pax_global_header00006660000000000000000000000064141070731540014514gustar00rootroot0000000000000052 comment=323f17bf5a05d08ef0a77198f8c7d8c7ccb543cc python-markdown2-2.4.1/000077500000000000000000000000001410707315400147435ustar00rootroot00000000000000python-markdown2-2.4.1/.github/000077500000000000000000000000001410707315400163035ustar00rootroot00000000000000python-markdown2-2.4.1/.github/workflows/000077500000000000000000000000001410707315400203405ustar00rootroot00000000000000python-markdown2-2.4.1/.github/workflows/python.yaml000066400000000000000000000011541410707315400225460ustar00rootroot00000000000000name: PythonCI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: [pypy3, 3.5, 3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install Pygments>=2.5.2 - name: Test run: | make testone python-markdown2-2.4.1/.gitignore000066400000000000000000000002431410707315400167320ustar00rootroot00000000000000*.pyc tmp deps/pygments deps/pygments3 dist MANIFEST build googlecode_upload.py perf/*.prof perf/tmp-*-cases sandbox/*.html __pycache__ .tox *.egg-info *.idea venvpython-markdown2-2.4.1/CHANGES.md000066400000000000000000000502331410707315400163400ustar00rootroot00000000000000# python-markdown2 Changelog ## python-markdown2 2.4.1 - [pull #389] Tables extra: allow whitespace at the end of the underline row - [pull #392] Pyshell extra: enable syntax highlighting if `fenced-code-blocks` is loaded. - [pull #402] Regex DOS bandaid fix ## python-markdown2 2.4.0 - [pull #377] Fixed bug breaking strings elements in metadata lists - [pull #380] When rendering fenced code blocks, also add the `language-LANG` class - [pull #387] Regex DoS fixes ## python-markdown2 2.3.10 - [pull #356] Don't merge sequential quotes into a single blockquote - [pull #357] use style=text-align for table alignment - [pull #360] introduce underline extra - [pull #368] Support for structured and nested values in metadata - [pull #371] add noopener to external links ## python-markdown2 2.3.9 - [pull #335] Added header support for wiki tables - [pull #336] Reset _toc when convert is run - [pull #353] XSS fix - [pull #350] XSS fix ## python-markdown2 2.3.8 - [pull #317] Temporary fix to issue #150 - [pull #319] Stop XML escaping the body of a link - [pull #322] Don't auto link patterns surrounded by triple quotes - [pull #324] Add class configurability to the enclosing tag - [pull #328] Accept [X] as marked task ## python-markdown2 2.3.7 - [pull #306] Drop support for legacy Python versions - [pull #307] Fix syntax highlighting test cases that depend on Pygments output - [pull #308] Add support for Python 3.7 - [pull #304] Add Wheel package support - [pull #312] Fix toc_depth initialization regression - [pull #315] XSS fix ## python-markdown2 2.3.6 - [pull #282] Add TOC depth option - [pull #283] Fix to add TOC html to output via CLI - [pull #284] Do not remove anchors in safe_mode - [pull #288] fixing cuddled-lists with a single list item - [pull #292] Fix Wrong rendering of last list element - [pull #295] link-patterns fix - [pull #300] Replace a deprecated method - [pull #301] DeprecationWarning: invalid escape sequence - [pull #302] Fix "make test" in Python 3 - [pull #303] Fix CVE-2018-5773 ## python-markdown2 2.3.5 - [pull #238] Fenced code blocks lang with leading space - [pull #260] Search for items only within metadata header - [pull #264] highlightjs language class support - [pull #265] FIPS compliance - [pull #274] Fix for double amp replacement inside link title ## python-markdown2 2.3.4 - [pull #243] task list extra visual changes - [pull #245] Don't let "target-blank-lines" break footnotes - [pull #247] Translatable footnote titles - [pull #252] Add pipe escaping in table extension ## python-markdown2 2.3.3 - [pull #236] Fix for safe_mode links regression - [pull #235] Fix for overgreedy regex in metadata - [pull #237] Fix for header-ids extra non-alpha character issue ## python-markdown2 2.3.2 - [pull #204] toc extra Python 3 error - [pull #207] Performance improvements - [pull #210] Leading paragraph with fenced code blocks - [pull #212] Target blank links extra - [pull #215] Optional metadata fences - [pull #218] Github style task list - [pull #220] Numbering extra - [pull #224] Metadata in blocks - [pull #230] safe_mode changes ## python-markdown2 2.3.1 - [pull #131] Markdown "spoiler" extra - [pull #170] html-classes support for table tags - [pull #190] "strike" extra - [pull #201] Allow empty table cells ## python-markdown2 2.3.0 - New "tables" extra for table syntax that matches GFM and PHP-Markdown Extra . For example: | Header 1 | *Header* 2 | | -------- | -------- | | `Cell 1` | [Cell 2](http://example.com) link | | Cell 3 | **Cell 4** | See for examples and edge cases. If you have documents using the 'wiki-tables' syntax and want to convert to the 'tables' syntax, there is a script to help with that here: ## python-markdown2 2.2.3 - [issue #165] Fix an edge case in list parsing. ## python-markdown2 2.2.2 - [pull #156] Footnotes XML compatibility. - [pull #157] Horizontal rule minimum length. - [pull #162] Fix escaping fenced code block with safe mode - [pull #163] Fix code highlight with safe mode ## python-markdown2 2.2.1 - [issue #142 pull #141] Fix parentheses and spaces in urls. - [issue #88 issue #95 pull #145] Fix code blocks in code blocks with syntax highlighting. - [issue #113 issue #127 via pull #144] Fix fenced-code-blocks html and code output. - [pull #133] Unify the -/= and ## style headers and fix TOC order - [pull #146] tag-friendly extra to require that atx headers have a space after # ## python-markdown2 2.2.0 - [issue #135] Fix fenced code blocks odd rendering. - [pull #138] specify shell in Makefile - [pull #130] break-on-newline extra - [pull #140] Allow html-classes for img - [pull #122] Allow parentheses in urls ## python-markdown2 2.1.0 - ["nofollow" extra, issue #74, pull #104] Add `rel="nofollow"` support (mostly by https://github.com/cdman): $ echo '[link](http://example)' | markdown2 -x nofollow

link

Limitation: This *can* add a duplicate 'rel' attribute to raw HTML links in the input. ## python-markdown2 2.0.1 - ["toc" extra] Unescape Markdown special chars in TOC entries. See . - Now 'tox' testing support (by github.com/msabramo): [sudo] pip install tox tox confirming that markdown2 works with jython (not sure which version) and pypy! Also added pypy to travis-ci testing (http://travis-ci.org/#!/trentm/python-markdown2). ## python-markdown2 2.0.0 - [issue #90] Add a `Markdown.preprocess(text) -> text` hook for subclasses. This is a match for the `Markdown.postprocess(text) -> text` hook added in an earlier version. (by @joestump). - [issue #90, backward incompatible change] Require a space between the '#' and a text for a title. I.e.: # This still works #This doesn't work ##Nor this This keeps comments, hash tags, and ticket numbers at the beginning of the line from turning into an h1. (by @joestump) This is a backward incompatible change, however small, hence the version change to 2.0.0. ## python-markdown2 1.4.2 - [issue #84, issue #87] Fix problems with fenced-code-blocks getting double-processed. ## python-markdown2 1.4.1 - [issue #67] Fix an sub-`ul` inside a `ol` not working with an indent less than 4 spaces. - Fix code blocks and fenced-code-blocks to work with a single leading newline at the start of the input. - [issue #86, 'fenced-code-blocks' extra] Fix fenced code blocks not being parsed out before other syntax elements, like headers. - [issue #83, 'fenced-code-blocks' and 'code-color' extras] Allow 'cssclass' code coloring option (passed to pygments) to be overridden (by https://github.com/kaishaku). E.g.: import markdown2 html = markdown2.markdown(text, extras={'fenced-code-blocks': {'cssclass': 'mycode'}}) ## python-markdown2 1.4.0 - [issue #64] Python 3 support! markdown2.py supports Python 2 and 3 in the same file without requiring install-time 2to3 transformation. ## python-markdown2 1.3.1 - [issue #80] Jython 2.2.1 support fix (by github.com/clach04) ## python-markdown2 1.3.0 - Deprecate `code-color` extra. Use the `fenced-code-block` extra and its cleaner mechanism for specifying the language, instead. This extra will be removed in v2.0 or so. - New `fenced-code-blocks` extra. It allows a code block to not have to be indented by fencing it with '```' on a line before and after. Based on [GFM](hi

Thanks Ryan! - Drop this "1.0.1.*" version silliness. The idea *was* that the first three numbers tracked the Markdown.pl on which markdown2.py was originally based. I don't believe Markdown.pl really gets releases anymore tho, so pointless. ## python-markdown2 1.0.1.19 - [Issue 66] Add "wiki-tables" extra for Google Code Wiki-style tables. See . ## python-markdown2 1.0.1.18 - [Issue 57] Add html5 block tags (article, section, aside, et al; see "_html5tags" variable) to Markdown literal HTML block tag handling. Thanks Tim Gray! - [Issue 56] Fix `setup.py install`. - [Issue 54] Fix escaping of link title attributes. Thanks FND! - Tweak list matching to NOT make a ul for something like this: - - - - - hi there Before this change this would be a silly 5-deep nested li. See "not_quite_a_list" test case. - [Issue 52] Fix potential pathologically slow matching for `
` markdown ("slow_hr" test case). - Add a `Markdown.postprocess(text) -> text` hook that is called near the end of markdown conversion. By default this does no transformation. It is called just before unescaping of special characters and unhashing of literal HTML blocks. - ["header-ids" and "toc" extras] Add "n" argument to `Markdown.header_id_from_text` hook. This allows a subclass using this hook to differentiate the header id based on the hN number (e.g. h1 diff that h2). Also allow a `None` return value to not add an id to that header (and exclude that header from the TOC). Note: If you used this hook, this is an incompatible change to the call signature. - Add a "markdown-in-html" extra similar to (but limited) . I.e. this:
Yo **yo**!
becomes:
Yo yo!
- [Issue 39] Test case fix for pygments 1.3.1 from thomas.moschny. - [Issue 42] Add "smarty-pants" extra for transforming plain ASCII punctuation characters into smart typographic punctuation HTML entities. Inspiration: Implementation by Nikhil Chelliah. Also add `\'` and `\"` escape sequences for forcing dumb quotes when this extra is in use. - Guard against using `True` instead of `None` as follows `markdown(..., extras={'header-ids': True})`. `None` is wanted, but `True` is commonly (at least I did it twice) used. ## python-markdown2 1.0.1.17 - [Issue 36] Fix "cuddled-lists" extra handling for an looks-like-a-cuddled-list-but-is-indented block. See the "test/tm-cases/cuddled_list_indented.text" test case. - Experimental new "toc" extra. The returned string from conversion will have a `toc_html` attribute. - New "header-ids" extra that will add an `id` attribute to headers: # My First Section will become:

My First Section

An argument can be give for the extra, which will be used as a prefix for the ids: $ cat foo.txt # hi there $ python markdown2.py foo.txt

hi there

$ python markdown2.py foo.txt -x header-ids

hi there

$ python markdown2.py foo.txt -x header-ids=prefix

hi there

- Preliminary support for "html-classes" extra: takes a dict mapping HTML tag to the string value to use for a "class" attribute for that emitted tag. Currently just supports "pre" and "code" for code *blocks*. ## python-markdown2 1.0.1.16 - [Issue 33] Implement a "cuddled-lists" extra that allows: I did these things: * bullet1 * bullet2 * bullet3 to be converted to:

I did these things:

  • bullet1
  • bullet2
  • bullet3
## python-markdown2 1.0.1.15 - [Issue 30] Fix a possible XSS via JavaScript injection in a carefully crafted image reference (usage of double-quotes in the URL). ## python-markdown2 1.0.1.14 - [Issue 29] Fix security hole in the md5-hashing scheme for handling HTML chunks during processing. - [Issue 27] Fix problem with underscores in footnotes content (with "footnotes" extra). ## python-markdown2 1.0.1.13 - [Issue 24] Set really long sentinel for max-length of link text to avoid problems with reasonably long ones. - [Issue 26] Complete the fix for this issue. Before this change the randomized obscuring of 'mailto:' link letters would sometimes result in emails with underscores getting misinterpreted as for italics. ## python-markdown2 1.0.1.12 - [Issue 26] Fix bug where email auto linking wouldn't work for emails with underscores. E.g. `Mail me: ` wouldn't work. - Update MANIFEST.in to ensure bin/markdown2 gets included in sdist. - [Issue 23] Add support for passing options to pygments for the "code-color" extra. For example: >>> markdown("...", extras={'code-color': {"noclasses": True}}) This `formatter_opts` dict is passed to the pygments HtmlCodeFormatter. Patch from 'svetlyak.40wt'. - [Issue 21] Escape naked '>' characters, as is already done for '&' and '<' characters. Note that other markdown implementations (both Perl and PHP) do *not* do this. This results in differing output with two 3rd-party tests: "php-markdown-cases/Backslash escapes.text" and "markdowntest-cases/Amps and angle encoding.tags". - "link-patterns" extra: Add support for the href replacement being a callable, e.g.: >>> link_patterns = [ ... (re.compile("PEP\s+(\d+)", re.I), ... lambda m: "http://www.python.org/dev/peps/pep-%04d/" % int(m.group(1))), ... ] >>> markdown2.markdown("Here is PEP 42.", extras=["link-patterns"], ... link_patterns=link_patterns) u'

Here is PEP 42.

\n' ## python-markdown2 1.0.1.11 - Fix syntax_color test for the latest Pygments. - [Issue 20] Can't assume that `sys.argv` is defined at top-level code -- e.g. when used at a PostreSQL stored procedure. Fix that. ## python-markdown2 1.0.1.10 - Fix sys.path manipulation in setup.py so `easy_install markdown2-*.tar.gz` works. (Henry Precheur pointed out the problem.) - "bin/markdown2" is now a stub runner script rather than a symlink to "lib/markdown2.py". The symlink was a problem for sdist: tar makes it a copy. - Added 'xml' extra: passes *one-liner* XML processing instructions and namespaced XML tags without wrapping in a `

` -- i.e. treats them as a HTML block tag. ## python-markdown2 1.0.1.9 - Fix bug in processing text with two HTML comments, where the first comment is cuddled to other content. See "test/tm-cases/two_comments.text". Noted by Wolfgang Machert. - Revert change in v1.0.1.6 passing XML processing instructions and one-liner tags. This changed caused some bugs. Similar XML processing support will make it back via an "xml" extra. ## python-markdown2 1.0.1.8 - License note updates to facilitate Thomas Moschny building a package for Fedora Core Linux. No functional change. ## python-markdown2 1.0.1.7 - Add a proper setup.py and release to pypi: http://pypi.python.org/pypi/markdown2/ - Move markdown2.py module to a lib subdir. This allows one to put the "lib" dir of a source checkout (e.g. via an svn:externals) on ones Python Path without have the .py files at the top-level getting in the way. ## python-markdown2 1.0.1.6 - Fix Python 2.6 deprecation warning about the `md5` module. - Pass XML processing instructions and one-liner tags. For example: Limitations: they must be on one line. Test: pi_and_xinclude. Suggested by Wolfgang Machert. ## python-markdown2 1.0.1.5 - Add ability for 'extras' to have arguments. Internally the 'extras' attribute of the Markdown class is a dict (it was a set). - Add "demote-headers" extra that will demote the markdown for, e.g., an h1 to h2-6 by the number of the demote-headers argument. >>> markdown('# this would be an h1', extras={'demote-headers': 2}) u'

this would be an h1

\n' This can be useful for user-supplied Markdown content for a sub-section of a page. ## python-markdown2 1.0.1.4 - [Issue 18] Allow spaces in the URL for link definitions. - [Issue 15] Fix some edge cases with backslash-escapes. - Fix this error that broken command-line usage: NameError: global name 'use_file_vars' is not defined - Add "pyshell" extra for auto-codeblock'ing Python interactive shell sessions even if they weren't properly indented by the tab width. ## python-markdown2 1.0.1.3 - Make the use of the `-*- markdown-extras: ... -*-` emacs-style files variable to set "extras" **off** be default. It can be turned on via `--use-file-vars` on the command line and `use_file_vars=True` via the module interface. - [Issue 3] Drop the code-color extra hack added *for* issue3 that was causing the a unicode error with unicode in a code-colored block, ## python-markdown2 1.0.1.2 - [Issue 8] Alleviate some of the incompat of the last change by allowing (at the Python module level) the usage of `safe_mode=True` to mean what it used to -- i.e. "replace" safe mode. - [Issue 8, **incompatible change**] The "-s|--safe" command line option and the equivalent "safe_mode" option has changed semantics to be a string instead of a boolean. Legal values of the string are "replace" (the old behaviour: literal HTML is replaced with "[HTML_REMOVED]") and "escape" (meta chars in literal HTML is escaped). - [Issue 11] Process markup in footnote definition bodies. - Add support for `-*- markdown-extras: ... -*-` emacs-style files variables (typically in an XML comment) to set "extras" for the markdown conversion. - [Issue 6] Fix problem with footnotes if the reference string had uppercase letters. ## python-markdown2 1.0.1.1 - [Issue 3] Fix conversion of unicode strings. - Make the "safe_mode" replacement test overridable via subclassing: change `Markdown.html_removed_text`. - [Issue 2] Fix problems with "safe_mode" removing generated HTML, instead of just raw HTML in the text. - Add "-s|--safe" command-line option to set "safe_mode" conversion boolean. This option is mainly for compat with markdown.py. - Add "link-patterns" extra: allows one to specify a list of regexes that should be automatically made into links. For example, one can define a mapping for things like "Mozilla Bug 1234": regex: mozilla\s+bug\s+(\d+) href: http://bugzilla.mozilla.org/show_bug.cgi?id=\1 See for details. - Add a "MarkdownWithExtras" class that enables all extras (except "code-friendly"): >>> import markdown2 >>> converter = markdown2.MarkdownWithExtras() >>> converter.convert('...TEXT...') ...HTML... - [Issue 1] Added "code-color" extra: pygments-based (TODO: link) syntax coloring of code blocks. Requires the pygments Python library on sys.path. See for details. - [Issue 1] Added "footnotes" extra: adds support for footnotes syntax. See for details. ## python-markdown2 1.0.1.0 - Added "code-friendly" extra: disables the use of leading and trailing `_` and `__` for emphasis and strong. These can easily get in the way when writing docs about source code with variable_list_this and when one is not careful about quoting. - Full basic Markdown syntax. (Started maintaining this log 15 Oct 2007. At that point there had been no releases of python-markdown2.) python-markdown2-2.4.1/CONTRIBUTORS.txt000066400000000000000000000037141410707315400174460ustar00rootroot00000000000000Nicholas Serra (github.com/nicholasserra, primary maintainer) Trent Mick (github.com/trentm, original author) Thomas Moschny (redhat packaging, https://bugzilla.redhat.com/show_bug.cgi?id=461692) Massimo Di Pierro (security fix, issue #29) Nikhil Chelliah ("smarty-pants" extra, issue #42) Tim Gray (html5 block tags, issue #57) Ryan Doenges (github.com/rhdoenges, filter CLI, issue #72) slomo (github.com/slomo, metadata extra, issue #78) Joe Stump (@joestump, pull #90) msabramo (github.com/msabramo, tox test setup) Attila-Mihaly Balazs (github.com/cdman) Taylan Aydinli (github.com/vape, pull #140) Joseph Turner (github.com/josephturnerjr, pull #122) Malcolm Rowe (github.com/malcolmr) Lukáš Pohlreich (github.com/polarkac) Devvyn Murphy (github.com/devvynm) Neo (github.com/neo5simple) Adam Labbe (github.com/adamatom) Marios Zindilis (github.com/marios-zindilis) keysona (github.com/keysona) nkanaev (github.com/nkanaev) liguangsheng (github.com/liguangsheng) ewankirk (github.com/ewankirk) Oz N Tiram (github.com/oz123) Alan Hamlett (github.com/alanhamlett) Stein Strindhaug (github.com/strindhaug) David Lowry-Duda (github.com/davidowryduda) neo5anderson (github.com/neo5anderson) cosven (github.com/cosven) David D Lowe (github.com/Flimm) Lapshin Dmitry (github.com/LDVSOFT) rox (github.com/roxma) Matthew Howle (github.com/mdhowle) Chris Riedl (github.com/wrwlf) Shaun Brady (github.com/shaunbrady) MattX (github.com/MattX) Denis Ivanov (github.com/tetafro) Hassan Magdy Saad (github.com/hmagdy) Christian Klus (github.com/kluchrj) Tsuyoshi Hombashi (github.com/thombashi) Sym Roe (github.com/symroe) Alex Elzenaar (github.com/aelzenaar) Francisco Saldaña (github.com/FrankSalad) Shivam Kumar Jha (github.com/thealphadollar) ryanvilbrandt (github.com/ryanvilbrandt) Gareth Simpson (github.com/xurble) Kat Hagan (github.com/codebykat) Stɑrry Shivɑm (github.com/starry69) André Nasturas (github.com/andrenasturas) Denis Kasak (github.com/dkasak) Maximilian Hils (github.com/mhils) python-markdown2-2.4.1/LICENSE.txt000066400000000000000000000044111410707315400165660ustar00rootroot00000000000000This implementation of Markdown is licensed under the MIT License: The MIT License Copyright (c) 2012 Trent Mick Copyright (c) 2010 ActiveState Software Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. All files in a *source package* of markdown2 (i.e. those available on pypi.python.org and the Google Code project "downloads" page) are under the MIT license. However, in the *subversion repository* there are some files (used for performance and testing purposes) that are under different licenses as follows: - perf/recipes.pprint Python License. This file includes a number of real-world examples of Markdown from the ActiveState Python Cookbook, used for doing some performance testing of markdown2.py. - test/php-markdown-cases/... test/php-markdown-extra-cases/... GPL. These are from the MDTest package announced here: http://six.pairlist.net/pipermail/markdown-discuss/2007-July/000674.html - test/markdown.py GPL 2 or BSD. A copy (currently old) of Python-Markdown -- the other Python Markdown implementation. - test/markdown.php BSD-style. This is PHP Markdown (http://michelf.com/projects/php-markdown/). - test/Markdown.pl: BSD-style A copy of Perl Markdown (http://daringfireball.net/projects/markdown/). python-markdown2-2.4.1/MANIFEST.in000066400000000000000000000004051410707315400165000ustar00rootroot00000000000000include README.txt include TODO.txt include LICENSE.txt include CONTRIBUTORS.txt include CHANGES.md include Makefile include setup.py include setup.cfg include bin/markdown2 include test/api.doctests recursive-include test/tm-cases *.text *.html *.opts *.tags python-markdown2-2.4.1/Makefile000066400000000000000000000016141410707315400164050ustar00rootroot00000000000000# python-markdown2 Makefile SHELL=/bin/bash .PHONY: all all: .PHONY: test test: cd test && python testall.py .PHONY: testone testone: cd test && python test.py -- -knownfailure .PHONY: pygments pygments: [[ -d deps/pygments ]] || ( \ mkdir -p deps && \ hg clone https://bitbucket.org/birkenfeld/pygments-main deps/pygments) (cd deps/pygments && hg pull && hg update) # And for Python 3 usage: rm -rf deps/pygments3 mkdir -p deps/pygments3 cp -PR deps/pygments/pygments deps/pygments3/pygments 2to3 -w --no-diffs deps/pygments3/pygments clean: rm -rf build dist MANIFEST .PHONY: versioncheck versioncheck: [[ `grep '^__version_info__' lib/markdown2.py | cut -d'(' -f2 | cut -d')' -f1 | sed 's/, /./g'` \ == `grep '^## ' CHANGES.md | head -1 | awk '{print $$3}'` ]] @echo Version check ok. .PHONY: cutarelease cutarelease: versioncheck ./tools/cutarelease.py -f lib/markdown2.py python-markdown2-2.4.1/README.md000066400000000000000000000122111410707315400162170ustar00rootroot00000000000000Markdown is a light text markup format and a processor to convert that to HTML. The originator describes it as follows: > Markdown is a text-to-HTML conversion tool for web writers. > Markdown allows you to write using an easy-to-read, > easy-to-write plain text format, then convert it to > structurally valid XHTML (or HTML). > > -- This (markdown2) is a fast and complete Python implementation of Markdown. It was written to closely match the behaviour of the original Perl-implemented Markdown.pl. Markdown2 also comes with a number of extensions (called "extras") for things like syntax coloring, tables, header-ids. See the "Extra Syntax" section below. "markdown2" supports all Python versions 2.6+ or 3.3+ (and pypy and jython, though I don't frequently test those). There is another [Python markdown.py](https://python-markdown.github.io/). However, at least at the time this project was started, markdown2.py was faster (see the [Performance Notes](https://github.com/trentm/python-markdown2/wiki/Performance-Notes)) and, to my knowledge, more correct (see [Testing Notes](https://github.com/trentm/python-markdown2/wiki/Testing-Notes)). That was a while ago though, so you shouldn't discount Python-markdown from your consideration. Follow @trentmick for updates to python-markdown2. # Install To install it in your Python installation run *one* of the following: pip install markdown2 pypm install markdown2 # if you use ActivePython (activestate.com/activepython) easy_install markdown2 # if this is the best you have python setup.py install However, everything you need to run this is in "lib/markdown2.py". If it is easier for you, you can just copy that file to somewhere on your PythonPath (to use as a module) or executable path (to use as a script). # Quick Usage As a module: ```python >>> import markdown2 >>> markdown2.markdown("*boo!*") # or use `html = markdown_path(PATH)` u'

boo!

\n' >>> from markdown2 import Markdown >>> markdowner = Markdown() >>> markdowner.convert("*boo!*") u'

boo!

\n' >>> markdowner.convert("**boom!**") u'

boom!

\n' ``` As a script (CLI): ```shell $ python markdown2.py foo.md > foo.html ``` or ```shell $ python -m markdown2 foo.md > foo.html ``` I think pip-based installation will enable this as well: ```shell $ markdown2 foo.md > foo.html ``` See the [project wiki](https://github.com/trentm/python-markdown2/wiki), [lib/markdown2.py](https://github.com/trentm/python-markdown2/blob/master/lib/markdown2.py) docstrings and/or `python markdown2.py --help` for more details. # Extra Syntax (aka extensions) Many Markdown processors include support for additional optional syntax (often called "extensions") and markdown2 is no exception. With markdown2 these are called "extras". Using the "footnotes" extra as an example, here is how you use an extra ... as a module: ```shell $ python markdown2.py --extras footnotes foo.md > foo.html ``` as a script: ```shell >>> import markdown2 >>> markdown2.markdown("*boo!*", extras=["footnotes"]) u'

boo!

\n' ``` There are a number of currently implemented extras for tables, footnotes, syntax coloring of `
`-blocks, auto-linking patterns, table of contents,
Smarty Pants (for fancy quotes, dashes, etc.) and more. See the [Extras
wiki page](https://github.com/trentm/python-markdown2/wiki/Extras) for full
details.


# Project

The python-markdown2 project lives at
.  (Note: On Mar 6, 2011 this
project was moved from [Google Code](http://code.google.com/p/python-markdown2)
to here on Github.) See also, [markdown2 on the Python Package Index
(PyPI)](http://pypi.python.org/pypi/markdown2).

The change log: 

To report a bug: 

# Contributing

We welcome pull requests from the community. Please take a look at the [TODO](https://github.com/trentm/python-markdown2/blob/master/TODO.txt) for opportunities to help this project. For those wishing to submit a pull request to `python-markdown2` please ensure it fulfills the following requirements:

* It must pass PEP8.
* It must include relevant test coverage.
* Bug fixes must include a regression test that exercises the bug.
* The entire test suite must pass.
* The README and/or docs are updated accordingly.


# Test Suite

This markdown implementation passes a fairly extensive test suite. To run it:
```shell
make test
```
The crux of the test suite is a number of "cases" directories -- each with a
set of matching .text (input) and .html (expected output) files. These are:

    tm-cases/                   Tests authored for python-markdown2 (tm=="Trent Mick")
    markdowntest-cases/         Tests from the 3rd-party MarkdownTest package
    php-markdown-cases/         Tests from the 3rd-party MDTest package
    php-markdown-extra-cases/   Tests also from MDTest package

See the [Testing Notes wiki
page](https://github.com/trentm/python-markdown2/wiki/Testing-Notes) for full
details.
python-markdown2-2.4.1/TODO.txt000066400000000000000000000064301410707315400162540ustar00rootroot00000000000000- py3: py2.4 test (broken?)
- add "smarty-pants" extra to wiki
- add "html-classes" extra to wiki
- more on the "code-color" extra wiki page
- better "Extras" wiki page that shows a quick example of each with link for
  more details. Mention "extensions" for gjuice.
- add description of demote-headers extras to wiki
- find more unicode edge cases (look for any usage of md5() and make that
  unicode)
- bug: can't have '<\w+' in a code span or code block with safe_mode if there
  is a '>' somewhere later in the document. E.g. code.as.com-beta/CHANGES.md.
  It captures all of that. Right answer is to not count code spans or code
  blocks.
  - add an issue for this
  - test cases
  - idea: better sanitation re-write? lot of work
  - idea: Change all <,>,& emission from markdown processing to something
    like {LT}, {GT}, {AMP}, {OPENTAG:$tag[:$class]} (first checking for
    conflicts and escaping those out of the way). Then do sanitization at the
    end:
        escape: escape all <,>,& with entities
        remove: not supported
        whitelist: (new) build a reasonable default whitelist of patterns to
            keep. Takes "extras" argument (and hook for subclassing) to
            for custom whitelist. Google Code (was it?) had some list
            of reasonable whitelist stuff.
    Then unescape these special chars. The use of OPENTAG above would make
    "html-classes" extra trivial.
- test safe_mode on HTML in footnotes
- http://www.freewisdom.org/projects/python-markdown/Available_Extensions
- Extras.wiki desc of code-color option. Not sure I love the ":::name"
  markup for the lexer name.
- update MDTest 1.1? (see
  http://six.pairlist.net/pipermail/markdown-discuss/2007-September/000815.html)
  update MDTest tests from http://git.michelf.com/mdtest/
- I see ref to Markdown.pl 1.0.2
  (http://six.pairlist.net/pipermail/markdown-discuss/2007-August/000756.html)
  Update to that? Yes. Copy, at least, in showdown package.
- take a look at other examples/test-cases from
  http://adlcommunity.net/help.php?file=advanced_markdown.html
- get on http://en.wikipedia.org/wiki/Markdown
- ask about remaining two MarkdownTest test failures
- fix the r135 xml option, add xml extra for it (see email)
- perhaps some extras from Maruku and PHP Markdown extra
  (http://maruku.rubyforge.org/maruku.html#extra)
    - tables (tho I don't really like the syntax, prefer google codes, see
      below)
    - markdown inside literal HTML (if 'markdown="1|true"' attr)
    - automatic toc generation (wanted that anyway, no a fan of maruku syntax
      for this)
    - weird markup in headers and links (does markdown2.py handle this?)
    - meta-data syntax? One example of this is ids for headers. How about
      automatically assigning header ids from the name (a la rest)?
    - at-the-top email-style headers?
    - maruku's footnote links are 'fn:1' and 'fnref:1' for a footnote id of
      'blah'. If this is the PHP Markdown Extras way, then should follow
      that.
- googlecode wiki markup ideas?
  (http://code.google.com/p/support/wiki/WikiSyntax)
    - ~~strikeout~~
-  at bottom has a wish
  list:
    - simple "cite" for blockquote. How about:
        [Zaphod Breeblebrox]
        > blah blah
        > blah
- look at http://markedapp.com/   screencast?
python-markdown2-2.4.1/bin/000077500000000000000000000000001410707315400155135ustar00rootroot00000000000000python-markdown2-2.4.1/bin/markdown2000077500000000000000000000007371410707315400173540ustar00rootroot00000000000000#!/usr/bin/env python

import sys
from os.path import join, dirname, exists

# Use the local markdown2.py if we are in the source tree.
source_tree_markdown2 = join(dirname(__file__), "..", "lib", "markdown2.py")
if exists(source_tree_markdown2):
    sys.path.insert(0, dirname(source_tree_markdown2))
    try:
        from markdown2 import main
    finally:
        del sys.path[0]
else:
    from markdown2 import main

if __name__ == "__main__":
    sys.exit( main(sys.argv) )
python-markdown2-2.4.1/lib/000077500000000000000000000000001410707315400155115ustar00rootroot00000000000000python-markdown2-2.4.1/lib/markdown2.py000077500000000000000000003365251410707315400200100ustar00rootroot00000000000000#!/usr/bin/env python
# Copyright (c) 2012 Trent Mick.
# Copyright (c) 2007-2008 ActiveState Corp.
# License: MIT (http://www.opensource.org/licenses/mit-license.php)

r"""A fast and complete Python implementation of Markdown.

[from http://daringfireball.net/projects/markdown/]
> Markdown is a text-to-HTML filter; it translates an easy-to-read /
> easy-to-write structured text format into HTML.  Markdown's text
> format is most similar to that of plain text email, and supports
> features such as headers, *emphasis*, code blocks, blockquotes, and
> links.
>
> Markdown's syntax is designed not as a generic markup language, but
> specifically to serve as a front-end to (X)HTML. You can use span-level
> HTML tags anywhere in a Markdown document, and you can use block level
> HTML tags (like 
and as well). Module usage: >>> import markdown2 >>> markdown2.markdown("*boo!*") # or use `html = markdown_path(PATH)` u'

boo!

\n' >>> markdowner = Markdown() >>> markdowner.convert("*boo!*") u'

boo!

\n' >>> markdowner.convert("**boom!**") u'

boom!

\n' This implementation of Markdown implements the full "core" syntax plus a number of extras (e.g., code syntax coloring, footnotes) as described on . """ cmdln_desc = """A fast and complete Python implementation of Markdown, a text-to-HTML conversion tool for web writers. Supported extra syntax options (see -x|--extras option below and see for details): * break-on-newline: Replace single new line characters with
when True * code-friendly: Disable _ and __ for em and strong. * cuddled-lists: Allow lists to be cuddled to the preceding paragraph. * fenced-code-blocks: Allows a code block to not have to be indented by fencing it with '```' on a line before and after. Based on with support for syntax highlighting. * footnotes: Support footnotes as in use on daringfireball.net and implemented in other Markdown processors (tho not in Markdown.pl v1.0.1). * header-ids: Adds "id" attributes to headers. The id value is a slug of the header text. * highlightjs-lang: Allows specifying the language which used for syntax highlighting when using fenced-code-blocks and highlightjs. * html-classes: Takes a dict mapping html tag names (lowercase) to a string to use for a "class" tag attribute. Currently only supports "img", "table", "pre" and "code" tags. Add an issue if you require this for other tags. * link-patterns: Auto-link given regex patterns in text (e.g. bug number references, revision number references). * markdown-in-html: Allow the use of `markdown="1"` in a block HTML tag to have markdown processing be done on its contents. Similar to but with some limitations. * metadata: Extract metadata from a leading '---'-fenced block. See for details. * nofollow: Add `rel="nofollow"` to add `` tags with an href. See . * numbering: Support of generic counters. Non standard extension to allow sequential numbering of figures, tables, equations, exhibits etc. * pyshell: Treats unindented Python interactive shell sessions as blocks. * smarty-pants: Replaces ' and " with curly quotation marks or curly apostrophes. Replaces --, ---, ..., and . . . with en dashes, em dashes, and ellipses. * spoiler: A special kind of blockquote commonly hidden behind a click on SO. Syntax per . * strike: text inside of double tilde is ~~strikethrough~~ * tag-friendly: Requires atx style headers to have a space between the # and the header text. Useful for applications that require twitter style tags to pass through the parser. * tables: Tables using the same format as GFM and PHP-Markdown Extra . * toc: The returned HTML string gets a new "toc_html" attribute which is a Table of Contents for the document. (experimental) * use-file-vars: Look for an Emacs-style markdown-extras file variable to turn on Extras. * wiki-tables: Google Code Wiki-style tables. See . * xml: Passes one-liner processing instructions and namespaced XML tags. """ # Dev Notes: # - Python's regex syntax doesn't have '\z', so I'm using '\Z'. I'm # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. __version_info__ = (2, 4, 1) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" import sys import re import logging from hashlib import sha256 import optparse from random import random, randint import codecs from collections import defaultdict # ---- Python version compat # Use `bytes` for byte strings and `unicode` for unicode strings (str in Py3). if sys.version_info[0] <= 2: py3 = False try: bytes except NameError: bytes = str base_string_type = basestring elif sys.version_info[0] >= 3: py3 = True unicode = str base_string_type = str # ---- globals DEBUG = False log = logging.getLogger("markdown") DEFAULT_TAB_WIDTH = 4 SECRET_SALT = bytes(randint(0, 1000000)) # MD5 function was previously used for this; the "md5" prefix was kept for # backwards compatibility. def _hash_text(s): return 'md5-' + sha256(SECRET_SALT + s.encode("utf-8")).hexdigest()[32:] # Table of hash values for escaped characters: g_escape_table = dict([(ch, _hash_text(ch)) for ch in '\\`*_{}[]()>#+-.!']) # Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: # http://bumppo.net/projects/amputator/ _AMPERSAND_RE = re.compile(r'&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)') # ---- exceptions class MarkdownError(Exception): pass # ---- public api def markdown_path(path, encoding="utf-8", html4tags=False, tab_width=DEFAULT_TAB_WIDTH, safe_mode=None, extras=None, link_patterns=None, footnote_title=None, footnote_return_symbol=None, use_file_vars=False): fp = codecs.open(path, 'r', encoding) text = fp.read() fp.close() return Markdown(html4tags=html4tags, tab_width=tab_width, safe_mode=safe_mode, extras=extras, link_patterns=link_patterns, footnote_title=footnote_title, footnote_return_symbol=footnote_return_symbol, use_file_vars=use_file_vars).convert(text) def markdown(text, html4tags=False, tab_width=DEFAULT_TAB_WIDTH, safe_mode=None, extras=None, link_patterns=None, footnote_title=None, footnote_return_symbol=None, use_file_vars=False, cli=False): return Markdown(html4tags=html4tags, tab_width=tab_width, safe_mode=safe_mode, extras=extras, link_patterns=link_patterns, footnote_title=footnote_title, footnote_return_symbol=footnote_return_symbol, use_file_vars=use_file_vars, cli=cli).convert(text) class Markdown(object): # The dict of "extras" to enable in processing -- a mapping of # extra name to argument for the extra. Most extras do not have an # argument, in which case the value is None. # # This can be set via (a) subclassing and (b) the constructor # "extras" argument. extras = None urls = None titles = None html_blocks = None html_spans = None html_removed_text = "{(#HTML#)}" # placeholder removed text that does not trigger bold html_removed_text_compat = "[HTML_REMOVED]" # for compat with markdown.py _toc = None # Used to track when we're inside an ordered or unordered list # (see _ProcessListItems() for details): list_level = 0 _ws_only_line_re = re.compile(r"^[ \t]+$", re.M) def __init__(self, html4tags=False, tab_width=4, safe_mode=None, extras=None, link_patterns=None, footnote_title=None, footnote_return_symbol=None, use_file_vars=False, cli=False): if html4tags: self.empty_element_suffix = ">" else: self.empty_element_suffix = " />" self.tab_width = tab_width self.tab = tab_width * " " # For compatibility with earlier markdown2.py and with # markdown.py's safe_mode being a boolean, # safe_mode == True -> "replace" if safe_mode is True: self.safe_mode = "replace" else: self.safe_mode = safe_mode # Massaging and building the "extras" info. if self.extras is None: self.extras = {} elif not isinstance(self.extras, dict): self.extras = dict([(e, None) for e in self.extras]) if extras: if not isinstance(extras, dict): extras = dict([(e, None) for e in extras]) self.extras.update(extras) assert isinstance(self.extras, dict) if "toc" in self.extras: if "header-ids" not in self.extras: self.extras["header-ids"] = None # "toc" implies "header-ids" if self.extras["toc"] is None: self._toc_depth = 6 else: self._toc_depth = self.extras["toc"].get("depth", 6) self._instance_extras = self.extras.copy() self.link_patterns = link_patterns self.footnote_title = footnote_title self.footnote_return_symbol = footnote_return_symbol self.use_file_vars = use_file_vars self._outdent_re = re.compile(r'^(\t|[ ]{1,%d})' % tab_width, re.M) self.cli = cli self._escape_table = g_escape_table.copy() if "smarty-pants" in self.extras: self._escape_table['"'] = _hash_text('"') self._escape_table["'"] = _hash_text("'") def reset(self): self.urls = {} self.titles = {} self.html_blocks = {} self.html_spans = {} self.list_level = 0 self.extras = self._instance_extras.copy() if "footnotes" in self.extras: self.footnotes = {} self.footnote_ids = [] if "header-ids" in self.extras: self._count_from_header_id = defaultdict(int) if "metadata" in self.extras: self.metadata = {} self._toc = None # Per "rel" # should only be used in tags with an "href" attribute. # Opens the linked document in a new window or tab # should only used in tags with an "href" attribute. # same with _a_nofollow _a_nofollow_or_blank_links = re.compile(r""" <(a) ( [^>]* href= # href is required ['"]? # HTML5 attribute values do not have to be quoted [^#'"] # We don't want to match href values that start with # (like footnotes) ) """, re.IGNORECASE | re.VERBOSE ) def convert(self, text): """Convert the given text.""" # Main function. The order in which other subs are called here is # essential. Link and image substitutions need to happen before # _EscapeSpecialChars(), so that any *'s or _'s in the # and tags get encoded. # Clear the global hashes. If we don't clear these, you get conflicts # from other articles when generating a page which contains more than # one article (e.g. an index page that shows the N most recent # articles): self.reset() if not isinstance(text, unicode): # TODO: perhaps shouldn't presume UTF-8 for string input? text = unicode(text, 'utf-8') if self.use_file_vars: # Look for emacs-style file variable hints. emacs_vars = self._get_emacs_vars(text) if "markdown-extras" in emacs_vars: splitter = re.compile("[ ,]+") for e in splitter.split(emacs_vars["markdown-extras"]): if '=' in e: ename, earg = e.split('=', 1) try: earg = int(earg) except ValueError: pass else: ename, earg = e, None self.extras[ename] = earg # Standardize line endings: text = text.replace("\r\n", "\n") text = text.replace("\r", "\n") # Make sure $text ends with a couple of newlines: text += "\n\n" # Convert all tabs to spaces. text = self._detab(text) # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ \t]*\n+/ . text = self._ws_only_line_re.sub("", text) # strip metadata from head and extract if "metadata" in self.extras: text = self._extract_metadata(text) text = self.preprocess(text) if "fenced-code-blocks" in self.extras and not self.safe_mode: text = self._do_fenced_code_blocks(text) if self.safe_mode: text = self._hash_html_spans(text) # Turn block-level HTML blocks into hash entries text = self._hash_html_blocks(text, raw=True) if "fenced-code-blocks" in self.extras and self.safe_mode: text = self._do_fenced_code_blocks(text) # Because numbering references aren't links (yet?) then we can do everything associated with counters # before we get started if "numbering" in self.extras: text = self._do_numbering(text) # Strip link definitions, store in hashes. if "footnotes" in self.extras: # Must do footnotes first because an unlucky footnote defn # looks like a link defn: # [^4]: this "looks like a link defn" text = self._strip_footnote_definitions(text) text = self._strip_link_definitions(text) text = self._run_block_gamut(text) if "footnotes" in self.extras: text = self._add_footnotes(text) text = self.postprocess(text) text = self._unescape_special_chars(text) if self.safe_mode: text = self._unhash_html_spans(text) # return the removed text warning to its markdown.py compatible form text = text.replace(self.html_removed_text, self.html_removed_text_compat) do_target_blank_links = "target-blank-links" in self.extras do_nofollow_links = "nofollow" in self.extras if do_target_blank_links and do_nofollow_links: text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="nofollow noopener" target="_blank"\2', text) elif do_target_blank_links: text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="noopener" target="_blank"\2', text) elif do_nofollow_links: text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="nofollow"\2', text) if "toc" in self.extras and self._toc: self._toc_html = calculate_toc_html(self._toc) # Prepend toc html to output if self.cli: text = '{}\n{}'.format(self._toc_html, text) text += "\n" # Attach attrs to output rv = UnicodeWithAttrs(text) if "toc" in self.extras and self._toc: rv.toc_html = self._toc_html if "metadata" in self.extras: rv.metadata = self.metadata return rv def postprocess(self, text): """A hook for subclasses to do some postprocessing of the html, if desired. This is called before unescaping of special chars and unhashing of raw HTML spans. """ return text def preprocess(self, text): """A hook for subclasses to do some preprocessing of the Markdown, if desired. This is called after basic formatting of the text, but prior to any extras, safe mode, etc. processing. """ return text # Is metadata if the content starts with optional '---'-fenced `key: value` # pairs. E.g. (indented for presentation): # --- # foo: bar # another-var: blah blah # --- # # header # or: # foo: bar # another-var: blah blah # # # header _meta_data_pattern = re.compile(r'^(?:---[\ \t]*\n)?((?:[\S\w]+\s*:(?:\n+[ \t]+.*)+)|(?:.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)|(?:\s*[\S\w]+\s*:(?! >)[ \t]*.*\n?))(?:---[\ \t]*\n)?', re.MULTILINE) _key_val_pat = re.compile(r"[\S\w]+\s*:(?! >)[ \t]*.*\n?", re.MULTILINE) # this allows key: > # value # conutiues over multiple lines _key_val_block_pat = re.compile( r"(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)", re.MULTILINE ) _key_val_list_pat = re.compile( r"^-(?:[ \t]*([^\n]*)(?:[ \t]*[:-][ \t]*(\S+))?)(?:\n((?:[ \t]+[^\n]+\n?)+))?", re.MULTILINE, ) _key_val_dict_pat = re.compile( r"^([^:\n]+)[ \t]*:[ \t]*([^\n]*)(?:((?:\n[ \t]+[^\n]+)+))?", re.MULTILINE ) # grp0: key, grp1: value, grp2: multiline value _meta_data_fence_pattern = re.compile(r'^---[\ \t]*\n', re.MULTILINE) _meta_data_newline = re.compile("^\n", re.MULTILINE) def _extract_metadata(self, text): if text.startswith("---"): fence_splits = re.split(self._meta_data_fence_pattern, text, maxsplit=2) metadata_content = fence_splits[1] match = re.findall(self._meta_data_pattern, metadata_content) if not match: return text tail = fence_splits[2] else: metadata_split = re.split(self._meta_data_newline, text, maxsplit=1) metadata_content = metadata_split[0] match = re.findall(self._meta_data_pattern, metadata_content) if not match: return text tail = metadata_split[1] def parse_structured_value(value): vs = value.lstrip() vs = value.replace(v[: len(value) - len(vs)], "\n")[1:] # List if vs.startswith("-"): r = [] for match in re.findall(self._key_val_list_pat, vs): if match[0] and not match[1] and not match[2]: r.append(match[0].strip()) elif match[0] == ">" and not match[1] and match[2]: r.append(match[2].strip()) elif match[0] and match[1]: r.append({match[0].strip(): match[1].strip()}) elif not match[0] and not match[1] and match[2]: r.append(parse_structured_value(match[2])) else: # Broken case pass return r # Dict else: return { match[0].strip(): ( match[1].strip() if match[1] else parse_structured_value(match[2]) ) for match in re.findall(self._key_val_dict_pat, vs) } for item in match: k, v = item.split(":", 1) # Multiline value if v[:3] == " >\n": self.metadata[k.strip()] = v[3:].strip() # Empty value elif v == "\n": self.metadata[k.strip()] = "" # Structured value elif v[0] == "\n": self.metadata[k.strip()] = parse_structured_value(v) # Simple value else: self.metadata[k.strip()] = v.strip() return tail _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*(?:(\S[^\r\n]*?)([\r\n]\s*)?)?-\*-", re.UNICODE) # This regular expression is intended to match blocks like this: # PREFIX Local Variables: SUFFIX # PREFIX mode: Tcl SUFFIX # PREFIX End: SUFFIX # Some notes: # - "[ \t]" is used instead of "\s" to specifically exclude newlines # - "(\r\n|\n|\r)" is used instead of "$" because the sre engine does # not like anything other than Unix-style line terminators. _emacs_local_vars_pat = re.compile(r"""^ (?P(?:[^\r\n|\n|\r])*?) [\ \t]*Local\ Variables:[\ \t]* (?P.*?)(?:\r\n|\n|\r) (?P.*?\1End:) """, re.IGNORECASE | re.MULTILINE | re.DOTALL | re.VERBOSE) def _get_emacs_vars(self, text): """Return a dictionary of emacs-style local variables. Parsing is done loosely according to this spec (and according to some in-practice deviations from this): http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables """ emacs_vars = {} SIZE = pow(2, 13) # 8kB # Search near the start for a '-*-'-style one-liner of variables. head = text[:SIZE] if "-*-" in head: match = self._emacs_oneliner_vars_pat.search(head) if match: emacs_vars_str = match.group(1) assert '\n' not in emacs_vars_str emacs_var_strs = [s.strip() for s in emacs_vars_str.split(';') if s.strip()] if len(emacs_var_strs) == 1 and ':' not in emacs_var_strs[0]: # While not in the spec, this form is allowed by emacs: # -*- Tcl -*- # where the implied "variable" is "mode". This form # is only allowed if there are no other variables. emacs_vars["mode"] = emacs_var_strs[0].strip() else: for emacs_var_str in emacs_var_strs: try: variable, value = emacs_var_str.strip().split(':', 1) except ValueError: log.debug("emacs variables error: malformed -*- " "line: %r", emacs_var_str) continue # Lowercase the variable name because Emacs allows "Mode" # or "mode" or "MoDe", etc. emacs_vars[variable.lower()] = value.strip() tail = text[-SIZE:] if "Local Variables" in tail: match = self._emacs_local_vars_pat.search(tail) if match: prefix = match.group("prefix") suffix = match.group("suffix") lines = match.group("content").splitlines(0) # print "prefix=%r, suffix=%r, content=%r, lines: %s"\ # % (prefix, suffix, match.group("content"), lines) # Validate the Local Variables block: proper prefix and suffix # usage. for i, line in enumerate(lines): if not line.startswith(prefix): log.debug("emacs variables error: line '%s' " "does not use proper prefix '%s'" % (line, prefix)) return {} # Don't validate suffix on last line. Emacs doesn't care, # neither should we. if i != len(lines)-1 and not line.endswith(suffix): log.debug("emacs variables error: line '%s' " "does not use proper suffix '%s'" % (line, suffix)) return {} # Parse out one emacs var per line. continued_for = None for line in lines[:-1]: # no var on the last line ("PREFIX End:") if prefix: line = line[len(prefix):] # strip prefix if suffix: line = line[:-len(suffix)] # strip suffix line = line.strip() if continued_for: variable = continued_for if line.endswith('\\'): line = line[:-1].rstrip() else: continued_for = None emacs_vars[variable] += ' ' + line else: try: variable, value = line.split(':', 1) except ValueError: log.debug("local variables error: missing colon " "in local variables entry: '%s'" % line) continue # Do NOT lowercase the variable name, because Emacs only # allows "mode" (and not "Mode", "MoDe", etc.) in this block. value = value.strip() if value.endswith('\\'): value = value[:-1].rstrip() continued_for = variable else: continued_for = None emacs_vars[variable] = value # Unquote values. for var, val in list(emacs_vars.items()): if len(val) > 1 and (val.startswith('"') and val.endswith('"') or val.startswith('"') and val.endswith('"')): emacs_vars[var] = val[1:-1] return emacs_vars def _detab_line(self, line): r"""Recusively convert tabs to spaces in a single line. Called from _detab().""" if '\t' not in line: return line chunk1, chunk2 = line.split('\t', 1) chunk1 += (' ' * (self.tab_width - len(chunk1) % self.tab_width)) output = chunk1 + chunk2 return self._detab_line(output) def _detab(self, text): r"""Iterate text line by line and convert tabs to spaces. >>> m = Markdown() >>> m._detab("\tfoo") ' foo' >>> m._detab(" \tfoo") ' foo' >>> m._detab("\t foo") ' foo' >>> m._detab(" foo") ' foo' >>> m._detab(" foo\n\tbar\tblam") ' foo\n bar blam' """ if '\t' not in text: return text output = [] for line in text.splitlines(): output.append(self._detab_line(line)) return '\n'.join(output) # I broke out the html5 tags here and add them to _block_tags_a and # _block_tags_b. This way html5 tags are easy to keep track of. _html5tags = '|article|aside|header|hgroup|footer|nav|section|figure|figcaption' _block_tags_a = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del' _block_tags_a += _html5tags _strict_tag_block_re = re.compile(r""" ( # save in \1 ^ # start of line (with re.M) <(%s) # start tag = \2 \b # word break (.*\n)*? # any number of lines, minimally matching # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) """ % _block_tags_a, re.X | re.M) _block_tags_b = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math' _block_tags_b += _html5tags _liberal_tag_block_re = re.compile(r""" ( # save in \1 ^ # start of line (with re.M) <(%s) # start tag = \2 \b # word break (.*\n)*? # any number of lines, minimally matching .* # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) """ % _block_tags_b, re.X | re.M) _html_markdown_attr_re = re.compile( r'''\s+markdown=("1"|'1')''') def _hash_html_block_sub(self, match, raw=False): html = match.group(1) if raw and self.safe_mode: html = self._sanitize_html(html) elif 'markdown-in-html' in self.extras and 'markdown=' in html: first_line = html.split('\n', 1)[0] m = self._html_markdown_attr_re.search(first_line) if m: lines = html.split('\n') middle = '\n'.join(lines[1:-1]) last_line = lines[-1] first_line = first_line[:m.start()] + first_line[m.end():] f_key = _hash_text(first_line) self.html_blocks[f_key] = first_line l_key = _hash_text(last_line) self.html_blocks[l_key] = last_line return ''.join(["\n\n", f_key, "\n\n", middle, "\n\n", l_key, "\n\n"]) key = _hash_text(html) self.html_blocks[key] = html return "\n\n" + key + "\n\n" def _hash_html_blocks(self, text, raw=False): """Hashify HTML blocks We only want to do this for block-level HTML tags, such as headers, lists, and tables. That's because we still want to wrap

s around "paragraphs" that are wrapped in non-block-level tags, such as anchors, phrase emphasis, and spans. The list of tags we're looking for is hard-coded. @param raw {boolean} indicates if these are raw HTML blocks in the original source. It makes a difference in "safe" mode. """ if '<' not in text: return text # Pass `raw` value into our calls to self._hash_html_block_sub. hash_html_block_sub = _curry(self._hash_html_block_sub, raw=raw) # First, look for nested blocks, e.g.: #

#
# tags for inner block must be indented. #
#
# # The outermost tags must start at the left margin for this to match, and # the inner nested divs must be indented. # We need to do this before the next, more liberal match, because the next # match will start at the first `
` and stop at the first `
`. text = self._strict_tag_block_re.sub(hash_html_block_sub, text) # Now match more liberally, simply from `\n` to `\n` text = self._liberal_tag_block_re.sub(hash_html_block_sub, text) # Special case just for
. It was easier to make a special # case than to make the other regex more complicated. if "", start_idx) + 3 except ValueError: break # Start position for next comment block search. start = end_idx # Validate whitespace before comment. if start_idx: # - Up to `tab_width - 1` spaces before start_idx. for i in range(self.tab_width - 1): if text[start_idx - 1] != ' ': break start_idx -= 1 if start_idx == 0: break # - Must be preceded by 2 newlines or hit the start of # the document. if start_idx == 0: pass elif start_idx == 1 and text[0] == '\n': start_idx = 0 # to match minute detail of Markdown.pl regex elif text[start_idx-2:start_idx] == '\n\n': pass else: break # Validate whitespace after comment. # - Any number of spaces and tabs. while end_idx < len(text): if text[end_idx] not in ' \t': break end_idx += 1 # - Must be following by 2 newlines or hit end of text. if text[end_idx:end_idx+2] not in ('', '\n', '\n\n'): continue # Escape and hash (must match `_hash_html_block_sub`). html = text[start_idx:end_idx] if raw and self.safe_mode: html = self._sanitize_html(html) key = _hash_text(html) self.html_blocks[key] = html text = text[:start_idx] + "\n\n" + key + "\n\n" + text[end_idx:] if "xml" in self.extras: # Treat XML processing instructions and namespaced one-liner # tags as if they were block HTML tags. E.g., if standalone # (i.e. are their own paragraph), the following do not get # wrapped in a

tag: # # # _xml_oneliner_re = _xml_oneliner_re_from_tab_width(self.tab_width) text = _xml_oneliner_re.sub(hash_html_block_sub, text) return text def _strip_link_definitions(self, text): # Strips link definitions from text, stores the URLs and titles in # hash references. less_than_tab = self.tab_width - 1 # Link defs are in the form: # [id]: url "optional title" _link_def_re = re.compile(r""" ^[ ]{0,%d}\[(.+)\]: # id = \1 [ \t]* \n? # maybe *one* newline [ \t]* ? # url = \2 [ \t]* (?: \n? # maybe one newline [ \t]* (?<=\s) # lookbehind for whitespace ['"(] ([^\n]*) # title = \3 ['")] [ \t]* )? # title is optional (?:\n+|\Z) """ % less_than_tab, re.X | re.M | re.U) return _link_def_re.sub(self._extract_link_def_sub, text) def _extract_link_def_sub(self, match): id, url, title = match.groups() key = id.lower() # Link IDs are case-insensitive self.urls[key] = self._encode_amps_and_angles(url) if title: self.titles[key] = title return "" def _do_numbering(self, text): ''' We handle the special extension for generic numbering for tables, figures etc. ''' # First pass to define all the references self.regex_defns = re.compile(r''' \[\#(\w+) # the counter. Open square plus hash plus a word \1 ([^@]*) # Some optional characters, that aren't an @. \2 @(\w+) # the id. Should this be normed? \3 ([^\]]*)\] # The rest of the text up to the terminating ] \4 ''', re.VERBOSE) self.regex_subs = re.compile(r"\[@(\w+)\s*\]") # [@ref_id] counters = {} references = {} replacements = [] definition_html = '

{}{}{}
' reference_html = '
{}' for match in self.regex_defns.finditer(text): # We must have four match groups otherwise this isn't a numbering reference if len(match.groups()) != 4: continue counter = match.group(1) text_before = match.group(2).strip() ref_id = match.group(3) text_after = match.group(4) number = counters.get(counter, 1) references[ref_id] = (number, counter) replacements.append((match.start(0), definition_html.format(counter, ref_id, text_before, number, text_after), match.end(0))) counters[counter] = number + 1 for repl in reversed(replacements): text = text[:repl[0]] + repl[1] + text[repl[2]:] # Second pass to replace the references with the right # value of the counter # Fwiw, it's vaguely annoying to have to turn the iterator into # a list and then reverse it but I can't think of a better thing to do. for match in reversed(list(self.regex_subs.finditer(text))): number, counter = references.get(match.group(1), (None, None)) if number is not None: repl = reference_html.format(counter, match.group(1), number) else: repl = reference_html.format(match.group(1), 'countererror', '?' + match.group(1) + '?') if "smarty-pants" in self.extras: repl = repl.replace('"', self._escape_table['"']) text = text[:match.start()] + repl + text[match.end():] return text def _extract_footnote_def_sub(self, match): id, text = match.groups() text = _dedent(text, skip_first_line=not text.startswith('\n')).strip() normed_id = re.sub(r'\W', '-', id) # Ensure footnote text ends with a couple newlines (for some # block gamut matches). self.footnotes[normed_id] = text + "\n\n" return "" def _strip_footnote_definitions(self, text): """A footnote definition looks like this: [^note-id]: Text of the note. May include one or more indented paragraphs. Where, - The 'note-id' can be pretty much anything, though typically it is the number of the footnote. - The first paragraph may start on the next line, like so: [^note-id]: Text of the note. """ less_than_tab = self.tab_width - 1 footnote_def_re = re.compile(r''' ^[ ]{0,%d}\[\^(.+)\]: # id = \1 [ \t]* ( # footnote text = \2 # First line need not start with the spaces. (?:\s*.*\n+) (?: (?:[ ]{%d} | \t) # Subsequent lines must be indented. .*\n+ )* ) # Lookahead for non-space at line-start, or end of doc. (?:(?=^[ ]{0,%d}\S)|\Z) ''' % (less_than_tab, self.tab_width, self.tab_width), re.X | re.M) return footnote_def_re.sub(self._extract_footnote_def_sub, text) _hr_re = re.compile(r'^[ ]{0,3}([-_*][ ]{0,2}){3,}$', re.M) def _run_block_gamut(self, text): # These are all the transformations that form block-level # tags like paragraphs, headers, and list items. if "fenced-code-blocks" in self.extras: text = self._do_fenced_code_blocks(text) text = self._do_headers(text) # Do Horizontal Rules: # On the number of spaces in horizontal rules: The spec is fuzzy: "If # you wish, you may use spaces between the hyphens or asterisks." # Markdown.pl 1.0.1's hr regexes limit the number of spaces between the # hr chars to one or two. We'll reproduce that limit here. hr = "\n tags around block-level tags. text = self._hash_html_blocks(text) text = self._form_paragraphs(text) return text def _pyshell_block_sub(self, match): if "fenced-code-blocks" in self.extras: dedented = _dedent(match.group(0)) return self._do_fenced_code_blocks("```pycon\n" + dedented + "```\n") lines = match.group(0).splitlines(0) _dedentlines(lines) indent = ' ' * self.tab_width s = ('\n' # separate from possible cuddled paragraph + indent + ('\n'+indent).join(lines) + '\n\n') return s def _prepare_pyshell_blocks(self, text): """Ensure that Python interactive shell sessions are put in code blocks -- even if not properly indented. """ if ">>>" not in text: return text less_than_tab = self.tab_width - 1 _pyshell_block_re = re.compile(r""" ^([ ]{0,%d})>>>[ ].*\n # first line ^(\1.*\S+.*\n)* # any number of subsequent lines ^\n # ends with a blank line """ % less_than_tab, re.M | re.X) return _pyshell_block_re.sub(self._pyshell_block_sub, text) def _table_sub(self, match): trim_space_re = '^[ \t\n]+|[ \t\n]+$' trim_bar_re = r'^\||\|$' split_bar_re = r'^\||(?' % self._html_class_str_from_tag('table'), '
', ''] cols = [re.sub(escape_bar_re, '|', cell.strip()) for cell in re.split(split_bar_re, re.sub(trim_bar_re, "", re.sub(trim_space_re, "", head)))] for col_idx, col in enumerate(cols): hlines.append(' %s' % ( align_from_col_idx.get(col_idx, ''), self._run_span_gamut(col) )) hlines.append('') hlines.append('') # tbody hlines.append('') for line in body.strip('\n').split('\n'): hlines.append('') cols = [re.sub(escape_bar_re, '|', cell.strip()) for cell in re.split(split_bar_re, re.sub(trim_bar_re, "", re.sub(trim_space_re, "", line)))] for col_idx, col in enumerate(cols): hlines.append(' %s' % ( align_from_col_idx.get(col_idx, ''), self._run_span_gamut(col) )) hlines.append('') hlines.append('') hlines.append('
') return '\n'.join(hlines) + '\n' def _do_tables(self, text): """Copying PHP-Markdown and GFM table syntax. Some regex borrowed from https://github.com/michelf/php-markdown/blob/lib/Michelf/Markdown.php#L2538 """ less_than_tab = self.tab_width - 1 table_re = re.compile(r''' (?:(?<=\n\n)|\A\n?) # leading blank line ^[ ]{0,%d} # allowed whitespace (.*[|].*) \n # $1: header row (at least one pipe) ^[ ]{0,%d} # allowed whitespace ( # $2: underline row # underline row with leading bar (?: \|\ *:?-+:?\ * )+ \|? \s? \n | # or, underline row without leading bar (?: \ *:?-+:?\ *\| )+ (?: \ *:?-+:?\ * )? \s? \n ) ( # $3: data rows (?: ^[ ]{0,%d}(?!\ ) # ensure line begins with 0 to less_than_tab spaces .*\|.* \n )+ ) ''' % (less_than_tab, less_than_tab, less_than_tab), re.M | re.X) return table_re.sub(self._table_sub, text) def _wiki_table_sub(self, match): ttext = match.group(0).strip() # print('wiki table: %r' % match.group(0)) rows = [] for line in ttext.splitlines(0): line = line.strip()[2:-2].strip() row = [c.strip() for c in re.split(r'(?' % self._html_class_str_from_tag('table')) # Check if first cell of first row is a header cell. If so, assume the whole row is a header row. if rows and rows[0] and re.match(r"^\s*~", rows[0][0]): add_hline('', 1) add_hline('', 2) for cell in rows[0]: add_hline("{}".format(format_cell(cell)), 3) add_hline('', 2) add_hline('', 1) # Only one header row allowed. rows = rows[1:] # If no more rows, don't create a tbody. if rows: add_hline('', 1) for row in rows: add_hline('', 2) for cell in row: add_hline('{}'.format(format_cell(cell)), 3) add_hline('', 2) add_hline('', 1) add_hline('') return '\n'.join(hlines) + '\n' def _do_wiki_tables(self, text): # Optimization. if "||" not in text: return text less_than_tab = self.tab_width - 1 wiki_table_re = re.compile(r''' (?:(?<=\n\n)|\A\n?) # leading blank line ^([ ]{0,%d})\|\|.+?\|\|[ ]*\n # first line (^\1\|\|.+?\|\|\n)* # any number of subsequent lines ''' % less_than_tab, re.M | re.X) return wiki_table_re.sub(self._wiki_table_sub, text) def _run_span_gamut(self, text): # These are all the transformations that occur *within* block-level # tags like paragraphs, headers, and list items. text = self._do_code_spans(text) text = self._escape_special_chars(text) # Process anchor and image tags. if "link-patterns" in self.extras: text = self._do_link_patterns(text) text = self._do_links(text) # Make links out of things like `` # Must come after _do_links(), because you can use < and > # delimiters in inline links like [this](). text = self._do_auto_links(text) text = self._encode_amps_and_angles(text) if "strike" in self.extras: text = self._do_strike(text) if "underline" in self.extras: text = self._do_underline(text) text = self._do_italics_and_bold(text) if "smarty-pants" in self.extras: text = self._do_smart_punctuation(text) # Do hard breaks: if "break-on-newline" in self.extras: text = re.sub(r" *\n", " | # auto-link (e.g., ) <\w+[^>]*> | # comment | <\?.*?\?> # processing instruction ) """, re.X) def _escape_special_chars(self, text): # Python markdown note: the HTML tokenization here differs from # that in Markdown.pl, hence the behaviour for subtle cases can # differ (I believe the tokenizer here does a better job because # it isn't susceptible to unmatched '<' and '>' in HTML tags). # Note, however, that '>' is not allowed in an auto-link URL # here. escaped = [] is_html_markup = False for token in self._sorta_html_tokenize_re.split(text): if is_html_markup: # Within tags/HTML-comments/auto-links, encode * and _ # so they don't conflict with their use in Markdown for # italics and strong. We're replacing each such # character with its corresponding MD5 checksum value; # this is likely overkill, but it should prevent us from # colliding with the escape values by accident. escaped.append(token.replace('*', self._escape_table['*']) .replace('_', self._escape_table['_'])) else: escaped.append(self._encode_backslash_escapes(token)) is_html_markup = not is_html_markup return ''.join(escaped) def _hash_html_spans(self, text): # Used for safe_mode. def _is_auto_link(s): if ':' in s and self._auto_link_re.match(s): return True elif '@' in s and self._auto_email_link_re.match(s): return True return False tokens = [] is_html_markup = False for token in self._sorta_html_tokenize_re.split(text): if is_html_markup and not _is_auto_link(token): sanitized = self._sanitize_html(token) key = _hash_text(sanitized) self.html_spans[key] = sanitized tokens.append(key) else: tokens.append(self._encode_incomplete_tags(token)) is_html_markup = not is_html_markup return ''.join(tokens) def _unhash_html_spans(self, text): for key, sanitized in list(self.html_spans.items()): text = text.replace(key, sanitized) return text def _sanitize_html(self, s): if self.safe_mode == "replace": return self.html_removed_text elif self.safe_mode == "escape": replacements = [ ('&', '&'), ('<', '<'), ('>', '>'), ] for before, after in replacements: s = s.replace(before, after) return s else: raise MarkdownError("invalid value for 'safe_mode': %r (must be " "'escape' or 'replace')" % self.safe_mode) _inline_link_title = re.compile(r''' ( # \1 [ \t]+ (['"]) # quote char = \2 (?P.*?) \2 )? # title is optional \)$ ''', re.X | re.S) _tail_of_reference_link_re = re.compile(r''' # Match tail of: [text][id] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (?P<id>.*?) \] ''', re.X | re.S) _whitespace = re.compile(r'\s*') _strip_anglebrackets = re.compile(r'<(.*)>.*') def _find_non_whitespace(self, text, start): """Returns the index of the first non-whitespace character in text after (and including) start """ match = self._whitespace.match(text, start) return match.end() def _find_balanced(self, text, start, open_c, close_c): """Returns the index where the open_c and close_c characters balance out - the same number of open_c and close_c are encountered - or the end of string if it's reached before the balance point is found. """ i = start l = len(text) count = 1 while count > 0 and i < l: if text[i] == open_c: count += 1 elif text[i] == close_c: count -= 1 i += 1 return i def _extract_url_and_title(self, text, start): """Extracts the url and (optional) title from the tail of a link""" # text[start] equals the opening parenthesis idx = self._find_non_whitespace(text, start+1) if idx == len(text): return None, None, None end_idx = idx has_anglebrackets = text[idx] == "<" if has_anglebrackets: end_idx = self._find_balanced(text, end_idx+1, "<", ">") end_idx = self._find_balanced(text, end_idx, "(", ")") match = self._inline_link_title.search(text, idx, end_idx) if not match: return None, None, None url, title = text[idx:match.start()], match.group("title") if has_anglebrackets: url = self._strip_anglebrackets.sub(r'\1', url) return url, title, end_idx _safe_protocols = re.compile(r'(https?|ftp):', re.I) def _do_links(self, text): """Turn Markdown link shortcuts into XHTML <a> and <img> tags. This is a combination of Markdown.pl's _DoAnchors() and _DoImages(). They are done together because that simplified the approach. It was necessary to use a different approach than Markdown.pl because of the lack of atomic matching support in Python's regex engine used in $g_nested_brackets. """ MAX_LINK_TEXT_SENTINEL = 3000 # markdown2 issue 24 # `anchor_allowed_pos` is used to support img links inside # anchors, but not anchors inside anchors. An anchor's start # pos must be `>= anchor_allowed_pos`. anchor_allowed_pos = 0 curr_pos = 0 while True: # Handle the next link. # The next '[' is the start of: # - an inline anchor: [text](url "title") # - a reference anchor: [text][id] # - an inline img: ![text](url "title") # - a reference img: ![text][id] # - a footnote ref: [^id] # (Only if 'footnotes' extra enabled) # - a footnote defn: [^id]: ... # (Only if 'footnotes' extra enabled) These have already # been stripped in _strip_footnote_definitions() so no # need to watch for them. # - a link definition: [id]: url "title" # These have already been stripped in # _strip_link_definitions() so no need to watch for them. # - not markup: [...anything else... try: start_idx = text.index('[', curr_pos) except ValueError: break text_length = len(text) # Find the matching closing ']'. # Markdown.pl allows *matching* brackets in link text so we # will here too. Markdown.pl *doesn't* currently allow # matching brackets in img alt text -- we'll differ in that # regard. bracket_depth = 0 for p in range(start_idx+1, min(start_idx+MAX_LINK_TEXT_SENTINEL, text_length)): ch = text[p] if ch == ']': bracket_depth -= 1 if bracket_depth < 0: break elif ch == '[': bracket_depth += 1 else: # Closing bracket not found within sentinel length. # This isn't markup. curr_pos = start_idx + 1 continue link_text = text[start_idx+1:p] # Fix for issue 341 - Injecting XSS into link text if self.safe_mode: link_text = self._hash_html_spans(link_text) link_text = self._unhash_html_spans(link_text) # Possibly a footnote ref? if "footnotes" in self.extras and link_text.startswith("^"): normed_id = re.sub(r'\W', '-', link_text[1:]) if normed_id in self.footnotes: self.footnote_ids.append(normed_id) result = '<sup class="footnote-ref" id="fnref-%s">' \ '<a href="#fn-%s">%s</a></sup>' \ % (normed_id, normed_id, len(self.footnote_ids)) text = text[:start_idx] + result + text[p+1:] else: # This id isn't defined, leave the markup alone. curr_pos = p+1 continue # Now determine what this is by the remainder. p += 1 if p == text_length: return text # Inline anchor or img? if text[p] == '(': # attempt at perf improvement url, title, url_end_idx = self._extract_url_and_title(text, p) if url is not None: # Handle an inline anchor or img. is_img = start_idx > 0 and text[start_idx-1] == "!" if is_img: start_idx -= 1 # We've got to encode these to avoid conflicting # with italics/bold. url = url.replace('*', self._escape_table['*']) \ .replace('_', self._escape_table['_']) if title: title_str = ' title="%s"' % ( _xml_escape_attr(title) .replace('*', self._escape_table['*']) .replace('_', self._escape_table['_'])) else: title_str = '' if is_img: img_class_str = self._html_class_str_from_tag("img") result = '<img src="%s" alt="%s"%s%s%s' \ % (_html_escape_url(url, safe_mode=self.safe_mode), _xml_escape_attr(link_text), title_str, img_class_str, self.empty_element_suffix) if "smarty-pants" in self.extras: result = result.replace('"', self._escape_table['"']) curr_pos = start_idx + len(result) text = text[:start_idx] + result + text[url_end_idx:] elif start_idx >= anchor_allowed_pos: safe_link = self._safe_protocols.match(url) or url.startswith('#') if self.safe_mode and not safe_link: result_head = '<a href="#"%s>' % (title_str) else: result_head = '<a href="%s"%s>' % (_html_escape_url(url, safe_mode=self.safe_mode), title_str) result = '%s%s</a>' % (result_head, link_text) if "smarty-pants" in self.extras: result = result.replace('"', self._escape_table['"']) # <img> allowed from curr_pos on, <a> from # anchor_allowed_pos on. curr_pos = start_idx + len(result_head) anchor_allowed_pos = start_idx + len(result) text = text[:start_idx] + result + text[url_end_idx:] else: # Anchor not allowed here. curr_pos = start_idx + 1 continue # Reference anchor or img? else: match = self._tail_of_reference_link_re.match(text, p) if match: # Handle a reference-style anchor or img. is_img = start_idx > 0 and text[start_idx-1] == "!" if is_img: start_idx -= 1 link_id = match.group("id").lower() if not link_id: link_id = link_text.lower() # for links like [this][] if link_id in self.urls: url = self.urls[link_id] # We've got to encode these to avoid conflicting # with italics/bold. url = url.replace('*', self._escape_table['*']) \ .replace('_', self._escape_table['_']) title = self.titles.get(link_id) if title: title = _xml_escape_attr(title) \ .replace('*', self._escape_table['*']) \ .replace('_', self._escape_table['_']) title_str = ' title="%s"' % title else: title_str = '' if is_img: img_class_str = self._html_class_str_from_tag("img") result = '<img src="%s" alt="%s"%s%s%s' \ % (_html_escape_url(url, safe_mode=self.safe_mode), _xml_escape_attr(link_text), title_str, img_class_str, self.empty_element_suffix) if "smarty-pants" in self.extras: result = result.replace('"', self._escape_table['"']) curr_pos = start_idx + len(result) text = text[:start_idx] + result + text[match.end():] elif start_idx >= anchor_allowed_pos: if self.safe_mode and not self._safe_protocols.match(url): result_head = '<a href="#"%s>' % (title_str) else: result_head = '<a href="%s"%s>' % (_html_escape_url(url, safe_mode=self.safe_mode), title_str) result = '%s%s</a>' % (result_head, link_text) if "smarty-pants" in self.extras: result = result.replace('"', self._escape_table['"']) # <img> allowed from curr_pos on, <a> from # anchor_allowed_pos on. curr_pos = start_idx + len(result_head) anchor_allowed_pos = start_idx + len(result) text = text[:start_idx] + result + text[match.end():] else: # Anchor not allowed here. curr_pos = start_idx + 1 else: # This id isn't defined, leave the markup alone. curr_pos = match.end() continue # Otherwise, it isn't markup. curr_pos = start_idx + 1 return text def header_id_from_text(self, text, prefix, n): """Generate a header id attribute value from the given header HTML content. This is only called if the "header-ids" extra is enabled. Subclasses may override this for different header ids. @param text {str} The text of the header tag @param prefix {str} The requested prefix for header ids. This is the value of the "header-ids" extra key, if any. Otherwise, None. @param n {int} The <hN> tag number, i.e. `1` for an <h1> tag. @returns {str} The value for the header tag's "id" attribute. Return None to not have an id attribute and to exclude this header from the TOC (if the "toc" extra is specified). """ header_id = _slugify(text) if prefix and isinstance(prefix, base_string_type): header_id = prefix + '-' + header_id self._count_from_header_id[header_id] += 1 if 0 == len(header_id) or self._count_from_header_id[header_id] > 1: header_id += '-%s' % self._count_from_header_id[header_id] return header_id def _toc_add_entry(self, level, id, name): if level > self._toc_depth: return if self._toc is None: self._toc = [] self._toc.append((level, id, self._unescape_special_chars(name))) _h_re_base = r''' (^(.+)[ \t]{0,99}\n(=+|-+)[ \t]*\n+) | (^(\#{1,6}) # \1 = string of #'s [ \t]%s (.+?) # \2 = Header text [ \t]{0,99} (?<!\\) # ensure not an escaped trailing '#' \#* # optional closing #'s (not counted) \n+ ) ''' _h_re = re.compile(_h_re_base % '*', re.X | re.M) _h_re_tag_friendly = re.compile(_h_re_base % '+', re.X | re.M) def _h_sub(self, match): if match.group(1) is not None and match.group(3) == "-": return match.group(1) elif match.group(1) is not None: # Setext header n = {"=": 1, "-": 2}[match.group(3)[0]] header_group = match.group(2) else: # atx header n = len(match.group(5)) header_group = match.group(6) demote_headers = self.extras.get("demote-headers") if demote_headers: n = min(n + demote_headers, 6) header_id_attr = "" if "header-ids" in self.extras: header_id = self.header_id_from_text(header_group, self.extras["header-ids"], n) if header_id: header_id_attr = ' id="%s"' % header_id html = self._run_span_gamut(header_group) if "toc" in self.extras and header_id: self._toc_add_entry(n, header_id, html) return "<h%d%s>%s</h%d>\n\n" % (n, header_id_attr, html, n) def _do_headers(self, text): # Setext-style headers: # Header 1 # ======== # # Header 2 # -------- # atx-style headers: # # Header 1 # ## Header 2 # ## Header 2 with closing hashes ## # ... # ###### Header 6 if 'tag-friendly' in self.extras: return self._h_re_tag_friendly.sub(self._h_sub, text) return self._h_re.sub(self._h_sub, text) _marker_ul_chars = '*+-' _marker_any = r'(?:[%s]|\d+\.)' % _marker_ul_chars _marker_ul = '(?:[%s])' % _marker_ul_chars _marker_ol = r'(?:\d+\.)' def _list_sub(self, match): lst = match.group(1) lst_type = match.group(3) in self._marker_ul_chars and "ul" or "ol" result = self._process_list_items(lst) if self.list_level: return "<%s>\n%s</%s>\n" % (lst_type, result, lst_type) else: return "<%s>\n%s</%s>\n\n" % (lst_type, result, lst_type) def _do_lists(self, text): # Form HTML ordered (numbered) and unordered (bulleted) lists. # Iterate over each *non-overlapping* list match. pos = 0 while True: # Find the *first* hit for either list style (ul or ol). We # match ul and ol separately to avoid adjacent lists of different # types running into each other (see issue #16). hits = [] for marker_pat in (self._marker_ul, self._marker_ol): less_than_tab = self.tab_width - 1 whole_list = r''' ( # \1 = whole list ( # \2 [ ]{0,%d} (%s) # \3 = first list item marker [ \t]+ (?!\ *\3\ ) # '- - - ...' isn't a list. See 'not_quite_a_list' test case. ) (?:.+?) ( # \4 \Z | \n{2,} (?=\S) (?! # Negative lookahead for another list item marker [ \t]* %s[ \t]+ ) ) ) ''' % (less_than_tab, marker_pat, marker_pat) if self.list_level: # sub-list list_re = re.compile("^"+whole_list, re.X | re.M | re.S) else: list_re = re.compile(r"(?:(?<=\n\n)|\A\n?)"+whole_list, re.X | re.M | re.S) match = list_re.search(text, pos) if match: hits.append((match.start(), match)) if not hits: break hits.sort() match = hits[0][1] start, end = match.span() middle = self._list_sub(match) text = text[:start] + middle + text[end:] pos = start + len(middle) # start pos for next attempted match return text _list_item_re = re.compile(r''' (\n)? # leading line = \1 (^[ \t]*) # leading whitespace = \2 (?P<marker>%s) [ \t]+ # list marker = \3 ((?:.+?) # list item text = \4 (\n{1,2})) # eols = \5 (?= \n* (\Z | \2 (?P<next_marker>%s) [ \t]+)) ''' % (_marker_any, _marker_any), re.M | re.X | re.S) _task_list_item_re = re.compile(r''' (\[[\ xX]\])[ \t]+ # tasklist marker = \1 (.*) # list item text = \2 ''', re.M | re.X | re.S) _task_list_warpper_str = r'<input type="checkbox" class="task-list-item-checkbox" %sdisabled> %s' def _task_list_item_sub(self, match): marker = match.group(1) item_text = match.group(2) if marker in ['[x]','[X]']: return self._task_list_warpper_str % ('checked ', item_text) elif marker == '[ ]': return self._task_list_warpper_str % ('', item_text) _last_li_endswith_two_eols = False def _list_item_sub(self, match): item = match.group(4) leading_line = match.group(1) if leading_line or "\n\n" in item or self._last_li_endswith_two_eols: item = self._run_block_gamut(self._outdent(item)) else: # Recursion for sub-lists: item = self._do_lists(self._outdent(item)) if item.endswith('\n'): item = item[:-1] item = self._run_span_gamut(item) self._last_li_endswith_two_eols = (len(match.group(5)) == 2) if "task_list" in self.extras: item = self._task_list_item_re.sub(self._task_list_item_sub, item) return "<li>%s</li>\n" % item def _process_list_items(self, list_str): # Process the contents of a single ordered or unordered list, # splitting it into individual list items. # The $g_list_level global keeps track of when we're inside a list. # Each time we enter a list, we increment it; when we leave a list, # we decrement. If it's zero, we're not in a list anymore. # # We do this because when we're not inside a list, we want to treat # something like this: # # I recommend upgrading to version # 8. Oops, now this line is treated # as a sub-list. # # As a single paragraph, despite the fact that the second line starts # with a digit-period-space sequence. # # Whereas when we're inside a list (or sub-list), that line will be # treated as the start of a sub-list. What a kludge, huh? This is # an aspect of Markdown's syntax that's hard to parse perfectly # without resorting to mind-reading. Perhaps the solution is to # change the syntax rules such that sub-lists must start with a # starting cardinal number; e.g. "1." or "a.". self.list_level += 1 self._last_li_endswith_two_eols = False list_str = list_str.rstrip('\n') + '\n' list_str = self._list_item_re.sub(self._list_item_sub, list_str) self.list_level -= 1 return list_str def _get_pygments_lexer(self, lexer_name): try: from pygments import lexers, util except ImportError: return None try: return lexers.get_lexer_by_name(lexer_name) except util.ClassNotFound: return None def _color_with_pygments(self, codeblock, lexer, **formatter_opts): import pygments import pygments.formatters class HtmlCodeFormatter(pygments.formatters.HtmlFormatter): def _wrap_code(self, inner): """A function for use in a Pygments Formatter which wraps in <code> tags. """ yield 0, "<code>" for tup in inner: yield tup yield 0, "</code>" def wrap(self, source, outfile): """Return the source with a code, pre, and div.""" return self._wrap_div(self._wrap_pre(self._wrap_code(source))) formatter_opts.setdefault("cssclass", "codehilite") formatter = HtmlCodeFormatter(**formatter_opts) return pygments.highlight(codeblock, lexer, formatter) def _code_block_sub(self, match, is_fenced_code_block=False): lexer_name = None if is_fenced_code_block: lexer_name = match.group(1) if lexer_name: formatter_opts = self.extras['fenced-code-blocks'] or {} codeblock = match.group(2) codeblock = codeblock[:-1] # drop one trailing newline else: codeblock = match.group(1) codeblock = self._outdent(codeblock) codeblock = self._detab(codeblock) codeblock = codeblock.lstrip('\n') # trim leading newlines codeblock = codeblock.rstrip() # trim trailing whitespace # Note: "code-color" extra is DEPRECATED. if "code-color" in self.extras and codeblock.startswith(":::"): lexer_name, rest = codeblock.split('\n', 1) lexer_name = lexer_name[3:].strip() codeblock = rest.lstrip("\n") # Remove lexer declaration line. formatter_opts = self.extras['code-color'] or {} # Use pygments only if not using the highlightjs-lang extra if lexer_name and "highlightjs-lang" not in self.extras: def unhash_code(codeblock): for key, sanitized in list(self.html_spans.items()): codeblock = codeblock.replace(key, sanitized) replacements = [ ("&", "&"), ("<", "<"), (">", ">") ] for old, new in replacements: codeblock = codeblock.replace(old, new) return codeblock lexer = self._get_pygments_lexer(lexer_name) if lexer: codeblock = unhash_code( codeblock ) colored = self._color_with_pygments(codeblock, lexer, **formatter_opts) return "\n\n%s\n\n" % colored codeblock = self._encode_code(codeblock) pre_class_str = self._html_class_str_from_tag("pre") if "highlightjs-lang" in self.extras and lexer_name: code_class_str = ' class="%s language-%s"' % (lexer_name, lexer_name) else: code_class_str = self._html_class_str_from_tag("code") return "\n\n<pre%s><code%s>%s\n</code></pre>\n\n" % ( pre_class_str, code_class_str, codeblock) def _html_class_str_from_tag(self, tag): """Get the appropriate ' class="..."' string (note the leading space), if any, for the given tag. """ if "html-classes" not in self.extras: return "" try: html_classes_from_tag = self.extras["html-classes"] except TypeError: return "" else: if tag in html_classes_from_tag: return ' class="%s"' % html_classes_from_tag[tag] return "" def _do_code_blocks(self, text): """Process Markdown `<pre><code>` blocks.""" code_block_re = re.compile(r''' (?:\n\n|\A\n?) ( # $1 = the code block -- one or more lines, starting with a space/tab (?: (?:[ ]{%d} | \t) # Lines must start with a tab or a tab-width of spaces .*\n+ )+ ) ((?=^[ ]{0,%d}\S)|\Z) # Lookahead for non-space at line-start, or end of doc # Lookahead to make sure this block isn't already in a code block. # Needed when syntax highlighting is being used. (?![^<]*\</code\>) ''' % (self.tab_width, self.tab_width), re.M | re.X) return code_block_re.sub(self._code_block_sub, text) _fenced_code_block_re = re.compile(r''' (?:\n+|\A\n?) ^```\s{0,99}([\w+-]+)?\s{0,99}\n # opening fence, $1 = optional lang (.*?) # $2 = code block content ^```[ \t]*\n # closing fence ''', re.M | re.X | re.S) def _fenced_code_block_sub(self, match): return self._code_block_sub(match, is_fenced_code_block=True) def _do_fenced_code_blocks(self, text): """Process ```-fenced unindented code blocks ('fenced-code-blocks' extra).""" return self._fenced_code_block_re.sub(self._fenced_code_block_sub, text) # Rules for a code span: # - backslash escapes are not interpreted in a code span # - to include one or or a run of more backticks the delimiters must # be a longer run of backticks # - cannot start or end a code span with a backtick; pad with a # space and that space will be removed in the emitted HTML # See `test/tm-cases/escapes.text` for a number of edge-case # examples. _code_span_re = re.compile(r''' (?<!\\) (`+) # \1 = Opening run of ` (?!`) # See Note A test/tm-cases/escapes.text (.+?) # \2 = The code block (?<!`) \1 # Matching closer (?!`) ''', re.X | re.S) def _code_span_sub(self, match): c = match.group(2).strip(" \t") c = self._encode_code(c) return "<code>%s</code>" % c def _do_code_spans(self, text): # * Backtick quotes are used for <code></code> spans. # # * You can use multiple backticks as the delimiters if you want to # include literal backticks in the code span. So, this input: # # Just type ``foo `bar` baz`` at the prompt. # # Will translate to: # # <p>Just type <code>foo `bar` baz</code> at the prompt.</p> # # There's no arbitrary limit to the number of backticks you # can use as delimters. If you need three consecutive backticks # in your code, use four for delimiters, etc. # # * You can use spaces to get literal backticks at the edges: # # ... type `` `bar` `` ... # # Turns to: # # ... type <code>`bar`</code> ... return self._code_span_re.sub(self._code_span_sub, text) def _encode_code(self, text): """Encode/escape certain characters inside Markdown code runs. The point is that in code, these characters are literals, and lose their special Markdown meanings. """ replacements = [ # Encode all ampersands; HTML entities are not # entities within a Markdown code span. ('&', '&'), # Do the angle bracket song and dance: ('<', '<'), ('>', '>'), ] for before, after in replacements: text = text.replace(before, after) hashed = _hash_text(text) self._escape_table[text] = hashed return hashed _strike_re = re.compile(r"~~(?=\S)(.+?)(?<=\S)~~", re.S) def _do_strike(self, text): text = self._strike_re.sub(r"<strike>\1</strike>", text) return text _underline_re = re.compile(r"--(?=\S)(.+?)(?<=\S)--", re.S) def _do_underline(self, text): text = self._underline_re.sub(r"<u>\1</u>", text) return text _strong_re = re.compile(r"(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1", re.S) _em_re = re.compile(r"(\*|_)(?=\S)(.+?)(?<=\S)\1", re.S) _code_friendly_strong_re = re.compile(r"\*\*(?=\S)(.+?[*_]*)(?<=\S)\*\*", re.S) _code_friendly_em_re = re.compile(r"\*(?=\S)(.+?)(?<=\S)\*", re.S) def _do_italics_and_bold(self, text): # <strong> must go first: if "code-friendly" in self.extras: text = self._code_friendly_strong_re.sub(r"<strong>\1</strong>", text) text = self._code_friendly_em_re.sub(r"<em>\1</em>", text) else: text = self._strong_re.sub(r"<strong>\2</strong>", text) text = self._em_re.sub(r"<em>\2</em>", text) return text # "smarty-pants" extra: Very liberal in interpreting a single prime as an # apostrophe; e.g. ignores the fact that "round", "bout", "twer", and # "twixt" can be written without an initial apostrophe. This is fine because # using scare quotes (single quotation marks) is rare. _apostrophe_year_re = re.compile(r"'(\d\d)(?=(\s|,|;|\.|\?|!|$))") _contractions = ["tis", "twas", "twer", "neath", "o", "n", "round", "bout", "twixt", "nuff", "fraid", "sup"] def _do_smart_contractions(self, text): text = self._apostrophe_year_re.sub(r"’\1", text) for c in self._contractions: text = text.replace("'%s" % c, "’%s" % c) text = text.replace("'%s" % c.capitalize(), "’%s" % c.capitalize()) return text # Substitute double-quotes before single-quotes. _opening_single_quote_re = re.compile(r"(?<!\S)'(?=\S)") _opening_double_quote_re = re.compile(r'(?<!\S)"(?=\S)') _closing_single_quote_re = re.compile(r"(?<=\S)'") _closing_double_quote_re = re.compile(r'(?<=\S)"(?=(\s|,|;|\.|\?|!|$))') def _do_smart_punctuation(self, text): """Fancifies 'single quotes', "double quotes", and apostrophes. Converts --, ---, and ... into en dashes, em dashes, and ellipses. Inspiration is: <http://daringfireball.net/projects/smartypants/> See "test/tm-cases/smarty_pants.text" for a full discussion of the support here and <http://code.google.com/p/python-markdown2/issues/detail?id=42> for a discussion of some diversion from the original SmartyPants. """ if "'" in text: # guard for perf text = self._do_smart_contractions(text) text = self._opening_single_quote_re.sub("‘", text) text = self._closing_single_quote_re.sub("’", text) if '"' in text: # guard for perf text = self._opening_double_quote_re.sub("“", text) text = self._closing_double_quote_re.sub("”", text) text = text.replace("---", "—") text = text.replace("--", "–") text = text.replace("...", "…") text = text.replace(" . . . ", "…") text = text.replace(". . .", "…") # TODO: Temporary hack to fix https://github.com/trentm/python-markdown2/issues/150 if "footnotes" in self.extras and "footnote-ref" in text: # Quotes in the footnote back ref get converted to "smart" quotes # Change them back here to ensure they work. text = text.replace('class="footnote-ref”', 'class="footnote-ref"') return text _block_quote_base = r''' ( # Wrap whole match in \1 ( ^[ \t]*>%s[ \t]? # '>' at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines )+ ) ''' _block_quote_re = re.compile(_block_quote_base % '', re.M | re.X) _block_quote_re_spoiler = re.compile(_block_quote_base % '[ \t]*?!?', re.M | re.X) _bq_one_level_re = re.compile('^[ \t]*>[ \t]?', re.M) _bq_one_level_re_spoiler = re.compile('^[ \t]*>[ \t]*?![ \t]?', re.M) _bq_all_lines_spoilers = re.compile(r'\A(?:^[ \t]*>[ \t]*?!.*[\n\r]*)+\Z', re.M) _html_pre_block_re = re.compile(r'(\s*<pre>.+?</pre>)', re.S) def _dedent_two_spaces_sub(self, match): return re.sub(r'(?m)^ ', '', match.group(1)) def _block_quote_sub(self, match): bq = match.group(1) is_spoiler = 'spoiler' in self.extras and self._bq_all_lines_spoilers.match(bq) # trim one level of quoting if is_spoiler: bq = self._bq_one_level_re_spoiler.sub('', bq) else: bq = self._bq_one_level_re.sub('', bq) # trim whitespace-only lines bq = self._ws_only_line_re.sub('', bq) bq = self._run_block_gamut(bq) # recurse bq = re.sub('(?m)^', ' ', bq) # These leading spaces screw with <pre> content, so we need to fix that: bq = self._html_pre_block_re.sub(self._dedent_two_spaces_sub, bq) if is_spoiler: return '<blockquote class="spoiler">\n%s\n</blockquote>\n\n' % bq else: return '<blockquote>\n%s\n</blockquote>\n\n' % bq def _do_block_quotes(self, text): if '>' not in text: return text if 'spoiler' in self.extras: return self._block_quote_re_spoiler.sub(self._block_quote_sub, text) else: return self._block_quote_re.sub(self._block_quote_sub, text) def _form_paragraphs(self, text): # Strip leading and trailing lines: text = text.strip('\n') # Wrap <p> tags. grafs = [] for i, graf in enumerate(re.split(r"\n{2,}", text)): if graf in self.html_blocks: # Unhashify HTML blocks grafs.append(self.html_blocks[graf]) else: cuddled_list = None if "cuddled-lists" in self.extras: # Need to put back trailing '\n' for `_list_item_re` # match at the end of the paragraph. li = self._list_item_re.search(graf + '\n') # Two of the same list marker in this paragraph: a likely # candidate for a list cuddled to preceding paragraph # text (issue 33). Note the `[-1]` is a quick way to # consider numeric bullets (e.g. "1." and "2.") to be # equal. if (li and len(li.group(2)) <= 3 and ( (li.group("next_marker") and li.group("marker")[-1] == li.group("next_marker")[-1]) or li.group("next_marker") is None ) ): start = li.start() cuddled_list = self._do_lists(graf[start:]).rstrip("\n") assert cuddled_list.startswith("<ul>") or cuddled_list.startswith("<ol>") graf = graf[:start] # Wrap <p> tags. graf = self._run_span_gamut(graf) grafs.append("<p%s>" % self._html_class_str_from_tag('p') + graf.lstrip(" \t") + "</p>") if cuddled_list: grafs.append(cuddled_list) return "\n\n".join(grafs) def _add_footnotes(self, text): if self.footnotes: footer = [ '<div class="footnotes">', '<hr' + self.empty_element_suffix, '<ol>', ] if not self.footnote_title: self.footnote_title = "Jump back to footnote %d in the text." if not self.footnote_return_symbol: self.footnote_return_symbol = "↩" for i, id in enumerate(self.footnote_ids): if i != 0: footer.append('') footer.append('<li id="fn-%s">' % id) footer.append(self._run_block_gamut(self.footnotes[id])) try: backlink = ('<a href="#fnref-%s" ' + 'class="footnoteBackLink" ' + 'title="' + self.footnote_title + '">' + self.footnote_return_symbol + '</a>') % (id, i+1) except TypeError: log.debug("Footnote error. `footnote_title` " "must include parameter. Using defaults.") backlink = ('<a href="#fnref-%s" ' 'class="footnoteBackLink" ' 'title="Jump back to footnote %d in the text.">' '↩</a>' % (id, i+1)) if footer[-1].endswith("</p>"): footer[-1] = footer[-1][:-len("</p>")] \ + ' ' + backlink + "</p>" else: footer.append("\n<p>%s</p>" % backlink) footer.append('</li>') footer.append('</ol>') footer.append('</div>') return text + '\n\n' + '\n'.join(footer) else: return text _naked_lt_re = re.compile(r'<(?![a-z/?\$!])', re.I) _naked_gt_re = re.compile(r'''(?<![a-z0-9?!/'"-])>''', re.I) def _encode_amps_and_angles(self, text): # Smart processing for ampersands and angle brackets that need # to be encoded. text = _AMPERSAND_RE.sub('&', text) # Encode naked <'s text = self._naked_lt_re.sub('<', text) # Encode naked >'s # Note: Other markdown implementations (e.g. Markdown.pl, PHP # Markdown) don't do this. text = self._naked_gt_re.sub('>', text) return text _incomplete_tags_re = re.compile(r"<(/?\w+?(?!\w).+?[\s/]+?)") def _encode_incomplete_tags(self, text): if self.safe_mode not in ("replace", "escape"): return text if text.endswith(">"): return text # this is not an incomplete tag, this is a link in the form <http://x.y.z> return self._incomplete_tags_re.sub("<\\1", text) def _encode_backslash_escapes(self, text): for ch, escape in list(self._escape_table.items()): text = text.replace("\\"+ch, escape) return text _auto_link_re = re.compile(r'<((https?|ftp):[^\'">\s]+)>', re.I) def _auto_link_sub(self, match): g1 = match.group(1) return '<a href="%s">%s</a>' % (g1, g1) _auto_email_link_re = re.compile(r""" < (?:mailto:)? ( [-.\w]+ \@ [-\w]+(\.[-\w]+)*\.[a-z]+ ) > """, re.I | re.X | re.U) def _auto_email_link_sub(self, match): return self._encode_email_address( self._unescape_special_chars(match.group(1))) def _do_auto_links(self, text): text = self._auto_link_re.sub(self._auto_link_sub, text) text = self._auto_email_link_re.sub(self._auto_email_link_sub, text) return text def _encode_email_address(self, addr): # Input: an email address, e.g. "foo@example.com" # # Output: the email address as a mailto link, with each character # of the address encoded as either a decimal or hex entity, in # the hopes of foiling most address harvesting spam bots. E.g.: # # <a href="mailto:foo@e # xample.com">foo # @example.com</a> # # Based on a filter by Matthew Wickline, posted to the BBEdit-Talk # mailing list: <http://tinyurl.com/yu7ue> chars = [_xml_encode_email_char_at_random(ch) for ch in "mailto:" + addr] # Strip the mailto: from the visible part. addr = '<a href="%s">%s</a>' \ % (''.join(chars), ''.join(chars[7:])) return addr def _do_link_patterns(self, text): link_from_hash = {} for regex, repl in self.link_patterns: replacements = [] for match in regex.finditer(text): if hasattr(repl, "__call__"): href = repl(match) else: href = match.expand(repl) replacements.append((match.span(), href)) for (start, end), href in reversed(replacements): # Do not match against links inside brackets. if text[start - 1:start] == '[' and text[end:end + 1] == ']': continue # Do not match against links in the standard markdown syntax. if text[start - 2:start] == '](' or text[end:end + 2] == '")': continue # Do not match against links which are escaped. if text[start - 3:start] == '"""' and text[end:end + 3] == '"""': text = text[:start - 3] + text[start:end] + text[end + 3:] continue escaped_href = ( href.replace('"', '"') # b/c of attr quote # To avoid markdown <em> and <strong>: .replace('*', self._escape_table['*']) .replace('_', self._escape_table['_'])) link = '<a href="%s">%s</a>' % (escaped_href, text[start:end]) hash = _hash_text(link) link_from_hash[hash] = link text = text[:start] + hash + text[end:] for hash, link in list(link_from_hash.items()): text = text.replace(hash, link) return text def _unescape_special_chars(self, text): # Swap back in all the special characters we've hidden. for ch, hash in list(self._escape_table.items()): text = text.replace(hash, ch) return text def _outdent(self, text): # Remove one level of line-leading tabs or spaces return self._outdent_re.sub('', text) class MarkdownWithExtras(Markdown): """A markdowner class that enables most extras: - footnotes - code-color (only has effect if 'pygments' Python module on path) These are not included: - pyshell (specific to Python-related documenting) - code-friendly (because it *disables* part of the syntax) - link-patterns (because you need to specify some actual link-patterns anyway) """ extras = ["footnotes", "code-color"] # ---- internal support functions def calculate_toc_html(toc): """Return the HTML for the current TOC. This expects the `_toc` attribute to have been set on this instance. """ if toc is None: return None def indent(): return ' ' * (len(h_stack) - 1) lines = [] h_stack = [0] # stack of header-level numbers for level, id, name in toc: if level > h_stack[-1]: lines.append("%s<ul>" % indent()) h_stack.append(level) elif level == h_stack[-1]: lines[-1] += "</li>" else: while level < h_stack[-1]: h_stack.pop() if not lines[-1].endswith("</li>"): lines[-1] += "</li>" lines.append("%s</ul></li>" % indent()) lines.append('%s<li><a href="#%s">%s</a>' % ( indent(), id, name)) while len(h_stack) > 1: h_stack.pop() if not lines[-1].endswith("</li>"): lines[-1] += "</li>" lines.append("%s</ul>" % indent()) return '\n'.join(lines) + '\n' class UnicodeWithAttrs(unicode): """A subclass of unicode used for the return value of conversion to possibly attach some attributes. E.g. the "toc_html" attribute when the "toc" extra is used. """ metadata = None toc_html = None ## {{{ http://code.activestate.com/recipes/577257/ (r1) _slugify_strip_re = re.compile(r'[^\w\s-]') _slugify_hyphenate_re = re.compile(r'[-\s]+') def _slugify(value): """ Normalizes string, converts to lowercase, removes non-alpha characters, and converts spaces to hyphens. From Django's "django/template/defaultfilters.py". """ import unicodedata value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode() value = _slugify_strip_re.sub('', value).strip().lower() return _slugify_hyphenate_re.sub('-', value) ## end of http://code.activestate.com/recipes/577257/ }}} # From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 def _curry(*args, **kwargs): function, args = args[0], args[1:] def result(*rest, **kwrest): combined = kwargs.copy() combined.update(kwrest) return function(*args + rest, **combined) return result # Recipe: regex_from_encoded_pattern (1.0) def _regex_from_encoded_pattern(s): """'foo' -> re.compile(re.escape('foo')) '/foo/' -> re.compile('foo') '/foo/i' -> re.compile('foo', re.I) """ if s.startswith('/') and s.rfind('/') != 0: # Parse it: /PATTERN/FLAGS idx = s.rfind('/') _, flags_str = s[1:idx], s[idx+1:] flag_from_char = { "i": re.IGNORECASE, "l": re.LOCALE, "s": re.DOTALL, "m": re.MULTILINE, "u": re.UNICODE, } flags = 0 for char in flags_str: try: flags |= flag_from_char[char] except KeyError: raise ValueError("unsupported regex flag: '%s' in '%s' " "(must be one of '%s')" % (char, s, ''.join(list(flag_from_char.keys())))) return re.compile(s[1:idx], flags) else: # not an encoded regex return re.compile(re.escape(s)) # Recipe: dedent (0.1.2) def _dedentlines(lines, tabsize=8, skip_first_line=False): """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines "lines" is a list of lines to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. Same as dedent() except operates on a sequence of lines. Note: the lines list is modified **in-place**. """ DEBUG = False if DEBUG: print("dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\ % (tabsize, skip_first_line)) margin = None for i, line in enumerate(lines): if i == 0 and skip_first_line: continue indent = 0 for ch in line: if ch == ' ': indent += 1 elif ch == '\t': indent += tabsize - (indent % tabsize) elif ch in '\r\n': continue # skip all-whitespace lines else: break else: continue # skip all-whitespace lines if DEBUG: print("dedent: indent=%d: %r" % (indent, line)) if margin is None: margin = indent else: margin = min(margin, indent) if DEBUG: print("dedent: margin=%r" % margin) if margin is not None and margin > 0: for i, line in enumerate(lines): if i == 0 and skip_first_line: continue removed = 0 for j, ch in enumerate(line): if ch == ' ': removed += 1 elif ch == '\t': removed += tabsize - (removed % tabsize) elif ch in '\r\n': if DEBUG: print("dedent: %r: EOL -> strip up to EOL" % line) lines[i] = lines[i][j:] break else: raise ValueError("unexpected non-whitespace char %r in " "line %r while removing %d-space margin" % (ch, line, margin)) if DEBUG: print("dedent: %r: %r -> removed %d/%d"\ % (line, ch, removed, margin)) if removed == margin: lines[i] = lines[i][j+1:] break elif removed > margin: lines[i] = ' '*(removed-margin) + lines[i][j+1:] break else: if removed: lines[i] = lines[i][removed:] return lines def _dedent(text, tabsize=8, skip_first_line=False): """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text "text" is the text to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. textwrap.dedent(s), but don't expand tabs to spaces """ lines = text.splitlines(1) _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line) return ''.join(lines) class _memoized(object): """Decorator that caches a function's return value each time it is called. If called later with the same arguments, the cached value is returned, and not re-evaluated. http://wiki.python.org/moin/PythonDecoratorLibrary """ def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args): try: return self.cache[args] except KeyError: self.cache[args] = value = self.func(*args) return value except TypeError: # uncachable -- for instance, passing a list as an argument. # Better to not cache than to blow up entirely. return self.func(*args) def __repr__(self): """Return the function's docstring.""" return self.func.__doc__ def _xml_oneliner_re_from_tab_width(tab_width): """Standalone XML processing instruction regex.""" return re.compile(r""" (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 [ ]{0,%d} (?: <\?\w+\b\s+.*?\?> # XML processing instruction | <\w+:\w+\b\s+.*?/> # namespaced single tag ) [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) """ % (tab_width - 1), re.X) _xml_oneliner_re_from_tab_width = _memoized(_xml_oneliner_re_from_tab_width) def _hr_tag_re_from_tab_width(tab_width): return re.compile(r""" (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in \1 [ ]{0,%d} <(hr) # start tag = \2 \b # word break ([^<>])*? # /?> # the matching end tag [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) """ % (tab_width - 1), re.X) _hr_tag_re_from_tab_width = _memoized(_hr_tag_re_from_tab_width) def _xml_escape_attr(attr, skip_single_quote=True): """Escape the given string for use in an HTML/XML tag attribute. By default this doesn't bother with escaping `'` to `'`, presuming that the tag attribute is surrounded by double quotes. """ escaped = _AMPERSAND_RE.sub('&', attr) escaped = (attr .replace('"', '"') .replace('<', '<') .replace('>', '>')) if not skip_single_quote: escaped = escaped.replace("'", "'") return escaped def _xml_encode_email_char_at_random(ch): r = random() # Roughly 10% raw, 45% hex, 45% dec. # '@' *must* be encoded. I [John Gruber] insist. # Issue 26: '_' must be encoded. if r > 0.9 and ch not in "@_": return ch elif r < 0.45: # The [1:] is to drop leading '0': 0x63 -> x63 return '&#%s;' % hex(ord(ch))[1:] else: return '&#%s;' % ord(ch) def _html_escape_url(attr, safe_mode=False): """Replace special characters that are potentially malicious in url string.""" escaped = (attr .replace('"', '"') .replace('<', '<') .replace('>', '>')) if safe_mode: escaped = escaped.replace('+', ' ') escaped = escaped.replace("'", "'") return escaped # ---- mainline class _NoReflowFormatter(optparse.IndentedHelpFormatter): """An optparse formatter that does NOT reflow the description.""" def format_description(self, description): return description or "" def _test(): import doctest doctest.testmod() def main(argv=None): if argv is None: argv = sys.argv if not logging.root.handlers: logging.basicConfig() usage = "usage: %prog [PATHS...]" version = "%prog "+__version__ parser = optparse.OptionParser(prog="markdown2", usage=usage, version=version, description=cmdln_desc, formatter=_NoReflowFormatter()) parser.add_option("-v", "--verbose", dest="log_level", action="store_const", const=logging.DEBUG, help="more verbose output") parser.add_option("--encoding", help="specify encoding of text content") parser.add_option("--html4tags", action="store_true", default=False, help="use HTML 4 style for empty element tags") parser.add_option("-s", "--safe", metavar="MODE", dest="safe_mode", help="sanitize literal HTML: 'escape' escapes " "HTML meta chars, 'replace' replaces with an " "[HTML_REMOVED] note") parser.add_option("-x", "--extras", action="append", help="Turn on specific extra features (not part of " "the core Markdown spec). See above.") parser.add_option("--use-file-vars", help="Look for and use Emacs-style 'markdown-extras' " "file var to turn on extras. See " "<https://github.com/trentm/python-markdown2/wiki/Extras>") parser.add_option("--link-patterns-file", help="path to a link pattern file") parser.add_option("--self-test", action="store_true", help="run internal self-tests (some doctests)") parser.add_option("--compare", action="store_true", help="run against Markdown.pl as well (for testing)") parser.set_defaults(log_level=logging.INFO, compare=False, encoding="utf-8", safe_mode=None, use_file_vars=False) opts, paths = parser.parse_args() log.setLevel(opts.log_level) if opts.self_test: return _test() if opts.extras: extras = {} for s in opts.extras: splitter = re.compile("[,;: ]+") for e in splitter.split(s): if '=' in e: ename, earg = e.split('=', 1) try: earg = int(earg) except ValueError: pass else: ename, earg = e, None extras[ename] = earg else: extras = None if opts.link_patterns_file: link_patterns = [] f = open(opts.link_patterns_file) try: for i, line in enumerate(f.readlines()): if not line.strip(): continue if line.lstrip().startswith("#"): continue try: pat, href = line.rstrip().rsplit(None, 1) except ValueError: raise MarkdownError("%s:%d: invalid link pattern line: %r" % (opts.link_patterns_file, i+1, line)) link_patterns.append( (_regex_from_encoded_pattern(pat), href)) finally: f.close() else: link_patterns = None from os.path import join, dirname, abspath, exists markdown_pl = join(dirname(dirname(abspath(__file__))), "test", "Markdown.pl") if not paths: paths = ['-'] for path in paths: if path == '-': text = sys.stdin.read() else: fp = codecs.open(path, 'r', opts.encoding) text = fp.read() fp.close() if opts.compare: from subprocess import Popen, PIPE print("==== Markdown.pl ====") p = Popen('perl %s' % markdown_pl, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True) p.stdin.write(text.encode('utf-8')) p.stdin.close() perl_html = p.stdout.read().decode('utf-8') if py3: sys.stdout.write(perl_html) else: sys.stdout.write(perl_html.encode( sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) print("==== markdown2.py ====") html = markdown(text, html4tags=opts.html4tags, safe_mode=opts.safe_mode, extras=extras, link_patterns=link_patterns, use_file_vars=opts.use_file_vars, cli=True) if py3: sys.stdout.write(html) else: sys.stdout.write(html.encode( sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) if extras and "toc" in extras: log.debug("toc_html: " + str(html.toc_html.encode(sys.stdout.encoding or "utf-8", 'xmlcharrefreplace'))) if opts.compare: test_dir = join(dirname(dirname(abspath(__file__))), "test") if exists(join(test_dir, "test_markdown2.py")): sys.path.insert(0, test_dir) from test_markdown2 import norm_html_from_html norm_html = norm_html_from_html(html) norm_perl_html = norm_html_from_html(perl_html) else: norm_html = html norm_perl_html = perl_html print("==== match? %r ====" % (norm_perl_html == norm_html)) if __name__ == "__main__": sys.exit(main(sys.argv)) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0015677�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/Markdown.pm�������������������������������������������������������������0000664�0000000�0000000�00000075262�14107073154�0020033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl # # Markdown -- A text-to-HTML conversion tool for web writers # # Copyright (c) 2004 John Gruber # <http://daringfireball.net/projects/markdown/> # package Markdown; require 5.006_000; use strict; use warnings; use Digest::MD5 qw(md5_hex); use vars qw($VERSION); $VERSION = '1.0.1'; # Tue 14 Dec 2004 ## Disabled; causes problems under Perl 5.6.1: # use utf8; # binmode( STDOUT, ":utf8" ); # c.f.: http://acis.openlib.org/dev/perl-unicode-struggle.html # # Global default settings: # my $g_empty_element_suffix = " />"; # Change to ">" for HTML output my $g_tab_width = 4; # # Globals: # # Regex to match balanced [brackets]. See Friedl's # "Mastering Regular Expressions", 2nd Ed., pp. 328-331. my $g_nested_brackets; $g_nested_brackets = qr{ (?> # Atomic matching [^\[\]]+ # Anything other than brackets | \[ (??{ $g_nested_brackets }) # Recursive set of nested brackets \] )* }x; # Table of hash values for escaped characters: my %g_escape_table; foreach my $char (split //, '\\`*_{}[]()>#+-.!') { $g_escape_table{$char} = md5_hex($char); } # Global hashes, used by various utility routines my %g_urls; my %g_titles; my %g_html_blocks; # Used to track when we're inside an ordered or unordered list # (see _ProcessListItems() for details): my $g_list_level = 0; sub Markdown { # # Main function. The order in which other subs are called here is # essential. Link and image substitutions need to happen before # _EscapeSpecialChars(), so that any *'s or _'s in the <a> # and <img> tags get encoded. # my $text = shift; # Clear the global hashes. If we don't clear these, you get conflicts # from other articles when generating a page which contains more than # one article (e.g. an index page that shows the N most recent # articles): %g_urls = (); %g_titles = (); %g_html_blocks = (); # Standardize line endings: $text =~ s{\r\n}{\n}g; # DOS to Unix $text =~ s{\r}{\n}g; # Mac to Unix # Make sure $text ends with a couple of newlines: $text .= "\n\n"; # Convert all tabs to spaces. $text = _Detab($text); # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ \t]*\n+/ . $text =~ s/^[ \t]+$//mg; # Turn block-level HTML blocks into hash entries $text = _HashHTMLBlocks($text); # Strip link definitions, store in hashes. $text = _StripLinkDefinitions($text); $text = _RunBlockGamut($text); $text = _UnescapeSpecialChars($text); return $text . "\n"; } sub _StripLinkDefinitions { # # Strips link definitions from text, stores the URLs and titles in # hash references. # my $text = shift; my $less_than_tab = $g_tab_width - 1; # Link defs are in the form: ^[id]: url "optional title" while ($text =~ s{ ^[ ]{0,$less_than_tab}\[(.+)\]: # id = $1 [ \t]* \n? # maybe *one* newline [ \t]* <?(\S+?)>? # url = $2 [ \t]* \n? # maybe one newline [ \t]* (?: (?<=\s) # lookbehind for whitespace ["(] (.+?) # title = $3 [")] [ \t]* )? # title is optional (?:\n+|\Z) } {}mx) { $g_urls{lc $1} = _EncodeAmpsAndAngles( $2 ); # Link IDs are case-insensitive if ($3) { $g_titles{lc $1} = $3; $g_titles{lc $1} =~ s/"/"/g; } } return $text; } sub _HashHTMLBlocks { my $text = shift; my $less_than_tab = $g_tab_width - 1; # Hashify HTML blocks: # We only want to do this for block-level HTML tags, such as headers, # lists, and tables. That's because we still want to wrap <p>s around # "paragraphs" that are wrapped in non-block-level tags, such as anchors, # phrase emphasis, and spans. The list of tags we're looking for is # hard-coded: my $block_tags_a = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del/; my $block_tags_b = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math/; # First, look for nested blocks, e.g.: # <div> # <div> # tags for inner block must be indented. # </div> # </div> # # The outermost tags must start at the left margin for this to match, and # the inner nested divs must be indented. # We need to do this before the next, more liberal match, because the next # match will start at the first `<div>` and stop at the first `</div>`. $text =~ s{ ( # save in $1 ^ # start of line (with /m) <($block_tags_a) # start tag = $2 \b # word break (.*\n)*? # any number of lines, minimally matching </\2> # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egmx; # # Now match more liberally, simply from `\n<tag>` to `</tag>\n` # $text =~ s{ ( # save in $1 ^ # start of line (with /m) <($block_tags_b) # start tag = $2 \b # word break (.*\n)*? # any number of lines, minimally matching .*</\2> # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egmx; # Special case just for <hr />. It was easier to make a special case than # to make the other regex more complicated. $text =~ s{ (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 [ ]{0,$less_than_tab} <(hr) # start tag = $2 \b # word break ([^<>])*? # /?> # the matching end tag [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egx; # Special case for standalone HTML comments: $text =~ s{ (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 [ ]{0,$less_than_tab} (?s: <! (--.*?--\s*)+ > ) [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egx; return $text; } sub _RunBlockGamut { # # These are all the transformations that form block-level # tags like paragraphs, headers, and list items. # my $text = shift; $text = _DoHeaders($text); # Do Horizontal Rules: $text =~ s{^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text =~ s{^[ ]{0,2}([ ]? -[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text =~ s{^[ ]{0,2}([ ]? _[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text = _DoLists($text); $text = _DoCodeBlocks($text); $text = _DoBlockQuotes($text); # We already ran _HashHTMLBlocks() before, in Markdown(), but that # was to escape raw HTML in the original Markdown source. This time, # we're escaping the markup we've just created, so that we don't wrap # <p> tags around block-level tags. $text = _HashHTMLBlocks($text); $text = _FormParagraphs($text); return $text; } sub _RunSpanGamut { # # These are all the transformations that occur *within* block-level # tags like paragraphs, headers, and list items. # my $text = shift; $text = _DoCodeSpans($text); $text = _EscapeSpecialChars($text); # Process anchor and image tags. Images must come first, # because ![foo][f] looks like an anchor. $text = _DoImages($text); $text = _DoAnchors($text); # Make links out of things like `<http://example.com/>` # Must come after _DoAnchors(), because you can use < and > # delimiters in inline links like [this](<url>). $text = _DoAutoLinks($text); $text = _EncodeAmpsAndAngles($text); $text = _DoItalicsAndBold($text); # Do hard breaks: $text =~ s/ {2,}\n/ <br$g_empty_element_suffix\n/g; return $text; } sub _EscapeSpecialChars { my $text = shift; my $tokens ||= _TokenizeHTML($text); $text = ''; # rebuild $text from the tokens # my $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags. # my $tags_to_skip = qr!<(/?)(?:pre|code|kbd|script|math)[\s>]!; foreach my $cur_token (@$tokens) { if ($cur_token->[0] eq "tag") { # Within tags, encode * and _ so they don't conflict # with their use in Markdown for italics and strong. # We're replacing each such character with its # corresponding MD5 checksum value; this is likely # overkill, but it should prevent us from colliding # with the escape values by accident. $cur_token->[1] =~ s! \* !$g_escape_table{'*'}!gx; $cur_token->[1] =~ s! _ !$g_escape_table{'_'}!gx; $text .= $cur_token->[1]; } else { my $t = $cur_token->[1]; $t = _EncodeBackslashEscapes($t); $text .= $t; } } return $text; } sub _DoAnchors { # # Turn Markdown link shortcuts into XHTML <a> tags. # my $text = shift; # # First, handle reference-style links: [link text] [id] # $text =~ s{ ( # wrap whole match in $1 \[ ($g_nested_brackets) # link text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }{ my $result; my $whole_match = $1; my $link_text = $2; my $link_id = lc $3; if ($link_id eq "") { $link_id = lc $link_text; # for shortcut links like [this][]. } if (defined $g_urls{$link_id}) { my $url = $g_urls{$link_id}; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<a href=\"$url\""; if ( defined $g_titles{$link_id} ) { my $title = $g_titles{$link_id}; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= ">$link_text</a>"; } else { $result = $whole_match; } $result; }xsge; # # Next, inline-style links: [link text](url "optional title") # $text =~ s{ ( # wrap whole match in $1 \[ ($g_nested_brackets) # link text = $2 \] \( # literal paren [ \t]* <?(.*?)>? # href = $3 [ \t]* ( # $4 (['"]) # quote char = $5 (.*?) # Title = $6 \5 # matching quote )? # title is optional \) ) }{ my $result; my $whole_match = $1; my $link_text = $2; my $url = $3; my $title = $6; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<a href=\"$url\""; if (defined $title) { $title =~ s/"/"/g; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= ">$link_text</a>"; $result; }xsge; return $text; } sub _DoImages { # # Turn Markdown image shortcuts into <img> tags. # my $text = shift; # # First, handle reference-style labeled images: ![alt text][id] # $text =~ s{ ( # wrap whole match in $1 !\[ (.*?) # alt text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }{ my $result; my $whole_match = $1; my $alt_text = $2; my $link_id = lc $3; if ($link_id eq "") { $link_id = lc $alt_text; # for shortcut links like ![this][]. } $alt_text =~ s/"/"/g; if (defined $g_urls{$link_id}) { my $url = $g_urls{$link_id}; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<img src=\"$url\" alt=\"$alt_text\""; if (defined $g_titles{$link_id}) { my $title = $g_titles{$link_id}; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= $g_empty_element_suffix; } else { # If there's no such link ID, leave intact: $result = $whole_match; } $result; }xsge; # # Next, handle inline images: ![alt text](url "optional title") # Don't forget: encode * and _ $text =~ s{ ( # wrap whole match in $1 !\[ (.*?) # alt text = $2 \] \( # literal paren [ \t]* <?(\S+?)>? # src url = $3 [ \t]* ( # $4 (['"]) # quote char = $5 (.*?) # title = $6 \5 # matching quote [ \t]* )? # title is optional \) ) }{ my $result; my $whole_match = $1; my $alt_text = $2; my $url = $3; my $title = ''; if (defined($6)) { $title = $6; } $alt_text =~ s/"/"/g; $title =~ s/"/"/g; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<img src=\"$url\" alt=\"$alt_text\""; if (defined $title) { $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= $g_empty_element_suffix; $result; }xsge; return $text; } sub _DoHeaders { my $text = shift; # Setext-style headers: # Header 1 # ======== # # Header 2 # -------- # $text =~ s{ ^(.+)[ \t]*\n=+[ \t]*\n+ }{ "<h1>" . _RunSpanGamut($1) . "</h1>\n\n"; }egmx; $text =~ s{ ^(.+)[ \t]*\n-+[ \t]*\n+ }{ "<h2>" . _RunSpanGamut($1) . "</h2>\n\n"; }egmx; # atx-style headers: # # Header 1 # ## Header 2 # ## Header 2 with closing hashes ## # ... # ###### Header 6 # $text =~ s{ ^(\#{1,6}) # $1 = string of #'s [ \t]* (.+?) # $2 = Header text [ \t]* \#* # optional closing #'s (not counted) \n+ }{ my $h_level = length($1); "<h$h_level>" . _RunSpanGamut($2) . "</h$h_level>\n\n"; }egmx; return $text; } sub _DoLists { # # Form HTML ordered (numbered) and unordered (bulleted) lists. # my $text = shift; my $less_than_tab = $g_tab_width - 1; # Re-usable patterns to match list item bullets and number markers: my $marker_ul = qr/[*+-]/; my $marker_ol = qr/\d+[.]/; my $marker_any = qr/(?:$marker_ul|$marker_ol)/; # Re-usable pattern to match any entirel ul or ol list: my $whole_list = qr{ ( # $1 = whole list ( # $2 [ ]{0,$less_than_tab} (${marker_any}) # $3 = first list item marker [ \t]+ ) (?s:.+?) ( # $4 \z | \n{2,} (?=\S) (?! # Negative lookahead for another list item marker [ \t]* ${marker_any}[ \t]+ ) ) ) }mx; # We use a different prefix before nested lists than top-level lists. # See extended comment in _ProcessListItems(). # # Note: There's a bit of duplication here. My original implementation # created a scalar regex pattern as the conditional result of the test on # $g_list_level, and then only ran the $text =~ s{...}{...}egmx # substitution once, using the scalar as the pattern. This worked, # everywhere except when running under MT on my hosting account at Pair # Networks. There, this caused all rebuilds to be killed by the reaper (or # perhaps they crashed, but that seems incredibly unlikely given that the # same script on the same server ran fine *except* under MT. I've spent # more time trying to figure out why this is happening than I'd like to # admit. My only guess, backed up by the fact that this workaround works, # is that Perl optimizes the substition when it can figure out that the # pattern will never change, and when this optimization isn't on, we run # afoul of the reaper. Thus, the slightly redundant code to that uses two # static s/// patterns rather than one conditional pattern. if ($g_list_level) { $text =~ s{ ^ $whole_list }{ my $list = $1; my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: $list =~ s/\n{2,}/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "</$list_type>\n"; $result; }egmx; } else { $text =~ s{ (?:(?<=\n\n)|\A\n?) $whole_list }{ my $list = $1; my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: $list =~ s/\n{2,}/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "</$list_type>\n"; $result; }egmx; } return $text; } sub _ProcessListItems { # # Process the contents of a single ordered or unordered list, splitting it # into individual list items. # my $list_str = shift; my $marker_any = shift; # The $g_list_level global keeps track of when we're inside a list. # Each time we enter a list, we increment it; when we leave a list, # we decrement. If it's zero, we're not in a list anymore. # # We do this because when we're not inside a list, we want to treat # something like this: # # I recommend upgrading to version # 8. Oops, now this line is treated # as a sub-list. # # As a single paragraph, despite the fact that the second line starts # with a digit-period-space sequence. # # Whereas when we're inside a list (or sub-list), that line will be # treated as the start of a sub-list. What a kludge, huh? This is # an aspect of Markdown's syntax that's hard to parse perfectly # without resorting to mind-reading. Perhaps the solution is to # change the syntax rules such that sub-lists must start with a # starting cardinal number; e.g. "1." or "a.". $g_list_level++; # trim trailing blank lines: $list_str =~ s/\n{2,}\z/\n/; $list_str =~ s{ (\n)? # leading line = $1 (^[ \t]*) # leading whitespace = $2 ($marker_any) [ \t]+ # list marker = $3 ((?s:.+?) # list item text = $4 (\n{1,2})) (?= \n* (\z | \2 ($marker_any) [ \t]+)) }{ my $item = $4; my $leading_line = $1; my $leading_space = $2; if ($leading_line or ($item =~ m/\n{2,}/)) { $item = _RunBlockGamut(_Outdent($item)); } else { # Recursion for sub-lists: $item = _DoLists(_Outdent($item)); chomp $item; $item = _RunSpanGamut($item); } "<li>" . $item . "</li>\n"; }egmx; $g_list_level--; return $list_str; } sub _DoCodeBlocks { # # Process Markdown `<pre><code>` blocks. # my $text = shift; $text =~ s{ (?:\n\n|\A) ( # $1 = the code block -- one or more lines, starting with a space/tab (?: (?:[ ]{$g_tab_width} | \t) # Lines must start with a tab or a tab-width of spaces .*\n+ )+ ) ((?=^[ ]{0,$g_tab_width}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }{ my $codeblock = $1; my $result; # return value $codeblock = _EncodeCode(_Outdent($codeblock)); $codeblock = _Detab($codeblock); $codeblock =~ s/\A\n+//; # trim leading newlines $codeblock =~ s/\s+\z//; # trim trailing whitespace $result = "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n"; $result; }egmx; return $text; } sub _DoCodeSpans { # # * Backtick quotes are used for <code></code> spans. # # * You can use multiple backticks as the delimiters if you want to # include literal backticks in the code span. So, this input: # # Just type ``foo `bar` baz`` at the prompt. # # Will translate to: # # <p>Just type <code>foo `bar` baz</code> at the prompt.</p> # # There's no arbitrary limit to the number of backticks you # can use as delimters. If you need three consecutive backticks # in your code, use four for delimiters, etc. # # * You can use spaces to get literal backticks at the edges: # # ... type `` `bar` `` ... # # Turns to: # # ... type <code>`bar`</code> ... # my $text = shift; $text =~ s@ (`+) # $1 = Opening run of ` (.+?) # $2 = The code block (?<!`) \1 # Matching closer (?!`) @ my $c = "$2"; $c =~ s/^[ \t]*//g; # leading whitespace $c =~ s/[ \t]*$//g; # trailing whitespace $c = _EncodeCode($c); "<code>$c</code>"; @egsx; return $text; } sub _EncodeCode { # # Encode/escape certain characters inside Markdown code runs. # The point is that in code, these characters are literals, # and lose their special Markdown meanings. # local $_ = shift; # Encode all ampersands; HTML entities are not # entities within a Markdown code span. s/&/&/g; # Encode $'s, but only if we're running under Blosxom. # (Blosxom interpolates Perl variables in article bodies.) { no warnings 'once'; if (defined($blosxom::version)) { s/\$/$/g; } } # Do the angle bracket song and dance: s! < !<!gx; s! > !>!gx; # Now, escape characters that are magic in Markdown: s! \* !$g_escape_table{'*'}!gx; s! _ !$g_escape_table{'_'}!gx; s! { !$g_escape_table{'{'}!gx; s! } !$g_escape_table{'}'}!gx; s! \[ !$g_escape_table{'['}!gx; s! \] !$g_escape_table{']'}!gx; s! \\ !$g_escape_table{'\\'}!gx; return $_; } sub _DoItalicsAndBold { my $text = shift; # <strong> must go first: $text =~ s{ (\*\*|__) (?=\S) (.+?[*_]*) (?<=\S) \1 } {<strong>$2</strong>}gsx; $text =~ s{ (\*|_) (?=\S) (.+?) (?<=\S) \1 } {<em>$2</em>}gsx; return $text; } sub _DoBlockQuotes { my $text = shift; $text =~ s{ ( # Wrap whole match in $1 ( ^[ \t]*>[ \t]? # '>' at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines \n* # blanks )+ ) }{ my $bq = $1; $bq =~ s/^[ \t]*>[ \t]?//gm; # trim one level of quoting $bq =~ s/^[ \t]+$//mg; # trim whitespace-only lines $bq = _RunBlockGamut($bq); # recurse $bq =~ s/^/ /g; # These leading spaces screw with <pre> content, so we need to fix that: $bq =~ s{ (\s*<pre>.+?</pre>) }{ my $pre = $1; $pre =~ s/^ //mg; $pre; }egsx; "<blockquote>\n$bq\n</blockquote>\n\n"; }egmx; return $text; } sub _FormParagraphs { # # Params: # $text - string to process with html <p> tags # my $text = shift; # Strip leading and trailing lines: $text =~ s/\A\n+//; $text =~ s/\n+\z//; my @grafs = split(/\n{2,}/, $text); # # Wrap <p> tags. # foreach (@grafs) { unless (defined( $g_html_blocks{$_} )) { $_ = _RunSpanGamut($_); s/^([ \t]*)/<p>/; $_ .= "</p>"; } } # # Unhashify HTML blocks # foreach (@grafs) { if (defined( $g_html_blocks{$_} )) { $_ = $g_html_blocks{$_}; } } return join "\n\n", @grafs; } sub _EncodeAmpsAndAngles { # Smart processing for ampersands and angle brackets that need to be encoded. my $text = shift; # Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: # http://bumppo.net/projects/amputator/ $text =~ s/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/&/g; # Encode naked <'s $text =~ s{<(?![a-z/?\$!])}{<}gi; return $text; } sub _EncodeBackslashEscapes { # # Parameter: String. # Returns: The string, with after processing the following backslash # escape sequences. # local $_ = shift; s! \\\\ !$g_escape_table{'\\'}!gx; # Must process escaped backslashes first. s! \\` !$g_escape_table{'`'}!gx; s! \\\* !$g_escape_table{'*'}!gx; s! \\_ !$g_escape_table{'_'}!gx; s! \\\{ !$g_escape_table{'{'}!gx; s! \\\} !$g_escape_table{'}'}!gx; s! \\\[ !$g_escape_table{'['}!gx; s! \\\] !$g_escape_table{']'}!gx; s! \\\( !$g_escape_table{'('}!gx; s! \\\) !$g_escape_table{')'}!gx; s! \\> !$g_escape_table{'>'}!gx; s! \\\# !$g_escape_table{'#'}!gx; s! \\\+ !$g_escape_table{'+'}!gx; s! \\\- !$g_escape_table{'-'}!gx; s! \\\. !$g_escape_table{'.'}!gx; s{ \\! }{$g_escape_table{'!'}}gx; return $_; } sub _DoAutoLinks { my $text = shift; $text =~ s{<((https?|ftp):[^'">\s]+)>}{<a href="$1">$1</a>}gi; # Email addresses: <address@domain.foo> $text =~ s{ < (?:mailto:)? ( [-.\w]+ \@ [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ ) > }{ _EncodeEmailAddress( _UnescapeSpecialChars($1) ); }egix; return $text; } sub _EncodeEmailAddress { # # Input: an email address, e.g. "foo@example.com" # # Output: the email address as a mailto link, with each character # of the address encoded as either a decimal or hex entity, in # the hopes of foiling most address harvesting spam bots. E.g.: # # <a href="mailto:foo@e # xample.com">foo # @example.com</a> # # Based on a filter by Matthew Wickline, posted to the BBEdit-Talk # mailing list: <http://tinyurl.com/yu7ue> # my $addr = shift; srand; my @encode = ( sub { '&#' . ord(shift) . ';' }, sub { '&#x' . sprintf( "%X", ord(shift) ) . ';' }, sub { shift }, ); $addr = "mailto:" . $addr; $addr =~ s{(.)}{ my $char = $1; if ( $char eq '@' ) { # this *must* be encoded. I insist. $char = $encode[int rand 1]->($char); } elsif ( $char ne ':' ) { # leave ':' alone (to spot mailto: later) my $r = rand; # roughly 10% raw, 45% hex, 45% dec $char = ( $r > .9 ? $encode[2]->($char) : $r < .45 ? $encode[1]->($char) : $encode[0]->($char) ); } $char; }gex; $addr = qq{<a href="$addr">$addr</a>}; $addr =~ s{">.+?:}{">}; # strip the mailto: from the visible part return $addr; } sub _UnescapeSpecialChars { # # Swap back in all the special characters we've hidden. # my $text = shift; while( my($char, $hash) = each(%g_escape_table) ) { $text =~ s/$hash/$char/g; } return $text; } sub _TokenizeHTML { # # Parameter: String containing HTML markup. # Returns: Reference to an array of the tokens comprising the input # string. Each token is either a tag (possibly with nested, # tags contained therein, such as <a href="<MTFoo>">, or a # run of text between tags. Each element of the array is a # two-element array; the first is either 'tag' or 'text'; # the second is the actual value. # # # Derived from the _tokenize() subroutine from Brad Choate's MTRegex plugin. # <http://www.bradchoate.com/past/mtregex.php> # my $str = shift; my $pos = 0; my $len = length $str; my @tokens; my $depth = 6; my $nested_tags = join('|', ('(?:<[a-z/!$](?:[^<>]') x $depth) . (')*>)' x $depth); my $match = qr/(?s: <! ( -- .*? -- \s* )+ > ) | # comment (?s: <\? .*? \?> ) | # processing instruction $nested_tags/ix; # nested tags while ($str =~ m/($match)/g) { my $whole_tag = $1; my $sec_start = pos $str; my $tag_start = $sec_start - length $whole_tag; if ($pos < $tag_start) { push @tokens, ['text', substr($str, $pos, $tag_start - $pos)]; } push @tokens, ['tag', $whole_tag]; $pos = pos $str; } push @tokens, ['text', substr($str, $pos, $len - $pos)] if $pos < $len; \@tokens; } sub _Outdent { # # Remove one level of line-leading tabs or spaces # my $text = shift; $text =~ s/^(\t|[ ]{1,$g_tab_width})//gm; return $text; } sub _Detab { # # Cribbed from a post by Bart Lateur: # <http://www.nntp.perl.org/group/perl.macperl.anyperl/154> # my $text = shift; $text =~ s{(.*?)\t}{$1.(' ' x ($g_tab_width - length($1) % $g_tab_width))}ge; return $text; } 1; __END__ =pod =head1 NAME B<Markdown> =head1 SYNOPSIS B<Markdown.pl> [ B<--html4tags> ] [ B<--version> ] [ B<-shortversion> ] [ I<file> ... ] =head1 DESCRIPTION Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text format into HTML. Markdown's text format is most similar to that of plain text email, and supports features such as headers, *emphasis*, code blocks, blockquotes, and links. Markdown's syntax is designed not as a generic markup language, but specifically to serve as a front-end to (X)HTML. You can use span-level HTML tags anywhere in a Markdown document, and you can use block level HTML tags (like <div> and <table> as well). For more information about Markdown's syntax, see: http://daringfireball.net/projects/markdown/ =head1 OPTIONS Use "--" to end switch parsing. For example, to open a file named "-z", use: Markdown.pl -- -z =over 4 =item B<--html4tags> Use HTML 4 style for empty element tags, e.g.: <br> instead of Markdown's default XHTML style tags, e.g.: <br /> =item B<-v>, B<--version> Display Markdown's version number and copyright information. =item B<-s>, B<--shortversion> Display the short-form version number. =back =head1 BUGS To file bug reports or feature requests (other than topics listed in the Caveats section above) please send email to: support@daringfireball.net Please include with your report: (1) the example input; (2) the output you expected; (3) the output Markdown actually produced. =head1 VERSION HISTORY See the readme file for detailed release notes for this version. 1.0.1 - 14 Dec 2004 1.0 - 28 Aug 2004 =head1 AUTHOR John Gruber http://daringfireball.net PHP port and other contributions by Michel Fortin http://michelf.com =head1 COPYRIGHT AND LICENSE Copyright (c) 2003-2004 John Gruber <http://daringfireball.net/> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. =cut ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/README.md���������������������������������������������������������������0000664�0000000�0000000�00000001643�14107073154�0017162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Test the perf of some Markdown implementations. 1. Generate some test cases: ./gen_perf_cases.py [limit] for example: ./gen_perf_cases.py 1000 This created a bunch of (small) test .txt files in "cases". These are derived from a bunch of [Python Cookbook][] data. "limit" is a max number of "recipes" in the data set for which to generate cases. The test files are small and don't necessarily a lot of markup, so this may not really be a good *breadth* perf suite -- it *is* real data though. 2. Process the Markdown for each "cases/*.txt" with Markdown.pl, markdown.py and markdown2.py: ./perf.py # TODO - strip out the .text cases that markdown.py blows up on? (encoding problems) - add some larger perf suites (perhaps those test case files that all Markdown implementations pass) - add markdown.php timing [Python Cookbook]: http://code.activestate.com/recipes/ ���������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/gen_perf_cases.py�������������������������������������������������������0000775�0000000�0000000�00000023041�14107073154�0021217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python2.5 import os from os.path import * import sys import re import datetime from glob import glob import operator import shutil import codecs TMP = "tmp-" def gen_aspn_cases(limit=0): base_dir = TMP+'aspn-cases' if exists(base_dir): print "'%s' exists, skipping" % base_dir return os.makedirs(base_dir) sys.stdout.write("generate %s" % base_dir); sys.stdout.flush() recipes_path = expanduser("~/as/code.as.com/db/aspn/recipes.pprint") recipe_dicts = eval(open(recipes_path).read()) for i, r in enumerate(recipe_dicts): sys.stdout.write('.'); sys.stdout.flush() f = codecs.open(join(base_dir, "r%04d.text" % i), "w", "utf-8") f.write(r["desc"]) f.close() for j, c in enumerate(sorted(r["comments"], key=operator.itemgetter("pub_date"))): text = _markdown_from_aspn_html(c["comment"]) headline = c["title"].strip() if headline: if headline[-1] not in ".!?,:;'\"": headline += '.' headline = _markdown_from_aspn_html(headline).strip() text = "**" + headline + "** " + text f = codecs.open(join(base_dir, "r%04dc%02d.text" % (i, j)), 'w', "utf-8") f.write(text) f.close() if limit and i >= limit: break sys.stdout.write('\n') def gen_test_cases(): base_dir = TMP+"test-cases" if exists(base_dir): print "'%s' exists, skipping" % base_dir return os.makedirs(base_dir) print "generate %s" % base_dir for test_cases_dir in glob(join("..", "test", "*-cases")): for text_file in glob(join(test_cases_dir, "*.text")): shutil.copy(text_file, join(base_dir, basename(text_file))) #---- internal support stuff br_pat = re.compile(r"</?br ?/?>", re.I) br_eol_pat = re.compile(r"</?br ?/?>$", re.I | re.MULTILINE) pre_pat = re.compile(r"<pre>(.*?)</pre>", re.I | re.DOTALL) single_line_code_pat = re.compile(r"<(tt|code)>(.*?)</\1>", re.I) a_pat = re.compile(r'''<a(\s+[\w:-]+=["'].*?["'])*>(.*?)</a>''', re.I | re.S | re.U) href_attr_pat = re.compile(r'''href=(["'])(.*?)\1''', re.I) title_attr_pat = re.compile(r'''title=(["'])(.*?)\1''', re.I) i_pat = re.compile(r"<(i)>(.*?)</\1>", re.I) def _markdown_from_aspn_html(html): from cgi import escape markdown = html markdown = br_eol_pat.sub('\n', markdown) # <br>EOL markdown = br_pat.sub('\n', markdown) # <br> while True: # <code>, <tt> on a single line match = single_line_code_pat.search(markdown) if not match: break markdown = single_line_code_pat.sub(r"`\2`", markdown) while True: # <i> on a single line match = i_pat.search(markdown) if not match: break markdown = i_pat.sub(r"*\2*", markdown) while True: # <a> match = a_pat.search(markdown) if not match: break start, end = match.span() attrs, content = match.group(1), match.group(2) href_match = href_attr_pat.search(attrs) if href_match: href = href_match.group(2) else: href = None title_match = title_attr_pat.search(attrs) if title_match: title = title_match.group(2) else: title = None escaped_href = href.replace('(', '\\(').replace(')', '\\)') if title is None: replacement = '[%s](%s)' % (content, escaped_href) else: replacement = '[%s](%s "%s")' % (content, escaped_href, title.replace('"', "'")) markdown = markdown[:start] + replacement + markdown[end:] markdown = markdown.replace(" ", ' ') # <pre> part 1: Pull out <pre>-blocks and put in placeholders pre_marker = "THIS_IS_MY_PRE_MARKER_BLAH" pre_blocks = [] while True: # <pre> match = pre_pat.search(markdown) if not match: break start, end = match.span() lines = match.group(1).splitlines(0) if lines and not lines[0].strip(): del lines[0] _dedentlines(lines) pre_blocks.append(lines) marker = pre_marker + str(len(pre_blocks) - 1) markdown = markdown[:start].rstrip() + marker + markdown[end:].lstrip() # <pre> part 2: Put <pre>-blocks back in. for i, pre_block in enumerate(pre_blocks): marker = pre_marker + str(i) try: idx = markdown.index(marker) except ValueError: print "marker: %r" % marker raise if not markdown[:idx].strip(): #TODO: Correct this false diagnosis. Problem is not limited # to <h1> #TODO: problem with 1203#c6 "Frozen dictionaries": comment title # insertion onto start of an indented-pre/code block # # There is a bug in python-markdown with an indented block # at the start of a buffer: the first line can get rendered # as a <h1>. Workaround that by adding a '.' paragraph # before. # At the time of this writing those comments affected are: # 16#c9, 31#c3, 155#c1, 203#c20, 230#c3, 356#c2, 490#c1, # 504#c2, 1127#c12 #log.warn("adding '.'-para Python Markdown hack") prefix = ['.'] else: prefix = [] lines = prefix + ['', ''] + [' '+ln for ln in lines] + ['', ''] replacement = '\n'.join(lines) markdown = markdown.replace(marker, replacement, 1) lines = markdown.splitlines(0) # Removing empty lines at start and end. while lines and not lines[0].strip(): del lines[0] while lines and not lines[-1].strip(): del lines[-1] # Strip trailing whitespace because don't want auto-<br>'s. for i in range(len(lines)): lines[i] = lines[i].rstrip() markdown = '\n'.join(lines) + '\n' #TODO: manual fixes: # - comment 1, recipe 7 return markdown # Recipe: dedent (0.1.2) def _dedentlines(lines, tabsize=8, skip_first_line=False): """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines "lines" is a list of lines to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. Same as dedent() except operates on a sequence of lines. Note: the lines list is modified **in-place**. """ DEBUG = False if DEBUG: print "dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\ % (tabsize, skip_first_line) indents = [] margin = None for i, line in enumerate(lines): if i == 0 and skip_first_line: continue indent = 0 for ch in line: if ch == ' ': indent += 1 elif ch == '\t': indent += tabsize - (indent % tabsize) elif ch in '\r\n': continue # skip all-whitespace lines else: break else: continue # skip all-whitespace lines if DEBUG: print "dedent: indent=%d: %r" % (indent, line) if margin is None: margin = indent else: margin = min(margin, indent) if DEBUG: print "dedent: margin=%r" % margin if margin is not None and margin > 0: for i, line in enumerate(lines): if i == 0 and skip_first_line: continue removed = 0 for j, ch in enumerate(line): if ch == ' ': removed += 1 elif ch == '\t': removed += tabsize - (removed % tabsize) elif ch in '\r\n': if DEBUG: print "dedent: %r: EOL -> strip up to EOL" % line lines[i] = lines[i][j:] break else: raise ValueError("unexpected non-whitespace char %r in " "line %r while removing %d-space margin" % (ch, line, margin)) if DEBUG: print "dedent: %r: %r -> removed %d/%d"\ % (line, ch, removed, margin) if removed == margin: lines[i] = lines[i][j+1:] break elif removed > margin: lines[i] = ' '*(removed-margin) + lines[i][j+1:] break else: if removed: lines[i] = lines[i][removed:] return lines def _dedent(text, tabsize=8, skip_first_line=False): """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text "text" is the text to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. textwrap.dedent(s), but don't expand tabs to spaces """ lines = text.splitlines(1) _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line) return ''.join(lines) #---- mainline if __name__ == "__main__": try: limit = int(sys.argv[1]) except: limit = 0 gen_aspn_cases(limit) gen_test_cases() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/perf.py�����������������������������������������������������������������0000775�0000000�0000000�00000011761�14107073154�0017216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python """Run some performance numbers. <cases-dir> is a directory with a number of "*.text" files to process. Example: python gen_perf_cases.py # generate a couple cases dirs python perf.py tmp-test-cases """ import os import sys import timeit import time from os.path import * from glob import glob import optparse from util import hotshotit clock = sys.platform == "win32" and time.clock or time.time @hotshotit def hotshot_markdown_py(cases_dir, repeat): time_markdown_py(cases_dir, repeat) def time_markdown_py(cases_dir, repeat): sys.path.insert(0, join("..", "test")) import markdown del sys.path[0] markdowner = markdown.Markdown() times = [] for i in range(repeat): start = clock() for path in glob(join(cases_dir, "*.text")): f = open(path, 'r') content = f.read() f.close() try: markdowner.convert(content) markdowner.reset() except UnicodeError: pass end = clock() times.append(end - start) print " markdown.py: best of %d: %.3fs" % (repeat, min(times)) @hotshotit def hotshot_markdown2_py(cases_dir, repeat): time_markdown2_py(cases_dir, repeat) def time_markdown2_py(cases_dir, repeat): sys.path.insert(0, "../lib") import markdown2 del sys.path[0] markdowner = markdown2.Markdown() times = [] for i in range(repeat): start = clock() for path in glob(join(cases_dir, "*.text")): f = open(path, 'r') content = f.read() f.close() markdowner.convert(content) end = clock() times.append(end - start) print " markdown2.py: best of %d: %.3fs" % (repeat, min(times)) def time_markdown_pl(cases_dir, repeat): times = [] for i in range(repeat): start = clock() os.system('perl time_markdown_pl.pl "%s"' % cases_dir) end = clock() times.append(end - start) print " Markdown.pl: best of %d: %.3fs" % (repeat, min(times)) def time_all(cases_dir, repeat): time_markdown_pl(cases_dir, repeat=repeat) time_markdown_py(cases_dir, repeat=repeat) time_markdown2_py(cases_dir, repeat=repeat) def time_not_markdown_py(cases_dir, repeat): time_markdown_pl(cases_dir, repeat=repeat) time_markdown2_py(cases_dir, repeat=repeat) #---- mainline class _NoReflowFormatter(optparse.IndentedHelpFormatter): """An optparse formatter that does NOT reflow the description.""" def format_description(self, description): return description or "" def main(args=sys.argv): usage = "python perf.py [-i all|markdown.py|markdown2.py|Markdown.pl] [cases-dir]" parser = optparse.OptionParser(prog="perf", usage=usage, description=__doc__, formatter=_NoReflowFormatter()) parser.add_option("-r", "--repeat", type="int", help="number of times to repeat timing cycle (default 3 if timing, " "1 if profiling)") parser.add_option("-i", "--implementation", help="Markdown implementation(s) to run: all (default), " "markdown.py, markdown2.py, Markdown.pl, not-markdown.py") parser.add_option("--hotshot", "--profile", dest="hotshot", action="store_true", help="profile and dump stats about a single run (not supported " "for Markdown.pl)") parser.set_defaults(implementation="all", hotshot=False, repeat=None) opts, args = parser.parse_args() if len(args) != 1: sys.stderr.write("error: incorrect number of args\n") sys.stderr.write(__doc__) return 1 cases_dir = args[0] if not exists(cases_dir): raise OSError("cases dir `%s' does not exist: use " "gen_perf_cases.py to generate some cases dirs" % cases_dir) if opts.repeat is None: opts.repeat = opts.hotshot and 1 or 3 if opts.hotshot: assert opts.implementation in ("markdown.py", "markdown2.py") timer_name = "hotshot_%s" \ % opts.implementation.lower().replace('.', '_').replace('-', '_') d = sys.modules[__name__].__dict__ if timer_name not in d: raise ValueError("no '%s' timer function" % timer_name) timer = d[timer_name] print "Profile conversion of %s (plat=%s):" \ % (os.path.join(cases_dir, "*.text"), sys.platform) timer(cases_dir, repeat=opts.repeat) print os.system("python show_stats.py %s.prof" % timer_name) else: timer_name = "time_%s" \ % opts.implementation.lower().replace('.', '_').replace('-', '_') d = sys.modules[__name__].__dict__ if timer_name not in d: raise ValueError("no '%s' timer function" % timer_name) timer = d[timer_name] print "Time conversion of %s (plat=%s):" \ % (os.path.join(cases_dir, "*.text"), sys.platform) timer(cases_dir, repeat=opts.repeat) if __name__ == "__main__": sys.exit( main(sys.argv) ) ���������������python-markdown2-2.4.1/perf/recipes.pprint����������������������������������������������������������0000664�0000000�0000000�00012134253�14107073154�0020602�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[{'comments': [{'comment': u"This method creates a cycle in the object for no reason\nat all. The following function will add any function to an\ninstance in a cycle free way:\n\n> def add_method(self, method, name=None):\n>     if name is None: name = method.func_name\n>     class new(self.__class__): pass\n>     setattr(new, name, method)\n>     self.__class__ = new\n\nUse as follows:\n\ndef pretty_str(self): pass\n\nadd_method(C(), pretty_str, '__str__') Moshe Zadka", 'title': u'There is a Better Way to Add Methods To Classes'}], 'desc': u"This recipe demonstrates the runtime addition of a __str__ method to a class instance. This can sometimes be useful for debugging purposes. It also demonstrates the use of the two special attributes of class instances: '__dict__' and '__class__'."}, {'comments': [], 'desc': u"This recipe demonstrates the runtime addition of a __str__ method to a class instance. This can sometimes be useful for debugging purposes. It also demonstrates the use of the two special attributes of class instances: '__dict__' and '__class__'.\n"}, {'comments': [{'comment': u'Isn\'t this the "Python" cookbook??? If I wanted to use Perl... Olivier Dagenais', 'title': u' '}, {'comment': u"Was the point to demonstrate the perl module? Otherwise, it's easier\nto do this without the perl.<br><br>\nimport urllib<br>\nuf = urllib.urlopen ('http://www.python.org')<br>\ndoc = uf.read()<br>\nprint doc<br>\n\n", 'title': u'What was the point?'}], 'desc': u'This recipe shows how you can get perl to do the dirty work.\nYou might also consider looking at the urllib module.'}, {'comments': [{'comment': u"Is available from ActiveState's web site at http://downloads.activestate.com/Zope-Perl/. It is also available through Python Package Manager as released with ActivePython 2.0. Andy McKay", 'title': u'Pyperl Distribution'}, {'comment': u"Isn't this incomplete? Doesn't it need at least one Import statement?<br>What exactly needs to be imported?\n<br>Assuming you need to import dbi.py, and supposing you are using the PythonWin packages (e.g. with ActivePython), how do you import dbi.py instead of dbi.dll? (And assuming you solve that, how can you still import dbi.dll when that is what you want?)<br><br>\nClyde Adams III", 'title': u'Import?'}], 'desc': u'The pyperl dist provide an interface to the Perl DBI (dbi.py).\nThis allow direct access to all the perl supported databases from\npython. Full documentation of the API from \'perldoc DBI\' or\nthe ORA "Programming the Perl DBI" book, by A. Descartes\nand T. Bunce.'}, {'comments': [{'comment': u'This is an amazing example of the power of python. These one-liners are great for beginners like me who want to tap into this power right up front!\n\nHow about a "Python Power" category for these simple but "not so obvious to the newbie" power tips.\n', 'title': u'Grab a document from the web'}, {'comment': u'Nice, but any real-life usage require a proxy. ', 'title': u'Adding support for proxy'}, {'comment': u"Set an environment variable HTTP_PROXY to your proxyserver:port\nSo it'll look something like this:<br><br>\nset HTTP_PROXY=http://proxy.domain.com:8080<br>\n<br>\nYou *need* to have the http:// in front... or else it won't work!<br>\n<br>\nCheers,<br>\nKraulin", 'title': u'Proxy in python'}, {'comment': u'Is there any way to work with a proxy server that requires authentication?', 'title': u'Support for proxy authentication?'}, {'comment': u'There is an example here: <br>\n<pre>\n http://pydoc.org/2.3/urllib2.html\n</pre>\n\n<br><pre>\nimport urllib2\n \n# set up authentication info\nauthinfo = urllib2.HTTPBasicAuthHandler()\nauthinfo.add_password(\'realm\', \'host\', \'username\', \'password\')\n \nproxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})\n \n# build a new opener that adds authentication and caching FTP handlers\nopener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)\n \n# install it\nurllib2.install_opener(opener)\n \nf = urllib2.urlopen(\'http://www.python.org/\')\n</pre>', 'title': u'Proxy auth urllib'}], 'desc': u'This recipe shows how you can grab a document from the web\nusing urllib.py.'}, {'comments': [{'comment': u'This recipe can be extended to cover output from costly subsidiary\nprocesses.\n\nSuppose your application executes and uses output from a legacy \nprogram. Suppose that program has no command-line options but\nreads its input from a batch file. Then you can generate a (very \nprobably) unique key for the input using a module such as md5 or \nsha and can store the output from the program in an application \ncache directory. \n\nHere\'s an untested example. It assumes the function to be memoized\ntakes as its sole argument a string to be used as input to the subprocess\n(with apologies for the double-spaced lines):\n<PRE>\nimport sys, os, md5, string\n\nclass AppMemo:\n def __init__(self, cacheDir=None):\n cacheDir = cacheDir or "./.app_cache"\n if not os.path.isdir(cacheDir):\n os.makedirs(cacheDir)\n self.cacheDir = cacheDir\n\n def __getitem__(self, input):\n """Given the input data for a subprocess, find the corresponding output."""\n pathname = self._inputToPathname(input)\n if not os.path.isfile(pathname):\n raise KeyError("No output file for provided input.")\n content = open(pathname, "rb").read()\n return content\n\n def _inputToPathname(self, input):\n """Given input data for a subprocess, get the filename containing the corresponding output."""\n hasher = md5.new(`input`)\n digest = hasher.digest()\n hash = []\n for c in digest:\n hash.append("%02X" % c)\n hash = string.join(hash, "")\n pathname = os.path.join(self.cacheDir, hash)\n return pathname\n\n...\nclass AppMemoize(Memoize):\n def __init__(self, fn, cacheDir=None):\n Memoize.__init__(self, fn)\n self.memo = AppMemo(cacheDir=cacheDir)\n</PRE> Mitch Chapman', 'title': u'Variation: Memoizing subprocesses'}, {'comment': u'How about a time-based expiry too? And a method to purge a key. zander lichstein', 'title': u'expiry'}, {'comment': u'Should create another (heavier) class which implements a Least Recently Used algorithm if you want to limit the size of the cache. zander lichstein', 'title': u'Add LRU code'}, {'comment': u'This is really cool, but it could be better if it used the new weak references from python 2.1.\n\nThe way it works now, the cached values will be stored forever, and will never be garbage collected. This is fine if they are small, but if they happen to be non trivial objects, the memory cost could be a problem. If they are refered to with weak references, they can still be garbage collected, as long as there are no strong references to them.\n\nIt\'s not necessary for all instances, but it should at least be mentioned.\n\nsee <a href="http://python.sourceforge.net/peps/pep-0205.html">pep 205</a> for more details on weak references. garrett rooney', 'title': u'weak refs would help here'}, {'comment': u"Although dictionaries don't work as keys for immutable args,\nthe MemoizeMutable version can handle keyword args with:<pre>\n def __call__(self, *args, **kw):\n import cPickle\n str = cPickle.dumps((args, kw))\n if not self.memo.has_key(str):\n self.memo[str] = self.fn(*args, **kw)\n return self.memo[str]\n </pre>", 'title': u'Add keyword args for mutable case'}, {'comment': u'Closures would be a neat solution here. And repr takes care of non-hashable arguments and the strong ref problem (..but assumes the arguments have a repr that exposes all about them uniquely..)\n<pre>\ndef memoize(fn):\n memo = {}\n def memoizer(*param1):\n key = repr(param1)\n if not memo.has_key(key):\n memo[key] = fn(*param1)\n return memo[key]\n return memoizer\n</pre>', 'title': u'How about this?'}, {'comment': u'For a memoization decorator which clears the cache when the last copy of the function returns, see Recipe 440678. This can be a useful cache-clearing scheme.', 'title': u'Clear cache on return'}], 'desc': u'For functions which are called often, particulary recursive functions or functions which are intensive to calculate, memoizing (cacheing) the return values can dramatically improve performance.'}, {'comments': [{'comment': u'This is cute; I hadn\'t seen this one before.\n\nIf I might suggest an extension, why not change the line "globals()[sys.argv[1]]()"\nto "apply(globals()[sys.argv[1]], sys.argv[2:])". This allows you to pass string arguments\nto your functions.\n Nick Mathewson', 'title': u'An extension for arugment handling'}], 'desc': u'Using sys.argv and globals(), you can build scripts which can modify their behavior at runtime based on arguments passed on the command line. This script, \'test_test.py\' is built to be run from the command line. It allows you to invoke the script without any command-line arguments, in which case, the main() function is run. However, if the script is invoked via "python test_test.py debug", the debug function is run instead. This script uses Stephen Purcell\'s \'unittest\' module from his PyUnit unit testing framework.\n'}, {'comments': [{'comment': u'THis approach is not very flexible imo. If you were to have a whole\nbunch of such statements all over the code, then you keep changing\nback and forth between the debug and non-debug modes of operation.\nEasy for error prone and too much manual work. I would usually prefer\nto have a \'debug\' variable defined some where in there and change the\nvalue to "0" or "1" and use that to control the program flow. That is\nhow I usually do my debug. Love to hear from others. Srinivas B.', 'title': u'Not very flexible'}, {'comment': u'I\'d echo what Srinivas said. Rather than changing code, using an "if debug:"\napproach makes much more sense. This is particularly true if you\'re\ndebugging a large application, where you want the ability to turn on and\noff debugging code in different objects/modules w/o having to worry about\nside-effects.\n\nAnother method that might be worth exploring is an object-oriented\nlogging approach. Most of the time, I use debugging sections to print\ninfo. In that case, using a "log" object makes more sense. In other words,\nrather than using \n\nif debug:\n  print counter\n\nuse\n\nlog.out(counter)\n\nThis way, not only is the code shorter, but it also allows you to \nchange formatting of your debugging output depending on what \nyou\'re doing. If you have an object that you use both for \ncommand-line apps and web apps, you can switch between the \ntwo by simply changing which version of log you use (e.g., one\nclass of log, weblog, might replace every "\\n" with a "<br>\\n"\nso you can more clearly read the output). Anders Schneiderman', 'title': u'Not very flexible, part II'}, {'comment': u'This is as much true for other languages like C or Perl... as it is for Python.\n\n Dinu Gherman', 'title': u'Not Python-specific'}, {'comment': u"I would recommend against ever writing this:\n<pre>\n if 0: # i < 1:\n doSomething()\n</pre>\nin favor of this construct:\n<pre>\n if 0: # i < 1: FIXME -- restore the condition\n doSomething()\n</pre>\nbecause it's quite dangerous to leave the incorrect\ncode there... you might forget to put it back when you\nfinish testing.\n\nI'm not sure I would recommend the entire approach...\nif your editor provides any support you can write this:\n<pre>\n## FIXME: Restore this statement after testing\n## if i < 1:\n## doSomething()\n</pre>\nwith only a couple of keystrokes. This has the advantage\nthat the ## on the left-hand-edge of the screen really\nshows up, and it's clear that you're really only testing.\n\n-- Michael Chermside Michael Chermside", 'title': u'Play it safe'}], 'desc': u"While debugging, if you don't want a section of code to be executed temporarily, replace the expression after an 'if' or 'while' with '0' and comment out the old expression, leaving it in place."}, {'comments': [{'comment': u'Warning: \nThis algorithm (by Odell and Russell, as reported in Knuth) is designed for English language surnames. If you have a significant number of non-English surnames, you might do well to alter the values in digits to improve your matches.\nFor example, to accomodate a large number of Spanish surname data, you should count \'J\' and \'L\' (\'L\' because of the way \'ll\' is used) as vowels, setting their position in digit to \'0\'.\n<br>\nThe basic assumptions of Soundex are that the consonants are more important than the vowels, and that the consonants are grouped into "confusable" groups. Coming up with a set of confusables \nfor a language is not horribly tough, but remember: each group should contain all letters that are confusable with any of those in the group. a slightly better code for both English and Spanish names has digits = \'01230120002055012623010202\'.\n</br>', 'title': u'Warning: This is designed for English names'}], 'desc': u"Function to generate soundex code for any string (usually a name). Conforms to Knuth's algorithm and the common Perl implementation."}, {'comments': [], 'desc': u'Make a method call to an XML-RPC server using xmlrpclib\n(http://www.pythonware.com/products/xmlrpc/).'}, {'comments': [{'comment': u'I wrote something similar to this, but this is nicer. I wrapped it in a separate script called debug.py. debug.py takes a parameter which is the script you wish to debug:<br>\n<br>\nimport sys, traceback<br>\n<br>\ndef print_exc_plus():<br>\n ...<br>\n<br>\ntry:<br>\n....execfile(sys.argv[1])<br>\nexcept:<br>\n....print_exc_plus()<br>\n<br>\nThen you can run: debug.py myscript.py\n\nThis is useful for extending editors. e.g. I assign this to F7 in SciTE.', 'title': u'This can be used to create a generic debug script'}, {'comment': u'The code that gets the frames is poor and will fail for certain types of frames. It is also way too complicated and long. Start the function like this and it will on all versions of Python with all types of frame.\n\n<pre>\n tb = sys.exc_info()[2]\n stack = []\n \n while tb:\n stack.append(tb.tb_frame)\n tb = tb.tb_next\n\n traceback.print_exc()\n print "Locals by frame, innermost last"\n</pre>', 'title': u'Code to get frames is poor'}], 'desc': u"The standard Python traceback module provides very useful functions to produce useful information about where and why an error occurred. Traceback objects actually contain a great deal more information than the traceback module displays, however. That information can greatly assist in detecting the cause of your error.\n\nHere's an example of an extended traceback printer you might use, followed by a usage example."}, {'comments': [{'comment': u'The parens are missing on the os.setsid() call.', 'title': u'Typo in the code:'}, {'comment': u"My understanding of *NIX daemon processes is that, to avoid creating a 'zombie' process, you must use the standard 'double-fork' technique -- you must fork an intermidiate child process, that then forks the desired child process. Comments?", 'title': u'Attack of the zombie processes...'}, {'comment': u'I just used:\n\n<pre>\n#!/usr/bin/python\nimport sys \nimport os,time \n\nif os.fork()==0:\n os.setsid()\n sys.stdout=open("/dev/null", \'w\')\n sys.stdin=open("/dev/null", \'r\')\n time.sleep(20)\n\nsys.exit(0)\n</pre>\nAnd it resulted in no Zombie. Therefore, I guess, things work out right. It might be another issue if you do Shell Magick when starting the program, so the double fork could be added, just to be safe:\n\n<pre>\n#!/usr/bin/python\n\nimport sys \nimport os,time \nif os.fork()==0:\n os.setsid()\n sys.stdout=open("/dev/null", \'w\')\n sys.stdin=open("/dev/null", \'r\')\n if os.fork()==0:\n time.sleep(20) # or whatever your daemon does\n\nsys.exit(0)\n</pre>', 'title': u'no Zombie army...'}, {'comment': u'A more definitive/complete answer to the question "How do I get my program to act like a daemon?" is given by the following Unix Programming FAQ entry:<br>\n<br>\nhttp://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16<br>\n<br>\n...which is fairly completely implemented by the following python cookbook entry (and its comments):<br>\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012<br>\n', 'title': u'More complete implementation of forking a daemon'}, {'comment': u"A daemon is different than a background process.\nA background process is attached to a process group of a\ncontrolling terminal (your login shell). If your controlling \nterminal dies then you background jobs also die.\nI strongly suspect that your original code will die when you\nexit your login shell.<br><br>\n\nThe reason you need to double fork is to disconnect your new\nprocess group from the parent process controlling terminal.\nFailing to do this does not cause a zombie. Instead,\nfailing to do this causes the child process to be sent copies\nof the signals sent to the parent. That means when the parent\nlogin shell dies (HUP signal) or gets killed (KILL signal)\nthose signals will be broadcast to the children.<br><br>\n\nThe following code demonstrates a daemon in Python.\nWhen you start this up and a file ('/tmp/daemon.log')\nwill slowly get filled with integers (once per second). \nYou can logout, kill your shell, or whatever and the\ndaemon will still run. It will not appear in the process list\nunless you do 'ps -x' to list processes without\ncontrolling terminals.<br><br>\n\nNote that you have to have correct permissions to do this.\nSome systems will not allow you to create a daemon.\nSome UNIXes have other mechanisms to do this.\nI'm pretty sure that this is portable.<br><br>\n\nI'm no authority. This is from memory. I may be wrong,<br>\nYours,<br>\nNoah<br>\n\n<pre>\n#!/usr/bin/env python\n'''Daemon example'''\n\nimport os, sys, time\n\ndef main ():\n '''This is the main function run by the daemon.\n '''\n fout = open ('/tmp/daemon.log', 'a')\n fout.write ('daemon started with pid %d\\n' % os.getpid())\n c = 0\n while 1:\n fout.write ('Count: %d\\n' % c)\n fout.flush()\n c = c + 1\n time.sleep(1)\n\nif __name__ == '__main__':\n pid = os.fork ()\n if pid == 0: # if pid is child...\n os.setsid() # Create new session and sets process group.\n pid = os.fork () # Will have INIT (pid 1) as parent process...\n if pid == 0: # if pid is child...\n main ()\n</pre>", 'title': u'You need to double fork...'}, {'comment': u'I believe that calling setpgrp() in your forked daemon obviates the need for a second fork. That is what I have always done and it seems to work fine. ', 'title': u'setpgrp vs. double fork'}, {'comment': u'I hate it personally when programs insist on behaving like this normally; I use supervise to monitor all my daemon processes and it works wonderfully; no extra code in the daemons at all and good notification (and auto-restarting) of daemon death.', 'title': u'Consider doing these only optionally'}], 'desc': u' '}, {'comments': [], 'desc': u'This code was originally designed for dynamically creating HTML. It takes a template, which is a string that may included embedded Python code, and returns another string where any embedded Python is replaced with the results of executing that code.'}, {'comments': [], 'desc': u'Sending short text messages with socket datagrams is simple \nto implement and provides a very lightweight message passing\nidiom.\n'}, {'comments': [], 'desc': u"A normal dictionary performs a mapping of the form: key -> value. Suppose you want a dictionary which maps each key to multiple values: key -> [value*]. Here's an easy and efficient way to achieve it. We rely on the setdefault() method of dictionarys both initialize the list of values for this key if necessary, and give us the list at the same time."}, {'comments': [{'comment': u"Here's an even easier CGI program that I use for testing:\n\n#!/usr/local/bin/python\nimport cgi\ncgi.test()\n\nThis handles printing headers, and displays environment and form variables. Amos Latteier", 'title': u'cgi.test() is even easier'}, {'comment': u"I've updated the script per Carey's suggestion to include cgi.escape. Thanks.\n Jeff Bauer", 'title': u'RE: cgi.escape'}, {'comment': u'Maybe it\'s a little picky, but you should <tt>import cgi</tt> and\nuse <tt>cgi.escape()</tt> to quote any potential HTML in the response.\ni.e.\n<pre> print "%s\\t%s" % (cgi.escape(k), cgi.ecape(os.environ[k]))</pre>\nWhy? First, it makes the output more readable if you happen\nto include code for a "<" in your query. Second, it protects you\nfrom attacks like those described in the links below if someone\nshould happen to find your script on a live web site.\n\n<a href="http://httpd.apache.org/info/css-security/index.html">Apache information</a>\n\n<a href="http://www.cert.org/advisories/CA-2000-02.html">CERT Advisory CA-2000-02</a>\n\n<a href="http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan">Zope Client Side Trojan information</a>\n\n(I wonder if this site <a href="javascript:alert(\'Yes it does!\')">allows arbitrary scripts</a>?) Carey Evans', 'title': u'cgi.escape'}, {'comment': u"You may also wan't to make it shorter ;-)\n\n<pre>\n#!/usr/bin/python\nimport cgi\ncgi.test()\n</pre>", 'title': u'Even smaller ...'}, {'comment': u'I may not have made my intention clear. This is called the "simplest" CGI program, not the "shortest". For a newbie Python programmer trying to write his first CGI script, the cgi.test() method hides too many details to be useful, IMO.\n', 'title': u'cgi.test()'}, {'comment': u'I just downloaded PYTHON, and this is the first script I found in the cookbook that showed how to make a quick web page.\n<br>\nI appreciate it\n<br>\nThanks', 'title': u'New Programmer Likes'}, {'comment': u'I am completely new to python,\n\nI want to test if python is working on my hosting account. I am told it is!\n\nI have copied the text at the bottom of my post, i have then pasted it to notepad, saved it as ptest.cgi and secondly ptest.txt\n\nuploaded it to my cgi-bin, inside a folder called python, chomod 755\nthen go to my page: http://yourfeet.co.uk/cgi-bin/python/ptest.cgi\n\nor http://yourfeet.co.uk/cgi-bin/python/ptest.txt\n\n\nboth give errors in log as : Premature end of script headers\n\nWhat am i missing out please\n.\n.\n.\n\n\n\n\n#!/usr/local/bin/python\nprint "Content-type: text/html"\nprint\nprint "<pre>"\nimport os, sys\nfrom cgi import escape\nprint "Python %s" % sys.version\nkeys = os.environ.keys()\nkeys.sort()\nfor k in keys:\n print "%s\\t%s" % (escape(k), escape(os.environ[k]))\nprint "</pre>" ', 'title': u'help please,'}, {'comment': u'Thanks for the excellant example. It does exactly what is says. Very simply shows how to create a CGI application. Gives an excellant starting point for which anyone can go from there.\n\nThere is nothing worse than trying to get something to atleast work (produce a result). Your example does this -- quickly and easily. Once you have a result, you can then build on it knowing that fundamentally it will work.\n\nIt was exactly what I was looking for.\n\nHugh,', 'title': u'Perfect Example'}, {'comment': u"<pre>\n#!/usr/bin/env python\n# This is my minimal cgi template.\n# Another thing I do is wrap my entire script in a try block.\n# It's also good to wrap the import statements, because\n# sometimes these will raise exceptions too.\ntry:\n import traceback, sys, os, cgi\n # The following makes errors go to HTTP client's browser\n # instead of the server logs.\n sys.stderr = sys.stdout \n cgi.test()\nexcept Exception, e:\n print 'Content-type: text/html\\n'\n print\n print '<html><head><title>'\n print str(e)\n print '</title>'\n print '</head><body>'\n print '<h1>TRACEBACK</h1>'\n print '<pre>'\n traceback.print_exc()\n print '</pre>'\n print '</body></html>'\n</pre>", 'title': u'My own simple CGI (perhaps not the simplest :-)'}, {'comment': u'Brendan, your trouble with the \'Premature end of script headers\' error message might be due to your having created the cgi script using a Windows text editor, and then uploading the script to your server using ftp.\n\n<br>\n<br>Windows text editors generally save text files with "\\r\\n" as the set of characters that marks the end of a line; you want to save the file as a "UNIX" format file, so that only "\\n" marks the end of a line.\n\n<br>\n<br>Some more info is here:\n<br>\n<br>http://sundown.greyledge.net/pages/2003/03/notes_on_using_python_for_cgi_scripts_under_apache.html', 'title': u"'Premature end of script headers' can be caused by using Windows as text editor"}, {'comment': u'Have a great vacation', 'title': u'Just vacation'}], 'desc': u'The simplest CGI program. This script displays the\ncurrent version of Python and the environment values.\n'}, {'comments': [{'comment': u'Larger Python applications consist of sets of Python packages and associated sets of "resource" files (e.g. Glade project files, SQL templates, image files). It\'s convenient to store these associated files together with the Python packages which use them. It\'s easy to do so if you use a variation on this recipe, one which finds files relative to the Python path.\n\n<PRE>\n#!/usr/bin/env python\nimport sys, os\n\nclass Error(Exception): pass\n\ndef _find(path, matchFunc=os.path.isfile):\n for dirname in sys.path:\n candidate = os.path.join(dirname, path)\n if matchFunc(candidate):\n return candidate\n raise Error("Can\'t find file %s" % path)\n \ndef find(path):\n return _find(path)\n\ndef findDir(path):\n return _find(path, matchFunc=os.path.isdir)\n</PRE> Mitch Chapman', 'title': u'Variation: Finding files on the Python path'}, {'comment': u"The call to string.split(), in the search_file() function, should just be a call to split() since the example uses 'from string import split'.\n", 'title': u'Small correction'}, {'comment': u"The abspath function is not imported. The first import statement should probably be 'from os.path import exists, join, abspath'.", 'title': u'Another one'}, {'comment': u'Here\'s a version that accommodates for implicit extensions (nice formatting system!)::\n\n\n def findFile(seekName, path, implicitExt=\'\'):\n """Given a pathsep-delimited path string, find seekName.\n Returns path to seekName if found, otherwise None.\n Also allows for files with implicit extensions (eg, .exe), but\n always returning seekName as was provided.\n >>> findFile(\'ls\', \'/usr/bin:/bin\', implicitExt=\'.exe\')\n \'/bin/ls\'\n """\n if (os.path.isfile(seekName)\n or implicitExt and os.path.isfile(seekName + implicitExt)):\n # Already absolute path.\n return seekName\n for p in path.split(os.pathsep):\n candidate = os.path.join(p, seekName)\n if (os.path.isfile(candidate)\n or implicitExt and os.path.isfile(candidate + implicitExt)):\n return candidate\n return None', 'title': u'Sometimes there are implicit extension on sought files'}], 'desc': u'Given search paths separated by a separator, find the first file that matches a given specification.'}, {'comments': [{'comment': u'I would very much like to see an implementation of XML-RPC that doesn\'t require Medusa. Maybe as a CGI or "threaded-long-running-web-process" program? (although then we\'re probably better off using SOAP) Olivier Dagenais', 'title': u'Without Medusa?'}, {'comment': u"The xmlrpclib module comes with both same client and server programs that don't require\nMedusa.\n", 'title': u'Example without using Medusa'}], 'desc': u'This section demonstrates remote method calls between two\nmachines (or processes) using the XML-RPC protocol. A complete\nexample of working client/server code is provided.\n'}, {'comments': [{'comment': u'Nice demonstration of <i>dict</i>.get(key, defaultval) - I seem to spend half my days in other languages coding this type of sequence in a much less concise manner. Dave Warner', 'title': u'Note use of dict.get(key, defaultval)'}, {'comment': u'\nPexpect is perfect for this type of application.\nUsing Pexpect you can do the same thing with SSH.\n<br>\nFind Pexpect here: <br>\nhttp://pexpect.sourceforge.net/', 'title': u'Try Pexpect and do the same with SSH.'}, {'comment': u"Pexpect only works on *nix systems, so don't waste your time looking at it if you use Win*.", 'title': u'sorry, *nix only'}], 'desc': u"Send commands to one or more logins using Python's standard\ntelnetlib module."}, {'comments': [{'comment': u'<br>\n<br>\nOriginal version uses map(None,...\n<pre>\ndef sort_by_attr(seq, attr):\n intermed = map(None, map(getattr, seq, (attr,)*len(seq)), xrange(len(seq)), seq)\n intermed.sort()\n return map(operator.getitem, intermed, (-1,) * len(intermed))\n</pre>\n<br>\nThis one uses list comprehensions instead..\n<pre>\ndef sort_by_attr2(seq,attr):\n intermed = [ (getattr(seq[i],attr), i, seq[i]) for i in xrange(len(seq)) ]\n intermed.sort()\n return [ tup[-1] for tup in intermed ]\n</pre></br></br></br>', 'title': u'Using list comprehensions:'}], 'desc': u'Fast sorting the list of objects by object\'s attribute using the "Schwartzian transform". Since this recipe uses _only_ builtins and doesn\'t use explicit looping, this is quite fast. Besides, it doesn\'t use any Python 2.0-specific features (such as zip() or list comprehensions) so can be used for Python 1.5.2/1.6 as well.'}, {'comments': [{'comment': u'If you use a Python 2 list comprehension instead of the two map() calls, the code is a little easier to read:\n<pre>\n def counts(self,desc=None):\n result = [[val, key] for (key, val) in self.dict.items()]\n result.sort()\n if desc: result.reverse()\n return result\n</pre>\nPS. It would be cool to have a link to download each Cookbook code snippet instead of having to copy, paste and then fix the whitespace. Fred Bremmer', 'title': u'List comprehension instead of map()'}, {'comment': u'Now you can by clicking on "Text Source"', 'title': u'Text Source available'}], 'desc': u"I've often found it necessary to produce ascending or descending counts -- the most or least common words in a file, popular pages on a website, etc. This is a simple class that makes this easy."}, {'comments': [{'comment': u'Sometimes using zip() will provide different results (with some lazily evaluted sequences) or fail (with unbounded sequences).<br>\n<br>\nSince we already have xrange and xreadlines, maybe someone should do a PEP on xfilter, xmap and xzip too. ;-)</br></br>', 'title': u'zip() not semantically equivalent'}, {'comment': u"map is also going to be depreciated in 3.0. So use the Class:\n<pre>\n>>> class Indexed(object):\n... def __init__(self, seq):\n... self.seq = seq\n... def __getitem__(self, i):\n... return self.seq[i], i\n \n>>> sequence = ['a','b','c','d','e','f']\n>>> for item, index in Indexed(sequence):\n... print item, str(index)\na 0\nb 1\nc 2\nd 3\ne 4\nf 5</pre>", 'title': u'so just use the Class'}, {'comment': u'Since almost all objects are iterable now we can enhance the class to work with them:<pre>\nclass Indexed(object):\n """provide index while iterating over an object\n\n >>> sequence = [\'a\',\'b\',\'c\',\'d\',\'e\',\'f\']\n >>> for item, index in Indexed(sequence):\n ... print item, str(index)\n a 0\n b 1\n c 2\n d 3\n e 4\n f 5\n \n """\n def __init__(self, object):\n self.object = object.__iter__()\n def __getitem__(self, i):\n return self.object.next(), i\n </pre>', 'title': u'An iterable version'}, {'comment': u"There is a builtin that provides the same functionality as the class:<pre>\n>>> sequence = ['a','b','c','d','e','f']\n>>> for index, item in enumerate(sequence):\n... \tprint index, item\n... \n0 a\n1 b\n2 c\n3 d\n4 e\n5 f</pre>\nI need to read the fine manuals more often.", 'title': u'Builtin with 2.3'}], 'desc': u'zip() stops zipping at the shortest of its sequence-arguments and thus also allows unbounded-sequence arguments. This affords, for example, a very spare idiom for the frequent need of a parallel loop on index and sequence-item.'}, {'comments': [{'comment': u'Why go to the trouble of greating a local class "Indices" when this would do the same job more simply?\n\n<pre>\n decorated = zip(alist, xrange(len(alist)))\n</pre>\n\nOr was it simply out of habit? :-)', 'title': u'why class Indices?'}, {'comment': u'I just wanted to correct a couple of errors in your understanding of the Schwartzian Transform in Perl.\n<br><br>\nFirstly, the form of the Schwartzian Transform is\n\n<pre>@sorted = map { ... } sort { ... } map { ... } @unsorted;</pre>\n\nThere is no use of "grep" as you imply.\n<br><br>\nSecondly, your example is actually of a more specialised version of the Schwartzian Transform where the middle sort has no associated code block\n\n<pre>@sorted = map { ... } sort map { ... } @unsorted;</pre>\n\nThis special case is usually known as the Guttman-Rosler Transform after the people who first described in in their paper at http://www.sysarch.com/perl/sort_paper.html.\n<br><br>\nOf course, the original Schwartzian Transform was just a Perl translation of a very common Lisp idiom.\n<br><br>\nhth,\n<br><br>\nDave...', 'title': u'Not a Schwartzian Transform'}, {'comment': u'There seems to be an error in this recipy. It should read like this:\n<pre>\ndef stable_sorted_copy(alist, _indices=xrange(sys.maxint)):\n decorated = zip(_indices, alist)\n decorated.sort()\n return [ item for index, item in decorated ]\n</pre>\nMichael Palmer', 'title': u'Correction '}, {'comment': u'It\'s pretty obvious that if the first items of decorated\'s pairs are the indices, as in your "correction", the whole function becomes nothing but a humorously complicated "no-op"! As it\'s unthinkable that you haven\'t even tried it out before posting, I do understand you\'re joking, but, don\'t do that, it might confuse some rank beginner. Presumably your point would be that this recipe\'s obsoleted by Python 2.3, whose built-in sort IS stable...\n\nAlex', 'title': u'you MUST be joking, right, Michael...?'}, {'comment': u'As Alex mentioned, list.sort in Python 2.3 is actually already stable.<br><br>\n\nEven better, as of Python 2.4, that artifact of the 2.3 implementation became a guaranteed property of the interpreter.', 'title': u'Not needed for Python 2.3 or later'}], 'desc': u'Python lists\' .sort method is not guaranteed stable -- items that compare equal may or may not be in unchanged order. Ensuring stability is easy as one of the many application of the commom idiom decorate-sort-undecorate (aka "Schwartzian transform").'}, {'comments': [{'comment': u'By changing:\n<pre> for base in A.__bases__:</pre>\nto:\n<pre> for base in self.__class__.__bases__:</pre>\nyou get a version of the snippet that can be used in other classes without modification.', 'title': u'Slightly more generalized'}, {'comment': u'Does this need updating for Python 2.2 and its new super() function?', 'title': u'super()'}], 'desc': u'Python has no equivalent to Java\'s "super" keyword (so that some part of a method can be delegated to the superclass), but it\'s easy to get similar convenience despite Python\'s multiple-inheritance generality.'}, {'comments': [{'comment': u'It may be that this "recipe" is long enough as is... I certainly\nlike the listing of different alternative approaches with\ncommentary. But you haven\'t even one example of doing this with\nmultiple inheritance. I can generalize from what you HAVE shown\nfairly easily... all I need to know is whether it is straightforward\nor if there are little tricks I need to be wary of.\n\nNot that I use multiple inheritance all that much... I never liked\nit much.\n\n-- Michael Chermside Michael Chermside', 'title': u'Multiple inheritance'}, {'comment': u"Maybe the 'Getting a dictionary of all members of a class\n hierarchy'-recipe might point to a possible solution.", 'title': u'Multiple Inheritance'}], 'desc': u'Python does not automatically call the __init__ (and __del__) methods of superclasses if subclasses define their own; explicit calling is needed, and it may be advisable to use a call-if-it-exists idiom.\n'}, {'comments': [{'comment': u"When trying to get attribute/method of an object, the object's superclasses are looked up before the __getattr__:\n<pre>\nclass SuperClass:\n special = 'super special'\n\nclass SubClass(SuperClass):\n def __getattr__(self, name):\n if name == 'special':\n return 'sub special'\n\nif __name__ == '__main__':\n S = SubClass()\n print S.special\n</pre>\nThis will print 'super special'.\n\n(But it IS correct that the value returned by __getattr__ is 'None' if no other is given!) willem broekema", 'title': u'__getattr__ only comes into play *after* looking in superclasses'}, {'comment': u"William is right... this recepie is incorrect, and should be fixed (or removed). I'd prefer a fix. (If this were a wiki, I'd just MAKE the fix, but there's no mechanism for that in the cookbook. Yet.)<br><br>\n-- Michael Chermside</br></br>", 'title': u'Please Fix'}, {'comment': u'There\'s another problem if you forget the else-branch:\nyour objects loose callability.\n\n<pre>\nclass Test:\n def __init__(self):\n pass\n def __getattr__(self,name):\n if name == \'myattr\':\n return \'value of myattr\'\n\ntest = Test()\ntest\nTraceback (most recent call last):\n File "", line 1, in ?\nTypeError: \'NoneType\' object is not callable\n</pre>', 'title': u'another problem: loosing callability'}, {'comment': u'The "NoneType" is not callable is because it is trying to look up "__repr__" in order to display it to you, and so it gets back a None from __getattr__ and promptly tries to call it (because it assumes it\'s a __repr__). You can see this by adding "print \'getting\', attr" to your __getattr__()s\n\nI ran into this very problem which is what led me here. Adding the exception line as in the recepie solved my problem; I believe python checks for AttributeErrors and keeps falling back until it can\'t fall back anymore.\n\n__repr__ is a special case; it should be one of the only (the only?) one that will trigger the strange "NoneType is not callable" error because, if I understand correctly, it\'s only when you type in an object at the interactive prompt that the follow pattern is run:\ntry:\n print getattr(object, \'__repr__\')()\nexcept AttributeError:\n print generic_repr(object)\nIn all other cases it will happily return None to you which would instantly signal to you "oops"', 'title': u' '}, {'comment': u'<pre>And in fact, according to the language reference:\n"This method should return the (computed) attribute value or raise an AttributeError exception."\n</pre>', 'title': u' '}], 'desc': u'__getattr__ is a very nice and powerful method that must be handled with care, otherwise you can discover that it has more power than you expected...\n'}, {'comments': [], 'desc': u'Unlike interpreted languages such as Perl and Python, \nthe keyword line must NOT be commented out in .c or .h files. \nThe keyword string is defined as a static char so that it\nremains unchanged in the compiled executable. \nThis program will display a complete keyword line \nwhere the number after CVSid is always unique. \nYou can then cut and paste the line into\nyour .c or .h file. The diplayed line will look like:\nstatic char *CVSid432422157="@(#) $Header$ ";\n'}, {'comments': [{'comment': u'Since this module uses a __import__ call, the extensions folder will have to have an __init__.py in it so that python treats the directory as module path.', 'title': u"Don't forget to have __init__.py"}, {'comment': u"Could you perhaps expand this recipe to allow either all, or multiple/selected names to be imported, for example,\n<pre>\nimportModule('module',('*'))\n</pre>\nto import all names, and\n<pre>\nimportModule('module',('func','func2','func3','class'))\n</pre>\nto import selected names.\n<br>\nAlso, it would be nice if the names did not have to be assigned manually, i.e., instead of\n<pre>\nfunc, func2, func3, class = importModule('module',('func','func2','func3','class'))\n</pre>\none could do, for instance, simply\n<pre>\nimportModule('module',('func','func2','func3','class'))\n</pre>\nand 'func', 'func2', 'func3', and 'class' would all be imported as attributes of 'module'.\n<br>\n<br>\nThanks.", 'title': u'Improve it.'}, {'comment': u"hmm, no, wait...\n<br><br>\nIf the second argument is NOT given it should just import module with all the attributes: 'module.func', 'module.func2', 'module.func3', 'module.class', and if the second argument IS given, it should import all the names into the global scope: 'func', 'func2', 'func3', 'class'.", 'title': u' '}], 'desc': u'This function allows you to do "from module import name", where both "module" and "name" are dynamic values (i.e. expressions or variables). For example, this can be used to implement a "plugin" mechanism to extend an application by external modules that adhere to some common interface.\n\nThis pattern is used in MoinMoin (http://moin.sourceforge.net/) to load extensions implementing variations of a common interface, like "action", "macro", and "formatter".'}, {'comments': [{'comment': u'See the following document for updates to this recipe, accommodating the updated 4Suite APIs:\n\nhttp://uche.ogbuji.net/tech/akara/pyxml/xslt-resolver/', 'title': u'Updates accommodating API changes'}, {'comment': u'I just noticed this stale link. The not now resides at:\n\nhttp://uche.ogbuji.net/tech/akara/nodes/2003-01-01/xslt-resolver\n\n--Uche', 'title': u'Updates accommodating API changes'}], 'desc': u'This code shows how to load a stylesheet from "virtual" URLs, by detecting a special URL scheme.'}, {'comments': [{'comment': u"You can include the filename of an attachment, like so:\n<pre>body = part.startbody('image/jpeg; name=kitten.jpg')</pre>\nMimeWriter will generate this header:\n<pre>Content-Type: image/jpeg; name=kitten.jpg</pre>\nand the mail reader will read that name.\n\nIf the name contains spaces, surround it with double quotes. Michael Strasser", 'title': u'You can include the filename of an attachment'}, {'comment': u'<a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a> states that the header:\n<pre>MIME-Version: 1.0</pre>\nis required for MIME Internet message bodies. Some mail programs don\'t care (e.g. Outlook) but others do (like PMMail). \n\nMimeWriter.py should put that in by itself. You can either edit MimeWriter.py by changing the MimeWriter class\'s __init__ method to have:\n<pre> self._headers = ["MIME-Version: 1.0\\n"]</pre>\ninstead of \n<pre> self._headers = []</pre>\nOr you can use MimeWriter.py as shipped and work around it by putting:\n<pre>writer.addheader(\'MIME-Version\', \'1.0\')</pre>\nbefore starting the multipart body in this cookbook example.\n\nNow, how do I submit a bugfix request to Python... \n Michael Strasser', 'title': u'MimeWriter.py is not writing a required header '}, {'comment': u'Some time ago I tried to solve the same problem and wrote a class doing that job. See http://sourceforge.net/snippet/detail.php?type=snippet&id=100444 for details. Would be nice to have a class like this in the Python distribiution but a request for that was not successful.', 'title': u'Wrap the whole stuff into a class'}], 'desc': u'This code constructs a multipart MIME email message and sends it using smtplib.'}, {'comments': [{'comment': u"I'm not sure, but...\n\nFrom the Python FAQ:\n\n<pre>\n6.16. How are lists implemented?\n\nDespite what a Lisper might think, Python's lists are really\nvariable-length arrays. The implementation uses a contiguous\narray of references to other objects, and keeps a pointer to\nthis array (as well as its length) in a list head structure.\nThis makes indexing a list (a[i]) an operation whose cost is\nindependent of the size of the list or the value of the index. \n\nWhen items are appended or inserted, the array of references is\nresized. Some cleverness is applied to improve the performance of\nappending items repeatedly; when the array must be grown, some extra\nspace is allocated so the next few times don't require an actual\nresize. \n</pre>\n\nI imagine most of the computational time is taken up for the\nappend, when the list needs to be grown (if it actually does need\nto be grown).\n Chris McDonough", 'title': u'Expense.'}, {'comment': u'I like the recepie, but can you throw in some comments\non performance? How expensive is a "turn" operation, and\ndoes it scale with the length of the list? Michael Chermside', 'title': u'Performance issues?'}, {'comment': u"<PRE>\n# here's a faster version:\n\nimport UserList\n\nclass Ring(UserList.UserList):\n def __init__(self, data = []):\n self.data = data\n self.offset=0\n\n def turn(self, n=1):\n self.offset = self.offset+n\n while self.offset<0:\n self.offset = self.offset + len(self.data)\n while self.offset>=len(self.data):\n self.offset = self.offset - len(self.data)\n \n def __getitem__(self, i):\n if abs(i)>=len(self.data):\n return self.data[i] # raise IndexError\n return self.data[(i-self.offset)%len(self.data)]\n\n def append(self, x):\n length = len(self.data)\n while self.offset>=length:\n self.offset = self.offset - length\n self.data[length-self.offset:length-self.offset] = [x]\n\n # needs slicing support ...\n # use list(ring) to see a list\n\n</PRE>\n Ken Seehof", 'title': u'A faster version O(constant).'}, {'comment': u"This doesn't come up much, but when you have a value for n in turn which is much larger than len(self.data), you may want to use the following rather than self.offset = self.offset + len(self.data).\nself.offset = divmod(self.offset, len(self.data))[1]\nas one division is a lot faster than several subtractions for a large offset.", 'title': u'For turn values well outside len(self.data)'}, {'comment': u'I guess the implementation posted in the last comment got cut off at the <, which is interpreted by this cookbook editing system as an HTML tag.\n<br>\nAnyhow, seeing as the data stays the same after the Ring is created, you could keep two copies of references to the data in one much longer list. Then you only need store an offset within that data to do the turning. Slicing can be made to work without worrying about boundary conditions.\n<br>\nSo, for the data\n<pre>[1,2,3,4]</pre>\nyou hold a list like this:\n<pre>[1,2,3,4,1,2,3]</pre>\nKeep a pointer to the index the ring starts at. If you turn the ring to the index len(original_data), set the index back to zero. To get the data from the current position, just slice the list you have from the pointer to the pointer+len(original_data).', 'title': u'Hold two contiguous copies of the list'}], 'desc': u'In some applications, it\'s advantageous to be able to define a circular data structure (a structure in which the last element is a pointer to the first). Python lists make it easy to make such a beast. A list is an ordered sequence of elements, so implementing a "ring" as a Python list is easy. "Turning" the ring consists of removing the last element from the list and placing it in the list\'s beginning slot. We can encapsulate this behavior in a class, which is shown below as the "Ring" class.\n'}, {'comments': [{'comment': u'This code as is will not work. The main problem is that the output file object is not closed, so nothing actually gets written to the file. Also xreadlines is not a method of the file object (at least not in Jython, where I tested this). Anyway, give this one a go:\n<pre>\n#!/usr/bin/env python\nimport os, sys, xreadlines\nusage = "usage: %s search_text replace_text [infile [outfile]]" % os.path.basename(sys.argv[0])\n\nif len(sys.argv) < 3:\n \tprint usage\nelse:\n \tstext = sys.argv[1]\n \trtext = sys.argv[2]\n \tinput = sys.stdin\n \toutput = sys.stdout\n \tprint "There are %s args " %len(sys.argv)\n \tif len(sys.argv) > 3:\n \tinput = open(sys.argv[3])\n \tif len(sys.argv) > 4:\n \toutput = open(sys.argv[4], \'w\')\n\t\tprint "output = ",output\n \tfor s in xreadlines.xreadlines(input):\n\t\tprint "s= ",s\n \toutput.write(s.replace(stext, rtext))\n \tif len(sys.argv)> 3:\n\t input.close()\n\t if len(sys.argv) > 4:\n\t\t output.close()\n</pre>', 'title': u'Slight Mods'}, {'comment': u'Since xreadlines is deprecated the solution should look like this:<br>\n<br>\n<pre>\n#!/usr/bin/python\nimport os, sys\nusage = "usage: %s search_text replace_text [infile [outfile]]" % os.path.basename(sys.argv[0])\n\nif len(sys.argv) < 3:\n print usage\n\nelse:\n stext = sys.argv[1]\n rtext = sys.argv[2]\n input = sys.stdin\n output = sys.stdout\n print "There are %s args " %len(sys.argv)\n\n if len(sys.argv) > 3:\n input = open(sys.argv[3])\n\n if len(sys.argv) > 4:\n output = open(sys.argv[4], \'w\')\n\n for s in input:\n output.write(s.replace(stext, rtext))\n\n if len(sys.argv)> 3:\n input.close()\n if len(sys.argv) > 4:\n output.close()\n</pre>', 'title': u'xreadlines is deprecated'}, {'comment': u'Actually, all of these examples are wrong, s is not defined anywhere in the script and the replace method requires 3 arguments.', 'title': u'None of these work.'}], 'desc': u'A simple text search and replace program.'}, {'comments': [{'comment': u'Use "operator.add" instead of "lambda x,y:x+y" which avoids the overhead of "n" Python function calls.', 'title': u'Use builtin over lambda whenever possible'}], 'desc': u'This one line function adds up the ascii values of a string and returns the total as a checksum. Also included is a variation which returns the checksum mod 256 (so it can be used as a single byte). \nThe same technique can be used to add up a list of numbers, or to return the average of a list (examples are also included) or to do any other any other simple processing on a list or a string.'}, {'comments': [{'comment': u"You don't need a cryptographically secure RNG just to make \nunguessable sessions -- one 128 bit number that's stored on\nthe server and md5.update'ed into the hash is enough. Moshe Zadka", 'title': u'No Need to Get Fancy -- Easy Security'}, {'comment': u"You don't need a cryptographically secure RNG just to make \nunguessable sessions -- one 128 bit number that's stored on\nthe server and md5.update'ed into the hash is enough. Moshe Zadka", 'title': u'No Need to Get Fancy -- Easy Security'}, {'comment': u'If an attacker can learn what the values of the "st" argument are, then the attacker can make some good guesses about the session ids of other users. \n\nThis recipe can be made more secure by using a cryptographically strong pseudo-random number generator in place of "st". Perhaps this is a good subject for another recipe. Bravada Zadada', 'title': u'can be more secure'}, {'comment': u'missing import string', 'title': u'missing import string'}], 'desc': u'This function is useful for web programs that need to generate a unique session id to store in a cookie (or some other safe place).\n'}, {'comments': [{'comment': u'By using "expat" parser directly, you get a better performance. I changed function parsefile() such that, it calls now the "expat" parser instead. It would be important, if you check the well-formedness of a big XML file.\n<br>\n\n<pre>\nimport xml.parsers.expat,sys\nfrom glob import glob\n\ndef parsefile(file):\n parser = xml.parsers.expat.ParserCreate()\n parser.ParseFile(open(file, "r"))\n\nfor arg in sys.argv[1:]:\n for filename in glob(arg):\n try:\n parsefile(filename)\n print "%s is well-formed" % filename\n except Exception, e:\n print "%s is %s" % (filename, e)\n</pre>', 'title': u'Using "expat" directly to get the best performance'}, {'comment': u'A modification of the script for the validness checking of an XML document with an internal DTD\n<pre>\n#!/usr/bin/env python\n\nfrom xml.parsers.xmlproc import xmlval\nimport sys\n\ndef parseFile(file):\n\tparser=xmlval.XMLValidator()\n\tparser.parse_resource(file)\n\nif len(sys.argv) != 2:\n\tprint \'\'\'Usage:\n\npython %s filename\n\n\'\'\' % sys.argv[0]\n\tsys.exit(0)\n\nfile=sys.argv[1]\n#f=open(file)\n\ntry: \n\tparseFile(file)\n\tprint "%s is well-formed and valid" % file\n\t\nexcept Exception,e:\n\tprint "%s is not well-formed or not valid %s!" % (file, e)\n</pre>', 'title': u'Check for validness'}], 'desc': u'This small script will check whether one or more XML documents are well-formed.'}, {'comments': [{'comment': u'It makes the assumption that the XML declaration is the only thing on the first line, but this is not necessarily going to be the case; there might not be any line breaks at all. For example, the encoding of \'<?xml version="1.0"?><foo encoding="x-bar"/>\' is detected as \'x-bar\' instead of \'utf-8\'. Using a regular expression to find the XML declaration would be more reliable.', 'title': u'Good, but...'}, {'comment': u"I made some changes to the code, beside blunt renaming and little cosmetic are worth mentioning:<br><br>\n- I haven't found some of the BOM byte patterns you used. Thus, I removed them<br>\n- the patterns for the 4 byte schemes fit to the names UTF32 rather than UCS4<br>\n- the algorithm searching in the xml declaration is wrong. I worked out a regex which should do for all halfway correct XML 1.0 headers<br> <br>My code: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363841", 'title': u'Some changes'}, {'comment': u'The discussion of this on page 469 of the 2nd print edition of the Python Cookbook acted upon my previous comment incorrectly. The book makes the assertion that the XML declaration must be terminated by a linefeed, and it implies that the recipe does not need to handle such cases of malformed "almost-XML". This is entirely wrong; there does not need to be linefeed at all; the XML grammar makes this clear in all three editions of XML 1.0. <br><br>Also, Lars Tiede has submitted a regex-based version at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363841.', 'title': u'Error in 2nd edition'}], 'desc': u'The XML specification describes the outlines of an algorithm for detecting the\nUnicode encoding that an XML document uses. This function will do that.'}, {'comments': [{'comment': u'You accidentally forgot to close the doc string\'s triple quote:\n<pre>"""Support the \'for item in set:\' protocol."</pre>\ninstead of:\n<pre>"""Support the \'for item in set:\' protocol."""</pre> Michael Strasser', 'title': u'Typo in <tt>__getitem__</tt> definition.'}, {'comment': u'The contain method must check\n self.dict.has_key(whatever)\n[which is O(1)], NOT\n whatever in self.dict.keys()\n[which is O(N)...].\n Alex Martelli', 'title': u'the contain method MUST use .has_key, NOT the in operator'}, {'comment': u'Maybe it could be usefull to overload the operator (+, -, |, &, ^)\nto performe the classical set operations.\n\nHere is a naive version of these operators.\n<pre>def __add__(self, set):</br> """Return the union of the set and an another set."""</br> result = Set()</br> for i in self:</br> result.add(i)</br> for i in set:</br> result.add(i)</br> return result</br> </br> def __sub__(self, set):</br> """Return the difference between the set and an another set."""</br> result = Set()</br> for i in self:</br> result.add(i)</br> for i in set:</br> if i in result:</br> result.remove(i)</br> return result </br> </br> def __and__(self, set):</br> """Return the intersection of the set and an another set."""</br> if len(self) < len(set):</br> a = self</br> b = set</br> else:</br> a = set</br> b = self</br> result = Set()</br> for i in a:</br> if i in b:</br> result.add(i)</br> return result</br> </br> __or__ = __add__</br> </br> def __xor__(self, set):</br> """Return the union of the set and an another set but their intersection."""</br> result = Set()</br> for i in self:</br> result.add(i)</br> for i in set:</br> if i in result:</br> result.remove(i)</br> else:</br> result.add(i)</br> return result</pre> Vivian De Smedt', 'title': u'union, substraction and intersection'}, {'comment': u"Since you are using dictionary keys to maintain uniqueness, you can add a value that would be a count of how many 'occurances' of a given object have been added to the Set, which would make it a Bag Jay O'Connor", 'title': u'Close to a Bag'}, {'comment': u' Thomas Heller', 'title': u'Thanks, Alex, for the tip.'}], 'desc': u'A Set is a collection of items containing no duplicates.'}, {'comments': [{'comment': u"hi:<br>\ni' new to all this. i came across zope and python via an htmlarea search on google.<br>\ni am currently working on no-mysql flattish databases that use databinding and TDCs, and save space on servers, and get the job done quickly.<br>\ni am interested in this icon tool, but i do not know how or where python code goes on an html or php page. i want to put in code that will add my homepage to the surfer's links, something like yahoo, google,and guardian unlimited do.<br>\nsorry to appear so clueless. my time and resources are at a minimum here. i live and teach and learn in guangzhou, china.\nthanks for any tips.\n(=_=)", 'title': u'totally new to this, but it looks cool'}], 'desc': u"This recipe will let you embed GIF images inside of your source code\nfor use in Tkinter buttons, labels, etc. It's really handy for making\ntoolbars, etc. without worrying about having the right icon files\ninstalled.\n\nThe basic technique is to encode the GIF with base64 and store it\nas a string literal in the Python code to be passed to Tk PhotoImage."}, {'comments': [{'comment': u'The sample threw an exception on my box.<br>\n\n<pre>\nTraceback (most recent call last):\n File "tryzipfile.py", line 3, in ?\n z = zipfile.ZipFile("zipfile.zip", "rb")\n File "c:\\python21\\lib\\zipfile.py", line 167, in __init__\n self.fp = open(file, modeDict[mode])\nKeyError: rb\n</pre>\n\nChanging the mode to:<br>\n<pre>\n z = zipfile.ZipFile("zipfile.zip", "r")\n</pre>\nworks ok.\n</br></br>', 'title': u'mode incorrect?'}, {'comment': u"You are on Unix/Linux I'll bet.\n\nthe 'b' is for mac or windows platforms.", 'title': u'Which platform'}, {'comment': u'I am running on Windows 2000 and recieve the exception with mode "rb". Everything worked fine with mode "r".', 'title': u'Which platform'}, {'comment': u"I was able to recreate the exception as well on Windows 2000 using ActivePython 2.1.1, build 212 (ActiveState). Changing 'rb' to 'r' worked.", 'title': u'Exception confirmation'}], 'desc': u'Python can work directly with data in zip files. You can look at the \nlist of items in the directory and work with the data files themselves.'}, {'comments': [{'comment': u'The scrollbar works as promised, scrolling all listboxes at once, but scrolling with the mouse wheel only scrolls the listbox it is over. Is there a way to use scroll events to link the scrolls or another way to trap mouse wheels?', 'title': u'Nice work, but there is a problem with mouse wheels'}, {'comment': u'Seems fine (using Win XP w/SP1).', 'title': u'Mouse Wheel works for me'}, {'comment': u'On X, the wheel corresponds to the events and (at least on my box), so we need to bind these events to yview. I just added the following lines to the end of the "for l,w in lists" loop:\n\n<br><br>lb.bind(\'\', lambda e, s=self: s._scroll(SCROLL, -1, UNITS))\n<br>lb.bind(\'\', lambda e, s=self: s._scroll(SCROLL, 1, UNITS))\n<br><br>\nAnd the following line to the function _scroll:\n\n<br><br>return \'break\',<br><br>\n\notherwise, the listbox under the mouse arrow will be scrolled more than the others...', 'title': u'Sugested solution for mouse wheel problem'}, {'comment': u"Ops... the braces of the event are being stripped as html tags and the pre tag is crazy... the events are 'Button-4' and 'Button-5'...", 'title': u'Ops... '}, {'comment': u'I really like your implementation. I made a few changes to the constructor, let me know what you think.\n<br>\n[changed]\n<br>\n\tfor l,w in lists:<br>\n\t frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH)<br>\n\t Label(frame, text=l, borderwidth=1, relief=RAISED).pack(fill=X)<br>\n<br>------------------------------------------------<br>\n[to]\n<br>\n\tfor l,w,a in lists:<br>\n\t frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH)<br>\n\t Button(frame, text=l, borderwidth=1, relief=RAISED, command=a).pack(fill=X)<br>\n<br>\nSo that I could pass a sort command to the multilistbox and call it when I pressed the button.\n<br>\n--Eric Rose', 'title': u'Sort Button'}, {'comment': u'You could do this:\n\n<pre>\n def _sortBy(self, column):\n """ Sort by a given column. """\n\n if column == self.sortedBy:\n direction = -1 * self.direction\n else:\n direction = 1\n\n elements = self.get(0, END)\n self.delete(0, END)\n elements.sort(lambda x, y: self._sortAssist(column, direction, x, y))\n self.insert(END, *elements)\n\n self.sortedBy = column\n self.direction = direction\n\n def _sortAssist(self, column, direction, x, y):\n c = cmp(x[column], y[column])\n if c:\n return direction * c\n else:\n return direction * cmp(x, y)\n</pre>\n\nYou then need to change the labels to buttons, and set the command to something like << lambda i=i: self._sortBy(i) >> (where i is the column number). And give self.sortedBy a good initial value (-1, perhaps).', 'title': u'Sorting columns'}, {'comment': u"Hi. I'm using this widget on my application but since I'm just starting with Python I'm having some difficulties into trying to adapt it in order to respect two constraints I have.\na) Columns resize\nIs it possible to allow the user to resize with the mouse the width of the columns on the multilistbox?\nMy problem is that by setting 2 columns, independent of the value that I set them with, they will have the same size on the GUI and I have very little information on one of the columns and more information on the other.\nb) Independent scroll\nI wanted to turn off the possibility to perform scroll on each list independently. Is this possible?\n\nThank you very much for your time,\nPedro Alves", 'title': u'Columns Resize, Independent scroll'}, {'comment': u"Hi,\n\nI add lines from this site to modify the initial script and instead of :\n- working with frame, I worked with PanedWindow\n- using single select i used 'MULTIPLE'\n\nFeel free to use this for your own.\n\nRegards,", 'title': u'this with some improved'}, {'comment': u'Hi,<br>\n<br>\nI add lines from this site to modify the initial script and instead of :<br>\n- working with frame, I worked with PanedWindow<br>\n- using single select i used \'MULTIPLE\'<br>\n<br>\nFeel free to use this for your own.<br>\n<br>\nThis is working, at least, under Linux<br>\nRegards,<br>\n<br>\n<br>\n<pre>\nfrom Tkinter import *\n\nclass MultiListbox(PanedWindow):\n def __init__(self,master,lists):\n PanedWindow.__init__(self,master,borderwidth=1,showhandle=False,sashwidth=2,sashpad=0,relief=SUNKEN)\n self.lists = []\n self.columns=[]\n for l,w in lists:\n self.columns.append(l)\n frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH)\n tl=Label(frame, text=l, borderwidth=2, relief=GROOVE)\n tl.pack(fill=X)\n tl.bind(\'\',self.clickon)\n lb = Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,relief=FLAT, exportselection=FALSE, selectmode=MULTIPLE ,bg=\'white\')\n lb.pack(expand=YES, fill=BOTH)\n self.lists.append(lb)\n lb.bind(\'\', lambda e, s=self: s._select(e.y,e.state))\n lb.bind(\'\', lambda e, s=self: s._select(e.y,e.state))\n lb.bind(\'\', lambda e: \'break\')\n lb.bind(\'\', lambda e, s=self: s._b2motion(e.x, e.y))\n lb.bind(\'\', lambda e, s=self: s._button2(e.x, e.y))\n lb.bind(\'\', lambda e, s=self: s._scroll(SCROLL, 1, PAGES)) \n lb.bind(\'\', lambda e, s=self: s._scroll(SCROLL, -1, PAGES))\n self.add(frame)\n Label(master, borderwidth=1, relief=FLAT).pack(fill=X)\n sb = Scrollbar(master, orient=VERTICAL, command=self._scroll,borderwidth=1)\n sb.pack(fill=Y,side=RIGHT,expand=NO)\n for l in self.lists:\n l[\'yscrollcommand\']=sb.set\n self.add(frame)\n self.pack(expand=YES,fill=BOTH)\n self.sortedBy=-1\n self.previousWheel=0\n\n \n def _select(self, y,state=16):\n row = self.lists[0].nearest(y)\n if state==16:self.selection_clear(0, END)\n self.selection_set(row)\n## print self.curselection()\n return \'break\'\n\n\n def _button2(self, x, y):\n for l in self.lists: l.scan_mark(x, y)\n return \'break\'\n\n\n def _b2motion(self, x, y):\n for l in self.lists: l.scan_dragto(x, y)\n return \'break\'\n\n\n def _scroll(self, *args):\n for l in self.lists:\n apply(l.yview, args)\n return \'break\'\n\n\n def clickon(self,e):\n self._sortBy(self.columns.index(e.widget[\'text\']))\n\n\n def _sortBy(self, column):\n """ Sort by a given column. """\n\n if column == self.sortedBy:\n direction = -1 * self.direction\n else:\n direction = 1\n\n elements = self.get(0, END)\n self.delete(0, END)\n elements.sort(lambda x, y: self._sortAssist(column, direction, x, y))\n self.insert(END, *elements)\n\n self.sortedBy = column\n self.direction = direction\n\n\n def _sortAssist(self, column, direction, x, y):\n c = cmp(x[column], y[column])\n if c:\n return direction * c\n else:\n return direction * cmp(x, y)\n\n def curselection(self):\n return self.lists[0].curselection()\n\n\n def delete(self, first, last=None):\n for l in self.lists:\n l.delete(first, last)\n\n\n def get(self, first, last=None):\n result = []\n for l in self.lists:\n result.append(l.get(first,last))\n if last: return apply(map, [None] + result)\n return result\n\n \n def index(self, index):\n self.lists[0].index(index)\n\n\n def insert(self, index, *elements):\n for e in elements:\n i = 0\n for l in self.lists:\n l.insert(index, e[i])\n i = i + 1\n\n\n def size(self):\n return self.lists[0].size()\n\n\n def see(self, index):\n for l in self.lists:\n l.see(index)\n\n def', 'title': u'this with some improved'}], 'desc': u'This is a compound widget that gangs multiple Tk Listboxes to a single\nscrollbar to achieve a simple multi-column scrolled listbox. Most of\nthe Listbox API is mirrored to make it act like the normal Listbox\nbut with multiple values per row.'}, {'comments': [{'comment': u'Carp {\nI tried this class on a DAO 3.51 db (yes I changed the Dispatch() method to use the correct engine) & it failed on in the writeColumn() function. The constant dbByte was not recognized. Since this is the first "if" comparison in the function, my guess is that the other constants also do not map. Using the PythonWin debugger I could not access the object "const." My guess is the "const" object is not accessing the DAO constants (of which, dbByte is one).\n}\n MG Foster', 'title': u'Errors in "Reverse engineer MS Access/Jet databases"'}, {'comment': u"Wow! What a great tool!\n\nIs it possible to distinguish between <tt>char</tt> and <tt>varchar</tt> fields? In Access the former are fixed length and values are padded with spaces. Access creates variable length text fields by default and there appears to be no way to instruct it otherwise (using Access itself). \n\nIt is possible to distinguish between fixed- and variable-length text fields via ODBC (ColdFusion Studio's ODBC browser can do it) so I guess you can get that information via ADO. Otherwise it is probably better to generate <tt>varchar</tt> fields instead of <tt>char</tt> ones. Michael Strasser", 'title': u'Can you distinguish between CHAR and VARCHAR fields?'}, {'comment': u'Not sure what is wrong, but I have successfully run this script under DAO 3.51 and 4.0, without errors. I repeated a test with DAO 3.51 on a Jet DB created with Access97, to be certain.', 'title': u'Re: Errors in "Reverse engineer MS Access/Jet databases", MG Foster, 2001/04/02'}, {'comment': u'I did get it to work. There has to be a Python byte code library\nof the DAO library. If you have PythonWin open it & make sure you\ndon\'t have any scripts in the edit window. From the main menu, select\nTools > "COM Makepy Utility." When the "Select Library" dialog box\nopens, look for the DAO library you want to make into a Python byte\ncode library & click it (it should be like "Microsoft DAO 3.5\nLibrary"). After this is accomplished the "Reverse Engineering" script worked.', 'title': u"MG's fix to his Carp"}, {'comment': u"You can also solve this problem by adding the following snippet of code:<br>\n<pre>\n# Use these commands in Python code to auto generate .py support\nfrom win32com.client import gencache\ngencache.EnsureModule('{00025E01-0000-0000-C000-000000000046}', 0, 5, 0)\n</pre></br>", 'title': u'Another (more elegant?) solution'}, {'comment': u' I tried the jet2sql.py program at\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52267 and got the error --\n<br><br>\nC:\\NASS\\DATA>c:\\python22\\python jet2sql.py ag_co_co.mdb ag_co_co.sql\n<br><br>\nReverse engineering ag_co_co.mdb to ag_co_co.sql\n<br><br>\n Tables.Traceback (most recent call last):<br>\n File "jet2sql.py", line 247, in ?\n jetEng.writeTable(tabl)<br>\n File "jet2sql.py", line 34, in writeTable<br>\n self.writeColumn(col.Name, col.Type, col.Size, col.Required,\ncol.Attributes,\n col.DefaultValue, col.ValidationRule, currTabl.Fields.Count-cn)<br>\n File "jet2sql.py", line 76, in writeColumn<br>\n if colType == const.dbByte: dataType = "Byte"<br>\n File "C:\\Python22\\lib\\site-packages\\win32com\\client\\__init__.py", line 168, in __getattr__<br>\n raise AttributeError, a<br>\nAttributeError: dbByte<br>\n<br>\n Any ideas?\n<br><br>\n Thanks,\n<br><br>\n Seth', 'title': u'jet2sql.py problem -- AttributeError: dbByte'}, {'comment': u'But it was solved by using makepy to generate class information for the database engine that I was using (DAO.DBEngine.36). ', 'title': u'I had the same problem...'}, {'comment': u'This is a fabulous utility.<br>\nOne enhancement on some applications though ... <br>\nSample Error Message:<br>\n**************<br>\n Tables.Traceback (most recent call last):<br>\n File "jet2sql.py", line 247, in ?<br>\n jetEng.writeTable(tabl)<br>\n File "jet2sql.py", line 66, in writeTable<br>\n self.writeLine(sql,"",1)<br>\n File "jet2sql.py", line 225, in writeLine<br>\n sqlfile.write(strLine)<br>\nUnicodeEncodeError: \'ascii\' codec can\'t encode character \'\\u03bc\'in position 52: ordinal not in range(128)<br>\n**************<br>\nunicode 03bc is small greek letter mu<br>\nThe Fix after much futzing around was:<br>\n*********<br>\nchanged line 66<br> \nfrom:<br>\nself.writeLine(sql,"",1)<br>\nto:<br>\nself.writeLine(sql.encode(\'UTF-8\'),"",1)<br>\n*********<br>\nWorked beautifully', 'title': u"UnicodeEncodeError: 'ascii' codec can't encode character "}, {'comment': u'getting DAO 3.6 working with python 2.4 on Windows XP SP2<br>\n*****<br>\nHad to get pythonWin (pyWin32) working first<br>\nDownloaded from<br>\nhttps://sourceforge.net/projects/pywin32/<br> \nexecuted the .msi<br>\nhad a complaint about mfc71.dll<br>\ndownload mfc71.dll from<br>\nhttp://starship.python.net/crew/mhammond/downloads/mfc71.dll<br> \nstuck it in Windows/System32 <br>\n****<br>\nnow for DA0 3.6<br>\nfrom Mark Hammonds superlative extensions<br>\nPythonWin ->tools -> COM makepy utility<br> \n-> from "Select Library" panel scroll down select \'Microsoft DAO 3.6 Object Library (5.0)<br>\nclick OK<br>\nyou\'re off ...', 'title': u'Same thing DAO 3.6 COM not configured'}, {'comment': u'<pre>\nI was using this in Windows XP, Python 2.4. First, I was getting this error,\n----\n Tables.Traceback (most recent call last):\n File "jet2sql.py", line 247, in ?\n jetEng.writeTable(tabl)\n File "jet2sql.py", line 34, in writeTable\n self.writeColumn(col.Name, col.Type, col.Size, col.Required, col.Attributes,\n col.DefaultValue, col.ValidationRule, currTabl.Fields.Count-cn)\n File "jet2sql.py", line 76, in writeColumn\n if colType == const.dbByte: dataType = "Byte"\n File "C:\\Python24\\lib\\site-packages\\win32com\\client\\__init__.py", line 168, in\n __getattr__\n raise AttributeError, a\nAttributeError: dbByte\n---\n\nand it was because python didn\'t know anything about the constant dbByte in the constants\nclass. I fixed it by using the "COM Makepy Utility" to generate the Microsoft DAO 3.6-specific\nPython stub so the named constants will be available.\n\n\nThe "invalid syntax" error came next.\n\n---\n File "C:\\jet2sql.py", line 257, in ?\n for qry in jetEng.dtbs.QueryDefs:\n \n __import__("win32com.gen_py." + dir_name + "." + child)\n File "C:\\Python24\\lib\\site-packages\\win32com\\gen_py\\00025E01-0000-0000-C000-000000000046x0x5x0\\_QueryDef.py", line 61\n "LastUpdated": (1610809345, 2, (12, 0), (), "LastUpdated", None),\n\t\t"MaxRecords": (1610809375, 2, (3, 0), (), "MaxRecords", None),\n ^\n SyntaxError: invalid syntax\n---\n\nand that was fixed by commenting out the "LastUpdated" line in _QueryDef.py. \nThen yet another "invalid syntax" error,\n\n---\n \n File "C:\\Python24\\lib\\site-packages\\win32com\\gen_py\\00025E01-0000-0000-C000-000000000046x0x5x0\\_QueryDef.py", line 140\n ((\'Updatable\', \'pb\'), 1610809353, (1610809353, (), [(16395, 10, None, None)], 1, 2, 4, 0, 68, (3, 0, None, None), 0)),\n\t((\'Connect\', \'pbstr\'), 1610809354, (1610809354, (), [(16392, 10, None, None)], 1, 2, 4, 0, 72, (3, 0, None, None), 0)),\n ^\n SyntaxError: invalid syntax\n---\n\nwhich was fixed by commenting out the "Updatable" line again in _QueryDef.py\n\nOverall, this is a very useful tool.\n</pre>', 'title': u'_QueryDefs.py errors'}, {'comment': u"I have not used this script in quite some time, as I have not used Access/Jet databases much in the part few years. After a recent conversation, I checked the comments on this recipe, and was plesantly surprised that someone found it useful within the year!\n\nTesting the script on Python 2.5 with pywin build 209.1 on WinXPsp2, I find the script still works with out modification. The one step that is necessary is to run the COM Makepy utility (part of Mark Hammond's excellent Win32 extensions) against the DAO 3.6 library.\n\nAfter noting the recent comments, I was going to update the script to use ADO, but decided if the DAO version still runs as-is, why reinvent the wheel.", 'title': u'MakePy necessary'}], 'desc': u'Reads the structure of a Jet (Microsoft Access .MDB) database file, and creates the SQL DDL necessary to recreate the structure. \n\nOriginally written to aid in migrating Jet databases to larger RDBMS systems, through E/R design tools, when the supplied "import" routines missed objects like indexes and FKs.\n\nA first experiment in Python, that became an often used tool.'}, {'comments': [{'comment': u'This is a nice class that people will find useful, but it needs some work.\n<br><br>\nI see a potential ERROR in __delitem__. The list.remove() command\nremoves the *first* matching item in the list. So if two items have\nthe same value, trouble will ensue if you try to remove the second\nof these two items. The key of the second item will be removed \nand the value of the *first* item will be removed. This will distort\nthe key,value alignment of the dict for all items between the first\nand second item mentioned.<br>\nSOLUTION: find the index of the key you are deleting, delete the key,\nand then delete the value at the same index.\n<br><br>\nAlso, a WARNING:<br>\n__getitem__ returns "None" when a key is not present.\nThis is instead of raising a KeyError like a regular dict.\n</br></br></br></br></br></br>', 'title': u'not entirely unlike a dict'}, {'comment': u'Using index() to locate a value in the _values list may be time-expensive if there are a large number of items. It may be better for the class to use its own dictionary to store the items (albeit at the cost of space), with the _keys list keeping track of the order.', 'title': u'Using index() may be time-expensive'}, {'comment': u'Of course I meant the _keys list rather than the _values list!', 'title': u'Correction'}, {'comment': u'def __len__ (self):\n return len(self._keys)', 'title': u'Typos'}], 'desc': u'This is a class that acts like a dictionary, except that it maintains insert order.\nThis can be useful when you wish to associate two objects in a key-value manner and would like to use a dictionary interface to access the elements, but you need to remember what order the elements were added'}, {'comments': [], 'desc': u'This piece of code takes in two infinite sequences, and, with the help of a cute math function, can cross these two together into another infinite sequence. (This is related to the diagonalization proof that the rationals are countable.) It should guarantee that, given enough time, we can reach any particular element.'}, {'comments': [{'comment': u'Nice job Alex. This is something I definitely could use.\nBill Tate', 'title': u'This will be a great help to me'}, {'comment': u'The page: PythonSpeed http://wiki.python.org/moin/PythonSpeed recommands using module operator instead of lambdas. (http://docs.python.org/lib/module-operator.html)\n<br>\nFor example:\n<pre>\nimport operator\n[...]\ndef __add__(self, other):\n return vector(map(operator.add, self, other))\n</pre>\n<br>\n<pre>\n--\nMaxime Biais\nhttp://www.biais.org\n</pre>', 'title': u'replace lambda by module operator'}], 'desc': u"This vector class stores elements in a list and hence allows the 'vector' to grow \ndynamically. Common mathematical functions (sin, cosh, etc) are supported elementwise\nand so are a number of 'external' operations (dot for the inner product between vectors,\nnorm, sum etc.). This class does not rely on NumPy but can be used in conjunction with\na 'sparse' matrix class to solve linear systems. Tested using Python 2.0 and Jython 2.0."}, {'comments': [{'comment': u"Change the name of the 'map' function - to avoid confusion with\nthe built-in function of the same name. Nick Efford", 'title': u' '}, {'comment': u"Following a comment, I changed the function name 'map' to 'strRgb' to avoid a clash \nwith the built-in function. --Alex.", 'title': u'Colormap'}, {'comment': u'Here is some code to return a html color string:\n<pre>\ndef htmlRgb(mag, cmin, cmax):\n return "#%02x%02x%02x"%rgb(mag, cmin, cmax)\n</pre>\n\nUsage:\n<pre>\ncmin = 0\ncmax = 100\nof = open("t.html", "w")\nof.write( """<html > <body> <table>""")\nfor i in range(cmin, cmax):\n of.write( """<tr"><td bgcolor="%s">%d</td></tr>"""%( htmlRgb( i, cmin, cmax), i ) )\n""" )\nof.write("""</table> </body> </html>""")\n</pre>', 'title': u'HTML color codes'}], 'desc': u"These functions, when given a magnitude 'mag' between cmin and cmax, return\na colour tuple (red, green, blue) on a 0 to 255 scale. The tuple can consist of strings\n(strRgb) as required in Tk calls, or integers (rgb) as required in Java applications. "}, {'comments': [{'comment': u"Where'd the code go? \n -- Brett Morgan", 'title': u'Uhh Source Code?'}, {'comment': u"This is great stuff!\n\nJust a little note. Line that reads import sparse isn't needed.", 'title': u'great work!'}, {'comment': u'This is really cool stuff. I suggest that it <br>\nbe made into a python module. Probably too big<br>\nfor the Cookbook... ;-)<br>\n<br><br>\n-Anand', 'title': u'Cool stuff'}, {'comment': u"I think there's a typo in __mul__; the res = csparse() should be res = sparse(), no?", 'title': u'Typo?'}, {'comment': u"You're right. Thanks for spotting this typo. --Alex.", 'title': u' '}], 'desc': u"'sparse' is a matrix class based on a dictionary to store data using 2-element tuples (i,j)\n as keys (i is the row and j the column index). The common matrix operations such as \n'dot' for the inner product, multiplication/division by a scalar, indexing/slicing, etc. are\noverloaded for convenience. When used in conjunction with the 'vector' class, 'dot'\nproducts also apply between matrics and vectors. Two methods, 'CGsolve' and \n'biCGsolve', are provided to solve linear systems. Tested using Python 2.2."}, {'comments': [{'comment': u'Formatting of report modified to keep columns in line when the server name is less that 5 characters.', 'title': u'Minor Update'}], 'desc': u'Reads a file containing a list of share names, and prints a report of the current free space on the volumes.\n\nSee the end of the source for an example of the required DRIVESPACE.CFG file.'}, {'comments': [], 'desc': u'Before overwriting an existing file it\'s often desirable to make a backup. This recipe emulates the behavior of Emacs by saving versioned backups. It\'s also compatible with the marshal module, so you can save versioned output in "marshal" format.'}, {'comments': [{'comment': u'Useful little gadget. Michael Chermside', 'title': u' '}, {'comment': u"I recognize some of the code I used in writing one of the Usenet posting the author mentions, however it lacks the sample output comments like I had in my code. I guess I'll just post my version and duke it out that way... :) Olivier Dagenais", 'title': u'Could use some sample output'}], 'desc': u"The function printexpr() takes a Python expression, and prints it's value, and the filename and line from which printexpr() is called. This is useful when debugging programs. The code is based off a couple of Usenet postings that I merged into one.\n"}, {'comments': [{'comment': u'This seems to have trouble with XHTML-style self-closed elements, for instance br, hr and img. When those such elements are encountered, the stripping parser will output a single greater-than character.', 'title': u'Problems with XHTML'}, {'comment': u"I'm not sure when HTMLParser.HTMLParser was introduced to the python library, but my guess is after Itamar wrotes this. You can use that instead of sgmllib.SGMLParser. Just change the import:\n<pre>\n import HTMLParser\n</pre>\ninstead of \n<pre>\n import sgmllib\n</pre>\nand change\n<pre>\n class StrippingParser(sgmllib.SGMLParser):\n</pre>\nto\n<pre>\n class StrippingParser(HTMLParser.HTMLParser):\n</pre>\n\nYou should be all set ;-)", 'title': u'Updated for XHTML'}, {'comment': u'Thanks! Using HTMLParser instead of sgmllib does indeed fix that issue. (The __init__() method of StrippingParser needs to be changed, too, of course.)', 'title': u'Thanks!'}, {'comment': u"The change over to HTMLParser.HTMLParser doesn't leave the elements specified in valid_tags -- it strips out all tags. The method unknown_starttag is not called at all.", 'title': u"Doesn't leave valid_tags elements anymore"}], 'desc': u'Sometimes we are getting HTML input from the user. We want to only allow valid, undangerous tags, we want all tags to be balanced (i.e. an unclosed <b> will leave all text on your page bold), and we want to strip out all Javascript.\n\nThis recipe demonstrates how to do this using the sgmllib parser to parse HTML. '}, {'comments': [{'comment': u"As has been noted, the (cond and val_1 or val_2) technique suffers from the fact that val_1 can't be false, while the disadvantage of the function approach is that it doesn't exhibit shortcircuit behaviour. However there is an elaboration of the and-or technique which does accomodate val_1 being false while still exhibiting shortcircuit behaviour (though perhaps it can't claim to be pretty!):\n\n (cond and [val_1] or [val_2])[0]\n\nEnclosing val_1 in a list ensures that it will be true. \n Hamish Lawson", 'title': u'Accomodating false val_1 while keeping shortcircuit behaviour'}, {'comment': u'It is *very* important to point out that\n<code>( cond and val_1 or val_2 )</code> is not the\nsame as <code>( cond ? val_1 : val_2 )</code> unless\nval_1 is guaranteed not to be false.\n<P>\nBecause of this, I would recomend including yet another\napproach... that of defining a utility function. Here\'s\nmine:\n\n<pre>def if_else(condition, trueVal, falseVal):\n if condition:\n return trueVal\n else:\n return falseVal\n</pre>\n\nThen I just use it in code as\n<pre>\n x = if_else( y>3, 3*y+1, None );\n</pre>\n\nAnd the disadvantage here is that there is no\n"short-circuiting"... both options are evaluated\neven if they aren\'t needed (in the example above,\nif y==2, then 3*y+1 will still be calculated).\n<p>\n-- Michael Chermside Michael Chermside', 'title': u'Important note and another approach'}, {'comment': u'Here\'s a technique that, while it isn\'t equivalent to a ? b : c, is\noften applicable in the same situations:\n\n<pre># multiply by result of condition<br>for i in range(1,3):<br> print "The loop ran %d time%s" % (i, \'s\' * (i != 1))<br>\n</pre> Brent Burley', 'title': u'One more variation'}, {'comment': u'It may be worth noting that the construct "a and b or c" only works as a simulation of the ternary operator if the value of b is always true (i.e. not any of zero, the empty string, the empty list or None). Hamish Lawson', 'title': u' '}, {'comment': u'The Algorithm category contains an entry by Alex Martelli on exactly this topic, with at least two solutions not included here...', 'title': u'simulating the ternary operator'}, {'comment': u"There's also an Python FAQ on the topic:<br>\nhttp://www.python.org/cgi-bin/faqw.py?query=ternary&querytype=simple&casefold=yes&req=search<br>\n<br>\nNote that the short circuit behaviour might be really necessary if evaluating b or c\nhas major side effects such as deleting a file. If that's the case I would rather use\na plain if-else construct than using (a and [b] or [c])[0] from the FAQ.<br>\n<br>\nIf there are no side effects I would prefer (b, c)[not a] or still the if-else thing.", 'title': u'a? b : c emulation is Python FAQ 4.16'}, {'comment': u"You can also do<pre>\n 's'*(i!=1)\n</pre>which is as close to obfuscated python as we can get.", 'title': u'Can also use the overloaded multiplication operator for strings'}, {'comment': u"Just kidding. I use the exact same utility function and find it much cleaner than any of the approaches in the recipe (maybe it's just me). I chose the name 'iif' because that's what it is called in VB. Whoddathunk I'd ever use VB for inspiration :-)", 'title': u'iif only you had chosen a better name ;-)'}, {'comment': u'In the Python FAQ 1.2.11 "Is there an equivalent of C\'s "?:" ternary operator?" the function solution given is<br>\n<br>\n<pre>def q(cond,on_true,on_false):\n if cond: \n if not isfunction(on_true): return on_true \n else: return apply(on_true)\n else:\n if not isfunction(on_false): return on_false \n else: return apply(on_false)</pre>\n<br>\nYou need to lambda: b or c if they are functions to prevent execution. However apply() is deprecated since release 2.3.\n<br>\nA much simpler and more efficient solution I use is \n<br>\n<pre> q=lambda a,b,c: (a and [b] or [c])[0]</pre>\n<br>\nyou still need to lambda: b or c functions but it does not use deprecated functions.<br>', 'title': u'a bound lambda solution'}, {'comment': u"First following stefan's comment I now use \n\n<pre>q=lambda a,b,c: (b,c)[not a]</pre>\n\nand secondly because this is a short circuit and the arguments are not passed to another function, you dont need to lambda: b or c if it is a fucntion to prevent side effects!", 'title': u'update'}, {'comment': u'If only I could edit my comments :-( - You still to lambda b or c if fucntions to avoid side effects.', 'title': u'update to update'}, {'comment': u'<pre>\nimport inspect\n# inspect.isfunction would not check for C functions.\n\ndef if_else_apply(condition, ifTrue, ifFalse, *args, **kwds):\n ""Apply ifTrue or ifFalse to args, but not both.\n >>> if_else_apply(False, sys.stderr.write, sys.stdout.write, \'No error\')\n No error\n """\n if condition:\n if not inspect.isroutine(ifTrue): return ifTrue \n else: return ifTrue(*args, **kwds)\n else:\n if not inspect.isroutine(ifFalse): return ifFalse \n else: return ifFalse(*args, **kwds)\n</pre>', 'title': u'A more flexible version'}, {'comment': u'Hey,\n<br><br>\nI got the idea for this function from code in "Python and Tkinter Programming" by John E. Grayson:<br><br>\n<pre>\ndef ImIf( bCondition, uTrue, uFalse ):\n #\n from operator import truth\n #\n return ( uFalse, uTrue )[ truth( bCondition ) ]\n</pre><br>\n"ImIf" is for Immediate IF, which is what Microsoft calls it, maybe someone else might call it that, too. \n<br><br>\nI believe it is truly and demonstrably "lazy". One can test it with these:\n<br><br>\ndef SayTrue(): print "True"\n<br><br>\ndef SayFalse(): print "False"\n<br><br>\nso \n<br><br>\nImIf( Value, SayTrue, SayFalse )()\n<br><br>\nprints either "True" or "False" but not both.\n<br><br>\nI hope this is helpful.\n<br><br>\nRick Graves', 'title': u'better ternary operator?'}, {'comment': u'This was my first post to the cookbook or similar, and I have learned that I should read the prior postings carefully before adding my own. I had recently finished reading the second edition of the hard copy cookbook, and the ternary operator presented there did not hit the spot for me. I was a little excited after seeing code in "Python and Tkinter Programming" that could be used in a function that would hit the spot. <br><br>\n\nThe file into which I would logically put my function already imported "truth" as a global, so I did not think hard about how to implement the function without it. It is obviously better to use "not", as in Martin Freedman\'s lambda implementation, as "not" does not need to be imported. So my function could become\n\n<pre>\ndef ImIf( bCondition, uTrue, uFalse ):\n #\n return ( uTrue, uFalse )[ not bCondition ]\n</pre>\n\nSo I see two related issues, a) which is better, an anonymous lambda or named function, and b) if using a named function, what should be the name. \n<br><br>\nAlthough I am one of those who prefer a function named with def over a lambda any day, for "the ternary operator," I personally would rather call an existing function with a short, descriptive name than type out the lambda line every time I wanted this function. \n<br><br>\nThe name "ternary" has to do with 3, as the function takes 3 parameters/arguments, which seems to be unusual in the C world. But I have lots of functions that take 3 parameters/arguments, so the name "ternary" does not seem descriptive to me. From that standpoint, "immediate if" seems more descriptive, but I admit "immediate if" is already etched into my brain. \n<br><br>\nBut I am not pushing "immediate if" -- if you want to have a named function rather than type out an anonymous lambda, use any name that works for you. ', 'title': u'more about ternary operator'}], 'desc': u'People coming from C, C++ or Perl might miss the so-called ternary operator ?: (condition ? then-expr : else-expr). It\'s most often used for avoiding several lines of code and temporary variables for very simple decisions, like printing the plural form of words after a counter (see example code).\n\nThere are two ways to get the same effect in Python: selecting one of two values from a tuple, or using the special behaviour of the "and" and "or" operators in Python. The second method has the advantage that only ONE of the two possible expressions is evaluated, and is thus more close to the behaviour of ?: as defined by C.'}, {'comments': [{'comment': u'I had to add the following function to get this script running:<br><br><br>\n\n\ndef getEnvValue(value):<br>\n\tenv = os.environ<br>\n\treturn env[value]<br>', 'title': u'GetEnvValue missing'}], 'desc': u'The following are some useful functions to build URLs within a CGI script, for example to send a HTTP redirection header (see example).'}, {'comments': [], 'desc': u'The following function creates a map of all members of a class, navigating ALL of the base classes in the correct order. This can be used for various purposes, like checking whether a certain method is defined anywhere in a class hierarchy.'}, {'comments': [{'comment': u"Cool example! Please discuss more in-depth what you're doing, i.e. what \nfor are you using UserDict, __call__, __nonzero__, and __getattr__ ?", 'title': u'Discussion too short'}, {'comment': u'definitely needs more discussion, particularly a critical examination of the anything-but-obvious design choices, yet the basic idea seems just fine... at least when renamed sensibly, e.g. to "Multicast" rather than the very generic and imprecise "Delegate"...!\n', 'title': u'please do beef this up AND rename it...!'}, {'comment': u"You are right: Delegate is not the best name for this class. I'm taking up your suggestion 'Multicast'.", 'title': u'Name change'}, {'comment': u"The reason for UserDict subclassing is that there has to be a way to register delegation targets on this class. I could have used a 'register' method and, to be complete, an 'unregister' method and then an 'exists' method and so on, but I wanted to leave the class short and crisp, so the bookkeeping gets done via the convenient dictionary interface.\n<br><br>\n__getattr__ returns a Multicast that wraps the object attributes for which the multicasting should happen. Since Multicast has no attributes of its own (other than UserDict's), this meta-method gets called *every* time an attribute is accessed. So every attribute of Multicast is yet another Multicast.\n<br><br>\nAnd this is why there is a __call__ method. If you want to make a multicasting method call like <pre>multicast.method()</pre> you first get a Multicast object returned via __getattr__ which wraps all 'method'-attributes of your delegation targets. After that the __call__ meta-method is invoked which will provide the real method calls.\n<br><br>\n__nonzero__ is there to make Multicasts usable in logical contexts: <pre>if multicast.closed: print 'Closed'</pre> will print 'Closed' if all 'closed'-attributes of your delegation targets are true. The operator.truth call in __nonzero__ is needed because an integer must be returned (doing otherwise is a TypeError).\n<br><br>\nThe example gives a hint how I came to write this class. I had a bunch of log files which needed to get the same messages, and Multicast did this quite fine.", 'title': u'More discussion'}, {'comment': u"I've found this recipe to be very useful and have added a couple enchancements which I thought I'd share.<br>\n\n<br>\n\nFirst of all, multicasting the setting of attributes is very straight-forward since direct assignment is not normally used in underlying dictionary class:<br>\n\n<pre>\n def __setattr__(self, name, value):\n for object in self.values():\n setattr(object, name, value)\n</pre>\n\nSecondly, the operations being invoked through __call__ may take a long time to complete. Here's a way to run them concurrently and produce the same result as the original recipe:<br>\n\n<pre>\n def __call__(self, *args, **kwargs):\n import threading\n lock = threading.RLock()\n result = {}\n\n def invoke(alias, object):\n value = object(*args, **kwargs)\n lock.acquire()\n result[alias] = value\n lock.release()\n\n threadlist = [threading.Thread(\n target=invoke, args=item)\n for item in self.items()]\n for thread in threadlist:\n thread.start()\n for thread in threadlist:\n thread.join()\n return self.__class__(result)\n</pre>", 'title': u'Suggested Enhancements'}, {'comment': u'If you use the __setattr__ as described above you get infinite recursion errors on Python 2.3.4 when you create an instance of Multicast with no parameters (at least). The fix below, which I got from Blake Winton, fixes the problem.\n\n<pre>\n def __setattr__(self, name, value):\n if name == "data":\n self.__dict__[name]=value\n return\n for object in self.values():\n setattr(object, name, value)\n<pre></pre>\n</pre>', 'title': u'Fix for __setattr__'}], 'desc': u"Use the 'Multicast' class to multiplex messages/attribute requests to objects which share the same interface."}, {'comments': [{'comment': u'I think that % string operator enables you to do almost the same\nmore efficiently.\n\n<pre>\ntemplate = "ttt %(x)s ttt"\nfor x in range(3) :\n print template % locals()\n\nresult:\nttt 0 ttt\nttt 1 ttt\nttt 2 ttt\n</pre>', 'title': u'% string operator '}], 'desc': u"This class encapsulates a string with embedded variable names. They are usually evaluated when the object's __str__() method is called. You can specify that they be evaluated when the object is created by including the immediate argument to the constructor. The doc string at the top of the module has an example of its use.\n\nItamar Shtull-Trauring's printexpr.py inspired me to try this out."}, {'comments': [{'comment': u'What is a bound-method?', 'title': u'Question'}, {'comment': u'Cfr http://www.python.org/~jeremy/tutorial/outline.html, http://www.python.org/doc/current/lib/typesmethods.html, http://www.python.org/doc/current/ref/types.html.\n', 'title': u'what is a bound method'}], 'desc': u'Python functions are naturally polymorphic on their arguments, and checking argument types loses polymorphism -- but we may still get early checks and some extra safety without any real cost.'}, {'comments': [], 'desc': u'If you have the freedom to choose your abscissas and your integrand is smooth or has\na log singularity, then this script is for you. It computes the definite integral of a user\ndefined function over the interval [a, b]. The user can specify the number of Gauss \npoints (1 <= ng <= 12), the default being ng=10.'}, {'comments': [{'comment': u'In my browser (IE 5.5) the length of the docstring lines makes the page very wide. A nice idea, though it would be even nicer if database fields could be accessed as attributes (assuming legal Python names). ', 'title': u'Script layout needs tweaking'}], 'desc': u'When you get a set of rows from a cursor.fetch[one, many, all] call, it is sometimes helpful to be able to access a specific column in a row by the field name and not the column number. This function takes a DB API 2.0 cursor object and returns a dictionary with column numbers keyed to field names.'}, {'comments': [], 'desc': u'To use multiple threads, you must release the Python thread-lock.\nThe simplest way with SWIG is to use an except directive.For example, \nMark Hammond does the following in the Win32 extensions:\n'}, {'comments': [{'comment': u'The title says it all: Python 2.2 allows subclassing of built-in types, so classic inheritance vs. delegation can be used in these cases. In particular, the example given can be simplified by creating a subclass of the built-in file type.\n\nE.g.:\n\n<pre>\nclass UpperCaseFile(file):\n def write(self, s):\n return file.write(self, s.upper())\n\n def writelines(self, strings):\n ...\n</pre>', 'title': u'Python 2.2 allows subclassing of built-in types'}, {'comment': u"the __getattr__ recurses.\n\nIt should look like so:\n<pre>\n def __getattr__(self, attr):\n return getattr(self.__dict__['file'], attr)\n def __setattr__(self, attr, value):\n return setattr(self.__dict__['file', attr, value)\n</pre>\n", 'title': u"Unfortunately this doesn't work"}, {'comment': u"__getattr__ is called only *after* the standard mechanisms are unsuccessful, so self.file doesn't invoke a recursive call.", 'title': u'no recursion involved'}], 'desc': u'Python classes cannot inherit from any type, just from other classes. However, automatic delegation (via __getattr__ and __setattr__) can provide pretty much the same functionality as inheritance (without such limits, and with finer-grained control).'}, {'comments': [{'comment': u"Wouldn't a call to time.sleep(0.1) work as well as the select([],[],[],.1) call? I might be missing something, but it seems like the only thing a call to select with three empty lists will do is sleep until the timeout.", 'title': u'Empty Select Necessary?'}, {'comment': u'The concatenation of the program\'s output can be done in \na more efficent way:\n<pre>\n outdata = []\n[...]\n outdata.append(outchunk)\n[...]\n return string.join(outdata,"")\n</pre>\nWith outdata=outdata+outchunk, the data is copyed over and over.\nProbably not really problematic, but at least in theory it may lead to\na quadratic running time. (The same is true of course for errdata...)', 'title': u'Concatenating Output (Little) Inefficent.'}, {'comment': u'I found the approach using tempfiles better:\n<pre>\nclass save_popen2:\n """This is a deadlock save version of popen2 (no stdin), that returns\n an object with errorlevel,out, and err"""\n def __init__(self,command):\n outfile=tempfile.mktemp()\n errfile=tempfile.mktemp()\n self.errorlevel=os.system("( %s ) > %s 2> %s" %\n (command,outfile,errfile)) >> 8\n self.out=open(outfile,"r").read()\n self.err=open(errfile,"r").read()\n os.remove(outfile)\n os.remove(errfile)\n</pre>\n', 'title': u'Differnet Approach: Using Tempfiles'}, {'comment': u'in python 2.3 and I think also in 2.2, FCNTL is deprecated. import fcntl instead. Also, the O_NDELAY constant has been moved to the os module.\n<pre>\nSo in order to get this to work under newer versions of python,\nThe following line:\n fl = fcntl.fcntl(fd, FCNTL.F_GETFL)\nshould be changed to:\n fl = fcntl.fcntl(fd, fcntl.F_GETFL)\n\nand\n\tfcntl.fcntl(fd, FCNTL.F_SETFL, fl | FCNTL.O_NDELAY)\nshould be changed to\n fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)\n</pre>', 'title': u'python 2.3 deprecates FCNTL, replaced by fcntl, and moves constants to os'}, {'comment': u'regarding this code:\n\n<pre>\ndef makeNonBlocking(fd):\n fl = fcntl.fcntl(fd, FCNTL.F_GETFL)\n try:\n fcntl.fcntl(fd, FCNTL.F_SETFL, fl | FCNTL.O_NDELAY)\n except AttributeError:\n fcntl.fcntl(fd, FCNTL.F_SETFL, fl | FCNTL.FNDELAY)\n\n</pre>\n \nI don\'t see the .FNDELAY object defined in either the "fcnt" module or the "os" module.\n\nWhat should I do here to adapt the recipe code to cygwin?\n\nI\'m using cygwin on windows 2000 and windows XP.\n\n<pre>\n (6:0) $ python\nPython 2.2.3 (#1, Jun 8 2003, 14:58:23)\n[GCC 3.2 20020927 (prerelease)] on cygwin\nType "help", "copyright", "credits" or "license" for more information.\n>>>\n\n~\n\n (7:0) $ bash --version\nGNU bash, version 2.05b.0(9)-release (i686-pc-cygwin)\nCopyright (C) 2002 Free Software Foundation, Inc.\n\n</pre>', 'title': u'cygwin and FCNTL.FNDELAY'}, {'comment': u"<pre>\nI based my program on getCommandOutput for a while\nbut the performance just got worse with newer versions\nof linux (different implementations of fork I suppose).\nAnyway I had a closer look and getCommandOutput is\nneedlessly looping over the descriptors. I.E. you\nneed to remove outfd or errfd from the select if\nouteof==1 or erreof==1 respectively. Then you can\nremove the select(....,.1) kludge.\n\nI've done my own extensively tested version here,\nthat has the added functionality of an optional timeout:\n\nhttp://www.pixelbeat.org/libs/subProcess.py\n</pre>", 'title': u'major performance bug'}, {'comment': u'There are several problems with this recipe... I know, I\'ve made them all :-) I even wrote up a draft PEP addressing what I saw as Python problems which I abandoned after I understood things better. See the following thread;\n<br>\nhttp://mail.python.org/pipermail/python-dev/2005-March/052263.html\n<br>\nThe problems are;\n<br>\n1) using file objects in non-blocking mode is bad. File object\'s behaviour is not clearly defined in non-blocking mode. Sure file.read() kinda works, but file.write() is broken, so you would hit serious problems with this approach if you had to also write data to the popened process. You should use os.read() and os.write() instead.\n<br>\n2) you don\'t need non-blocking mode. The os.read() and os.write() methods will do incomplete reads/writes in blocking mode. They will only block if nothing at all could be read/written. However, you should never attempt to read/write to a blocked file, because the select() tells you what files can at least be partialy read/written and hence will not block.\n<br>\n3) As pointed out by P\xe1draig Brady, it is bad to include "finished" files in the select() lists. When os.read() returns nothing, you have reached the end of the input, so close it and remove it from the select() list for any further iterations. The same goes for output files; close and remove them when you have written all your data. Otherwise your select statement imediately completes returning the empty file, and your polling loop races around doing nothing until one of the other files also has something.\n<br>\n4) That second select is ugly. As Bradey Honsinger said, a sleep would have been better to achieve what you wanted here. However, I suspect that the main reason you saw speedups by adding this is that you reduce the "loop racing" explained by point 3).\n<br>\nThis recipe needs to be re-written...', 'title': u'Several problems with this recipe'}, {'comment': u"I tried a slightly modified version of this recipie. And it works well on linux, however I have a hard time making it work on windows. The main problem is that windows doesn't allow select on files. I only do this for strout and stderr, and these are pipes, right? In linux pipes are just exposed as files, but they are really sockets. Anyone know how to make it work on windows?", 'title': u'Windows equivalent?'}], 'desc': u'This recipe shows how to execute a unix shell command and capture the\noutput and error streams in python. By contrast, os.system() sends\nboth streams directly to the shell.\n'}, {'comments': [{'comment': u"Shouldn't that be <pre>\nself.fontStack.append((italic, bold))\n</pre>", 'title': u'minor bugfix needed?'}, {'comment': u"The append(a,b) syntax used to work, though it probably should have been append((a,b)) from the beginning. In any case, I've fixed the bug. Thanks!", 'title': u'Fixed.'}], 'desc': u'This is a complete program that reads an html doc and converts it to\nplain ASCII text. In the spirit of minimalism, this operates as a\nstandard unix filter.\nE.g. htmltotext < foo.html > foo.txt\n\nIf the output is going to a terminal, then bold and underline are\ndisplayed on the terminal. Italics in HTML are mapped to underlining\non the tty. Underlining in HTML is ignored (mostly due to laziness).'}, {'comments': [{'comment': u'We are using this recipe to colorize this very cookbook, thanks. I made a slight change though so that the script uses css and span to allow easy colour manipulation.', 'title': u'Thanks'}, {'comment': u'Doesnt handle continued lines, using the \\ operator.', 'title': u'\\'}, {'comment': u"In its original environment, the code works, see http://purl.net/wiki/python/MoinMoinColorizer. Can't say what causes it not to work in the Cookbook.", 'title': u'\\ works, at some places'}, {'comment': u'Some small changes make it possible to invoke this as (a) a CGI script that uses the PATH_TRANSLATED CGI environment variable to know what file to colorize; (b) a command-line tool that takes the filename from the first argument; or (c) a filter that colorizes whatever it gets from stdin. See http://skew.org/~mike/colorize.py for my version.\n\nTo finish set it up as a handler in Apache, so that when you request a .py file, the file is served up as colorized HTML, you will need to save the script as colorize.cgi (not .py, lest it get confused), and add this to your .htaccess or httpd.conf:\n\n<pre>\nAddHandler application/x-python .py\nAction application/x-python /full/virtual/path/to/colorize.cgi\n</pre>\n\nAlso make sure you have the Action module enabled in your httpd.conf.', 'title': u'Easy to turn this into an Apache handler - serve up colorized .py files!'}, {'comment': u'Based on your version, I made some additional enhancements:<br>\n<br>\n- make script usable as a module<br>\n- use <class> tags and style sheet instead of <style> tags<br>\n- when called as a script, add HTML header and footer<br>\n<br>\nThis version can be found here:<br>\n<br>\nhttp://chrisarndt.de/en/software/python/colorize.html', 'title': u'... and also as a module!'}], 'desc': u'This code is part of MoinMoin (http://moin.sourceforge.net/) and converts Python source code to HTML markup, rendering comments, keywords, operators, numeric and string literals in different colors.\n\nIt shows how to use the built-in keyword, token and tokenize modules to scan Python source code and re-emit it with no changes to its original formatting (which is the hard part).\n\nThe test code at the bottom of the module formats itself and launches a browser with the result.'}, {'comments': [{'comment': u"Thanks for taking the time to contribute this! It really helped me learn how to interface with imaplib. I have a couple of improvements that can reduce the network traffic of this script.\n\nFirst of all, this bit:\n<pre>\ntyp, data = M.search(None, '(UNSEEN UNDELETED)')\n for num in string.split(data[0]):\n try:\n f = M.fetch(num, '(BODY[HEADER.FIELDS (SUBJECT FROM)])')\n m = rfc822.Message(msg(f[1][0][1]), 0)\n</pre>\ncan be updated to this:\n<pre>\ntyp, data = M.search(None, '(UNSEEN UNDELETED)')\nmsg_id = [m for m in data[0].split()]\nmsg_id = ','.join(msg_list)\nmsg_list = M.fetch(msg_id, '(BODY[HEADER.FIELDS (SUBJECT FROM)])')\nfor m in msg_list:\n msg = rfc822.Message(msg(m[1][0][1]), 0)\n</pre>\nThis way, a list of the requested message parts is returned at once instead of hitting the server for each message individually. While we're at it, that last line can be updated to use the email module, like so:\n<pre>\nfrom email.Parser import HeaderParser\n\nfor m in msg_list:\n hp = HeaderParser()\n msg = hp.parsestr(m[1][0][1])\n</pre>", 'title': u'Improvement'}, {'comment': u'The code is organized in an awkward way.\n\nPresentation does not cleanly separate from the core code.\n<br><br>\nThis showed painfully when I wanted to deploy this recipe on a box where\ntcl/Tk was not available. Thus I wanted to replace Tkinter calls so that simply an external program gets called if there is a new mail.\n<br><br>\nIdeally, this should be the matter of replacing a presentation class or function call with another one, leaving IMAP related code intact.\n\nBut the Mailwatcher class just blends everything together with no concern, so I had to actually understand the IMAP code to achieve what I want, and alltogether, work more on it.', 'title': u'rough edges'}], 'desc': u'Polls an IMAP inbox for unread messages and displays the sender\nand subject in a scrollable window using Tkinter.\n\nReads servername, user, and password from ~/.imap file. They must be\non one line, separated with spaces.'}, {'comments': [{'comment': u"This module implements the same feature as the standard library's linecache module. This shows the importance of reading Python's documentation as the library contains solutions to many common problems. ", 'title': u'Thoroughly read the standard library'}], 'desc': u'Some tasks require reading from a set of files in a random manner. Opening and reading files is a time consuming operation even when the operating system is caching the contents of the files in memory. Caching files explicitly can speed up processing greatly especially where the cached form is optimised for likely access patterns.'}, {'comments': [{'comment': u"Very nice approach! Please do not omit the discussion. If this is supposed to help people with\nintermediate python knowledge you should be more specific about when and why the \nproblem you're trying to solve occurs and what's your paricular trick for\nsolving the problem?", 'title': u'Where is the discussion?'}, {'comment': u'Python 2.2 and later support static methods by using the built in staticmethod function. It looks like an ugly hack, but it works.<br>\nFrom the python documentation:<br>\n---\n<pre>\nclass C:\n def f(arg1, arg2, ...): ...\n f = staticmethod(f)\n</pre>\nIt can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.<br>\n---<br>\nIn addition to static methods, python also has classmethods:<br>\nFrom the python documentation:<br>\n---\n<pre>\nclass C:\n def f(cls, arg1, arg2, ...): ...\n f = classmethod(f)\n</pre>\nIt can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class. If a class method is called for a derived class, the derived class object is passed as the implied first argument.<br>\n---', 'title': u'static methods and classmethods in python 2.2 and later'}], 'desc': u'Class methods that do not require an object instance.'}, {'comments': [{'comment': u'For those of you who did not see this on the printed Cookbook: what Guido said! :^)\n<br>\nIn the intro to the Network Programming chapter, on page 329, our dear BDFL said:\n<br>\n"My favorite is Recipe 10.12, which discusses PyHeartBeat: it\'s useful, it uses the socket module, and it\'s simple enough to be a good educational example."\n<br>\nThat was too nice to not let the world know, so thanks, Guido, for your kindness and for Python too!', 'title': u'Let me brag a little... :^)'}, {'comment': u'I spotted two problems:\n\n<br><br>In main():\n\n<pre>\nwhile True:\n try:\n ...\n except KeyboardInterrupt:\n ...\n</pre>\n\nThis will never end, but can be easily solved by putting the while inside the try/except.\n\n<br><br>In Receiver.run():\n\n<pre>\nwhile self.goOnEvent.isSet():\n ...\n data, addr = self.recSocket.recvfrom(5)\n ...\n</pre>\n\nThis will halt until the server receives anything, which might not happen if all clients are down. I modified it to:\n\n<pre>\nwhile self.goEvent.isSet():\n try:\n ...\n except socket.timeout:\n pass\n</pre>\n\nwith in the __init__:\n\n<pre>\nself.recSocket.settimeout(CHECK_TIMEOUT)\n</pre>\n\nThis will eventually respond.', 'title': u"The threaded server won't stop"}, {'comment': u'Thanks for the fixes, they are spot-on. I added them to the recipe, revised the text a bit, and restructured the Twisted server too. It should all be pretty streamlined now. :-)', 'title': u'Thanks, Rogier!'}], 'desc': u'PyHeartbeat detects inactive computers by sending and receveing "heartbeats" as UDP packets on the network, and keeping track of how much time passed since each known computer sent its last heartbeat. The concurrency in the server is implemented using threads first, and then again using the Twisted Matrix framework.'}, {'comments': [], 'desc': u'Python\'s "in" operator is extremely handy, but O(N) when applied to an N-item sequence; if a sequence is subject to frequent "in" tests, an auxiliary dictionary at its side can boost performance A LOT if the values are hashable.'}, {'comments': [{'comment': u'I am trying to write static class methods to class data, and this doesn\'t work for that. Is there a way to do that? Here is the code I was trying to use:\n<pre>\nclass Callable:\n\n def __init__(self, anycallable):\n self.__call__ = anycallable\n\n\nclass Num:\n\n num = 0\n\n def get():\n\n print "Num.get"\n return num\n\n def set(value = 0):\n \n print "Num.set"\n num = value\n\n get = Callable(get)\n set = Callable(set)\n\nif __name__ == \'__main__\':\n\n print Num.set(10)\n print Num.get()\n</pre>', 'title': u'Accessing class data?'}, {'comment': u'Class data needs to be qualified, like so:\n\n<pre>\ndef get():\n print "Num.get"\n return Num.num # qualify w/ classname\n</pre>\n\n--A\n', 'title': u'Accessing Class Data'}], 'desc': u'An attribute of a class-object is implicitly mutated into an unbound-method object if it starts out as a Python-coded function; thus, such functions must be wrapped as other callables if "just calling them" (without an instance-argument) is desired.'}, {'comments': [{'comment': u"> If a statement must be embedded that does NOT end with a colon (e.g. , an assignment statement), then a Python comment MUST terminate its line;\n<br>\nOf course you can use a ';' as well. Looks better.", 'title': u'# at the end of a line'}], 'desc': u'"Templating" (copying an input file to output, on the fly inserting Python expressions and statements) is a frequent need, and YAPTU is a small but complete Python module for that; expressions and statements are identified by arbitrary user-chosen regular-rexpressions.'}, {'comments': [{'comment': u'hello,\n<br>\n\nHow would you sort a dictionary if the keys are not numbers or strings but tuples <br>\ne.g. {(0, 1): 2, (0, 2): 3, ...} <br>\n\n- JJH\n', 'title': u"re: dictionary 'sort'"}, {'comment': u'Where Alist = [(3, 4), (2, 3), (1, 2)], Alist.sort() yields [(1, 2), (2, 3), (3, 4)]. I love this language!', 'title': u'Sorting a list of tuples/lists...'}, {'comment': u'Here\'s some code to sort the keys of a dictionary by\ntheir associated values.\n<pre>\n\nd={1:1,2:2,5:1,10:2,44:3,67:2}\nitems=d.items()\nbackitems=[ [v[1],v[0]] for v in items]\nbackitems.sort()\nsortedlist=[ backitems[i][1] for i in range(0,len(backitems))]\n\nOr as a function:\n\ndef sort_by_value(d):\n """ Returns the keys of dictionary d sorted by their values """\n items=d.items()\n backitems=[ [v[1],v[0]] for v in items]\n backitems.sort()\n return [ backitems[i][1] for i in range(0,len(backitems))]\n</pre>', 'title': u'Sorting dictionary by values'}, {'comment': u'I just came here straight from diveintopython section on dictionaries...\nIs this any different or simmilar to which solution?\n<pre>\n\ndef dictSort(d):\n """ returns a dictionary sorted by keys """\n our_list = d.items()\n our_list.sort()\n k = {} \n for item in our_list:\n k[item[0]] = item[1]\n return k</pre>', 'title': u'newbie sort'}, {'comment': u'def sortedDictValues2(adict):\n keys = adict.keys()\n keys.sort()\n return [*a*dict[key] for key in keys]', 'title': u'typo'}, {'comment': u'<pre>The 2.4 new sorted() function is grand, especially in list abstractions.\n\n>>> di= dict(zip("e d c b a".split(),"egbdf dec cdr both any".split()))\n>>> di.keys()\n[\'a\', \'c\', \'b\', \'e\', \'d\']\n>>> di.items()\n[(\'a\', \'any\'), (\'c\', \'cdr\'), (\'b\', \'both\'), (\'e\', \'egbdf\'), (\'d\', \'dec\')]\n\n## sort by key\n>>> [ (k,di[k]) for k in sorted(di.keys())]\t## (k,v) tuples in resulting list\n[(\'a\', \'any\'), (\'b\', \'both\'), (\'c\', \'cdr\'), (\'d\', \'dec\'), (\'e\', \'egbdf\')]\n\n>>> [ di[k] for k in sorted(di.keys())]\t\t## values only in resulting list\n[\'any\', \'both\', \'cdr\', \'dec\', \'egbdf\']\n\n## sort by value (there is no elegant way to get the key from the value)\n>>> [ k for k in sorted(di.values())]\t\t## values (sorted) only in result\n[\'any\', \'both\', \'cdr\', \'dec\', \'egbdf\']</pre>', 'title': u'List comprehensions and the 2.4 sorted() function'}, {'comment': u'This would sort the dictionary by the field (numeric column) you supply and return the result in form of a list.\n\ndef sort_dict(dictionary, field):\n tmp_list = []\n for key, value in dictionary.items():\n tmp_list.append([key, value])\n tmp_list.sort(key=lambda x:x[field])\n return tmp_list', 'title': u'sort_dict'}, {'comment': u"strange people, making fast things slow, easy things hard<br>\n<br>\nsorting by value ...<br>\n>>> def sortfunc(x,y):<br>\n...         return cmp(x[1],y[1])<br>\n...<br>\n>>> lijst={'een':1,'drie':3,'vier':4,'twee':2}<br>\n>>> items=lijst.items()<br>\n>>> items<br>\n[('drie', 3), ('vier', 4), ('een', 1), ('twee', 2)]<br>\n>>> items.sort(sortfunc)<br>\n>>> items<br>\n[('een', 1), ('twee', 2), ('drie', 3), ('vier', 4)]<br>\n>>> items.sort()<br>\n>>> items<br>\n[('drie', 3), ('een', 1), ('twee', 2), ('vier', 4)]<br>\n>>> <br>\n\nof course reverse sorting would be<br>\n>>> def sortfunc(x,y):<br>\n...          return cmp(y[1],x[1])<br>\n... <br>\n>>> items.sort(sortfunc)<br>\n>>> items<br>\n[('vier', 4), ('drie', 3), ('twee', 2), ('een', 1)]<br>\n>>> <br>\n\nor without the need for an extra list<br>\n>>> sorted(lijst.items(),sortfunc)<br>\n[('vier', 4), ('drie', 3), ('twee', 2), ('een', 1)]<br>\n>>> <br>", 'title': u'why not pass in a function to sort ???????'}, {'comment': u'sorting dictionary d by value:<br>\n> sorted(d.items(), lambda x, y: cmp(x[1], y[1]))<br>\nand reverse sorting:<br>\n> sorted(d.items(), lambda x, y: cmp(x[1], y[1]))', 'title': u'or use a lambda expression'}, {'comment': u'reverse sorting:<br>\n> sorted(d.items(), lambda x, y: cmp(x[1], y[1]), reverse=True)', 'title': u'oops I meant..'}, {'comment': u"It's clear you just came over.\n\nThis will not produce expected results.\n\nRead the top of this page.\n\nDictionaries do not hold ordering information!", 'title': u'Oh my'}, {'comment': u'With python 2.4 you have the key= parameter, so you can say:\n\n<pre>sorted(d.items(), key=lambda (k,v): (v,k))</pre>\n\nkey returns the "sort key" that sort will do the comparison on.', 'title': u'Using the new key= parameter'}], 'desc': u"Dictionaries can't be sorted -- a mapping has no ordering! -- so, when you feel the need to sort one, you no doubt want to sort its *keys* (in a separate list). Sorting (key,value) pairs (items) is simplest, but not fastest."}, {'comments': [{'comment': u"<pre>\nclass Bunch:\n __init__ = lambda self, **kw: setattr(self, '__dict__', kw)\n<pre>\n\nYou could also accept *args and put them in a sequence accessible\nwith [].\n\nWhen python 2.2 permits the above dynamic __dict__ this could be\nbe something like:\n\n<pre>\nclass Bunch(list):\n def __init__(*args, **kw):\n self[:] = list(args)\n setattr(self, '__dict__', kw)\n<pre>\n\n</pre></pre></pre></pre>", 'title': u'Even shorter Bunch'}, {'comment': u'Quite simple extension of the original Bunch, just one extra line:\n\n<pre>\nclass BunchDict(dict):\n def __init__(self,**kw):\n dict.__init__(self,kw)\n self.__dict__.update(kw)\n</pre>\n\nThis has the added benefit that it can directly be printed and it shows its contents in interactive environments like ipython.', 'title': u'Using a bunch as a dictionary'}, {'comment': u'Quite simple extension of the original Bunch, just one extra line:\n\n<pre>\nclass BunchDict(dict):\n def __init__(self,**kw):\n dict.__init__(self,kw)\n self.__dict__.update(kw)\n</pre>\n\nThis has the added benefit that it can directly be printed and it shows its contents in interactive environments like ipython.', 'title': u'Using a bunch as a dictionary'}, {'comment': u'How about just replacing self.__dict__ with self, since self is a dict? <pre>\nclass Bunch(dict):\n def __init__(self,**kw):\n dict.__init__(self,kw)\n self.__dict__ = self\n</pre>\nThen any deletions, modifications, etc. are accessible via both the dict and attribute interfaces.', 'title': u'One dictionary is better than two'}, {'comment': u'For debugging purposes, it\'s nice to have a meaningful string representation. This works for me:\n\n<pre> def __str__(self):\n state = ["%s=%r" % (attribute, value)\n for (attribute, value)\n in self.__dict__.items()]\n return \'\\n\'.join(state)</pre>', 'title': u'String representation'}, {'comment': u"You could simply do something like this, given the current functionality of dict (with kwd args etc.):<br>\n<br>\n<pre>class bunch(dict):\n __getattr__ = dict.__getitem__</pre>\n<br>\nOf course, you won't get the right exceptions etcl., and simply setting __setattr__ the same way won't really work. But it seems to be about as simple as this recipe can get :)", 'title': u'Using dict functionality'}, {'comment': u"As written, pickling and unpickling such an object breaks the\nequivalence between self and self.__dict__. Adding the methods\n__getstate__ and __setstate__ used by the pickle protocol fixes this:\n\n<pre>\nclass Bunch(dict):\n def __init__(self, **kw):\n dict.__init__(self, kw)\n self.__dict__ = self\n\n def __getstate__(self):\n return self\n\n def __setstate__(self, state):\n self.update(state)\n self.__dict__ = self\n</pre>\n\n(Perhaps there's a better way to do this, but it seems to have the\ndesired effect.)", 'title': u'Improvement to handle pickling'}, {'comment': u'Apologies; that was supposed to be a comment on\n\n"One dictionary is better than two", Graham Fawcett', 'title': u'Ugh; follow-up in wrong place'}, {'comment': u'this one leaks memory\njust try:\n\n>>> for i in range(10**9):\n... a = Bunch()\n\nyou need to stay away from circular references', 'title': u'CAUTION'}, {'comment': u'this one leaks memory <br>\njust try: <br>\n<br>\n>>> for i in range(10**9): <br>\n... a = Bunch() <br>\n<br>\nyou need to stay away from circular references', 'title': u'CAUTION'}, {'comment': u'as noted before - this leaks memory!', 'title': u'CAUTION'}, {'comment': u"If your use case is accessing **kw using dot notation then how about:<br><br>\nkw=type('bunch',(), kw)<br><br>\n\nOr, more closely following the 'utility helper' style of the original:<br><br>\n\n<pre>\ndef bunch(**kw):\n return type('bunch',(), kw)\n\nB=bunch(apples=1,pears=2)\nb=B()\nassert B.apples == b.apples and b.apples=1\n\nclass Y(B)\n bannanas=3\n pears=19\n\ny=Y()<br>\nassert y.pears == Y.pears and y.pears != b.pears\n</pre>", 'title': u'Is there an issue with using the type builtin for this ?'}], 'desc': u"Often we want to just collect a bunch of stuff together, naming each item of the bunch; a dictionary's OK for that, but a small do-nothing class is even handier, and prettier to use."}, {'comments': [{'comment': u'<pre>\nI am careful always to return Py_BuildValue("") rather than\nPy_None when I extend or embed Python with C code.\n\nReturning Py_None will not work if you build your C code with a\ncompiler other than the compiler used to build Python itself!\nIMO, this point should be emphasized in the extending and embedding docs.\n\nReturning Py_None anywhere outside the actual Python build is\ndangerous because Py_None is a struct whose layout depends on\n1) the compiler used and\n2) various C/C++ compiler settings.\n\nIn contrast, return Py_BuildValue("") can never fail, because\nPy_BuildValue("") returns a pointer to a struct that was built\nwhen Python was built.\n\nIf your C code does return Py_None, then you must guarantee that\nyour compiler and build settings match the compiler and build\nsettings used to build Python.\n\nFixing the problem at (and in) the C source seems much safer to me.\n\nEdward K. Ream</pre>', 'title': u'why I only use Py_BuildValue("") to return None'}, {'comment': u"This comment about Py_BuildValue() doesn't make sense to me.<br>\n<br>\nMany things ordinarily done in extension modules depend on the compiler's alignment rules matching those of the Python executable. Just off the top of my head:<br>\n<br>\n * using Py_INCREF and Py_DECREF at all<br>\n * using any other macros defined in Python.h, such as PyString_AS_STRING()<br>\n * declaring a static PyTypeObject<br>\n<br>\nIf your compiler settings aren't fully link-compatible with the ones used to build Python, then it seems to me that Py_None is the least of your problems.\n", 'title': u'Eh?'}, {'comment': u'Thanks for this correction. I really made a hash of this posting. For me, replacing Py_None by Py_BuildValue("") got everything working. As you point out, this was really just by accident.<br>\n<br>\nMy original thought was that it would be easier to write extensions if macros like Py_INCREF, Py_DECREF, PyTypeObject, etc. were functions. Replacing macros with functions in the C API would reduce (but not eliminate!) the compiler settings that could cause problems at link time. In particular, compiler settings affect function calls as well. I am acutely embarrassed not to have realized this. Thanks again for setting me straight.<br>\n<br>\nEdward', 'title': u'Ooops'}], 'desc': u'Often a function written in C for Python needs to return nothing in particular -- a "return None" in Python terms; but _don\'t_ just "return Py_None" from C, as that will mess up reference counts!'}, {'comments': [{'comment': u"Here's a slight variant that may or may not have a different appeal.\nAs with the C version, a ? b : c, and the final version here,\nit evaluates only one of b and c, depending on the value of a,\nand then it picks that one, making no assumptions about its truth value:\n\n[a and b, not a and c][not a]\n", 'title': u'"conditionals" in expressions'}, {'comment': u'a ? b : c <==> (a and (lambda:b) or (lambda:c))()', 'title': u'this works too...'}, {'comment': u'Can also abuse slice for syntax that looks more suggestive of a?b:c<br>\n\n>>> cond[0:2:3]<br>\n3<br>\n>>> cond[1:2:3]<br>\n2<br>\n>>><br>\n\nWhere cond previously defined by:\n\n<pre>\nclass cond:\n __getitem__ = lambda self, sl: (sl.start and sl.stop,\n not sl.start and sl.step)[not sl.start]\n\ncond=cond()\n</pre>\n\nCould probably also do something like:\n\nQ(a)[b:c]\n\nIn general __getitem__ and slice objects can be abused to define any ternary or quad(?) operations using [::] syntax.\n</br></br></br></br></br></br>', 'title': u'sugar for a?b:c - cond[a:b:c]'}, {'comment': u"Unfortunately, Doug, your solution is not short circuiting. So it really doesn't meet the requirements. I'll also throw out that this is exactly the kind of abuse seen in C++ which made me decide that I personally don't like operator overloading. It encourages programmers to invent their own strange syntax for their libraries.", 'title': u'Not short circuiting'}, {'comment': u'[falseValue, trueValue][conditionIndex]\n\n<br>\nshould do the ternary operator - and it works like a switch as well...\nno?', 'title': u"Newbie question - why can't I do this? [falseValue, trueValue][conditionIndex]"}, {'comment': u"[falseValue, trueValue][conditionIndex]\n<br>\nshould do the ternary operator - and it works like a switch as well...\nno?\n\nor equivalents\n<br>\n{True: 'trueValue', False: 'falseValue'} [3>4]\n<br>\n('falseValue', 'trueValue')[conditionIndex]", 'title': u"Newbie question - why can't I do this? [falseValue, trueValue][conditionIndex]"}, {'comment': u"The problem is when you use [falseValue, trueValue] syntax, all items of the list are executed. For example:\n<pre>\nli = [1, 2, 3, 4]\nid = 1\nre = [0, li.pop()][not id]\nprint re, li\n</pre>\nIt reads:\n<pre>\n0 [1, 2, 3]\n</pre>\nAnother example of and-or:\n<pre>\nli = [1, 2, 3, 4]\nid = 1\nre = (id and [0] or [li.pop()])[0]\nprint re, li\n</pre>\nIt reads:\n<pre>\n0 [1, 2, 3, 4]\n</pre>\nThus it's different.", 'title': u"Re: why can't I do this? [falseValue, trueValue][conditionIndex]"}, {'comment': u'This needs a bit of defensive programming in cases where exceptions may arise (like division by zero), but, here it is, with examples:\n<pre>\n#!/usr/bin/env python\n#\n#\n#\tdsilvia: 2006/06/25\n#\tHere\'s how it works. It\'s a sequence that is indexed on the conditional.\n#\tIn order to evaluate to a zero/non-zero, the \'not\' of the conditional\n#\tis used, as python generates an error for conditionals that are non-numeric.\n#\n\nwhich=\\\n\tlambda boolConditionTest,truthReturn,falseReturn:\\\n\t\t (truthReturn,falseReturn)[not boolConditionTest]\n\n\nif __name__ == \'__main__\':\n\tprint "Syntax:"\n\tprint " which(bool conditional test,return if true,return if false)"\n\tprint "Description:"\n\tprint " lambda function to approximate the C conditional operator"\n\tprint ""\n\n\ttheCond=\'\'\n\tifTrue=\'string\'\n\tifFalse=\'null string\'\n\tprint "which(\'"+theCond+"\',\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=\'non-empty string\'\n\tprint "which(\'"+theCond+"\',\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=[]\n\tifTrue=\'list\'\n\tifFalse=\'no list\'\n\tprint "which(",theCond,",\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=[\'one\',2]\n\tprint "which(",theCond,",\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=0 == 1\n\tifTrue=\'true\'\n\tifFalse=\'false\'\n\tprint "which(",theCond,",\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=1 == 1\n\tprint "which(",theCond,",\'"+ifTrue+"\',\'"+ifFalse+"\')"\n\tprint " returns \'"+which(theCond,ifTrue,ifFalse)+"\'"\n\ttheCond=0\n\tifTrue=1\n\tifFalse=0\n\tprint "which(",theCond,",",ifTrue,",",ifFalse,")"\n\tprint " returns ",which(theCond,ifTrue,ifFalse)\n\ttheCond=1\n\tprint "which(",theCond,",",ifTrue,",",ifFalse,")"\n\tprint " returns ",which(theCond,ifTrue,ifFalse)\n# Note: if division by zero is possible in your test, you need to nest\n# a call to which into the expression where this is possible to\n# avoid an exception. There may be similar cases in other instances.\n\ttheCond=-.25\n\tifTrue=16+4/which(theCond,theCond,1)\n\tifFalse=23\n\tprint "which(",theCond,",",ifTrue,"(*) ,",ifFalse,")"\n\tprint " returns",which(theCond,ifTrue,ifFalse)\n\ttheCond=0\n\tifTrue=16+4/which(theCond,theCond,1)\n\tprint "which(",theCond,",",ifTrue,"(**) ,",ifFalse,")"\n\tprint " returns",which(theCond,ifTrue,ifFalse)\n\ttheCond=-.25\n\tprint "(*) 16+4/which(",theCond,",",theCond,", 1 ) ==",\\\n\t\t which(theCond,theCond,1),\\\n\t\t "->",16+4/which(theCond,theCond,1)\n\ttheCond=0\n\tprint "(**) 16+4/which(",theCond,",",theCond,", 1 ) ==",\\\n\t\t which(theCond,theCond,1),\\\n\t\t "->",16+4/which(theCond,theCond,1)\n\n<br>\nAnd the output:\n<pre>\nSyntax:\n which(bool conditional test,return if true,return if false)\nDescription:\n lambda function to approximate the C conditional operator\n\nwhich(\'\',\'string\',\'null string\')\n returns \'null string\'\nwhich(\'non-empty string\',\'string\',\'null string\')\n returns \'string\'\nwhich( [] ,\'list\',\'no list\')\n returns \'no list\'\nwhich( [\'one\', 2] ,\'list\',\'no list\')\n returns \'list\'\nwhich( False ,\'true\',\'false\')\n returns \'false\'\nwhich( True ,\'true\',\'false\')\n returns \'true\'\nwhich( 0 , 1 , 0 )\n returns 0\nwhich( 1 , 1 , 0 )\n returns 1\nwhich( -0.25 , 0.0 (*) , 23 )\n returns 0.0\nwhich( 0 , 20 (**) , 23 )\n returns 23\n(*) 16+4/which( -0.25 , -0.25 , 1 ) == -0.25 -> 0.0\n(**) 16+4/which( 0 , 0 , 1 ) == 1 -> 20</pre></pre>', 'title': u'This appears to work everywhere'}, {'comment': u'<pre>\n>>> li=[1,2,3,4]\n>>> which(0,li.pop(),li)\n[1, 2, 3]\n>>> which(0,li.pop(),li)\n[1, 2]\n>>> which(0,li.pop(),li)\n[1]\n>>> which(0,li.pop(),li)\n[]\n>>> which(0,li.pop(),li)\nTraceback (most recent call last):\n File "", line 1, in ?\nIndexError: pop from empty list\n>>> \n</pre>', 'title': u'The above which(a,b,c) evaluates all arguments'}, {'comment': u'See http://mail.python.org/pipermail/python-dev/2005-September/056846.html', 'title': u'"a if b else c" is in python 2.5'}], 'desc': u'Python\'s "if" is a _statement_, and there is no conditional _operator_ (like C\'s "a?b:c" ternary) that we could use where expressions are needed (lambdas, etc); however, with some due care, equivalents can easily be coded.'}, {'comments': [{'comment': u'This recipe is only a slight variation on Alex Martelli\'s recipe, "Static-methods" (aka "class-methods") in Python,\nwhich is also more concise and better explained. The main difference is that Thomas\' variation\npasses the class object as the first parameter to the class method which allows inheritence.\n\nThe Zope dependency apparently comes from the need to have access to the class object while \nthe class is being defined. The Zope ExtensionClass.Base class extends the Python class model\nby calling a __class_init__(classObject) method immediately after the class has been defined. The \nZope ExtensionClass is a C extension which makes it inaccessible to non-Zope users.\n\nEither the recipe should be altered to not depend on Zope, or the Zope dependency should be more\nclearly explained. Brent Burley', 'title': u'Confusing; Zope dependency unclear and not explained'}, {'comment': u'Python now has classmethods (\xe0 la Smalltalk) and staticmethods (\xe0 la Java).', 'title': u'Out of date'}], 'desc': u"This recipe demonstrates 'real' class methods, like they are known from Smalltalk.\n\nClass methods implicitely receive the actual class as the first parameter.\n\nThey are inherited by subclasses, and may as well be overridden.\n\nClass methods may return anything, although they are particularly useful as constructors.\n"}, {'comments': [{'comment': u"Your suggested code is Ok.\nBut you shouldn't call a function **dict**\nbecause it's a builtin-function.\nRegards\nPeter", 'title': u'Method for constructing a dictionary without '}, {'comment': u'> Your suggested code is Ok. But you shouldn\'t call\n\n<br>\n\n> a function **dict** because it\'s a builtin-function.\n\n<br>\n\ndict is not a built-in function. dict is a built-in type since Python 2.2. You can verify this by typing "type(dict)" at the interactive prompt. \n\n<br>\n\nIf you look at the date of the recipe and you\'ll realize that this is the exact syntax has been accepted into Python 2.3 :-). ', 'title': u'This recipe has been accepted into Python 2.3'}, {'comment': u"Nice to see this Recipe accepted into Python 2.3. Another thing I miss from Perl is reduced quoting for access. When you access $data{red}, Perl automatically quotes the key for you. In Python you need to do data['red']. Wouldn't it be nice if you didn't have to do the quoting like in Perl? In fact, since you can inherit from types since Python 2.2, we can do one better than Perl. With the following code you can access data['red'] simply as data.red. Code follows:\n\n<pre>\nclass attrdict(dict):\n def __getattr__(self, name):\n return self[name]\n\n def __setattr__(self, name, value):\n self[name] = value\n\ndata = attrdict(red=1, green=2, blue=3)\nprint data.red\ndata.black = 4\n\n</pre>", 'title': u'Avoiding excessive quoting during access'}, {'comment': u'<pre>\nThere are times when inline functionality is desired without defining functions or classes.<br>Lambda and map served this purpose well but might be leaving Python.<br>List compressions (a la Haskell) will fill the void.<br>In the above examples dictionary values are literal integers.<br>Sometimes they might be strings requiring quotes.\n \n>>> ls1= "m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12"\n>>> ls2= "January February March April May June July August September October November December"\n\n>>> dict( zip( *[ l.split() for l in ( ls1, ls2) ] ))\n\nThe asterisk (*) before the list compression is necessary for zip to not interpret the nested<br>result of the compression as a single argument.\n\n\nTo have literal, keyed access to the dictionary values without class or function definitions:\n\n>>> import __main__; MD=__main__.__dict__\n>>> MD.update( dict( zip( *[ l.split() for l in ( ls1, ls2) ] )) )\n\n>>> print "Quarters start in the months %s, %s, %s and %s." % (m1, m4, m7, m10)\n\nQuarters start in the months January, April, July and October.</pre>', 'title': u'Inline quote minimization'}], 'desc': u'The syntax for constructing a dictionary can be tedious due to the\namount of quoting required. This recipe presents a technique which \navoids having to quote the keys.'}, {'comments': [], 'desc': u"Can't use a stepping debugger to diagnose and fix your programs? Use these functions to log state and execution flow. Sample use provided."}, {'comments': [{'comment': u'The getframe function described in this recipe is available as a builtin function in Python 2.1.\nsys._getframe() returns the current frame object.', 'title': u'Python 2.1 sys._getframe()'}, {'comment': u"Hi!<br>\nBecause sys._getframe() is available for Python > 2.1 I suggest to change the Code like this - so you make sure that noone overwrites the fast Python >= 2.1 -implementation:<br>\n<pre>\nif sys.version[:3] < '2.1': # sys.version_info is also not available for early pythons....\n #print 'loading emulated sys._getframe() for Python < 2.1'\n def _getframe(level=0):\n try:\n 1/0\n except:\n import sys\n tb = sys.exc_info()[-1]\n frame = tb.tb_frame\n while level >= 0:\n frame = frame.f_back\n level = level - 1\n return frame\n\n sys._getframe = _getframe\n del _getframe\n</pre>", 'title': u'Determining Python Version on import'}, {'comment': u'The reference to tb needs to be eradicated (well known Python lore).\nI had a case of the reference causing a refcount bump on an object\n(a lock object) two levels up from the call to getframe(). The increased refcount caused the lock object to persist after it was\ndeleted, which was not expected (or appreciated). <br><br>\nNot a problem with newer Python with native getframe(), I hope.\n<pre>\ndef getframe(level=0):\n try:\n 1/0\n except:\n import sys\n tb = sys.exc_info()[-1]\n frame = tb.tb_frame\n # The next line seems important.\n tb = None\n while level >= 0:\n frame = frame.f_back\n level = level - 1\n return frame\n</pre>\n<p>\n\n-- Sean True<br>\nWebreply, Inc.\n', 'title': u'A mild flaw in this implementation.'}, {'comment': u"Perhaps better than checking the version is simply to test for the existence of the function:\n<pre>\n if not hasattr(sys, '_getframe'):\n # do the rest here as before\n</pre>\n\nIt's generally better to test for capabilities rather than versions.", 'title': u'Slightly better approach?'}], 'desc': u'How to obtain the name of a method or a function from within \nthe running method/function.\n\nAcknowledgement: the solution to this problem is given by \nChristian Tismer (tismer@tismer.com; Mission Impossible 5oftware) \n'}, {'comments': [{'comment': u'dsu variant of this (faster, clearer):<pre>\n\n# "decorate" == Pack the auxiliary list:\naux_list=[(sort_crit1(x),sort_crit2(x),x) for x in star_list]\n# "sort" == JUST sort, no wasted effort/complication\naux_list.sort()\n# "undecorate" == Unpack the resulting list:\nstar_list = [x[-1] for x in aux_list]\n</pre>\nThis doesn\'t easily do "reverse" sorting on some of the fields while being "direct" on others. On number criteria, you can just change sign (use -sort_critN(x)). On string criteria, you need a string map that swaps chr(x) with chr(255-x) for x in range(128), or wider if Unicode (but you only need to write that once).\n', 'title': u'decorate-sort-undecorate idiom does it better'}], 'desc': u'Here we use the properties of "cmp()" and "or" to produce a compact dialect for sorting a list.'}, {'comments': [{'comment': u'Note the trickiness with "z" -- it is a zero of the same type as the argument lim. This allows you to use longs as the limit if need be.\nTo print "odds":<pre> n,d = farey(probability,lim)\n print "Odds are %d : %d" % (n,d-n)</pre>\n\nThis code is ideally suited for re-implementation in a lower level language (say C or assembly) if you have the need or desire for rational or "odds" output. Because this uses only multiplication and addition, it can play to hardware strengths.\n\nIf you are using this in an environment where you call it with a lot of values very near 0., 1., or 0.5 (or _very_ simple fractions), you may find it too slow. You may improve its performance in a "continued fraction" style by appending to the first if:\n<pre>\n if v < 0:\n ...\n elif v < 0.5:\n n,d = farey((v-v+1)/v, lim) # lim is wrong: decide what you want\n return (d,n)\n elif v > 1:\n intpart = floor(v)\n n,d = farey(v-intpart)\n return n+intpart*d, d\n ...\n</pre>\n\nJames Farey was an English surveyor who wrote a letter to the "Journal of Science" around the end of the eighteenth century. In that letter he observed that, while reading a privately published list of the decimal equivalents of fractions, he noticed the following. For any three consecutive fractions in least terms (say, A/B, C/D, E/F), the middle one (C/D) is equal to the (A+E)/(B+F).\n\nI enjoy my own image of Mr. Farey sitting up late on a rainy English night, reading tables of decimal expansions of fractions by an oil lamp. Calculation has come a long way since his day, and I\'m pleased to be able to benefit from his work.', 'title': u'notes on farey'}, {'comment': u'Alternatively, you can use continued fractions: http://mathworld.wolfram.com/ContinuedFraction.html . Note that in the continued fraction, you can use subtractions as well as additions. Thus math.pi == 3+1/(7+1/(16-.003405593314)) ~= 3+1/(7+1/16.) == 355./113.', 'title': u'Continued fractions'}, {'comment': u'For example, farey(0.36, 10) returns (1, 3), whereas (3, 8) is correct.\n\nFor another, farey(0.584115140346, 100) returns (7, 12) whereas (52, 89) is correct.\n\nDick Moores\nrdmoores@gmail.com', 'title': u'farey() often gives incorrect result'}], 'desc': u'This converts a Numeric to a rational. The result is always \nin reduced form, but the proof, while possible, is subtle.\n\nfarey(math.pi,100) = (22,7)'}, {'comments': [{'comment': u"The statement\n<pre>\n inf = urllib.URLopener().open(url)\n</pre>\nneeds replacing with\n<pre>\n inf = urllib.FancyURLopener().open(url)\n</pre>\nto prevent an exception being raised due to the site returning an HTML code '302' (redirected).\n", 'title': u"Fix for '302' error"}, {'comment': u'The owners of the site you are using to access the lat/long database are very specific about this: "Automatic access by query-generating software is not acceptable and will be considered illegal".', 'title': u'Illegal use of their site'}, {'comment': u"You're right. This program could use Microsoft TerraServer to do the same thing legally.", 'title': u"You're right"}, {'comment': u"GetPlaceList is a WebServices function accessible using the either HTTP or SOAP protocols. It returns XML formatted info (including LatLong) about places that match the name given.\n<br>\nHere's a demo page with the details on access: <br>\nhttp://terraserver.microsoft.net/TerraService.asmx?op=GetPlaceList", 'title': u'Legal way to get Lat Long from Terraserver'}, {'comment': u'Thanks for the pointer to Terraserver. Here is an update of the\nfindcity function. The PARC map server is long since 404-ed, so the\nrest of the recipe is useless. The getText() function was very\nhastily modified from the one appearing in the Python docs for\nxml.dom.minidom, and could probably be improved. But it\'s nice to\nsee how elegantly the minidom stuff works.\n\n<pre>\ndef findcity(city, state):\n def getText(nodelist):\n rc = ""\n for node in nodelist:\n if node.nodeType == node.TEXT_NODE:\n rc = rc + node.data\n elif node.hasChildNodes():\n rc = rc + getText(node.childNodes)\n return rc\n url = (("http://terraserver.microsoft.net/TerraService.asmx/GetPlaceList?" +\n "placeName=%s&MaxItems=1&imagePresence=false")\n % (string.replace(city, " ", "+") + "%2C+" + state))\n inf = urllib.FancyURLopener().open(url)\n dom = xml.dom.minidom.parse(inf)\n inf.close()\n placeFacts = dom.getElementsByTagName("PlaceFacts")\n center = placeFacts[0].getElementsByTagName("Center")\n lat = string.atof(getText(center[0].getElementsByTagName("Lat")))\n lon = string.atof(getText(center[0].getElementsByTagName("Lon")))\n return lon, lat\n</pre>', 'title': u'accessing Terraserver'}], 'desc': u'Given a list of cities, this recipe fetches their latitudes and longitudes from\none website (a database used for astrology, of all things) and uses them to\nbuild a URL for another website which creates a map highlighting the cities\nagainst the outlines of continents. Maybe some day it will be clever enough to\nload the latitudes and longitudes as waypoints into your GPS receiver.\n'}, {'comments': [{'comment': u"This also works very well for creating a sort of lightwieght subclass..<br>\nie. you can curry the constructor of a class to give the illusion of a subclass as follows:<br>\n<br>\nbluewindow = curry(window, bg='blue')<br>\nbw = bluewindow()<br>\n<br>\n..of course type(bluewindow) is still type(window),\n( not a sub-type )<br>\n\nAdditional parameters can still be passed to the curried constructor:<br>\nbw2 = bluewindow( title='blah', fg='yellow')<br>\n<br>\ncurry is cool, and not just for callbacks!\n</br></br></br></br></br></br></br></br></br></br>", 'title': u" 'Lightweight' subclasses"}, {'comment': u'Lexically nested scopes (in Python 2.2 -- "from __future__ import" if you want to use them in 2.1) allow interesting currying too, e.g.:\n<pre>\ndef curry(func, *args, **kwds):\n def callit(*moreargs, **morekwds):\n kw = kwds.copy()\n kw.update(morekwds)\n return func(*(moreargs+args), **kw)\n return callit\n</pre>\nThis curries positional arguments from the right, and gives named arguments specified at call-time precedence over those specified at currying-time, but these policies are clearly easy to alter:-).\n\n_Without_ nested scopes, I don\'t think it can be done with this level of generality (injecting names into the inner scope becomes hard to do generally when one wants fully-general *args and **kwds...:-).\n\n\nAlex\n', 'title': u'curry-by-closure'}, {'comment': u'The \'curry\' function can be used in debugging as well. For example, we can "wrap" method calls in objects:\n<pre>\n def report(originalFunction, name, *args, **kw):\n print name + \'(\', \', \'.join(map(repr,args) +\n [k+\'=\'+repr(kw[k]) for k in kw.keys()]), \')\'\n result = originalFunction(*args, **kw)\n if result: print name, \'==>\', result\n return result\n\n class Sink:\n def write(self, text):\n pass\n\n dest = Sink()\n dest.write = curry(report, dest.write, \'write\')\n print >>dest, \'this\', \'is\', 1, \'test\'\n</pre>\n', 'title': u'Using curry to wrap debugging information around calls'}, {'comment': u"Nick Perkins' latest version of curry-by-closure (from c.l.p, for the record) is more general (no named args at all, thus no accidental name capture -- except, I think, for args and create_time_kwds...) and quite readable, although marginally more verbose, due to good name choices for intermediate locals. It also has curry-from-left (for positional args) and call-time-dominates (for named args) semantics, which may be popular:\n<pre>\ndef curry(*args, **create_time_kwds):\n func = args[0]\n create_time_args = args[1:]\n def curried_function(*call_time_args, **call_time_kwds):\n args = create_time_args + call_time_args\n kwds = create_time_kwds.copy()\n kwds.update(call_time_kwds)\n return func(*args, **kwds)\n return curried_function\n</pre>\n", 'title': u'alternative curry-by-closure'}, {'comment': u'Why not also add this before returning the curried function:\n\n<pre>\ncurried_function.__doc__ = "Curried function \'%s\':\\n%s" % ( \n func.func_name, func.func_doc\n )\n</pre>\n', 'title': u"Enhancement: the original function's __doc__ string..."}, {'comment': u'The operation performed by the operator described here is actually called "Partial Application". A good definition of currying can be inferred from http://tinyurl.com/3d6w6 and http://tinyurl.com/ly29.\n<br>\n\n<br>Several languages have misused the term "curry" this way\n<br><br>\n http://tinyurl.com/2p6gb, http://tinyurl.com/2onya (Python)<br>\n http://tinyurl.com/36pus (JavaScript)<br>\n http://tinyurl.com/3dj6j (Dylan)<br>\n<br>\n<br>\nCurrying transforms a function taking a single tuple argument into a function taking multiple arguments, and uncurrying reverses the process.\n<pre>\n>>> def curry(f):\n... return lambda *args: f(args)\n...\n>>> def add2(args): # add the first 2 elements of an argument tuple\n... return args[0] + args[1]\n...\n>>> curry(add2)(1,2) # make add2 accept multiple args\n3\n>>> def uncurry(f):\n... return lambda x: f(*x)\n...\n>>> uncurry(curry(add2))((1,2)) # reverse currying; pass a tuple\n3\n</pre>', 'title': u"This isn't currying"}, {'comment': u'I\'d eliminate some micro-optimizations today and avoid spurious copies. Also, to allow named parameters such as \'self\' to be \nspecified in keywords, _no_ directly named args are provided.\n<pre>\nclass curry:\n def __init__(*args, **kwargs):\n self = args[0]\n self.fun = args[1]\n self.pending = args[2:]\n self.kwargs = kwargs\n\n def __call__(*args, **kwargs):\n self = args[0]\n kw = self.kwargs.copy()\n kw.update(kwargs)\n return self.fun(*self.pending + args, **kw)\n</pre>\nThe above works back through _many_ versions of python (though\nyou might have to use "apply" to call self.fun if your Python is old).\n"Nested scopes" became a feature after this code was written. If I were to write it now, I might write:\n<pre>\ndef curry(*args, **kwargs):\n function, args = args[0], args[1:]\n def result(*rest, **kwrest):\n combined = kwargs.copy()\n combined.update(kwrest)\n return function(*args + rest, **combined)\n return result\n\n</pre>\nFinally, putting the micro-optimizations (and one new one) back in:\n<pre>\nimport new\n\ndef curry(*args, **kwargs):\n function, args = args[0], args[1:]\n if args and kwargs:\n def result(*rest, **kwrest):\n combined = kwargs.copy()\n combined.update(kwrest)\n return function(*args + rest, **combined)\n elif args:\n if len(args) > 1:\n def result(*rest, **kwrest):\n return function(*args + rest, **kwrest)\n else:\n # Special magic: make a bound object method on the arg\n return new.instancemethod(function, args[0], object)\n elif kwargs:\n def result(*rest, **kwrest):\n if kwrest:\n combined = kwargs.copy()\n combined.update(kwrest)\n else:\n combined = kwargs\n return function(*rest, **combined)\n else:\n return function\n return result\n</pre>', 'title': u'Current curry code'}, {'comment': u'In the code above, bonono recently pointed out that instancemethod will not do what I want with a value of None, so the code above should be changed from:\n<pre>\n ...\n elif args:\n if len(args) > 1:\n ...\n</pre>\nto:\n<pre>\n ...\n elif args:\n if len(args) > 1 or args[0] is None:\n ...\n</pre>', 'title': u'Warning: special case. Change needed above'}, {'comment': u'Hi. I wanna include code in commercial project, do you mind? :)\n<br>\nhttp://mortgage-calculator.teach-nology.com', 'title': u'can i use this code in commercial project?'}, {'comment': u'I\'ve found that using the closure you cannot apply curry to instance methods and classmethods using:\n\n<pre>\nclass X(object):\n def test(self, arg):\n ..\n curried = curry(test, 10)\n...\n</pre>\n\nHowever with the addition of the decorator protocol to the class based implementation\n\n<pre>\nclass curry(object):\n ....\n ....\n def __get__(self, obj, typ):\n """\n This method is an addition to the python cook book receipe.\n\n It allows partial function to be applied to method and classmethods\n """\n return curry(self.fn.__get__(obj, typ), *self.args, **self.kw)\n</pre>\n\nperhaps it could be done better but it works (even with classmethod)', 'title': u'Curryng methods'}], 'desc': u'In functional programming, currying is a way to bind arguments with\na function and wait for the rest of the arguments to show up later.\nYou "curry in" the first few parameters to a function, giving\nyou a function that takes subsequent parameters as input and\ncalls the original with all of those parameters. This recipe uses\na class instance to hold the parameters before their first use.\nFor example:\n\n double = curry(operator.mul, 2)\n triple = curry(operator.mul, 3)\n'}, {'comments': [], 'desc': u'This recipe allows you to update desired files in a directory tree. It needs to be run from the shell. Once you run it, it will ask you for: a) the "string" you want to insert in the file b) the extension of the files to update e.g: .html c) a regular expresion ( where you want the string to be inserted ) and d) the path of the directory where you want this update to occur. '}, {'comments': [{'comment': u"all id's in the sample output must be equal!<br>\n<br>\nTry this:<br>\n<br><pre>\nclass A:<br>\n # attribute known to function Singleton<br>\n _instance = None<br>\n def foo(self):<br>\n return id(self)<br>\n<br>\ndef Singleton(klass):<br>\n if not klass._instance:<br>\n klass._instance = klass()<br>\n return klass._instance<br>\n<br>\n# subclass A<br>\nclass B(A):<br>\n pass<br>\n<br>\nb = Singleton(A)<br>\nc = Singleton(B)<br>\nd = Singleton(A)<br>\nprint id(b),b.foo()<br>\nprint id(c),c.foo()<br>\nprint id(d),c.foo()<br>\n<br>\n# Output:<br>\n7963404 7963404<br>\n7963404 7963404<br>\n7963404 7963404<br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></pre></br></br></br></br>", 'title': u'RE: Singleton right behavior'}, {'comment': u'Phooey, both of these examples are too complicated. :-)\n\n<pre>\nclass _Spam:\n def __call__(self):\n return self\n\nSpam = _Spam()\ndel _Spam\n</pre>\n\nAlas, this isn\'t perfect. If for some reason you need to subclass Spam, you obviously can\'t. But I think this is sufficient for most people\'s needs.\n\nSince Python doesn\'t have any notion of class/static methods, it isn\'t possible to build singletons "the right way". Every workable solution will be a compromise of some sort.', 'title': u'A simpler singleton'}, {'comment': u'ps: Of course this is possible too...\n\n<pre>\nclass Spam:\n def __call__(self):\n return self\n\nSpam = Spam()\n</pre>', 'title': u'Obfuscated singleton'}, {'comment': u"<pre>\nclass TestSingleton :\n\n # Create a class variable that will hold a reference\n # to the single instance of TestSingleton.\n\n instance = None\n\n # Define a helper class that will override the __call___\n # method in order to provide a factory method for TestSingleton.\n\n class TestSingletonHelper :\n\n def __call__( self, *args, **kw ) :\n\n # If an instance of TestSingleton does not exist,\n # create one and assign it to TestSingleton.instance.\n\n if TestSingleton.instance is None :\n object = TestSingleton()\n TestSingleton.instance = object\n \n # Return TestSingleton.instance, which should contain\n # a reference to the only instance of TestSingleton\n # in the system.\n\n return TestSingleton.instance\n \n # Create a class level method that must be called to\n # get the single instance of TestSingleton.\n\n getInstance = TestSingletonHelper()\n\n # Initialize an instance of the TestSingleton class.\n\n def __init__( self ) :\n\n # Optionally, you could go a bit further to guarantee\n # that no one created more than one instance of TestSingleton:\n\n if not TestSingleton.instance == None :\n raise RuntimeError, 'Only one instance of TestSingleton is allowed!'\n\n #Continiue initialization...\n\n \n# Test this implementation of the Singleton pattern. All of the\n# references printed out should have the same address.\n\nfor i in range( 10 ) :\n print TestSingleton.getInstance()\n\n# This call should raise a RuntimeError indicating\n# that a single instance of TestSingleton already exists.\n\nTestSingleton()\n\n</pre>\n\nThis singleton implementation draws from 'static method/class method'<br>\nexamples by Thomas Heller and Clark Evans.\n</br>", 'title': u'Singleton example'}, {'comment': u'Inheritance is possible and can be documented as such if you use such an idiom \nto implement the Singleton.\n<pre>\n class Eggs(Spam.__class__): # The original class is still available\n def __call__(self): # These 3 lines\n return self # should be\n Eggs=Eggs() # replicated\n</pre>\n', 'title': u'Subclassing is possible, but ugly!'}, {'comment': u"This does only work if you call 'getInstance()' before\nthe constructor ; if not, you will get a much different instances\nas you wish until 'getInstance()' get called:\n\n<pre>\n>>> for i in range(3):\n>>> print '> %s'%TestSingleton()\n\n> <TestSingleton instance at 0x811f55c>\n> <TestSingleton instance at 0x812469c>\n> <TestSingleton instance at 0x811eaec>\n</pre>\n\nIf you want to make sure that the constructor is not called\nmore than once, 'TestSingleton.__init__' should read:\n\n<pre>\n def __init__(self):\n if not TestSingleton.instance == None :\n raise RuntimeError, 'Only one instance of TestSingleton is allowed!'\n TestSingleton.instance=self\n</pre>\n(last line added)\n", 'title': u'Small correction'}, {'comment': u'I found some of the previously mentioned ideas a bit too complicated. <br>Here\'s my implementation:\n<br>\n<pre>\nclass _Singleton(object):\n\n def __init__(self):\n # just for the sake of information\n self.instance = "Instance at %d" % self.__hash__()\n\n\n_singleton = _Singleton()\n\ndef Singleton(): return _singleton\n</pre>\n=====\n<pre>\n>>> from singleton import Singleton\n>>> s1 = Singleton()\n>>> s2 = Singleton()\n>>> s1.instance\n\'Instance at -1226695220\'\n>>> s2.instance\n\'Instance at -1226695220\'\n>>> s1 == s2\nTrue\n</pre>\n\n', 'title': u'Much easier solution'}], 'desc': u'The following class shows how to implement the singleton pattern[1] in Python. A singleton\nis a class that makes sure only one instance of it is ever created. Typically such classes\nare used to manage resources that by their very nature can only exist once.\n'}, {'comments': [{'comment': u'unique() systematically loses order, but if items are hashable it\'s not hard to keep order intact -- only eliminate "later" insertions of already-present items. In case items _aren\'t_ hashable, for a big enough N using their cPickle.dumps() might be worth it... that\'s easily generalized to "uniqueness within equivalence classes" -- parameter function idfun must return hashable objects which are == for and only for items that are duplicates.\n<pre>\ndef uniquer(seq, idfun=None):\n if idfun is None:\n def idfun(x): return x\n seen = {}\n result = []\n for item in seq:\n marker = idfun(item)\n # in old Python versions:\n # if seen.has_key(marker)\n # but in new ones:\n if marker in seen: continue\n seen[marker] = 1\n result.append(item)\n return result\n</pre>\nTo get the *latest* rather than *earliest* appearance of an item (==a member of an equivalence class as defined by idfun), the best solution is to take quite another equivalent tack:\n<pre>\ndef uniquest(seq, idfun=None):\n import sys\n if idfun is None:\n def idfun(x): return x\n seen = {}\n for item, index in zip(seq,xrange(sys.maxint)):\n marker = idfun(item)\n seen[marker] = index, item\n auxlist = seen.keys()\n auxlist.sort()\n return [item for index, item in auxlist]\n</pre>\n\nuniquest generalizes quite easily to cases in which choice among multiple items in the same equivalence class needs to depend on some arbitrary precedence-function that considers both the actual items and their indices of occurrence, as long as said precedence can operate pairwise -- you just need to replace the simplistic "seen[marker] = index, item" with a call to the precedence function when marker is already a key in dictionary \'seen\' -- the precedence function must return the (index,item) pair for the chosen occurrence among the two (the one already seen and the newly occurring item/index). Here\'s the code, giving up the default idfun since this is really useful only for a substantial equivalence-function...:\n<pre>\ndef fancy_unique(seq, idfun, precedence):\n seen = {}\n for item, index in zip(seq,xrange(sys.maxint)):\n marker = idfun(item)\n if seen.has_key(marker):\n index, item = precedence((index,item),seen[marker])\n seen[marker] = index, item\n auxlist = seen.keys()\n auxlist.sort()\n return [item for index, item in auxlist]\n</pre>\nFor example, say we have a list of words: we need to extract from it a list *respecting order* where no two items begin with the same letter; out of several words in the original list that begin with the same letter, we want to keep the longest, and, for equal length, the one appearing later in the list. Phew, sounds complicated, right? Not with fancy_unique to help us...:\n<pre>\ndef complicated_stuff(wordlist):\n def first_letter(aword): return aword[0].lower()\n def prefer((id1,word1),(id2,word2)):\n if len(word2)>len(word1): return id2,word2\n return id1,word1\n return fancy_unique(wordlist, first_letter, prefer)\n</pre>\nHere, \'prefer\' is slightly tricky/fragile as it "knows" fancy_unique always calls it with id1>id2, so the older\nid2,word2 pair need only be returned when word2 is longer\nthan word1, otherwise id1,word1 must always be the\nresult. It\'s only a bit wordier to express the full set\nof tests in \'prefer\', though.\n<br>\nAnd the nice thing is, these are ALL O(N) [in the same sense\nas the best case of the unique in the original recipe], although when one is using cPickle.dumps and/or other heavy stuff the\nmultiplicative constants may be a tad heavyweight:-).\n', 'title': u"and when you can't lose order..."}, {'comment': u'<pre>\ndef uniq(alist) # Fastest order preserving\n set = {}\n return [set.setdefault(e,e) for e in alist if e not in set]\n\ndef uniq(alist) # Fastest without order preserving\n set = {}\n map(set.__setitem__, alist, [])\n return set.keys()</pre>', 'title': u'Lightweight and fast ...'}, {'comment': u"If you are prepared to lose some backwards compatibility by using list comprehensions, then these functions are tidier variants of Tim's first algorithm. However they don't work if the supplied list contains unhashable items (such as a another list). Providing fallback algorithms to address that is what makes Tim's code longer.\n", 'title': u"But these don't address unhashability"}, {'comment': u"This always worked for me:<br>\n<pre>\n>>> hasDupes=[['a','b'],['a','b'],['c','d']]\n>>> noDupes=[]\n>>> [noDupes.append(i) for i in hasDupes if not noDupes.count(i)]\n[None, None]\n>>> noDupes\n[['a', 'b'], ['c', 'd']]\n>>>\n</pre>\n\nYou could always wrap it in a function.", 'title': u'another approach'}, {'comment': u"This uses a dictionary with repr, similar to my previous approach, but much faster for large sequences. repr handles the hashability issues:\n<pre>\n>>> import operator\n>>> setitem = operator.setitem\n>>> hasDupes=[['a','b'],['a','b'],['c','d']]*1000\n>>> noDupes={}\n>>> [operator.setitem(noDupes,repr(i),i) for i in hasDupes if not noDupes.has_key(repr(i))]\n[None, None]\n>>> noDupes = noDupes.values()\n>>> noDupes\n[['a', 'b'], ['c', 'd']]\n</pre>\n", 'title': u'this is much faster for large sequences, using a dictionary'}, {'comment': u"In Python 2.4, sets will be introduced as a builtin-type. This probably means the 'dictionary-method' can be replaced by a method using sets.", 'title': u'Python 2.4'}, {'comment': u'In your second method, \n\n (t[lasti] = last = t[i])\n\nlist indexing is O(n), so the whole algo works in O(n^2).\n\n- R. Sridhar', 'title': u'second method is O(n^2)'}, {'comment': u'Why the map() with set._setitem_? Create a set from the list, like this:\n\n<pre>\nreturn set(alist).keys()\n</pre>\n\nIn pre-set Python, I\'ve used a similar approach for dictionaries to be used as sets, though I haven\'t timed it\nagainst a for loop. Convert the list into a list of tuples with\nthe second value a "1" (or true). Make that list into a dictionary.\n\n<pre>\nadict = dict(map(lambda a: (a,1), alist))\n</pre>\n\nFor the all-purpose unique routine, the for loop is probably better than the dict/map/lambda one-liner, because it will fail earlier on non-hashable elements. This approach makes a whole list before it tries to hash anything. Calling set() directly should not have that problem.\n\nOne other minor thing: getting the length of a sequence is so fast that I don\'t see the point of saving it at the beginning of the routine. Try this to test for empty sequences, and to get graceful behavior when passed None. Then get the length closer to the loop that uses it.\n\n<pre>\nif not s: return []\n</pre>', 'title': u'Use built-in functions'}, {'comment': u"Python's list data type does not mean a linked list. Under the hood it's an array of pointers, so that indexing works in constant time.\nWhich means that the sorting version of unique() does have complexity O(n*log(n)), just like Tim Peters said.", 'title': u'Indexing is O(1)'}, {'comment': u"Sometimes you don't want to iterate through all the sequence, and just want the first few unique elements. Here is an iterator that does just that, assuming objects are hashable (otherwise, approaches seen in this recipe and comments can be used).\n\n<pre>\ndef iunique(iterable):\n seen = set([])\n for i in iterable:\n if i not in seen:\n seen.add(i)\n yield i\n</pre>", 'title': u'Using an iterator...'}, {'comment': u'<pre>Chris Perkins\' recipe "The Secret Name of List Comprehensions"<br>\'_[1]\' is again of high value.<br>\n\n>>> hasDups= [[\'a\',\'b\'],[\'a\',\'b\'],[\'c\',\'d\']]\n>>> [ u for u in hasDups if u not in locals()[\'_[1]\'] ]\n[[\'a\',\'b\'],[\'c\',\'d\']]\n\nAlso it is not necessary to append or setitem as the primary operation<br>of a list comprehension. If you want to construct a list it does exactly that.<br>If you want to name it for reuse then\n\n>>> noDups=[ u for u in hadDups if u not in locals()[\'_[1]\'] ]</pre>', 'title': u"Or you could use Chris Perkins' wonderful trick"}, {'comment': u"<pre>And they are as polymorphic as the Python list.\n\n>>> list(set([ chr(i) for i in range(97,123)] * 1000))\n['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']</pre>", 'title': u'Yes, Python 2.4 sets are marvelous and fast'}, {'comment': u'http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/438599', 'title': u'A derivate version'}], 'desc': u"The fastest way to remove duplicates from a sequence depends on some pretty subtle properties of the sequence elements, such as whether they're hashable, and whether they support full comparisons. The unique() function tries three methods, from fastest to slowest, letting runtime exceptions pick the best method available for the sequence at hand."}, {'comments': [], 'desc': u"Sometimes you just don't want a page to be cached, ever, by the client's web browser. This recipe tells you how to do that from DTML."}, {'comments': [{'comment': u'I had to add "self." to these two lines to get the code to work.<br>\n<p>\n num_defaults = totlen - self.defnum <br> \n args += a + self.defaults[self.defnum-num_defaults:] <br>\n<br><br>\nHere is a test:<br>\n<pre>\ndef myfun(a,b):\n print a,b\n\nmyfun = Curry(myfun)\nmyfun(1)\nmyfun(2)\nmyfun(3)(4)\nmyfun(5,6) # the usual way\n</pre>', 'title': u'A few bugs and a test'}], 'desc': u'A class to allow programmers to curry functions, so that arguments can be supplied one at a time instead of all at once.\nE.g., if F = Curry(lambda a,b: a+b), then\nF(1,2) == F(1)(2)'}, {'comments': [{'comment': u"s.isdigit() [in Python 2.0 and later] is a faster version of this isAllDigits function, except that ''.isdigit() is 0 [only if s has at least one digit, AND nothing but digits, does isdigit succeed] so if you want an empty string to be OK you need to code<pre>\n s.isdigit() or not s\n</pre>\nThis doesn't diminish the value of the exception-based approach to testing general properties, of course!\n", 'title': u'isdigit method of string objects'}, {'comment': u'Thanks for the comment. This specific function was written before Python 2.0. As noted, the general method is still useful, and is often missed by those new to exceptions.', 'title': u'thanks'}, {'comment': u'A very minor consideration, but to increase speed and minimize memory usage, I return at the point of determination. Any problems with this I do not see?\n<pre>\ndef IsInt( str ):\n """ Is the given string an integer?"""\n try:\n num = int(str)\n return 1\n except ValueError:\n return 0\n</pre>', 'title': u'A minor speed/memory tweak.'}], 'desc': u"Exceptions provide very handy ways of performing simple tests. For example, if you want to know if the contents of a string represent an integer, why not just try to convert it? That's what IsInt() does."}, {'comments': [{'comment': u'under UNIX, you don\'t need the "if x: parts.append(x)" part. the x var is empty, if the\npath name is not fully specified. if it is, the x var holds a "/", which should be omitted \nin the output list.\n', 'title': u'under UNIX...'}, {'comment': u'The lines in question *are* required for systems like Windows where there is a drive specification preceding the path.', 'title': u'but only UNIX'}], 'desc': u'This function parses a full file specification into tuple of:\na) list of drive and folders\nb) file name\nc) (last) file extension (including dot)'}, {'comments': [{'comment': u'There are two problems with this code: you should call os.path.abspath and os.path.exists on the argument, and also make a second test with os.sep added (sys.path sometimes contains paths with or without a trailing [back]slash).', 'title': u'Improvements'}, {'comment': u'Extending the wish to avoid duplication, you might want to standardize the case and the separator you use before committing the change to sys.path in Microsoft environments.', 'title': u'Windows is not case-sensitive, and accepts forward and backward slashes'}, {'comment': u'I have updated the code to reflect the shortcomings addressed in the previous two comments. It has been tested on Linux and Win32. Thanks!', 'title': u'Updated'}, {'comment': u"First off, thanks for posting the code. Now, unto my gripe. The concept of dynamically adding a path suggests adding a path expression on-the-fly, i.e., prompting a user for a path expression.\n<br><br>\nHow does this function dynamically add a path as you suggest? The code suggests a static reference toward a file system folder/sub-directory within the namespace of a given file, either MS Windows or a Unix variant.\n<br><br>\nThe explanation of your function might confuse first-time Python developers. Perhaps the following explanation might improve the situation:\n<br><br>\nFor Python to import a module, the Python interpreter requires a reference to the location of the module within the namespace of your file system, i.e., Python needs to know the sub-directory/folder where a module exists. One method that informs the Python interpreter regarding the whereabouts of a module is to use the sys.path.append('your_path_here') function of the sys module that is part of the Python environment.\n\n", 'title': u'Dynamic or Static?'}], 'desc': u'Adds the specified path to the Python system path if it is not already there. Takes into account terminating slashes and case (on Windows).\n\nReturns -1 if the path does not exist, 1 if it was added, and 0 if it was not (because it is already present).'}, {'comments': [{'comment': u"The code to detect and handle numeric extensions, namely the:<br>\n<pre>\n > # is e an integer?\n > try:\n > num = int(e)\n > root = n\n > except ValueError:\n > root = file_spec\n</pre>\nwill not work because if the file name does have an extension, after the os.path.splitext() call the variable 'e' will contain a string that starts with a period. <br><br>\nBecause of that fact, the int(e) expression will always raise an exception, in which case the entire file name will be assigned to varible 'root'. After this happens the renamed file *would* have another three-digit extension added to it each time this function is called.", 'title': u'Bug'}], 'desc': u'If the specified file exists, it is versioned by appending to the extension a three-digit number, starting with "000".'}, {'comments': [{'comment': u"<pre>\nHi, minor comment ...\n\nThe logic used for creating pat_list can be simplified ...\n\nFROM THIS:\n if not pattern:\n pat_list = ['*']\n elif ';' in pattern:\n pat_list = string.split(pattern, ';')\n else:\n pat_list = [pattern]\n\nTO THIS:\n pat_list = string.splitfields( pattern , ';' )\n\n\nThanks,\n-Saveen\n</pre>", 'title': u'Simplification for pat_list'}, {'comment': u"You still need \n\npattern = pattern or '*'\n\nbefore the split, else your code is not functionally equivalent.", 'title': u'Not TOO simple :)'}, {'comment': u'Thanks for the comments -- I have implemented this change.', 'title': u'updated'}, {'comment': u'To avoid multiple matches for different patterns, replace the \'continue\' statement with a \'break\' statement<br>\n\nFor example, if the pattern was set as "*;*.py", all Python files would be included twice. This is most likely not what you want.', 'title': u'Avoid duplicate matches'}], 'desc': u'This function walks a directory tree starting at a specified root folder, and returns a list of all of the files (and optionally folders) that match our pattern(s).'}, {'comments': [], 'desc': u'Decision_Analysis is a mini-expert system or AI program to help a user make decisions. It includes a general program to help in making any decisions, big or small, as well as four sub-programs that illustrate the use of the program by applying it to four specific kinds of decisions.'}, {'comments': [], 'desc': u'These two classes show two styles of function composition. The \ndifference is only when the second function (g) returns a tuple.\ncompose passes the results of g as a tuple, mcompose treats it as\na tuple of args to pass along. Note that extra args provided to \n(m)compose are treated as extra args to f (there is no standard\nfunctional behavior here to follow).\n\n compose(f,g, x...)(y...) = f(g(y...), x...)\n mcompose(f,g, x...)(y...) = f(*g(y...), x...)'}, {'comments': [{'comment': u'Also consider:<pre>\ndef every(pred, seq):\n return len(seq)==len(filter(pred,seq))\ndef any(pred, seq):\n return len(filter(pred,seq))\nand/or:\nimport operator\ndef every(pred, seq):\n return reduce(operator.and,map(pred,seq))\ndef any(pred, seq):\n return reduce(operator.or,map(pred,seq))\n</pre>\nThe functional forms are elegant and fast.\n', 'title': u'Numeric (aka Numpy) has interesting, fast implementations of these'}, {'comment': u'The example usage indicated, produces the wrong (the inverse) output, which I guess is caused by a typo.\n<br><br>\nRegards<br>\nJorgen Cederberg', 'title': u'Errors in example.'}, {'comment': u"These versions can be much slower if the evidence is found early in the sequence - they don't bail out immediately like those in the recipe.", 'title': u'No early bail-out'}], 'desc': u'Often it is useful to know whether all elements of sequence meet\ncertain criteria, or if only some pass a test.\nThese two functions "every" and "any" do just that.\n\nExample usage:\n>>> every(lambda c: c > 5,(6,7,8,9))\n1\n>>> every(lambda c: c < 5,(6,7,8,9))\n0\n>>> any(lambda c: c > 5,(6,7,8,9))\n1\n>>> any(lambda c: c < 5,(6,7,8,9))\n0\n'}, {'comments': [], 'desc': u'This demonstrates a simple binary search through sorted data.\nA binary search is a basic algorithm provided by bisect in Python.\nThe binary search can be summarized by two lines of code:\n list.sort()\n item_insert_point = bisect.bisect (list, item)'}, {'comments': [{'comment': u'<pre>\nHi,\ngreat article. Here a short follow-up.\nProblems arise when trying to implement __getattr__ in a way described above.\nThe C-implementation is not called if added in a same way as "doSomething".\nAccording to Python Language Reference, __getattr__ must be available at the\ntime of class definition and will not be called if added to __dict__ later.\nSo, __getattr__, __setattr__ and co must be added before calling PyClass_New.\nObviously, they are added as functions, and not as methods.\n\nCode:\n\nstatic PyMethodDef AttrMethods[] =\n{\n { "__setattr__", test_setattr, METH_VARARGS },\n { "__getattr__", test_getattr, METH_VARARGS },\n { NULL, NULL },\n};\n\nfor(PyMethodDef* _def = AttrMethods; _def->ml_name; _def++) {\n PyObject *func = PyCFunction_New(_def, NULL);\n PyDict_SetItemString(classDict, _def->ml_name, func);\n Py_DECREF(func);\n }\n // finally add class and all the methods as before\n testClass = PyClass_New(NULL, classDict, className);\n // ...\n\n // skipped\n\nstatic PyObject* test_getattr(PyObject *self, PyObject *args) {\n PyObject *selfobj, *arg0;\n if(!PyArg_ParseTuple(args, "OO:test_foo", &selfobj, &arg0)) {\n // handle error\n }\n if (!PyString_Check(arg0)) {\n return NULL;\n } \n char* name = PyString_AsString(arg0);\n if (!name) return NULL;\n if (strcmp(name, "id")==0) {\n return Py_BuildValue("i", 42);\n }\n // throw attribute not found and and ...\n}\n\nBye\nVlado\n</pre>', 'title': u'getattr trouble'}, {'comment': u'With python 2.2 or better you can do a lot better than this. Python 2.2 and better have the new Class/Type unification. This was not documented until version 2.3. See the Python 2.3 "Extending and Embedding" for an example of the new interface.\n<br> <br>\nhttp://python.org/doc/2.3c1/ext/ext.html', 'title': u'With python 2.2 or greater you can do a lot better'}], 'desc': u'This recipe shows how to define a new Python class from a C extension module. The class methods are implemented\nin C, but the class can still be instantiated, extended, subclassed, etc. from Python. The same technique can also\nbe used to extend an existing Python class with methods written in C.'}, {'comments': [{'comment': u'The changes made to the environment in the proposed way do not have an effect immediately, even not for a newly start cmd.exe. The following function refreshEnvironment(), if called after setting the environment in the registry lets newly started programs (cmd.exe) "see" the new environment values.\n\nThanks for this method to Geoffrey Faivre-Malloy and Ronny Lipshitz. See http://www.installsite.org/files/PathSetup.zip\n\n<pre>\ndef refreshEnvironment():\n HWND_BROADCAST = 0xFFFF\n WM_SETTINGCHANGE = 0x001A\n SMTO_ABORTIFHUNG = 0x0002\n sParam = "Environment"\n\n import win32gui\n res1, res2 = win32gui.SendMessageTimeout(HWND_BROADCAST,\n WM_SETTINGCHANGE, 0, sParam, SMTO_ABORTIFHUNG, 100)\n if not res1:\n print ("result %s, %s from SendMessageTimeout" % (bool(res1), res2))\n\n</pre>', 'title': u'environment changes do not have an effect immediately'}], 'desc': u'Display environment variables, then append C:\\ to PATH. Example program, uses _winreg.'}, {'comments': [{'comment': u'Perhaps it should be mentioned that xmlrpclib is not in the standard library; it may be useful to give details of how it may be obtained (refer to the Vaults of Parnassus?).', 'title': u'Information on where to get xmlrpclib'}, {'comment': u'It has been checked in to the source tree for Python 2.2, until then you can get it at Python Labs here: http://www.pythonware.com/downloads/index.htm#xmlrpc', 'title': u'xmlrpclib to be included in Python 2.2'}, {'comment': u'Really? How about soap as well...', 'title': u'Standard library'}, {'comment': u'Is the text of the example correct? Everything from the second import of "pprint" down seems to duplicate the first few lines.', 'title': u'Duplicate text in example?'}, {'comment': u'Oops, thanks.', 'title': u'Duplicated text.'}], 'desc': u"This simple recipe shows how you can pull recipes from O'Reilly's meerkat service using xml-rpc."}, {'comments': [{'comment': u"Here is my code:\n<pre>\nht = httplib.HTTP('www.spam.es')\nfich='/spam.gif'\nprint fich, \nht.putrequest('GET', fich)\nht.endheaders()\nerrcode, errmsg, headers = ht.getreply()\ntextoFecha=headers.dict['last-modified']\nprint textoFecha,\nfecha = strptime.strptime(textoFecha,'%a, %d %b %Y %H:%M:%S %Z')\nprint fecha\n</pre>", 'title': u'It worked for parsing a HTTP header'}, {'comment': u"I'm so happy someone wrote this. I was just about to write it myself.\nYou should submit this to dev-python to see if is interest in creating\na PEP to add this to the Python Standard Library.", 'title': u'Good stuff'}, {'comment': u'I guess it already was.', 'title': u'Duh...'}, {'comment': u'Thanks Brett for putting this up, i just downloaded the text and imported it into my jython script and it worked like a charm. ', 'title': u'Fantastic!'}], 'desc': u'This is a modification of the Python code that powers time.strptime() in CVS on 2003-08-11 (Python 2.4 development) to be compatible with Jython 2.1 and CPython 2.1 . It does require the datetime package if you want missing date info to be filled in; it can be found in CVS at /python/nondist/sandbox/datetime/ .\n\nIf you are using CPython version 2.3.0 or higher, then you do not need this. A more modernized version of the code is included in the language.'}, {'comments': [{'comment': u'A well coded recipe. I find only one drawback: Using [filename].tmp as temporary filename might pose a security risk. Use os.mkstemp() instead to get rid of the risk.', 'title': u'os.mkstemp()'}], 'desc': u'A class that enables a client to securely update an existing file,\nincluding the ability to make an automated backup version.'}, {'comments': [{'comment': u"Well done.<br>\n<br>\nOf course, you don't have to use lambda to create a function which can be returned. You can use any kind of function. \nIf you can't define the new function in a lambda expression, you can just define the function in the 'normal' way, and return it:<br>\n<br>\nie. the example works just as well if you change:<br>\n<br>\n<pre> return lambda s,a=allchars,d=delchars: s.translate(a,d)</pre><br>\nto:<br>\n<pre> def filter_function(s,a=allchars,d=delchars): \n return s.translate(a, d)\n return filter_function\n</pre>\n<br>\nIn this case it's longer, but lambda is very limited, so it's useful to know that you can use a full function definition.\n</br></br></br></br></br></br></br></br></br>", 'title': u"If it won't fit in a lambda..."}, {'comment': u"<pre>str = 'USD 890,009.90 '\n\nset = '0123456789,.'\n\n''.join([c for c in str if c in set])\n\nresult: '890,009.90'</pre>\n", 'title': u'Try a list comprehension'}], 'desc': u'The following code creates a filtering functor for a given character set, that can then be used on any number of strings.'}, {'comments': [], 'desc': u'Grab a part of a web page and generarte a new page with a base href to the source server, so that relative links will still work.'}, {'comments': [], 'desc': u'This procedure reads through a file of unknown size once, returning a random line from the file.'}, {'comments': [], 'desc': u'Want to get a value from a dictionary but want to make sure that the value exists in the dictionary? Then use the incredibly useful get method.'}, {'comments': [], 'desc': u"This code eliminates the need to convert line endings when moving .py modules between OSes. Put in your sitecustomize.py, anywhere on sys.path, and you'll be able to import Python modules with any of Unix, Mac, or Windows line endings, on any OS."}, {'comments': [{'comment': u"The code does not test whether or not the service actually changes from one state to another. I don't know if there is some return code that can be associated with the change of the service, but it would help if it was checked.", 'title': u'Problems changing modes'}], 'desc': u'Its easy to mess with Windows Service using Python.'}, {'comments': [{'comment': u'I am interested in your snippet of code. But as I an an extream newbe I need a little hand holding to get it going. And suggestions? Thatnks Diana. diana_org@hotmail.com', 'title': u'How do you use it?'}, {'comment': u'save it as a textfile, say makepass.py in some directory on your sys.path, then from any Python script, or interactively (in the Python interpreter, IDLE, etc):<pre>\nimport makepass\nprint makepass.GenPasswd2()\n</pre>\nand similar uses. Write help@python.org for any more help request!\n', 'title': u"it's easy to use this module"}, {'comment': u"Fun little snippet, comes in handy, but there's a little bug, of course ;)\n\nThe var 'newpasswd' is being created inside the 'for', and so may not be returned. The correct snippet should be:\n\n<pre>\ndef GenPasswd():\n chars = string.letters + string.digits\n newpasswd = ''\n for i in range(8):\n newpasswd = newpasswd + choice(chars)\n return newpasswd\n</pre>\n\nThat should do it ...", 'title': u'Bug.'}, {'comment': u"How about:\n\n<pre>\nreturn ''.join([choice(chars) for i in xrange(8)])\n</pre>", 'title': u'Even shorter'}], 'desc': u'This is a code snippet to generate an 8 character alphanumeric password.'}, {'comments': [{'comment': u'I think the code here has a typo, it should say "has_key" instead of "has_keys"', 'title': u' '}, {'comment': u'Note that the difference disappears in the forthcoming Python 2.2: there, "if somekey in in adict" becomes equivalent to "if adict.has_key(somekey)". The recipe should therefore be indicated as only important for Python 2.1 and earlier.\n', 'title': u'A Python 2.2 enhancement'}, {'comment': u'Thanks.', 'title': u'Oops'}, {'comment': u'<pre>\nintersect = [item for item in some_dict.keys() if another_dict.has_key(item)]\n\nor\n\nintersect = filter(another_dict.has_key, some_dict.keys())\n</pre>', 'title': u'Alternatively...'}, {'comment': u'It is also worthwhile to note that if one dictionary has considerably more elements, the smallest dictionary should be the one to loop over. However, the difference starts to get noticeable only with dictionaries that have thousands of keys.', 'title': u'Dictionaries of different size'}, {'comment': u'What if I want to find the items that are *not* in both dictionaries?', 'title': u'Finding items *not* in both dictionaries'}], 'desc': u"A simple little task, how to find the intersection of two hashes. There's probably many ways to do this but there is one way to avoid..."}, {'comments': [{'comment': u"I was hoping there would be an addendum to the go4 book one day giving\nPython examples. It seems as if this 'Object Oriented ...' section \nmight serve that purpose. (Among others, of course.)\nThanks for this example!", 'title': u'GO4 addendum'}], 'desc': u"has a base Factory class that is meant to be subclassed and then define a default implementation to return, as well as module's to search for the class implementation. "}, {'comments': [{'comment': u'__getattr__ should pass two arguments *not* one.\nThe fix is as follows.<br>Thanks,<br>--Raj<br>\n<pre> \ndef __getattr__(self, x):\n return Constant(getattr(self._value, x))\n</pre>', 'title': u'recipe works well, except for DeepConstant which has a bug'}, {'comment': u'<pre>class DeepConstant(Constant):\n def __getattr__(self, x):\n return Constant(getattr(self._value))\n def __getitem__(self, x):\n return Constant(self._value[x])\n def __getslice__(self, x, y):\n return Constant(self._value[x:y])\n</pre>\nwill only give constancy to 1 more level. (e. g. DeepConstant([[["x"]]])[0][0][0]=\'y\')\nThe following should traverse the whole object structure:\n<pre>\nclass DeepConstant(Constant):\n def __getattr__(self, x):\n return DeepConstant(getattr(self._value))\n def __getitem__(self, x):\n return DeepConstant(self._value[x])\n def __getslice__(self, x, y):\n return DeepConstant(self._value[x:y])\n</pre>', 'title': u'DeepConstant is only skin deep...'}], 'desc': u'How to pass objects as "constant" (immutable) in python.'}, {'comments': [{'comment': u'Even the "faster" version is very inefficient since deleting an item\nfrom the middle of a list has to move all of the trailing items one\nplace up. It is still O(n**2).\n\n<br><br>\n\nHere is an O(n) algorithm. After it picks the element to remove, it\nreplaces it with the element from the end of the list, avoiding the\ncostly copy of all the trailing elements.\n\n<pre>\nsize = len(data)\nwhile size:\n size = size - 1\n index = whrandom.randint(0, size)\n elem = data[index]\n data[index] = data[size]\n print elem\n</pre>\n</br></br>', 'title': u'A quicker way to do it...'}, {'comment': u'Very clever! Thanks for the enlightenment!', 'title': u'Re: A quicker way ...'}, {'comment': u'Incorporing the helpful comment of Dr. Grisby (above), a pythonic \nfunction to select a random element of a list, consuming it, would \nlook like this:\n\n<pre>\nimport whrandom\n\ndef select(data):\n\tif data != []:\n\t\tindex = whrandom.randint(0, len(data) - 1)\n\t\telem = data[index]\n\t\tdata[index] = data[-1]\n\t\tdel data[-1]\n\t\treturn elem\n\telse:\n\t\treturn data\n</pre>\n\nThis way, no searching and no trailing-element copying are made, but \nthe caller can still rely on the (shrinking) referenced list size.', 'title': u'Adding up...'}, {'comment': u'The whrandom module is an "internal implementation detail". Module random should be used for most RNG tasks.\n', 'title': u'Use random, not whrandom...'}, {'comment': u'... and all list elements are going to be consumed, it would perhaps\nbe faster to make a shallow copy using copy.copy and perform len(list) random pair interchanges. You can then simply iterate over the re-ordered copy using for and delete the copy.\n\nThis avoids a lot of unpleasant memory allocation and deallocation.', 'title': u"If duplicating the list isn't a problem ..."}, {'comment': u"Pull the whrandom lookup out of the loop with a:<br><br>\n<pre>from whrandom import randint</pre><br><br>\nThen use randint alone in the code. You'll get a nice performance boost!\n<br><br>\nAlso the suggestion to use random instead of whrandom is probably correct especially since whrandom is being phased out. randint is *also* deprecated in favor of randomrange, though that doesn't work with older implementations of python.<br>\n<br>\n--Todd Warner</br></br></br></br></br></br></br></br>", 'title': u'Even faster...'}, {'comment': u'So replace your original poor algorithm with this clearly much better one, which shuffles the list as it goes. Some newbie might not read this far.\n', 'title': u'So change it already!'}, {'comment': u'just random.shuffle will do it!\n', 'title': u'or even better...'}], 'desc': u"The simplest, direct way of consuming a list in a random fashion is painfully \nslow for list with a few 100's of elements. There are equally simple, but much \nfaster ways to do this."}, {'comments': [], 'desc': u'This is an example of how to write a stack and then employ that stack to have a stack for use in an RPN calculator. Among other things, this shows how classes work and how to make classes that are like types.'}, {'comments': [], 'desc': u'You want to replace that portion of a string at a given position.'}, {'comments': [{'comment': u'I think this needs a little more explanation.\n\nThis recipe is for people who want to embed images in Zope DTML documents. DTML is a tag-based scripting language that is tightly integrated with Zope. You can get more info in the DTML chapter of the Zope book - http://www.zope.org/Members/michel/ZB/DTML.dtml. <br><br>\n\nTo show an image in a DTML document, you would usually write something like\n\n<pre>\n <dtml-var "myimage">\n</pre>\n\nWhen the page is being displayed Zope would look for "myimage" and call its __str__() method. This method inserts an HTML img tag with the correct src, height, width and alt attributes. <br><br>\n\nIf you want to add your own attributes (or override default values for other attributes) then you can call its tag() method directly. This is what Mikhail has demonstrated above.</br></br></br></br>', 'title': u'A bit more info'}], 'desc': u'Seems like standart question: "How make/remove img border?"\nThat is simple solution.'}, {'comments': [{'comment': u'If you know where the variable is located (local or global), you can use the much more efficient "vars().has_key(\'x\')" or "globals().has_key(\'x\')".', 'title': u'Use has_key on the internal dicts'}, {'comment': u"If you do know that the variable is in either locals() or globals(), then using has_key() on those dictionaries is certainly preferable. However, in one of Alex Martelli's posts it seemed to be his understanding that the introduction of nested scopes could mean that a variable may not be in either of those scopes. Attempting to access the variable and catching the possible exception is so far the only general technique I've come across for testing a variable's definedness.", 'title': u'But will a variable always be in globals() or locals()?'}, {'comment': u'I had problems when implementing the above when the variable I was testing for was to be a global variable, i.e.\n\n<pre>\ntry:\n myVar\nexcept NameError:\n global myVar\n myVar = 1\n</pre>\n\nThis gave a warning that myVar is used prior to global declaration. Anyone know how to deal with this? ', 'title': u'Testing for an undefined global variable'}, {'comment': u'Try declaring it as global above the try.\n<pre>\nglobal myVar\ntry:\n myVar\nexcept NameError:\n myVar = 1\n</pre>', 'title': u'It looks like only the second myVar is global'}], 'desc': u'You want to take different courses of action based on whether a variable is defined or not.\n\n'}, {'comments': [{'comment': u"Greetings,sl4ckw4re_syst3m@nunswithguns.co.uk here. \n The above module no longer works as the altavista page has changed, \ni've modified it slightly and made a working version once again.. \nUnable to post it all in here as the filters break it for some reason - posting a url instead.. \n\nhttp://gether.2ya.com/babelizer.py \n\nHope this helps\n\nsl4ckw4re_syst3m", 'title': u'Reworked to bring up to date 20/oct/2003'}], 'desc': u'This module provides a simple API to allow translation between English and several European languages via the babelfish.altavista.com web site. There is one function for simple translation, and one for "babelizing", going back and forth between two languages.\n'}, {'comments': [], 'desc': u'Python version of the MSDN VBScript example for using SendKeys. The example uses the Windows calculator and sends keystrokes to execute a simple calculation. The codes to use with SendKeys are documented at http://msdn.microsoft.com/scripting/default.htm?/scripting/windowshost/doc/wsMthSendKeys.htm'}, {'comments': [{'comment': u"And what is this script good for?\n\nPlease provide examples of how it can be used.\nI'd love to be able to right click a .py file and open it in IDLE. Can that be done with COM?", 'title': u'why?'}, {'comment': u"Perhaps I'm missing something, but coming from a VB background, we were taught (frequently, often and painfully) that if you didn't explicitly kill your COM objects when you were done with them then you were probably going to be opening memory holes. I would expect that this also holds true of Python (when done with a COM object, close the fool thing), but I can't find any examples... inclusive of this one.", 'title': u'Am I missing something?'}, {'comment': u"Python (and VB) do garbage collection, so will eventually close\nyour COM objects when you're done with them (Python is better at\nit -- no worry even if you have a cycle of references -- but it's\nnot a worry all that big in VB either, as you rarely make cycles,\nand it goes away in VB.NET anyway as it gains full GC like Python).\n", 'title': u'not a big worry'}], 'desc': u'various Windows Script Host (WSH) examples converted to Python. The originals are at:\nhttp://msdn.microsoft.com/scripting/default.htm?/scripting/windowshost/doc/wsMthRun.htm\nhttp://msdn.microsoft.com/scripting/windowshost/doc/wsproenvironment.htm\nhttp://msdn.microsoft.com/scripting/default.htm?/scripting/windowshost/doc/wsMthSendKeys.htm\n\nNote that this script is a Python program that utilizes WSH, so use a .py extension rather than .pys.'}, {'comments': [{'comment': u'To get this to work with PyGTK2 and Python 2.2.2 I had to make the following changes:\n<pre>\n--- gtkpython.py-\tWed Jan 15 20:32:00 2003\n+++ gtkpython.py\tWed Jan 15 14:00:35 2003\n@@ -3,7 +3,6 @@\n import __main__\n import codeop\n import keyword\n-import gtk\n import os\n import re\n import readline\n@@ -11,6 +10,10 @@\n import traceback\n import signal\n import sys\n+if sys.version[0] == \'2\':\n+ import pygtk\n+ pygtk.require("2.0")\n+import gtk\n \n def walk_class (klass):\n list = []\n@@ -28,8 +31,8 @@\n self.locals = lokals\n \n self.completions = keyword.kwlist + \\\n- __builtins__.__dict__.keys() + \\\n- __main__.__dict__.keys()\n+ __builtin__.__dict__.keys() + \\\n+ __main__.__dict__.keys()\n def complete (self, text, state):\n if state == 0:\n if "." in text:\n@@ -98,6 +101,11 @@\n \n def run (self):\n gtk.timeout_add (self.TIMEOUT, self.code_exec)\n+ try:\n+ if gtk.gtk_version[0] == 2:\n+ gtk.gdk.threads_init()\n+ except:\n+ pass\n gtk.mainloop ()\n \n def code_exec (self):\n</pre>', 'title': u'This program needs some simple mods to make it work with PyGTK2 and Python 2.2.2'}, {'comment': u'I don\'t know why that walk_class() function was created, but using it I wasn\'t able to do something like this:\n<pre>\n>>> w = gtk.Window()\n>>> w.sh<Tab>\n</pre>\nto see the gtk.Window methods that start with "sh". <br><br>\nThe following patch fixes this, together with some cosmetic changes.\n<br>\n<pre>\n--- pygtk-console-old.py 2004-10-26 21:03:20.732813616 -0300\n+++ pygtk-console.py 2004-10-26 20:42:36.893905872 -0300\n@@ -10,22 +10,12 @@ import threading\n import traceback\n import signal\n import sys\n+import string\n if sys.version[0] == \'2\':\n import pygtk\n pygtk.require("2.0")\n import gtk\n\n-def walk_class (klass):\n- list = []\n- for item in dir (klass.__class__):\n- if item[0] != "_":\n- list.append (item)\n-\n- for base in klass.__class__.__bases__:\n- list = list + walk_class (base())\n-\n- return list\n-\n class Completer:\n def __init__ (self, lokals):\n self.locals = lokals\n@@ -66,10 +56,7 @@ class Completer:\n expr, attr = m.group(1, 3)\n\n obj = eval (expr, self.locals)\n- if str (obj)[1:4] == "gtk":\n- words = walk_class (obj)\n- else:\n- words = dir(eval(expr, self.locals))\n+ words = dir(eval(expr, self.locals))\n\n matches = []\n n = len(attr)\n@@ -79,7 +66,7 @@ class Completer:\n return matches\n\n class GtkInterpreter (threading.Thread):\n- """Run a gtk mainloop() in a separate thread.\n+ """Run a gtk main() in a separate thread.\n Python commands can be passed to the thread where they will be executed.\n This is implemented by periodically checking for passed code using a\n GTK timeout callback.\n@@ -106,12 +93,12 @@ class GtkInterpreter (threading.Thread):\n gtk.gdk.threads_init()\n except:\n pass\n- gtk.mainloop ()\n+ gtk.main()\n\n def code_exec (self):\n """Execute waiting code. Called every timeout period."""\n self.ready.acquire ()\n- if self._kill: gtk.mainquit ()\n+ if self._kill: gtk.main_quit ()\n if self.new_cmd != None:\n self.ready.notify ()\n self.cmd = self.cmd + self.new_cmd\n@@ -164,16 +151,21 @@ if __name__=="__main__":\n prompt = \'>>> \'\n interpreter = GtkInterpreter ()\n interpreter.start ()\n- interpreter.feed ("from gtk import *")\n+ interpreter.feed ("import gtk")\n interpreter.feed ("sys.path.append(\'.\')")\n if len (sys.argv) > 1:\n for file in open (sys.argv[1]).readlines ():\n interpreter.feed (file)\n print \'Interactive GTK Shell\'\n+ py_version = string.join(map(str, sys.version_info[:3]), \'.\')\n+ pygtk_version = string.join(map(str, gtk.pygtk_version), \'.\')\n+ gtk_version = string.join(map(str, gtk.gtk_version), \'.\')\n+ print \'Python %s, Pygtk %s, GTK+ %s\' % (py_version, pygtk_version,\n+ gtk_version)\n\n try:\n while 1:\n- command = raw_input (prompt) + \'\\n\' # raw_input strips newlines\n+ command = raw_input (prompt) + \'\\n\' # raw_input strips newlines\n prompt = interpreter.feed (command) and \'>>> \' or \'... \'\n except (EOFError, KeyboardInterrupt): pass\n</pre>', 'title': u'Tab not working in gtk objects'}], 'desc': u'One of pythons greatest strengths is the ability to try things interactively at the interpreter. \nUsing Tkinter shares this strength, since one can create buttons, windows and other widgets, \nand instantly see them onscreen, click on buttons to activate callbacks and still be able to\nedit and add to the widgets from the python command line.\n\nWhile the python GTK bindings are generally excellent, one of their flaws is that this is not possible. \nBefore anything is actually displayed, the gtk.mainloop() function must be called, ending the \npossibility of interactive manipulation.\n\nThis recipe is a program which simulates a python interpreter which transparently allows the user to\nuse gtk widgets without having to call mainloop(), in much the same way as Tk widgets.\n\nThis latest version contains enhancements added by Christian Robottom Reis to add readline completion support.'}, {'comments': [{'comment': u'Looks pretty good - I see how you\'re using the inherent inaccuracy of the system clock to add a bit of randomness to your calculation. My only concern is the time.sleep() call. Unless we really have to, we don\'t want the user waiting while the computer sleeps. I know we\'re only talking a few milliseconds, but they all add up! You don\'t want to spend them unnecessarily. How about this revised version?\n\n<pre>\ndef getNewSID2(tag):\n """Build a new Session ID"""\n t1 = time.time()\n t2 = t1 + whrandom.random()\n base = md5.new( tag + str(t1 +t2) )\n sid = tag + \'_\' + base.hexdigest()\n return sid\n</pre>\n\nNow, I\'m not going to say that this is just as random. In fact, I have to confess I have no idea what my change does to the distribution of values that you\'ll get out. But it seems pretty good to me. I reckon a combination of the system time, a pseudorandom number and a bit of hashing is enough to foil someone trying to guess those ids! <br><br>\n\nPersonally, when I\'m generating numbers which need to be hard to guess and unique I go for a very simple solution.\n\n<pre>\n unique_and_hard_to_guess_number = str(unique_number) + \'_\' + str(hard_to_guess_number)\n</pre>\n\nI\'ll usually get unique numbers by starting a counter at 1 and increasing it each time. My "hard to guess" numbers are usually just the result of a call to random(), but a technique like you use here might be a better approach.</br></br>', 'title': u'Save those seconds!'}, {'comment': u'The unique_and_hard_to_guess_number in the previous comment is not very hard to guess if you have knowledge of other values in the sequence.\n<br>\n<br>\nFor truely hard to guess random numbers, use the algorithm on page 425-426 in "Applied Cryptography".</br></br>', 'title': u"unique_and_hard_to_guess_number isn't hard to guess"}], 'desc': u'This is a method I developed recently for generating all but guaranteed unique session IDs for a non-web application I am working on. It takes a string and returns a string.'}, {'comments': [{'comment': u"This is great for basic coding, but for inner loops use the temporary variable.\n<br>\nThis comes straight from the Python Tutorial, section 10.10 on Performance Measurement.\n<pre>\n>>> from timeit import Timer\n>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()\n0.60864915603680925\n>>> Timer('a,b = b,a', 'a=1; b=2').timeit()\n0.8625194857439773\n</pre>\nhttp://www.python.org/doc/2.3.3/tut/node12.html", 'title': u'Runtime penalty'}, {'comment': u"don't know the reason but this is what I got on my system<br>\n<br>\n>>> from timeit import Timer <br>\n>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit() <br>\n0.25679183006286621 <br>\n>>> Timer('a,b = b,a', 'a=1; b=2').timeit() <br>\n0.20631599426269531 <br>\n<br>\nso bye to temp variables", 'title': u'I found tuple method is faster'}], 'desc': u"You want to swap the values of some variables, but don't want to use a temporary variable."}, {'comments': [], 'desc': u'You want to get the ASCII number of a character, or you want to get the character given by an ASCII number.'}, {'comments': [{'comment': u"You can also use map:<br>\n<pre>\nmap(function, chars)\n</pre>\nThat way you throw the for loop on a C loop, that is faster. I don't know if it will work fine with nested scopes, but should work fine.", 'title': u'Use map()'}], 'desc': u'You want to process a string one character at a time.'}, {'comments': [{'comment': u'<pre>There is a typo numotkens in\ndef assertlex ... \n assert len(lexxml(data)) ... (data, numotkens)\n\nwhere it should read (data, numtokens)</pre>', 'title': u'Hint: Typo in line 60'}], 'desc': u'Sometimes you want to work more with the form of an XML document than with the structural information it contains. For instance if you wanted to change a bunch of entity references or element names. Also, sometimes you have slightly incorrect XML that a traditional parser will choke on. In that case you want an XML lexer or "shallow parser". This is a Python implementation.'}, {'comments': [], 'desc': u'Construct a dictionary with String (or other) keys and unbound methods or functions as values. During execution, use the string keys to select which method or function to execute. Can be used for simple parsing of tokens from a file thru a kind of object-oriented case statement.'}, {'comments': [{'comment': u'I was struggling with use of sax parser but this article solved that problem', 'title': u'This is good'}, {'comment': u"set_default is no use for immutable values (like, here, numbers). Rather, the elegant alternative idiom is:<pre>\n adict[akey] = 1 + adict.get(akey,0)\n</pre>\nEven more old-fashioned than Paul's choice - no += ...!-)\n", 'title': u'on the set_default side note'}], 'desc': u'This is an example SAX application and can be used as the basis for any SAX application. It is somewhat useful in and of itself when you want to get a sense of the frequency of occurance of particular elements in XML.'}, {'comments': [{'comment': u'http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65125', 'title': u'Direct link to author\'s "XML lexing"'}, {'comment': u'from sgmllib import SGMLParser\n\nclass XMLJustText ( SGMLParser ) :\n def handle_data ( self, data ) :\n print data\n\nXMLJustText ( ) . feed ( "text 1text 2" )\n\n', 'title': u'Another way'}], 'desc': u'People often ask how to extract the text from an XML document. This small program does it.'}, {'comments': [{'comment': u'..easy fix:\nchange: "pairings.append(units[i], units[count-i-1])", on line 12, to: "pairings.append((units[i], units[count-i-1]))", and it works, fine!', 'title': u'syntax error'}, {'comment': u"I have been trying to figure a four on four RR pairing where each of four players plays the opponent team's four players. My problem is trying to even out the waits between games for all players fairly. Any ideas would be appreciated. thanks.", 'title': u'A slight twist for you.'}], 'desc': u'An implementation of a round-robin algorithm for "fair" pairing of items from a list. The function produces a schedule of the pairings that can occur simultaneously. '}, {'comments': [{'comment': u'_get_method_names freely allows duplicate names for inherited and overridden methods, placing the base versions after the overriding ones. But then the loop that builds self.__methods will make the latter (base-class) version \'override\' the former (inheriting/overriding!) version. Easy fix, just guard the body of that loop with "if not self.__methods.has_key(name)".\n', 'title': u'subtle, interesting bug when wrapping an object that inherits and overrides a method'}, {'comment': u"The type checks do not work for new style classess, actually for instance objects of new style classes. Their type is not anymore InstanceType but rather ObjectType. Here follows fixed _get_method_names() function fixed and tested with the Python version 2.2.3:\n\n<pre>\ndef _get_method_names (obj):\n from types import InstanceType, ObjectType\n from types import ClassType, TypeType\n from types import FunctionType, MethodType\n\n if isinstance(obj, ObjectType):\n if isinstance(obj, InstanceType ):\n return _get_method_names(obj.__class__)\n elif isinstance(obj, TypeType)or isinstance(obj, ClassType):\n result = []\n for name, func in obj.__dict__.items():\n if isinstance(func, FunctionType) or isinstance(func, MethodType):\n result.append((name, func))\n for base in obj.__bases__:\n result.extend(_get_method_names(base))\n return result\n else:\n return _get_method_names(obj.__class__)\n else:\n raise TypeError, 'Invalid type'\n</pre>\n\nMight not be 100% pythonic but I apologize as I am C++ convert :-)\n<br>\nRadovan", 'title': u'There is a problem when using new style classes'}, {'comment': u'...but I do not understand this line from the SynchronizedObject constructor:\n<pre> lock = lock and lock or threading.RLock()</pre>\n\nCan someone shed light on what this does?', 'title': u'I thought I know python...'}, {'comment': u'The line just checks to see if you passed a lock to the function and if you didn\'t, creates a new one.\n\nThis is known as the and/or idiom and acts in a similar way to the ?: operator in C/C++. If lock is None, "lock and lock" will return False, and "new RLock()" will be used. The usage of this idiom is not encouraged however as there are some pitfalls.\n', 'title': u'Short circuit'}], 'desc': u'Makes sure that only one thread at a time is "inside" the object. This restriction can be lifted for methods whose locking you want to handcode.'}, {'comments': [{'comment': u"Although these platforms have os.name == 'nt', the Win32 API on them does not support the LockFileEx and UnlockFileEx functions -- this recipe will fail with api_error at the win32 function calls.\n\nWin32 supports LockFile, UnlockFile on all platforms, but with lower functionality: no shared/exclusive flag, no block-until-locked mode.\n", 'title': u'Note however this fails on Win95, Win98'}, {'comment': u'This generates warnings under Python 2.3.3, about what will happen in Python 2.3.4: \n\n<pre>\nrunning py2exe\nportalocker.py:62: FutureWarning: hex/oct constants > sys.maxint will return positive values in Python 2.4 and up\n win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)\nportalocker.py:66: FutureWarning: hex/oct constants > sys.maxint will return positive values in Python 2.4 and up\n win32file.UnlockFileEx(hfile, 0, 0xffff0000, __overlapped)\n</pre>\n\nIs this going to be a problem?', 'title': u'Python 2.3.4'}, {'comment': u'The code does cause an error under Python 2.4\n\nApparently, this is because the hexidecimal constant, 0xffff0000, which evaluated to the integer -65536 in Python 2.3, evaluates to the long integer 4294901760 in Python 2.4 due to the unification of long and short integers.\n\nChanging the constant to -0x10000 seems to correct the problem.', 'title': u'How to make the recipe work for Python 2.4'}, {'comment': u'<pre>\nhere\'s an approach to file locking that might be useful to somebody, especially for a consumer-producer type situation. It uses the fact that on windows, renaming a file that is already open will raise an exception.\n\n____Producer___: \n\nimport time, os\n\n#lock readers out by renaming the file \nif os.access("filename", os.F_OK):\n for failure_counter in range(0, 600):\n try:\t\t\t\t\n\t os.rename("filename", "filename.temp") \n break #removed the file successfully\n\t except:\t\t\t\t\n\t time.sleep(1) #someone is reading from the file \n else:\n\traise Exception #consumers kept the file open for over 10 min\n\n#file is now locked\nfile = open("filename.temp", "w") \nfile.write("bla bla")\nfile.close()\t\t\nos.rename("filename.temp", "filename") #unlock the file\n\n \n____Consumers___:\n\nimport time, os\n\n#wait until file exists (eg. is unlocked\nfor i in range(0,600):\n if os.acces("filename", os.F_OK):\n break\n else:\n time.sleep(1)\nelse:\n raise Exception #file still locked after 10 minutes\n\n#access the file\nfile = open("filename", "r")\ncontents = file.read()\nfile.close()\n\n</pre>', 'title': u'home-made file locking'}, {'comment': u'ActivePython 2.4.1 Build 247 (ActiveState Corp.) based on\nPython 2.4.1 (#65, Jun 20 2005, 17:01:55) [MSC v.1310 32 bit(Intel)] on win32\n\n<p></p>\nTraceback (most recent call last):\n File "portalocker.py", line 80, in ?\n portalocker.lock(log, portalocker.LOCK_EX)\n File "C:\\portalocker.py", line 61, in lock\n win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)\nOverflowError: long int too large to convert to int', 'title': u'error in WinXpsp2 '}], 'desc': u'Synopsis:\n\n import portalocker\n file = open("somefile", "r+")\n portalocker.lock(file, portalocker.LOCK_EX)\n file.seek(12)\n file.write("foo")\n file.close()\n'}, {'comments': [{'comment': u'<pre>\nclass typecheck:\n def __init__(self,i):\n self.__type__ = type(i)\n def __setattr__(self,name,value):\n if (name.find(\'__type__\') != 0) and (type(value) != self.__type__):\n raise TypeError, "(%s) is not %s"%(name,self.__type__.__name__)\n self.__dict__[name]=value\n\n\nif __name__ == \'__main__\':\n import sys\n try:\n my_int = typecheck(1)\n my_int.x = 3\n my_int.y = 4\n my_int.z = 5\n my_int.h = \'hey\'\n except:\n print sys.exc_type, sys.exc_value\n\n try:\n my_string = typecheck(\'\')\n my_int.s = \'hello\'\n my_int.t = \'byebye\'\n my_int.u = 3\n except:\n print sys.exc_type, sys.exc_value\n</pre>', 'title': u'good for typechecking too?'}, {'comment': u'This is clever, but keep in mind that all the standard modules implement constants this way:\n\n<pre>AUDIO_FILE_MAGIC = 0x2e736e64\nAUDIO_FILE_ENCODING_MULAW_8 = 1\nAUDIO_FILE_ENCODING_LINEAR_8 = 2\nAUDIO_FILE_ENCODING_LINEAR_16 = 3\n</pre>\n\nThis is much clearer to me. (It runs faster, too.)\n', 'title': u"Don't get carried away, though"}, {'comment': u'Jason Orendorff,\n What prevents someone from re-declaring your variables?', 'title': u' '}, {'comment': u"The fact that they are all-uppercase and that the programmer knows that means they are intended to be constants.<br><br>\n\nIf the programmer is a moron, you're screwed anyway. I find all this tendency to try and create libraries/frameworks/utils that can not possibly be used incorrectly a little wrong-headed. Just follow conventions, document, and hope for the best.", 'title': u' '}, {'comment': u"Just make sure that you don't follow that philosophy when you are creating your end product. Your end-user should be able to crash the product. They should, instead, get warnings, if anything.", 'title': u'except:'}, {'comment': u'This philosophy is the reason I like python.\nNo need for restrictive private functions and stuff. It should be clear to people that this function is not supposed to be called, but if they REALLY want to, they can do it.\nAnd yes, this has nothing to do with the end user, which should of course be protected against h(im|er)self.', 'title': u'Good philosophy'}], 'desc': u'In Python, any variable can be re-bound at will -- and modules don\'t let you define special methods such as an instance\'s __setattr__ to stop attribute re-binding. Easy solution (in Python 2.1 and up): use an instance as "module"...\n'}, {'comments': [{'comment': u'Does anyone have a library that will supply access to the NT User Database on an NT4 server that does not run ADSI?\n\nTIA Adrian', 'title': u'Manipulating NT User Information with PERL (No ADSI)'}], 'desc': u"This script gives an example on how to use Python COM to instantiate an ADSI object and change a NT user's password."}, {'comments': [{'comment': u"The output doesn't show the sorted list in the reverse order that would be expected for the given comparision function. I haven't looked through the C code to see if there is actually a coding error there, or whether a slip was made merely in capturing the program's output.\n", 'title': u"Sorted list isn't in reverse order as expected"}, {'comment': u'It works as expected when it is run. I made a mistake while\npasting the code in. Thanks for pointing it out.\n\n', 'title': u'Typo while cut and pasting - apologies'}, {'comment': u'At least with gcc, you can use the __thread modifier to store the py_compare_func in TLS. Simply do this:\n\n__thread static PyObject *py_compare_func = NULL;\n\nAnd now each thread should get its own version of the variable, solving the multi-threaded issue.', 'title': u'maybe could use thread local storage'}, {'comment': u"It looks like after PyCallable_Check is called, a 'return NULL;' is necessary after the PyErr_SetString() line so as the TypeError exception is actually actived.", 'title': u'callable check typo'}], 'desc': u'Lets say you have a function in C or C++ that takes a function callback as an argument. You want to call this function by passing a Python function as the callback. This recipe shows the basics by calling the standard C library function qsort, and passing a python function as the compare function.'}, {'comments': [{'comment': u'The example dictionary should not contain codes like r\'\\0\'. While the letter escapes work, you need to represent the numeric codes as full 3-digit octal (r\'\\000\') or hex (r\'\\x00\') values, or you will be surprised translating the two-character string "\\x007\' into a constant that becomes a bell character. \'\\8\' and \'\\9\' are really just the characters \'8\' and \'9\'. It is also a bad idea to have a dictionary constant with conflicting entries (\'\\7\' and \'\\a\').\n\nSo, replace the last part of the escape_dict definition with:\n<pre> ...,\n \'\\"\':r\'\\"\',\n \'\\0\':r\'\\000\',\n \'\\1\':r\'\\001\',\n \'\\2\':r\'\\002\',\n \'\\3\':r\'\\003\',\n \'\\4\':r\'\\004\',\n \'\\5\':r\'\\005\',\n \'\\6\':r\'\\006\'}\n</pre>\n', 'title': u'\\0 through \\9 are not great examples'}, {'comment': u"If I use your suggestion, I end up with the following result:\n<pre>\n>>> raw('\\1\\2\\3')\n'\\\\001\\\\002\\\\003'\n>>> r'\\1\\2\\3'\n'\\\\1\\\\2\\\\3'\n</pre>\nThe whole point of this is to get back the string to the form it should be in had an r been appended to the string when it was created. Unfortunately your solution breaks that.", 'title': u'Defeats Purpose'}], 'desc': u'This function takes in an arbitrary string and converts it into its raw string equivalent. Unfortunately \\x will raise a ValueError and I cannot figure out how to deal with it.\n\n[2001-06-18: Completely reworked function for performance]'}, {'comments': [{'comment': u'Just as 9 is the biggest number in base-10, z is the biggest number in base-36, not base-35.', 'title': u'Max is base-36'}, {'comment': u"Couldn't the num_rep dictionary be more concisely set up using a for loop (assuming you want to stick to doing the conversion using dictionary lookup rather than computation)?", 'title': u'Setting up num_rep more concisely?'}, {'comment': u'The description of the algorithm is incorrect: it does not take a decimal number as input, but a Python integer object - whether this was created through a decimal literal, or through a hexadecimal one, or through some other expression is irrelevant.', 'title': u'Input is not decimal'}, {'comment': u'This code fails in several ways:<br>\n\n- base = 1 causes infinite loop<br>\n- base = 0 causes divide by zero<br>\n- non-numerics passed for number or base cause exception<br>\n- incorrectly converts number 0 to "" for any base<br>\n<br>\nThe code is much longer than it should be. Using a dictionary for a sequentially-indexed list of letters is wasteful; even worse is the suggestion to populate the dictionary with a for loop. Making the distinction between digits in the 0..9 range and digits in the a..z range over-complicates the code. The digits needed for bases 2..36 are a constant string.\n<br><br>\nHere\'s a version that doesn\'t have these problems (though it may have other bugs). And I think it is more Pythonic.<br>\n<pre>\ndef baseconvert(n, base):\n """convert positive decimal integer n to equivalent in another base (2-36)"""\n\n digits = "0123456789abcdefghijklmnopqrstuvwxyz"\n\n try:\n n = int(n)\n base = int(base)\n except:\n return ""\n \n if n < 0 or base < 2 or base > 36:\n return ""\n\n s = ""\n while 1:\n r = n % base\n s = digits[r] + s\n n = n / base\n if n == 0:\n break\n\n return s\n</pre>\n<br>\nIt doesn\'t deal with base > 36 but it should be obvious how to extend the code to do it.\n<br><br>\nGreg Jorgensen<br>\nPDXperts LLC - Portland, Oregon USA', 'title': u'quite a few problems, and not a great implementation'}], 'desc': u'This function takes in any base-10 integer and returns the string representation of that number in its specified base-n form.\n\nUp to base-36 is supported without special notation for symbolizing when a number is really in a single digit position. When that does occur, the number that takes up that single base is surrounded by parantheses.\n\n[2004-06-30: Renamed function to base10toN to be more proper]\n\n[2001-06-17: Changed comments to base-36 instead of base-35; thanks Klaus Alexander Seistrup]\n\n[2001-06-17: Added for loop mechanism in Discussion for alternative way of creating num_rep dictionary; thanks Hamish Lawson for suggesting that possibility]'}, {'comments': [{'comment': u'It is important to note that email adresses _can_ be shorter than 7 characters. Although domain names shorter than 2 letters are not allowed in .com .net and .org, many ISO country domain registrars do allow one letter domain names. For example in Denmark, where I live. \nFor example see http://www.n.dk\n', 'title': u'Short email adresses'}, {'comment': u"If you'll do 'nslookup -type=mx va' or similar you'll find that va has mail exchangers associated. This means that the shortest email address, IMHO, is .", 'title': u'Short email addresses and .va'}, {'comment': u"Doesn't look like your code will validate .info domains. Here is the regexp I use for my email validation:\n\nre.compile('^[_\\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\\.)+[a-z]{2,4}$')", 'title': u'.info?'}, {'comment': u'I think this recepie may not validate idn email ids.\nTry validating user@z\xe4\xe4z.de .', 'title': u'idn emails'}], 'desc': u'This function simply validates an e-mail address. Ignore this recepie and go to my "StringValidator" recepie, which is a much better solution'}, {'comments': [], 'desc': u'This class generates passwords, either random or from a dictionary.'}, {'comments': [{'comment': u'See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66517 for a version of this useful code that uses Python built-in socket and struct modules to avoid "recoding the wheel".\n', 'title': u'good base idea, but I think it needs enhancements'}, {'comment': u'Alex is right--the Python libraries already have functions to do this.\n<br><br>\nI wrote these functions as part of explaining IP addresses, dotted-quad notation, and masking to someone. I posted them here more as a learning tool than production code.', 'title': u'recoding the wheel'}], 'desc': u'Convert dotted-quad IP addresses to long integer and back, get network and host portions from an IP address.'}, {'comments': [{'comment': u"If no exception is raised by the base class task() method, it might just quietly 'pass' in the backgroud, and the error would be hard to detect.\n\nInstead of:\ndef task(): pass\n\nusing:\ndef task(): raise Exception #( or a more specific exception )\n\n..would prevent errors arising from attempting to use the TaskThread class without subclassing it, and properly overriding the task() method.\n", 'title': u'raise an exception to ensure subclass overrides task()'}, {'comment': u'You might also try this:\n<pre>\nclass PeriodicExecutor(threading.Thread):\n def __init__(self,sleep,func,params):\n """ execute func(params) every \'sleep\' seconds """\n self.func = func\n self.params = params\n self.sleep = sleep\n threading.Thread.__init__(self,name = "PeriodicExecutor")\n self.setDaemon(1)\n def run(self):\n while 1:\n time.sleep(self.sleep)\n apply(self.func,self.params)\n</pre>\n\nIt allows you to specify a function to be executed with specified params every n seconds.\n', 'title': u'Improvement'}, {'comment': u'I tried to use this functionality as follows :\n<pre>\nif __name__ == \'__main__\':\n class printTaskThread(TaskThread):\n def task(self):\n print \'running\'\n \n tt = printTaskThread()\n tt.setInterval(3)\n print \'starting\'\n tt.run()\n print \'started, wait now\'\n import time\n time.sleep(7)\n print \'killing the thread\'\n tt.shutdown()\n print \'killed and done\'\n\n</pre>\n\nthis results in the following output under Win NT.\n\n<pre>\nE:\\python.samples>python thread_its.py\nstarting\nrunning\nrunning\nrunning\nrunning\nrunning\nrunning\nrunning\nrunning\nTraceback (most recent call last):\n File "thread_its.py", line 40, in ?\n tt.run()\n File "thread_its.py", line 26, in run\n self._finished.wait(self._interval)\n File "C:\\python22\\lib\\threading.py", line 331, in wait\n self.__cond.wait(timeout)\n File "C:\\python22\\lib\\threading.py", line 209, in wait\n _sleep(delay)\nKeyboardInterrupt\n</pre>\n\nSo the calling program doesn\'t get control again. I thougt that it is the point of threads to allow just that. Wondering ...\n\n\n', 'title': u'This seems odd ...'}, {'comment': u'Change the tt.run() to tt.start()', 'title': u're: This seems odd ...'}, {'comment': u'<pre>\nA way of doing this in wxPython would be to subclass\nwxThread and post an event every interval you specify.\nMake the window / widget catch this event and let it\nprocess it accordingly.\n</pre>\n\n<pre>\nSomething like this...\n</pre>\n<pre>\nMYSPECIFICEVENT=500 #or some number\n\nclass MyWindow(wxFrame):\n """ Window which handles events """\n<pre>\n def __init__(self):\n ...\n EVT_MENU(self, MYSPECIFICEVENT, self.HandleEvent)\n self._scheduler=myTimer(self)\n self._scheduler.SetInterval(1000)\n</pre><pre>\n #create the thread and run it\n self._scheduler.Create()\n self._scheduler.Run()\n</pre>\n<pre>\n def HandleEvent(self, event):\n """ This function handles events """\n</pre>\n<pre>\n id = event.GetInt()\n if id == MYSPECIFICEVENTID:\n #do something\n ....\n elif id == SOMETHINGELSE:\n #dom something else\n .....\n elif ...\n #do other things\n</pre>\n<pre>\nclass myTimer(wxThread):\n</pre>\n<pre>\n def __init__(self, window):\n self._window = window # widget where work is done\n self._gap = 0\n self._timer = threading.Event()\n</pre>\n<pre>\n def SetInterval(self, gap):\n self._gap = gap\n</pre>\n<pre>\n def Entry(self):\n while 1:\n self.Sleep(self._gap)\n evt=wxCommandEvent(MYSPECIFICEVENT)\n evt.SetInt(MYSPECIFICEVENTID)\n wxPostEvent(self._window, evt)\n</pre>\n<pre>\n if self._timer.isSet():\n break\n</pre>\n\n<pre> \n def Exit(self):\n pass\n</pre>\n<pre>\n def EndThread(self):\n self._timer.set()\n</pre> \n\n<pre>\n The idea is to allow the main window or thread creator to do the work and use the thread to just post events. This has the added advantage that we can create many scheduler threads firing events with different ids and let the window perform many tasks simaltaneously. \n</pre>\n\n<pre>\nThis example is courtesy the threading example in wxWindows samples.</pre></pre>', 'title': u'Doing it in wxPython'}], 'desc': u'The TaskThread class allows you to create threads that execute a specific action at a specified interval, by subclassing - just override the task() method. You can also shutdown a TaskThread without having to wait for it to finish "sleeping" (due to the use of threading.Event objects as an alternative to time.sleep()).'}, {'comments': [], 'desc': u"Advogato (http://www.advogato.org) exports members' diaries in a simple XML format. This script fetches the entries and stores them in a dictionary keyed by date. I assume it can also be used with other virgule sites, such as http:///www.badvogato.org."}, {'comments': [{'comment': u'# for the last function<br>\n<pre>\ndef split_at(theline, cuts, lastfield=True):\n pieces = [ theline[i:j] for i, j in zip([0]+cuts, cuts) ]\n if lastfield:\n pieces.append(theline[cuts[-1]:])\n return pieces\n</pre>\n<br>\n# Notice the boolean value vs. None and the proper slicing in the<br>\n# conditional vs. the "()"<br>\n# Thanks for the nice recipe<br>\n# John Pywtorak', 'title': u'I think the intention was the following, slight patch'}], 'desc': u"You want to access portions of a string. For example, you've read a fixed-width record and want to extract the fields."}, {'comments': [{'comment': u'The reverse of a string is the first letter prefixed by the reverse of the *rest* of the string:\n\n<pre>\ndef reverse(str):\n\tif len(str)==1:\n\t\trevstr=str\n\telse :\n\t\trevstr=reverse(str[1:])+str[0]\n\t\t\n\treturn revstr\n</pre>', 'title': u'Recursively reversing a string'}, {'comment': u"<br> a = 'abcdefghi'\n <br>print a[::-1]\n<br>'ihgfedcba'", 'title': u'There is more simple way'}], 'desc': u'You want to reverse the characters or words of a string.'}, {'comments': [], 'desc': u'You want to convert tabs in a string to the appropriate number of spaces, or vice versa.'}, {'comments': [{'comment': u'The function could handle multidimensional lists if recursion were used:\n\n<pre>\ndef SequenceToUnorderedList(seq):\n html_code = "<ul>\\n"\n for item in seq:\n if type(item) == type([]):\n html_code += SequenceToUnorderedList(item)\n else:\n html_code += "<li>%s</li>\\n" % item\n html_code += "</ul>\\n"\n return html_code\n</pre>\n', 'title': u'Handle multidimensional lists using recursion '}, {'comment': u'You could also have it nicely format your recursion:\n\n<pre>\ndef SequenceToUnorderedList(seq,i=1):\n tab = \'\\t\'\n html_code = "%s\\n" % (tab*(i-1))\n for item in seq:\n if type(item) == type([]):\n html_code += SequenceToUnorderedList(item, i+1)\n else:\n html_code += "%s%s\\n" % (tab*i, item)\n html_code += "%s\\n" % (tab*(i-1))\n return html_code\n</pre>\n', 'title': u'Recursion w/ indentation'}, {'comment': u'A list comprehension may make the body clearer:\n<pre>\ndef SequenceToUnorderedList(seq):\n return "\\n".join(["<ul>\\n"] +\n ["<li> " + item for item in seq] +\n ["\\n</ul>\\n"])\n</pre>', 'title': u'List Comprehensions are a natural here'}], 'desc': u'This function simply takes a single-dimension sequence and converts into into an HTML unordered list. This function makes it simple to present the contents of a sequence on the web in an neat fashion.'}, {'comments': [{'comment': u'Note that for up-to-date distributions of MySQLdb you need to go to http://sourceforge.net/projects/mysql-python<br>', 'title': u'New Link for Downloads'}, {'comment': u'I will update the url so nobody gets mislead.', 'title': u'Thank you!'}, {'comment': u'In order to have the script working, I have to add a comma between passwd and db parameters.<br>\n<br>\nAs here :<br>\n<br><pre>\nCon = MySQLdb.Connect(host="127.0.0.1", port=3306, user="joe", passwd="egf42", db="tst")</pre>\n<br>\nAnyway, thanks for this recipe, it help me to start with mysql-python.<br>', 'title': u'Typo'}, {'comment': u"<pre>\ncon = MySQLdb.Connect(host='localhost', port=3306, user='user', passwd='secret', db='dbname', unix_socket='/var/lib/mysql/mysql.sock') \n</pre><br><br>\nsockets are faster on localhost and some distributions of linux keep things in funny places... You can just add the unix_socket parameter like above for Fedora Core 3.\n<br><br>\nMaybe named_pipe on windows is similar; I can't say though.", 'title': u'UNIX Sockets'}], 'desc': u'A simple example showing how to use the MySQLdb interface to function with your MySQL database.'}, {'comments': [], 'desc': u'This is a reusable way to use "xml.parsers.expat" to parse an XML file. When re-using the "MyXML" class, all you need to define a new class, with "MyXML" as the parent. Once you have done that, all you have to do is overwrite the inherited XML handlers and you are ready to go.'}, {'comments': [], 'desc': u'wxPython provides a powerul functionality that allows you to use a "Notebook" user interface with multiple panels - whose interface each is determined by individual Python scripts. Each panel runs in the background (even when it is not selected), and maintains the state it is in as the user switches back and forth.'}, {'comments': [{'comment': u'Ip = line.split(" ")[0]\n\nAttributeError: \'string\' object has no attribute \'split\'\n', 'title': u'line.split ???'}, {'comment': u'You must be using Python 1.52, or maybe 1.6, or something?\n<br><br>\n".split" (without importing \'string\') is a feature introduced in Python 2.0+\n<br><br>\nTo make that work in older versions you will need to change it to something like:\n<br><br>\nimport string\n<br><br>\nIp = string.split("", line)</br></br></br></br></br></br></br></br>', 'title': u'Older version of Python..'}, {'comment': u'In Python 2.0 and above the string module is used for backward compatibility. Instead, a builtin strop module is used.\n<br><br>\nAnd now, even strop is obsolete, with the string functions being built-in\n<br><br>\nIf you use the string module nevertheless, there is no overhead.</br></br></br></br>', 'title': u'Strop'}, {'comment': u'the part where is tested for a good IP is not wholy correct:<br>\n# ensure length of the ip is proper: see discussion<br>\nif 6 the part where is tested for a good IP is not wholy correct:<br>\n# ensure length of the ip is proper: see discussion<br>\nif 6 ', 'title': u'Thanks for the code but small bug'}, {'comment': u'# ensure length of the ip is proper: see discussion<br>\nif 6 < len(Ip) < 15:<br>\nshould be:<br>\nif 6 < len(Ip) < 16:<br><br>\n\n\n', 'title': u'again the small bug'}], 'desc': u'This function returns a dictionary containing the hit counts for each individual IP that has accessed your Apache web server.'}, {'comments': [], 'desc': u'This function will return a list containing the indices needed to reach an item in embedded sequences.\n\nSo deepindex([[1,2],[3,[4,[5,6]]],7,[8,9]],6) will return [1,1,1,1].'}, {'comments': [{'comment': u'I was going to make some suggestions, such as adding a jump-to, command-line options, simplifying the code in various places, and making it all more Pythonic.\n\nBut instead I have modified my own hex dump utility to add your screen clearing. It can be found here as hexify.', 'title': u'alternate implementation'}], 'desc': u'READBIN is a Text Console-based program which reads a single Input File specified on the command line one character at a time and prints out a formatted hex "dump" representation of the files contents 16 characters per display line. A prompt for continuation is issued after displaying 20 lines (320 characters of information). An entry of "X" or "x" followed by the <Enter> key terminates the program execution. Any other entry followed by <Enter> continues the display of the formatted hex and character information. A "." character is used for any non-displayable hex character.'}, {'comments': [{'comment': u'You may want to mention that zip(a, b) could be used where you wanted the *shortest* list to determine how many cross-sections were taken, rather than the longest list as with map.\n', 'title': u'Mention zip for shortest list?'}, {'comment': u'Mentioned...', 'title': u'Good idea'}, {'comment': u"<pre>Nice tip, I wish I had found this site sooner. I had a similar \nproblem with loops, in that I found myself with lots of code that \nlooks like this:\n\nfor a in x:\n\tfor b in y:\n\t\tfor c in z:\n\t\t\t.......\n\nI kept getting tabbed over so far it was getting annoying, so I wrote\na little function, permuteflat(), so I could do this:\n\nfor a, b, c in permuteflat(x,y,z):\n\nwhich seems to work pretty well. I hadn't heard about the 'for a in x \nfor b in y' syntax then, though. But for laughs, here's permuteflat:\n\ndef permuteflat(*args):\n outs = []\n olen = 1\n tlen = len(args)\n for seq in args:\n olen = olen * len(seq)\n for i in range(olen):\n outs.append([None] * tlen)\n plq = olen\n for i in range(len(args)):\n seq = args[i]\n plq = plq / len(seq)\n for j in range(olen):\n si = (j / plq) % len(seq)\n outs[j][i] = seq[si]\n for i in range(olen):\n outs[i] = tuple(outs[i])\n return outs\n \nI probably could have done this much more easily recursively, or any\nother way, really, but I was working on truth tables at the time and\nit seemed like the obvious way to go. Thanks again for the tip!\n</pre>", 'title': u'loop unrolling'}], 'desc': u'Often you need to loop through every item of multiple lists and compare them. This can be done without a using a counter.'}, {'comments': [{'comment': u"This is a great idea; I'd love to use it under the PythonWin gui debugger. Any way to make that happen?\n\nI'm using Python as the Active Script language for IIS/ASP, and would love to throw the errors into the PythonWin debugger.\n\nThanks!", 'title': u'Gui debugger?'}, {'comment': u'instead of:\n \nimport pdb\npdb.pm()\n\nuse:\n\nimport pywin.debugger\npywin.debugger.pm()', 'title': u'using pywin debugger'}, {'comment': u"It is nice to check if the exception is a syntax error\nbecause SyntaxError's can't be debugged.\n<br>\n<pre>\n if hasattr(sys, 'ps1') or not sys.stderr.isatty() or \\\n type == SyntaxError: # there is nothing to be done on syntax errors\n</pre>\n<br>\n<br>\nAlso nice is just assigning the debug exception hook when the program is run is debug mode.\n<br>\n<pre>\nif __debug__:\n sys.excepthook = info\n</pre>\n", 'title': u'Some small improvements'}, {'comment': u'If stdin isn\'t a tty (e.g. a pipe) and this gets called the pdb code will just start printing it\'s prompt continually instead of giving a useful traceback. Changing the test to "not (sys.stderr.isatty() and sys.stdin.isatty())" fixes it.\n\n-Adam', 'title': u'Should check if stdin.isatty also'}, {'comment': u"If the standart output is redirected to a file, then you might not want to start the debugger, because you do not see the debugger's output. Under consideration of the previous comments the condition has to be changed to:\n<br>\nif hasattr(sys, 'ps1') or not sys.stderr.isatty() or not sys.stdin.isatty() or not sys.stdout.isatty() or type==SyntaxError:\n", 'title': u'Addidtional check: sys.stdout.isatty()'}], 'desc': u'When Python runs a script and an uncatched exception is raised, a traceback is printed and the script is terminated.\nPython2.1 has introduced sys.excepthook, which can be used to override the handling of uncaught exceptions. This allows to automatically start the debugger on an unexpected exception, even if python is not running in interactive mode.'}, {'comments': [{'comment': u'This was found at:\nhttp://www.opendocspublishing.com/pyqt/index.lxp?lxpwrap=x3738.htm\n<br>\n<pre>\nKilling or stopping threads from outside the threads is not supported in Python, but you can create a global variable, stop, to circumvent this. In the threads themselves, you then check whether stop is true.\n</pre>\nGreetings, Leo', 'title': u'Stopping Threads from outside'}, {'comment': u'http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473781', 'title': u'Demonstration'}], 'desc': u"The threading module of Python is quite nice to use, but sometimes you'd like to know how long your tasks are already running, so you may react on long running threads. In my example I tried to make creating usual threads more easy also."}, {'comments': [{'comment': u"<pre>\n# This redirects errors to the web browser.\n# Normally stderr goes to the web server errors log, but\n# this will cause the message to go to the user's browser.\nimport sys\nsys.stderr = sys.stdout\n\n\n# Another thing I do is wrap my entire script in a try block:\n# It's also good to wrap your import statements, because sometimes\n# these will cause errors. This is my minimal cgi template.\ntry:\n import traceback, sys, os, cgi\n sys.stderr = sys.stdout\n do_my_cgi_stuff ()\nexcept Exception, e:\n print 'Content-type: text/html\\n'\n print\n print '<html><head><title>'\n print str(e)\n print '</title>'\n print '<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">'\n print '</head><body>'\n print '<h1>TRACEBACK</h1>'\n print '<pre>'\n traceback.print_exc()\n print '</pre>'\n print '</body></html>'\n</pre>", 'title': u'Another way to catch stderr in a CGI'}, {'comment': u'Try this in a program that uses threads ;-)', 'title': u'Multithreading'}, {'comment': u'The cgitb module provides a special exception handler for Python scripts. It displays more than the usual ascii traceback.\n<br><br>\nIt includes the sourcecode of the 3 lines above and below the\nlines and the values of the variables. This means you should only\nuse it for developement and display a different message in production.', 'title': u'Since Python2.2 there is cgitb'}], 'desc': u"For CGI programmers it's important to display tracebacks in the HTML pages to debug their scripts, but the usual functions in the modules cgi and traceback print to sys.sterr. So this small programm returns the traceback as a string an can even add entities for HTML."}, {'comments': [], 'desc': u"You now that there is garbage in your program but you don't know what exactly. In this piece of code additionaly to the normal debugging output of gc the object itself are shown to get an idea where the leak may be."}, {'comments': [{'comment': u'At first I saw this and said, "why concatenate the section and option?" seems like extra string processing right? it makes the write function harder i think. but once you get your dictionary, the values are easy to reference in your code.<br>\n<br>\nhere\'s the write function. i\'m a newbie so it\'s probably not very tight code. <br>\n<pre>\ndef write(self, file, config):\n """\n given a dictionary with key\'s of the form \'section.option: value\'\n write() generates a list of unique section names\n creates sections based that list\n use config.set to add entries to each section\n """\n f= open(file,\'w\')\n cp = ConfigParser.ConfigParser()\n #a little string hacking because our section names are un-normalized\n #this builds a list of all the sections names\n sectionslst = []\n sections = []\n for k in config.keys():\n sectionslst.append(string.split(k,".")[0])\n #get unique entries\n sections = uniquer(sectionslst)\n for sec in sections:\n #make the headers\n cp.add_section(sec)\n #for each item in my dictionary\n #it splits the key in two and uses that for the first and second "set" args\n #then it uses the item.value for the 3rd arg\n # from \'section.option:value\'\n for k in config.items():\n cp.set(string.split(k[0],".")[0],string.split(k[0],".")[1] ,k[1] )\n cp.write(f)\n f.close()\n\ndef uniquer(seq, idfun=None):\n if idfun is None:\n def idfun(x): return x\n seen = {}\n result = []\n for item in seq:\n marker = idfun(item)\n if marker in seen: continue\n seen[marker] = 1\n result.append(item)\n return result\n</pre>', 'title': u'the writer...'}, {'comment': u'This updates the write() function for python > 2.4 and makes it tighter and a little easier to understand.<br><br>\n\nAlso, sets eliminate the need for uniquer().\n\n<pre>\ndef write(self, filename, config):\n """\n given a dictionary with key\'s of the form \'section.option: value\'\n write() generates a list of unique section names\n creates sections based that list\n use config.set to add entries to each section\n """\n cp = ConfigParser.ConfigParser()\n sections = set([k.split(\'.\')[0] for k in config.keys()])\n map(cp.add_section, sections)\n for k,v in config.items():\n s, o = k.split(\'.\')\n cp.set(s, o, v)\n cp.write(open(filename, "w"))\n</pre>', 'title': u'An updated a tighter write()'}], 'desc': u'Many people use Python modules as config files, but this way your program may be manipulated or an syntax error may come into that file. Try the small script here to use the good old INI config files, known from Windows.'}, {'comments': [{'comment': u'A very neat idiom and a good illustration of the power of list comprehensions.', 'title': u'Neat idiom'}, {'comment': u"It might be a neat idiom, but i prefer the following solution, because:<br><br>\n\na) It reads almost as plain English and I think this is always more Pythonic :)<br><br>\nb) It is definitely more efficient. You can break out of the loop early via return after the first matching character is found (containsAny case) and after the first character in 'set' is found that is not contained in 'str' (containsAll case).<br><br>\n<pre>\ndef my_containsAny(str, set):\n\tfor c in set:\n\t\tif c in str: return 1;\n\treturn 0;\n\n\ndef my_containsAll(str, set):\n\tfor c in set:\n\t\tif c not in str: return 0;\n\treturn 1;\n</pre></br></br></br></br></br></br>", 'title': u'Another solution'}], 'desc': u'While the find() and count() string functions can check for string occurences, there is no function to check on the occurence of a set of characters.'}, {'comments': [], 'desc': u'You want to send binary data, such as for an image, to stdout under Windows.'}, {'comments': [], 'desc': u'The following code shows how to "decorate" objects with new functions, in this case any stream with two methods that work similar to the built-in "print" statement.'}, {'comments': [{'comment': u' ', 'title': u'This one works on Win NT'}, {'comment': u'Why do you call\n threading.Thread.join(self, timeout)\ninstead of just calling\n self.join(timeout)\n? \nI use almost exactly the same idiom for trivial treads, but\nI have a generic thread looper that will run a loop on any given function:\n<pre>\n#!/usr/bin/env python\n\nimport time\nimport threading\n\nclass thread_looper (threading.Thread):\n def __init__ (self, interval, function, args=[], kwargs={}):\n threading.Thread.__init__(self)\n self.interval = interval\n self.function = function\n self.args = args\n self.kwargs = kwargs\n self.finished = threading.Event()\n def stop (self):\n self.finished.set()\n self.join()\n def run (self):\n while not self.finished.isSet():\n self.finished.wait(self.interval)\n self.function(*self.args, **self.kwargs)\n\ndef my_function (a, b, c):\n print "meaningless arguments as an example:", a, b, c\n print time.asctime()\n\nprint "Calling my_function() in a thread every 1/10th of second for two seconds."\nt = thread_looper (0.1, my_function, (1,0,-1))\nt.start()\n# The thread, t, runs while we are asleep.\ntime.sleep(2)\nt.stop()\nprint "Done!"\n</pre>', 'title': u'Why do you call threading.Thread.join(self, timeout) instead of just calling self.join(timeout)?'}], 'desc': u'This is a basic idiom I use on almost every thread I write. '}, {'comments': [{'comment': u'The above code works fine on Mac OS X, with one small exception. The value of SIOCGIFFLAGS is 0xc0206911. This would imply to me that this method is not as portable as it seems.', 'title': u'Query whether interface is up on Mac OS X'}], 'desc': u'This code shows how to call the low-level POSIX interface of Python, and handle the return values with the struct module.'}, {'comments': [{'comment': u'The source code contains entities which are interpreted by web browsers, so these do not display correctly on this page.<br><br>\n\nThe text source is fine.</br></br>', 'title': u'Be sure to use the source from the text source link above.'}, {'comment': u"I've just found out that the way commas are escaped in csv is to put the whole data element in quotes, not just the comma. (A much less sensible idea, IMHO). This means that the posted version will not work where one or more commas are present in the csv values.<br><br>\nSorry about that. If anyone wants to post a fix, I'd be grateful. Otherwise, I'll fix and update this very shortly.\n</br></br>", 'title': u'Escaped commas'}, {'comment': u'For the job of parsing CSV you may want to use one of the existing modules available at the Vaults of Parnassus:\n\nhttp://www.vex.net/parnassus/apyllo.py?find=csv\n\nThey will probably already have solved the problem of dealing properly with commas and quotes.', 'title': u'Use existing module to parse CSV?'}, {'comment': u"Yes, you are quite right. Well that's saved me a bit of work!\n\nI'll simplify the script to just accept the pre-parsed data and repost the module shortly. Thanks!", 'title': u"I should have looked there first, shouldn't I?"}, {'comment': u"OK, I've slashed and burned and rejigged, and now the module seems to work fine. Send it a well formed list of lists (sublists all of equal length) and it will spit XML at you.<br><br>\nAs before, use the plain text link, as the script as it appears on this page is broken.<br><br>\nNow I suppose it will be rejected for being too long.<br><br>\nAh well.</br></br></br></br></br></br>", 'title': u'csv to XML? Pah! I convert a list of lists!'}, {'comment': u'OK, I\'ve stripped out the documentation (it\'s on my web site), used the Exception class to create my exceptions, and used the append method throughout, rather than use string manipulation (it\'s quicker).\n\nOne nice additional feature: If you do LL2XML.LL2XML(LL,"table") - where LL is a list of equal length lists - the script returns an HTML table.\n\n(As before, use the text source, or download from my site.)', 'title': u'Tidied it up'}, {'comment': u'See http://www.outwardlynormal.com/python/ll2XML.htm for details.', 'title': u'Added a few minor fixes'}, {'comment': u'What about:<br>\n<pre>\nLL_no_heads = LL[1:]\n</pre>\nIt should save some typing... :)', 'title': u'Just a minor thing'}, {'comment': u"The version of this script in the Cookbook book has this and several other improvements. I will synch the two versions soon. Out of interest, I will be checking the effect on performance of the much more compact code in the published version.<br><br>\nUnfortunately the O'Reilly published version has problems. Two of the entity replacements are broken. It looks like the editor didn't use the source code, but copied and pasted from a browser.<br><br>\n\nI'm trying to get this fixed in their online version of the module. Too late for the printed version, I expect (I've not seen it yet).<br><br>\nAh well, good to be in there, anyway.", 'title': u'Yes. Quite right.'}], 'desc': u'This module takes a list of equal length lists and converts it into XML.\n\nIf the first sublist is a list of headings, these are used to form the element names of the rest of the data, or these can be defined in the function call. Root and "row" elements can be named if required.'}, {'comments': [], 'desc': u'These short functions convert identifier names between the most common naming conventions: CapitalizedWords, mixedCase and under_scores.\n'}, {'comments': [{'comment': u'I think that all of the strings in this example that contain backslashes should be raw strings (such as r"This is an example of a \\ backslash")', 'title': u'Backslashes'}], 'desc': u'The code below shows how to read from/write to the Windows Registry. In this example all the tasks are listed which are executed at logon. A new task (opening the explorer) is added to ths logon.\n'}, {'comments': [{'comment': u' ', 'title': u"os.chdir('/') is not needed"}, {'comment': u"If you ever wanted to delete the directory you started a demon in that does NOT have that code, you'd think otherwise.", 'title': u'Sure a "cd /" is needed'}, {'comment': u'Check out the UNIX Programming FAQ for the full skinny on\nforking a daemon:<br>\n<br>\n http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16<br>\n<br>\nThis cookbook entry\'s a pretty good implementation of the above, except that one of the things the FAQ entry advises is closing the standard file descriptors and redirecting them elsewhere (eg /dev/null, or log files, etc.). I\'ve been bitten in the ass by forgetting to do this, so it\'s worth remembering. :-)<br>\n<br>\nIn the simplest form:<br>\n\n<pre>\n # Redirect standard file descriptors\n sys.stdin = open(\'/dev/null\', \'r\')\n sys.stdout = open(\'/dev/null\', \'w\')\n sys.stderr = open(\'/dev/null\', \'w\')</pre>\n\nThe FAQ entry also does things in a slightly different order - in particular it doesn\'t set the umask, or chdir(\'/\') until after the second fork - but I don\'t know if that\'s important.<br>\n<br>\nIt also gives further justification for calling os.chdir(\'/\'), namely "what if the sysadmin wants to umount the filesystem the daemon was run from?". Good stuff...', 'title': u"It's also worth redirecting the standard file descriptors"}, {'comment': u"Just reassigning to the sys streams is not 100% effective if you are importing modules that write to stdin and stdout from C code. Perhaps the modules shouldn't do that, but this code will make sure that all stdin and stdout will go where you expect it to.\n<pre>\nimport os, sys\n\nout_log = file('/out/log/file/name', 'a+')\nerr_log = file('/err/log/file/name', 'a+', 0)\ndev_null = file('/dev/null', 'r')\n\nos.dup2(out_log.fileno(), sys.stdout.fileno())\nos.dup2(err_log.fileno(), sys.stderr.fileno())\nos.dup2(dev_null.fileno(), sys.stin.fileno())\n</pre>", 'title': u'More reliable i/o stream redirection'}, {'comment': u'Of course, that should be:\n<pre>\n... os.stdin ...\n</pre>\nnot\n<pre>\n... os.stin ...\n</pre>', 'title': u'oops...'}, {'comment': u'So taking everyone\'s suggestions I got this.\nJust save this into a file called "daemonize.py".\nIf you run it as a script it will daemonize an example \nmain() function. It should be self-documenting...<br>\n<br>\nDid I miss anything?<br>\n<br>\nNoah<br><br>\n<pre>\n#!/usr/bin/env python\nimport sys, os\n\n\'\'\'This module is used to fork the current process into a daemon.\n Almost none of this is necessary (or advisable) if your daemon \n is being started by inetd. In that case, stdin, stdout and stderr are \n all set up for you to refer to the network connection, and the fork()s \n and session manipulation should not be done (to avoid confusing inetd). \n Only the chdir() and umask() steps remain as useful.\n References:\n UNIX Programming FAQ\n 1.7 How do I get my program to act like a daemon?\n http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16\n \n Advanced Programming in the Unix Environment\n W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.\n \'\'\'\n\ndef daemonize (stdin=\'/dev/null\', stdout=\'/dev/null\', stderr=\'/dev/null\'):\n \'\'\'This forks the current process into a daemon.\n The stdin, stdout, and stderr arguments are file names that\n will be opened and be used to replace the standard file descriptors\n in sys.stdin, sys.stdout, and sys.stderr.\n These arguments are optional and default to /dev/null.\n Note that stderr is opened unbuffered, so\n if it shares a file with stdout then interleaved output\n may not appear in the order that you expect.\n \'\'\'\n # Do first fork.\n try: \n pid = os.fork() \n if pid > 0:\n sys.exit(0) # Exit first parent.\n except OSError, e: \n sys.stderr.write ("fork #1 failed: (%d) %s\\n" % (e.errno, e.strerror) )\n sys.exit(1)\n \n # Decouple from parent environment.\n os.chdir("/") \n os.umask(0) \n os.setsid() \n \n # Do second fork.\n try: \n pid = os.fork() \n if pid > 0:\n sys.exit(0) # Exit second parent.\n except OSError, e: \n sys.stderr.write ("fork #2 failed: (%d) %s\\n" % (e.errno, e.strerror) )\n sys.exit(1)\n \n # Now I am a daemon!\n \n # Redirect standard file descriptors.\n si = file(stdin, \'r\')\n so = file(stdout, \'a+\')\n se = file(stderr, \'a+\', 0)\n os.dup2(si.fileno(), sys.stdin.fileno())\n os.dup2(so.fileno(), sys.stdout.fileno())\n os.dup2(se.fileno(), sys.stderr.fileno())\n\ndef main ():\n \'\'\'This is an example main function run by the daemon.\n This prints a count and timestamp once per second.\n \'\'\'\n import time\n sys.stdout.write (\'Daemon started with pid %d\\n\' % os.getpid() )\n sys.stdout.write (\'Daemon stdout output\\n\')\n sys.stderr.write (\'Daemon stderr output\\n\')\n c = 0\n while 1:\n sys.stdout.write (\'%d: %s\\n\' % (c, time.ctime(time.time())) )\n sys.stdout.flush()\n c = c + 1\n time.sleep(1)\n \nif __name__ == "__main__":\n daemonize(\'/dev/null\',\'/tmp/daemon.log\',\'/tmp/daemon.log\')\n main()\n\n</pre>\n', 'title': u'Wrapping it all together...'}, {'comment': u'I took a look at the code, and I remembered that I\'ve written various\nPerl daemons some time ago.\nSo, I took their source and translated it into python code.\nHere\'s what works for me\n\n#!/usr/bin/python\nimport sys\nimport os\ntry:\n pid = os.fork()\nexcept:\n print "Could not fork"\n sys.exit(1)\nif pid:\n # Let parent die !\n sys.exit(0)\nelse:\n try:\n # Create new session\n os.setsid()\n except:\n print "Could not create new session"\n sys.exit(1)\n while 1:\n # Your daemon code here\n\n\nThat\'s all, so I\'m asking myself why you try these double-fork stuff ?', 'title': u'Things can be done much easier'}, {'comment': u'<pre>\n\'\'\'\n This module is used to fork the current process into a daemon.\n Almost none of this is necessary (or advisable) if your daemon \n is being started by inetd. In that case, stdin, stdout and stderr are \n all set up for you to refer to the network connection, and the fork()s \n and session manipulation should not be done (to avoid confusing inetd). \n Only the chdir() and umask() steps remain as useful.\n References:\n UNIX Programming FAQ\n 1.7 How do I get my program to act like a daemon?\n http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16\n Advanced Programming in the Unix Environment\n W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.\n\n History:\n 2001/07/10 by J\xfcrgen Hermann\n 2002/08/28 by Noah Spurrier\n 2003/02/24 by Clark Evans\n \n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012\n\'\'\'\nimport sys, os, time\nfrom signal import SIGTERM\n\ndef deamonize(stdout=\'/dev/null\', stderr=None, stdin=\'/dev/null\',\n pidfile=None, startmsg = \'started with pid %s\' ):\n \'\'\'\n This forks the current process into a daemon.\n The stdin, stdout, and stderr arguments are file names that\n will be opened and be used to replace the standard file descriptors\n in sys.stdin, sys.stdout, and sys.stderr.\n These arguments are optional and default to /dev/null.\n Note that stderr is opened unbuffered, so\n if it shares a file with stdout then interleaved output\n may not appear in the order that you expect.\n \'\'\'\n # Do first fork.\n try: \n pid = os.fork() \n if pid > 0: sys.exit(0) # Exit first parent.\n except OSError, e: \n sys.stderr.write("fork #1 failed: (%d) %s\\n" % (e.errno, e.strerror))\n sys.exit(1)\n \n # Decouple from parent environment.\n os.chdir("/") \n os.umask(0) \n os.setsid() \n \n # Do second fork.\n try: \n pid = os.fork() \n if pid > 0: sys.exit(0) # Exit second parent.\n except OSError, e: \n sys.stderr.write("fork #2 failed: (%d) %s\\n" % (e.errno, e.strerror))\n sys.exit(1)\n \n # Open file descriptors and print start message\n if not stderr: stderr = stdout\n si = file(stdin, \'r\')\n so = file(stdout, \'a+\')\n se = file(stderr, \'a+\', 0)\n pid = str(os.getpid())\n sys.stderr.write("\\n%s\\n" % startmsg % pid)\n sys.stderr.flush()\n if pidfile: file(pidfile,\'w+\').write("%s\\n" % pid)\n \n # Redirect standard file descriptors.\n os.dup2(si.fileno(), sys.stdin.fileno())\n os.dup2(so.fileno(), sys.stdout.fileno())\n os.dup2(se.fileno(), sys.stderr.fileno())\n\ndef startstop(stdout=\'/dev/null\', stderr=None, stdin=\'/dev/null\',\n pidfile=\'pid.txt\', startmsg = \'started with pid %s\' ):\n if len(sys.argv) > 1:\n action = sys.argv[1]\n try:\n pf = file(pidfile,\'r\')\n pid = int(pf.read().strip())\n pf.close()\n except IOError:\n pid = None\n if \'stop\' == action or \'restart\' == action:\n if not pid:\n mess = "Could not stop, pid file \'%s\' missing.\\n"\n sys.stderr.write(mess % pidfile)\n sys.exit(1)\n try:\n while 1:\n os.kill(pid,SIGTERM)\n time.sleep(1)\n except OSError, err:\n err = str(err)\n if err.find("No such process") > 0:\n os.remove(pidfile)\n if \'stop\' == action:\n sys.exit(0)\n action = \'start\'\n pid = None\n else:\n print str(err)\n sys.exit(1)\n if \'start\' == action:\n if pid:\n mess = "Start aborded since pid file \'%s\' exists.\\n"\n sys.stderr.write(mess % pidfile)\n sys.exit(1)\n deamonize(stdout,stderr,stdin,', 'title': u'Adding start/stop/restart behavior'}, {'comment': u"I'm sure the references (Stevens, FAQ) explain this. The reason is we don't like zombies.", 'title': u'Why double-fork?'}, {'comment': u'The first fork accomplishes two things - allow the shell to return, and allow you to do a setsid().\n<br><br>\nThe setsid() removes yourself from your controlling terminal. You see, before, you were still listed as a job of your previous process, and therefore the user might accidentally send you a signal. setsid() gives you a new session, and removes the existing controlling terminal.\n<br><br>\nThe problem is, you are now a session leader. As a session leader, if you open a file descriptor that is a terminal, it will become your controlling terminal (oops!). Therefore, the second fork makes you NOT be a session leader. Only session leaders can acquire a controlling terminal, so you can open up any file you wish without worrying that it will make you a controlling terminal.\n<br><br>\nSo - first fork - allow shell to return, and permit you to call setsid()\n\n<br><br>\n\nSecond fork - prevent you from accidentally reacquiring a controlling terminal.', 'title': u'The second fork _is_ necessary'}, {'comment': u'<pre>#!/usr/bin/python<br><br><br># \tDieses Modul wird verwendet, um sein aktuelles Skript in eine Daemon-App. zu versetzen.<br># \tSollte ihr Daemon ueber inetd laufen (s. inet daemon Linux) so sind die meisten, hier<br>#\tangefuehrten Routinen nicht notwendig. Ist dies der Fall, dass std -in,-out u. -err ueber<br>#\tdas "Netzwerk" arbeiten, so sollten forks-commands u. Session Manipulation vermieden werden.<br># \tNur chdir() und unmask() erweisen sich in diesem Fall als brauchbar. <br># <br># \tQuellennachweise:<br># \t UNIX Programming FAQ<br># \t\t1.7 How do I get my program to act like a daemon?<br># \thttp://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16<br># \tAdvanced Programming in the Unix Environment<br># \t\tW. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.<br>#\t\t\t(http://www.yendor.com/programming/unix/apue/ch13.html)<br>#<br>#\tGeschichte:<br># \t\t2001/07/10 by J|rgen Hermann<br># \t\t2002/08/28 by Noah Spurrier<br># \t\t2003/02/24 by Clark Evans<br>#\t\t2004/06/16 by Peter Landl / IFO.net<br># <br># \thttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012<br><br>import sys, os, time<br>from signal import SIGTERM<br><br>def deamonize(stdout = \'/dev/null\', stderr = None, stdin = \'/dev/null\', pidfile = None, startmsg = \'started with pid %s\' ):<br> \'\'\'\t<br>\tDiese Routine gabelt ("forks", kloned) den aktuellen Prozess in einen Daemon.<br>\tDie Parameter stdin, stdout und stderr sind Dateinamen, welche die<br>\tStandard- Err-/Ein-/Aus- gabe "ersetzen". Diese Argumente sind optional<br>\tund zeigen standardmaessig ins Nirvana (/dev/null).<br>\tZu beachten ist, dass stderr ungepuffert geoeffnet ist und so, wenn es<br>\tdoppelt offen scheint, nicht die Daten enthaellt, die sie erwarten.<br> [Letzter Satz im Original: Note that stderr is opened unbuffered, so<br> if it shares a file with stdout then interleaved output<br> may not appear in the order that you expect.]<br> \'\'\'<br> # Erstes fork (erster Klon) => fork erstellt aus dem gesamten Prozess einen child-Prozess<br> try: <br> pid = os.fork() <br> if (pid > 0):<br>\t sys.exit(0) # Parent-Prozess schliessen<br> except OSError, e: <br> sys.stderr.write("fork #1 failed: (%d) %s\\n" % (e.errno, e.strerror))<br> sys.exit(1)<br> <br> # Parent "Table/Umgebung" verlassen<br> os.chdir("/") <br> os.umask(0) <br> os.setsid() <br> <br> # Zweites fork<br> try: <br> pid = os.fork() <br> if (pid > 0):<br>\t sys.exit(0) # Zweiten Parent-Prozess schliessen<br> except OSError, e: <br> sys.stderr.write("fork #2 failed: (%d) %s\\n" % (e.errno, e.strerror))<br> sys.exit(1)<br> <br> # Standard Ein-/Ausgaben oeffnen und Standard-message ausgeben<br> if (not stderr):\t# Wurde stderr nicht uebergeben => stdout-Pfad nehmen <br>\tstderr = stdout<br><br> si = file(stdin, \'r\')<br> so = file(stdout, \'a+\')<br> se = file(stderr, \'a+\', 0)<br> pid = str(os.getpid())<br> sys.stderr.write("\\n%s\\n" % startmsg % pid)<br> sys.stderr.flush()<br> if pidfile: file(pidfile,\'w+\').write("%s\\n" % pid)<br> <br> # Standard Ein-/Ausgaben auf die Dateien umleiten<br> os.dup2(si.fileno(), sys.stdin.fileno())<br> os.dup2(so.fileno(), sys.stdout.fileno())<br> os.dup2(se.fileno(), sys.stderr.fileno())<br><br># start/stop/restart Routine fuer den Daemon<br>def startstop(stdout=\'/dev/null\', stderr=None, stdin=\'/dev/null\', pidfile=\'pid.txt\', startmsg = \'gestartet mit pid %s\' ):<br> <br> if len(sys.argv) > 1:<br> action = sys.argv[1]<br> try:<br> pf = file(pidfile,\'r\')<br> pid = int(pf.read().strip())\t# Von geoeffnetem pid-File "pid" auslesen um Prozess zu kontrollieren (ueber kill..)<br> pf.close()<br> except IOError:<br> pid = None<br>\t <br> if ((action == \'stop\') or (action == \'restart\')):<br> if (not pid):<br> mess = "Konnte Prozess nicht stoppen, pid-Datei \'%s\' f', 'title': u'And here is the translation in German'}, {'comment': u'This is very useful code, but there is one detail that is wrong. If startstop() gets action=\'restart\' and pid has not been set, the daemon is not started. Instead, the code reports "Could not stop, pid file \'%s\' missing." and calls sys.exit(1).<br>\n<br>\nThe code in the next few lines handles this correctly: if the os.kill() fails then the exception handler sets action = \'start\' and falls through to allow the daemon to be started.<br>\n<br>\nSo, the code should read:<br>\n<pre>\n if \'stop\' == action or \'restart\' == action:\n if not pid:\n mess = "Could not stop, pid file \'%s\' missing.\\n"\n sys.stderr.write(mess % pidfile)\n if \'stop\' == action:\n sys.exit(1)\n action = \'start\'\n pid = None\n else:\n try:\n while 1:\n os.kill(pid,SIGTERM)\n time.sleep(1)\n except OSError, err:\n err = str(err)\n if err.find("No such process") > 0:\n os.remove(pidfile)\n if \'stop\' == action:\n sys.exit(0)\n action = \'start\'\n pid = None\n else:\n print str(err)\n sys.exit(1)\n</pre>', 'title': u'Restart should handle not finding the pid'}, {'comment': u"Before dup'ing a new file into the underlying stdout/stderr file descriptors, you should flush the stdio buffers. Otherwise, it is entirely possible that pending output could get sent to the wrong file.\n<br><br>\nThus:\n<pre>sys.stdout.flush()\nsys.stderr.flush()\nos.dup2(out_log.fileno(), sys.stdout.fileno())\nos.dup2(err_log.fileno(), sys.stderr.fileno())\nos.dup2(dev_null.fileno(), sys.stdin.fileno())\n</pre>\n", 'title': u'even safer to flush first'}, {'comment': u"Using Python 2.3.4 on linux, when I called sys.stdin.close() before calling daemonize(), the line:\n\n<pre>os.dup2(si.fileno(), sys.stdin.fileno())</pre>\n\nthrows an exception:\n<pre>ValueError: I/O operation on closed file</pre>\n\nTry it out. I came up with the following expedient hack which should be called before calling os.dup2 (and if you are flushing the output of sys.stdout, etc., before that too.) If you have a better way, please let me know!\n\n<pre>\nif sys.stdin.closed: sys.stdin = open('/dev/null', 'r')\nif sys.stdout.closed: sys.stdout = open('/dev/null', 'a+')\nif sys.stderr.closed: sys.stderr = open('/dev/null', 'a+')\n</pre>\n\nEnjoy!\n<br>-Todd DeLuca\n<br>P.S. Thanks everyone for this very useful piece of code.", 'title': u'os.dup2 throws exception when sys.stdin closed'}, {'comment': u'Made startstop more general by including the action parameter. That enables you to call it from everywhere. Also added status parameter, that performs a very simple check if process is running.\n<br>\n<pre>\ndef startstop(stdout=\'/dev/null\', stderr=None, stdin=\'/dev/null\',\n pidfile=\'pid.txt\', startmsg = \'started with pid %s\', action=\'start\' ):\n if action:\n try:\n pf = file(pidfile,\'r\')\n pid = int(pf.read().strip())\n pf.close()\n except IOError:\n pid = None\n \n if \'stop\' == action or \'restart\' == action:\n if not pid:\n mess = "Could not stop, pid file \'%s\' missing.\\n"\n sys.stderr.write(mess % pidfile)\n if \'stop\' == action:\n sys.exit(1)\n action = \'start\'\n pid = None\n else:\n try:\n while 1:\n os.kill(pid,SIGTERM)\n time.sleep(1)\n except OSError, err:\n err = str(err)\n if err.find("No such process") > 0:\n os.remove(pidfile)\n if \'stop\' == action:\n sys.exit(0)\n action = \'start\'\n pid = None\n else:\n print str(err)\n sys.exit(1)\n \n if \'start\' == action:\n if pid:\n mess = "Start aborded since pid file \'%s\' exists.\\n"\n sys.stderr.write(mess % pidfile)\n sys.exit(1)\n\n deamonize(stdout,stderr,stdin,pidfile,startmsg)\n return\n\n if \'status\' == action:\n if not pid:\n sys.stderr.write(\'Status: Stopped\\n\')\n\n else: sys.stderr.write(\'Status: Running\\n\')\n sys.exit(0)\n</pre>', 'title': u'More general startstop method'}, {'comment': u'<pre>\nBTW, There is now a second edition of this great boot.\nISBN: 0-201-43307-9\nhttp://www.awprofessional.com/title/0201433079\n</pre>', 'title': u'Advanced Programming in the UNIX(R) Environment (2nd Edition)'}, {'comment': u'<pre>\nThe Linux man page of dup2 says:\n\n"""\nint dup2(int oldfd, int newfd)\n...\nIf newfd was open, any errors that would have been reported at close()time, are lost.\nA careful programmer will not use dup2 without closing newfd first.\n"""\n\nYou can add this before dup2:\n os.close(sys.stdin.fileno())\n os.close(sys.stdout.fileno())\n os.close(sys.stderr.fileno())\n\nI don\'t know if os.close() flushes python interal buffers.\nDoing sys.stdout.flush() and sys.stderr.flush() before the close\ndoes not hurt.\n\nPS: sys.stdin.close() does not work\n</pre>', 'title': u'close newfd before dup2'}], 'desc': u'Forking a daemon on Unix requires a certain sequence of system calls. Since Python exposes a full POSIX interface, this can be done in Python, too.'}, {'comments': [{'comment': u"Hi,\n\nThe form:\n<pre>\n g=[blah(i) for i in foo]\n</pre>\nis pretty tricky (I hadn't seen it before), but it's faster (and easier for me to read it) as:\n<pre>\n g=map(blah, foo)\n</pre>\nAt least, it's faster on my timing tests.\n\n", 'title': u'faster to map'}, {'comment': u'That comment was misplaced. I came back to the wrong link after signing in. Please delete it.', 'title': u'Whoops'}, {'comment': u'A somewhat more flexible version of Eval is:\n\n<pre>\nclass Eval:\n def __init__(self, globals=None, locals=None):\n self.globals = globals or {}\n self.locals = locals or None\n \n def __getitem__(self, key):\n if self.locals is None:\n self.locals = sys._getframe(1).f_locals\n key = key % self\n return eval(key, self.globals, self.locals)\n</pre>\n\n<br>\n\nIt handles recursive formats such as "%(text.%(method)s)s" and\nworks with local variables. You could get fancier and\nparameterize the number of frames to look up for locals. In \npractice, I find that\'s not generally necessary.\n\n<br>\n<br>\n\nMy Eval is based on/stolen from something that Steve Majewski\nposted to c.l.py.\n\n<br>\n<br>\n\nSkip Montanaro (skip@pobox.com)\n', 'title': u'More flexible string eval()'}], 'desc': u"In Python, String and Unicode objects have one special operator: the % operator.\nWith that operator, strings can be formatted with format codes.\nFormatting is given syntax format % values, where format is a string with format codes that are replaced with values.\nWhen value is any kind of mapping, formats must include parenthesis that contain a key.\nAn item is fetched from directory with key or __getitem__ is overloaded with key.\nIn this example, Eval's __getitem__ returns the result of eval(key)."}, {'comments': [{'comment': u"Hi, <br><br>The form: \n<pre>\n g=[blah(i) for i in foo]\n</pre>\nis pretty tricky (I hadn't seen it before), but it's faster (and easier for me to read it) as: \n<pre>\n g=map(blah, foo)\n</pre>\nAt least, it's faster on my timing tests. \n</br></br>", 'title': u'faster to map'}, {'comment': u"Thanks for the comment. Interesting... Using map I guess it would be something like:\n\n<pre>\ndef indentLine(line, spaces=8):\n return (' ' * spaces) + string.lstrip(line)\n\ndef reindentBlock(s, numSpaces):\n s = string.split(s, '\\n')\n s = map(lambda a, ns=numSpaces: indentLine(a, ns), s)\n s = string.join(s, '\\n')\n return s\n</pre>\n\nWhen I tested this particular example, I found that it ran slightly slower than the version that uses a list comprehension, but they were very close.\n\n<br><br>\nTom Good\n</br></br>", 'title': u'with map'}, {'comment': u"I found that teh recipe doesnt keep newlines so my modified\nfunction is like this:\n\n<pre>\n leadingSpace = self.indents * ' '\n lines = outstr.splitlines(True)\n for i in range(len(lines)):\n if lines[i].strip(): # Keep empty lines\n lines[i] = leadingSpace+lines[i].lstrip()\n\nI found that teh recipe doesnt keep newlines so my modified\nfunction is like this:\n\n<pre>\n leadingSpace = self.indents * ' '\n lines = outstr.splitlines(True)\n for i in range(len(lines)):\n if lines[i].strip(): # Keep empty lines\n lines[i] = leadingSpace+lines[i].lstrip()\n\n</pre></pre>", 'title': u' '}], 'desc': u' '}, {'comments': [{'comment': u"just for the record,\n<pre>\nif [ x for x in [ whatever() ] if cond(x) ] : process(x)\n</pre>\nis a close Python transliteration of C's:\n<pre>\nif( cond(x=whatever()) ) process(x);\n</pre>\n\nPretty obscure, though.\n", 'title': u'list comprehension abuse is an alternative'}, {'comment': u'Similar results can be obtained using function attributes instead of a class, since functions are first class objects in Python. One advantage being that it requires one less explict function call in the loop. For example:\n\n<pre>\ndef TestResult(value):\n TestResult.theValue = value\n return value\n\nwhile TestResult(file.readline()):\n process(TestResult.theValue)\n</pre>\nOn the other hand, the class approach has the advantage that it is possible to use it in a way that would handle nested loops properly.', 'title': u'Alternative: Function Attributes'}], 'desc': u'When transliterating C, Perl &c to Python, one often misses idioms such as "if((x=foo())" or "while((x=foo())" -- but, it\'s easy to get them back, with one small utility class!'}, {'comments': [], 'desc': u"You want to determine the name of the currently running function, e.g. to create error messages that don't need to be changed when copied to other functions. Function _getframe of module sys does this and much more."}, {'comments': [{'comment': u'A simple generator version (requires "from __future__ import generators" in 2.2):\n\n<pre>\ndef paragraphs(file, separator=None):\n if not callable(separator):\n def separator(line): return line == \'\\n\'\n paragraph = []\n for line in file:\n if separator(line):\n if paragraph:\n yield \'\'.join(paragraph)\n paragraph = []\n else:\n paragraph.append(line)\n yield \'\'.join(paragraph)\n</pre>', 'title': u'Using iterators and generators'}, {'comment': u"If one doesn't want an empty paragraph at the end when the file has one or more trailing separators\n(and one usually wouldn't want that), the last line should probably read:\n\n<pre>\n if paragraph: yield ''.join(paragraph)\n</pre>", 'title': u'Addendum'}, {'comment': u'If someone misunderstands call sequence and passes in a string such as \'++\\n\', you silently replace it with wrong thing.<pre>\n if not callable(separator):\n def separator(line): return line == \'\\n\'\n self.separator = separator</pre>\nBetter to generate right thing or raise TypeError by inserting<pre>\n if separator != None: raise TypeError, "separator must be callable"\n </pre>', 'title': u'Wrong Separator'}, {'comment': u"It's definitely better to diagnose an unusable argument than to silently ignore it:-).\n", 'title': u'good point! fixed in this new version, thanks for pointing it out'}], 'desc': u"Text files are most often read by-line, with excellent direct Python support. Sometimes we need to use other units, such as the paragraph -- a sequence of non-empty lines separated by empty lines. Python doesn't support that directly, but, as usual, it's not too hard to add such functionality."}, {'comments': [{'comment': u'I was going to use Alex\'s implementation, but since xreadlines has been deprecated, I wrote a generator version instead:\n<pre>\ndef loglines(rawdata):\n lines = []\n for i in rawdata.splitlines():\n lines.append(i)\n if not i.endswith("\\\\"):\n yield "".join(lines)\n lines = []\n if len(lines) > 0: yield "".join(lines)\n</pre>\nThis has the downside of needing the whole file (or having to chunk it manually) at once, but has the nice upside of using splitlines to handle DOS/Unix/Max line ending conventions seamlessly. \n<pre>\n# print out the merged lines of \'test.txt\':\nfor i in loglines(open(\'test.txt\').read()):\n print i\n</pre>', 'title': u'a generator version'}], 'desc': u'You have a file with long lines split over two or more lines, with backslashes to indicate that a continuation line follows. You want to rejoin those split lines.'}, {'comments': [], 'desc': u'A utility function somewhat similar to what parsing resolv.conf for nameserver entries would do on Unix. '}, {'comments': [], 'desc': u"Many programs only show the long service description such as 'Windows Time', but this recipe finds you the actual service name."}, {'comments': [{'comment': u"There's no need to go quite so far to establish the domain controller. The following will do the job quite nicely, altho' I don't know how it will behave in a domainless setup.\n\n<pre>\nwin32net.NetUserGetInfo (win32net.NetGetAnyDCName (), win32api.GetUserName (), 1)\n<pre></pre></pre>", 'title': u'Alternatively, and a lot more concisely...'}, {'comment': u"Well, I do know. It won't work. :-} My example does the proper fallback.", 'title': u">altho' I don't know how it will behave in a domainless setup."}], 'desc': u'Calling win32net.NetUserGetInfo(None, win32api.GetUserName(), 1) works for users logged in to the local machine, only, but fails for domain users. The snippet below demonstrates how to query the domain controller if there is one. \n'}, {'comments': [{'comment': u'You\'re missing a couple of dictionary methods:\n\n<pre>\n def __len__(self):\n """Returns the number of (key, value) pairs."""\n return len(self._dict)\n \n def clear(self):\n """Clears the dictionary."""\n self._dict.clear()\n</pre>\n', 'title': u'Missing methods'}, {'comment': u'For testing \'key in dict\'\n\n<pre>\n def __contains__(self, key):\n """Case insensitive test where key is in dict"""\n k = key.lower()\n return k in self._dict\n</pre>', 'title': u'One more'}, {'comment': u'This class doesn\'t respond to iteration as a normal dictionary. Here is an example of it failing:\n<br>\n===firstly with a normal dictionary\n<br>\n>>> x = {}<br>\n>>> x[\'fred\'] = 76<br>\n>>> x[\'joe\'] = 98<br>\n>>> for key in x:<br>\n... print key<br>\n...<br>\njoe<br>\nfred<br>\n<br>\n=============and then with the one proposed here<br>\n<br>\n>>> x = KeyInsensitiveDict()<br>\n>>> x[\'fred\'] = 76<br>\n>>> x[\'joe\'] = 98<br>\n>>> for key in x:<br>\n... print key<br>\nTraceback (most recent call last):<br>\n File "", line 1, in ?<br>\n File "CIMCommon.py", line 231, in __getitem__<br>\n k = key.lower()<br>\nAttributeError: \'int\' object has no attribute \'lower\'<br>\n<br>\nThis would seem to be an error with the __getitem__ function.', 'title': u"Class Doesn't Respond as a Dictionary"}, {'comment': u"The problem described above of failing with the statement\n<pre>\nfor key in dictionary:\n</pre>\ncan be solved by adding simple __iter__() and next() methods. However, there is still an issue:\n<pre>\n>>> x = KeyInsensitiveDict()\n>>> x['fred'] = 47\n>>> print 'fred' in x\nTrue\n>>> print 'FRED' in x\nFalse\n</pre>", 'title': u'Iterator Improvement'}, {'comment': u'In order to satisfy the requirements of supporting\n<pre>\nfor key in dictionary:\n</pre>\nand\n<pre>\nif \'fred\' in dictionary:\n</pre>\nI have augmented the code of this algorithm as follows. This seems to satisfy at least all of the tests which I have thrown at it:\n<pre>\n# ********************************************\n# class caselessDict\n# purpose emulate a normal Python dictionary\n# but with keys which can accept the\n# lower() method (typically strings).\n# Accesses to the dictionary are\n# case-insensitive but keys returned\n# from the dictionary are always in\n# the original case.\n# ********************************************\n\nclass caselessDict:\n def __init__(self,inDict=None):\n """Constructor: takes conventional dictionary\n as input (or nothing)"""\n self.dict = {}\n if inDict != None:\n for key in inDict:\n k = key.lower() \n self.dict[k] = (key, inDict[key])\n self.keyList = self.dict.keys()\n return\n\n def __iter__(self):\n self.iterPosition = 0\n return(self)\n\n def next(self):\n if self.iterPosition >= len(self.keyList):\n raise StopIteration\n x = self.dict[self.keyList[self.iterPosition]][0]\n self.iterPosition += 1\n return x\n\n def __getitem__(self, key):\n k = key.lower()\n return self.dict[k][1]\n\n def __setitem__(self, key, value):\n k = key.lower()\n self.dict[k] = (key, value)\n self.keyList = self.dict.keys()\n\n def has_key(self, key):\n k = key.lower()\n return k in self.keyList\n\n def __len__(self):\n return len(self.dict)\n\n def keys(self):\n return [v[0] for v in self.dict.values()]\n\n def values(self):\n return [v[1] for v in self.dict.values()]\n\n def items(self):\n return self.dict.values()\n\n def __contains__(self, item):\n return self.dict.has_key(item.lower())\n \n def __repr__(self):\n items = ", ".join([("%r: %r" % (k,v)) for k,v in self.items()])\n return "{%s}" % items\n\n def __str__(self):\n return repr(self)\n\n# *****************************************\n# Test Code\n# *****************************************\n\nif __name__ == \'__main__\':\n foundError = False\n\n # firstly create an empty caselessDict\n\n x = caselessDict()\n x[\'frEd\'] = 76\n x[\'jOe\'] = 92\n x[\'bERT\'] = 54\n x[\'Bert\'] = 53\n if x[\'bert\'] != 53:\n print "Error 1"\n foundError = True\n shouldBe = [ \'Bert\', \'jOe\', \'frEd\' ]\n for key in x:\n if not key in shouldBe:\n print "Error 2"\n foundError = True\n else:\n shouldBe.remove(key)\n if len(shouldBe) != 0:\n print "Error 2a"\n foundError = True\n if not \'frEd\' in x:\n print "Error 3"\n foundError = True\n if not \'fRed\' in x:\n print "Error 4"\n foundError = True\n if \'fReda\' in x:\n print "Error 5"\n foundError = True\n y = x.keys()\n if len(y) != 3:\n print "Error 6"\n foundError = True\n for yy in y:\n if (yy != \'Bert\') and (yy != \'jOe\') and (yy != \'frEd\'):\n print "Error 7"\n foundError = True\n if x[\'FRED\'] != 76:\n print "Error 8"\n foundError = True\n if x[\'joe\'] != 92:\n print "Error 9"\n foundError = True\n\n # then create a caselessDict from an existing dictionary\n\n y = { \'frEd\' : 76, \'jOe\' : 92, \'Bert\' : 53 }\n x = caselessDict(y)\n if x[\'bert\'] != 53:\n print "Error 10"\n foundError = True\n shouldBe = [ \'Bert\', \'jOe\', \'frEd\' ]\n for key in x:\n if not key in shouldBe:\n print "Error 11"\n foundError = True\n else:\n shouldBe.remove(key)\n if len(shouldBe) != 0:\n print "Error 11a"\n foundError = True\n if not \'frEd\' in x:\n print "Error ', 'title': u'Reworked Version of Algorithm'}, {'comment': u'To round off things:\n<pre>\n def get(self, key, alt):\n if self.has_key(key):\n return self.__getitem__(key)\n return alt\n</pre>', 'title': u'Get method missing'}, {'comment': u"This relies on the fact that in 2.4 you can derive from 'dict' like any other class. Also, note that this /changes/ the key, to your canonical (here, lowercase) form; it doesn't leave it in the dictionary as given while continuing to match it case-insensitively as the previous examples do:\n\n<pre>\nclass CaselessDict(dict):\n def __init__(self, other=None):\n if other:\n # Doesn't do keyword args\n if isinstance(other, dict):\n for k,v in other.items():\n dict.__setitem__(self, k.lower(), v)\n else:\n for k,v in other:\n dict.__setitem__(self, k.lower(), v)\n\n def __getitem__(self, key):\n return dict.__getitem__(self, key.lower())\n\n def __setitem__(self, key, value):\n dict.__setitem__(self, key.lower(), value)\n\n def __contains__(self, key):\n return dict.__contains__(self, key.lower())\n\n def has_key(self, key):\n return dict.has_key(self, key.lower())\n\n def get(self, key, def_val=None):\n return dict.get(self, key.lower(), def_val)\n\n def setdefault(self, key, def_val=None):\n return dict.setdefault(self, key.lower(), def_val)\n\n def update(self, other):\n for k,v in other.items():\n dict.__setitem__(self, k.lower(), v)\n\n def fromkeys(self, iterable, value=None):\n d = CaselessDict()\n for k in iterable:\n dict.__setitem__(d, k.lower(), value)\n return d\n\n def pop(self, key, def_val=None):\n return dict.pop(self, key.lower(), def_val)\n</pre>\n<br>\nThe idea is to override just what you must and leave as much as possible to the base class. As noted, it doesn't do keyword initialization. Other than that it should be pretty complete, and hopefully no slower than it must be. ", 'title': u'Another approach, with 2.4'}], 'desc': u'A dictionary that has case-insensitive keys.'}, {'comments': [{'comment': u"Hi, the Fibonacci numbers starts at 0, no 1\n(http://www.mcs.surrey.ac.uk/Personal/R.Knott/Fibonacci/fib.html)\n<br>\nYou have to change your while loop \n<br>\n<pre>\nwhile 1:\n x, y = y, x + y\n yield x\n</pre>\nwith this\n<pre>\nwhile 1:\n yield x\n x, y = y, x + y\n</pre>\nHTH\n<br>\ninkel\n<br>\n(Excuse my english, I'm from Argentina)", 'title': u"That isn't the Fibonacci numbers"}], 'desc': u'Generators, introduced in Python 2.2, can be used to work with infinite sets. Here is a simple example of a generator that creates the Fibonacci sequence.'}, {'comments': [{'comment': u'No answer from http://leviathan.kdart.com/~kdart/python/ipv4.py', 'title': u'URL is dead'}, {'comment': u'URL worked just fine today.', 'title': u'URL Works for me'}, {'comment': u'This looks like something that should be added to the Python Package Index \nhttp://cheeseshop.python.org/', 'title': u'cheeseshop?'}], 'desc': u'Complete IPv4 class that can represent a host or network, and iterate over networks. Supports slash notation, stringifying, and range generation (among other things).'}, {'comments': [{'comment': u'Instead of _relative_scheme being a dictionary, it might be simpler to make it a sequence ("_relative_scheme = [\'http\', \'https\', ...").<br>\n<br>\nThe line "if _relative_scheme.get(scheme, 0):" could then be replaced with the prettier "if scheme in _relative_scheme:".\n\n</br></br>', 'title': u'Sequence instead of Dictionary?'}, {'comment': u"in Python 2.2, you can use 'in' with a dictionary RHS operand, so getting both the nice syntax AND the dictionary's speed.\n", 'title': u'best of both worlds'}], 'desc': u"Normalise a URL by collapsing case where appropriate, trimming '..' path segments, etc."}, {'comments': [], 'desc': u'LazyDB extends the DB API to provide lazy connections (only\nestablished when needed) and access to query results by column\nname. A LazyDB connection can transparently replace any normal\nDB API connection but is significantly more convenient, making\nSQL queries feel almost like a built-in Python feature.\n'}, {'comments': [{'comment': u'From your code it looks like this code allows new connections to read the data and in some cases the code will not ever allow to update the data.', 'title': u'How do you prevent from new connections reading the data'}, {'comment': u"This is just a threaded lock; it's up to the programmer to make sure that more than unmanaged connections don't try to access the same file. Also, as far as I can see, there's no source of conflict in this code. Certainly it's performed well in my tests, and I've gone through the code fairly thoroughly...", 'title': u' '}], 'desc': u'A lock object that allows many simultaneous "read-locks", but only one "write-lock".'}, {'comments': [{'comment': u'The "return" statement in the code above should be indented so as to be inside the else:', 'title': u'fix'}, {'comment': u'You can use the two-argument form of iter() to get some of the same effect.\n<br>\nSo, this:\n<pre>\n[x for x in iter(genEven().next, 12)]\n</pre>\ngives the same result as this:\n<pre>\n[x for x in genWhile(genEven(), "< 12")]\n</pre>\n\nOf course, genWhile is more flexible, as it understands predicates rather than just a simple sentinel.', 'title': u'Use the two argument form of iter'}], 'desc': u'With Python 2.2+, you can make generators that return unbounded output. By creating a "wrapper" generator that runs the first generator, you can restrict its output to some defined subset. '}, {'comments': [{'comment': u'Oops...\n\n<pre>try:\n import thread\nexcept:\n def get_thread_storage():\n return {}\n</pre>\nis wrong since it returns a different dictionary instance every time it is called. It should be:\n\n<pre>try:\n import thread\nexcept:\n _tss = {}\n def get_thread_storage():\n return _tss\n</pre>\n\n', 'title': u'Bug-fix to single-threaded version'}, {'comment': u"The id's returned by get_ident are only unique to the currently active threads, so when a thread dies its id (and storage) might get used by another thread.\n\nI don't know how often this could bite you in practice, but maybe there should be a clear_storage()-function that a thread can call when it's done.", 'title': u'Problem with get_ident()'}, {'comment': u'The TSS implementation is based on a "global" variable that can be accessed by all threads within a process. Currently, potential problems occur when a TSS entry is created for a new thread or when a TSS entry is removed. Both action can lead to a restructering of the internal dictionary structure. Threads that access their TSS variable at this may obtain a access to "dangling" or corrupted TSS data.\n\nAs already stated by a comment above, a thread that creates an TSS entry shoulds also removed again when it dies or is killed.', 'title': u'_tss dictionary is not multi-threading protected'}, {'comment': u'Yup, there does exist a potential race condition when changing the global _tss dictionary. Anyway, this should fix that:\n\n<pre>\n...\nelse:\n _tss = {}\n _tss_lock = thread.allocate_lock()\n def get_thread_storage():\n """Return a thread-specific storage dictionary."""\n thread_id = thread.get_ident() # Identify the calling thread.\n tss = _tss.get(thread_id)\n if tss is None: # First time being called by this thread.\n try: # Entering critical section.\n _tss_lock.acquire()\n _tss[thread_id] = tss = {} # Create a thread-specific dictionary.\n finally:\n _tss_lock.release()\n return tss\n</pre>\nAs to the problem of deleting thread-specific storage on thread death, that is an issue since thread ids can be recycled. However, I use get_thread_storage() in a program that has a pool of "worker" threads that live as long as the main thread so it isn\'t a problem in this scenario.\n<br>\n<br>\nWriting a corresponding delete_thread_storage() is thus left as an Exercise for the Reader, ;), but it is symmetric to get_thread_storage().</br></br>', 'title': u'Thread-safe get_thread_storage()'}, {'comment': u'The updated source code now incorporates the changes I made in earlier comments.', 'title': u'Updated source reflects bug-fix comments'}, {'comment': u' def get_thread_storage(_get_ident=thread.get_ident):#make thread.get_ident a local var<br>\n    """Return a thread-specific storage dictionary."""<br>\n    thread_id = _get_ident() # Identify the calling thread.<br>\n    try:<br>\n        return _tss[thread_id]<br>\n    except KeyError:<br>\n        tss = _tss[thread_id]={}<br>\n        return tss<br>\nI don\'t need a lock because only a exists one thread with thread_id.\n\n', 'title': u'better get_thread_storage'}], 'desc': u'The get_thread_storage() function described below returns a thread-specific storage dictionary. (It is a generalization of the get_transaction() function from ZODB, the object database underlying Zope.) The returned dictionary can be used to store data that is "private" to the thread.'}, {'comments': [{'comment': u"entab doesn't work on the columnar assumption normally implied by tabs (and respected by detab). It changes runs of spaces to tabs with no care about where the columns end up, which is just about useless (when substituting all tabs).\n", 'title': u'entab is rather misleading'}], 'desc': u"Some other solutions to this problem have been posted, but most of them require lots of looping or many lines of code. Well, I've done up a couple of simple regular expressions that solve the en/detab problem. Enjoy."}, {'comments': [{'comment': u'For converting to DOS, how about:<br>\n<pre>\nimport re\ntemp = re.sub("\\r(?!\\n)|(?<!\\r)\\n", "\\r\\n", temp)\n</pre></br>', 'title': u' '}, {'comment': u'The standard Python distribution comes with two command-line scripts (in Tools/scripts) called crlf.py and lfcr.py that do this very thing.', 'title': u' '}, {'comment': u"Ah, so DOS line endings are \\r\\n, not \\n\\r. I don't have any DOS formatted files lying around, so I guess I got them mixed up.", 'title': u'DOS'}, {'comment': u'Thanks.', 'title': u'Change made'}, {'comment': u"what if it doesn't? I tried all sorts of line-at-a-time reads in binary mode, but could never find \\n or \\r\\n ending the string. PS I'm running 2.3 on Windows platform", 'title': u'Fine if the entire text fits in memory, but'}], 'desc': u'When working between platforms, it is often necessary to convert the line endings on files for them to work, especially when it comes to code. Pass Unix Python code with \\r and it goes nowhere. Same on Mac Python with \\n. This code simply and easily fixes the problem.'}, {'comments': [{'comment': u'Why not implement lazy caching of the actual objects produced by compile() and keep them in the validator instance?', 'title': u"Why compile Rx's each time?"}, {'comment': u'Thanks for the suggestion. That makes alot of sense. Its definately more efficient. I have made the change to the code, let me know if thats what you were thinking of.', 'title': u'thanks'}, {'comment': u'Actually the other way would be more efficient if I know I was just going to use the "is" only once or twice, because it would only compile the Rx\'s it needs. However, assuming that we will call this "is" methods many times, the new way is more efficient because the Rx\'s wouldn\'t be compiled every time.\n\nEither way, I think the new way is better design.', 'title': u'actually..'}, {'comment': u'So we could combine the ideas and reuse compiled regular expressions, but only compile them as they\'re needed. Each time a validity-testing method is invoked, just check to see whether the pattern has been compiled, if so use it, if not compile it but save it. I would also add support for arbitrary patterns stored by name that could be added at the class level. One last note, if you want to make the internal service method private, append "__" to the beginning of it\'s name.', 'title': u'Lazy Rx compilations'}, {'comment': u'I implemented lazy compilations. Please review my code. Is there any way that I can directly detect whether a variable is a compiled re object? I tried "isinstance".. but it didn\'t seem to work.\n<br><br>\nIn other words, are you saying.. you would like to see the ability to add arbitary patterns at run time?</br></br>', 'title': u'Ok..'}, {'comment': u'Just about there... but I would set those class-level variables to None and then just test the variables like:\n\n<pre>\nclass StringValidator:\n RE_ALPHA = None\n ...\n\n def isAlpha(self):\n if not self.RE_ALPHA:\n self.RE_ALPHA = re.compile("^\\D+$")\n return self.checkStringAgainstRe(self.RE_ALPHA)\n ...\n</pre>\n\nNote that the return statement should NOT be under the else clause that you had before! This means that in the case where a pre-compiled Rx was not found in the cache-variable, it will perform the compilation but skip the return statement, meaning that the calling expression recieves the default return value of None.\n\n<p>The idea I threw out about arbitrary patterns was just storing custom named patterns and lazy-compiling those as well. The user would then have to employ a method with the name as an argument or something similiar:\n\n<pre>\nStringValidator.definePattern("year", "^\\d{4}$")\n\nstrvalidator = StringValidator("text text abc123...")\nif strvalidator.validForPattern("year"):\n print "Is a valid year!"\n</pre></p>', 'title': u'Getting closer'}, {'comment': u'You can\'t call a method from a uninstantiated method withod an instance.<br>\nSo here\'s a module function that stores the pattern in a class variable:<br>\n<br>\n<pre>\ndef storePattern(re_name, re_pat):\n StringValidator._patterns[re_name] = re_pat\n<pre>\n<br>\nand a method to test the instance against that stored pattern:<br>\n<br>\n<pre>\n def isValidForPattern(self, re_name):\n if self._patterns.has_key(re_name):\n if type(self._patterns[re_name]) == type(\'\'):\n self._patterns[re_name] = re.compile(\n self._patterns[re_name]\n )\n return self.checkStringAgainstRe(\n self._patterns[re_name])\n else:\n raise KeyError, "No pattern named \'%s\' stored."\n</pre>\nhere\'s the testing code (BTW: als testing code should be placed in an <br>\n<br>\n<pre>\nif __name__ == \'__main__\':\n</pre>\nconstruct):<br>\n<br>\n<pre>\n\n # test for stored patterns\n storePattern(\'inquisition\', \'.*inquisition.*\')\n sv3 = StringValidator(\'spammish requisition\')\n print sv3._patterns\n\n if sv3.isValidForPattern(\'inquisition\'):\n print "I didn\'t expect the spanish inquisition!"\n else:\n print "Nobody expects the spanish inquisition!"\n</pre>\n<br>\nBTW: the method of testing the RE if they are of type string allows defining them\nat the start of the class definition for more clarity</br></br></br></br></br></br></br></br></pre></pre></br></br></br>', 'title': u'isValidForPattern'}, {'comment': u"Of course you have to add a class variable '_patterns = {}' to the StringValidator \nclass. Or you alter the storePattern method thus:<br>\n<br>\n<pre>\ndef storePattern(re_name, re_pat):\n if not hasattr(StringValidator, '_patterns'):\n\tStringValidator._patterns = {}\n StringValidator._patterns[re_name] = re_pat\n</pre></br></br>", 'title': u'isValidForPattern revisited'}, {'comment': u'Ok. I have implemented all recommended changes, please review the code.', 'title': u'ok.'}, {'comment': u'It is important to note that email adresses _can_ be shorter than 7 characters. Although domain names shorter than 2 letters are not allowed in .com .net and .org, many ISO country domain registrars do allow one letter domain names. For example in Denmark, where I live. \nFor example see http://www.n.dk\n\nSo a@n.dk is in fact a potential valid email address, which would not get through your regexp :-)', 'title': u'Short email addresses'}, {'comment': u'better to bind, e.g., self.__class__.RE_ALPHA=etc, rather than self.RE_ALPHA, so all other instances of the same class will transparently re-use the compiled re (keep per-class, not per-instance).\n', 'title': u'a slight enhancement'}, {'comment': u'Great idea! :]', 'title': u'!'}, {'comment': u'Great idea! :]', 'title': u'!'}, {'comment': u'The regex for isEmail will return true even if the string being validated contains space characters. The following regex allows for any character (just as the original) except a space:\n<br><br>\n<pre>\nself.__class__.RE_EMAIL = re.compile("^[^\\s]+@[^\\s]+\\.[^\\s]{2,3}$")\n</pre>', 'title': u'RE_EMAIL regex'}, {'comment': u'Why not make definePattern a classmethod i.e.\n\n definePattern = classmethod(definePattern)\n\nthen you define patterns without requiring an instance i.e.\n\n StringValidator.definePattern(....)', 'title': u'Classmethod'}], 'desc': u'A portable class to carry out all sorts of validation on strings. It uses regular expressions to carry out common validation procedures. '}, {'comments': [], 'desc': u'A function to calculate the percent of requests that were "refused" by Apache server due to the clients ability to read the file from their cache instead.'}, {'comments': [{'comment': u'Surely the builtins map(), filter() and reduce() will use iterators by default in Python 2.2? And what about the for loop? I was under the impression that "for x in seq" would in fact execute "for x in iter(seq)"?', 'title': u'Redundancy?'}, {'comment': u'The original builtins cannot be changed, since that would break a lot of existing code that expects lists from those functions. ', 'title': u"I don't think so"}, {'comment': u'I believe Martin is correct; python internals that iterated over sequences now use the iterator protocol.\n<br><br>\n"In 2.2, Python\'s for statement no longer expects a sequence; it expects something for which iter() will return an iterator. For backward compatibility and convenience, an iterator is automatically constructed for sequences that don\'t implement __iter__() or a tp_iter slot, so for i in [1,2,3] will still work. Wherever the Python interpreter loops over a sequence, it\'s been changed to use the iterator protocol."<br>\n--What\'s New in Python 2.2 (A. M. Kuchling)<br>\n<br>\nI experimented and found that I could indeed use my own trivial iterator classes (as long as they provide __iter__ which returns self) with for loops, list comprehensions, map, filter, and reduce.', 'title': u'These are indeed mostly redundant'}, {'comment': u"Even in 2.3, the builtin functions like map, filter and zip return lists, not iterators. Sami's code will return iterators - which may or may not be important. If, for example, you map some function over the lines of a 4 GB file, you /really/ don't want map to return a list unless you happen to have 4+ GB of memory sitting around. Sami's code will still operate reasonably under these circumstances, where the builtin functions won't.", 'title': u'depends what you mean by redundant...'}], 'desc': u'A collection of small utility functions for iterators (all functions can also be used with normal sequences). Among other things, the module provides generator ("lazy") versions of the built-in sequence-manipulation functions. The generators can be combined to produce a more specialised iterator.'}, {'comments': [{'comment': u"The following line is incorrect:\n<pre>print 'DEBUG: Metadata file',metadatafile,'does not exist.'</pre>\nInstead it should read:\n<pre>print 'DEBUG: Metadata file',self.metadatafile,'does not exist.'</pre>\n\n\n ", 'title': u'Error in line'}, {'comment': u'Sam - Thanks! I missed that when I was rewriting part of the script. I hope that you found this code useful.', 'title': u'Thank you'}], 'desc': u'Provides a class for creating and manipulating plain-text logfiles. MD5 checksums are used to verify the integrity of logfiles between sessions. A file of metadata for each log is also maintained. Includes an example of how to create and use a logpyl object.'}, {'comments': [], 'desc': u'The "CookieInfo" and "Cookie" classes provide developers with an read-only interface to the "cookies.txt" that most browsers store. The CookieInfo class makes Cookie objects from the cookie file. It also provides methods to operate on the whole set of Cookies. The Cookie object provides methods to convert a cookie into both XML and SQL.'}, {'comments': [{'comment': u'I am using a Win2000 Professional box and I can type dir /s \\\\remoteserver\\c$ and get the directory info. I can also md, rd, del, and copy from my local box to the remote server on the command line. copy c:\\somefile.txt \\\\remoteserver\\c$\\temp works. It is a good script and I will be modifying to work with the 57 Domain Controllers here.', 'title': u'Why map drive Z:\\ ?'}, {'comment': u'<pre>\nimport win32com.client as com\n\n\ndef TotalSize(drive):\n """ Return the TotalSize of a shared drive [GB]"""\n try:\n fso = com.Dispatch("Scripting.FileSystemObject")\n drv = fso.GetDrive(drive)\n return drv.TotalSize/2**30\n except:\n return 0\n\ndef FreeSpace(drive):\n """ Return the FreeSape of a shared drive [GB]"""\n try:\n fso = com.Dispatch("Scripting.FileSystemObject")\n drv = fso.GetDrive(drive)\n return drv.FreeSpace/2**30\n except:\n return 0\n\ndrive = r\'\\\\servername\\c$\'\nprint \'TotalSize of %s = %d\' % (drive, TotalSize(drive))\nprint \'FreeSapce on %s = %d\' % (drive, FreeSapce(drive))\n</pre>', 'title': u'The same with win32com.client'}], 'desc': u'This module , does not take any i/p file. It first does a net view\ncommand , and gets the list of computers in the domain. Connects\nto each computer , performs size check and returns the size of the\nharddisk. Please note that , the file and dir sizes are caluclated\nin DOS. Windows performs a sort of approximation. So there will be\nslight variation in the amount of space reported by DOS and Windows.\nIf I am not wrong DOS gives u the best values.'}, {'comments': [{'comment': u"If you're generating the permutations of a long list, speed matters a lot. The code below is about four times faster than the recipe presented above.<br><br>\n\n<pre>def permute(alist, level=0):\n index, copy, printing = level, list(alist), level+1 == len(alist)\n\n while 1:\n if printing:\n print ''.join(copy)\n else:\n permute(copy, 1+level); \n\n if index != 0:\n copy[index-1], copy[index] = copy[index], copy[index-1]\n\n index -= 1\n if index < 0:\n break\n</pre></br></br>", 'title': u'A faster way'}, {'comment': u'The logic behind generating permutations is a little more visible in the following (IMO):\n\n<pre>\n\ndef getPermutations(a):\n if len(a)==1:\n yield a\n else:\n for i in range(len(a)):\n this = a[i]\n rest = a[:i] + a[i+1:]\n for p in getPermutations(rest):\n yield this + p\n\n\n</pre>', 'title': u'A different way using generators'}, {'comment': u'Its best to avoid those by using:\n\n<pre>\ndef ...(...blist=None...):\n if blist == None:\n blist = []\n ...\n</pre>\n\nOr otherwise, this function can only run once in parallel and is not reentrant and not safe (when using threads, or if callbacks eventually re-call it).', 'title': u'mutable default argument'}], 'desc': u'A small but efficient recursive function for printing the permutation of characters in a given string.'}, {'comments': [{'comment': u'First off, thanks for your effort. \n<br><br>Using the string:\n<pre>abcdefghijklmnopqrstuvwxyz</pre>\n<br>produces an interesting side effect, namely, the script does not self-replicate two-digit combinations, i.e., no aa, bb, cc, dd, ee, ff, ... combinations occur.', 'title': u'String Plucking'}, {'comment': u'I also post this in http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/190465\n\n<pre>\ndef printUniqueCombinations(alist, numb, blist=[]):\n if not numb: return printList(blist)\n for i in range(len(alist)-numb+1):\n blist.append(alist[i])\n printUniqueCombinations(alist[i+1:], numb-1, blist)\n blist.pop()\n</pre>', 'title': u'A faster printUniqueCombinations'}, {'comment': u"<pre>\ndef getUniqueCombinations(alist, numb):\n for i in range(len(alist)):\n if numb==1:\n yield alist[i]\n else:\n for combo in getUniqueCombinations(alist[i+1:], numb-1):\n yield alist[i] + combo\n\n</pre>\n\nNote this does not print them but you have to iterate over the result:\n\n<pre>\nfor combo in getUniqueCombinations('love', 2):\n print combo\n</pre>\n\n<br>", 'title': u'Unique combinations using generators - faster'}], 'desc': u'Efficient recursive functions for generating combinations of specified length from a specified string. Can generate unique or all possible combinations.'}, {'comments': [{'comment': u'You can get a substantial speed boost by pre-allocating the list instead of calling append over and over. This also allows you to get rid of the conditionals in the inner loop. For 1 element, this version is barely faster, and above about 10 elements it\'s consistently about 5 times faster. I get identical output for every test case I can think of.\n\n<pre>\ndef frange2(start, end=None, inc=None):\n "A range function, that does accept float increments..."\n\n if end == None:\n end = start + 0.0\n start = 0.0\n else: start += 0.0 # force it to be a float\n\n if inc == None:\n inc = 1.0\n\n count = int((end - start) / inc)\n if start + count * inc != end:\n # need to adjust the count.\n # AFAIKT, it always comes up one short.\n count += 1\n\n L = [None,] * count\n for i in xrange(count):\n L[i] = start + i * inc\n\n return L\n</pre>', 'title': u'This is faster'}, {'comment': u"count = int(math.ceil((end-start)/inc)\nso you don't need if start + count * inc != end: ...\n", 'title': u'A little simplification'}, {'comment': u'<pre>\nThe algorithm has a slight problem where floating point representation\nerror accumulates over the range, giving unexpected results:\n\n[i/10. for i in range(-2,2)] == frange2(-0.2,0.2,0.1) -> False\n\nSince 0.1 is actually 0.10000000001\n\nThis slight modification corrects the problem:\n\ndef frange3(start, end=None, inc=None):\n """A range function, that does accept float increments..."""\n import math\n\n if end == None:\n end = start + 0.0\n start = 0.0\n else: start += 0.0 # force it to be a float\n\n if inc == None:\n inc = 1.0\n count = int(math.ceil((end - start) / inc))\n\n L = [None,] * count\n\n L[0] = start\n for i in xrange(1,count):\n L[i] = L[i-1] + inc\n return L\n</pre>', 'title': u'More Correct'}, {'comment': u'The \'start\' and \'end\' arguments in the previous scripts are out of place: the function initially starts at 0, and stop at \'end\', \'end\' itself exclusive, not the other way around.\n\nSuggestion: Allow a precision to be specified. (Not implemented yet.)\n\n<pre>\ndef frange4(end,start=0,inc=0,precision=1):\n """A range function that accepts float increments."""\n import math\n\n if not start:\n start = end + 0.0\n end = 0.0\n else: end += 0.0\n\n if not inc:\n inc = 1.0\n count = int(math.ceil((start - end) / inc))\n\n L = [None] * count\n\n L[0] = end\n for i in (xrange(1,count)):\n L[i] = L[i-1] + inc\n return L\n</pre>', 'title': u'Even more correct, but not nearly complete...'}, {'comment': u'I think this is best solved by\n\n<pre>\nfrom Numeric import *\narange(-1,1,0.1)\n</pre>\n\nthen if you really need a list:\n\n<pre>\narange(-1,1,0.1).tolist()\n</pre>', 'title': u'Use Numeric '}, {'comment': u'A naive but working xrange() -like implementation using generators could be as follows:\n\n<pre>\ndef xfrange(start, stop=None, step=None):\n """Like range(), but returns list of floats instead\n\n All numbers are generated on-demand using generators\n """\n\n if stop is None:\n stop = float(start)\n start = 0.0\n\n if step is None:\n step = 1.0\n\n cur = float(start)\n\n while cur < stop:\n yield cur\n cur += step\n</pre>\n\nUsage:\n\n<pre>\nif __name__ == \'__main__\':\n\n for f in xfrange(5): print f,\n print\n for f in xfrange(1, 3): print f,\n print\n for f in xfrange(1, 2, 0.25): print f,\n print\n</pre>', 'title': u'More memory-efficient implementation with generators'}, {'comment': u'The following implementation does not require Numeric and is fast, as the generator is created directly by python. It also accepts integers. There is no accumulation of errors, as the increment is not added incrementally. \n\n<pre>\nimport math\ndef frange5(limit1, limit2 = None, increment = 1.):\n """\n Range function that accepts floats (and integers).\n\n Usage:\n frange(-2, 2, 0.1)\n frange(10)\n frange(10, increment = 0.5)\n\n The returned value is an iterator. Use list(frange) for a list.\n """\n\n if limit2 is None:\n limit2, limit1 = limit1, 0.\n else:\n limit1 = float(limit1)\n\n count = int(math.ceil(limit2 - limit1)/increment)\n return (limit1 + n*increment for n in range(count))\n</pre>', 'title': u'Fast, flexible and memory-efficient; also accepts integers; does not require Numeric'}, {'comment': u'<pre>frange4(-1, 0, 0.1)</pre> breaks the above frange4.\n\nA possible solution would be to set start = None as a default argument and test whether start is None.', 'title': u'This can break, unfortunately'}, {'comment': u'In the example above, the range function should really be replaced the xrange function, if memory efficiency is desired.\n\n<br>\nPrecision: in the doc string, "list(frange)" means "list(frange(start,...))".', 'title': u'range -> xrange, for memory efficiency'}, {'comment': u'There is a small typo in the original code, which should be corrected as:\n\n<pre>\nint(ceil(...)/increment) -> int(ceil((...)/increment))\n</pre>\n\n<br>\nAlso, it is possible to mimic the behavior of the built-in range even better: frange(0,5,-1) should return an empty list. This can be accomplished with:\n<pre>\nrange(count) -> range(0,count)\n</pre>', 'title': u'Typo: int(ceil(...)/increment) -> int(ceil((...)/increment))'}], 'desc': u'Sadly missing in the Python standard library, this function\nallows to use ranges, just as the built-in function range(),\nbut with float arguments. \n\nAll thoretic restrictions apply, but in practice this is \nmore useful than in theory.\n'}, {'comments': [{'comment': u'It looks like the "\\" continuation character was dropped from the code and my third and fourth lines were combined. I guess it really is quicksort in 3 lines!\n<br><br>\nFYI, the third and fourth lines should have looked like:<br>\n<pre>\n return qsort( [ lt for lt in L[1:] if lt < L[0] ] ) + [ L[0] ] + qsort( [ ge for ge in L[1:] if ge >= L[0] ] ).\n</pre>\n<br><br>\nASPN, you may want to fix this problem, since line continuations are common in python. (Be aware that the "\\" shows up in the preview).</br></br></br></br></br>', 'title': u'Continuation character dropped '}, {'comment': u'Yes, the "\\" was dropped again from the above comment. I give up. :-(', 'title': u'Sigh.'}, {'comment': u'It looks like <pre>"\\ "</pre> is not interpreted as line continuation by the ASPN filters. Alas, the end-user now has to manually delete the space if she wants to run the code, so I\'ve added a note to the description.', 'title': u'Success! (Sort of)'}, {'comment': u'Here is a slightly less naive version. Pivot selection is random to make worst case performance less likely. Pivots are counted to handle degenerate cases with many equal elements. Filter is used for rapid partitioning.\n\n<pre>\ndef qs(ds):\n if len(ds) <= 1: return ds\n pivot = random.choice(ds)\n return qs(filter(lambda x: x < pivot, ds)) +\n [pivot]*ds.count(pivot) +\n qs(filter(lambda x: x > pivot, ds))\n</pre>', 'title': u'Refinements'}, {'comment': u'Of course this must not be used in real code too!\n\n<pre>\nq=lambda x:(lambda o=lambda s:[i for i in x if cmp(i,x[0])==s]:len(x)>1 and q(o(-1))+o(0)+q(o(1)) or x)()\n</pre>\n\nThis lambda expression is just a rewriting of this function:\n\n<pre>\ndef q(x):\n\tif len(x)>1:\n\t\tlt = [i for i in x if cmp(i,x[0]) == -1 ]\n\t\teq = [i for i in x if cmp(i,x[0]) == 0 ]\n\t\tgt = [i for i in x if cmp(i,x[0]) == 1 ]\n\t\treturn q(lt) + q(eq) + q(gt)\n\telse:\n\t\treturn x\n</pre>', 'title': u'Just For Fun: Quicksort in 1 Line'}, {'comment': u'<pre>\ndef q(x):\n\tif len(x)>1:\n\t\tlt = [i for i in x if cmp(i,x[0]) == -1 ]\n\t\teq = [i for i in x if cmp(i,x[0]) == 0 ]\n\t\tgt = [i for i in x if cmp(i,x[0]) == 1 ]\n\t\treturn q(lt) + q(eq) + q(gt)\n\telse: ^^^^^ \n\t\treturn x\n</pre>\nRunning q(eq) will infinitely recurse. Use eq instead of q(eq)', 'title': u'Bug in quicksort long form...'}, {'comment': u"O'Reilly's _Python Cookbook_ published this recipe without the second list comprehension [ L[0] ]. It looks like:\n\n<pre>\ndef qsort(L):\n if len(L) O'Reilly's _Python Cookbook_ published this recipe without the second list comprehension [ L[0] ]. It looks like:\n\n<pre>\ndef qsort(L):\n if len(L) </pre></pre>", 'title': u"Misprinted in O'Reilly's _Python Cookbook_"}, {'comment': u"This site's markup is unfathomable.\n\nO'Reilly published this recipe as\n\n<pre>def qsort(L):\n if len(L) This site's markup is unfathomable.\n\nO'Reilly published this recipe as\n\n<pre>def qsort(L):\n if len(L) </pre></pre>", 'title': u'Correction'}], 'desc': u"OK, 4 lines if you count wrapped lines. :^) This is a rather naive implementation of quicksort that illustrates the expressive power of list comprehensions. DO NOT USE THIS IN REAL CODE!\n\nNOTE: Due to an annoyance in the ASPN submission filters you must manually remove the space after the '\\' character in the third line if you intend to use the code. Otherwise you will get a syntax error."}, {'comments': [{'comment': u'The module "new" already contains this.', 'title': u'new.instance does this already'}, {'comment': u'Sorry, I should have read till the end, and you cannot remove comments... :/', 'title': u'hmmmm...'}, {'comment': u"Shouldn't it rather be :\nnew.instance(self.__class__, self.__dict__.copy() )", 'title': u'new.instance ?'}], 'desc': u"Special method __copy__ is the easiest way for an object to cooperate with the copy.copy function, but how do you bypass the object's __init__, if it's slow, to get an 'empty' object of this class? Easy -- here's how."}, {'comments': [{'comment': u'This worked instantly in linux as well.\n', 'title': u'Thanks!'}, {'comment': u"Didn't work on OS X (10.3.3), Python complains that there is no module elemlist.\n\nWill post solution when I figure it out unless someone beats me to it.", 'title': u"Didn't work on OS X "}, {'comment': u'Returned this error:\n\n"error: The .NET Framework SDK needs to be installed before building extensions for Python."\n\nPython install seems to be working fine. Curiously, I have Visual Studio .NET professional installed.', 'title': u"Didn't work (Python 2.4)"}, {'comment': u'I spent a couple of hours researching the problem this afternoon. It seems that Python 2.4 on Windows XP requires some modifications to distutils to use Microsoft compilers (and the development environment needs to be setup correctly). I followed the instructions at\n<br><br>\nhttp://www.vrplumber.com/programming/mstoolkit/index.html\n<br><br>\nand was able to successfully reproduce this recipe.\n<br><br>\nMarcus', 'title': u'Found the fix for Python 2.4 on Windows XP'}], 'desc': u"C-coded Python extension types have an aura of mystery and difficulty they don't really deserve. Sure, it's a lot of work to implement every possible nicety, but a fundamental useful type doesn't take much."}, {'comments': [{'comment': u'I generally find the process of stepping through all the modules that Python reads at startup rather tedius. So I modify the file Modules/main.c before I build my interpreter to include a new function\n\n<br><br>void Py_DebugTrap(void);<br><br>\n\nI now can add a call to this function in whatever extension I want to debug. This symbol is available when you type "gdb python" so you can set a breakpoint there immediately. I then set args to my script and continue. It even works in parallel under MPI!</br></br></br></br>', 'title': u'Better but more intrusive trick'}], 'desc': u"If a dynamically loaded C/C++ extension is causing Python to core dump, \nhere's a technique to debug your extension using gdb."}, {'comments': [{'comment': u"I'm curious to hear how this technique compares to another common idiom I've seen, which for the example would be:<br>\n<pre>\ndef addword(word, pagenumber):\n theIndex[word] = theIndex.get(word, []) + [pagenumber]\n</pre>\nTIA", 'title': u'Better?'}, {'comment': u"So I ran the following code. I have yet to get a result for dict_2(). It was running for far too long. dict_1() takes about .7 seconds.\n\n<pre>\n# test.py\nWORDS = ['this', 'that', 'other']\ndef dict_1():\n d = {}\n for x in xrange(0, 100000):\n word = WORDS[x%3]\n d.setdefault(word, []).append(x)\ndef dict_2():\n d = {}\n for y in xrange(0, 100000):\n word2 = WORDS[y%3]\n d[word2] = d.setdefault(word2, []) + [y]\n\nif __name__ == '__main__':\n import profile\n profile.run('dict_1()')\n profile.run('dict_2()')\n</pre>", 'title': u'I had the same question....'}, {'comment': u"Here are some specifics on the test I ran above:\n\n<pre>\n 3 function calls in 0.752 CPU seconds\n\n Ordered by: standard name\n\n ncalls tottime percall cumtime percall filename:lineno(function)\n 1 0.038 0.038 0.690 0.690 :1(?)\n 1 0.653 0.653 0.653 0.653 dictTest.py:2(dict_1)\n 1 0.061 0.061 0.752 0.752 profile:0(dict_1())\n 0 0.000 0.000 profile:0(profiler)\n</pre>\n======================================================================\n<pre>\n 3 function calls in 551.600 CPU seconds\n\n Ordered by: standard name\n\n ncalls tottime percall cumtime percall filename:lineno(function)\n 1 0.026 0.026 551.518 551.518 :1(?)\n 1 551.492 551.492 551.492 551.492 dictTest.py:7(dict_2)\n 1 0.082 0.082 551.600 551.600 profile:0(dict_2())\n 0 0.000 0.000 profile:0(profiler)\n\n</pre>\nAs you can see, there's a massive difference.\n<br>\nMy system:<br>\nPython 2.3b1<br>\nWindows 2K<br>\nPIII 1.13 GHz<br>", 'title': u'Some specifics'}], 'desc': u"Often, when working with a dictionary D, you need to use the entry D[k] if it's already present, or add a new D[k] if k wasn't a key into D. The setdefault method of dictionaries is a very handy shortcut for this task."}, {'comments': [{'comment': u'Hi!<br>\n<br>\nThe interpretation via the struct-module is not correct on most platforms. You have to force interpretation in network (= big-endian) byte order, i.e. "!L" as format string, not just "L".<br>\n<br>\nTino\n', 'title': u'Careful: byte-order -> example is not correct on usual (PC) platforms'}, {'comment': u'Yes, obviously there\'s not much point to calling with 0, as it\'s a no-op, but "it\'s easier to ask forgiveness than permission."\n<br>\nHere\'s a version that works with the (valid) input of 0:\n\n<pre>\ndef makeMask(n):\n "return a mask of n bits as a long integer"\n return (1L<<n)-1\n</pre>', 'title': u'makeMask fails with argument of 0'}, {'comment': u'Is there a similar lib for IPv6 addresses?', 'title': u'IPv6?'}], 'desc': u'Convert dotted-quad IP addresses to long integer and back, get network and host portions from an IP address, all nice and fast thanks to the builtin socket module (with a little help from the builtin struct module, too).'}, {'comments': [{'comment': u'Your __call__ method would have to take *args, **kwds arguments as well, and you\'d have to merge your preset arguments and the ones given. Don\'t ask me how :-)\n<br>\nA "callback" that only supports empty argument lists isn\'t very useful!</br>', 'title': u'But what if the callback takes arguments?'}, {'comment': u"typical tkinter callbacks have no args, so this recipe's quite useful for that need. more general curry solutions (applicable to all sort of callbacks &c) can be found in other recipes.\n", 'title': u'tkinter often uses no args'}, {'comment': u'This function is definitely in Grayson\'s "Python and Tkinter Programming", and is credited to a Python news group posting by Timothy R. Evans.', 'title': u'source of utility function'}], 'desc': u'A utility class that makes writing callbacks more pleasant than using lambda. Especially using with Tkinter.'}, {'comments': [{'comment': u'If the list of points passed to this function is not unique, it will raise an assertion. To fix this, remove these lines from the beginning of the convexHull function:\n\n<pre>\n # Get a local list copy of the points and sort them lexically.\n points = list(P)\n points.sort()\n</pre>\n\nReplace this with these lines:\n\n<pre>\n # Remove any duplicates\n # If the hull has a duplicate point, it will be returned once\n # It is up to the application to handle it correctly\n unique = {}\n for p in P:\n unique[p] = 1\n\n points = unique.keys()\n points.sort()\n</pre>', 'title': u'Small Bug: Only works with a list of UNIQUE points'}], 'desc': u'This simple code calculates the convex hull of a set of 2D points\nand generates EPS files to visualise them. The algorithm was taken\nfrom a textbook on Computional Geometry.\n'}, {'comments': [{'comment': u"How about Hivemind? I've seen that used in science fiction situations that might\nfit this concept ", 'title': u'Another name...'}, {'comment': u"I think the 'Borg' fits this pattern quite well. =)", 'title': u'Name suggestion'}, {'comment': u'The singleton name is correct, even though your Python implementation is neat++.\n<br><br>\nIn Effective C++ by Scott Meyers (item 47) he solves the singleton problem in exactly the same way.\nThe object is created once and then subsquent calls simply return a reference to the original object.\nIn C++ Meyers uses a function wrapper to ensure that it will be declared early enough, but the principle is the same.\n<br><br>\nIn the Design Patterns book the C++ implementation has a class wide Singleton::Instance() function and prevents the constructor being\nused by making it protected. Same trick.\n<br><br>\nCoincidently, in an upcoming PHP cookbook web site I am going to publish a singlton pattern that uses the same trick.\n<br><br>\nyours, Marcus.\n</br></br></br></br></br></br></br></br>', 'title': u'Should just call it a singleton!'}, {'comment': u'This is a completely and deeply different pattern from Singleton, and thus I find the latest comment totally off-base. Singleton focuses (wrongly) on *object IDENTITY*: that\'s what the Gof4 focuses on, that\'s what "EffC++" focuses on, etc, etc. But we *don\'t really care* about identity most of the time, but about *state and behavior*.\n<br> \n<br>The "Borg" design pattern IS quite possible in C++ (just a bit more laborious, but not much) and was indeed once written up in C++ Report (but I forget the name it was given then and can\'t find my old issue): you get as many objects as you want, with separate identities but all sharing state and behavior. That\'s the POINT! Just about all the *practical USEFULNESS* of Singleton *without* the troublesome identity-issue that Singleton tends to give.\n</br></br>', 'title': u"It's NOT a singleton object... it doesn't NEED to be!"}, {'comment': u'You have a point with the state thing and all, however you do loose the encapsulation offered by the Singleton pattern. You also loose readability and explicitness.<br> <br>\nIf you take the gof course, your implementation can still return new instances implemented just as you have described. <br> <br>\nHowever, if you take your course it will be much difficult (or impossible) to replace the creation of new instances with a single one.<br> <br>\nAlso, you loose the explicitness offered by the gof pattern. Clients know that they use a shared object and that it is - transient - and susceptible to change by others. <br> <br>\nYour suggestion might lead to serious misunderstandings (i.e. bugs) in clients of the object (and the external interface exposed to the client is more important than the implementation and the implementers).\n</br></br></br></br></br></br></br></br>', 'title': u'You loose the encapsulation, readability and explicitness offered by the Singleton'}, {'comment': u'Please calm down.\n<br><br>\nFrom GOF4:\n"...to make the class itself responsible for keeping track of it\'s sole instance."\nwhich does cover your intention.\n<br>\nI probably did not make clear that it was their intention rather than their implementation I was trying to get accross.\nEffC++ was trying to solve a slightly different problem and recast it as a singleton.\nIt seems pretty clear that both were trying to get around the "new" semantics in their implementations and that\nyour implementation is different. Agreed.\n<br><br>\nSingleton is a very nice name. Agreed.\n<br><br>\nBorg is a nice name, but I am not sure that it is exactly right.\nIt could fit a lot of cooperative behaviours as well as "all as one".\nA thread pool that all worked at the same task would fit.\n<br><br>\nI could not say which is the more confusing and you will have to just ask lots of programmers as a usability test.\nI am afraid my personal vote is still for singleton as when I inherit a singleton I know what I want,\nbut when I inherit a Borg I am (a little) less sure.\n<br><br>\nPlease let us know which issue of C++ report it is in when you find it.\n<br>yours, Marcus.</br></br></br></br></br></br></br></br></br></br></br></br>', 'title': u'quoting...'}, {'comment': u'What happens in a large system when two separate subsystems both inherit from (extend) a singleton-class? It\'s anything but clear to me -- error at runtime, at compiletime, at linktime (none such in Python, let\'s say at import-time), or what behavior...?<br>\n<br>\nWith Borg, it\'s simplicity itself: as Borg can be instantiated as many times as you want, but all instances share state, each separate subclass may differently override _behavior_, but _state_ will still be collectively shared by all Borg\'s and sub-Borg\'s. (Separate sub-Borg classes may of course have class-private state by naming attributes with two leading underscores, as typically done in Python). Easy as pie -- and by that very token, easy to document and explain, too. "All state is shared, identity is indifferent, you\'ll be assimilated"!-)\n</br></br>', 'title': u'inheriting singleton vs inheriting borg'}, {'comment': u'... is getting very long and thin (at least in my browser).\n\nPerhaps additional remarks could appear in a new thread?', 'title': u'This discussion ...'}, {'comment': u'Alex, isn\'t this pattern the one you once referred to as "Stateless Proxy"? And, Marcus, Borg is similar to Singleton,\nexcept that you separate access and functionality. In C++ you\'d still have a static instance of the class that provides the\n*functionality* (no loss of encapsulation, then), but it would be private to the Borg class and would only be accessed by\nthe Borg class\'s member functions.', 'title': u'Borg vs. Singleton'}, {'comment': u"Yes Nicola, Borg is the new and improved name (suggested by David Ascher, chief editor of this Cookbook, in a comment above) for the pattern formerly known as 'stateless proxy'.\n", 'title': u"Borg is indeed 'stateless proxy'"}, {'comment': u'There was an article in the C++ Report several years ago that introduced the Monostate pattern, where all instances share the same state.\n\nThe major problem I have found with most implementations of Singletons or Monostates in various languages is that if you need to support multithreading, you have to jump through some fairly major hoops to achieve a good balance of correctness and efficiency.', 'title': u'also known as Monostate'}, {'comment': u'There was an article in the C++ Report several years ago that introduced the Monostate pattern, where all instances share the same state.\n\nThe major problem I have found with most implementations of Singletons or Monostates in various languages is that if you need to support multithreading, you have to jump through some fairly major hoops to achieve a good balance of correctness and efficiency.', 'title': u'also known as Monostate'}, {'comment': u"If you want to use the Borg pattern from more than one module, it works as follows:\nExtract the Borg Pattern into a module and a class of its own:\nborg.py:\n<pre>\nclass Borg:\n __shared_state = {} # or org.python.core.PyStringMap in jython\n def __init__(self):\n self.__dict__ = self.__shared_state\n</pre>\nLet your class in a separate module inherit from Borg and call Borg's initializer in your __init__:\n<pre>\nimport borg\nclass Test(borg.Borg):\n def __init__(s):\n borg.Borg.__init__(s)\n</pre>\nAlthough sounding like a swedish chef, it works now. The state is shared across all modules using the Test class.", 'title': u'Borg and more than one module'}, {'comment': u"Sorry for the replication. Must've hit add instead of preview somewhere...", 'title': u' '}, {'comment': u"Although it looks now like a bug in the Cookbook code... I'm sure I added the last comment only once!", 'title': u' '}, {'comment': u'Threading issues really have little to do with Highlander vs Borg (or Singleton vs Monostate if you prefer boring names:-). In Python, it\'s simplest to devote a thread to handling a bunch of resources that need to be serialized (no matter whether they\'re wrapped into one or more objects of whatever type), with a Queue of requests on which the devoted-thread (Guardian thread) always sleeps working for requests. All access by working threads to the guardian thread and the resources it protects is by posting to the guardian queue a tuple (response-queue, callable, args, kwds) followed by waiting on the response-queue. Why people would want to conflate this important idiom with the equally important and unrelated idiom of state sharing is a mystery to me, as they work just as well together or separately. What\'s the contrary of "divide and conquer" -- "conflate and suffer"?-)\n', 'title': u'threading'}, {'comment': u'Sorry there was a bug, its fixed now.', 'title': u'Double comments'}, {'comment': u'Philosophical considerations aside, the "classic" Singleton pattern\nwould seem to perform better than the Borg pattern, when it comes to garbage collection, wouldn\'t it? What is the point of having\nthe garbage collector keep track of reference counts for a million\nobjects, when one object would suffice?', 'title': u'what about GC?'}, {'comment': u"<pre>\nclass Singleton(object):\n def __new__(type):\n if not '_the_instance' in type.__dict__:\n type._the_instance = object.__new__(type)\n return type._the_instance\n</pre>\n<br>\nJust inherit from this class. Everything else is handled automatically.", 'title': u'Singletons using new-style classes'}, {'comment': u'<pre>\n# here is the new-style Borg (not much more complex then the "old-style")\nclass Borg(object):\n _state = {}\n def __new__(cls, *p, **k):\n self = object.__new__(cls, *p, **k)\n self.__dict__ = cls._state\n return self\n</pre>', 'title': u'New-style Borg...'}, {'comment': u"For those just joining us from Google, use Oren Tirosh's in the comment one above. Two instances of this singleton do not pass the id(a) == id(b) test. Oren's does.", 'title': u'Re: New-style Borg...'}, {'comment': u"<pre>\nclass Singleton(object):\n def __new__(cls, *p, **k):\n if not '_the_instance' in cls.__dict__:\n cls._the_instance = object.__new__(cls)\n return cls._the_instance\n</pre>\nType is now a keyword. And classes can be initialized with params. This handles that.<br>", 'title': u'Slight improvement.'}, {'comment': u"You don't need singletons in python simply because classes and modules are always singletons, and they are also first class objects. They can have everything instances have, and as import statements don't make copies there is only ever one of them. We don't need no stinkin' design patterns.", 'title': u'classes and modules are singletons'}, {'comment': u'I agree, but who prevents us from doing stupid things then? Such as instanciating a class, meant to be a singelton within a modul twice? ', 'title': u'Classes and modules are singeltons, but who prevents us?'}, {'comment': u"Let's suppose you're implementing a singleton-like class, and you create an instance in your module. You don't want anyone else to be able to create another instance of your class. Just remove the class just after having created your instance ! That's all...\n\nExemple (in module singleton) : \n\n class MySingleton( object ) :\n pass\n \n singleton = MySingleton()\n MySingleton = None\n\nThen, you can use :\n from singleton import singleton\n\nBut you can't do :\n import singleton\n singleton.MySingleton()\n\nOf course, you can acces to the class threw the instance. But if you're lurking within the instances to find funny things, you'll have problems everywhere...\n", 'title': u'Classes and modules are singeltons, but who prevents us? : You !'}, {'comment': u"Who can prevent someone from doing type(singleton)(...)?\n\nI think the real solution could be class with classmethods and __new__ raising an Error, then you don't need no instance. But even then someone could have just replaced __new__. :)", 'title': u'You forgot about type'}], 'desc': u'The Singleton design pattern (DP) has a catchy name, but the wrong focus -- on identity rather than on state. The Borg design pattern has all instances share state instead, and Python makes it, literally, a snap.'}, {'comments': [{'comment': u'I later discovered that this doesn\'t handle cases where the header\nfiles must be chased down thru a string of "-I" compiler directives.Ideally this script should search include directories in the same order\nthat the compiler will do so. I\'ll ponder that and see if I can figure\nout a fix.', 'title': u'doesn\'t handle "-I<directory>"'}, {'comment': u'You would be better of running the code files through the cpp phase of the compiler and then extracting the #line information to determine what files it is dependent on. Ie., something like:\n\n<pre>\n gcc -C -E file.c | script-to-extract-dependencies\n</pre>\n\nDepening on the cpp, the #line information will be output as either:\n\n<pre>\n #line 1 "file.c"\n</pre>\n\nor:\n\n<pre>\n # 1 "file.c"\n</pre>\n\nIt is suggested that you not include dependencies on any files referred to using an absolute path as they tend to be system files and will make your makefile potentially non portable.\n\nIf you need -I flags, just add them as options to the compiler when running it through your script.', 'title': u'Better off running code through cpp.'}], 'desc': u'This script scans .c files for "#include" statements and creates a list of\ndependencies, suitable for inclusion in a makefile. Name this script "mkdep"\nand then type "mkdep *.c"; dependencies will come out standard output.\n'}, {'comments': [], 'desc': u"Once in a while it becomes necessary to globally change the behaviour of classes in a third party library. This code demonstrates the ability to modify the __init__ method of an arbitrary class in-place. It's also good for making functional programmers wince, which can be entertaining :-)"}, {'comments': [{'comment': u'This script is nice, except that it doesn\'t set the To and From headers which will make some MUA\'s (Thunderbird for example) show "undisclosed recipients" in the To field. The fix is simple, just pass the sender and recipient to the createhtmlmail() function and add the following two lines to that function:\n\n<pre>\n writer.addheader("From", sender)\n writer.addheader("To", recipient)\n</pre>', 'title': u'Needs to send To and From headers'}, {'comment': u'The script is great, but I also need to embed images with the IMG tag into the body of my HTML messages. How do I ensure that they come with them message and are displayed in the correct IMG placeholders? I do not want to rely on an image linked to a file sitting on a server, but carried with the message? ', 'title': u'How do you add images to HTML Messages?'}, {'comment': u'See this recipie: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473810', 'title': u'HTML with images, too'}], 'desc': u"After wrestling and wrestling with Outlook 2000 to turn *off* HTML mail, I had to figure out how to send HTML from Python for a recent project. Oh the irony, the irony.\n\nIt's good policy (and trivially easy) to embed two versions of your message if you're planning on sending HTML mail: the HTML version, and a text-only version. Lots of folks still prefer their character-mode MUAs (viva Mutt!) so don't go alienating them by sending them something that they can't read.\n\nThe e-mails generated by this code have been tested on and render correctly with Outlook 2000, Eudora 4.2, Hotmail, and Netscape Mail. It's likely that they will work in other HTML-capable MUAs as well.\n"}, {'comments': [{'comment': u"Would this not be more efficient if it were implemented as a callable class? <br><br>That way, you wouldn't have to re-build the re.compile() object each time you call the function.</br></br>", 'title': u'Efficiency...'}, {'comment': u'I don\'t know why the code won\'t print out here. --------\r<br>\r<br>\r\r\r\n\r\r\r\r\r\n\r\r\r\r\r\n#!/usr/bin/env python\r\r\r<br>\r<br>\r\r\r\n\r\r\r\r\r\r\r\nimport re\r<br>\r\r\r<br>\r\r\r\n\r\r\r\r\r\r\r\nclass Is_A_Number :\r\r\r<br>\r\r\r\r\n """This function/object determines if its argument, accused, is in the \r\r\r<br>\r\r\r\r\n format of a number. It can be number can be in integer, floating point, \r\r\r<br>\r\r\r\r\n scientific, or engineering format. The function returns \'1\' if the argument \r\r\r<br>\r\r\r\r\n is formattted like a number, and \'0\' otherwise."""\r\r\r\r\r\r\r\n\r\r\r<br>\r\r\r\r<br>\n num_re = re.compile(r\'^[-+]?([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE][-+]?[0-9]+)?$\')\r\r\r<br>\r\r<br>\r\r\n\r\r\r\r\r\r\r\n def __call__ (self, accused) :\r\r\r<br>\r\r\r\r\n return str(re.match(self.num_re, accused))) != \'None\'\r\r\r<br>\r\r\r\r\n# End of the class <br>\r\n\r\r\r\r<br>\r\r\r\nis_a_number = Is_A_Number()\r\r\r<br>\r\r\r\r\n\r\r\r\r\r\r\n\r\r\r\r\r\r\n</br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br>', 'title': u'Here is the sample code...'}], 'desc': u'The present recipe shows a function to check whether or not its argument is consistent with standard numerical formats: integer, floating point, scientific, or engineering.\n'}, {'comments': [], 'desc': u'How do you sort efficiently a list of (x, y) coordinates? Now generalize that to a list of (dictionaries, or lists, or classes). I HATE not being able to sort via any attribute, so I wrote a class-function to do it for me.'}, {'comments': [{'comment': u'I like it more complicated :-)\nThe following class allows you to use enums as like\ncolors.red, to convert like colors["red"], get the string value\nlike someColor.asString and some other\nnifty things. Of course, the overhead is higher.\n\nHere it is ...\n\n<pre>\n# This library is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nclass Enum emulates Enumerations.\n\nEnum instances contain _EnumNodes. These have two attributes:\nasString and asInt.\n\nCreate one with\n\n Enum(list,*startvalue)\nor: Enum(string,*startvalue) (default for startvalue is 0)\n\ne.g.:\n\nWD = Enum(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], 1)\nWD = Enum["Monday Tuesday Wednesday Thursday Friday Saturday Sunday", 1]\n\nTypical use:\n\nworkdays = WD.irange(WD.Monday,WD.Friday) # inclusive ranges are better\n # for Enums, hence "irange"\n # equivalent: workdays = WD[1:6]\nfor i in WD.each():\n if i in workdays:\n print i.asInt, i.asString + " is a work day"\n else:\n print i.asInt, i.asString + " is a weekend day."\nprint "There are ", len(WD), "days per week"\nif "Monday" in WD: print "Monday is a valid name"\nif not "August" in WD: print "August is not"\n\nsome systematic examples:\n\nWD.Monday.asString --> \'Monday\'\nWD.Monday.asInt --> 1\nWD.stringToInt(\'Monday\') --> 1\nWD[2].asString --> \'Tuesday\'\nWD.intToString(2) --> \'Tuesday\'\nWD["Tuesday"].asInt --> 2\nWD.Saturday > WD.Tuesday --> 1\n"Monday" in WD --> 1\n6 in WD --> 1\n0 in WD --> 0\nWD.each() gives you a list of all EnumNodes.\nWD.eachString() --> find out by yourself!\n\nNote: You cannot create EnumNodes other than creating an Enum.\n The EnumNode class is considered private.\n Never not try to change attributes of these objects.\n\n"""\n\n################################################################\n\nimport types\n\nclass _EnumNode:\n def __init__(self,i,name):\n self.asInt=i\n self.asString=name\n\n def __cmp__(left,right):\n return cmp(left.asInt, right.asInt)\n\n def __str__(self):\n return self.asString\n\n def __repr__(self):\n return "("+str(self.asInt)+":"+self.asString+")"\n\n def __hash__(self):\n return self.asInt\n\nclass Enum:\n def __init__(self,stringList,start=0):\n if type(stringList)==types.StringType:\n stringList = stringList.split()\n self._start = start\n self._byString = {}\n self._byInt = [ None ] * (start + len(stringList))\n for i in range(len(stringList)):\n node = _EnumNode(i+start,stringList[i])\n self._byInt[i+start] = node\n self._byString[node.asString] = node\n\n def addAlternate(self,node,aString):\n self._byString[aString] = node\n\n def intToString(self,num):\n return self._byInt[num].asString\n\n def stringToInt(self,name):\n node = self._byString.get(name,None)\n if node: return node.asInt\n else: return None\n\n def __contains__(self,key):\n if type(key)==types.IntType:\n return key >= self._start and key < len(self._byInt)\n else:\n return self._byString.has_key(key)\n\n def __getattr__(self,name):\n return self._byString[name]\n\n def __len__(self):\n return len(self._byInt) - self._start\n\n def __getitem__(self,key):\n if type(key)==types.IntType:\n return self._byInt[key]\n elif type(key)==types.SliceType:\n return self._byInt[max(self._start,key.start):key.stop]\n else:\n return self._byString[key]\n\n def __repr__(self):\n return str(self._byInt[self._start:])\n\n def irange(self, start=None, stop=None, step=1):\n if start:\n startInt = start.asInt\n else:\n startInt = se', 'title': u'A different approach'}, {'comment': u"On 2001/08/29 Michael Radziej wrote:<br>\n> I like it more complicated :-)<br>\n<br>\nThat's fine, as long as the code isn't broken and is complete, which does not seem to be the case in what was posted. Specifically there was a crucial line missing from Enum.__init__(), the cleverness in the if in Enum.__contains__() messed up when the default start values was used, and a number other methods need for the examples were missing.<br>\n<br>\nBelow is a complete and functional version that was tested with Python 2.4. There are comments for most of the changes made.<br>\n<br>\nAdditional observations: The list contained in the _byInt attribute could be quite long if the starting integer value is is a big number. Also, some of the methods are fairly inefficient in those circumstances.<br>\n<br>\n<pre>\n# This library is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"""\nclass Enum emulates Enumerations.\n\nEnum instances contain _EnumNodes. These have two attributes:\nasString and asInt.\n\nCreate one with\n\n Enum(list,*startvalue)\nor: Enum(string,*startvalue) (default for startvalue is 0)\n\ne.g.:\n\nWD = Enum(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], 1)\nWD = Enum["Monday Tuesday Wednesday Thursday Friday Saturday Sunday", 1]\n\nTypical use:\n\nworkdays = WD.irange(WD.Monday,WD.Friday) # inclusive ranges are better\n # for Enums, hence "irange"\n # equivalent: workdays = WD[1:6]\nfor i in WD.each():\n if i in workdays:\n print i.asInt, i.asString + " is a work day"\n else:\n print i.asInt, i.asString + " is a weekend day."\nprint "There are ", len(WD), "days per week"\nif "Monday" in WD: print "Monday is a valid name"\nif not "August" in WD: print "August is not"\n\nsome systematic examples:\n\nWD.Monday.asString --> 'Monday'\nWD.Monday.asInt --> 1\nWD.stringToInt('Monday') --> 1\nWD[2].asString --> 'Tuesday'\nWD.intToString(2) --> 'Tuesday'\nWD["Tuesday"].asInt --> 2\nWD.Saturday > WD.Tuesday --> 1\n"Monday" in WD --> 1\n6 in WD --> 1\n0 in WD --> 0\nWD.each() gives you a list of all EnumNodes.\nWD.eachString() --> find out by yourself!\n\nNote: You cannot create EnumNodes other than creating an Enum.\n The EnumNode class is considered private.\n Never not try to change attributes of these objects.\n\n"""\n\n################################################################\n\nimport types\n\nclass _EnumNode:\n def __init__(self,i,name):\n self.asInt=i\n self.asString=name\n\n def __cmp__(left,right):\n return cmp(left.asInt, right.asInt)\n\n def __str__(self):\n return self.asString\n\n def __repr__(self):\n return "("+str(self.asInt)+":"+self.asString+")"\n\n def __hash__(self):\n return self.asInt\n\nclass Enum:\n def __init__(self,stringList,start=0):\n if type(stringList)==types.StringType:\n stringList = stringList.split()\n self._start = start\n self._byString = {}\n self._byInt = [ None ] * (start + len(stringList))\n for i in range(len(stringList)):\n node = _EnumNode(i+start,stringList[i])\n setattr(self, stringList[i], node)\n self._byInt[i+start] = node\n self._byString[node.asString] = node\n\n def addAlternate(self,node,aString): # note: doesn't update '_byInt'\n self._byString[aString] = node\n\n def intToString(self,num):\n return self._byInt[num].asString\n\n def stringToInt(self,name):\n node = self._byString.get(name,No", 'title': u'Re: A different approach'}, {'comment': u'This fixes a minor bug that would have become apparent if my test case had used specified values that might have collided with the normal numbering (e.g. 4 for Volkswagen.THING instead of 400).\n\n<pre>class Enumeration:\n def __init__(self, name, enumList):\n self.__doc__ = name\n lookup = { }\n reverseLookup = { }\n uniqueNames = [ ]\n self._uniqueValues = uniqueValues = [ ]\n self._uniqueId = 0\n for x in enumList:\n if type(x) == types.TupleType:\n x, i = x\n if type(x) != types.StringType:\n raise EnumException, "enum name is not a string: " + x\n if type(i) != types.IntType:\n raise EnumException, "enum value is not an integer: " + i\n if x in uniqueNames:\n raise EnumException, "enum name is not unique: " + x\n if i in uniqueValues:\n raise EnumException, "enum value is not unique for " + x\n uniqueNames.append(x)\n uniqueValues.append(i)\n lookup[x] = i\n reverseLookup[i] = x\n for x in enumList:\n if type(x) != types.TupleType:\n if type(x) != types.StringType:\n raise EnumException, "enum name is not a string: " + x\n if x in uniqueNames:\n raise EnumException, "enum name is not unique: " + x\n uniqueNames.append(x)\n i = self.generateUniqueId()\n uniqueValues.append(i)\n lookup[x] = i\n reverseLookup[i] = x\n self.lookup = lookup\n self.reverseLookup = reverseLookup\n def generateUniqueId(self):\n while self._uniqueId in self._uniqueValues:\n self._uniqueId += 1\n n = self._uniqueId\n self._uniqueId += 1\n return n\n def __getattr__(self, attr):\n if not self.lookup.has_key(attr):\n raise AttributeError\n return self.lookup[attr]\n def whatis(self, value):\n return self.reverseLookup[value]</pre>', 'title': u'Specified values should be considered before unspecified'}], 'desc': u"I once tried to give Python something like C's enums, as described\nhere: http://groups.google.com/groups?selm=G6qzLy.6Fo%40world.std.com\nThat approach tried to assign to a dictionary returned by the locals()\nfunction, intending that such assignments would become class attributes.\nThe Tim-bot explained to me the errors of my ways. The quest for the\nperfect Python enum goes on.\n"}, {'comments': [{'comment': u'Good stuff! I tried it out. It helped me understand the reference counting in Python.\n\n--Alex.', 'title': u'works for Python 2.2'}], 'desc': u'When developing C extensions and running into memory problems, I find\nthe typical problem is mismanagement of reference\ncounts, particularly abuses of Py_INCREF and Py_DECREF, as well as\nforgetfulness of the refcount effects of functions like Py_BuildValue,\nPyArg_ParseTuple, PyTuple/List_SetItem/GetItem, etc. The\n1.5.2 source codebase offers some help with this (search for\nPy_TRACE_REFS) but I found it useful to add this function in\nObjects/object.c, just before _Py_PrintReferences.\n\nUnlike _Py_PrintReferences, this function will print only the total of\nall the refcounts in the system, so it can be used safely in loops that\nwill repeat millions of times, where_Py_PrintReferences would print out way too\nmuch stuff to be useful. This can help you to identify errantly wandering\nPy_INCREFs and Py_DECREFs.'}, {'comments': [], 'desc': u'A script can use this code to determine whether another instance of itself is already in execution. 32-bit MSW only.'}, {'comments': [{'comment': u'This function can be improved to handle larger factorials by changing the code to use long integers:\n<br>\n<pre>\nf = lambda n:n-1 + abs(n-1) and f(n-1)*long(n) or 1\n</pre>', 'title': u'Larger Factorials'}, {'comment': u'Just do the following:\n<br>f = lambda n: n and f(n-1)*long(n) or 1', 'title': u'No need for the complexity...'}, {'comment': u"This doesn't handle negative values. =)\n<br>-- gently inserting foot into mouth...", 'title': u'Ignore this...'}, {'comment': u'I want to point that the third formula is a functional solution (non recursive). A more concise formula:<br>\n<pre>\nfac=lambda n: [1,0][n>0] or reduce(lambda x,y: x*y, xrange(1,n+1))\n</pre>', 'title': u'functional solution'}, {'comment': u'Or better:<br>\n<pre>\nf=lambda n: n<=0 or reduce(lambda a,b: a*b,xrange(1,n+1))\n</pre>', 'title': u'functional solution'}, {'comment': u"Trying to get the factorial of 20 causes an overflow.<br>\n<pre>lambda n: n<=0 or reduce(lambda a,b: a*b,xrange(1,n+1))\nOverflowError: integer multiplication\n\nI've amended the function to handle this.\n\nlambda n: n<=0 or reduce(lambda a,b: long(a)*long(b),xrange(1,n+1))</pre>\n\n", 'title': u'Requires long conversions'}, {'comment': u'<pre>\n>>> f= lambda n: [[[j for j in (j*i,)][0] for i in range(2,n+1)][-1] for j in (1,)][0]\n>>> f(5)\n120\n\nIf I were going to use reduce which might be removed from python I would<br>use it with the operator mul. Long ints are automatic in Python 2.4.\n\n>>> from operator import mul\n>>> f= lambda n: reduce(mul,range(2,n+1))\n>>> f(6)\n720\n\nAssuming no one would want or need the factorial of anything less than 2.</pre>', 'title': u'A one-line numeric function using list comprehensions'}, {'comment': u'Steven Bethard pointed out in recipe 436482 that<pre>\n\nf= lambda n: [j for j in [1] for i in range(2,n+1) for j in [j*i]] [-1]\n\nis equivalent but easier to read, write and use.</pre>', 'title': u'A better list comprehension expression'}], 'desc': u'One Liner Factorial function \nThis code gets factorial of a number and for negative numbers returns 1\n'}, {'comments': [], 'desc': u"Dummy classes can be used to create dummy instances of class\nwhich we can't create currently!"}, {'comments': [], 'desc': u'This function takes a list and pulls it apart into a user-defined number of pieces. It acts like a sort of reverse zip function (although it deals with only the very simplest cases).'}, {'comments': [{'comment': u'How about making it slightly more interesting?\n\n<pre>\ndef decode(*arguments):\n """Use the first argument to select one of the subsequent item.\n\n First argument is any value. Subsequent argument must be sequence\n type with minimum of 2 items. One of the subsequent argument will\n be selected when its first item is equal to the first argument.\n The second and subsequent item in the selected argument will \n be returned.\n\n """\n if len(arguments) < 2:\n raise TypeError, \'decode() takes at least 2 arguments (%d given)\' % (len(arguments))\n arg = arguments[0]\n for item in arguments[1:]:\n if arg == item[0]: return item[1:]\n\n\n\n# Example\nprint decode(\'b\', (\'a\', 1), (\'b\', 2))\nprint decode(\'a\', \'aGood Morning\', \'pGood Evening\')\n\nvar=\'list\'\nprint decode(var, [\'tuple\', ()], [\'dict\', {}], [\'list\', []], [\'string\', \'\'])\n</pre>', 'title': u'A bit more pythonic.'}, {'comment': u'As my pre-poster suggested:\n\n<pre>\ndef decode(sel, *seq):\n for s in seq:\n if sel == s[0]:\n return s[1:]\n break\n\ndef ternary(cond, a, b):\n """If `cond` evaluates to True, return `a`, otherwise `b`."""\n\n return decode(cond, (True, a), (False, b))[0]\n</pre>', 'title': u'decode.py'}], 'desc': u'This simple code act like conditional operator "?:" (or ternary) operator,\nwhich operates as in C and many other languages, but more readable.\n\nSimilar to Oracle\'s decode function but can return any value :-)'}, {'comments': [{'comment': u'Trying ``fib(10)`` on the first version returns 89. But the same Fibonacci number for the second returns 144.\n\nAlso seems off since the second Fibonacci number is 2 when it is supposed to be 1. Seems to lead to the correct value being in the argument + 1.', 'title': u'Differing results'}], 'desc': u'One Liner fibonacci series generator'}, {'comments': [{'comment': u'Maybe you could include an example of how this works?', 'title': u'Example'}], 'desc': u'This is my attempt at extracting the file version information\nfrom .dll, .exe, .ocx files etc. on Windows 2000 \n(should work with others, but I haven\'t tested it), \nwithout resorting to using extensions (i.e. dll functions). \n\nIt is "Pure Python"... but unfortunately is not \ndocumented very well. Please let me know if it helps you! \n\nPut the code in a file in your PYTHONPATH (such as \'verchecker.py\')\nand say \'from verchecker import *\'. You may then get version \ninfo by executing: calcversioninfo(\'path/filename\')\n\n-Joshua W. Biagio -- jw_SPAM_biagio@juno.com (remove _spam_)\n\n'}, {'comments': [], 'desc': u"The ActiveState Python distribution includes an example that shows how to get and set MSW shortcuts. This code shows how to extend the example to decode the hotkeys (such as 'Alt-Ctrl-Z' and 'Shift-Ctrl-B' that can be associated with shortcuts."}, {'comments': [], 'desc': u"This class provides objects that can be sorted by multiple keys, with each key independently ascending or descending. The class is designed to replicate the functionality of the SQL 'ORDER BY' clause."}, {'comments': [{'comment': u'try this:\r\n<pre>\r\n>>>x=Null()\r\n>>>dir(x)\r\n</pre>\r\n:-)\r\n<br><br>\n-=jbk=-\r\n<br>\r\njbk@checkit.cz', 'title': u'a small TODO for you'}, {'comment': u"IMHO the '__str__' method should rather return an empty string.\nAt least that's what I'd expect of 'do nothing'.", 'title': u'str(Null())'}, {'comment': u'This allows you to test if you have a real "live" reference. Or not. For example, you may have a reference to a Customer object, but you want to do something if you have a real customer and skip that processing if you have a Null. Additionally, testing the reference, through a \'not\' or an \'if\' throws a TypeError if you DON\'T have the __nonzero__.<br>\n<pre>def __nonzero__(self) : \n return False\n<br>\nAdded this code to the test suite.\n<br>\ndef test():\n<br>\n "Perform some decent tests, or rather: demos."\n<br>\n....\n<br>\nassert(not n, "n should return False. i.e. I would expect same behavior as testing an empty list or string")\n<br></pre>', 'title': u'Another, perhaps useful addition...'}], 'desc': u'Null objects are intended to provide first-class citizens as \na replacement for the primitive value None. Using them you \ncan avoid conditional statements in your code and express\nalgorithms with less checking for special values.\n'}, {'comments': [], 'desc': u'Uses ssh to gather patch information on two solaris boxes. It prints out the differences in patches of the two computers.'}, {'comments': [{'comment': u'Since reduce() is probably going away sometime soon, using a list comprehension or generator expression is a better way to do this in future Python:\n\n<pre>from random import randrange\n\ndef dice(num, sides):\n return sum(randrange(sides)+1 for die in range(num))\n</pre>\n\nWhich is also more straightforward, come to think of it.', 'title': u'Getting rid of reduce'}, {'comment': u'The inner most (furthest left) comprehension is an accumulator.<br>The furthest right, an initializer.<br>The result is a triply nested list so the stuff at the end is there to<br>get only the final single digit result.<pre>\n\n>>> dice=lambda s,n: [[[j for j in (j+randrange(s)+1,)] for die in range(n)] for j in (0,)] [0][-1][0]</pre>', 'title': u'A list comprehension version'}], 'desc': u'A simple function to permit you to generate random numbers by emulating a dice roll. The number of dice and the number of sides to each die are the parameters of the function. In order to (for example) roll 4d6, you would call dice( 4, 6 ).'}, {'comments': [], 'desc': u'The goal of this recipe is to help the use of classes that need a great number of options in constructor for configuration. '}, {'comments': [{'comment': u"I've always liked the idea of ring buffers (bounded queues, or whatever people choose to call them). But the inefficiency of testing if the ring is full, and if so doing something different, is a nuisance, especially in a language like Python where there's no difficulty in allowing the list to grow without bound - other than the massive memory cost involved!!!<br>\n<br>\nThe idea of assigning to __class__ to switch behaviours when the ring gets full is a very nice one - it's a one-off operation, so it doesn't make the steady-state case less efficient.<br>\n<br>\nPresumably, you could define the helper class (for the bounded case) inside the main class, which makes it more obvious that it isn't meant for general use.", 'title': u'I like the technique of assigning to __class__'}, {'comment': u'I guess you could define two methods, _full_get and _full_append, and instead of reassigning self.__class__, reassign like this:\n<br>\n<pre>\n self.append=self._full_append\n self.get=self._full_get\n</pre>\n<br>\nI think this will still work with new style Python 2.2 classes.', 'title': u'Perhaps reassign methods rather than reassign __class__'}], 'desc': u"A ring buffer is a buffer with a fixed size. When it fills up, adding another element overwrites the first. It's particularly useful for the storage of log information. There is no direct support in Python for this kind of structure but it's easy to construct one.\n\nHere is a suggestion of implementation optimized for element insertion. "}, {'comments': [{'comment': u'\'Xcuse me, but which "dictionary" class are you subclassing? My Python interpreter doesn\'t come with any dictionary class...?', 'title': u'Which "dictionary"?'}, {'comment': u'I\'m subclassing the class used for native dictionaries. I\'m new to Python, \nso this may not be as clear (or as accurate) as I would like.<br>\n\nAs I understand it, in Python, everything is an object. In particular, the "built-in"\ndata types, such as dictionaries, are objects too. This means that they have classes. I believe that I have\nseen specific references to the classes for native objects, but I could not find them\nwhen I wrote this, so I tried the simplest thing and inserted "dictionary" as the \nsuperclass.<br>\n\nThe script ran, so I first tested it and then posted it.\n\nI would be pleased if someone with more knowledge would correct, extend, amend, \nor generally improve on this explanation.</br></br>', 'title': u'Which dictionary...'}, {'comment': u'You can subclass the built-in types in Python 2.2, not in 2.1 or earlier.', 'title': u'Subclassing built-in types'}, {'comment': u"Substituting UserDict.UserDict for dictionary solves the problem with the missing dictionary class, but the RaggedArray2D class needs minor rewriting to make it work.<br><br>I've tried it now, it's need. Thanks for the inspiration.</br></br>", 'title': u'The UserDict class might solve the problem'}, {'comment': u's/need/neat/', 'title': u'Oops'}], 'desc': u'This class implements a two-dimensional ragged array using nested dictionaries. \n\nAs written this class requires Python 2.2 or later. This meets my requirements, but it may not\nmeet yours.\n\nKlaus Alexander Seistrup has described a way to get around this restriction by substituting \n"UserDict.UserDict" for "dictionary" as the base class. I believe this solves the problem \nfor Python versions at least as far back as 1.5.2. This approach will require some editing of\nthe insertion and retrieval functions to make it work. \n\nThanks Klaus!'}, {'comments': [], 'desc': u'Priority queues are a kind of container that allows specification of the relative order of the data.'}, {'comments': [{'comment': u'If you steal Lisp\'s concept of "cons cells", you can achieve the same sort of result using nested tuples. Effectively, you implement the FIFO [1, 2, 3] (where 1 is the first item you\'ll pop) as (1, (2, (3, ()))).<br>\n\nHere\'s how:<br>\n<pre>\nclass Fifo:\n def __init__(self):\n self.fifo = ()\n def append(self, data):\n self.fifo = (data, self.fifo)\n def pop(self, n):\n # Use tuple unpacking - popping an empty FIFO will\n # raise a ValueError, which is OK\n ret, self.fifo = self.fifo\n return ret\n</pre>\n\nThis is more compact than your list representation (tuples take up less space than lists) as well as being faster (tuple unpacking is a fast operation). Of course, it\'s also more obscure unless you\'re a Lisp hacker :-)', 'title': u'You can do this more efficiently using nested tuples'}, {'comment': u"The author doesn't give himself enough credit.\nThe built-in operations are faster only for\nshort lists. His code runs in O(n) time which\nalways wins in the longer run.\n\nHere is a tighter version of the above code.\n\n<pre>\nclass Fifo:\n stored = [None]\n stored[0] = stored\n def append(self,data): # to inside\n if len(self.stored) == 1:\n return self.stored.append(data)\n self.stored[0] = self.stored = [self.stored[0], data]\n def pop(self): # from outside\n whole = self.stored[0]\n self.stored[0] = whole[0]\n return whole[1]\n</pre>", 'title': u'Tighter version'}, {'comment': u"There was a news group discussion on the fastest FIFO implementation:\n<pre>http://groups.google.com/groups?th=e79e99edc138cb02 </pre>\n\nTwo O(n) approaches were found, the nested list approach\nshown above and a dictionary based approach from Alex\nMartelli. The dictionary approach beat nested list by about 30%. Space consumption was not measured -- S\xe9bastien Keim's nested list approach may use less memory per queue element.\nBoth approaches kept their O(n) characteristics in tests upto 300,000 queued elements. Here is the winning source code:\n\n<pre>\nclass Fifo:\n 'Fastest implementation of FIFO queues'\n def __init__(self):\n self.nextin = 0\n self.nextout = 0\n self.data = {}\n def append(self, value):\n self.data[self.nextin] = value\n self.nextin += 1\n def pop(self, n=-1):\n value = self.data[self.nextout]\n del self.data[self.nextout]\n self.nextout += 1\n return value\n</pre>\n\nThree slower approaches were also found. Each had performance that degraded to worse than O(n^2) for large test sets. The approaches were prepending to lists, appending to lists, and using array.array('i') which only works for storing integers. Not only were these appoaches slower, but they all took a major performance hit when there were more than 65,536 items in the queue (apparently having long\nintegers as indices will more than double the lookup times).\n<br>\n<br>\nFor Python 2.2 users, variations were tried which sub-classed from built-in types. Revising Alex's code to inherit from a dictionary slowed his code by about 30%. Revising the list based approaches to inherit from built-in lists resulted in a 2% performance gain.", 'title': u'Fastest FIFO'}, {'comment': u' ', 'title': u'This is a stack, not a FIFO queue'}, {'comment': u'This is not quite equivalent to the original class: it does not raise an exception if there are more pops then appends.', 'title': u'No exception raised'}, {'comment': u"Here's a version that's (by my tests) even faster than the dict method. It uses a design well-known in the functional programming world for making FIFO queues with singly linked lists.\n<br><br>\nWith this method, keeping a FIFO queue requires two lists. The basic idea is that one list is the front of the queue and the other is the back. Enqueuing an element simply appends that element to the back list. Dequeuing an element pops from the end of the front list. If the front list is empty, then the front list is set to the reversed back list and the back list is reset to be empty. Thus the queue is amortized O(1) time, since one O(N) operation is required per N operations total.\n<br><br>\nHere's the code. Instead of maintaining two separate lists, it subclasses list and thus itself is the front list; the back list is kept as an attribute. It's slightly faster this way than it is keeping separate lists.\n<br><br>\n<pre>\nclass ListSubclassFifo(list):\n __slots__ = ('back',)\n def __init__(self):\n self.back = []\n def enqueue(self, elt):\n self.back.append(elt)\n def dequeue(self):\n if self:\n return self.pop()\n else:\n self.back.reverse()\n self[:] = self.back\n self.back = []\n return self.pop()\n</pre>", 'title': u'An even faster FIFO queue.'}, {'comment': u"I find your solution very pythonic. I have explored an implementation which should be a little faster since it avoid one copy:\n<pre>\nclass Fifo(object):\n __slots__ = ('data',)\n def __init__(self):\n self.data = [[], []]\n def append(self, value):\n self.data[1].append(value)\n def pop(self,n=-1):\n d = self.data\n if not d[0]:\n d.reverse()\n d[0].reverse()\n return d[0].pop()\n</pre>", 'title': u'Very nice'}], 'desc': u'Fifo mean "First In First Out". This is a kind of container, which only allow element insertion and removal and where the first element inserted is the first element removed.'}, {'comments': [], 'desc': u'Yet another attempt to deal with Interface concept in Python'}, {'comments': [], 'desc': u"This script checks if command-line argument 'n' has been passed; if not, it sets\nit to the user-defined default value."}, {'comments': [{'comment': u'The last half of this code module has been cut off from the display. I am sorry for this. I did not know the interface would do this when actually posting the code.\n\t\t\t\t-- Alan Eldridge, author of xgetopt.py', 'title': u'The latter half of this code is missing.'}, {'comment': u'1. You must get the source using the "Text Source" link near the top of the listing. It contains the full source code.\n<br>\n2. You must get the source code for word_wrap.py, also posted to the Python Cookbook. ', 'title': u'In order to use xgetopt.py'}, {'comment': u'<pre>\n#!/usr/bin/env python\n\nimport os\nimport sys\nimport string\n\nimport xgetopt\n\nAPPNAME = sys.argv[0].split(os.sep)[-1]\n\n######################################################################\n# comand line parser\n######################################################################\n\nG_opt = {}\nG_optparser = xgetopt.parser()\n\nG_optparser.set_app(APPNAME)\nG_optparser.set_args(\'filename [...]\')\n\nG_optparser.add_opt(\'-v\', \'--verbose\', None, \'v\',\n "verbose messages")\nG_optparser.add_opt(\'-h\', \'--help\', None, \'help\',\n \'display this help message\')\nG_optparser.add_opt(\'-f\', \'--force\', None, \'force\',\n "don\'t ask before overwriting files")\nG_optparser.add_opt(\'-l\', \'--lang\', \'language\', \'lang\',\n \'specify source language for output file\')\nG_optparser.add_opt(\'-d\', \'--dir\', \'conf-dir\', \'conf-dir\',\n \'configuration and skeleton-file directory\')\nG_optparser.add_opt(\'-a\', \'--author\', \'author\', \'author\',\n \'author\\\'s name\')\nG_optparser.add_opt(\'-e\', \'--email\', \'email-address\', \'email\',\n \'author\\\'s email address\')\nG_optparser.add_opt(\'-L\', \'--license\', \'license-dir\', \'license\',\n \'use this license/copyright type\')\nprint G_optparser.add_opt(\'-z\', \'--desc\', \'text\', \'desc\',\n \'summary text [used in RPM spec files]\')\n\n######################################################################\n# set built-in defaults\n######################################################################\n\n# skel dir => ~/.$APPNAME.d\nG_opt[\'conf-dir\'] = os.environ[\'HOME\'] + os.sep + \'.\' + APPNAME + \'.d\'\n\n######################################################################\n# now get our setup\n######################################################################\n\ntry:\n opts, args, G_opt = G_optparser.getopt(sys.argv[1:], G_opt)\nexcept:\n G_optparser.usage(1)\n\nprint \'Options given:\\n\'\n\nfor key in G_opt.keys():\n print key, G_opt[key]\n\nif G_opt[\'help\'] is not None:\n print\n G_optparser.usage(0)\n\n\n#\n#EOF\n##\n</pre>', 'title': u'EXAMPLE OF USE'}, {'comment': u'Hi,\n\n I quite like your xgetopts, but long options were not wroking. The fix is:\n<br>\n1. In method add_opt() line 94 change to:<br>\n<pre>\nself.__l.append(long[2:]) # in order to remove leading hypens --\n</pre>\n<br>\n2. In method getopt() line 137 change to:<br>\n<pre>\nself.__l # geoopt.getopt expect list of strings\n # not a single string\n</pre>\n<p>\nCheers', 'title': u'2 bugs prevent from using long options, fix included...'}], 'desc': u'The getopt module, like GNU getopt/getopt_long, separates short and long options, and makes no way to coordinate options with usage messages. This leads to an opportunity for usage info and the actual options to diverge, and makes it harder to see, at a glance, what short and long options correspond to one another. It also leaves handling of preset or default options up to ad-hoc solutions, often the same or similar code implemented time and time again. Xgetopt addresses all of these concerns in a simple, easy to use module.This code requires my word_wrap.py module, which is also posted to the Python Cookbook following this module.'}, {'comments': [], 'desc': u'Word_wrap.py provides a simple, brute-force, solution to word-wrapping text to a given width. It was invented for the use by my xgetopt module.'}, {'comments': [], 'desc': u"If you feel that the global directive don't fit Python language. Here is a short class for your aesthetic sensibility. "}, {'comments': [{'comment': u'An alternative is to write a Python extension to call the InternetGetCookie API in WININET.DLL. Search MSDN for info on this API.\n\nThe InternetGetCookie function returns all of the cookies that the browser will send in a request for a given URL.\n\n', 'title': u'WININET InternetGetCookie API'}], 'desc': u'This script looks through your IE Cookies and returns a value of the chosen cookie'}, {'comments': [{'comment': u'Cute! Here is a useful function version.\n<pre>\ndef Plural(num=0, text=\'\'):\n\treturn "%d %s%s" % (num, text, "s"[num==1:])\n</pre>', 'title': u'function version'}], 'desc': u'Sometimes it\'s useful to print singular or plural versions of a word, depending on the value of the number of items that the word is describing: for example, "0 files", "1 file", "2 files" (note that "file" is used in the case of 1; "files" otherwise). This idiom does this inline, as a single expression.'}, {'comments': [{'comment': u'<pre>\nclass _meta_enum (type) :\n def __init__ (cls, name, bases, di) :\n vdict = {}\n for v in di.itervalues() :\n vdict[v] = 1\n max = 0\n for k,v in di.iteritems() :\n if v == None :\n while 1 :\n if not vdict.has_key(max) :\n setattr(cls, k, max)\n vdict[max] = 1\n max += 1\n break\n max += 1\n else :\n vdict[v] = 1\n return cls\n\n# Empty enum\nclass enum :\n __metaclass__ = _meta_enum\n\n\n# Test class\nclass myenum (enum) :\n foo = None\n bar = 0\n\n\nprint myenum.foo # prints 1\nprint myenum.bar # prints 2\n</pre>\n\nThe _meta_enum.__init__ needs check uniqueness of values and\nshould acquire inherited values from eventual parent classes!', 'title': u'Simple solution with python2.2 __metaclass__'}], 'desc': u"Will Ware posted some enum code [ http://groups.google.com/groups?hl=en&newwindow=1&selm=GIJJzq.Jx1%40world.std.com ] a while ago, which I started playing with. I am now using a modified version mainly for error numbers instead of an Error class. It's just very nice not to worry about values. "}, {'comments': [{'comment': u"There's a standard Python library for binary searches, 'bisect.' Tim Peters once called this the best underused Python module.\n<br><br>\n\n>>> import bisect<br>\n>>> bisect.bisect_right([1, 5, 9, 12, 18, 35], 5)<br>\n2<br>\n>>> bisect.bisect_left([1, 5, 9, 12, 18, 35], 5)<br>\n1<br>\n>>> bisect.bisect_left([1, 5, 9, 12, 18, 35], 15)<br>\n4<br>\n>>><br>", 'title': u'available in a standard python module'}], 'desc': u'A straightforward implementation of the binary search algorithm.'}, {'comments': [{'comment': u'In the following line:\n<pre>\n rls = [len(row[col]) for row in data if row[col]] \n</pre>\nin case of a NUMBER column, you get a TypeError in len() function.', 'title': u'TypeError in case of NUMBER'}, {'comment': u"As you can see, I've now changed that line to read\n<pre>\n rls = [len(str(row[col])) for row in data if row[col]]\n</pre>\nwhich should avoid the error.\n\n", 'title': u'Thanks, Farhad'}, {'comment': u"According to standard dbapi2, this it's the cursor description :\n\n .description \n \n This read-only attribute is a sequence of 7-item\n sequences. Each of these sequences contains information\n describing one result column: (name, type_code,\n display_size, internal_size, precision, scale,\n null_ok). The first two items (name and type_code) are\n mandatory, the other five are optional and must be set to\n None if meaningfull values are not provided.\n\n For this reason i belive that in the line where you write:\n for dd in d: # iterate over description\n l = dd[1]\n\n Must be:\n for dd in d: # iterate over description\n l = dd[2]\n\n \n Rosendo Martinez.\n", 'title': u'Cursor Description'}, {'comment': u'Thanks for the example. Reading through the code I noticed\nthat if you do not set the data argument in the calling\ncode then the value of data is left as a None object\nand results in problems in the statement after if rowlens:\n\nSimple fix,\n\nif not data:\n data = cursor.fetchall()', 'title': u'Bug if data argument is not set'}, {'comment': u'<pre>Hi - \n\nNot sure if anyone ran into this or not. I\'ve just acquired a copy\nof SQLite, and wanted to try out the "pretty" version for printing\ncolumns w/ rowlens=1. When I ran it, I got:\n\n-> TypeError: not enough arguments for format string\n\nAfter some debugging, I think SQLite returns a string instead of a\ntuple at the line:\n\n-> result.append(format % row)\n\nat the very end of the script. Simply changing this to:\n\n-> result.append(format % tuple(row))\n\nseemed to clean it up, though, and it now works :)</pre>', 'title': u'SQLite TypeError'}], 'desc': u"One of the problems of dealing with databases is presenting the result of a query when you may not know much about the data. This recipe uses the cursor's description attribute to try and provide appropriate headings, and optionally examines each output row to ensure column widths are adequate."}, {'comments': [{'comment': u'<pre>\nprint zip(*arr)\n</pre>', 'title': u'Shorter and Faster'}, {'comment': u'While the original proposal returns a list of lists, zip(*arr) returns a list of tuples, and as a consequence the elements of the array cannot be modifed anymore.', 'title': u'Not the same!'}, {'comment': u'map(list, zip(*arr))', 'title': u'OK then...'}], 'desc': u'A short way to turn rows into columns. Not necessarily the fastest, mind you. The list comprehension is your friend.'}, {'comments': [{'comment': u'The fieldnames could be obtained dynamically from the cursor rather than being explicitly specified:\n\n<pre>\ncurs.execute(sql)\ndescr = dtuple.TupleDescriptor(curs.description)\nflist = [d[0] for d in cursor.description]\n</pre>\n', 'title': u'Fieldnames could be obtained from cursor'}, {'comment': u'The OPAL Group (my company) has made available a more general and higher performance result set implementation that does not allocate a Python dictionary per row returned from a query. It allows tuple-like, dict-like, and object-like access to fields. The implementation requires Python 2.2.1 or better, and includes both pure-Python and C extension module implementations.\nFor more information see: http://opensource.theopalgroup.com/', 'title': u'A more general and higher performance alternative exists...'}, {'comment': u'I consider this lightweight:\nTake the list of tuples from fetchall(), the description from the cursor and create a dtuple.DatabaseTuple only when needed:\n\n<pre>\nimport dtuple\n\nclass DB_ROWS:\n def __init__(self, description = [], rows = []):\n self._descriptor = dtuple.TupleDescriptor([[f][0] for f in description])\n self._rows = rows\n\n def __getitem__(self, index):\n return dtuple.DatabaseTuple(self._descriptor, self._rows[index])\n\n def __len__(self):\n """Nice to have."""\n return len(self._rows)\n</pre>\n\nFor example:\n\n<pre>\nconnection = psycopg.connect(myDSN)\ncursor = connection.cursor()\ncursor.execute("""SELECT * FROM mytable""")\nraw_rows = cursor.fetch_all()\ndescription = cursor.description\n\nrows = DB_ROWS(description, raw_rows)\nprint len(rows)\nprint rows[0].mycolumn\n</pre>\n\nBtw, the column (field) names are in rows._descriptor.names', 'title': u'Here you are'}, {'comment': u'When I first started using databases from Python, we designed the DB-API to return data "as close to native" as possible. That made it easier for the extension developers, and made it faster by omitting (potentially) unnecessary work.\n<br>\n<br>\nNext came ease-of-use at the application level: wanting to refer to a column as row.my_column_name. That didn\'t match well with the .fetchall() results. My first iteration produced a bunch of objects with attribute-based values.\n<br>\n<br>\nNot fast.\n<br>\n<br>\nThus, the idea with dtuple is to provide a proxy object in between the accesses and the raw data. It stores just a couple references, and performs all of the mapping at access time.\n<br>\n<br>\nThe initial setup is fast, memory is low, and any "nice naming" cost is amortized over the entire duration of processing the rows (rather than up front).', 'title': u'some rationale'}], 'desc': u"Greg Stein's dtuple module deserves wider recognition. This recipe shows you how to use it with a simple list of database field names."}, {'comments': [{'comment': u"It is not exactly the same thing, but I think it's simpler for specific uses:\n\n<pre>\nfrom weakref import ref\n\nclass X :\n\tdef f( self , name ) : print 'hi' , name\n\tdef __del__( self ) : print 'Bye'\n\nclass WeakMethod :\n\tdef __init__( self , f ) :\n\t\tself.f = f.im_func\n\t\tself.c = ref( f.im_self )\n\tdef __call__( self , *arg ) :\n\t\tif self.c() == None :\n\t\t\tprint 'No more object'\n\t\t\treturn\n\t\tapply( self.f , ( self.c , ) + arg )\n\nx = X()\nf = WeakMethod( x.f )\nf( 'foo' )\ndel x\nf( 'bar' )\n</pre>\n\nOutput is:\n<pre>\nhi foo\nBye\nNo more object\n</pre>", 'title': u'Simpler implementation'}, {'comment': u"Hum, of course it's better to handle error correctly.\n\nReplace\n<pre>\n print 'No more object'\n return\n</pre>\nwith\n<pre>\n raise TypeError , 'Method called on dead object'\n</pre>", 'title': u'Simpler implementation'}, {'comment': u"Sorry, I've missed the dereference on self.c. The corrected class is:\n\n<pre>\nimport weakref\n\nclass WeakMethod :\n\tdef __init__( self , f ) :\n\t\tself.f = f.im_func\n\t\tself.c = weakref.ref( f.im_self )\n\tdef __call__( self , *arg ) :\n\t\tif self.c() == None :\n\t\t\traise TypeError , 'Method called on dead object'\n\t\tapply( self.f , ( self.c() , ) + arg )\n</pre>", 'title': u'Simpler implementation (without typo)'}, {'comment': u"Here is a version (hopefully the last from me) which support both free/bounded method:\n\n<pre>\nimport weakref\n\nclass WeakMethodBound :\n\tdef __init__( self , f ) :\n\t\tself.f = f.im_func\n\t\tself.c = weakref.ref( f.im_self )\n\tdef __call__( self , *arg ) :\n\t\tif self.c() == None :\n\t\t\traise TypeError , 'Method called on dead object'\n\t\tapply( self.f , ( self.c() , ) + arg )\n\nclass WeakMethodFree :\n\tdef __init__( self , f ) :\n\t\tself.f = weakref.ref( f )\n\tdef __call__( self , *arg ) :\n\t\tif self.f() == None :\n\t\t\traise TypeError , 'Function no longer exist'\n\t\tapply( self.f() , arg )\n\ndef WeakMethod( f ) :\n\ttry :\n\t\tf.im_func\n\texcept AttributeError :\n\t\treturn WeakMethodFree( f )\n\treturn WeakMethodBound( f )\n</pre>\n\nExample:\n\n<pre>\nimport WeakMethod\n\nclass X :\n\tdef f( self , name ) : print 'hi' , name\n\ndef x( name ) : print 'hi' , name\n\nf1 = WeakMethod.WeakMethod( x )\nf1( 'foo' )\ndel x\nf1( 'bar' ) # exception\n\nx = X()\nf2 = WeakMethod.WeakMethod( x.f )\nf2( 'foo' )\ndel x\nf2( 'bar' ) # exception\n</pre>", 'title': u'Alternative implementation'}, {'comment': u"Here's another version, that uses module new to return a true bound-method, and works with functions and unbounded methods also. \n\n<pre>\nimport weakref\nimport new\n\n\nclass ref(object):\n\n def __init__(self, method):\n try:\n if method.im_self is not None:\n # bound method\n self._obj = weakref.ref(method.im_self)\n else:\n # unbound method\n self._obj = None\n self._func = method.im_func\n self._class = method.im_class\n except AttributeError:\n # not a method\n self._obj = None\n self._func = method\n self._class = None\n\n\n def __call__(self):\n '''Return a new bound-method like the original, or the\n original function if refers just to a function or unbound\n method.\n Returns None if the original object doesn't exist\n '''\n if self.is_dead():\n return None\n if self._obj is not None:\n # we have an instance: return a bound method\n return new.instancemethod(self._func, self._obj(), self._class)\n else:\n # we don't have an instance: return just the function\n return self._func\n \n\n def is_dead(self):\n '''Returns True if the referenced callable was a bound method and\n the instance no longer exists. Otherwise, return False.\n '''\n return self._obj is not None and self._obj() is None\n\n\n def __eq__(self, other):\n try:\n return type(self) is type(other) and self() == other()\n except:\n return False\n\n\n def __ne__(self, other):\n return not self == other\n \n\nNote that calling the ref has the same semanthics as calling a weakref.ref: if the referent died, it returns None. If you want something like weakref.proxy:\n\nclass proxy(ref): \n '''Exactly like ref, but calling it will cause the referent method to\n be called with the same arguments. If the referent's object no longer lives,\n ReferenceError is raised.\n '''\n\n def __call__(self, *args, **kwargs):\n func = ref.__call__(self)\n if func is None:\n raise ReferenceError('object is dead')\n else:\n return func(*args, **kwargs)\n\n\n def __eq__(self, other):\n try:\n func1 = ref.__call__(self)\n func2 = ref.__call__(other)\n return type(self) == type(other) and func1 == func2\n except:\n return False \n\n</pre> ", 'title': u'Another version'}], 'desc': u'Reference to a bound method that permits the associated object\nto be garbage collected.'}, {'comments': [{'comment': u'Also check out FNORB for a pure Python CORBA ORB.<br>\nIt can be found at:<br>\nhttp://sourceforge.net/projects/fnorb<br>\n', 'title': u'Also check out FNORB for a Pure Python CORBA ORB'}, {'comment': u'Does not support newer CORBA features, esp. POA (Portable Object Adapter).\n<br> <br>\nWhile not pure Python, omniORB is quite Python-friendly.', 'title': u'Latest Fnorb is CORBA 2.1 only'}, {'comment': u"You could also use ORBit, which supports dynamic IDL compiling:<br>\n<br>\nhttp://www.gnome.org/projects/ORBit2/python/dynamic_idl.html<br>\n<br>\nThis is especially useful for clients, as you don't have to compile the IDLs to stubs and skeletons beforehand.", 'title': u'Dynamic IDL Compiling'}], 'desc': u'CORBA has a reputation for being hard to use, but it is really very easy, expecially if you use Python. This example shows the complete implementation of a fortune cookie server and its client.'}, {'comments': [{'comment': u'If dict has no entries, then the regex matches everything. Need to have an explicit check so as not to call re.sub() in that case.\n<br>\n<br>\nThe dict-like object is IMO the way to go. Now, if we have one of these, then we may (probably?) be using it more than once. So, we ought to keep the compiled regex around. There\'s no harm in keeping the text regex around either: it\'s nice for debugging, and we can get a further optimization out of it, too.\n<br>\n<br>\nHere\'s what I came up with based on your original code:\n<br>\n<br>\n<pre>\n# Original algorithm by Xavier Defrang.\n# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330\n# This implementation by alane@sourceforge.net.\n\nimport re\nimport UserDict\n\nclass textsub(UserDict.UserDict):\n def __init__(self, dict = None):\n self.re = None\n self.regex = None\n UserDict.UserDict.__init__(self, dict)\n \n def compile(self):\n if len(self.data) > 0:\n tmp = "(%s)" % "|".join(map(re.escape,\n self.data.keys()))\n if self.re != tmp:\n self.re = tmp\n self.regex = re.compile(self.re)\n\n def __call__(self, match):\n return self.data[match.string[match.start():match.end()]]\n\n def sub(self, s):\n if len(self.data) == 0:\n return s\n return self.regex.sub(self, s)\n</pre>', 'title': u'Nice algorithm; needs one fix and one optimization.'}, {'comment': u'<pre>I like this re based function a lot and was interested to compare it to a similar string replace function\nI already use -- the results are interesting:\n\nimport time\nvars = {\'%_fred\':\'hello\',\'%_dick\':\'world\',\'%_freddy\':\'sunny\'}\nline = "%_fred beautiful %_dick"\n\ndef string_replace(dict,text):\n keys = dict.keys()\n keys.sort()\n for n in keys:\n if \'%\' not in text: break\n text = text.replace(n,dict[n])\n return text\n\nstart = time.time()\nfor n in range(1000):\n multiple_replace(vars,line)\nprint 1000/(time.time()-start)\n\nstart = time.time()\nfor n in range(1000):\n string_replace(vars,line)\nprint 1000/(time.time()-start)\n\nOn my PIII 1.1GHz machine:\nmultiple_replace 3831.41707853 loops/sec\nstring_replace 50000.0476838 loops/sec\nHowever.. if the re.compile statement is moved out of the function\nnew_multiple_replace 10000.0095368 loops/sec\n\nIf you can arrange to compile outside of the routine then the re <br>version is best otherwise the longer string based function has the performance.</pre>', 'title': u'Performance tweaking..'}, {'comment': u'Actually, the\n<pre>\n keys.sort()\n</pre>\nshown in the string_replace() function doesn\'t do any thing useful and could be omitted. For the small number of keys, three, shown in the example, doing this doesn\'t speed up the routine very much.\n<br>\nHowever, it can be useful to sort the keys by the reverse of their string lengths, like this instead:\n<pre>\n keys.sort(lambda a,b: len(b)-len(a))\n</pre>\nbecause doing this will try matches with the longest patterns first. This can be signficant if one or more of the keys are substrings of others -- as the case with \'%_fred\' and \'%_freddy\' in the example.\n<br>\nIf the keys are not sorted by length (either the default way, as originally shown, or not at all), the following string:\n<pre>\n "%_freddy beautiful %_dick"\n</pre>\nwill become:\n<pre>\n "hellody beautiful world"\n</pre>\ninstead of:\n<pre>\n "sunny beautiful world"\n</pre>\nThe down side of the reverse length sort is that it does slow the routine down (about 50% on my machine).\n<br><br>\nAll versions above might also benefit by placing a "str(...)" call around the dictionary lookups. This allow the replacement values to be numbers and other object, as well as strings. I find this useful when the replacement values are calculated.', 'title': u'Re: Performance tweaking'}, {'comment': u'Interestingly, removing the line:\n<pre>\n if \'%\' not in text: break\n</pre>\nfrom the string_replace() function speeds it up fairly significantly, with no detrimental effects. Another advantage to leaving the line out is that it makes the routine more general, since keys no longer all have to start with a "%" character.', 'title': u'Re: Performance tweaking'}, {'comment': u"You're right of course - the sort needs to be reversed and done outside of the function if possible :D<br>\nI did some more checking... \nWith modifed code, using the same small sample string and increasing the size of the dictionary:<br>\nkeys,string,regex<br>\n20,20k,10k<br>\n40,11k,10k<br>\n200,2k,10k<br>\n2000,250,12k<br><br>\nAs the dictionary grew > 40 items, the perfomance of the regex routine was unaffected whereas my string replace function started to perfom badly - we live and learn!<br>\n\n", 'title': u'Futher Tweaking...'}, {'comment': u"I used it in a script for xchat to display rhythmbox's output (http://www.schitterendedingen.com/scripts/rhy.py).. now users can easily change extensions I used it in a script for xchat to display rhythmbox's output (http://www.schitterendedingen.com/scripts/rhy.py).. now users can easily change extensions ", 'title': u'Thanx!'}, {'comment': u'just need to change one line:<br>\n<br>\n<pre>\ndef compile(self):\n if len(self.data) > 0:\n tmp = r"(\\b%s)" % "|" r"\\b".join( map( re.escape,\n self.data.keys() ) )\n if self.re != tmp:\n self.re = tmp\n self.regex = re.compile(self.re)\n</pre>\n<br>\nfor those who don\'t know:<br>\n to match breaking spaces you need to use r"\\b"<br>\n so reg exp. r"\\bPYTHON\\b" will be matched in "I love PYTHON" <br>\n but not "PYTHON_version"<br>\n<br>\nwhat i just realized is that the above change in compile doesn\'t account for<br>\nbreaking spaces after the string!<br>\n<br>\nit is too late to fool around with python ;> <br>', 'title': u'great compact class !! To ignore breaking spaces before the key'}, {'comment': u'<pre>\nimport re\ndef strTr( text, dic ):\n\t""" Replaces keys of dic with values of dic in text. 2005-02 by Emanuel Rumpf """\n\tpat = "(%s)" % "|".join( map(re.escape, dic.keys()) )\n\treturn re.sub( pat, lambda m:dic[m.group()], text )\n\n</pre>', 'title': u'Maybe just use this'}, {'comment': u'This is a simple change to the code to include breaking spaces before and after each of the keys:\n\n tmp = r"(\\b%s)" % "|" r"\\b".join( map( re.escape,\nchange to:\n tmp = r"(\\b%s\\b)" % r"\\b" "|" r"\\b".join( map( re.escape,', 'title': u'add breaking spaces after each string '}], 'desc': u'This recipe shows how to use the Python standard re module to perform single-pass multiple string substitution using a dictionary.\n'}, {'comments': [], 'desc': u"You can't use the os library to determine the size of large files on 32 bit Windows. It may not be obvious from the name, however, a win32 call to FindFiles, can provide a solution."}, {'comments': [{'comment': u'The code is problematic as is. It may, or may not work.\n\nTo enable this code on locked down NT based systems (Win2k and XP) you will first have to enable "Act as Operating System" and grant rights to the appropriate user groups (run secpol.msc and select Local Policies, then User Rights Assignments). Once this is completed, you have one more step remaining. You will need to grant the rights listed with the code. To do this, you can use the following code snippet.\n\nBegin code:\ndef AdjustPrivilege(priv, enable = 1):\n # Get the process token.\n print priv\n flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY\n #flags= TOKEN_QUERY\n htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags)\n # Get the ID for the privilege.\n id = win32security.LookupPrivilegeValue(None, priv)\n # Now obtain the privilege for this process.\n # Create a list of the privileges to be added. \n if enable:\n newPrivileges = [(id, SE_PRIVILEGE_ENABLED)]\n else:\n newPrivileges = [(id, 0)]\n # and make the adjustment.\n try:\n win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)\n except:\n fail.append(priv)\n\n# now set the rights\nAdjustPrivilege(SE_CHANGE_NOTIFY_NAME)\nAdjustPrivilege(SE_TCB_NAME)\nAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_NAME)\n\n', 'title': u'Additional information'}], 'desc': u'Sometimes it is convenient to make thread authenticated as another principle.\nFor example, perhaps something should run temporarily w/administrative rights.\nThis is especially useful if you do not want the issues of making a COM object or service(which are other ways to solve the problem).'}, {'comments': [], 'desc': u"This recipe lets you take into account time spent in C modules when profiling your Python code. Normally the profiler only profiles Python code, so finding out how much time is spent accessing a database, running encryption code, sleeping and so on is difficult. Profilewrap makes it easy to profile C code as well as Python code, giving you a clearer picture of where your application is spending its time.\n\nProfilewrap demonstrates how to create proxy objects at runtime that intercept calls between pre-existing pieces of code. It also demonstrates the use of the 'new' module to create new functions on the fly.\n\n"}, {'comments': [{'comment': u'Nice idea. Would it be more pythonic to sublcass FieldStorage to create (e.g. SimpleFieldStorage) and implement it such that each form parameter is an attribute? You could then say\n<pre>\nfield = SimpleFieldStorage()\nprint "Hello %s" % field.firstname\n</pre>\ninstead of\n<pre>\nprint "Hello %s" % field[\'firstname\']\n</pre>\nI admit, it\'s splitting some hairs, and I\'ve never done any CGI in python so I\'ve no experience of the FieldStorage class either. Just wondering what people think...', 'title': u'Alternative implementation?'}, {'comment': u'The reason I use a plain dictionary is that dictionaries are totally generic and fit in well with many other Python constructs. For instance, taking your example a stage further, it\'s more intuitive to write this:\n\n<pre>print "Hello %(firstname)s %(lastname)s of %(town)s" % dict</pre>\n\nthan\n\n<pre>print "Hello %s %s of %s" % ( field.firstname, field.lastname, field.town )</pre>\n\nOne of the things I do with CGI parameters is plug them into SQL queries using exactly that construct (plus a bit of quoting for security).\n\n', 'title': u'Re: Alternative implementation?'}], 'desc': u"Rather than using Python's cgi.FieldStorage class, a simple dictionary is enough for 99% of CGI scripts. This recipe shows you how to convert a FieldStorage object into a simple dictionary."}, {'comments': [{'comment': u'This isn\'t my code, I found it when I wanted to run an XMLRPC server in a separate thread:<br>\n<pre>\nclass SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):\n pass\n\nif __name__ == "__main__":\n server = SimpleThreadedXMLRPCServer(("localhost", 8001))\n server.register_instance(MyXMLRPCObject()) # register your distant Object here\n server.serve_forever()\n</pre>\nMore here:<br>\nhttp://www.codecomments.com/Python/message190478.html<br>\nhttp://www.python.org/doc/2.3.3/lib/module-SocketServer.html', 'title': u'Threaded example'}, {'comment': u'Similarly, you can invoke each XML-RPC method in a single process with \ncode like this:\n\n<pre>\nimport SocketServer\nimport SimpleXMLRPCServer\n\nclass ForkingXMLRPCServer (SocketServer.ForkingMixIn,\n SimpleXMLRPCServer.SimpleXMLRPCServer):\n pass\n\nserver = ForkingXMLRPCServer(("localhost", 8000))\n# Register functions here...\nserver.serve_forever()\n</pre>\n\nIf using this code, remember that the methods can\'t rely on any shared global state, for example such as a dictionary used as a cache, because each method is run in a subprocess that does its work and then exits. Any changes to global variables or object attributes in the method won\'t be visible to the parent process.', 'title': u'Forking XML-RPC server'}, {'comment': u'In this server code, __init__ has\n\n import string\n self.python_string = string\n\nlines and the client code has the\n\nprint server.python_string.join([\'I\', \'like it!\'], " don\'t ")\n\nline. These codes are intended to use the dotted notation of function that Python 2.4\'s xmlrpclib disallows to use in default so the client code raise an exception when the line is executed. \nYou can choise from some options to make the client code line to work. they are:\n・assign string functions FUNCNAME to self.python_string.FUNCNAME one bye one or by looping names of string functions.\n・change the server code:\nserver.register_instance(StringFunctions())\nto:\nserver.register_instance(StringFunctions(), allow_dotted_names = True)\nallows dotted notation of the function.', 'title': u"2.4 doesn't allow dotted notation of functions"}], 'desc': u'This recipe demonstrates the creation of a simple XML-RPC server using the SimpleXMLRPCServer class. It requires either Python 2.2 or later or the XML-RPC package from PythonWare (http://www.pythonware.com/products/xmlrpc/index.htm) to run.'}, {'comments': [{'comment': u'The following is my first attempt at int_to_roman. In this version, my approach was simply to follow, as closely as I could, the plain english description of the rules given above. I rejected this version because it actually ends up being longer and more complex than the version given above. It turns out to be easier to just forcibly assign values to "IV" and its friends than it is to implement the rule that determines the values.\n\n<pre>\ndef int_to_roman(input):\n if type(input) != type(1):\n raise TypeError, "expected integer, got %s" % type(input)\n if not 0 < input < 4000:\n raise ValueError, "Argument must be between 1 and 3999"\n result = ""\n nums = (\'M\', \'D\', \'C\', \'L\', \'X\', \'V\', \'I\')\n ints = (1000, 500, 100, 50, 10, 5, 1)\n places = [0,] * len(nums)\n # count how many times each int we have\n for i in range(len(ints)):\n value = ints[i]\n count = input / value\n places[i] = count\n if count: input -= count * value\n # Format the output string\n for i in range(len(places)):\n if places[i] < 4:\n result += nums[i] * places[i]\n else:\n # 4 repetitions means we\'re trying to represent 4 or 9\n # of something.\n if places[i -1] == 0:\n # it\'s a 4.\n result += nums[i] + nums[i -1]\n else:\n # it\'s a 9.\n # \'the next\' character is 2 away from here, not 1;\n # otherwise we\'d get \'IV\' when we want \'IX\'.\n # We\'ll also need to delete the previous character,\n # or we\'ll get stuff like \'VIX\' when we want \'IX\'.\n result = result[:-1] + nums[i] + nums[i -2]\n return result\n</pre>', 'title': u'int_to_roman: another approach'}, {'comment': u"See Mark Pilgrim's chapter on developing a roman numeral conversion module, with unit testing in his excellent Dive into Python book: http://diveintopython.org/roman_divein.html for another alternative.", 'title': u'Alternative - roman.py with unit testing'}, {'comment': u'I checked out Mark\'s "Dive Into Python". Good stuff, and all free under the Python license. \n<br>\n<br>His roman-to-int converter is much simpler than the one I posted above. However, Mark relies on a regexp to validate the input. That\'s fine, and makes the function nicely short; but it puts a lot of the logic in the regexp, which I feel is more likely to be misread than is a slightly longer function. \n<br><br>\nSo here\'s my latest version. It\'s based on Mark\'s, except that I use an additional field in each tuple to enforce the maximum allowed repetitions of each numeral, and I rely on the ordering of the tuple to enforce the correct ordering of numerals. With that done, we don\'t need a regexp, nor do we need to test by calling int_to_roman(result) as my first version did.\n\n<pre>\ndef roman_to_int(input):\n """\n Convert a roman numeral to an integer.\n \n >>> r = range(1, 4000)\n >>> nums = [int_to_roman(i) for i in r]\n >>> ints = [roman_to_int(n) for n in nums]\n >>> print r == ints\n 1\n\n >>> roman_to_int(\'VVVIV\')\n Traceback (most recent call last):\n ...\n ValueError: input is not a valid roman numeral: VVVIV\n >>> roman_to_int(1)\n Traceback (most recent call last):\n ...\n TypeError: expected string, got \n >>> roman_to_int(\'a\')\n Traceback (most recent call last):\n ...\n ValueError: input is not a valid roman numeral: A\n >>> roman_to_int(\'IL\')\n Traceback (most recent call last):\n ...\n ValueError: input is not a valid roman numeral: IL\n """\n try:\n input = input.upper()\n except AttributeError:\n raise TypeError, \'expected string, got %s\' % type(input)\n # map of (numeral, value, maxcount) tuples\n roman_numeral_map = ((\'M\', 1000, 3), (\'CM\', 900, 1),\n (\'D\', 500, 1), (\'CD\', 400, 1),\n (\'C\', 100, 3), (\'XC\', 90, 1),\n (\'L\', 50, 1), (\'XL\', 40, 1),\n (\'X\', 10, 3), (\'IX\', 9, 1),\n (\'V\', 5, 1), (\'IV\', 4, 1), (\'I\', 1, 3))\n result, index = 0, 0\n for numeral, value, maxcount in roman_numeral_map:\n count = 0\n while input[index: index +len(numeral)] == numeral:\n count += 1 # how many of this numeral we have\n if count > maxcount:\n raise ValueError, \'input is not a valid roman numeral: %s\' % input\n result += value\n index += len(numeral)\n if index < len(input): # There are characters unaccounted for.\n raise ValueError, \'input is not a valid roman numeral: %s\'%input\n else:\n return result\n</pre>', 'title': u'A better roman_to_int... Thanks Graham (and Mark!).'}], 'desc': u'Functions to convert between integers and Roman numerals. Doctest examples included.'}, {'comments': [], 'desc': u'This is yet another example of an XML-RPC capable web service. Where this example is different though, is that the service can be accessed at the same time using the SOAP protocol. Confusion is avoided by clients for each protocol using different URLs to access the service.'}, {'comments': [], 'desc': u'Shows how to remotely access a database via a web service supporting XML-RPC and SOAP protocols. The example uses the MySQLdb module, but should be easily customised to any database with Python module adhering to the Python DB API. The web service interface provides the ability to make a self contained query, or allows the creation of a distinct database cursor to service a series of queries or updates without other clients interfering. Cursors automatically expire and delete themselves after a set period of inactivity if not explicitly closed.'}, {'comments': [], 'desc': u'Simple example of setting up a distributed publish/subscribe system. Shows creation of a central exchange service which all participating processes connect to. Services can then set themselves up as publishers, with other services able to subscribe to what is being published.'}, {'comments': [], 'desc': u'Simple example of setting up a distributed message oriented request/reply architecture. Shows creation of a central exchange service which all participating processes connect to. Services assign themselves a name and export the methods which are remotely accessible. Client services are then able to make calls against the exported methods.'}, {'comments': [], 'desc': u'This is a Priority Queue based on a heap data strucuture. Elements come out of the queue least first. The heap is a complete binary tree with root at _a[1] and, for a node N, its parent is _a[N>>1] and children are _a[2*N] and _a[2*N+1].'}, {'comments': [], 'desc': u"When you create a Python module, you can use a test script wich import your module. But you probably have noticed that when you run the test script, it always use the first version of your module even if you made changes in the code.\nThis is because the import statement check if the module is already in memory and do the import stuff only when this is mandated.\n\nYou can use the reload() function but this is quite difficult if you do changes in a module wich isn't directly imported by your test script.\n\nA good solution could be to remove all modules from memory before running the test script.\nYou only have to put some few lines at the start of your test script."}, {'comments': [{'comment': u"By binding or re-binding attributes of object func, this recipe is fragile -- if funcToMethod is called twice on the same func, confusion is quite possible. Module new is designed to help exactly with such dynamic needs:<pre>\ndef funcToMethod(func,clas,method_name=None):\n import new\n method = new.instancemethod(func,None,clas)\n if not method_name: method_name=func.__name__\n clas.__dict__[method_name]=method\n</pre>\nA somewhat mind-boggling (or mind-expanding:-) extra of this approach is that func can in fact be any callable, such as an instance of any class that supplies a __call_ special method, or a bound-method...<br>\nThe 'instancemethod' function name may be slightly misleading: it generates both bound and unbound methods, depending on whether the second argument is None (unbound) or an instance of the class that is the third argument. See http://www.python.org/doc/current/lib/module-new.html for all the details (there's not much more to it than this, though).\n", 'title': u'module new may be preferable'}, {'comment': u"This is what happens when you get too excited about writing code and don't bother to plan far enough ahead to read the documentation.\n\nThank you for pointing out the more proper way of handling this, Alex.", 'title': u'Should Have Read the Docs'}, {'comment': u"The problem with only adding a new function to a class instance's dictionary, is it must always be called in a special manner - it dosn't behave in the same way as normal methods. Using a wrapper class can get round this problem providing a more transparent solution.\n<br>\n<br>\nThe function to be added is say(). The parameter host performs the same purpose as what we normally refer to as self - the object which this method works on. The name host simply reminds us we are parasites in this place!\n<pre>\n#!/usr/bin/env python\n\ndef say(host, msg):\n print '%s says %s' % (host.name, msg)\n\ndef funcToMethod(func, clas, method_name=None):\n setattr(clas, method_name or func.__name__, func)\n\nclass transplant: \n def __init__(self, method, host, method_name=None):\n self.host = host\n self.method = method\n setattr(host, method_name or method.__name__, self)\n\n def __call__(self, *args, **kwargs):\n nargs = [self.host]\n nargs.extend(args)\n return apply(self.method, nargs, kwargs)\n\nclass Patient:\n def __init__(self, name):\n self.name = name\n\nif __name__ == '__main__':\n jimmy = Patient('Jimmy')\n transplant(say, jimmy, 'say1')\n funcToMethod(say, jimmy, 'say2')\n\n jimmy.say1('Hello')\n jimmy.say2(jimmy, 'Good Bye!')\n</pre>", 'title': u'Using a function wrapper to automatically provide self to methods added at runtime.'}, {'comment': u'Slight modification to the recipe "9.1 Synchronizing All Methods in an Object." Whereas the the former synchronizes all instances of a class on a single lock, this code synchronizes each instance on it\'s own lock to makes sure that only one thread at a time has access to certain bound methods. Unsynchronized methods behave normally. Plus, I think this version is more clear.\n\nimport threading\n\n# Just as it is in recipe 9.1 of Python Cookbook, v2\ndef wrap_callable(any_callable, before, after, new_name=None):\n """ Wrap any callable with before/after calls """\n def _wrapped(*args, **kwds):\n before()\n try:\n return any_callable(*args, **kwds)\n finally:\n after()\n _wrapped.__name__ = new_name and new_name or any_callable.__name__\n return _wrapped\n\nif __name__ == \'__main__\':\n import threading, time\n\n class A(object):\n def __init__(self):\n self.lock = threading.Lock()\n # Synchronize these on self.lock, and make them unbound/bound methods\n A.foo = wrap_callable(A._foo, self.lock.acquire, self.lock.release)\n A.bar = wrap_callable(A._bar, self.lock.acquire, self.lock.release)\n def _foo(self):\n print \'I am foo\'\n time.sleep(2)\n def _bar(self):\n print \'I am bar\'\n def baz(self):\n print \'I am baz\'\n a = A()\n\n print A._foo, A.foo\n print a._foo, a.foo\n print a._foo.__name__, a.foo.__name__\n print type(a._foo), type(a.foo)\n\n\n threading.Thread(target=a.foo).start()\n time.sleep(0.2)\n threading.Thread(target=a.bar).start()\n time.sleep(0.2)\n threading.Thread(target=a.baz).start()\n ', 'title': u'Synchronizing instance methods'}], 'desc': u'Ruby has the functionality of being able to add a method to a class at an arbitrary point in your code. I figured Python must have some way for allowing this to happen, and it turned out it did. The method is available instantly to all already existing instances and of course ones yet to be created. If you specify method_name then that name is used for the method call.\n\nOne thing to make sure to do is that the function has a variable for the instance to be passed to (i.e. self).'}, {'comments': [{'comment': u"This is a nice implementation of eiffel's contracts. It even works for __init__! But then again, why wouldn't it?", 'title': u'Very Nice'}, {'comment': u'The contracts do not seem to be inherited by a overridden method as we have in Eiffel. I am a Python newbie so I am unable to figure it out myself and I would appreciate such a feature', 'title': u'What about inherited methods'}, {'comment': u"Unfortunately the recipe doesn't offer this kind of support. If you need to deal with derived classes, you should take a look at the files Eiffel.py in the directories Demo/metaclass and Demo/newmetaclass of Python distribution.", 'title': u'Contratcs and inheritance'}, {'comment': u'I am concerned about using exec. I suspect it would be very easy to make the application do something completely different by manipulating the data that is going to be passed to exec. I am afraid of a security leak.', 'title': u'exec ?'}], 'desc': u'This sample show how you can use intospection to create a function wraper that verify Eiffel like contracts.'}, {'comments': [], 'desc': u'This script creates an Access 2000 table and adds a primary key to it. '}, {'comments': [{'comment': u'I just removed a redundant line of code.<br><br>\nIn use, look out for escaped characters if your OS uses backslash characters in folder paths. Using a raw string to define the "dir" argument might be the best approach.', 'title': u'A tiny change'}, {'comment': u'This script made it into the Cookbook book. The editors gave it a good going over, so I\'m reposting it.<br><br>\nChanges:<br><br>\nThe "checking for leading dots" is now in the swapextensions function, not in the call back. This now only gets done once, which is as it should be.<br><br>\nThe script now explicitly only affects the end of the file name, so files that happen to have ."extension" *inside* their name as well as at the end will only get the real extension changed. This makes the script more targeted, and so more safe.<br><br>\nThe redundant import of string survived the editing process. I\'ve removed it here.\n', 'title': u'A new, improved, swapextensions.py'}, {'comment': u'I love python as much as the next cookbook reader, but I\'d like to point out that this is not a useful python script. The reason is the same as why we don\'t have a recipe for "copy files with a given extension into another directory"[1] or "create the given empty directory trees"[2]. Simple file renaming operations are easily done in the shell.\n<br>\n\n<br>\nI use zsh, where I say:\n<br>\n<pre>for x (**/*.ext1) { mv $x $x:r.ext2 }</pre>\n<br>\nThe shell variable x loops over all files that match *.ext1 in all directories below the current one (** is short for something like "any number of subdirectories"). $x:r is the "root" of $x; $x without its extension. When $x is "foo/file1.ext1", the loop body becomes "mv foo/file1.ext1 foo/file1.ext2". :r is not the only zsh modifier by any means. You can do incredible things with just a few keystrokes.[3]\n<br>\n\n<br>\nI guess maybe windows users might need extra tools to manipulate their filenames, but I would think they\'d just download and run zsh if they cared about this kind of thing.\n<br>\n\n<br>\n(Yes, I know my example\'s functionality is slightly different for cases like file.ext1.ext2.ext3. I don\'t see the common-case usefulness of the python script\'s different behavior, though.)\n<br>\n\n<br>\n[1] cp *.ext newdir\n<br>\n[2] mkdir -p path1/part2/part3 path2/part4\n<br>\n[3] more modifiers at http://zsh.sourceforge.net/Doc/Release/zsh_13.html#SEC45', 'title': u'this is not for shell users'}, {'comment': u"Perhaps <pre>if before[:1] != '.'</pre> could be wrote <pre>if before[0] != '.'</pre>It looks clearer for me...<br>\n<br>\nAlso, passing the negative length of 'before' to the 'callback' function and use it for slicing is pretty disturbing...<br>\nWhat about passing the (positive) length of the var 'before' and negate it in the slice, it should make it explicit if the slice value is referenced from the start of the string (positive values) or from the end of the string (negative value). It's no very explicit here.<br>\n<br>\nRegards", 'title': u'Minor comments'}], 'desc': u'This script will swap extensions on all files in the specified directory,\nand all of its subdirectories, and all of their subdirectories, etc.\nDefine your arguments with care. Swapextensions.py will do what you tell it to do!'}, {'comments': [{'comment': u'The above code for unique() has quadratic runtime (slow for long lists) because \'item not in L2\' uses a sequential search over list L2.\n\nTo achieve linear runtime (fast for long lists), convert L2 to a dictionary so that sequential searching is replaced by fast hashing:\n\n<pre>\ndef unique(L1, L2):\n """Return a list containing all items in \'L1\' that are not in \'L2\'"""\n L2 = dict([(k,None) for k in L2])\n return [item for item in L1 if item not in L2]\n</pre>', 'title': u'Faster Implementation using a Dictionary'}], 'desc': u"If you need to synchronize two lists here's a simple pattern.\n"}, {'comments': [], 'desc': u'Method Enhancement\n\nThis recipe demonstrates a technique for adding functionality to an\nexisting class method after the class has already been defined.\n\nRequires python 2.1 or later.\n'}, {'comments': [{'comment': u"readers will likely be interested in http://pydispatcher.sourceforge.net/ which solves a similar problem.\n\nI use pydispatcher often, but I have not used this recipe so I can't\ncomment on which is better.", 'title': u'also see PyDispatcher'}], 'desc': u'The "broadcaster" and "broker" modules enable loose coupling between objects in a running application.'}, {'comments': [], 'desc': u'This recipe shows how to modify the class hierarchy of an instance object after it has already been instantiated.\n'}, {'comments': [], 'desc': u"Smart pluralisation function that provides more intelligence than simply adding an 's' to the end of a word."}, {'comments': [], 'desc': u'This tiny script logs on a POP3 server and allows you to view the top of the messages and eventually mark them for deletion.'}, {'comments': [{'comment': u"This obviously doesn't work when you're dealing with packages.\nFor instance, importCode(code,'my.packaged.module') won't work.\n", 'title': u"This doesn't work with packages"}], 'desc': u'This recipe will let you import a module from code that is dynamically\ngenerated. My original use for it was to import a module stored in a\ndatabase, but it will work for modules from any source.'}, {'comments': [], 'desc': u"If you're familiar with thread programming, Python is reasonably straightforward to work with, once you realize the global interpreter lock is around; however, sometimes they can be trouble. One case is when threads don't die when you expect them to. Resorting to infrequent polling, even if more advanced logic is active in your program, is one way to deal with this, especially during debugging."}, {'comments': [], 'desc': u"In win32, as in other event-driven systems, you must process messages or bad things happen. \n(Or at best, good things don't happen.) The MsgWaitForMultipleObjects is one way to deal\nwith handling messages as well as coordinating several other activities."}, {'comments': [], 'desc': u'A python script very loosely approximating pkill.'}, {'comments': [], 'desc': u'Given the number of literals and clauses, returns a randomly generated\n3-CNF sentence composed of clauses in the form of lists of tuples.\nThe first number in the tuple is the literal; the second number is its truth value.'}, {'comments': [], 'desc': u'Execute a command-line argument repeatedly between arbitrary intervals of time.'}, {'comments': [{'comment': u'Note the standard os.makedirs() supports the make all intermediates behavior and also support the optional mode argument.', 'title': u'os.makedirs(), the standard way'}], 'desc': u"A more friendly mkdir() than Python's standard os.mkdir().\nLimitations: it doesn't take the optional 'mode' argument\nyet."}, {'comments': [{'comment': u"There appear to be numerous typos an other related errors in the example code provide, but I think I understand the idea and believe it's a pretty good one, namely dispatching based on regular expression pattern matching.", 'title': u'Poorly Presented Examples'}], 'desc': u'Although python has no literal representation for compiled \nregular expressions (which is good) you can compile them\nat Python read/compile-time. You can also use regexs to\nmatch strings and automatically call funtions with arguments\nthat are based on the groups of the matched strings.'}, {'comments': [], 'desc': u'Hexify is a hex dump utility handy for viewing binary files at the command-prompt.'}, {'comments': [], 'desc': u"I've decided to sum up my recent experiences on this issue in a short HOWTO\ndocument. There are still things that are unclear to me, like how to set\nbreakpoints. If something doesn't work or is unclear, please point it out.\n"}, {'comments': [{'comment': u'If you want to replace the Tkinter code with wxPython code, that will work as well.\nLaura Creighton lac@strakt.com', 'title': u"FYI: This isn't Tkinter specific."}, {'comment': u'<pre>\n"""\n\nThis recipe describes how to handle asynchronous I/O in an environment\nwhere you are running PyQt as the graphical user interface. PyQt is\nsafe to use as long as all the graphics commands are handled in a\nsingle thread. Since it is more efficient to make I/O channels to\nblock and wait for something to happen rather than poll at regular\nintervals, we want I/O to be handled in separate threads. These can\ncommunicate in a threasafe way with the main, GUI-oriented process\nthrough one or several queues. In this solution the GUI still has to\nmake a poll at a reasonable interval, to check if there is something\nin the queue that needs processing. Other solutions are possible, but\nthey add a lot of complexity to the application.\n\nCreated by Jacob Hall\xe9n, AB Strakt, Sweden. 2001-10-17\nAdapted by Boudewijn Rempt, Netherlands. 2002-04-15\n"""\n\nimport sys, time, threading, random, Queue, qt\n\nclass GuiPart(qt.QMainWindow):\n\n def __init__(self, queue, endcommand, *args):\n qt.QMainWindow.__init__(self, *args)\n self.queue = queue\n # We show the result of the thread in the gui, instead of the console\n self.editor = qt.QMultiLineEdit(self)\n self.setCentralWidget(self.editor)\n self.endcommand = endcommand\n \n def closeEvent(self, ev):\n """\n We just call the endcommand when the window is closed\n instead of presenting a button for that purpose.\n """\n self.endcommand()\n\n def processIncoming(self):\n """\n Handle all the messages currently in the queue (if any).\n """\n while self.queue.qsize():\n try:\n msg = self.queue.get(0)\n # Check contents of message and do what it says\n # As a test, we simply print it\n self.editor.insertLine(str(msg))\n except Queue.Empty:\n pass\n\n\nclass ThreadedClient:\n """\n Launch the main part of the GUI and the worker thread. periodicCall and\n endApplication could reside in the GUI part, but putting them here\n means that you have all the thread controls in a single place.\n """\n def __init__(self):\n # Create the queue\n self.queue = Queue.Queue()\n\n # Set up the GUI part\n self.gui=GuiPart(self.queue, self.endApplication)\n self.gui.show()\n\n # A timer to periodically call periodicCall :-)\n self.timer = qt.QTimer()\n qt.QObject.connect(self.timer,\n qt.SIGNAL("timeout()"),\n self.periodicCall)\n\n # Start the timer -- this replaces the initial call to periodicCall\n self.timer.start(100)\n\n # Set up the thread to do asynchronous I/O\n # More can be made if necessary\n self.running = 1\n \tself.thread1 = threading.Thread(target=self.workerThread1)\n self.thread1.start()\n\n\n def periodicCall(self):\n """\n Check every 100 ms if there is something new in the queue.\n """\n self.gui.processIncoming()\n if not self.running:\n root.quit()\n \n def endApplication(self):\n self.running = 0\n\n\n def workerThread1(self):\n """\n This is where we handle the asynchronous I/O. For example, it may be\n a \'select()\'.\n One important thing to remember is that the thread has to yield\n control.\n """\n while self.running:\n # To simulate asynchronous I/O, we create a random number at\n # random intervals. Replace the following 2 lines with the real\n # thing.\n time.sleep(rand.random() * 0.3)\n msg = rand.random()\n self.queue.put(msg)\n\n\nrand = random.Random()\nroot = qt.QApplication(sys.argv)\n\nclient = ThreadedClient()\nroot.exec_loop()\n\n</pre>\n\nIt\'s amazing how similar these are. Two improvements: it doesn\'t use sys.exit, but asks the QApplication instance to quit, and it shows the result of t', 'title': u"Here's the same, but for PyQt"}, {'comment': u'There is must be set thread as daemon by self.thread1.setDaemon(1) method:\n<pre>\n self.running = 1\n \tself.thread1 = threading.Thread(target=self.workerThread1)\n self.thread1.setDaemon(1)\n self.thread1.start()\n</pre>', 'title': u'Set thread subprocess as daemon'}], 'desc': u'This recipe shows the easiest way of handling access to sockets, serial ports\nand other asynchronous I/O ports while running a Tkinter based GUI.\nIt allows for a worker thread to block in a select(). Whenever something arrives\nit will received and inserted in a queue. The main (GUI) thread then polls\nthe queue 10 times per second (often enough so the user will not notice any\nsignificant delay), and processes all messages that have arrived.\n '}, {'comments': [], 'desc': u'This recipe, taken a class definition (see the docstring for further explain), \ngenerate the class code, evaluate it and return an instance of the constructed \nclass. '}, {'comments': [], 'desc': u'What is your Viking name? This script will tell you.'}, {'comments': [{'comment': u'i downlaod a url\n"http://news.sina.com.cn/old1000/news1000_20050702.shtml"\nthis page about 1.1M, on Windows 2000, python2.4\nsometimes, it resumes, and sometime, it downlaod from begin, \ndon\'t know why.', 'title': u"thanks, but some times doen's work"}], 'desc': u'This script shows how to resume downloading of a file that has been partially downloaded from a web server. It\'s been tested with Apache 1.3.x, but should work with any web server that understands the "range" header.'}, {'comments': [], 'desc': u'This describes possible ways of using userdefined class instances as dictionary keys.'}, {'comments': [{'comment': u'cool idea. minor nit... if the function being run in a Future generates an exception the Condition is never released...\n<br><br>\nmaybe a try / finally around the self.__result=func(*param)?\n', 'title': u'what about exceptions?'}, {'comment': u"That's a very good point, thanks for pointing it out. A try/finally where you suggested is probably the best way to deal with it. I'll give it a shot.", 'title': u'Re: what about exceptions?'}, {'comment': u'And done. I made it a try / except, rather than try / finally, so the Future can report an error message rather than dying silently.', 'title': u'Fixed'}, {'comment': u"This is really nice. it's a pity you can't easily stop the function\nfrom where you started the future. Sometimes one would certainly \nlike timeouts or other termination conditions. ", 'title': u'very nice'}, {'comment': u'If a thread takes a REAL long time, one might want to query the thread to see if it is done. Something like this (in the class) should work:<br>\n<pre>\ndef isDone(self): return self.__done\n</pre>\nIf one stored the starting time, one could query the lenght of time the thread has been running.<br>\n<br>\nQuestion. Is there any way that the actual running thread can pass information back to the instance of Future? So I could know it is working on iteration 23 of 100, or some such?', 'title': u'Am I done?'}, {'comment': u'In my version I added self.__excpt = None in __init__, then in __call__ I added (just before copying the result):\n<pre>\n # an exception was thrown in the thread, re-raise it here.\n if self.__excpt: raise self.__excpt\n</pre>\nand finally in Wrapper, I added an extra layer of exception handling:\n<pre>\n try:\n self.__result == func(*param)\n except Exception, e: # we got an exception object, save it.\n self.__excpt = e\n except:\n self.__result = "Unknown exception raised within Future"\n</pre>\nAssuming the user inherits his exception from Exception (which he is supposed to), this will make futures semi transparent in exception cases, i.e. the exception will be thrown when the user fetches the value of the future.', 'title': u'Exception handling'}, {'comment': u"Back-communication is simple: just pass the 'self' object into the function in Wrapper, and it will be able to assign to an appropriate property on the Future instance.", 'title': u' '}, {'comment': u'Is there a maximum number of feeds this can handle?', 'title': u'Maximum number of feeds'}, {'comment': u'In my version, Wrapper() does this:\n<pre>\ntry:\n self.__result = func(*args, **kwargs)\nexcept:\n self.__result = "Exception raised within Future"\n self.__excpt = sys.exc_info()\n</pre>\n<br>\nand __call__() does this:\n<pre>\nif self.__excpt:\n raise self.__excpt[0], self.__excpt[1], self.__excpt[2]\n</pre>\n<br>\nThis way, all exceptions are caught, regardless of inheriting from Exception, and you even get a nice traceback (with a little gc expense).', 'title': u'Better exceptions'}], 'desc': u"Although Python's thread syntax is nicer than in many languages, it can still be a pain if all one wants to do is run a time-consuming function in a separate thread, while allowing the main thread to continue uninterrupted. A Future provides a legible and intuitive way to achieve such an end."}, {'comments': [], 'desc': u'One of the few problems with using Python to process XML is the speed -- if the XML becomes somewhat large (>1Mb), it slows down exponentially as the size of the XML increases. One way to increase the processing speed is to break the XML down via tag name. This is especially handy if you are only interested in one part of the XML, or between certain elements throughout the XML.\n\nHere is a function that I came up with to handle this problem -- I call it "tinyDom". It uses the Sax reader from PyXML, although it could be easily changed for minidom, etc.\n\nThe In parameters are the XML as a string, the tag name that you want to build the DOM around, and an optional postition to start at within the XML. It returns a DOM tree and the character position that it stopped at.'}, {'comments': [], 'desc': u'This code show how to use the relatively unknown LexicalHandler\ninterface, which is an extension to the standard SAX2 interfaces like\nContentHandler (we assume you already have some SAX2 know-how). \n'}, {'comments': [{'comment': u'This article was indirectly useful, in highlighting that you done need to know the __len__ of the collection object S in "for X in S" loops. Just providing __getitem__(self,index) is sufficient, and throwing IndexError when it goes out of bounds.\n<br>\nThe reason this is useful to me, is where S is an extension object which interfaces to some other date element source, where we can get the next element, but dont know where the end is until we reach it.', 'title': u'how "for X in S" terminates'}, {'comment': u'<pre>\ndef nloop(*lol):\n l=len(lol)\n dims=map(len,lol)\n totl=reduce(lambda x,y:x*y,dims)\n i=0\n idx=[0]*l\n while totl>i:\n a=i\n i+=1\n for j in range(l-1,-1,-1):\n a,b= divmod(a,dims[j])\n idx[j]=lol[j][b]\n yield tuple(idx)\n\n\namounts to transforming a n-dimensional array in a long vector, and\nconvert the linear index to multiple index.</pre>', 'title': u'a shorter version'}], 'desc': u'Do nested for loops on an arbitrary list of iterable things.\n'}, {'comments': [{'comment': u'pydirstat is a really handy cross-platform, command-line way to generate information about disk usage.\n<br>\n<br>\nhttp://developer.berlios.de/projects/pydirstat/\n<br>\n<br>\nON WINDOWS\n<br>\nGoogle for "pydirstat exe" to find the download page of the windows executable or go to http://developer.berlios.de/projects/pydirstat/ and look for the link.\nInstall by clicking the the .exe file.\nThen go into Windows explorer and right-click the folder or drive letter you want to inspect, choosing then pydirstat option. When the black DOS window finally closes you will find a "dirstat.html" file in the directory of the folder you were inspecting. Double-click that. If you have firefox installed and that\'s the default then you should be able to move your mouse over the various files to find out their sizes. (Not sure about IE.)\n<br>\n<br>\nON LINUX\n<br>\ncd ; wget http://download.berlios.de/pydirstat/pydirstat-0.9.10.tar.gz ; tar xvfz pydirstat-0.9.10.tar.gz; cd pydirstat-0.9.10/; \\\ncd /; sudo python ~/pydirstat-0.9.10/src/pdshtml.py\n<br><br>\nUse Firefox to view the resultant "dirstat.html"\n<br><br>\n\nON MACOSX:\n<br>\ncd ; curl http://download.berlios.de/pydirstat/pydirstat-0.9.10.tar.gz > pydirstat-0.9.10.tar.gz ; \\\ntar xvfz pydirstat-0.9.10.tar.gz; cd /; sudo python ~/pydirstat-0.9.10/src/pdshtml.py; open dirstat.html\n<br><br>\n(Again, use Firefox to open it.)', 'title': u'Pydirstat'}], 'desc': u'List the summed size of a directory (or set of directories) without the GUI. This recipe makes it quick and easy to see where all your disk space has gone! It has been tested under Windows and Unix, however it will probably be most useful under Windows considering the fact that Unix ships with a similar command, du.\n\nHave fun!'}, {'comments': [{'comment': u'Am I right in thinking that you would probably only want one instance of the Prototype class in a program? In which case the Prototype class should itself implement the Singleton (or possibly better yet, Borg) pattern.\n', 'title': u'Should Prototype class be a Singleton or Borg?'}, {'comment': u'What this actually seems to be is an impementation of what the GOF book calls a "prototype manager" with Clone() implemented in the prototype manager rather than the prototype class. This does have its advantages, but anyway...<br><br>\nYou don\'t necessarily want to have only one single prototype of a given object per application. For example, you might have a (XML) DOM tree object that has its own set of prototypes for various different elements, and another DOM tree object with totally different prototypes for the same elements.', 'title': u'Sometimes you may want more than one "prototype manager."'}, {'comment': u"After looking at http://www.prothon.org/ it seemed like the prototype stuff it does could be acheived through a metaclass. Here's a simple implementation:\n\n<pre>\nfrom copy import deepcopy, copy\n\ncopyfunc = deepcopy\n\ndef Prototype(name, bases, dict):\n class Cls:pass\n Cls.__name__ = name\n Cls.__bases__ = bases\n Cls.__dict__ = dict\n inst = Cls()\n inst.__call__ = copyier(inst)\n return inst\n\nclass copyier:\n def __init__(self, inst):\n self._inst = inst\n def __call__(self):\n newinst = copyfunc(self._inst)\n if copyfunc == deepcopy:\n newinst.__call__._inst = newinst\n else:\n newinst.__call__ = copyier(newinst)\n\treturn newinst\n</pre>\n\nYou can set 'copyfunc' to 'copy' if you would prefer shallow copies of the prototyped objects and it will still behave appropriately.\n<br><br>\nTo mimic some of the Prothon examples:\n\n<pre>\nclass Point:\n __metaclass__ = Prototype\n x = 0\n y = 0\n def move(self, x, y):\n self.x += x\n self.y += y\n\na = Point()\nprint a.x, a.y # prints 0 0\na.move(100, 100)\nprint a.x, a.y # prints 100 100\n\nPoint.move(50, 50)\nprint Point.x, Point.y #prints 50 50\np = Point()\nprint p.x, p.y #prints 50 50\n\nq = p()\nprint q.x, q.y #prints 50 50\n</pre>\n\n\n\nThis doesn't support everything that Prothon does. For example, it doesn't currently support __init__ and set_proto (for changing the prototype of an instance). Also, it currently does not support inheritance. If anyone has suggestions for how to support these please post them.", 'title': u'Prototype as a metaclass'}, {'comment': u'I\'m not sure if this deserves its own recipe or not. Since it\'s strongly related to the Prototype pattern, I thought it might make the most sense to include it here.\n<br><br>\nThe clone protocol is simple. Basically any object that implements a method clone() that returns a copy of itself implements the clone protocol. The reason for doing things this way is that the user may not know what the copy "deepness" should be for any given object. Implementing the clone protocol allows an object to implement for itself how a copy of itself should be made.\n<br><br>\nThis protocol can be used with the implementations above. Just replace deepcopy(obj) or copy(obj) with obj.clone().\n<br><br>\nYou can also define a simple class that provides a default implementation of the clone method, though this isn\'t really necessary. One of the strengths of python is that you don\'t have to do this. (An object doesn\'t have to have a certain type in most cases as long as it implements certain expected methods.)\n<br><br>\n<pre>\n\nfrom copy import copy\n\nclass Cloner(object):\n def clone(self):\n return copy(self)\n\n</pre>', 'title': u'The "Clone" Protocol'}], 'desc': u'This is an implementation of the prototype pattern. In the prototype pattern you create a new instance cloning from other.'}, {'comments': [{'comment': u"Excellent example -- this was exactly what I needed.\n\nI think the email module has changed slightly since this example was written: I suppose the 'subMsg.add_payload' command should be replaced by 'subMsg.set_payload' and the 'mainMsg.add_payload' command should be replaced by 'mainMsg.attach'. However, I'd leave it to some more knowledgable person to confirm this. \n\nOther than that, the example runs fine and helped me a lot. Thanks, Hans", 'title': u'Good work!'}, {'comment': u"For the Generator use the flatten method as the __call__ method is depricated.\n\nThe Message method add_payload is depricated in favor of attach, however with a multipart/mixed you should be using set_payload in all the attached messages. Use attach in your main message, the one that has the content-type multipart/mixed. The sub messages with other content-types like text/plain, application/pdf, etc you use set_payload.\n\nIf you do not do this you will get an exception, or error that says something like:\nTypeError string payload expected: type list\nfrom the Generator.py module\n\nThis is because by using attach, or add_payload the payload becomes a list and the content-type won't match, so the generator bombs.\n\nJohnny P", 'title': u'Python 2.2.1 and older ok, but 2.2.2+ need a little more'}, {'comment': u'I had problems using the "attach" method and found reference to this problem in your comments re this example.\nThis looks like a bug in the current (>= 2.3) python versions (it has allsorts of nasty consequences other than just this example) . Have you submitted a bug report to the library maintainer . I am using 2.3 and have not yet checked 2.4.\nYour post was very useful - I had read and reread the python manual and was getting nowhere! \nThanks.', 'title': u' '}], 'desc': u'An example of using the email module to create a multipart MIME message.'}, {'comments': [], 'desc': u'An example of using the email module to unpack and decode a MIME message.'}, {'comments': [], 'desc': u"An example of using the email module to unpack and decode a MIME message. This\nexample uses the message's walk() method."}, {'comments': [{'comment': u'Hmm, can\'t find my go4 - but this looks to me like the _abstract_ factory pattern rather than the factory pattern. Very nice to see another "design pattern"!', 'title': u'Abstract Factory?'}, {'comment': u'Since apply() is deprecated. Should we:\n<br>\n setattr(self, methodName, apply(Functor, _args, kargs))\n\nchange to:\n<br>\n setattr(self, methodName, Functor(*_args, **kargs))\n\nand\n<br> \n return apply(self._function, _args, _kargs)\n\nchanged to:\n<br>\n return self._function(*_args, **_kargs)\n', 'title': u'should apply() be replaced'}], 'desc': u'In the factory pattern you have an object that creates other objects.'}, {'comments': [{'comment': u"I'd like to recognize and thank the following people who either helped with the code or gave inspiration: Joseph A. Knapka has his own variation on this theme, from which I learned a lot; Bernhard Herzog's Sketch project has a message passing system from which I drew inspiration; Magnus Lie Hetland provided his share of ideas, as did Paolo Invernizzi and others on the anygui project. Of course, any flaws in the code are strictly my own doing.", 'title': u'Credit where credit is due...'}, {'comment': u'FYI, this system is now maintained at pydispatcher.sourceforge.net\nwith additional features and bugfixes. (Not by me)', 'title': u'now a separate sourceforge project'}, {'comment': u'Another variant called Louie is now available at http://louie.berlios.de/.', 'title': u'Now there is Louie, too.'}], 'desc': u'This module, dispatcher.py, provides global signal dispatching services suitable for a wide variety of purposes, similar to Model-View-Controller or Model-View-Presenter patterns. This particular implementation allows a looser coupling than most Observer patterns. It also does transparent cleanup through the use of weak references and weak reference callbacks. This version defaults to using weak references, but provides an option to not use weak references for those cases where weak references are problematic (lambdas and such).'}, {'comments': [], 'desc': u"Script that raises an error when you didn't declare a property in the __init__ method."}, {'comments': [], 'desc': u"r'''Initialize the Python runtime environment when the interpreter starts.\n\nLocal modules are kept in a PythonLib directory instead of site-packages,\nso they are not affected by updating, replacing, or removing the Python\ndirectory tree under Windows.\n"}, {'comments': [{'comment': u'Queue.Queue does not have a pop() method.\nIt does however have a get() method.', 'title': u'pop or get?'}, {'comment': u'For me, this outputs:\nz b a c d', 'title': u'output'}, {'comment': u'typo corrected.', 'title': u'output'}, {'comment': u"I don't quite understand what you mean. the pop() call in _get-calls the internal queue-data structure, which is python list.", 'title': u'pop method'}, {'comment': u'Would using bisect.insort_right() cause problems?\ni.e. <br>\n<pre>\n def _put(self, item):\n bisect.insort_right(self.queue, item)\n</pre>\nseems to work nicely.\n<br>\nI also found a \'top\' method useful: <br>\n<pre>\n def top(self):\n "non-destructively return smallest element in pqueue"\n try:\n x = self.queue[0]\n except IndexError:\n x = None\n return x\n</pre>\n ', 'title': u'using bisect.insort_right()'}, {'comment': u'Using bisect.insort_right as you suggest would not work.<br>\nAssuming item is a tuple of (priority, data), then it would be inserted amongst other items in the queue with the same priority, but sorted by the value of its data, rather than by its arrival time.<br>\nYou may be able to hack around this with something like:<br>\n<pre>self.queue.insert(bisect.bisect_right(self.queue, (priority, sys.maxint)), (priority, data))\n</pre>\nif the data are all integers.', 'title': u'bisect.insort_right will not work'}, {'comment': u"why bother with bisection if you're just going to use an O(n) insert?", 'title': u'bisection'}, {'comment': u'Like this:\n\n<pre>\nfrom Queue import Queue\nfrom heapq import heappush, heappop\n\nclass PriorityQueue(Queue):\n # Initialize the queue representation\n def _init(self, maxsize):\n self.maxsize = maxsize\n self.queue = []\n \n # Put a new item in the queue\n def _put(self, item):\n return heappush(self.queue, item)\n \n # Get an item from the queue\n def _get(self):\n return heappop(self.queue)\n\nif __name__ == "__main__":\n q = PriorityQueue()\n q.put((2,"a"))\n q.put((0,"b"))\n q.put((1,"c"))\n q.put((2,"d"))\n q.put((1,"e"))\n while not q.empty():\n print q.get()\n</pre>\n\nprints b, c, e, a, d', 'title': u'Why not use a heapqueue'}, {'comment': u'I don\'t really understand the maths of heapq, but it doesn\'t seem to maintain the existing ordering. In fact if you use the example from the published 2nd edition cookbook, if you insert a series of items with the same time.time() value they get ordered according to their (undecorated) item value which is not so good. \n\nAnd I\'m a bit bothered by not re-using the bisect algorithm, so\nhere is a version that doesn\'t sort on item value, but does\nuse the bisect module.\n<pre>\nfrom Queue import Queue\nfrom bisect import bisect_left\n\nclass PriorityQueue(Queue):\n\n def _init(self, maxsize):\n self.maxsize = maxsize\n # Python 2.5 uses collections.deque, but we can\'t because\n # we need insert(pos, item) for our priority stuff\n self.queue = []\n\n def put(self, item, priority=0, block=True, timeout=None):\n """Puts an item onto the queue with a numeric priority (default is zero).\n \n Note that we are "shadowing" the original Queue.Queue put() method here.\n """\n Queue.put(self, (priority, item), block, timeout)\n\n def _put(self, item):\n """Override of the Queue._put to support prioritisation."""\n # Priorities must be integers!\n priority = int(item[0])\n\n # Using a tuple (priority+1,) finds us the correct insertion\n # position to maintain the existing ordering.\n self.queue.insert(bisect_left(self.queue, (priority+1,)), item)\n\n def _get(self):\n """Override of Queue._get(). Strips the priority."""\n return self.queue.pop(0)[1]\n</pre>', 'title': u'Using bisect module'}], 'desc': u'Thread-safe priority queue using Queue.Queue'}, {'comments': [], 'desc': u'This simple collection class forwards requests to '}, {'comments': [], 'desc': u'A scheduled queue is a queue with priorities that are scheduled. It is not preemtitive, higher priorities are not\nexecuted always before than lower priorities (only more often).'}, {'comments': [{'comment': u'The problem with this implementation is that it does not consider inheritance.\n\nWhen I override the method f in a subclass, the pre_f and post_f methods will not be called anymore. When I choose a different name for the original and the eiffelized method like here:\n<pre>\nclass C:\n def _f(self, arg):\n return arg+1\n def _f_pre(self, arg):\n assert arg>0\n def _f_post(self, result, arg):\n assert result>arg\n f = eiffelmethod(f,f_pre,f_post)\n</pre>\n\nand then override the method _f in a subclass:\n<pre>\nclass D:\n def _f(self, arg):\n return arg * 2\n\nd = D()\n</pre> \n\nthen d.f(10) will call the method of class C and return 11 instead of 20.\n ', 'title': u'Inheritance?'}, {'comment': u"When you override a method in a subclass you're changing what it does. If it does something else, it should have different pre and post conditions.\n<br><br>\nYou're free to eiffelize your new method.\n<br><br>\nThe implementation detail I *do* disagree with is that if you don't specify pre/post explicitly it will getattr the class instance to find it. In that case you can run into funky behavior when subclassing if you take advantage of this lazy feature. For example, if class A method f is eiffelized with a precondition and postcondition, class B(A) method f is eiffelized with just a precondition then the eiffelization of class B(A) method f will find the postcondition for class A method f and assume that it still applies.\n<br><br>\nI'd probably do it differently myself.. I'd allow either str or callable arguments, have a pre/post condition chain (with each returning self so you could chain them up in one line for convenience), and also allow you to specify what it throws.. This way you could have chains of pre/postconditions:\n<br><pre>\nclass NumberIsNotOdd(Exception):\n pass\ndef even_to_odd(even):\n return even + 1\neven_to_odd = eiffelize(odd)\neven_to_odd.preCondition('int(even)').preCondition(lambda even:not (even & 1))\neven_to_odd.postCondition(lambda rval:rval & 1, NumberIsNotOdd)\n</pre><br>\nPerhaps it would even be nice to be able to say that certain pre or postconditions should be run even when __debug__ == 0", 'title': u'Inheritance works.'}, {'comment': u'If I override a method in a subclass, I am changig its implementation, I am neither changig its semantics nor its contract. So, perhaps I could add further pre- and post-condition, but I cannot get out of the contract the superclass subscribed to. (Liskov\'s substitution principle)\n<br>\n<br>\nAnyway, if overriding the method should ivalidate the contract specified in the superclass, why to "eiffelize" it at all? Why not simply put the pre- and post-condition in the mehod itself? Why eiffelmethod and not simply assert?', 'title': u'Why eiffelize?'}], 'desc': u'An eiffel like method, with preconditions and postconditions, in python2.2'}, {'comments': [], 'desc': u'This recipe discribes how to change the implementation of the _run_child method in Popen3 at runtime.'}, {'comments': [{'comment': u"Isn't there a loop missing? The program starts, a voice says 'Started successfully' and then the program ends.", 'title': u'Program runs, but aborts?'}, {'comment': u"Yes, you're right. It worked fine running under PythonWin, but needed a message loop running from the command line. I've now added it.", 'title': u'Now fixed'}], 'desc': u'This is an example of using the Microsoft Speech SDK 5.1 under Windows for command and control speech recognition in Python.'}, {'comments': [{'comment': u"Hi, good source. Maybe i'm wrong, but for my own curiosity: you are using just a mixin?\nPS: sorry for my english, and...\nLINUX POWER TO U 'o)\n", 'title': u'A great MIX ! 8o)'}, {'comment': u'Thanks for the comment.<br>\nActually, instead of a Mixin, I am using nested scope inheritance.', 'title': u'Re: A great MIX ! 8o)'}], 'desc': u'This is a C++-like template based inheritance implementation in Python.'}, {'comments': [], 'desc': u'For when you need to check a web page is still working.'}, {'comments': [], 'desc': u"Translate is a powerful string function that can create groups of characters and convert one set of characters to another. We'll describe the basic pieces of translate, and how to use that to look for string in a binary file. For example, if you want to look for Berkley copyrights in MicroSoft code."}, {'comments': [{'comment': u'A slightly nicer way of doing this is to explicitly catch the\nexceptions you\'re not interested in, rather than checking the\nexception type (for which purpose, by the way, the identity\noperator seems rather strict). It\'s also useful to print a\ndebug message when you\'re testing the code, because the\nexcept: can easily mask real problems. For example, if you\nhave a function called load which can raise IOError:\n\n<pre>\nimport traceback\nfrom cStringIO import StringIO\n\nDEBUG = 1\n\ndef debug(msg):\n print msg\n\ndef load(filename):\n try:\n # Some code that might raise IOError, or another exception that you\n # weren\'t expecting, if the user is imaginitive enough...\n except (KeyboardInterrupt, IOError):\n # NOTE WELL the brackets around the exception classes -- an except\n # with two arguments means something quite different!\n raise\n except:\n if DEBUG:\n f = StringIO()\n traceback.print_exc(None, f)\n debug("uncaught exception:\\n%s" % f.getvalue())\n raise IOError, "invalid file \'%s\'" % filename\n\nload("/some/nonsense/file.txt")\n</pre>', 'title': u'Multiple except:s'}], 'desc': u'Minesweeper expects the user to enter properly bounded integers for\nmoves. Should the user enter something unexpected, the resulting exception\ncan be caught and handled in some way other than exiting.'}, {'comments': [{'comment': u'> ... startEntity and endEntity in the LexicalHandler interface (no parser call them!!) ...\n\nNot true, PIRXX _does_ call them, besides you cannot know whether your assumption holds true in the future. So you either have to inherit from the interfaces (so you get empty implementations for methods you do not overload) or provide the empty callbacks yourself. Anything else is likely to break.', 'title': u'Always provide full interfaces'}, {'comment': u"very true ! I'll add the missing callbacks...", 'title': u'Always provide full interfaces'}, {'comment': u'You have to remember you are in a CDATA section and switch off escaping in the characters() event, see \n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/84516\n\nfor the correct handling.', 'title': u'Wrong CDATA handling'}, {'comment': u'now fixed', 'title': u'Wrong CDATA handling,'}], 'desc': u"This recipe take an xml file as input and output a colorized version of this file, using html or docbook (with emphasis elements and a particular role). It provides a little command line interface and it's really easy to configure your output.\n"}, {'comments': [{'comment': u'In 2.4, use the threading.local object to get a thread-local storage. ', 'title': u'Builtin to 2.4'}], 'desc': u'Expands the idea from Thread-specific storage (by John E.Barham). \nThreadedContext is like a dictionary, but stores its data in a private namespace for every thread.'}, {'comments': [{'comment': u'<pre>\n_global_dict = {}\n\nclass Singleton:\n def __init__(self, name, bases, namespace):\n ns=[item for item in namespace.iteritems()]\n ns.sort()\n key=(name,bases,tuple(ns))\n if key in _global_dict:\n self._obj = _global_dict[key]\n else:\n self._obj = _global_dict[key] = type(name,bases,namespace)\n \n def __call__(self):\n return self._obj\n</pre>', 'title': u'This simplifies things and allows subclassing'}, {'comment': u'<pre>\nclass Singleton:\n def __init__(self, name, bases, namespace):\n self._obj=type(name,bases,namespace)\n \n def __call__(self):\n return self._obj\n</pre>', 'title': u'Even better: this is probably as simple as it gets...'}, {'comment': u"The previous examples give the correct test output, but don't function as actual classes. Doh!\n<br>\nI'll have a think about this and post back once I've tested it properly.\n<br>\nSorry for the noise!", 'title': u"...and it doesn't work"}, {'comment': u'Silly really... in the last example, I was returning a class rather than an object from my factory.\n<br>\n<pre>\nclass Singleton:\n def __init__(self, name, bases, namespace):\n self._obj=type(name,bases,namespace)()\n \n def __call__(self):\n return self._obj\n</pre>', 'title': u'This one works!'}, {'comment': u'<pre>\nWhat\'s wrong with the following code?\n>>> class A:\n... __metaclass__ = Singleton\n... var = 1\n... def __init__(self):\n... A.var = A.var + 1\n... \nTraceback (most recent call last):\n File "", line 1, in ?\n File "", line 3, in __init__\n File "", line 5, in __init__\nNameError: global name \'A\' is not defined\n>>> class A:\n... var = 1\n... def __init__(self):\n... A.var = A.var + 1\n... \n>>>\n</pre>', 'title': u'Class variables and __metaclass__'}, {'comment': u"The problem is that the Singleton is trying to construct an instance of your class before the class has finished being fully defined. Hence, you don't get access to a bound variable for your class.\n\nHere's a version that gets around that problem, although it adds a line or two more of code:\n<pre>\nclass Singleton(type):\n\n _obj = None\n \n def __init__(self, name, bases, namespace):\n type.__init__(self,name,bases,namespace)\n \n def __call__(self):\n if self._obj is None:\n self._obj = type.__call__(self)\n return self._obj\n</pre>", 'title': u"Here's a version that copes with your code"}, {'comment': u"Use 'super' to make your metaclass safe for multiple inheritance:\n\n<pre>\nclass Singleton(type):\n\n _obj = None\n \n def __init__(self, name, bases, namespace):\n super(Singleton, self).__init__(name,bases,namespace)\n \n def __call__(self):\n if self._obj is None:\n self._obj = type.__call__(self)\n return self._obj\n</pre>\n", 'title': u'One small recommended change'}, {'comment': u'If you do\n\n<pre>\nclass C:\n __metaclass__=Singleton\n\nclass D(C):\n pass\n\nc=C()\nd=D()\n\nprint d\n\nyou will see that d is None.\n\nHere is a Singleton metaclass that works:\n\nclass Singleton(type):\n def __init__(cls,name,bases,dic):\n super(Singleton,cls).__init__(name,bases,dic)\n cls.instance=None\n def __call__(cls,*args,**kw):\n if cls.instance is None:\n cls.instance=super(Singleton,cls).__call__(*args,**kw)\n return cls.instance\n</pre>\nMichele\n', 'title': u'This is not inheritance safe'}], 'desc': u'Use of metaclasses to hide access to class constructor.'}, {'comments': [{'comment': u'The code shown uses a function named "failIf". There is one by that name in the unittest module, is that what was intended?\n', 'title': u'failIf?'}], 'desc': u'This class is a basic Singleton log file creator. It allows separate classes/modules to log their activities to the same file (even the same line if they want to).'}, {'comments': [{'comment': u'A shorter version of unzip can be:\n<br>\n<pre>\nunzip = lambda l:tuple(zip(*l))\n</pre>\n\nor for older Python versions:\n<br>\n<pre>\nunzip = lambda l:tuple(apply(zip,l))\n</pre>', 'title': u'unzip'}, {'comment': u"This is very useful; I don't see why it isn't in the python standard library. When I'm doing heavy list manipulations this is extremely handy.\n\nPEP anyone?", 'title': u"Why isn't this standard?"}, {'comment': u'>>> zip((1, 2), (\'a\', \'b\'))<br>\n[(1, \'a\'), (2, \'b\')]<br>\n>>> zip((1,"a"),(2,"b"))<br>\n[(1, 2), (\'a\', \'b\')]<br>\n<br>\nWhy do we need an unzip?<br>\n<br>\nThanks,<br>\n-- sudhir', 'title': u"isn't zip its own inverse?"}, {'comment': u'unzip = lambda ll: apply (zip, ll) <br>\nsuch unzip is actually a matrix transposer; <br>\nalso unzip (unzip (ll)) == ll <br>\n\n', 'title': u'Simple unzip'}, {'comment': u'def unzip(seq): return zip(*seq)', 'title': u'Another unzip'}, {'comment': u"Zip isn't its own inverse in general, e.g.,\n<pre>\n>>> zip(zip((1, 2, 3), (4, 5, 6), (7, 8, 9)))\n[((1, 4, 7),), ((2, 5, 8),), ((3, 6, 9),)]\n</pre>", 'title': u'Zip is not its own inverse'}, {'comment': u"I just realized that this is equivalent to the first lambda expression on the top. Oh, well. It's redundant, but to my eye it looks more Pythonic.", 'title': u'Redundancy'}, {'comment': u'<pre>Zip *is* its own inverse.\n\nYou are giving your outer zip call a single argument. The inner zip<br>produces a single list of tuples. If you give zip a single argument<br>it will return what you are getting. If you precede any single list<br>with an asterisk in any function the function is passed len(list)<br>arguments.\n\nTry this:\n\n>>> zip( *zip( (1, 2, 3), (4, 5, 6), (7, 8, 9) ) )\n[(1, 2, 3), (4, 5, 6), (7, 8, 9)]\n\nKumar was manually separating the elements of his list. He was feeding<br>his second zip two arguments. He could have typed\n\n>>> zip_out= zip((1, 2), (\'a\', \'b\'))\n>>> zip( *zip_out )\n[(1, 2), (\'a\', \'b\')]\n\nand saved typing so he could focus on gaining more valuable insights.\n\n\n\nThe asterisk is necessary when using list compressions with zip.\n\n>>> zip( *[ s.split() for s in ("a b c d e f g", "t u v w x y z") ] )\n[(\'a\', \'t\'), (\'b\', \'u\'), (\'c\', \'v\'), (\'d\', \'w\'), (\'e\', \'x\'), (\'f\', \'y\'), (\'g\', \'z\')]\n\n\nDictionaries are easily created in this fashion.\n\n>>> dict( zip( *[ s.split() for s in ("Q1 Q2 Q3 Q4", "Jan Apr Jul Oct") ] ) )\n{\'Q1\': \'Jan\', \'Q3\': \'Jul\', \'Q2\': \'Apr\', \'Q4\': \'Oct\'}</pre>', 'title': u'Feed zip arguments correctly'}], 'desc': u'Inverse of zip'}, {'comments': [], 'desc': u"Maybe not too sophisticated, but a handy little tool I use for myself.\n\nThis program does the three essential tasks that (at least) I need:\n1. Unzip an archive to a folder\n2. Zip a folder to an archive\n3. Zip a (big) file to an archive\n\nFreeze it, drop it into the 'sendto' folder, and you have a very convenient way to use this program via right mouseclick/sendto->zip2folder."}, {'comments': [], 'desc': u'Break all of time up into "slices" in order to categorize events.'}, {'comments': [{'comment': u'You can replace that huge if...if...if.. block with:\n\n<pre>def __init__(self, adoField):\n\n reg_types = {win32com.client.constants.adInteger: \'integer\',\n win32com.client.constants.adCurrency: \'money\',\n win32com.client.constants.adDate: \'timestamp\',\n win32com.client.constants.adBoolean: \'boolean\',\n win32com.client.constants.adDBTimeStamp: \'timestamp\',\n win32com.client.constants.adVarWChar: \'varchar(%d)\' % adoField.DefinedSize,\n win32com.client.constants.adLongVarWChar: \'text\',\n }\n\n try:\n self.sqlString = reg_types[adoField.Type]\n except KeyError: raise "unrecognized ado field type %d" % adoField.Type\n self.name = adoField.Name\n self.adoType = adoField.Type\n self.adoLen = adoField.DefinedSize\n</pre>\n\nNext step would be to set the reg_types dicitonary outside of __init__(), so it only has to be created once.', 'title': u"Nice. Here's a cleaner, dispatch version of __init__"}], 'desc': u'Utilities are provided to open an ADO connection, list all the tables\nfound on the connection, and generate field definitions of any of\nthe tables. An ADO connection string is used to open the connection.\nThe field definitions are in the form of a PostgreSQL table creation\nscript.'}, {'comments': [{'comment': u'there is a typo in the listing, the line that says "for x in directoryWalk(fullpath):" should say "for x in dirwalk(fullpath):"', 'title': u'oops - typo'}, {'comment': u'fixed the typo mentioned above', 'title': u' '}, {'comment': u"I'm new to Python. Can you give an example of how to use this?", 'title': u'How would I use this?'}, {'comment': u'If you want to list the content of the directory "c:\\python22" you can use the following code : <br> <br>\n\n<pre> for elem in dirwalk("c:\\python22"):\n print elem</pre>', 'title': u'Example of use'}, {'comment': u'Is there a way for this to also yield empty directory paths?', 'title': u'Empty directory paths?'}, {'comment': u'I\'ve answered my own request...\n\n<pre>\ndef dirwalk(dir, giveDirs=0):\n """\n walk a directory tree, using a generator\n """\n import os\n\n for f in os.listdir(dir):\n fullpath = os.path.join(dir,f)\n if os.path.isdir(fullpath) and not os.path.islink(fullpath):\n if not len(os.listdir(fullpath)):\n yield fullpath + os.sep\n else:\n for x in dirwalk(fullpath): # recurse into subdir\n if os.path.isdir(x):\n if giveDirs:\n yield x\n else:\n yield x\n else:\n yield fullpath\n</pre>', 'title': u'Now gives empty directories!'}], 'desc': u"This is a new implementation of directory walking inspired by Fredrik Lundh's directoryWalker.py (see http://aspn.activestate.com/ASPN/Mail/Message/541112 ). This code uses a generator instead of a class, so it requires Python 2.2 or above."}, {'comments': [{'comment': u"Will only work with Python 2.2 and you need to import generators<br>\nfrom __future__ import generators<br>\n<br>\nIt also only seems to handle string sequence types.<br>\n<br>\nI'll have a look at converting it to take lists.\n\n", 'title': u'Only handles strings'}, {'comment': u'The base case should have "yield seq", not "yield seq[0]". This will make it work for all sequence types, not just strings.', 'title': u'fix for general sequences'}], 'desc': u'permIter() takes a sequence and returns an iterator that goes through all possible permutations of that sequence.'}, {'comments': [], 'desc': u'list() will convert a tuple to a list, but any elements that are also tuples\nwill stay as such. This utility function fully converts an arbitrary "tuple tree" to a same-structured list.'}, {'comments': [], 'desc': u'Associate object attributes with database columns.\n'}, {'comments': [], 'desc': u"Visual Studio can be configured to invoke a Python script during your build process. If you need to do this, you'll likely want to report errors and\nwarnings in a way that Visual Studio will understand. Here's how."}, {'comments': [{'comment': u'That\'s a good one-liner. Using %s to insert the literal % is not really necessary ("%%" does the same thing), so you could trim it down to this:\n\nshift = lambda text,sft=1:string.joinfields(map(eval("lambda ch:chr((ord(ch)-ord(\'a\')+%d)%%26+ord(\'a\'))"%sft),text),\'\')', 'title': u'good'}, {'comment': u"i changed '%s'%('%') to '%%'\nand added a test function :)", 'title': u'thanks! changed'}], 'desc': u"One liner code to shift each char of a string by some passed value\nvery simple encryption :)\nadded version 2 fixing following bugs:\n1. Capital chars are shifted correctly.\n2. Only alpha numeric chars are shifted.\n3. No hard-coded numbers so that as long as first alphabet is 'a'\n and last 'z' it will work :)"}, {'comments': [], 'desc': u'This class uses the error propagation formulae of physicists. An operator overloading example.'}, {'comments': [{'comment': u'I think there is a pair of minor bugs. In order to try this class without getting a syntax error I had to change <br>\ndel self.elems.remove(elem)\n<br>\nto\n<br>\nself.elems.remove(elem)\n<br>\nin both the remove and discard methods', 'title': u'Minor glitch'}, {'comment': u'You are absolutely right.\n\n*thwaps himself on the head for being so distracted*', 'title': u'Changed...'}, {'comment': u'took the opportunity of correcting the minor glitch and overloaded multiplication with cartesian product.', 'title': u'Added'}, {'comment': u'Nearly trivial, but the sort method is missing. Suggestion:\n<pre>def sort(self, func = cmp):\n self.elems.sort(func)</pre>', 'title': u'sort is missing'}, {'comment': u"... could I suggest the following addition?\n<br>\n<pre>\n def __getitem__ (self, index):\n return self.elems[index]\n</pre>\n<br>\nThis gives the class all that's needed to run under 2.1 (afaict). The __iter__ won't matter because 2.1 will just ignore it. I don't think that 2.2 will be bothered by the __getitem__ either: it just means that some can do a -- potentially meaningless -- lookup of a set item by index.\n", 'title': u'For those of use who have to use Python 2.1 for some reason...'}, {'comment': u"sets have no order and implementations are free to swap the order of the elements around as much as they want. It is only the fact that the underlying implementation uses a list that gives an idea of order. Just imagine a set for hashables-only implemented via dicts to see where I'm getting at. If you want a sorted *list* of the elements just ask for it:\n\n<pre>\nlst = list(my_set)\nlst.sort()\n</pre>", 'title': u'Not really'}], 'desc': u'This is a pure Pythonic implementation of a set class. The syntax and methods implemented are, for the most part, borrowed from PEP 218 by Greg Wilson.\n\nPython version: 2.2'}, {'comments': [{'comment': u'<pre>At least in XP, the screen saver can be set to "None" from the drop-down box. Selecting this option completely removes the "SCRNSAVE.EXE" Value from CONTROL PANEL\\DESKTOP, and causes an error later when trying to check/change the value.\n\nI wrote a quick solution to this, though it uses the built-in _winreg module in python.\n\nI will overlap the code sligthly so you can see where I put it.\n\n#########################################\n#On to the real work now!\n#########################################\n\n#Before we begin, lets record the state of the values that we\'ll be working with:\n\n#If no screen saver is set, we have to create the key\nimport _winreg\nkeyValName = "SCRNSAVE.EXE"\ndeleteSCRNSAVEkey = False\nn = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "CONTROL PANEL\\\\DESKTOP\\\\", 0, _winreg.KEY_SET_VALUE)\ntry:\n _winreg.QueryValueEx(n, keyValName)\nexcept WindowsError:\n deleteSCRNSAVEkey = True\n _winreg.SetValueEx(n, keyValName, 0, _winreg.REG_SZ, "")\nelse:\n n.Close()\n\n\nThis will attempt to access the value, and if it cannot, it will create the value as an empty string. I could put the value we want in now, but that would be redundant since that is taken care of later.\n\nNext, at the end of the code, I simply put:\n\nif deleteSCRNSAVEkey == True: #clean up!\n _winreg.DeleteValue(n, keyValName)\n n.Close()\n\nand it seems to work just as expected. With a screen saver set to None, it will run fine, and afterwards no SCRNSAVE.EXE value exists.\n\nThe reason I did not do n.Close() if it needed to be deleted was so we could call _winreg.DeleteValue using it later. While DeleteValue can be called with just the Key name, it will not have appropriate permissions to actually remove the Value, and will only clear the data. It needs an open handle to do so.\n\nI am sure this could have been coded into the other functions and have been much smoother, but that was not my goal. If anyone has any improvements or comments on this, they are welcome. Is this only an XP issue?</pre>', 'title': u'A problem, if a screen saver is set to "None"'}, {'comment': u"I was looking to do the same thing and came across your code. It<br>looks kind of complicated to me. Here's what worked for me.<br>\n<br>\nimport os<br>\n<br>\nwinpath=os.environ['windir']#yes, brackets not parentheses<br>\n# path to windows installation directory,<br>\n# usually c:\\windows or c:\\winnt<br>\n\n<br>\nos.system(winpath + '\\\\system32\\\\rundll32 user32.dll, LockWorkStation')<br>\n<br>\nif you want, you can use the newer subprocess.Popen() or subprocess.call()<br>", 'title': u'Easier way'}, {'comment': u"The 'LockWorkStation' function doesn't exist in Windows NT (when this recipe was written).\n\nThe only way is to call the screensaver :)", 'title': u'Only works in 2000+'}], 'desc': u'This code implements a Python solution for locking a workstation via a secure screensaver as recommended by the Microsoft KB article Q262646. It sets up a secure screensaver, then calls it. Really simple code.'}, {'comments': [], 'desc': u"A collection groups a set of objects together and forwards attribute lookups to all elements of the collection that contain the desired attribute. It's not an error for an element of the collection to be missing an attribute. The list returned is just missing that value. The same holds true when forwarding __call__.\n"}, {'comments': [{'comment': u"If UserDict.__init__ is actually passed a dictionary from __init__, then it will attempt to call update; but _keys isn't yet defined, and so an error will be raised. Therefore _keys must be defined first: \n\n<pre>\n def __init__(self, dict = None):\n self._keys = []\n UserDict.__init__(self, dict)\n</pre>\n", 'title': u'Bug in __init__ regarding _keys'}, {'comment': u'I made the above change to the source. Thanks for catching this.', 'title': u'Bug in __init__ regarding _keys'}, {'comment': u'There is a more complete module addressing this topic under\nhttp://home.arcor.de/wolfgang.grafen/Python/Modules/Modules.html called\nseqdict. \n<br>\n* seqdict keeps one value for one key \n<br>\n* mseqdict keeps multiple values per key and is the closest emulation of areal world dictionary. \n<br>\n\n(Search Parnassus for seqdict)', 'title': u'Ordered Dictionary at Parnassus'}, {'comment': u'There is a serious problem with copy()\nThe returned object instance is one of UserDict not of odict.\nI use:\n\n<pre>\ndef copy(self):\n newInstance = odict()\n newInstance.update(self)\n return newInstance\n</pre>\n\nand for update:\n\n<pre>\ndef update(self, dict):\n for (key,val) in dict.items():\n self.__setitem__(key,val)\n</pre>', 'title': u'Serious bug in copy()'}, {'comment': u'It would be better to have\n\n<pre>\n def keys (self):\n return self._keys[:]\n</pre>\n\nto prevent changes to self._keys by callers of the keys() method.', 'title': u'keys() should return a copy of self._keys'}, {'comment': u'setdefault returns the value (new or existing) for the given key.<br>\nhere is a correct setdefault:<br>\n\n<pre>\ndef setdefault(self, key, failobj = None):\n if key not in self._keys: self._keys.append(key)\n return UserDict.setdefault(self, key, failobj)\n</pre>', 'title': u'Bug in setdefault'}, {'comment': u'I needed a Sorted Dictionary and this Ordered Dictionary made a great starting point.\n\nI substituted:\n bisect.insort(self._keys,key)\nfor:\n self._keys.append(key)\n\nin a few places and I was there.\n\nThanks for the help', 'title': u'Extending to Sorted Dictionary'}], 'desc': u'This dictionary class extends UserDict to record the order in which items are added. Calling keys(), values(), items(), etc. will return results in this order. This works similarly to the array type in PHP.'}, {'comments': [{'comment': u"Just have a look at:\nhttp://sourceforge.net/projects/gnuplot-py/\n- there's quite a complex module already that works on the basis of your reciepe.\n", 'title': u'gnuplot.py'}, {'comment': u'Pexpect was designed just for this type of application.\nPopen has a lot of problems when working with\ninteractive child applications. You application is safe because\nit does not try to read back any of the GNUPlot responses, but if you did want your script to depend on responses from the child, then a pipe will not work.\n<br><br>Try Pexpect here:<br>\n http://pexpect.sourceforge.net/ <br>\n ', 'title': u'Try Pexpect instead of popen when you want to use python as a glue language'}], 'desc': u'os.popen is really great when you need to drive a text based software.\nHere is a sample of use which create animated graphics using the free software gnuplot.'}, {'comments': [], 'desc': u'script for making executables with py2exe'}, {'comments': [{'comment': u"I had to change line 66 to read:<br>\nfor store in win32com.client.GetObject('LDAP://'+ldap_store):<br><br>\n\ninstead of:<br>\n\nfor store in win32com.client.GetObject('LDAP://'+ldap_ex_store):<br><br>\n\nto use the variable ldap_store set on line 64. Once I did this, the script worked fine. Just a typo.", 'title': u'Works well once variable name is fixed...'}, {'comment': u'Thanks for noticing the typo. I fixed it.', 'title': u'Thanks.'}, {'comment': u"the script breaks if you have more than one admin group, like we do. A simple for loop and one or two changes sorts that out:<br><br>\n\nfor admin_grp in admin_grps:<br>\n print ' Administrative Group:',admin_grp.cn\n ", 'title': u'for multiple admin groups'}], 'desc': u"Active directory is wordy and very detailed. It can be daunting to first figure out what you need to know to interface with it. Here is some simple code to discover information about the exchange environment you are in. This isn't a full discussion of how to manage exchange with active directory. I thought I'd get something out now and then plan to add that when I get time."}, {'comments': [], 'desc': u'"property", a very nice new Python 2.2 feature that allows to specify per-attribute access logic, has one drawback: it requires to specify attribute access functions (fget and/or fset) even if direct access to the attribute is needed (the case when f.i. only setting the attribute must be controlled but getting can be performed directly). There is an excellent solution for this problem in systems like Delphi or Borland C++ Builder: a programmer can specify the name of a member variable as a getter and/or setter of a property, in which case corresponding property access goes directly to that member variable.\nHere is a proposed solution for Python:'}, {'comments': [], 'desc': u'The filesystem on Windows usually preserves the case of filenames, but is case insensitive if you are accessing files.'}, {'comments': [{'comment': u"This gives an incorrect answer for non-zero base systems. For instance, if BASE8=12345678 then decimal '9' should be octal '11'. Instead, it's given as '21'.", 'title': u'Does not handle non-zero systems'}, {'comment': u'The digits for BASE8 would be "01234567", not "12345678". With the latter set of digits, decimal 9 is properly output as \'22\' (octal, but not with the standard digits). The standard octal for decimal \'9\' is \'11\'. \n\nNote that baseconvert("9","123456789","12345678") will output \'21\', but that input is not a decimal 9. It\'s a decimal 8.', 'title': u'confusion about "non-zero systems"'}, {'comment': u'Python 2.3:\n<br>\n<br>\n>>> baseconvert(9,"01234567890","01234567")\n<br>\n\'11\'\n<br>\n<br>\nthis is ok, but\n<br>\nthan:\n<br>\n<br>\n>>> baseconvert(10,"01234567890","01234567")\n<br>\n\'13\'\n<br>\n<br>\nI thin, it should be 12 ??\n<br>\n<br>\nBest regards.\n<br>', 'title': u'What abut OCT ?'}, {'comment': u'the BASE10 was wrong :)))', 'title': u'Sorry'}, {'comment': u'This problem appears to have something to do with the number of digits in the base10 number being converted. \n\nIn [28]: baseconvert(99,"01234567890","01234567")\nOut[28]: \'154\'\n\nIn [29]: baseconvert(100,"01234567890","01234567")\nOut[29]: \'171\'', 'title': u'further confirmation'}, {'comment': u'Been just trying baseconvert(0, BASE10, BASE62), it simply returns null string. A simple solution is to add:\n<pre>\nif x == 0:\n res = todigits[0]\n</pre>\njust below the res="" line for the correct operation.', 'title': u'0 (Zero) does not work?'}, {'comment': u'With a little re help, you can convert back from a word representation \nlike "OneZeroOne". I believe this will work as long as you use words \nthat start with a capital as you have done. The approach is to use an \nalternation regex expression to split the number into "digits" and \nthen continue as you already do. \n<br><br>\nAt the start of the def, put an "import re" statement and then replace \nthe "for digit in str(number)" with the following:\n<pre>\n fromdigits=list(fromdigits)\n pat=fromdigits[:]\n pat.sort(lambda x,y:cmp(len(y),len(x))) #longest first\n pat="(%s)" % \'|\'.join(pat)\n number=[tmp for tmp in re.split(pat,str(number)) if tmp!=\'\']\n for digit in number:\n\n</pre>\n<br>\nHere is a demonstration:<br>\n<pre>\n###\n>>> BASEWORDS=(\'Zero\',\'One\')\n>>> BASE2=\'01\'\n>>> baseconvert(\'OneZeroOne\',BASEWORDS,BASE2)\n\'101\'\n>>> \n###\n</pre>', 'title': u'you can inter-convert with Word-representations'}], 'desc': u'This is a traditional base converter with the twist that it\naccepts any strings as the digits for the input and output bases.\n\nBesides all the normal base-converts, you can now create compact\nversions of huge numbers by converting them to a base that uses\nall the letters and numbers for its digits, for example.'}, {'comments': [{'comment': u'I\'m not seeing the advantage over python\'s own % operator. If\nyou used %( and )s for the "start and end tokens", the % operator will easily interpolate in a dictionary of replacements. \n<br>\n <pre>"SELECT * from User WHERE id=%(ID)s AND domain like \'%(Domain)s\'" % { "Domain": "python.org", "ID": "007" }</pre><br>\ngives<br>\n<pre> "SELECT * from User WHERE id=007 AND domain like \'python.org\'"</pre>\n<br>\nand it\'s already available in all python programs.', 'title': u'advantage over % ?'}, {'comment': u'oops,\n\nthis was defenitly a case of rtfm on my side.\ndidnt know, that this is possible.\n\nso the only advantage might be to have\na automatic representation of an object\n(not very much i admit)\n\nciao robertj\n', 'title': u' '}], 'desc': u"is a very simple templating-system.\nthe goals of this 'system' were\n- easy to use and to learn\n cheetah and yaptu for example was much to complex to\n install and learn and did a lot of things i didnt need.\n- easy to change.\n blender is going to be used and serviced by python newbies.\n there is absolutely no chance to have something like\n complex regexes, evaluation or automatically including\n the namespaces and the like.\n- much cooler name than 'yaptu' ;-)"}, {'comments': [{'comment': u'I don\'t see why the first function isn\'t just "return \'.\'.join(map(str,seq))". Perhaps there\'s a reason, but I can\'t\nthink of it. Either way, you\'ll get len(seq) numbers in your\nresult; zeros are handled correctly; and I can\'t see how speed/memory\nconcerns would ever come into play for a function like this. (I \nsuspect my version is faster, in any case.) \n<br>\nGreat example of calling join() on a literal string, by the way.', 'title': u"what's the advantage of the %s interpolation?"}, {'comment': u"Um, because I didn't think of it? :-)\n\nYou're right, though, that's probably a better approach and is most likely faster.", 'title': u' '}], 'desc': u'It is common for Python modules to export their version number in list or tuple form. While it is simple to convert a dot-delimited string to a tuple, it\'s subtle and tricky to go the other way, particularly when you don\'t know how many "digits" there are. This recipe includes a pair of functions that convert between forms. Also handy for IP addresses!'}, {'comments': [], 'desc': u'This is a basic re-implementation of fileinput using generators. It supports all basic functionality that the library module has (nextfile(), lineno(), filelineno(), close(), and filename()). It also adds an __iter__() method that is a generator.'}, {'comments': [], 'desc': u'Many people are used to having printf with its format expansion. Using lambdas and pythons % expansion, this can be done in a single line. It also does not add spaces or newlines (as print does).'}, {'comments': [{'comment': u"The line \n\n<pre>\nexec('import %s as module' % modulename)\n</pre>\n\ncan be replaced by \n\n<pre>\nmodule = __import__(modulename)\n</pre>\n\nUsing exec can significantly impact the performance of the program.\n", 'title': u'Use __import__ rather than exec'}, {'comment': u' ', 'title': u'Roger that!'}], 'desc': u'The following recipe ensures unit tests are run whenever the code is compiled.\n\n-- See <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/125385">microtest.py</a>'}, {'comments': [{'comment': u"In python 2.2, with class methods, you can write things like:\nFoo.bar()\nThe same thing with the previous classmethod function raise:\nunbound method must be called with instance as first argument.\n\nBy the way, the code use nested scopes so it won't work with old python versions.", 'title': u'not absolutly similar to 2.2 class methods'}, {'comment': u'Yeah,\nIt\'s got some problems, but I have used this effectiely regardless.\n\nThanks for the comment. Maybe you can help me with this one.\n\nMaking __setattr__, and __getattr__ into classmethods I get the \nfollowing error:\n<pre>\nclass Foo:\n def __setattr__(klass, name, value):\n return setattr(klass, name, value)\n __setattr__ = classmethod(__setattr__)\n def __getattr__(klass, name):\n return getattr(klass, name)\n __getattr__ = classmethod(__getattr__)\nf = Foo()\nf.junk = \'junk\'\nTraceback (most recent call last):\n File "", line 1, in ?\n File "C:\\Python\\Python22\\junk.py", line 15, in ?\n f.junk = \'junk\'\nTypeError: \'classmethod\' object is not callable\n\n\nThis DOES work with my classmethod?! Any ideas?</pre>', 'title': u'Yup ...'}, {'comment': u'For this classmethod to work the following statement is needed:\n<pre>\nfrom __future__ import nested_scopes\n</pre>\n\ncf. http://www.python.org/doc/2.1/ref/nested-scopes.html ', 'title': u'Python2.1 needs nested_scopes'}], 'desc': u"Class methods were introduced in python2.2. The following code illistrates how the same effect can be achived in python 2.1 and probably under although I haven't checked."}, {'comments': [], 'desc': u'Since the class is itself a singleton, it makes since to utilize it as such. The solution is to make every thing in sight a classmethod.\n\nSee\n\n<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52558"> ...We don\'t need no stinkin\' singleton: Borg class</a>\n\n<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/102187">The Singleton Pattern implemented with Python</a>\n\n<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/113645">classmethod</a> \n'}, {'comments': [], 'desc': u'List like protocol for bit field manipulation'}, {'comments': [], 'desc': u'An example of using the MS Speech SDK to implement TTS (Text-To-Speech).'}, {'comments': [{'comment': u'Hi,\n\nI am not familiar with Python but I want to build an activeX control in which the IE can use this object to speed up the download of a resource e.g. Flash movie. If you can guide me how to write it in ActiveX Control..that will be great...but if not, I hope you can explain the concept behind this in details possible. I am sorry to bug you here but I have been searching high and low for something that can guide me and apparently I only found yours which is the one and only I can find so far.\n\nI would really appreciate your help and guidance if you can generously help me. Thanks in advance and I really mean it.\n\nfrom,\n Steven', 'title': u'can this be done in ActiveX Control'}, {'comment': u"Hi! there Mr.Steven and Mr.Nelson, I am Santosh.M.Pillai a software engineer from india. \nWell friends problem is also as similar to the ones stated by Mr.Steven. I too want to make \nan Win32 running application and I am not familiat with Python so I am unable to understand\nthe logic and convert the pythyon code in Win32 application. I too searched the Web for \ninformation on File segmentation and mutiple connection download, logic details but couldn't\nfind any. If u people have any(any) information eg.URL or documentation regarding \nthese topics please help me. I hope u people will help to solve this problem. Thanksxx\nin advance. Expecting a reply soon.{ pillai_santosh@indiatimes.com ]. Thankyou.\n\n", 'title': u'Help'}], 'desc': u"A fast multi-part file downloader ala FlashGet, GetRight, Gozilla, etc. Currently only supports HTTP but FTP wouldn't be hard. Use this instead of wget. ;-)"}, {'comments': [{'comment': u"You could also express this as:\n<pre>\nquit = 0\ndef kill():\n global quit\n quit = 1\n\nserver = MyServer(('127.0.0.1', 8000))\nserver.register_function(kill)\n\nwhile not quit:\n server.handle_request()\n</pre>\nThis saves you the hassle of subclassing SimpleXMLRPCServer.\n", 'title': u'Easier way'}, {'comment': u"Brian Quinlan adds a nice enhancement to the original code. But don't\nforget to add a return statement to the kill function.\n<pre>\ndef kill():\n global quit\n quit = 1\n return 1\n</pre>", 'title': u'return value'}, {'comment': u'<pre>import SimpleXMLRPCServer\nclass Server:\n quit = False\n def __init__(self):\n self.server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8888))\n self.server.register_instance(self)\n while not self.quit:\n self.server.handle_request()\n def shutdown(self):\n self.quit = True\n return 0\n def other_functions():pass\nServer()\n</pre>', 'title': u'Slicker?'}, {'comment': u'The idea is good but doesn\'t seem to help me with handling signals like Ctrl+C in the console too well. \n<br>\nBelow I have put a complete, standalone script that provides an alternative server that has built-in support to map signals to a clean shutdown and an exposable shutdown method if you want to allow that via XML-RPC.\n<br>\nThere are pros/cons to using a subclass approach, but it may be useful for some...\n<br>\n<pre>\n#!/usr/bin/env python\nimport socket, signal\nfrom SimpleXMLRPCServer import *\n\nclass AltXMLRPCServer(SimpleXMLRPCServer):\n\n\tfinished=False\n\t\n\tdef register_signal(self, signum):\n\t\tsignal.signal(signum, self.signal_handler)\n\t\t\n\tdef signal_handler(self, signum, frame):\n\t\tprint "Caught signal", signum\n\t\tself.shutdown()\n\t\t\n\tdef shutdown(self):\n\t\tself.finished=True\n\t\treturn 1\n\n\tdef serve_forever(self):\n\t\twhile not self.finished: server.handle_request()\n\n\nclass MyFuncs:\n\tdef div(self, x, y) : \n\t\t"""Returns division of two numbers"""\n\t\treturn x // y\n\n\tdef add(self, x, y) : return x + y\n\n\nhostname=socket.gethostname(); port=8086\nserver = AltXMLRPCServer((hostname, port))\nprint "Serving on %s:%d" %(hostname, port)\nserver.register_function(pow)\nserver.register_function(server.shutdown)\nserver.register_function(lambda x,y: x-y, \'minus\')\nserver.register_introspection_functions()\nserver.register_instance(MyFuncs())\nserver.register_signal(signal.SIGHUP)\nserver.register_signal(signal.SIGINT)\n\nserver.serve_forever()\nprint "Closed"\n</pre>', 'title': u'Handling signals better'}], 'desc': u'this shows how to enable a SimpleXMLRPCServer to be cleanly killed (exited) by a client. '}, {'comments': [{'comment': u'I want to know more on how you use the Thread class to get two sockets to talk to eachother. I want to set a socket server and then forward all incoming data to a client connection (This server and client is in the same script) that connects to another socket server on a different machine.\nThanks Your code looks simple enough so that I can use the idea.\n\nJohan', 'title': u'Pinhole'}], 'desc': u'Pinhole is a simple network utility that forwards a port\nto the host specified. The optional newport parameter\nmay be used to redirect to a different port on the target\nhost. Uses threads gratuitously.\n\n'}, {'comments': [{'comment': u'PythonCard\nhttp://pythoncard.sourceforge.net/\ncontains a turtle graphics sample app which include Koch curves and many other standard fractal patterns. You can program one or more turtles interactively or write standalone scripts. There are some sample shots of the turtles in action at\nhttp://pythoncard.sourceforge.net/samples3.html', 'title': u'PythonCard contains a turtle graphics sample app'}], 'desc': u'wxKoch draws a Koch snowflake fractal. It is based on C++ code\nwritten by Martin Bernreuther and included in the wxWindows\ntutorial.\n'}, {'comments': [{'comment': u"On MacOS X this didn't work, because a jittery timer leads to a negative (self._runtime - start) which is in turn an invalid argument to time.sleep(). Changing the last line in Thread.run() to \n<pre> \ntime.sleep( max( 0, self._runtime - start ) ) \n</pre> \nfixes this.", 'title': u'Fix for OSes with jittery timer.'}, {'comment': u'I gather that this recipy is superceded by the sched module from the standard library?', 'title': u'Superceded by the sched module?'}], 'desc': u'A simple multi-threaded scheduler that enables\ntasks to be run at specified intervals.'}, {'comments': [], 'desc': u'Mock up a html page on-the-fly. This one looks like\na remote-sensing weather station. Just add rain gauge,\nanomometer, etc to suit.'}, {'comments': [], 'desc': u'A simple function to extract a subset of items from a dictionary.'}, {'comments': [{'comment': u'I didn\'t read the above example very carefully, but I do know\nhow to draw a transparent-background pygame surface with opengl.\nHere\'s the relevant code from my program:\n<pre>\n glEnable(GL_BLEND)\n glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)\n\n rendered=pygamefont.render(text,1,[int(c*255) for c in color])\n txtsize=txtdata.get_size() \n txtdata=pygame.image.tostring(rendered,"RGBA",1)\n\n glRasterPos2d(*pos)\n glPixelZoom(1,1)\n glDrawPixels(txtsize[0],txtsize[1],\n GL_RGBA, GL_UNSIGNED_BYTE, txtdata)\n</pre>', 'title': u'how to make the background transparent'}], 'desc': u'An OpenGL example in Python using PyOpenGL and PyGame modules to render a spinning triangle while the FPS (Frames Per Second) is displayed in the upper right hand corner using a TrueType font.'}, {'comments': [{'comment': u'Oh yah, and btw... all of this code is Public Domain if you guys are wondering. I forgot to mention that.', 'title': u'Copyright'}], 'desc': u"Let's you create a password db and let users login, etc.\nThis is not a real password system, its just something I came up with.\nIe. Don't try using this on /etc/passwd"}, {'comments': [{'comment': u'It may be worth noting that the module only handles dates since the adoption of the Gregorian calendar reforms; different states adopted the reforms at different times from the 16th century onwards.\n\nAlso, might it be better to employ the date manipulation services provided by the mxDateTime package?', 'title': u'mxDateTime?'}, {'comment': u'Well it was a programming exercise. The guy I was helping had to show to his teacher he was capable of actually programming this.\n\nYes there is plenty of room for improvement.', 'title': u'Okay...'}, {'comment': u"Wouldn't it have been easier to;\nimport time\nand convert the two dates to a unix timestamp then find the difference in seconds and devide the result by 86400 (seconds in a day).\n\nJust a thought.", 'title': u'Was the objective of the task to re-invent the wheel?'}, {'comment': u'I have converted the code to a Java program and for two dates that have the same year, it does not work. Hmmm.....', 'title': u"Doesn't work"}], 'desc': u'Finds the number of days between two dates.'}, {'comments': [{'comment': u'The fetchstatus method can loop forever if you ask for the wrong\nstatus. The service name requires an exact match (case sensitive)\nto process a service. This is stricter than the underlying\nsystem functions.', 'title': u'usage difficulties'}, {'comment': u'It\'s true the fetchstatus method can run forever but I don\'t see that as a bad thing, do you? It\'s not often we have things that can last forever, so I say enjoy it and let it rip! ;-) Actually I\'ve updated the method, it now supports a timeout argument but forever is still the default. For the hard corers out there! lol \n<br><br>\nThe service name thingy... I thought "What\'s so hard about pulling the name out of the service control manager? Just double click on the service and then CTRL-C." when I wrote it. So I think the service name lookup is being a bit picky but it\'s been adjusted. It now supports long and short names with mixed cases. The feature in the win32serviceutil where it does the kinder, gentler service name lookup isn\'t that low level though. It uses some of the very code on this cookbook site. Look for the "Get the Windows service name from the long name" recipe, it\'s in the System Admin section. I\'m not sure which came first though, the recipe or the win32serviceutil? \n<br><br>\nThanks for the comments. Keep them coming! ;-)', 'title': u'Re: usage difficulties'}, {'comment': u"I wrote a small python hack using the sc.exe command to poll our Win2000 Domain Controller's Service status. I mainly look at ntfrs for File Replication. Would it be possible to add this ability to WService?", 'title': u'Review status of remote servers'}, {'comment': u"Good question. I've modified WService to work with remote machines but I'm not sure if it works correctly since I don't have a setup to properly test it. I believe the api depends on one or more services, namely the Server and possibly the RPC's and/or Remote Registry services, running on the remote machine. It would be great if you could test it and let me know if it works.", 'title': u'Re: Review status of remote servers'}], 'desc': u'The WService Class is used for controlling WinNT, Win2k & WinXP like services. Just pass the name of the service you wish to control to the class instance and go from there.'}, {'comments': [{'comment': u'def refineFTPList(sites): return filter( isFTPSiteUp, sites )', 'title': u'simpler definition of refineFTPList'}, {'comment': u"False is a built-in.<br>\nNot sure that we care about the specific exception raised.<br>\nquit returns a non-null value (usually '221 Goodbye.') when it succeeds.<br>\nSo how about:<br>\n<pre>\nfrom ftplib import FTP\n\ndef isFTPSiteUp(site):\n try:\n return FTP(site).quit()\n except:\n return False\n\ndef refineFTPList(sites): return filter( isFTPSiteUp, sites )\n\nprint refineFTPList( ['ftp.cdrom.com', 'ftp.redhat.com', 'ftp.ska143blah.com'] )\n</pre>", 'title': u'another refactoring'}], 'desc': u'A pair of functions for checking whether FTP sites are up. The refineFTPList() function will take in a list of FTP sites and returns a list of sites that are not down. The isFTPSiteUp() function checks a particular FTP site to see if it is up.'}, {'comments': [{'comment': u'Good idea. See my xml2obj recipe which is a variation on the theme that uses the expat parser for lower overhead and a stack to keep track of parents.', 'title': u'An alternate solution'}, {'comment': u'pyRXP from Reportlab turns XML into a python tuple tree and is extremely fast. Check it out (http://www.reportlab.com/xml/pyrxp.html)\n', 'title': u'Check out pyRXP'}, {'comment': u"Shouldn't the first\n\n<pre>\ndic.update({n.nodeName:l})\n</pre>\n\nbe outdented one level? Otherwise, it's adding the partially-built list to the dictionary every time through the loop. (Or maybe it's late and I'm seeing double. ;-)", 'title': u'buglet?'}, {'comment': u'Great idea! Very nice for small config.\nIt is also good to add something like this:\n<pre>\ntmp = nodeToDic(c)\nif tmp != {}\n l.append(tmp)\nelse:\n l.append(getTextFromNode(c))\n\neg. piece of xml file\n\n<Shared multiple="true">\n <Folder>c:\\Mp3</Folder>\n <Folder>d:\\Tmp</Folder>\n</Shared>\n\nwithout: {.. u\'Shared\': [{}, {}] ..} ,\nwith: {.. u\'Shared\': [u\'c:\\\\Mp3\', u\'d:\\\\Tmp\'] ..}\n</pre>', 'title': u'Improvement?'}, {'comment': u"How about this as an alternative to allow it to work without specifying the multiple attribute?\n\n<pre>\ndef nodeToDic(node):\n\n dic = {}\n multlist = {} # holds temporary lists where there are multiple children\n multiple = False\n for n in node.childNodes:\n if n.nodeType != n.ELEMENT_NODE:\n continue\n\n # find out if there are multiple records\n if len(node.getElementsByTagName(n.nodeName)) > 1:\n multiple = True\n # and set up the list to hold the values\n if not multlist.has_key(n.nodeName):\n multlist[n.nodeName] = []\n\n try:\n #text node\n text = getTextFromNode(n)\n except NotTextNodeError:\n if multiple:\n # append to our list\n multlist[n.nodeName].append(nodeToDic(n))\n dic.update({n.nodeName:multlist[n.nodeName]})\n continue\n else:\n # 'normal' node\n dic.update({n.nodeName:nodeToDic(n)})\n continue\n\n # text node\n if multiple:\n multlist[n.nodeName].append(text)\n dic.update({n.nodeName:multlist[n.nodeName]})\n else:\n dic.update({n.nodeName:text})\n return dic\n\n\n</pre>", 'title': u'Another improvent?'}], 'desc': u'I decided not to customize the xml-parser to fit the structure of a xml-document, but to make a parser that adapts the structure of the document. By converting the xml-document in this way, the access to the elements is simple and code-customization is minimal.'}, {'comments': [{'comment': u"According to the Python documentation:\n<br><br>\nclass HTTPSConnection( \thost[, port, key_file, cert_file])\n A subclass of HTTPConnection that uses SSL for communication with secure servers. Default port is 443. key_file is the name of a PEM formatted file that contains your private key. cert_file is a PEM formatted certificate chain file.\n<br><br>\n Warning: This does not do any certificate verification!\n<br><br>\n New in version 2.0. \n<br><br>\nIf this doesn't do certificate verification, it seems to be very incomplete. Is there anyway to verify the certs or is this planned in a future release? The article/code snippet should state this defiency.", 'title': u"Doesn't do authentication"}, {'comment': u'I believe the comment in the Python docs means that Python code does not check or verify the peer certificate. However, the files do seem to be presented to the connection peer properly. When tested against Apache, an unexpected certificate was rejected and only certificates from the proper authorities were accepted.', 'title': u'Authentication to Apache worked'}], 'desc': u'A 16-line python application that demonstrates SSL client authentication over HTTPS. We also explain the basics of how to set up Apache to require SSL client authentication. This assumes at least Python-2.2 compiled with SSL support, and Apache with mod_ssl.'}, {'comments': [{'comment': u'Nice short and clear recipe, however, <br>\nInstead of:\n<pre>\n\tif D.has_key(p+q):\n\t\tD[p+q].append(p)\n\telse:\n\t\tD[p+q] = [p]\n</pre>\nI would use:\n<pre>\n D.setdefault(p+q,[]).append(p)\n</pre>\n\nSee: Add an entry to a dictionary, unless the entry is already there. <br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66516 \n\n', 'title': u'Shortcut'}, {'comment': u'neat indeed, but we can be marginally faster (about 40%+ on my machine for primes up to 1,000,000 for example) by keeping in the dict a single value for each composite number -- the first prime factor that revealed to us that number is a composite. Here\'s the Python 2.3 code for the enhanced main loop:\n<pre>\n while True:\n p = D.pop(q, None) \n if p:\n x = p + q\n while x in D: x += p\n D[x] = p\n else:\n D[q*q] = q\n yield q\n q += 1\n</pre>\nthis uses the new-in-2.3 "fetch and remove" method .pop of\ndictionaries, but that\'s marginal (and I put just the same\nsmall enhancement in the list-using version -- I posted both\nto comp.lang.python just now) -- the small speedup in this\nvariant comes from not having to build so many small lists.\n\n\nAlex\n', 'title': u'slightly faster by keeping a dict of single numbers instead of one of lists'}, {'comment': u"haskell's canonical version:\n<pre>\nprimes = sieve [ 2.. ]\n where\n sieve (p:x) = p : sieve [ n | n <- x, n `mod` p > 0 ]\n</pre>\n\ntranslates roughly to python as:\n<pre>\nimport itertools as it\ndef sieve(num=it.count(2)):\n p=num.next()\n x=sieve(n for n in num if n%p)\n yield p\n while True: yield x.next()\n\n</pre>\nUnfortunately it exceeds the recursion limit after about 3000 on my machine.", 'title': u"I hapen to like haskell's"}, {'comment': u"<pre>\ndef sieve():\n yield 2\n D = {}\n q = 3\n while True:\n p = D.pop(q, 0)\n if p:\n x = q + p\n while x in D: x += p\n D[x] = p\n else:\n yield q\n D[q*q] = 2*q\n q += 2\n</pre>\n\nIt's too bad itertools.count doesn't take a step argument! This would look cleaner, and likely be marginally faster, with \n<pre>\n for q in count(3,step=2)\n</pre>\nrather than the current while True cruft. ", 'title': u'Slightly faster yet by skipping even numbers'}, {'comment': u"<pre>\nfrom itertools import count, ifilter\ndef sieve():\n seq = count(2)\n while True:\n p = seq.next()\n seq = ifilter(p.__rmod__, seq)\n yield p\n</pre>\nThis uses ifilter to generate the recursive sequence. It's much less vulnerable to stack overflow than the version that recurses on sieve, but otherwise it's pretty similar.\n\nI managed to generate all primes up to 909,691 before it bombed the Python interpreter mysteriously, but it takes a while!", 'title': u'Another recursive version'}], 'desc': u'Computes an infinite sequence of primes using simple generators. A Python dictionary is used to mark multiples of the generated primes, according to the Sieve of Eratosthenes.'}, {'comments': [{'comment': u"Nice job in a few lines of code. I'd like to see the namespace-polluting import line replaced, especially in published Python code.\n<pre>\nreplace: from socket import *\nwith: from socket import socket, AF_INET, SOCK_DGRAM\n</pre>", 'title': u'from socket import *'}, {'comment': u"I can't login to change this code having lost my account details\nbut the codes so short I can just post it here.\n\n<pre>\nimport socket\nimport struct\nimport sys\nimport time\n\nTIME1970 = 2208988800L # Thanks to F.Lundh\n\nclient = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )\ndata = '\\x1b' + 47 * '\\0'\nclient.sendto( data, ( sys.argv[1], 123 ))\ndata, address = client.recvfrom( 1024 )\nif data:\n print 'Response received from:', address\n t = struct.unpack( '!12I', data )[10]\n t -= TIME1970\n print '\\tTime=%s' % time.ctime(t)\n</pre>", 'title': u'Done as requested'}], 'desc': u'Uses the SNTP protocol (as specified in RFC 2030)\nto contact the server specified in the command line\nand report the time as returned by that server. This\nis about the simplest (and dumbest) client I could\nmanage.'}, {'comments': [{'comment': u"It's looking cool, but in my tests 500-700 times slow:\n<pre>\nimport random, time\n\nbigstr = ''.join(map(lambda i:chr(random.randrange(32,127)), xrange(650000) ))\ninstr = ''.join(map(lambda i:chr(random.randrange(32,127)), xrange(3) ))\nprint 'Searching', instr, 'in', bigstr[:30]\n\nt=time.clock()\ni = 0\nfor f in KnuthMorrisPratt(bigstr,instr): i += 1\nprint 'Found',i,'times, in', time.clock()-t,'clocks'\n\nt=time.clock()\ni = 0\npos =0\nwhile 1:\n pos = bigstr.find(instr)\n if pos<0:break\n i += 1\n bigstr = bigstr[pos+1:]\nprint 'Found',i,'times, in', time.clock()-t,'clocks'\n</pre>\nOutput:\n<pre>\nSearching 2SM in s<.z~GWKoA\\NrDmxCzZ[[eRlXnRy(V\nFound 3 times, in 5.43653341416 clocks\nFound 3 times, in 0.0177835451154 clocks\n</pre>", 'title': u'benchmarks'}, {'comment': u'Thanks for the comment. Partly, the slowdown you saw is the penalty for using interpreted code instead of built-in functions. But partly, you chose parameters that would make the built-ins look good and my KMP implementation look bad: your code pays a linear-time penalty every time it finds a match, while increasing the number of matches does not slow my function down much. Random data does not have a large number of matches, compared to most situations where one would use a string matching routine. If I change your test code only very slightly, to limit the character set in your random strings to four characters (increasing the number of matches, and also increasing the similarity to biological data), the statistics look very different:\n\n<pre>\nSearching ! ! in "!""! "" " !!!" " !"" ! \nFound 24136 times, in 6.455586 clocks\nFound 24136 times, in 49.912182 clocks\n</pre>\n\nMy routine takes roughly the same time as I was getting on your original example, while using your loop with find and slice is now slower than my routine by a factor of eight. ', 'title': u'Re: benchmarks'}, {'comment': u'Now I see, it\'s more effective on often matches. But to be correct, second cycle must be changed to:\n<pre>\nt=time.clock()\ni = 0\npos = -1\nwhile 1:\n pos = bigstr.find(instr, pos+1)\n if pos<0:break\n i += 1\nprint \'Found\',i,\'times, in\', time.clock()-t,\'clocks\'\n</pre>\nto eliminate lots of string reallocating. \n<pre>\nSearching ! in "!! !!!" ! !! ! ! ""!"! "\nFound 23909 times, in 6.90686190563 clocks\nFound 23909 times, in 0.220056739055 clocks\n</pre>\nstill too slow...', 'title': u' '}, {'comment': u'I agree that, as you found, with the addition of the pos argument, the built-in find is faster, and should be used when you are searching a string in-memory. If what you are searching is not a string, string.find() is not applicable, and this KMP code would be more useful.', 'title': u' '}, {'comment': u"It's worth to notice, the biggest weak point - interpreted code gives in change big advantage in flexibility - one can change this function for case-insensetive searches or using wildcards.", 'title': u"It's can be much flexible then find"}, {'comment': u"try this :-)<br>\n\nbigstr = 'A'*10**7+'B'<br>\ninstr = 'A'*10**6+'B'<br>\n", 'title': u' '}], 'desc': u'This is an implementation of the Knuth-Morris-Pratt algorithm for finding copies of a given pattern as a contiguous subsequence of a larger text. Since KMP accesses the text only sequentially, it is natural to implement it in a way that allows the text to be an arbitrary iterator. After a preprocessing stage which takes time linear in the length of the pattern, each text symbol is processed in constant amortized time.'}, {'comments': [{'comment': u'Try running Pychecker over your code.', 'title': u' '}, {'comment': u'There is a hidous bug in the __lt__ and __le__ operators\nThe fix should be something like the following.\n\n<pre>\n def __lt__(self, date):\n if self.year There is a hidous bug in the __lt__ and __le__ operators\nThe fix should be something like the following.\n\n<pre>\n def __lt__(self, date):\n if self.year </pre></pre>', 'title': u'Bug in __lt__ and __le__'}, {'comment': u'Gak! I posted the correct code in the previous comment, but the posting process munged it horribly. So... trust me, there really is this bug and I really do have a fix.\n', 'title': u'Re: previous comment'}, {'comment': u"Yeah, I see the bug, too. In case it's not clear, the bug is that 2000-04-20 won't be less than 2002-07-03, because 20 > 3.<br>\n <br>\nA simple fix that I used in my own date module is:<br>\n <br>\ndef __lt__(self, other):<br>\n    return (self.year, self.month, self.day) < (other.year, other.month, other.dy)<br>\n <br>\ndef __le__(self, other):<br>\n    return (self.year, self.month, self.day) <= (other.year, other.month, other.dy)<br>\n <br>", 'title': u'__le__ and __lt__ bug'}, {'comment': u"Thanks a bunch for caughting this! It had passed all my testing (not included in the code). I've applied your suggested fix - it's the simplest. Now I can go and hide in shame and never show my face again and...", 'title': u'Thanks for caughting this newbie error'}, {'comment': u'This module can easily be made cross platform by removing the unconditional import of pythoncom. The ToCOMTime method will not work then but all the other functionality is OK. The import can either be moved into the ToCOMTime method or wrapped in a try block like so:\ntry:\n import pythoncom\nexcept ImportError:\n pass', 'title': u'Can be made cross-platform'}, {'comment': u'Thank you for the code, works nice. Found a small bug in the testcode section: <br>\n"temp += NumberDaysMonth(temp.month)" <br> gives a wrong result when the loop is extended to compute dates over a leap year. <br> \nShould better be set to<br>\n"temp += NumberDaysMonth(temp.month, temp.year)"<br>\n<br>\nCheers, <br>Ralf\n', 'title': u'small bug in testcode section'}, {'comment': u'I have not find any licence. Could you choose any to clarify distribution conditions? I like this package very much.', 'title': u'Licence'}], 'desc': u'This pure Python module defines a class Date and several methods\nto deal with it, including conversions to some other formats.\n\nNeeds Python 2.2'}, {'comments': [], 'desc': u'This is a recipe for extracting file version information from Windows files, using the Win32 API.'}, {'comments': [{'comment': u'Which ispell are you using?\nEvery ispell I tried wants to read from a file.\nIs there an option to spell one word from stdin?<br> \n<br> \nAlso, try pexpect instead of popen:<br> \n http://pexpect.sourceforge.net/<br> \n<br> \nYours,\nNoah\n', 'title': u'Which ispell are you using?'}, {'comment': u'<pre>\n#ispell class found on internet: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117221\n#modified by chris thomson \nclass ispell:\n def __init__(self):\n self._f = popen2.Popen3("ispell -a")\n self._f.fromchild.readline() #skip the credit line\n def __call__(self, word):\n self._f.tochild.write(word+\'\\n\')\n self._f.tochild.flush()\n s = self._f.fromchild.readline()\n\tif not (s[:1]=="*" or s[:1]=="+" or s[:1]=="-" or s[:1]=="#" or s[:1]=="?" or s[:1]=="<pre>\n#ispell class found on internet: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117221\n#modified by chris thomson \nclass ispell:\n def __init__(self):\n self._f = popen2.Popen3("ispell -a")\n self._f.fromchild.readline() #skip the credit line\n def __call__(self, word):\n self._f.tochild.write(word+\'\\n\')\n self._f.tochild.flush()\n s = self._f.fromchild.readline()\n\tif not (s[:1]=="*" or s[:1]=="+" or s[:1]=="-" or s[:1]=="#" or s[:1]=="?" or s[:1]=="</pre></pre>', 'title': u'Here is a modified version for other versions of ispell'}, {'comment': u'<pre>\nclass ispell:\n def __init__(self):\n self._f = popen2.Popen3("ispell -a")\n self._f.fromchild.readline() #skip the credit line\n def __call__(self, word):\n self._f.tochild.write(word+\'\\n\')\n self._f.tochild.flush()\n s = self._f.fromchild.readline()\n\tif not (s[:1]=="*" or s[:1]=="+" or s[:1]=="-" or s[:1]=="#" or s[:1]=="?" or s[:1]=="&"):\n\t return None\n self._f.fromchild.readline()\n if s[:1]=="*" or s[:1]=="+" or s[:1]=="-": #correct spelling\n\t return None\n elif s[:1]=="#": # no matches\n return []\n else:\n\t m = re.compile("^[&\\?] \\w+ [0-9]+ [0-9]+:([\\w\\- ,]+)$", re.M).search("\\n"+s, 1)\n return (m.group(1).split(\', \'))\n\n</pre>', 'title': u'Arrg try again!'}, {'comment': u'Hi,\n<br><br>\nSince this is an extremely high-ranking page when Googling for "python spell check" and similar phrases, I thought I\'d take the time to point out several new [well, compared to this recipie :-)] Python modules for spell checking. Hopefully you might find one to suit your needs:\n<br><br>\n"aspell-python" is a wrapper around aspell: http://www.republika.pl/wmula/proj/aspell-python/index.html\n<br>\n"pyenchant" is a wrapper around enchant, a backend-neutral spell check system: http://pyenchant.sourceforge.net\n<br>\n"pyaspell" is another aspell wrapper: http://savannah.nongnu.org/projects/pyaspell/\n<br>\n"myspell-python" is a wrapper around MySpell: http://developer.berlios.de/projects/myspell-python/\n<br><br>\nCheers,\n<br>\n Ryan\n<br><br>\nDisclaimer: I am the author of PyEnchant', 'title': u'Other Methods'}, {'comment': u'I found this hack to work for me using Ispell and the French dictionary (largerly based from the examples from this page):\n<pre>\n#!/usr/bin/python\n\nimport popen2\n\nclass ispell:\n def __init__(self):\n self._f = popen2.Popen3("/sw/bin/ispell -a -d francais")\n self._f.fromchild.readline() #skip the credit line\n def __call__(self, word):\n self._f.tochild.write(word+\'\\n\')\n self._f.tochild.flush()\n s = self._f.fromchild.readline()\n if not (s[:1]=="*" or s[:1]=="+" or s[:1]=="-" or s[:1]=="#" or s[:1]=="?" or s[:1]=="&"):\n return None\n self._f.fromchild.readline()\n if s[:1]=="*" or s[:1]=="+" or s[:1]=="-": #correct spelling\n return None\n elif s[:1]=="#": # no matches\n return []\n else:\n #print s\n info, suggested = s.split(\': \')\n return suggested.split(\', \')\n \nif __name__=="__main__":\n f = ispell()\n print f(\'scene\')\n</pre>', 'title': u'Spell checking with Python and Ispell using the French dictionary'}], 'desc': u'use popen2 module to drive the ispell typo checker \n'}, {'comments': [], 'desc': u'A string searching algorithm based upon Boyer-Moore string searching, which is considered one of the most efficient string searching algorithms. Boyer-Moore-Horspool only uses the bad-suffix window for matching and is therefore simpler to implement and faster than normal BM.'}, {'comments': [{'comment': u"I find this code to be especially readable and elegant with\nits use of 'yield'.", 'title': u"I really like this use of 'yield'"}, {'comment': u"Some of the formulas become a little simpler if we represent points by complex numbers as pairs of reals:\n\n<pre>\ndef orientation(p,q,r):\n return ((q - p) * (r - p).conjugate()).imag\n...\n # still points left on both lists, compare slopes of next hull edges\n # being careful to avoid divide-by-zero in slope calculation\n elif ((U[i+1] - U[i]) * (L[j] - L[j-1]).conjugate()).imag > 0:\n i += 1\n else: j -= 1\n...\ndef diameter(Points):\n diam,pair = max([(abs(p-q), (p,q)) for p,q in rotatingCalipers(Points)])\n return pair\n</pre>\n\nOf course, under the hood, the complex version is doing more work: it's finding the real as well as imaginary components in the first and second formula, and doing an unnecessary square root in the third one.", 'title': u'Complex arithmetic'}, {'comment': u'If you need a result as a single sequence of points, you can join the lists (the first of L is the last of U):<br>\nU[:-1] + L', 'title': u'Note'}, {'comment': u'This is Andrew\'s monotone chain algorithm, from the paper "Another Efficient Algorithm for Convex Hulls in Two Dimensions". The lexicographic sort and generation of upper and lower portions of the hull are features of Andrew\'s algorithm that are not present in Graham\'s.', 'title': u"Not Graham's algorithm at all"}], 'desc': u"Returns the convex hull (separated into upper and lower chains of vertices) and the diameter (farthest pair of points), given input consisting of a list of 2d points represented as pairs (x,y). The convex hull algorithm is Graham's scan, using a coordinate-based sorted order rather than the more commonly seen radial sorted order. A rotating calipers algorithm generates candidate pairs of vertices for the diameter calculation. Care was taken handling tricky cases such as pairs of points with the same x-coordinate and colinear triples of points."}, {'comments': [{'comment': u"I set the original string to 'lempel ziv text compression'.\nThe decoded output was 'lempel ziv tlxv colerlssitn'.", 'title': u'Bug'}], 'desc': u'LZ77 is a compression algorithm upon which most popular compression formats are based; PKZIP, GZIP, LHA, RAR, etc.'}, {'comments': [{'comment': u'Because of way deletions are handled lazily, the only dictionary operations that need to be overloaded are the ones that add new items. I thought I had covered them all, but I missed one:\n<pre>\n def update(self, other):\n for key in other.keys():\n self[key] = other[key]\n</pre>\nAlternatively, one could use the dictionary mixin from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117236 to make sure all dictionary methods are overloaded, but this would make the methods that only clear or read items unnecessarily inefficient.', 'title': u'Missing update()'}, {'comment': u"I have found that using lists to hold the values is 10 to 20% faster than using a dictionary. I tend to do something like:\n<br>\n<pre> graph = {'A': [('B',3), ('C',5)],\n 'B': [('C', 2), ('D', 2)],\n 'C': [('D', 1)],\n 'D': [('C', 3)],\n 'E': [('F', 8)],\n 'F': [('C', 2)]}\n</pre>\n<br>\nWhich gives the ?best? of both worlds. This structure is very difficult to modify though so dictionaries might be appropriate for editable graphs.\n<br>\n<br>\nI must admit that I am might be in the minority of preferring full blown graph structures. I tend to do a lot of funky matching on node and vertex objects and I find them easier to modify at a class level. This might also be a byproduct of dealing with chemistry related structures where nodes are atoms and edges are bonds. \n<br>\n<br>\nMy current standard is:\n<pre>\nclass Node:\n def __init__(self, label):\n self.label = label\n self.edges = [] # connected edges\n self.anodes = [] # adjacent nodes (in order of edge)\n\nclass Edge:\n def __init__(self, label, node1, node2):\n self.label = label\n self.nodes = [node1, node2] # an edge can only have two nodes\n \n node1.edges.append(self)\n node1.anodes.append(node2)\n node2.edges.append(self)\n node2.anodes.append(node1) \n\nclass Graph:\n def __init__(self, nodes, edges):\n self.nodes = nodes\n self.edges = edges\n</pre>\nThis means that when I am looking at an edge I can get to the nodes easily and vice versa. Plus I like writing things like:\n<pre>\nfor node in g.nodes:\n for edge in node.edges:\n pass\n\nas opposed to (pre python 2.2)\n\nfor node in g.keys():\n for node2, edge2 in g.items():\n pass\n\nAlthough this could be fixed by subclassing Dict.</pre>", 'title': u'Observations'}, {'comment': u"I'm not quite sure how a discussion of graph representation relates to this recipe, but I prefer dicts over lists for the inner part:\n<pre>\n graph = {'A': {'B':3, 'C':5},\n 'B': {'C':2, 'D':2},\n 'C': {'D':1},\n 'D': {'C':3},\n 'E': {'F':8},\n 'F': {'C':2}}\n</pre>\nModifiability is one reason, but more important to me is that this allows fast adjacency tests: 'C' in graph['A'] tests whether there is an edge 'A'-'C', not possible with your list-of-pairs representation, and for large graphs is faster with dicts than with lists. One can also easily loop over all neighbors of v (for w in graph[v]: ...) and associate useful information with the edge v-w (graph[v][w]).", 'title': u'Graph data structures'}, {'comment': u"Just wanted to let you know that I found this code very useful, after realizing I needed a full-on priority queue, this was a lot easier than writing my own (for like the 3rd time in as many languages).\n<br><br>\ni couldn't find any papers of yours describing this code (I understand from a CS perspective writing code isn't very paper-worthy) so I cited this as a webpage, you can see the paper here:\n<br><br>\n<pre>\nhttp://dx.doi.org/10.1016/j.jmb.2006.07.022</pre>", 'title': u'thanks'}], 'desc': u'This data structure acts almost like a dictionary, with two modifications: First, D.smallest() returns the value x minimizing D[x]. For this to work correctly, all values D[x] stored in the dictionary must be comparable. Second, iterating "for x in D" finds and removes the items from D in sorted order. Each item is not removed until the next item is requested, so D[x] will still return a useful value until the next iteration of the for-loop.'}, {'comments': [{'comment': u'Forgive me if I\'m missing something, but how does this differ\nfrom/add more value than the standard library module "UserDict"\n(or, in python 2.2 or later, just inheriting directly from\ndictionary)?<br><pre>http://www.python.org/doc/current/lib/module-UserDict.html</pre>', 'title': u'How does this differ from UserDict?'}], 'desc': u'This mixin makes it easy to provide a full dictionary interface to a class defining only a few mapping methods for getting, setting, deleting, and listing keys. Also, a function is provided to incorporate the mixin at runtime so that code for existing modules need not be modified.\n'}, {'comments': [{'comment': u'I\'ve been enjoying Programming Pearls too.\n\nI think a Python dictionary is a more natural structure for holding the anagram keys and associated word lists. Also, list comprehension is helpful assuming you\'re using Python 2.0 or later.\n<pre>\nDict={}\n## list comprehension reads all the lines from inFile eliminating lines with only one char\n## returns the full word and a list of letters suitable for key generation\nfor (word,letters) in [(word[0:len(word)-1],list(word[0:len(word)-1])) for word in inFile.readlines() if len(word)>1]:\n letters.sort()\n ## join the sorted letters to create a key\n ## Dict.setdefault returns [] if the key is not found\n Dict.setdefault(string.join(letters,""),[]).append(word)\n\n## Use list comprehension and string joins to print formatted output\nprint "Anagrams found:\\n"+string.join([string.join(Dict[key],", ") for key in Dict.keys() if len(Dict[key])>1],"\\n")\n</pre>', 'title': u'Use a Dict?'}, {'comment': u'Note that word[0:len(word)-1] == word[:-1].', 'title': u'Simplify...'}], 'desc': u'Code for fetching Anagrams out of any given file that contains words seperated\nby new lines.'}, {'comments': [{'comment': u'I cannot get this code to work. Using Jython 2.1\nTomcat 4.1. I get the following errors:\n\nC:\\Tomcat 4.1\\work\\Standalone\\localhost\\jythontest\\jython_jsp.java:74: cannot resolve symbol\nsymbol : method setPageContext (javax.servlet.jsp.PageContext)\nlocation: class jythonsupport.DemoTag\n _jspx_th_app_jydemo_0.setPageContext(pageContext);\n ^\nC:\\Tomcat 4.1\\work\\Standalone\\localhost\\jythontest\\jython_jsp.java:75: cannot resolve symbol\nsymbol : method setParent (I cannot get this code to work. Using Jython 2.1\nTomcat 4.1. I get the following errors:\n\nC:\\Tomcat 4.1\\work\\Standalone\\localhost\\jythontest\\jython_jsp.java:74: cannot resolve symbol\nsymbol : method setPageContext (javax.servlet.jsp.PageContext)\nlocation: class jythonsupport.DemoTag\n _jspx_th_app_jydemo_0.setPageContext(pageContext);\n ^\nC:\\Tomcat 4.1\\work\\Standalone\\localhost\\jythontest\\jython_jsp.java:75: cannot resolve symbol\nsymbol : method setParent (', 'title': u'does this really work?'}], 'desc': u'A simple example which shows how to implement your own JSP custom tag with the help of Jython.'}, {'comments': [], 'desc': u'lace: forms a list of tuples by interlacing elements from several lists.\n'}, {'comments': [{'comment': u"Generalize to arbitery weight. Weights are not need to add up to 1.0\n\n<pre>\nimport random\n\ndef windex(lst):\n\t'''an attempt to make a random.choose() function that makes weighted choices\n\t\n\taccepts a list of tuples with the item and probability as a pair'''\n\n wtotal = sum([x[1] for x in lst])\n\tn = random.uniform(0, wtotal)\n\tfor item, weight in lst:\n\t\tif n < weight:\n\t\t\tbreak\n\t\tn = n - weight\n\treturn item\n\n</pre>", 'title': u' '}], 'desc': u'weighted choice from list'}, {'comments': [{'comment': u'Holger, thanks for this.\n\nI make extensive use of ~/tmp and other user-directory based paths for a project. makepath did not behave well for those cases, so I added \n\n<pre>\n path=expanduser(path)\n</pre>\nimmediately before\n<pre>\n dpath = normpath(dirname(path))\n</pre>\nwhich seems to work fine in testing on OSX.\n\nI also created a mkdirs function using makepath that forces directories. \n\n<pre>\ndef mkdirs(path):\n """ensures that all elements are created as directories, see makepath().\n \n Doctest\n =======\n \n setup\n >>> tmpdir = os.tempnam(None,\'dir\')\n >>> os.mkdir(tmpdir)\n \n simple use\n >>> abspath = mkdirs(os.path.join(tmpdir, \'subdir\'))\n >>> assert abspath.startswith(tmpdir)\n >>> assert abspath.endswith(\'subdir\')\n \n nice use for making some directories \n >>> dirs = map (mkdirs, ( os.path.join(tmpdir, \'var/log/\'),\\\n os.path.join(tmpdir,\'var/db/\'),\\\n os.path.join(tmpdir,\'tmp/logfile\')))\n >>> os.listdir(tmpdir)\n [\'subdir\', \'tmp\', \'var\']\n >>> os.listdir(os.path.join(tmpdir,\'var\'))\n [\'db\', \'log\']\n \n NOTE: no \'/\' at end of string - got a subdir anyway!\n >>> os.listdir(os.path.join(tmpdir,\'tmp\'))\n [\'logfile\']\n \n """\n return(makepath(path+\'/\'))\n</pre>\n\n--r.', 'title': u'Expanding the user directory'}], 'desc': u'"makepath(path)" creates missing directories for path and\nreturns a normalized absolute version of the path. As often\nthe case with python, the documentation is more important than the \ncode.'}, {'comments': [], 'desc': u'This algorithm takes as input a function for computing matrix values, and searches for the position of maximum value in each row. The matrix must satisfy the "totally monotone" property: in each submatrix (in particular each 2x2 submatrix) the positions of the maxima must move leftward as you go down the rows. The algorithm uses this property to greatly reduce the number of matrix elements evaluated, compared to a naive algorithm that explicitly constructs the matrix.\n\nAs a simple example, we apply the algorithm to finding nearest neighbors in B for each point in A, where B may be distributed arbitrarily in space but the points of A lie along a single line. Using SMAWK for this problem takes only linear time if the input is already sorted.'}, {'comments': [], 'desc': u"Distutil's bdist_wininst installers offer uninstallation support for Python extensions, many developers however only distribute sources in zip or tar.gz format. The typical steps to install such a distribution are:\n- download the file\n- unpack with winzip into a temporary directory\n- open a command prompt and type 'python setup.py install'\n- remove the temporary directory\n\nThis script unpacks a source distribution into a temporary directory, builds a windows installer on the fly, executes it, and cleans everything up afterward.\n"}, {'comments': [], 'desc': u'given a string that has the contents of a .zip, how to handle ?\n(or "on using StringIO and zipfile")'}, {'comments': [{'comment': u"In the class RecursiveContent, there are backquotes around the data references:\n<pre>\n def __repr__(self): return '%s...%s' % ( `self.data`[0], `self.data`[-1] )\n ^ ^ ^ ^\n</pre>\nWhat is the purpose of the backquotes?", 'title': u'Backquotes in __repr__'}], 'desc': u'This is a function to iterate over a container and its elements that checks for recursive traps. The condition for descending into elements is highly configurable (a list of type() results, or a callable). Spin-offs: a function to check for iterability in a loose and in a strict sense; a function to flatten a hierarchical container into a list of its elements.'}, {'comments': [{'comment': u"I like your ideas of recursive lambdas although \n<pre>f('a'*10000)</pre>\n<br>\nwill usually fail with stack overflow.", 'title': u'Very nice, but stack use is O( len(string) )'}, {'comment': u"<pre>\nstrlist = list(string_var); strlist.reverse(); ''.join(strlist)\n</pre>\n\n<br>\nnot really a one liner ;)", 'title': u'how about'}, {'comment': u"i tried that for f('a'*100000) \n:)", 'title': u"Second version won't fail"}, {'comment': u'see third version I have stiched it as a one liner,\none liner i mean that can be used in lambda functions\n<br>using list for evaluating mutiple expressions\nis a great techiniqe :)', 'title': u'but that can be done'}, {'comment': u"Very good solution! By the way i would be interested in your oppinion\nabout my related new recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/119596\nI actually came to it thinking about your recipe! Good that\nyou didn't have the third solution from the beginning :-)", 'title': u'Cool'}, {'comment': u'I just thought, that we might combine our ideas to\nturn my recipe into lambda functions. I have some ideas\nand see some problems. we should probably discuss this via\nemail. drop me a note if you are interested to collaborate/discuss\nholger at trillke net. Or just deliver the lambda :-) ', 'title': u'Maybe you can turn my recipe into a lambda?'}, {'comment': u'I am just doing that but as it is lot of code\nit seems slight difficult...\n...any way i will try to improve your shortcut :)\n\nif u want to contact me my mail id is anuraguniyal@yahoo.com', 'title': u'sure'}, {'comment': u"Another way to do this is to use list comprehensions:\n<br>\n<pre>\nf3 = lambda s: ''.join([s[i] for i in xrange(len(s)-1, -1, -1)])\n</pre>\nor\n<br>\n<pre>\nf4 = lambda s: ''.join([s[-1 - i] for i in xrange(len(s))]))\n</pre>\n<br>\nI find these pretty readable and easy to write. They also perform\nquite well (clearly better than the others). I will post my test\nresults as a follow up to this. There are some surprises.\n", 'title': u'Try using list comprehensions'}, {'comment': u"I tested the various flavors of string reverse over the range\nof 10 to 100,000 character strings with 1 to 100,000 iterations.\n<br>\nList comprehensions win. And there is some very odd behaviour for\nsome of the others. Here is a summary of my observations:\n<br>\n<pre>\nf0 = lambda s: s and f0(s[1:]) + s[0]\n\n recursive lambda len(s) iters secs ms/each usec/chr\n 10 10000 0.38 0.038 3.815\n 100 10000 4.02 0.402 4.017\n maximum recursion depth exceeded at len 1000 count 1\n</pre>\nOk, no suprise there.\n<br>\n<pre>\nf1 = lambda s: reduce(lambda a,b: b+a, s, '')\n\n plus and reduce len(s) iters secs ms/each usec/chr\n 10 100000 3.31 0.033 3.311\n 100 100000 28.72 0.287 2.872\n 1000 1000 3.05 3.049 3.049\n 10000 100 7.66 76.563 7.656\n 100000 1 9.13 9131.513 91.315\n</pre>\nLooks ok, except when the string gets large.\n<br>\n<pre>\nf2 = lambda s, l=[]: (l.extend(s), l.reverse(), ''.join(l))[2]\n\ntransform to list len(s) iters secs ms/each usec/chr\n 10 10 0.00 0.032 3.210\n 10 100 0.01 0.106 10.598\n 10 1000 0.89 0.886 88.625\n 10 10000 107.88 10.788 1078.757\n\n 100 10 0.20 20.260 202.599\n 100 100 2.19 21.888 218.880\n 100 1000 33.56 33.564 335.643\n\n 1000 10 0.43 43.131 43.131\n 1000 100 5.46 54.624 54.624\n\n 10000 10 0.76 76.485 7.648\n 10000 100 18.06 180.565 18.057\n\n 100000 1 0.32 322.159 3.222\n 100000 10 4.19 419.239 4.192\n</pre>\nNot only does it slow down as the strings get longer, but different\niteration counts radically affect the timing in both absolute and\nper character terms. And not in a predictable way either, look at\nthe 10 character string case which appears to be O(N*iterations)\nversus the 100 character string case which is O(N) but extremely slow\nanyway. Something there is that does not like a list... Also,\nthis method seems to improve (relatively) as the string gets very\nlarge. Curiouser and curiouser.\n<br>\n<pre>\nf3 = lambda s: ''.join([s[i] for i in xrange(len(s)-1, -1, -1)])\n\nlist comprehension len(s) iters secs ms/each usec/chr\n 10 100000 3.46 0.035 3.457\n 100 100000 17.71 0.177 1.771\n 1000 10000 15.99 1.599 1.599\n 10000 1000 16.01 16.007 1.601\n 100000 100 18.12 181.179 1.812\n</pre>\nThis is twice as fast as any of the other methods and is also\nquite predictable, taking the same time per character no matter what\nlength string or number of iterations. The alternative comprehension:\n<pre>\nf4 = lambda s: ''.join([s[-1 - i] for i in xrange(len(s))])\n</pre>\nwas similar, but slightly slower.\n<br>\nHere, for those who wish to play with it, or simply to laugh at my\npython style is the test program I used:\n<pre>\nimport sys, time, gc\n\nf0 = lambda s: s and f0(s[1:]) + s[0]\nfuns = (('recursive lambda', f0),\n ('plus and reduce',\n lambda s: reduce(lambda a,b: b+a, s, '')),\n ('transform to list',\n lambda s, l=[]: (l.extend(s), l.reverse(), ''.join(l))[2]),\n ('list comprehension',\n lambda s: ''.join([s[i] for i in xrange(len(s)-1, -1, -1)])),\n ('another lc',\n lambda s: ''.join([s[-1 - i] for i in xrange(len(s))])) )\n\nhdr = '\\n\\n %20s len(s) iters secs ms/each usec/chr'\nfmt = ' %6d %6d %6.2f %8.3f %8.3f'\nstrings = ['0123456789' * factor for factor in 1, 10, 100, 1000, 10000]\r", 'title': u'Performance surprises'}, {'comment': u"I don't know why the add comment procedure insisted on having an extra\ncopy of my post, but it did, I previewed it many times and could\nnever get rid of it...\n<br>\nsigh...\n", 'title': u'Eeeh...'}, {'comment': u'See the code above! I have changed third lambda slightly\ndue to some feature of Python which I fail to understand!', 'title': u'Corrected version is fastest :)'}, {'comment': u"f=lambda s:(lambda a:a.reverse()or a.tostring())(__import__('array').array('c', s))", 'title': u' '}, {'comment': u'This recipe is out of date since Python 2.3.<br>\nNow you should simply use<br>\n<br>\n reversed_string = s[::-1]<br>\n<br>\nIt is much simpler and faster than all solutions mentioned above.<br>\n<br>', 'title': u'Python 2.3'}], 'desc': u'one line to reverse a string'}, {'comments': [], 'desc': u'Sometimes you want a Class whose functions do nothing. '}, {'comments': [], 'desc': u'Hook on stdout and stderr so that we can handle\nprinting of text,error differently\ne.g in GUI base application divert text to a log window.'}, {'comments': [{'comment': u"Dijkstra's algorithm can be simplified by allowing a (cost, vertex) \n\npair to be present multiple times in the priority queue:\n\n<pre>\ndef shortest_path(G, start, end):\n def flatten(L): # Flatten linked list of form [0,[1,[2,[]]]]\n while len(L) > 0:\n yield L[0]\n L = L[1]\n\n q = [(0, start, ())] # Heap of (cost, path_head, path_rest).\n visited = set() # Visited vertices.\n while True:\n (cost, v1, path) = heapq.heappop(q)\n if v1 not in visited:\n visited.add(v1)\n if v1 == end:\n return list(flatten(path))[::-1] + [v1]\n path = (v1, path)\n for (v2, cost2) in G[v1].iteritems():\n if v2 not in visited:\n heapq.heappush(q, (cost + cost2, v2, path))\n</pre>\n\nIf there are n vertices and m edges, the modified-Dijkstra algorithm \n\ntakes O(n+m) space and O(m*log(m)) time. In comparison, the Dijkstra \n\nalgorithm takes O(n) space and O((n+m)*log(n)) time. All time bounds \n\nassume no hash collisions.<br><br>\n\nUsing Eppstein's (excellent) dictionary graph representation, it takes O(n+m) space \n\nto store a graph in memory, thus the memory overhead of the \n\nmodified-Dijkstra algorithm is reasonable.<br><br>\n\nI tested running times on a Pentium 3, and for complete graphs of ~2000 \n\nvertices, this modified Dijkstra function is several times slower than \n\nEppstein's function, and for sparse graphs with ~50000 vertices and \n\n~50000*3 edges, the modified Dijkstra function is several times faster \n\nthan Eppstein's function.<br><br>\n\nP.S.: Eppstein has also implemented the modified algorithm in Python (see python-dev). This implementation is faster.", 'title': u'Can be simplified (with tradeoffs in time and memory)'}], 'desc': u'Dijkstra(G,s) finds all shortest paths from s to each other vertex in the graph, and shortestPath(G,s,t) uses Dijkstra to find the shortest path from s to t. Uses the priorityDictionary data structure (Recipe 117228) to keep track of estimated distances to each vertex.'}, {'comments': [{'comment': u"Your return technique will not do the\nright thing if the function is passed\nan empty tuple or a null string. In\nthese cases it will return an empty list.\n\nIn some cases, of course, this doesn't\nmatter, but you have to be careful when\npromoting generic solutions.\n", 'title': u'Be careful!'}, {'comment': u'<pre>\nAdd\n if not o:\n return o\n\nnear the top of the function</pre>', 'title': u'To fix this'}, {'comment': u'Ouch. you are right. Actually i wasn\'t aware that empty string/tuples have a\n"false" boolean value. Thanks for pointing this out!\n\nYour fix is correct for "reverse" and "sort" and but not for "extend".\nAs i don\'t want to lose the function template \ni have modified the return magic to handle null results. (version 1.2)', 'title': u'Thanks, fixed'}, {'comment': u'but really obfuscated \nlets try to obfuscate it further :)', 'title': u'really good'}, {'comment': u"Let's ***NOT** obfuscate it further. That might be fun for comp.lang.python but i really don't see that this is the place for obfuscated code or showing off. It is supposed to be a repository for useful code. Useful means that the code is called for often and that the code is resonably efficient, clean, and readable. People who are bored and want to show off their programming ability should consider another forum.\n", 'title': u"let's not and say we did..."}, {'comment': u'Great code example. Any code example is practical if one really gives some thought. This excellent piece of work might become the basis of a larger solution for someone.\n<br><br>\nIf one bothers to read a real cookbook, you know, one written for food recipes; then one would see that often, major recipes refer to sub-recipes, say, for a sauce.\n<br><br>\nThis type of code is sauce code. One can use it within a larger recipe. That\'s why this is a cookbook, and not a "here\'s how you solve your specific problem, book." If you are looking for a book like that, email me. Those kind of books are known as a "consultant".', 'title': u'Great Code...Learning = Playing = Purpose'}, {'comment': u"Wow. I gotta remember more of my functional/logical programming skills.\n\nDo you care to give a brief desctiption of how that return statement works? I'm just not seeing how the casted (is that a word) value is returned instead of the rest. (I'm upset that I haven't been able to figure it out yet, BTW.)", 'title': u'Good God. '}], 'desc': u'If you like obfuscated but powerful Oneliners you will really enjoy this one.\nIt allows to use reverse, sort and extent "on the fly" with tuples, strings or list types.\nIt returns a new instance of the same type as the input type. Extending a tuple results in\na new tuple. Sorting a string results in a new string and so on. Thanks to Patrick\nMaupin since version 1.2 it handles Null-Strings and tuples correctly. \n\nThough the functionality can be expressed in a 290-character "Oneliner" i recommend\nthat you use the longer 15-line code (at the end) as it is more understandable and "pythonic".'}, {'comments': [], 'desc': u'A one line code to do that...\n'}, {'comments': [], 'desc': u"Using this class user may call list type methods e.g sort,reverse,remove,index,pop\non strings,tuple which don't support such operations"}, {'comments': [], 'desc': u' '}, {'comments': [], 'desc': u'This recipe provides a class which will read a text file in reverse... It basically reads a block of data from the end of the file as a list and keeps popping items off of that everytime the readline() method is called. When the block is exhausted, another block is read, and so forth... This takes care of corner cases where a line is longer than the buffer or the file is smaller than the buffer, etc.'}, {'comments': [], 'desc': u"The following code implements a splash screen as typically found in windows applications. Using only API's available from win32gui, win32api and win32con, it avoids dependancy on MFC (wrapped by win32ui). This way the 600kb or so win32ui.pyd extension DLL is not needed when freezing your app with py2exe.\nAnother 80kb could be squeezed out by not using win32con but to define the necessary constants directly in the code itself."}, {'comments': [{'comment': u'This is a fine illustration of fileinput which I was not familiar with.\n<br>\nHowever, it should be noted that perl treats this kind of operation\nas a common case, and the entire callback function can be expressed\nin one short line. Furthermore, you can call that line as a command\nline option, like this:\n<pre>\n perl -pi -e \'s/theunderdogs/the-underdogs/g\' **/*.url\n</pre>\n(-p means process every line of the files, -i means in-place, -e means execute this command) The **/*.url is a special zsh trick. If you don\'t run zsh, use something like this:\n<pre>\n find favorites/ -name \'*.url\' | xargs perl -pi -e \'...\'\n</pre>\nPerl even has a shortcut for making backups of the files it processes. Use "-pi.bak" to copy inputfile to inputfile.bak\nbefore processing.\n<br>\nAlso, I think the python program meant to say \'.*theunderdogs.*\' (or just \'theunderdogs\'. That\'s the functionality of my perl version.', 'title': u'a perl way to do it (for educational purposes only)'}, {'comment': u'I fixed * to .* but I think it would probably work without it only slower', 'title': u'Right'}], 'desc': u'This script go thru directory tree and looks for files off specified pattern, and then replace in those files string with new one, overwriting old file without backups\n'}, {'comments': [{'comment': u"You can use the 'types' module to check for other sequence types\ne.g.\n<pre>\nimport types\nsequence_types = \\\n[types.ListType,types.TupleType,types.StringTypes,types.SliceType,types.XrangeType,types.BufferType]\n\nfor arg in args:\n if type(arg) in sequence_types:\n#rest of the code same as before\n</pre>\n\n-Hemanth (hemanth_sethuram at yahoo dot com)", 'title': u'Checking for other sequence types'}, {'comment': u'A string\'s elements are strings, so flatten recurs infinitely if\nit encounters a string in the structure it is flattening. Having no\nstring element type is one of Python\'s warts, and the author of this\nrecipie has just stumbled over it.\n<br>\n<pre>\n>>> for x in flatten((\'a\',\'b\')): print x\n...\nTraceback (most recent call last):\n File "", line 1, in ?\n File "", line 5, in flatten\n File "", line 5, in flatten\n[snip]\n File "", line 5, in flatten\nRuntimeError: maximum recursion depth exceeded\n>>>\n</pre>', 'title': u"This function won't work if a string occurs anywhere within its argument(s)"}, {'comment': u'If you know the structure in advance, you may be able to do it with list comprehensions.<br>\n<br>\nFor example, you know you have a list of lists of tuples:<br>\n<br>\narr = [[(1,2), (2,3)], [(3,5), (5,8), (8,13)], [(13,21)]]<br>\n<br>\nYou can flatten this as:<br>\n<br>\n [x for z in arr for y in z for x in y]<br>', 'title': u'List comprehensions'}], 'desc': u'this generator flattens nested containers such as\n \n<code> l=( (1,23), [[[[42,(5,23)]]]])</code>\n\nso that\n\n<code> for i in flatten(l): print i</code>\n\ngives you 1,23,42,5,23\n\n\n '}, {'comments': [{'comment': u"I think the reason that the brute-force code is faster than the functional-style one is in that 'map' on a list would generate a new intermediate list, which is avoided in the direct implementation. Following this rule, the matrix multiplication could be accelerated a little bit like this:\n\n<pre>\ndef inner_prod(v1, v2):\n 'inner production of two vectors.'\n sum = 0\n for i in xrange(len(v1)):\n sum += v1[i] * v2[i]\n return sum\n\ndef matmult3(m, v):\n 'matrix multiply vector by inner production.'\n return [inner_prod(r, v) for r in m]\n\n</pre>", 'title': u'a faster code'}, {'comment': u"Xunning Yue's code is hard to beat for its clarity. Here a couple more code snippets for your speed tests.\n<br>\nRemember, map and reduce are generally fast but were slowed down in the first example by lambda and the unnecessary intermediate lists. The operator module takes care of the lambda problem. Xunning's approach takes care of the intermediate lists. Map also helps by pre-allocating the right amount of space which is something a list comprehension cannot do.\n\n<pre>\nimport operator\ndef matmult4(m, v):\n return [reduce(operator.add,map(operator.mul,r,v)) for r in m]\n\ndef matmult5(m, v):\n return map(lambda r: reduce(operator.add,map(operator.mul,r,v)),m)\n</pre>", 'title': u'More Speed'}, {'comment': u"I love Raymond's code (matmult4) though Xunnin's remains the fastest, by a small margin. These are my test results obtained on PIII 600Mhz for a 800x800 matrix. I give here the ratios of CPU time to the CPU time taken by matmult: \nmatmult2=>0.76\nmatmult3=>0.68\nmatmult4=>0.72\nmatmult5=>0.73.\nWell done!", 'title': u'And the winner is...'}, {'comment': u'Looping is apparently faster. Keeping this in mind, one has merely to ensure no computational power is wasted by repeatedly performing the same tasks multiple times. For instance initializing a list of indices for the nested loop saves 5% and extracting the current row of the matrix once also roughly saves 5%. Introducing local variables is therefor optimal, hence you will find this to be faster:\n\n<pre>\ndef matmult6(m, v):\n\trows = len(m)\n\tw = [0]*rows\n\tirange = range(len(v))\n\tsum = 0\n\tfor j in range(rows):\n\t\tr = m[j]\n\t\tfor i in irange:\n\t\t\tsum += r[i]*v[i]\n\t\tw[j],sum = sum,0\n\treturn w\n</pre>', 'title': u'Another suggestion'}], 'desc': u"Using 'reduce' and 'map', this code shows how a matrix vector multiplication \ncan be reduced to a single loop. "}, {'comments': [{'comment': u'Argh, thanks for making your Python code look like Perl.', 'title': u' '}], 'desc': u'here I have shown how to generate base64 alpahbets \nand encode string in one line...'}, {'comments': [], 'desc': u'A class that defines a compare function that can be used to sort lists of objects by any number of fields.'}, {'comments': [], 'desc': u'Very simple example using BaseDocTemplate with 2 PageTemplate, somes Frame.'}, {'comments': [], 'desc': u"Takes as input a bipartite graph in a variation of Guido van Rossum's dictionary-of-lists format, and outputs both a maximum matching (largest possible set of nonadjacent edges) and a maximum independent set (largest possible set of nonadjacent vertices). The running time in the worst case is O(E sqrt(V)) but for many graphs it runs faster due to doing fewer than the worst case number of iterations."}, {'comments': [{'comment': u"Hi \n<br>\nI just tried your guestbook script, and noticed that when have submitted a message, a blank screen appears. I refreshed a couple of times, then I went back to the Guestbook a saw that my message was added twice. Shouldn't you rather redirect to a thank you page or to the guestbook?\n<br>\nRegards<br>\nJorgen", 'title': u'Blank screen when adding an entry'}, {'comment': u'The problem was a mistake at the end of the bookEntry function. It now works as shown above.', 'title': u'Fixed the problem.'}, {'comment': u"What's the simplest thing you could to do to protect this script against Javascript injection attacks?", 'title': u'Injection attacks'}], 'desc': u'A guest book for your web page that demonstrates CGI, and file access. '}, {'comments': [{'comment': u'...using time.time() instead of time.clock() will measure real time instead of the time the program has got. Will work with Python2 only.', 'title': u'Nearly right, but...'}, {'comment': u'My motive for using time.clock() was, that it says in the documentation that time.clock() is used for timing or benchmarking algorithms (even in Python 1.5.2, which I have never used).<br> Further, as time is only measured relatively, it does not matter what the time is, when starting and stopping the stopwatch.', 'title': u'time.clock()'}, {'comment': u"Well, time.clock() returns the CPU time the process has received so far, so if it doesn't get 100% CPU time, the programs perception of time will be slower than the real time.\n\nIt is used for benchmarking so that other programs running on the machine don't influence the benchmark outcome.", 'title': u'time.clock()'}], 'desc': u'This is a small implementation of a stopwatch widget in Tkinter. The widget displays a label with minutes:seconds:1/100-seconds. The label is updated every 50 ms, but that can easily be changed. Methods are availble for starting, stopping and resetting the stopwatch. A simple program demonstrates the widget.'}, {'comments': [{'comment': u"The line\n\n<pre>\nexec('import %s as module' % modulename)\n</pre>\n\ncan be replaced by\n\n<pre>\nmodule = __import__(modulename)\n</pre>\n\nUsing exec will significantly affect the performance of the program.", 'title': u'Use __import__ rather than exec'}, {'comment': u'Thanks for the suggetion; change applied.', 'title': u'Thanks, got it.'}, {'comment': u'Hi.\n\nYou are typechecking on\n<pre> if type(module.__dict__[name]) == type(unittest):</pre>\nstatement, but python has no builtin unittest type and the code stops.<br>\n\nPlease let me know how you are running this test suits.', 'title': u'there is no unittest type'}], 'desc': u'My goal is to create a framework that is easier than command line testing with \nthe benifit of automatic unittesting. That way there is simply no excuse for \n*not* testing. \n\n-- Based on Bruce Eckels Java class UnitTest (see BruceEckel.com /Thinking in Patterns/).\n-- Best when combined with <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/113408">pretest.py</a>\n\n\n'}, {'comments': [{'comment': u"I wanted this the other day, but I need my (extensive :) docstrings to\nbe counted as comments in order to get an accurate result. The above solution can be had in a single line of shell script using egrep. I'm looking for something that involves the python parser perhaps. ", 'title': u'anyone care to handle docstrings?'}], 'desc': u'Displays the total number of code lines in a single source file or for all the files of the same type in an entire directory. User provides a filename including the extension, or an just the extension preceded by a wildcard character. '}, {'comments': [{'comment': u'The recipe as posted doesn\'t return the index-th permutation in standard (lexicographic) order, as shown by the following snippet:<br>\n<pre>\n>>> for i in range (0, 6):\n... print i, getPerm ([1, 2, 3], i)\n... \n0 [1, 2, 3]\n1 [1, 3, 2]\n2 [2, 1, 3]\n3 [3, 1, 2]\n4 [2, 3, 1]\n5 [3, 2, 1]\n</pre>\n\nThis can be corrected by revising the function as follows (using a helper which could have been in-lined):<br>\n\n<pre>\ndef NPerms (seq):\n "computes the factorial of the length of "\n return reduce (lambda x, y: x * y, range (1, len (seq) + 1), 1)\n\ndef PermN (seq, index):\n "Returns the th permutation of (in proper order)"\n seqc = list (seq [:])\n result = []\n fact = NPerms (seq)\n index %= fact\n while seqc:\n fact = fact / len (seqc)\n choice, index = index // fact, index % fact\n result += [seqc.pop (choice)]\n return result\n</pre>\n\nWith this replacement, the permutations are now in the expected order:<br>\n\n<pre>\n>>> for i in range (0, 6):\n... print i, PermN ([1, 2, 3], i)\n... \n0 [1, 2, 3]\n1 [1, 3, 2]\n2 [2, 1, 3]\n3 [2, 3, 1]\n4 [3, 1, 2]\n5 [3, 2, 1]\n</pre>\n-jn-', 'title': u'Not in lexicographic order...'}], 'desc': u'This function, given a sequence and a number n as parameters, returns the <n>th permutation of the sequence (always as a list). '}, {'comments': [], 'desc': u'A password generator that will generate random length alpha-numeric passwords given a range to work with.'}, {'comments': [], 'desc': u'A simple piece of code in Python that inverts function in the Laplace field\nto the real field. Accurate, fast and easy to use.'}, {'comments': [], 'desc': u'An algorithm to numerically invert functions in the Laplace field is presented.\nIt is based on the Fast Fourier Transform (FFT) technique and yields a\nnumerical solution for t=a ("a" is a real number) for a Laplace function\nF(s) = L(f(t)), where "L" represents the Laplace transformation.'}, {'comments': [{'comment': u'Fun project! I prefer x ** y in place of pow(x, y) your milage may vary.', 'title': u'Try **'}, {'comment': u"... but I haven't seen any changes :\\\n<br>\nAnyway, thanks for yor comments... I kept with ** instead of pow :)\n<br>\nRegards\n<br>\ninkel", 'title': u"I've tried it..."}, {'comment': u'Your problem is the limitation of floating point numbers, not your machine. You could get around this by keeping all your calculations as integers and letting Python\'s "big number" arithmetic do its thing. You\'re better off if you just calculate the first n Fibonacci numbers and then report the nth one as your result.', 'title': u'The problem is with floating point numbers.'}, {'comment': u'I just made a simple for, in stead of that ugly code and whats the result: it takes me 2 sec for the calculation of the 100000th fib-number s... where is the limit???', 'title': u'Why can i calculate even the 100000th fib-number?'}, {'comment': u'While iterating through all values 1...n to generate the nth<br>\nfibonacci number via DP is reasonably fast, it can be done even<br>\nfaster.<br>\n\n<pre>\ndef dfib(n):\n if 2 >= n:\n return 1\n i, j = 1, 1\n for _ in xrange(n-2):\n i,j = i+j, i\n return i\n</pre>\n>>> t = time.clock();C = dfib(100000);time.clock()-t<br>\n4.1060637595001026\n\n<pre>\ndef fibo(n):\n if 2 >= n:\n return 1\n t = 1\n while n >= t:\n t *= 2\n t = int(t/4)\n i, j, k = 1, 1, 0\n while t > 0:\n B = j*j\n j *= i+k\n i = i*i + B\n k = k*k + B\n if n&t:\n k = j\n j = i\n i = j+k\n t = int(t/2)\n return j\n</pre>\n>>> t = time.clock();B = fibo(100000);time.clock()-t<br>\n0.079098041790302887<br>\n>>> t = time.clock();B = fibo(1000000);time.clock()-t<br>\n2.6970709964534763<br>\n>>> len(hex(B))<br>\n173564<br><br>\n\nWith an n much larger than 1,000,000 we start running into the<br>\ninefficiencies of large integer multiplication.', 'title': u'Or you can do it the right way...'}, {'comment': u"If you look into the algorithm's complexity you'll find out that the algebraic solution is by no means more efficient than the plain simple series development algorithm.", 'title': u'Way ineffiecient'}], 'desc': u'A simple object to compute Fibonacci numbers. Object methods return the nth Fibonacci number, return list first n Fibonacci numbers and list from F(k) to F(n) numbers.\nIn a future I hope to add more functions closely related with applications of Fibonacci Numbers'}, {'comments': [], 'desc': u"Since try-finally can't be used in a generator, it can be somewhat tricky to ensure that a resource is released if the generator is exited early. This solution wraps the generator with an enclosing class to ensure the resource is released."}, {'comments': [{'comment': u'This is an usage of descriptors I have never thought about ;)', 'title': u'clever!'}], 'desc': u"How to create attributes with 'computed at first use' values."}, {'comments': [{'comment': u'I would humbly suggest removing the Observer class, as it adds no value to the program. Also modifying the attach command to help avoid double additions would be a good thing:\n<pre>\nclass Subject:\n def attach(self, observer):\n if not observer in self._observers:\n self._observers.append(observer)\n</pre>\n', 'title': u'Tightening up...'}, {'comment': u'Based on the comment, I removed the Observer Class. Additionally I changed the try-except clause, to except ValueError instead of all errors.', 'title': u'Removed observer class'}, {'comment': u"I think it was wrong to remove the Observer class. Observer was a kind of interface that documented the behaviour of an observer. Of course, in practice it isn't needed _because this is python and it is a dynamic language_, but it makes it clearer to the reader/maintainer.", 'title': u' '}, {'comment': u"I disagree, forcing observers to be subclassed from an IObserver class is unecessary. As long as your Subject class is well documented, there shouldn't be any confusion. If you really can't trust the observers, why not add extra checks to the attach method to enforce the contract.\n\n<pre>\nclass Subject:\n def attach(self, observer):\n # must have update method\n assert hasattr(observer,'update')\n # update must accept at least one argument\n assert observer.update.func_code.co_argcount > 0\n if not observer in self._observers:\n self._observers.append(observer)\n</pre>\n\nThose checks don't cover every bad observer, but i'm sure it's possible with some extra work.", 'title': u'subclassing necessary?'}], 'desc': u'This is a Python implementation of the observer pattern described by Gamma et. al. It defines a one-to many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.\n\nThe example should output:\nSetting Data 1 = 10\nDecimalViewer: Subject Data 1 has data 10\nHexViewer: Subject Data 1 has data 0xa\nSetting Data 2 = 15\nHexViewer: Subject Data 2 has data 0xf\nDecimalViewer: Subject Data 2 has data 15\nSetting Data 1 = 3\nDecimalViewer: Subject Data 1 has data 3\nHexViewer: Subject Data 1 has data 0x3\nSetting Data 2 = 5\nHexViewer: Subject Data 2 has data 0x5\nDecimalViewer: Subject Data 2 has data 5\nDetach HexViewer from data1 and data2.\nSetting Data 1 = 10\nDecimalViewer: Subject Data 1 has data 10\nSetting Data 2 = 15\nDecimalViewer: Subject Data 2 has data 15'}, {'comments': [], 'desc': u'This class allows you to use generators as more list-like streams. The chief advantage is that it is impossible to iterate through a generator more than once, while a stream can be re-used like a list.'}, {'comments': [{'comment': u"The ConfigParser module in the standard library already does this:\n<pre>\nimport ConfigParser\n\ncfg = ConfigParser.ConfigParser()\ncfg.readfp(open('myconfig.ini'))\nprint cfg.get('system', 'database')\n</pre>\n", 'title': u'Why not use ConfigParser?'}, {'comment': u'This functionality is already included with Python via the ConfigParser module.', 'title': u'I agree.'}], 'desc': u'In a configuration file you have some options. These are grouped in name and value pairs. These pairs belong to one section and a section is indicated by a name in brackets.\n\nThe following Python class read such a file.'}, {'comments': [{'comment': u"This cannot be used for encryption for the simple fact that the\nsize of the 'encrypted' data is tooo large when compared to the\noriginal data. As for strength, this will rate 1/10 probably in\nthe pantheon of encryption algorithms. \n\nThis is a good candidate for data obfuscation rather than\nencryption.", 'title': u'Not a good idea !'}, {'comment': u"We recently needed to generate a set of filenames one per employee; the requirement was that the filename must not be easily correlated to the basic datum - the Employee id. We used this method for the purpose. <br>\nWhile writing the code, I combined the OctalEncode and Encrypt as follows: \n<pre>\ndef Encode( text ):\n oStr = ''\n for ch in text:\n chv = 8 + random.randrange( 2 )\n oStr = '%s%d%o' %( oStr, chv, ord( ch ) )\n n = long( oStr )\n return str( n * n )\n</pre>", 'title': u'An improvement'}], 'desc': u'Here is the way nowdays I am encrypting my data\nIt is simple and effective...\nDoes any encryption-master knows how much effective :)'}, {'comments': [], 'desc': u'This Module contains a function that formats paragraphs of text to have a certain\nlinewidth, optionally stretching lines to that width by filling word gaps with \nspaces. In other words, it does left-justified/word-wrapped and block formatted \nparagraphs.'}, {'comments': [{'comment': u'If you use an old python version (e.g. 1.5) you have to include \n"TERMIOS" additionally to "termios" and the "TCSADRAIN" is\nfound in "TERMIOS".', 'title': u'old python versions have to include TERMIOS'}, {'comment': u'<pre>\nA few modifications make this work for the mac with Carbon,\ntoo: a modification to the _Getch to try one more import, a \nmodification to the Unix init, and the inclusion of the instructions\nfor the MacOS with Carbon support.\n\n\nclass _Getch:\n """Gets a single character from standard input. Does not echo to the\nscreen."""\n def __init__(self):\n try:\n self.impl = _GetchWindows()\n except ImportError:\n try:\n\t self.impl = _GetchUnix()\n except ImportError:\n self.impl = _GetchMacCarbon()\n\n def __call__(self): return self.impl()\n\n\nclass _GetchUnix:\n def __init__(self):\n import tty, sys, termios # import termios now or else you\'ll get the Unix version on the Mac\n\n def __call__(self):\n import sys, tty, termios\n fd = sys.stdin.fileno()\n old_settings = termios.tcgetattr(fd)\n try:\n tty.setraw(sys.stdin.fileno())\n ch = sys.stdin.read(1)\n finally:\n termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)\n return ch\n\nclass _GetchWindows:\n def __init__(self):\n import msvcrt\n\n def __call__(self):\n import msvcrt\n return msvcrt.getch()\n\n\nclass _GetchMacCarbon:\n\t"""\n\tA function which returns the current ASCII key that is down;\n\tif no ASCII key is down, the null string is returned. The\n\tpage http://www.mactech.com/macintosh-c/chap02-1.html was\n\tvery helpful in figuring out how to do this. \n\t"""\n\tdef __init__(self):\n\t\timport Carbon\n\t\t\n\tdef __call__(self):\n\t\timport Carbon\n\t\tif Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask\n\t\t\treturn \'\'\n\t\telse:\n\t\t\t#\n\t\t\t# The event contains the following info:\n\t\t\t# (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]\n\t\t\t# \n\t\t\t# The message (msg) contains the ASCII char which is\n\t\t\t# extracted with the 0x000000FF charCodeMask; this\n\t\t\t# number is converted to an ASCII character with chr() and \n\t\t\t# returned\n\t\t\t#\n\t\t\t(what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]\n\t\t\treturn chr(msg <pre>\nA few modifications make this work for the mac with Carbon,\ntoo: a modification to the _Getch to try one more import, a \nmodification to the Unix init, and the inclusion of the instructions\nfor the MacOS with Carbon support.\n\n\nclass _Getch:\n """Gets a single character from standard input. Does not echo to the\nscreen."""\n def __init__(self):\n try:\n self.impl = _GetchWindows()\n except ImportError:\n try:\n\t self.impl = _GetchUnix()\n except ImportError:\n self.impl = _GetchMacCarbon()\n\n def __call__(self): return self.impl()\n\n\nclass _GetchUnix:\n def __init__(self):\n import tty, sys, termios # import termios now or else you\'ll get the Unix version on the Mac\n\n def __call__(self):\n import sys, tty, termios\n fd = sys.stdin.fileno()\n old_settings = termios.tcgetattr(fd)\n try:\n tty.setraw(sys.stdin.fileno())\n ch = sys.stdin.read(1)\n finally:\n termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)\n return ch\n\nclass _GetchWindows:\n def __init__(self):\n import msvcrt\n\n def __call__(self):\n import msvcrt\n return msvcrt.getch()\n\n\nclass _GetchMacCarbon:\n\t"""\n\tA function which returns the current ASCII key that is down;\n\tif no ASCII key is down, the null string is returned. The\n\tpage http://www.mactech.com/macintosh-c/chap02-1.html was\n\tvery helpful in figuring out how to do this. \n\t"""\n\tdef __init__(self):\n\t\timport Carbon\n\t\t\n\tdef __call__(self):\n\t\timport Carbon\n\t\tif Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask\n\t\t\treturn \'\'\n\t\telse:\n\t\t\t#\n\t\t\t# The event contains the following info:\n\t\t\t# (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]\n\t\t\t# \n\t\t\t# The message (msg) contains the ASCII char which is\n\t\t\t# extracted with the 0x000000FF charCodeMask; this\n\t\t\t# number ', 'title': u'extended for MacOS'}, {'comment': u'<pre>Sorry about the repeated text. I see that the ampersand\ninside the <pre> tag is what caused it...and it also caused\nthe last line to appear incorrectly. The last line should\nread\n\nreturn chr(msg & 0x000000FF)</pre>', 'title': u'erratum for MacOS modification'}, {'comment': u'The following code (along with the _GetUnix and _GetWindows above) gives the correct getch behavior whether imported in the pythonIDE or in a Terminal script on the Mac. The order of trial imports is changed in _Getch because when in the IDE, the Unix import was succeeding. A single line in the _GetMacCarbon was added to see if the Carbon module has the Evt method. When the import succeeds when in the Terminal, the Carbon library there does not have the Evt method and so the import fails and the _GetchUnix() line is executed.\n<br><br>\nI also found that the curses snippet at < http://www.pythonapocrypha.com/Chapter22/Chapter22.shtml > works in the Terminal but will cause the pythonIDE to quit without warning if you run it there.\n<br><br>\n<pre>\n###\n\nclass _Getch:\n """Gets a single character from standard input. Does not echo to the\nscreen."""\n def __init__(self):\n try:\n self.impl = _GetchWindows()\n except ImportError:\n try:\n self.impl = _GetchMacCarbon()\n except AttributeError:\n self.impl = _GetchUnix()\n\n def __call__(self): return self.impl()\n\nclass _GetchMacCarbon:\n """\n A function which returns the current ASCII key that is down;\n if no ASCII key is down, the null string is returned. The\n page http://www.mactech.com/macintosh-c/chap02-1.html was\n very helpful in figuring out how to do this.\n """\n def __init__(self):\n import Carbon\n Carbon.Evt #see if it has this (in Unix, it doesn\'t)\n\n def __call__(self):\n import Carbon\n if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask\n return \'\'\n else:\n #\n # The event contains the following info:\n # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]\n #\n # The message (msg) contains the ASCII char which is\n # extracted with the 0x000000FF charCodeMask; this\n # number is converted to an ASCII character with chr() and\n # returned\n #\n (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]\n return chr(msg & 0x000000FF)\n\nif __name__ == \'__main__\': # a little test\n print \'Press a key\'\n inkey = _Getch()\n import sys\n for i in xrange(sys.maxint):\n k=inkey()\n if k<>\'\':break\n print \'you pressed \',k\n###</pre>', 'title': u'updated for OS X'}, {'comment': u'I was unable to make this work in IDLE on OSX. I guess because of what IDLE seems to do to stdio. I always got "AttributeError".', 'title': u'getch with IDLE'}], 'desc': u'A small utility class to read single characters from standard input, on both Windows and UNIX systems. It provides a getch() function-like instance.'}, {'comments': [], 'desc': u"I get a lot of spam. :( Unfortunately, much of this spam is not the good old 4-5k message trying to sell something...many contain attachments in the 80-150k size range. Add to this the facts that I still live off a dialup line and my mail client (the otherwise amazing sylpheed) does not filter at the POP3 level and it's clear that I need to do something about it. Hence this python applet. It uses poplib to connect to a POP3 server, list messages greater than a given size (default is 50k), and then prompt for which messages to delete. It's been pretty handy for me."}, {'comments': [], 'desc': u'Shows: how to derive a class from NullWriter that accumulates text from the body of an HTML page, how to derive a class from HTMLParser that retains metatag information, how to instantiate these classes and display a typical result of using them.'}, {'comments': [], 'desc': u"Semi-lazy interrogation of searchhippo.com returns a virtual array of the search engine's records."}, {'comments': [{'comment': u'Looks as of the Cookbook uploader can\'t take XML in the "notes" field. Yes. I tried preview, and it did show the tags, though with indentation removed. Nothing like what showed up in the end. I\'ve put the 2 XBEL files you can use for testing at<br>\nhttp://uche.ogbuji.net/etc/020625/bm1.xbel<br>\n and<br>\nhttp://uche.ogbuji.net/etc/020625/bm2.xbel<br>\nSorry for any inconvenience.', 'title': u'The sample XML files got corrupted'}], 'desc': u'This recipe uses DOM (precisely, cDomlette or the minidom variant in 4Suite) to merge two files containing XBEL boomark listings. It uses Python 2.2. generators for straightforward and efficient iteration over the XBEL DOM trees in document order. It requires Python 2.2 and 4Suite 0.12.0a2 or more recent versions.'}, {'comments': [], 'desc': u'This recipe sorts a list of strings using the numeric order where possible.'}, {'comments': [], 'desc': u'Provides some packaging for the win32serviceutil module to simplify starting\nand stopping services. It also provides a small test example that\nincludes providing arguments for starting a service.'}, {'comments': [], 'desc': u'MSHTML is the COM component used by Internet Explorer to parse HTML pages (since version 4 of IE). It can be used independently of IE as shown here.'}, {'comments': [{'comment': u'Algorithms are excellent. Thanks for the effort.', 'title': u'Good one!'}], 'desc': u'This is a module with pure Python implementations of binary and\ngeneralized (multi-node) trees. \n'}, {'comments': [{'comment': u'The code is stated to require Python 2.2 or later, but the use of True and False means that Python 2.2.1 will actually be required.', 'title': u'Use of True and False requires Python 2.2.1'}, {'comment': u'Right you are, I updated the comment. \n\n2.2 users can of course just replace True/False with 1/0', 'title': u'True/False and 2.2.1'}, {'comment': u"Why not instead this? It's a bit cleaner, and certainly easier on the eyes...\n\n<pre>\ndef ResultIter(cursor, arraysize=1000):\n 'An iterator that uses fetchmany to keep memory usage down'\n while True:\n results = cursor.fetchmany(arraysize)\n if not results:\n break\n for result in results:\n yield result\n</pre>", 'title': u'code cleanup'}, {'comment': u'MySQLdb returns results as tuples, so the comparison ( results == [] ) fails. The\n<pre>\nwhile True:\n if not results:\n break\n</pre>\napproach works correctly.', 'title': u'previous comment fixes problem'}], 'desc': u"When using the python DB API, it's tempting to always use a cursor's fetchall() method so that you can easily iterate through a result set. For very large result sets though, this could be expensive in terms of memory (and time to wait for the entire result set to come back). You can use fetchmany() instead, but then have to manage looping through the intemediate result sets. Here's a generator that simplifies that for you."}, {'comments': [], 'desc': u'RegObj is an ActiveX server for registry manipulation that can be driven using Python. Its object model provides significant advantages over the use of the \nregistry API.'}, {'comments': [{'comment': u"Please note that in addition to many other v2.0+ features, this routine uses the new python v2.2 feature of nested local scopes; if you have an older version you may need to change <pre>\n def formatline(*cols):\n return format % tuple(map(lambda s: (s or ''), cols))\n</pre>to a lambda statement or use the format=format default-parameter stunt.", 'title': u'Please note: Some version 2.2 features used.'}, {'comment': u'..... Is there an easy way from Python to tell what parameters line up with a method? Would one call a (dir) on the method?\n\nJust curious...\n', 'title': u'Parameters of a method....'}, {'comment': u'See the signature.py module written by Neel Krishnaswami at \n<pre>\n http://www.sff.net/people/neelk/open-source\n</pre>\nThe Signature class it defines allows you to determine what parameters a method (or other callable) takes.<br>\n<br>\nThere are number of other interesting modules to check out there, too.\n<br>', 'title': u'Signatures'}, {'comment': u"I need to rewrite your lovely dumpObj to work with python2.1 but I don't understand the formatline() method.\nSome more hints maybe?", 'title': u'What stunt?'}, {'comment': u'This code is great, but it does not support unicode values in the __dict__.\n\nPlease change line 152 from<br>\n<pre>\n truncstring(str(val), maxspew)),\nto\n truncstring(unicode(val), maxspew)),\n</pre>', 'title': u'Missing unicode support'}], 'desc': u"Print a nicely formatted overview of an object, including _everything_ in the object's `dir'. This is great when programming interactively.\n\nMore comprehensive than help(), prettier than dir()."}, {'comments': [{'comment': u'<pre>\n>>> mailsrch = re.compile(r\'[\\w\\-][\\w\\-\\.]+@[\\w\\-][\\w\\-\\.]+[a-zA-Z]{1,4}\')\n>>> mailsrch.findall("peter@grenna. net")\n[\'peter@grenna\']\n</pre>\n\nAnd do you know an equivalent regular expression for words that start with www., http:// etc?', 'title': u'Not quite right'}, {'comment': u"Couple of points:\n<pre>\n</pre>\n1) since python2.4, you can use a set to keep a list without duplicates. Something like\n<pre>\nfound=set()\n... \nfor file in files: \n for line in open(file,'r'): \n found.update(mailsrch.findall(line)) \n</pre>\n2) The regex doesn't match email addresses like 'a@somewhere.com', where the part before the @ is just one letter. You can fix it by changing a '+' to a '*':\nr'[\\w\\-][\\w\\-\\.]*@[\\w\\-][\\w\\-\\.]+[a-zA-Z]{1,4}'\n\n", 'title': u' '}], 'desc': u'A quick way to find valid email addresses in text files using a regular expression search. It then removes duplicate entries and returns the results in a list.'}, {'comments': [], 'desc': u'This class extends ConfigParser class to make it able to read and write configuration settings from specified registry key. \n Code below should work with ActivePython 2.1+ '}, {'comments': [], 'desc': u'Two methods to return the intersection/union of sets of data, where the form of the data is not a limiting factor.'}, {'comments': [], 'desc': u'A generator for cycling over a set of values. This recipe shows a generator-based approach for creating repeating alternators as well as several other approaches.'}, {'comments': [], 'desc': u'This recipe draws a dendrogram (horizontal format used for evolutionary trees), as ASCII text, given as input a binary tree in the form of a tuple for each tree node. Tree leaves can be any Python object other than a length-2 tuple, and are converted to strings in the output. Tree nodes at the same distance from the root will line up at the same column, with the distance between tree levels controlled by an optional "sep" parameter. The algorithm works by a straightforward inorder traversal, keeping some simple data structures to keep track of the tree edges that need to be drawn on each output line. Its output is via print statements but it could easily be modified to send its output lines to any other kind of stream.'}, {'comments': [], 'desc': u'Sorts a list of objects by either attribute or index across a prioritized group of attributes, indices, or both.\n'}, {'comments': [], 'desc': u'Searches nested strings from a line of text.\nThe strings are limited by two different characters.\n'}, {'comments': [], 'desc': u"Two items:\n\n1. Python script that defines and registers a factory COM class and another COM class that can be instantiated by the factory.\n2. (Ugly) VC++ code that exercises the factory and then the object returned by the factory.\n\nThe Python COM object returned by the factory provides rudimentary stemming; ie, it removes any final 's' from a word that is passed to it and returns the truncated word as its result."}, {'comments': [{'comment': u'If class a already has a metaclass then a "metatype conflict among bases" is raised. \n\nFor example, I might define a tracer class as metaclass for class a to be traced. \n\nSo question is how can class b be defined to have two metaclasses i.e. get tracing facility from class a and also be defined as a final class.', 'title': u'does not work if super class already has a metaclass'}, {'comment': u'Have a look at my recipe \n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197\n\nwhich solves the metaclass conflict.\n\n Michele', 'title': u'Forbidding inheritance '}], 'desc': u'How to prevent the use of a class as a base class.'}, {'comments': [{'comment': u'Looking into the future, Py2.3 comes with a wonderfully efficient priority queue implementation in a module called heapq. Applying heapq simplifies and speeds the above code considerably.\n<br>\n<pre>\nfrom heapq import heapify, heappop, heapreplace\n\ndef xmerge(*ln):\n pqueue = []\n for i in map(iter, ln):\n try:\n pqueue.append((i.next(), i.next))\n except StopIteration:\n pass\n heapify(pqueue)\n while pqueue:\n val, it = pqueue[0]\n yield val\n try:\n heapreplace(pqueue, (it(), it))\n except StopIteration:\n heappop(pqueue)\n</pre>', 'title': u'In the future, no need to roll your own priority queue'}, {'comment': u'In spite of number of comparisons on random ordered sequences:\n<br><pre>\n\ndef imerge ( *ordered ) :\n """Merge ordered iterables.\n """\n L = len(ordered)\n if L == 0 : return ()\n if L == 1 : return ordered[0]\n\n if L == 2 : return imerge_two(ordered[0],ordered[1])\n L /= 2\n return imerge_two(imerge(*ordered[:L]),imerge(*ordered[L:]))\n</pre>\n<br>Where imerge_two - real merging iterator.', 'title': u'Recursive is faster.'}, {'comment': u'I was a bit stymied by the way iterators were used in the original code (frankly, I did not understand the code), I came up with one using heapq, but with easier to read, but producing the same effect.\nI am not sure of performance hit on large sequences due to the multiple maps, but the number of lines are reduced, which was my goal\n.\n<br><br>\n<pre>\ndef xmerge2(*ln):<br>\n """ Uses a simplified syntax """\n \n heap = []\n map(lambda l: map(heap.append, l), ln)\n\n while heap:\n yield heappop(heap)\n</pre>', 'title': u'More readable'}, {'comment': u'Using itertools, simplifies it further.\n\n<pre>\ndef xmerge3(*ln):\n\n from itertools import chain\n\n heap = []\n for i in chain(*ln):\n heap.append(i)\n\n while heap:\n yield heappop(heap)\n</pre>', 'title': u'Using itertools'}], 'desc': u'How to merge several iterable sequences and keep things ordered.'}, {'comments': [], 'desc': u'The basic iterator for a list is a very "fast-but-dumb" design. It doesn\'t allow one to skip forward (except with "continue"), or backward (at all), nor does it behave well if the list is modified while it is being traversed. The following is NOT the be-all and end-all of improved iterators, but it gives a few ideas of how a better one might be created.'}, {'comments': [{'comment': u'<pre>\ndef dump2(src, length=8):\n result=[]\n for i in xrange(0, len(src), length):\n s = src[i:i+length]\n hexa = \' \'.join(["%02X"%ord(x) for x in s])\n printable = s.translate(FILTER)\n result.append("%04X %-*s %s\\n" % (i, length*3, hexa, printable))\n return \'\'.join(result)\n</pre>', 'title': u'Small Improvements'}], 'desc': u'Hexadecimal display of a byte stream'}, {'comments': [{'comment': u'For even better cracking, you could use digrams as well or even trigrams, and things like most appearing beginning/final letters.<br>\n<br>\n1) Most frequently appearing letters overall:<br>\neiaorn tslcup mdhygb fvkwzx qj<br>\n2) Most frequently appearing letters BEGINNING words:<br>\nspcaut mbdrhi eofgnl wvkjqz yx<br>\n3) Most frequent final letters:<br>\neysndr ltacmg hkopif xwubzv jq<br>\n4) Most frequent digrams (ordered pairs of letters)<br>\ner in ti on te al an at ic en is re ra le ri ro st ne ar<br>', 'title': u'Interesting...'}], 'desc': u'How to use letter frequencies analysis to decipher French and English texts.'}, {'comments': [{'comment': u"I can't execute procedures like EXEC sp_addlogin ...\nIs there a special way to do that ?\n\nThanks You", 'title': u'CallProc'}, {'comment': u"Hi,\n when i run your script i get erros, dbcp is not defined. python can't find this module. where can i get it.\nplease reply.\nthanks", 'title': u"what's dbcp, "}, {'comment': u'Hi Khawaja\n\ndbcp is the module from another colaborator (Steve Holden).\nDo a search on the Cookbook for "Pretty Printer" and you will find it.\nSave it as a module named dbcp and your dblib will work ok.\nI will be updating dblib soon, thanks for trying it', 'title': u'dbcp and Pretty Printer'}, {'comment': u'Hi Bertrand\n\nThanks for testing dblib!<br>\nSorry for the late reply<br>\nI tested using the sp_addlogin with EXEC (and without it)<br>\nand it worked fine.<br>\nJust make sure you configure the sql statement with a combination of double quotes and single quotes:<br><br>\nlst = cu.execute("EXEC sp_addlogin \'test3\', \'test3\'")<br><br>\nAnd it should work ok.<br>\nI will be working more on this from now on.<br>\nBest regards<br>\nJorge<br>\n<br>\n<br>\nUpdated test program follows<br>\n#dblib_test.py<br>\n#test program to test dblib.py<br>\n<br>\nfrom dblib import *<br>\nfrom dbcp import pp #Pretty Printer imported here<br>\nc = Connection(\'SERVERNAME\', \'sa\', \'password\',\'pubs\')<br>\nprint c.constr #print the connection string<br>\nprint c.connected #prints 1 if connected OK<br>\ncu = c.cursor #create the cursor<br>\nlst = cu.execute(\'select * from authors\')<br>\nprint \'rowcount=\' + str(cu.rowcount) #test print of record count<br>\nrows = cu.fetchall() <br>\nprint pp(cu, rows, rowlens=1)<br>\n<br>\n#new test using sp_addlogin, no EXEC<br>\nlst = cu.execute("sp_addlogin \'test2\', \'test2\'")<br>\nprint \'rowcount=\' + str(cu.rowcount) #test print of record count<br>\nrows = cu.fetchall() <br>\nprint pp(cu, rows, rowlens=1) <br>\nc.close()<br>\n<br>\n#new test using EXEC<br>\nlst = cu.execute("EXEC sp_addlogin \'test3\', \'test3\'")<br>\nprint \'rowcount=\' + str(cu.rowcount) #test print of record count<br>\nrows = cu.fetchall() <br>\nprint pp(cu, rows, rowlens=1)<br>\n<br>\n#checking the logins were created:<br>\nlst = cu.execute("select name from master..syslogins")<br>\nprint \'rowcount=\' + str(cu.rowcount) #test print of record count<br>\nrows = cu.fetchall() <br>\nprint pp(cu, rows, rowlens=1)<br>\n<br>\nc.close()<br>\n#-----------------------------------------------------', 'title': u'EXEC ok with sp_addllogin'}, {'comment': u'Hi there:<br>\n<br>\nI\'m not getting all of the fields from my query:<br>\n<br>\nsql="""select contact1.*,contact2.* from contact1 left outer join contact2 on contact1.accountno=contact2.accountno"""<br>\nc = Connection(...) <br> \ncu = c.cursor #create the cursor <br> \nlst = cu.execute(sql)<br>\nprint cu.fieldnames<br>\n<br>\nI\'m getting 31 field names but the two combined tables should have 194.<br>\n\nthanks<br>\n\nGreg', 'title': u'Not getting all fields'}, {'comment': u'Hi Greg - thanks for using dblib!<br>\nI made a copy of the authors table (named it authors2) from SQL server pubs database and run this version of your query<br><br>\n\nsql="select authors.*,authors2.* from authors left outer join authors2 on authors.au_id=authors2.au_id"<br>\nc = Connection(\'(local)\',db=\'pubs\')<br>\ncu = c.cursor #create the cursor<br> \nlst = cu.execute(sql)<br>\nprint cu.fieldnames<br>\n\n<br><br>\nAnd got the complete set of columns<br><br>\n[\'au_id\', \'au_lname\', \'au_fname\', \'phone\', \'address\', \'city\', \'state\', \'zip\', \'contract\', \'au_id\', \'au_lname\', \'au_fname\', \'phone\', \'address\', \'city\', \'state\', \'zip\', \'contract\']<br>\n\n<br>\nRegards - Jorge', 'title': u'Please try this'}, {'comment': u"After downloading and kicking around your osql module, I'm quite happy with its performance. The only difficulty I'm having with it concerns memory usage.\n<br><br>\nWhen running the following query with cursor.execute()\n<br><br>\nSELECT TOP 2000000 * FROM DATA\n<br><br>\nI end up using about 1.5 gigs of memory, which is rather what I expected. However, after I have closed and deleted all of the connection and cursor objects associated with the query, and all variables which took data from the query, the memory isn't released.\n<br><br>\nEven after deleting all the variables created in the scrpit, the memory remains allocated, only to be released when I exit the python session. Is there something I can do to recover this memory without needing to exit python altogether?\n<br><br>\nThanks,\n<br><br>\nBrian", 'title': u'Memory Usage'}, {'comment': u"Hi Brian, thanks for using dblib<br>\nI did some tests and could verify the fact: memory not being released. I did a little fix that improved a little: from 22MB went down to 16MB when closing the cursor, and before exiting Python; did not notice improvement when closing the connection<br><br>\nDoing some Google I found that this will be fixed in version 2.5<br><br>\n\n\nhttp://sourceforge.net/tracker/?func=detail&aid=1123430&group_id=5470&atid=305470<br><br>\n\nThe original link that took me to the previous one was this:<br>\nhttp://evanjones.ca/python-memory-part2.html<br><br>\n\nFor the time being, please test my partial fix (please fix indentation):<br><br>\n\n#changed the close function in the cursor:<br><br>\ndef close(self):<br> \nself.records=None #NEW LINE ADDED<br> \nself=None<br> \nreturn self<br><br><br>\n\nAnd here is the test section, I used the AdventureWorks2000 database with a cross join to get a good sized recordset<br><br>\n\nif __name__ == '__main__':<br>\n m = raw_input('Read memory 1 (Python Only) (approx 3,300KB), Hit Enter ')<br>\n c = Connection('(local)',db='AdventureWorks2000')<br> \n print c.constr #print the connection string<br> \n print c.connected #prints 1 if connected OK<br>\n cu = c.cursor #create the cursor<br>\n cu.execute('select top 10000 a.*, b.* from Address a, Address b')<br>\n print 'rowcount=' + str(cu.rowcount) #test print of record count<br> \n rows = cu.fetchall()<br> \n m = raw_input('Read memory 2 , (Cursor opened) Approx 22,000KB, Hit Enter')<br>\n cu.close()<br>\n m = raw_input('Read memory 3 (Cursor closed) Approx 16,000KB, Hit Enter')<br> \n c.close()<br> \n m = raw_input('Read memory 4 (Connection closed) Approx 16,000KB, Hit Enter') <br> ", 'title': u'Known issue with Python interpreter'}, {'comment': u"Hi,\n\nWhy on earth should one use this recipe and start an osql process from within Python to execute SQL requests, when there are sane and proven alternatives like ODBC and ADO ? What are the possible advantages ? There is no way this can be faster, more compatible, more maintainable than the already existing alternatives... Don't touch this recipe without a 10-foot pole !<br>\n<br>\nExcept as a toy example of the power of os.popen, do yourself a favor and forget about this.<br>\n<br>\nSorry to be so harsh but this gives me the creeps. Really.<br>\n<br>\nFYI, there is a Daily WTF article about this here :<br>\nhttp://thedailywtf.com/forums/62973/ShowPost.aspx<br>", 'title': u'WTF ?'}, {'comment': u'Depending on your circumstances, this module could be a better choice than ODBC or ADO. ODBC (or the more popular mxODBC) requires that you have the win32all package installed (usually not a problem but your situation may be different). Use of mxODBC in a commercial environment requires a license, available at a very reasonable cost. The ADO approach requires the ctypes package for the ADO related modules I\'ve seen. Docs and useful examples are fairly thin (and approaching being\nwoefully out of date) for the ODBC and ADO modules. \nThis module has at least some useful example usage demonstrated.\n<br>\n<br>\nAs far as performance goes, one should refer back to the original discussion segment where the author mentions his intended use, which is to aid in managing databases, ie., adding tables, adding users, simple queries to count rows, etc. I\'m skeptical that the user of this module would suffer any meaningful performance \npenalty for that sort of use. But, if you\'re Amazon, you shouldn\'t use this module for your website transaction processing. Nor should you use this if you are NOAA crunching terabytes of sea-surface, air temps and humidity to issue hurricane forecasts. \n<br>\n<br>\nThere isn\'t any way that this module will ever be compatible with Oracle, DB2, MySQL, PostGreSQL, SQLite, etc. But, if you\'re in a MS-SQL Server environment, who cares? If and when you transition to SQLServer 2005, you\'ll probably have to substitute for the planned deprecation of osql. This is certainly manageable.\n<br>\n<br>\nI also don\'t see a problem with maintainability if your use falls within the spectrum of use envisioned by the author. Don\'t use this to control nuclear power plants and don\'t think you can use this in a high availability mission-critical near real-time OLTP environment. \n<br>\n<br>\nThere\'s so many other Python modules out there that make use of os.popen to great advantage, that I don\'t understand why one would object to this one. \nWhy re-invent the wheel or bother with increased complexity if using popen meets your needs? It\'s not like the hardware you\'re likely to be operating on will collapse under the "burden".\n<br>\n<br>\nDo yourself a favor and skip the Daily WTF link. The postings there have so little relevance to this module. Unless you\'re in to gratuitous self-reference that\'s wholly devoid of useful content, you\'ve seen all the critique specificity the prior respondent could muster.\n<br>\n<br>\nWhile I might quibble about the name of the module (IMO, it should be named msdblib), some non-idiomatic Python syntax, the extraneous HTML line-break tags on the ASPN page and other minor issues, this module can be useful.\n<br>\nDepending on your environment and circumstances, the fact that\nit has no external dependencies (other than osql) may be reason enough to use this module.\n<br> \n<br> \nThe 3 star rating is justified. ', 'title': u'Counterpoint'}, {'comment': u'I agree with Kip that this dblib may not be suitable for some applications, but it is very useful for others. If you find yourself using in your system administration job a lot of calls to osql from scripts, it really simplifies your life. And the performance for this kind of use is not bad: the speed is comparable to ADO. I do not have an equivalent version of the dblib using ADO (one that conforms the output cursor like the dblib does), but I did some speed tests with this code, just to compare the plain speed of both (put it after the line (if __name__ == \'__main__\'):\n<br>\n<br> \n\n\n\n\nfrom time import time <br>\n import win32com.client <br>\n <br>\n server = \'(local)\' <br>\n database = \'AdventureWorks2000\' <br>\n ssql = \'select top 20000 a.*, b.* from Address a, Address b\' <br>\n <br>\n print "Execute using dblib" <br>\n c = Connection(server,db = database ) <br>\n cu = c.cursor <br>\n t1 = time() <br>\n cu.execute(ssql) <br>\n t2 = time() <br>\n t3 = t2 - t1 <br>\n print "Elapsed time:" + `t3` <br>\n print "" <br>\n <br>\n print \'Execute using ADO, no processing\' <br>\n t4 = time() <br>\n con=win32com.client.Dispatch(\'ADODB.Connection\') <br>\n rs=win32com.client.Dispatch(\'ADODB.recordset\') <br>\n cstr = "Provider=SQLOLEDB.1;Data Source=" + server <br>\n cstr = cstr + ";Initial Catalog=" + database + ";Integrated Security=SSPI;" <br>\n con.Open(cstr) <br>\n rs=con.Execute(ssql) <br>\n con.Close <br>\n t5 = time() <br>\n t6 = t5 - t4 <br>\n print "Elapsed time:" + `t6` <br>\n print "" <br>\n ', 'title': u'Some performance tests by author - not bad'}, {'comment': u"You have a point : this recipe may be interesting if you need a simple DBAPI implementation in a non-production context, for example to perform administrative tasks.<br>\n<br>\nOf course this should not be used in a high concurrency context, like in a Web application, but I guess this was not what the author intended.<br>\n<br>\nSorry if I've been too harsh, but I've read this recipe a few hours after reading the Daily WTF article, and the similarity in concepts made me go ping.<br>\n<br>\nRegards,<br>\nNicolas", 'title': u'OK for the no-dependency part'}], 'desc': u"This DBI implements the Cursor and Connection objects. It is functional: you can create connections, cursors, do fetchone, fetchall, get rowcount, etc. It uses osql or SQL2005's sqlcmd instead of ODBC or ADO. There is a good sized section with examples to get you started. The SQL2005 support is new, showing improved execution speed for SQL2005's sqlcmd.exe, even when accessing SQL2000 databases.\n"}, {'comments': [{'comment': u'Ok, I\'ve been pointed to the standard lib. module\n"colorsys" which does the same thing and more.\nCould someone please remove this entry? Thanks!\n\nDinu', 'title': u'Superfluous because of "colorsys" module'}], 'desc': u'Yet another way to code the conditional operator to simulate the C\'s "a?b:c" ternary operator.'}, {'comments': [], 'desc': u'"desc.py scott/tiger order " will list the column info for table "order".\n"desc.py scott/tiger@production order " will list the column info for table "order" of tns name "production".\n'}, {'comments': [], 'desc': u'This recipe allows a user to place debug messages, error messages and standard messages throughout a program. The function name and line number will be added to each debug and error message before it is printed out. In addition, each of these messages can be passed to multiple handler objects that can direct the output to log files, e-mails, stdout, etc.'}, {'comments': [], 'desc': u'look up personal/home address from a phone number (US & Canada)\nusage: ryp.py -s sendmail.your.com -e dude@your.com -p 416-345-3432 \nit has built in email & phone # validation. \nThe phone number can take most common format.'}, {'comments': [], 'desc': u"This snippet of code allows us to grab the current line number easily, and demonstrates the power of the 'inspect' module for introspective Python programs."}, {'comments': [{'comment': u'You might not want *all* the common indentation to be trimmed from a block. Perhaps a marker for each block could indicate where to trim up to.\n', 'title': u'Control how much indentation to trim?'}, {'comment': u"What I do is prefix the trimmed block with as much indentation has I need wherever I'm emitting the code. The Script object that I submit trimmed fragments to has an internal indentation level that it keeps track of, so each line submitted becomes\n<pre>\n '\\t'*indentLevel + lineText</pre>\nThe idea of this function is that you free it from the indentation\nof the surrounding Python code, not that you place it into some\nnew indent level, since that depends on where you emit the code.\n<br><br>\nNote, though, that relative indentation IS preserved after the first line; you can have\n<pre>\nhtmlFag = formatBlock('''\n....<p>\n....::::Paragraph text goes here.\n....</p>\n''')</pre>\nWhere '.' whitespace gets trimmed but ':' is left intact.", 'title': u'Re: Control how much indentation to trim?'}, {'comment': u"What I do is prefix the trimmed block with as much indentation as needed for wherever I'm emitting the code. The way I do that is that the Script object that I submit trimmed fragments to has an internal indentation level that it keeps track of, so each line submitted becomes\n<pre>\n '\\t'*indentLevel + lineText</pre>\nThe idea of formatBlock() is that you free text from the indentation of the surrounding Python code, not that you place it into some new indent level, since that depends on where you emit the text.<br><br>\nNote, though, that relative indentation IS preserved after the first line; you can have\n<pre>\nhtmlFag = formatBlock('''\n....<p>\n....::::Paragraph text goes here.\n....</p>\n''')</pre>\nWhere '.' whitespace gets trimmed but ':' is left intact. Does that address what you were thinking of?", 'title': u'Re: Control how much indentation to trim?'}, {'comment': u"What I do is prefix the trimmed block with as much indentation as needed for wherever I'm emitting the code. The way I do that is that the Script object that I submit trimmed fragments to has an internal indentation level that it keeps track of, so each line submitted becomes\n<pre>\n '\\t'*indentLevel + lineText</pre>\nThe idea of formatBlock() is that you free text from the indentation of the surrounding Python code, not that you place it into some new indent level, since that depends on where you emit the text.<br><br>\nNote, though, that relative indentation IS preserved after the first line; you can have\n<pre>\nhtmlFrag = formatBlock('''\n....<p>\n....::::Paragraph text goes here.\n....</p>\n''')</pre>\nWhere '.' whitespace gets trimmed but ':' is left intact. Does that address what you were thinking of?", 'title': u'Re: Control how much indentation to trim?'}, {'comment': u"I made a small modification of this useful recipe to suite my needs for indentation. I added an 'nlspaces' (number of leading spaces) parameter to the function call so that the user can specify the number of spaces that should be prepended to each line in the final return string.\n\nThe recipe then becomes\n<pre>\ndef format_block(block,nlspaces=0):\n '''Format the given block of text, trimming leading/trailing\n empty lines and any leading whitespace that is common to all lines.\n The purpose is to let us list a code block as a multiline,\n triple-quoted Python string, taking care of \n indentation concerns.'''\n\n import re\n\n # separate block into lines\n lines = str(block).split('\\n')\n\n # remove leading/trailing empty lines\n while lines and not lines[0]: del lines[0]\n while lines and not lines[-1]: del lines[-1]\n\n # look at first line to see how much indentation to trim\n ws = re.match(r'\\s*',lines[0]).group(0)\n if ws:\n lines = map( lambda x: x.replace(ws,'',1), lines )\n\n # remove leading/trailing blank lines (after leading ws removal)\n # we do this again in case there were pure-whitespace lines\n while lines and not lines[0]: del lines[0]\n while lines and not lines[-1]: del lines[-1]\n\n # account for user-specified leading spaces\n flines = ['%s%s' % (' '*nlspaces,line) for line in lines]\n\n return '\\n'.join(flines)+'\\n'\n</pre>", 'title': u'Re: Control how much indentation to trim?'}, {'comment': u'As part of a code generator, I often need to output fragments like:\n<pre>\n txt = """\n x = a[i] + b[i];\n }\n }\n """\n method.addlines(codeblock(2, txt)) # put at tabstop 2\n</pre>\nThe code is split up into one function that removes the whitespace, and one that outputs the result in the right position.\n<pre>\n\ndef ltrimBlock(s):\n w = len(s)\n s = s.strip(\'\\n\') # leading/trailing empty lines\n lines = s.expandtabs(4).split(\'\\n\')\n\n # find w, the smallest indent of a line with content\n for line in lines:\n line2 = line.lstrip()\n if line2:\n w = min(w, len(line)-len(line2))\n\n return [line[w:] for line in lines]\n\ndef codeblock(ntabs, text):\n """Return list of correctly indented lines."""\n tabs = \'\\t\' * ntabs\n return [tabs+line for line in ltrimBlock(text)]\n\n</pre>\n-- bjorn', 'title': u"Receipe doesn't handle text where first line is not aligned."}], 'desc': u"Function to auto-strip indentation and whitespace from triple-quoted multi-line strings in Python code. Useful when you need to emit blocks of HTML/TCL/etc. from Python, but don't want to mess up the visual flow of your Python code."}, {'comments': [{'comment': u'Why not use sys.stdout.write() or my printf-lambda with control characters?', 'title': u'alternatives'}, {'comment': u'Why so complicated?\n\n<pre>\nimport sys\nimport time\n\ndef status(s):\n sys.stdout.write(s + " " * (78 - len(s)) + "\\r")\n\nfor i in range(12):\n status(str(12-i))\n time.sleep(1)\nstatus("done")\n</pre>\n', 'title': u'simpler'}, {'comment': u'You\'re right, I was a bit precipitate.\nYou could even put the \'str()\' cast *inside* the function so you need not to do it in every call. (And this way it would be conceptually more correct ;).\n\n<pre>\nimport sys\nimport time\n\ndef status(obj):\n s = str(obj)\n sys.stdout.write(s + " " * (78 - len(s)) + "\\r")\n\nfor i in range(12):\n status(12-i)\n time.sleep(1)\n\nfor i in range(8):\n status(range(8-i))\n time.sleep(1)\n\nstatus("done")\n</pre>', 'title': u'better'}, {'comment': u"def PrintStatic(a_string=''):<br>\n     print '\\b%s%s'%(a_string,'\\b' * len(a_string)),\n", 'title': u'This Version is platform-independent...'}], 'desc': u"With this function you can overwrite what you printed in the console, remaining in the same line.\nIt's specially useful when you want to show information and update it regularly."}, {'comments': [], 'desc': u'With this snippet you can exit a loop by just pressing a single key (or detect a single key press for other purposes).'}, {'comments': [{'comment': u'Where can I find more good info, tutorials etc on finite state machines.', 'title': u'Info on fsm'}, {'comment': u'http://systems.cs.uchicago.edu/ply/index.html', 'title': u"Don't forget PLY"}, {'comment': u'I wanted to use this recipe to process unhashable "tokens" (in this case, element objects from effbot\'s most excellent elementtidy). Here\'s a subclass to process generic objects.\n<br><br>\n<pre>\nclass ObjFSM(FSM):\n \'\'\'A subclass of FSM where input_symbol may be any kind of object, even an unhashable one.\n For each input_symbol to process, the machine will try a sequence of functions;\n the first to return True determines (action, next_state).\n \'\'\'\n \n def add_transition(self, test, state, action, next_state):\n self.state_transitions.setdefault(state, []).append((test, action, next_state))\n\n def get_transition(self, input_symbol, state):\n #input_symbol arg is not used, but we keep it for compatibility with FSM class\n for (test, action, next_state) in self.state_transitions.get(state, []):\n if test(self):\n return (action, next_state)\n try:\n return self.state_transitions_any[self.current_state]\n except KeyError:\n pass\n if self.default_transition != None:\n return self.default_transition\n raise ExceptionFSM(\'Transition is undefined: (%s, %s).\' % \n (str(input_symbol), str(self.current_state)) )\n</pre>', 'title': u'Subclass for unhashable input_symbols'}, {'comment': u'One more little modification that I found useful: if next_state is None, keep self.current_state unchanged.\n\n<pre>\n def process(self, input_symbol):\n self.input_symbol = input_symbol\n (action, next_state) = self.get_transition(self.input_symbol, self.current_state)\n if action is not None:\n action(self)\n if next_state is not None:\n self.current_state = next_state\n</pre>', 'title': u'Allow a next_state of "no change"'}, {'comment': u'A simple change allows transition routines to return data back to the FSM caller:\n<pre>\n def process(self, input_symbol):\n self.input_symbol = input_symbol\n (action, next_state) = self.get_transition(self.input_symbol, self.current_state)\n if action is not None:\n ret = action(self)\n if next_state is not None:\n self.current_state = next_state\n return ret\n</pre>', 'title': u'And allow transitions to return data to FSM caller'}, {'comment': u'passed to the function is state, whereas inside the member function current_state is used.', 'title': u'get_transition somewhat incorrect'}], 'desc': u'This recipe shows a Finite State Machine (FSM) that can be used for small parsing tasks. The code is quite simple. The bulk of it is comments. In addition to state this FSM also maintains a user defined "something". This "something" is effectively memory, so this FSM could be considered a Push-down Automata (PDA) since a PDA is a FSM + memory. This module contains an example function that demonstrates a simple RPN expression evaluator.\n'}, {'comments': [], 'desc': u'Okay, using the windows registry became easier with the newest versions of Python but do you exctly know where the keys have to be placed? You just want to store some data for your progam in the windows registry without fiddling around with SetValue() etc. Have a look at this class:'}, {'comments': [{'comment': u"I made a wrapper to urllib2.urlopen() in order to support file uploading\n\nhttp://fabien.seisen.org/python/\n\nIt uses boundary creation from mimetools and doesn't read the whole file in memory\n\n<pre>\nimport urllib2_file\nimport urllib2\n\ndata = {'name': 'value',\n 'file': open('/etc/services')\n }\nurllib2.urlopen('http://site.com/script_upload.php', data)\n</pre>", 'title': u'python mod'}, {'comment': u'<pre>\nimport urlparse\n\ndef posturl(url, fields, files):\n urlparts = urlparse.urlsplit(url)\n return post_multipart(urlparts[1], urlparts[2], fields,files)\n</pre>\n\nThis allows you to specify the form as a url and not worry about host and selector.', 'title': u'using urls'}, {'comment': u"simple update to use HTTPConnection instead of HTTP for the recipe to simplify it and also to use HTTP 1.1.\n\nOnly replace first function of the recipe:\n<pre>\ndef post_multipart(host, selector, fields, files):\n content_type, body = encode_multipart_formdata(fields, files)\n h = httplib.HTTPConnection(host) \n headers = {\n 'User-Agent': 'INSERT USERAGENTNAME',\n 'Content-Type': content_type\n }\n h.request('POST', selector, body, headers)\n res = h.getresponse()\n return res.status, res.reason, res.read() \n</pre>\n\nShould work as the original version.", 'title': u'Update to use HTTPConnection'}, {'comment': u'new version does additionally return Status and Reason information. For exact same return of original version replace\n\n<pre>\n res.status, res.reason, res.read() \n</pre>\n\nwith\n\n<pre>\n res.read() \n</pre>', 'title': u'extended return...'}, {'comment': u'Here\'s a version of your code that supports cookies with python 2.4\'s urllib2 and cookielib.\n\n<pre>\nimport httplib, mimetypes, mimetools, urllib2, cookielib\n\ncj = cookielib.CookieJar()\nopener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))\nurllib2.install_opener(opener)\n\ndef post_multipart(host, selector, fields, files):\n """\n Post fields and files to an http host as multipart/form-data.\n fields is a sequence of (name, value) elements for regular form fields.\n files is a sequence of (name, filename, value) elements for data to be uploaded as files\n Return the server\'s response page.\n """\n content_type, body = encode_multipart_formdata(fields, files)\n headers = {\'Content-Type\': content_type,\n \'Content-Length\': str(len(body))}\n r = urllib2.Request("http://%s%s" % (host, selector), body, headers)\n return urllib2.urlopen(r).read()\n\ndef encode_multipart_formdata(fields, files):\n """\n fields is a sequence of (name, value) elements for regular form fields.\n files is a sequence of (name, filename, value) elements for data to be uploaded as files\n Return (content_type, body) ready for httplib.HTTP instance\n """\n BOUNDARY = mimetools.choose_boundary()\n CRLF = \'\\r\\n\'\n L = []\n for (key, value) in fields:\n L.append(\'--\' + BOUNDARY)\n L.append(\'Content-Disposition: form-data; name="%s"\' % key)\n L.append(\'\')\n L.append(value)\n for (key, filename, value) in files:\n L.append(\'--\' + BOUNDARY)\n L.append(\'Content-Disposition: form-data; name="%s"; filename="%s"\' % (key, filename))\n L.append(\'Content-Type: %s\' % get_content_type(filename))\n L.append(\'\')\n L.append(value)\n L.append(\'--\' + BOUNDARY + \'--\')\n L.append(\'\')\n body = CRLF.join(L)\n content_type = \'multipart/form-data; boundary=%s\' % BOUNDARY\n return content_type, body\n\ndef get_content_type(filename):\n return mimetypes.guess_type(filename)[0] or \'application/octet-stream\'\n</pre>', 'title': u'With cookie support on Python 2.4'}, {'comment': u'Here is the same basic idea, but using a class inherited into the BasicHandler hierarchy of urllib2. It has the advantage of leaving all the existing urllib2 functionality intact.\n\nExample usage:\n<pre>\nimport MultipartPostHandler, urllib2, cookielib\n\ncookies = cookielib.CookieJar()\nopener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),\n MultipartPostHandler.MultipartPostHandler)\nparams = { "username" : "bob", "password" : "riviera",\n "file" : open("filename", "rb") }\nopener.open("http://wwww.bobsite.com/upload/", params)\n</pre>\n\nThe code is at: http://odin.himinbi.org/MultipartPostHandler.py', 'title': u'a less intrusive version using the urllib2 hierarchy'}], 'desc': u'A scripted web client that will post data to a site as if from a form using ENCTYPE="multipart/form-data". This is typically used to upload files, but also gets around a server\'s (e.g. ASP\'s) limitation on the amount of data that can be accepted via a standard POST (application/x-www-form-urlencoded).'}, {'comments': [{'comment': u'I was just wondering if there\'s a reason in not using the simpler dictionry trick as described in http://www.webreview.com/2000/07_07/developers/07_07_00_2.shtml\n\n<pre>\nmydict = {"title":"Formatted from Dict",\n"pi": 3.1415, "e": 2.7182,\n"sqrt3": 1.73205, "sqrt2": 1.4142}\n\ntemplate = """\n%(title)s\n\nFamous irrational numbers\nPi\n%(pi)2.3f\nSquare-root of 2\n%(sqrt2)2.3f\n"""\n\nprint template % mydict\n</pre>', 'title': u'Dictionary for template'}, {'comment': u'http://www.python.org/doc/current/lib/typesseq-strings.html', 'title': u'2.2.6.2 String Formatting Operations from Python Library Reference'}, {'comment': u"I chose to use a generic template language over Python's dictionary trick for format strings for one reason. I don't like having to put double percentile in the template whereever I want a literal one. Personally, I think that the template should be literal except for the variables. I'm sure there's a performance hit doing it this way, but I could solve that problem with some intelligent caching.", 'title': u'Using a generic template language'}], 'desc': u'This recipe consists of two classes usable for managing html templates, applicable to output from a CGI.'}, {'comments': [{'comment': u'Note that the locale module includes a format function that will insert\ncommas (or periods) in your numbers:\n<br>locale.format("%.2f", num, 1)<br>\nwill convert num to a separated string with two decimal places.', 'title': u' '}, {'comment': u"locale.format( '%.2f', xx, 1 ) commafies but only if you do\nlocale.setlocale(locale.LC_ALL, '') first.", 'title': u'Commafying with locale'}], 'desc': u'A quick function to comma separate thousands in an integer or float.'}, {'comments': [{'comment': u'Why call constructors/destructors of grandancestors? Either it has been done by direct ancestors or this behavior is undesirable.', 'title': u'incorrect behaviour - you must only worry about you direct ancestors'}, {'comment': u'Immediate ancestors are the only base classes being called. We must screen against diamond inheritance in the case of this technique being used by all classes up the inheritance chain. If it is not, it will still work, with only a small amount of additional bookkeeping that is unnecessary.\n\nUnless you are suggesting that grand-ancestors should not be called in general in OOP, which is not strictly a Python question.', 'title': u'Only direct ancestors are being called'}, {'comment': u"Would it be better to use issubclass instead of the setattr technique you are using? So you can call __init__ on all self.__class__.__bases__ except those which are superclasses of other bases?\n\nI haven't tested this though:\n\ndef __init__(self):\n for base in self.__class__.__bases__:\n skip = False\n for b2 in self.__class__.__bases__ if (b2 is not base):\n if issubclass(b2,base):\n skip = True\n break\n if (not skip):\n try:\n base.__init__(self)\n except AttributeError:\n pass\n\nAlso it would be nice to perhaps create a metaclass that automatically chains certain methods transparently.", 'title': u'Use issubclass?'}], 'desc': u'Chaining constructor and destructor calls together during object creation/destruction.'}, {'comments': [{'comment': u'Words can not express how much you have done for me with this code.\nThank You', 'title': u'GREAT JOB--------Thanks!!'}, {'comment': u'You may want to look at ctypes from Tom Heller.\n\nhttp://starship.python.net/crew/theller/ctypes/\n\nGene', 'title': u'Another module for calling dll functions.'}, {'comment': u'What do I have to do when my functions from DLL that don\'t have arguments?\n\nresult=self._dllcall("RevMensagens","","h",(\'\')) ==> it doesn\'t work!!', 'title': u'Function Without Arguments'}, {'comment': u'Today you are much better using ctypes (which is now part of the Standard Library) than this routine.', 'title': u'Depricated'}], 'desc': u'When I wanted to use Python to call functions in Windows .DLL I was surprised that I had a difficult time locating the necessary information for making this happen. This is a base class that you use to define your class (and methods for each function). It uses Sam Rushings calldll, cstring and membuf modules but I think it will make interfacing with any DLL much easier for the beginner (especially for the first time).'}, {'comments': [{'comment': u'Apperently you need to import nested scopes in Python versions before 2.2, i.e. from __future__ import nested_scopes.<br>\nOtherwise, this is an excellent function.', 'title': u'Nested scopes.'}, {'comment': u'I\'ve edited the recipe, adding "width=width" to the anonymous function\'s signature. This should work better than importing from __future__, as that would only work in Python 2.1.', 'title': u'fixed'}, {'comment': u"As noted above, until today, the function had a bug that sometimes caused premature line breaks. My apologies. It's fixed now, at a cost of some speed.", 'title': u'Another fix'}, {'comment': u"The code\n<br>\n<pre>len(line[line.rfind('\\n')+1:])</pre>\n\nactually makes a temporary copy of the last word, only to throw it away immediately.\n<br>\nBetter:\n<br>\n<pre>len(line)-line.rfind('\\n')-1</pre>", 'title': u'small inefficiency'}, {'comment': u'http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/358117', 'title': u'another CJK supported unicode word-wrap function'}, {'comment': u"It's code like this that gives reduce() a bad name. :-/ The code is both inscrutable and quadratic.", 'title': u"Don't use this for long inputs"}], 'desc': u'This word-wrap function flows paragraphs of text so they fit in a certain column width. It differs from similar methods in that it preserves existing whitespace such as newlines and runs of spaces.'}, {'comments': [{'comment': u' ', 'title': u'No need for __len__ here'}], 'desc': u'In order to change into a list, the length of\nan instance is investigated first.\n"__len__()" Next, all the contents are taken out in order. "__getitem__()"'}, {'comments': [], 'desc': u'Using gzip and StringIO module, then controllable gzipped stream.'}, {'comments': [], 'desc': u'This is a pure Python implementation of finite arithmetic.\n\nNeeds Python > 2.2'}, {'comments': [], 'desc': u'This recipe shows a simple way to filter out elements and attributes \nbelonging to a particular namespace.\n'}, {'comments': [{'comment': u'How do you print out the parsed xml object? Do you have any examples? Thanks.', 'title': u'Output'}, {'comment': u"I took this code and updated it to where it works pretty well for me now. First, I changed the Element to have its attributes in a dictionary. Then I added a few methods to provide easy access within the tree. Since I am very new to XML, I borrowed ideas from this recipe and a few notes by Uche Ogbuji. If you are interested, I would be happy to send the code with examples. I have never commented here nor posted any code so I really don't know how to approach it.", 'title': u' '}, {'comment': u'Add this method to Element to recreate the XML:\n\n<pre>\nprint element.toString()\n</pre>\n\nor you could even call this method __str__ to make it easy.\n\n<pre>\n def toString(self, level=0):\n retval = " " * level\n retval += "<%s" % self.name\n for attribute in self.attributes:\n retval += " %s=\\"%s\\"" % (attribute, self.attributes[attribute])\n c = ""\n for child in self.children:\n c += child.toString(level+1)\n if c == "":\n retval += "/>\\n"\n else:\n retval += ">\\n" + c + ("</%s>\\n" % self.name)\n return retval\n</pre>', 'title': u'obj2xml: and back again'}], 'desc': u'A generic script using expat to convert xml into objects'}, {'comments': [], 'desc': u'I needed a simple solution for sending MAPI mail within Python and at the cmd prompt. Here is a down and dirty solution'}, {'comments': [{'comment': u' In Java this is called a Dynamic Proxy. They were demonstrated in 1999 and added to the language core with Java 1.3.\n\nhttp://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html#api\nhttp://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html\nhttp://www.google.com/search?hl=en&lr=&ie=ISO-8859-1&q=java+dynamic+proxy&btnG=Google+Search ', 'title': u'Java Dynamic Proxies'}, {'comment': u'Why not just use __getattr__ (and __setattr__ if you write to members of the target):\n<pre>\nclass Proxy:\n def __init__(self,ProxyClass,**ProxyArgs):\n self.Target = ProxyClass(**ProxyArgs) \n def __getattr__(self,Name):\n #Minimal - all unresolved requests go to Target\n return getattr(self,Name)\n def __setattr__(self,Name,Val):\n if self.Target.__dict__.has_key(Name):\n setattr(self.Target,Name,Val)\n else:\n self.__dict__[Name] = Val</pre>', 'title': u'Easier way'}, {'comment': u'Oops - embarassing error corrected!<br>\n\nWhy not just use __getattr__ (and __setattr__ if you write to members of the target):\n<pre>\nclass Proxy:\n def __init__(self,ProxyClass,**ProxyArgs):\n self.Target = ProxyClass(**ProxyArgs) \n def __getattr__(self,Name):\n #Minimal - all unresolved requests go to Target\n return getattr(self.Target,Name)\n def __setattr__(self,Name,Val):\n if self.Target.__dict__.has_key(Name):\n setattr(self.Target,Name,Val)\n else:\n self.__dict__[Name] = Val</pre>', 'title': u'Easier way'}, {'comment': u'Running your code, I get a segmentation fault.\n<br><br>\nIt really should be something like:\n<br><br>\n<pre>\nclass Proxy (object):\n def __init__ (self, ProxyClass, *ProxyArgs, **ProxyKw):\n \'\'\'Initialize the ProxyClass with passed in args and keyword args\'\'\'\n self.__dict__[\'Target\'] = ProxyClass (*ProxyArgs, **ProxyKw) \n \n def __getattr__ (self, Name):\n \'\'\'Try to get our target\'s attribute, otherwise use our own attribute\'\'\'\n try:\n return getattr (self.__dict__[\'Target\'], Name)\n except:\n return object.__getattr__ (Name)\n\n def __setattr__(self,Name,Val):\n \'\'\'Try to set our target\'s attribute, otherwise set our own attribute\'\'\' \n if self.Target.__dict__.has_key(Name):\n setattr (self.Target, Name, Val)\n else:\n self.__dict__[Name] = Val\n\nx = Proxy(foo, 23)\nx.func1()\nx.func2(10,20)\n</pre>\n<br><br>\nBut, then you don\'t get the nice listing of function names when you do "dir(foo)" like to originally posted proxy code...\n<br><br>\n*BUT*, the original proxy code doesn\'t account for property objects, just function objects. If you\'re going to program to an interface, the property objects are just as important as the functions...', 'title': u'Another embarrassing error...'}, {'comment': u'Hi guys - Thanks for the alternative code! Perhaps both ways should be implemented, for as Tracy Ruggles points out - the function names should appear in the class dict, and they should also be part of the property objects. <br>\n-Paul\n\n', 'title': u'Response to "Easier ways"'}, {'comment': u'Hi Ry4an -<br>\nThanks for the links...I\'ve never heard of Dynamic Proxies before, as usual I am 3 years behind and had to reinvent the wheel. The material on the "Dynamic Proxy Classes" web page will be great for improving the design for python. I\'ve also noticed that the Python Cookbook recipe "Synchronizing All Methods on an Object" (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65202) has a good function for recursively finding all the functions in the superclasses of an object, which is what this recipe also needs. Anyhow, thanks a bunch for the feedback!<br>\n-Paul\n', 'title': u'Java Dynamic Proxies'}, {'comment': u'Have you considered using __metaclass__ instead? Suppose you want to create a large number of these proxy objects. Your method would mean all the wrapping happens for each instance, true? If you used a metaclass, you could do the wrapping before your wrapping class itself is created.', 'title': u'Why not use metaclass?'}], 'desc': u'"Design Patterns" [GoF] prescribes two commandments to live by: \n\n1) Program to an interface, not an implementation. \n2) Favor object composition over class inheritance. \n\nThis implies that every class should have a defined interface, and that every class should be a composition of objects. However, there is often a large barrier to object composition - sometimes a class needs to have the interface of its components. You don\'t want to extend the functionality of the component, you just want its interface, and you want all calls to that interface to be sent to the component object. In this case, it is so much easier to inherit even though you are not really extending the functionality of the parent class (this especially happens when writing GUI applications, where the components have huge APIs). If you bite the bullet and make a composite, you end up writing a lot of wrapper functions (see Figure 1). (A wrapper function has the same function signature as the function it is wrapping, and it simply calls the same function in the target object.) No one likes to write wrapper functions - its dull, boring, menial work. I\'ve thrown out plenty of my own designs because they would have required me to write wrappers for a huge number of functions (for example, the wxWindow class has over 130 member functions. See http://www.wxWindows.org), so I end up inheriting even though I know it is "wrong".\n\nThere is no way around this problem in C++ and Java (though maybe an IDE vendor could put in a tool to automatically generate wrapper functions). Amazingly enough, however, Python allows you to modify classes at run time. This means it is possible to make Python automatically write these wrapper (or proxy) functions for you. \n'}, {'comments': [], 'desc': u'Reformat the clipboard text.'}, {'comments': [{'comment': u'Also try Pexpect for scripting SSH or anything else.\nTake a look here:<br>\n http://pexpect.sourceforge.net/<br>\nStill beta, but very stable and easy to use.\n', 'title': u'Also try Pexpect for scripting SSH or anything else'}, {'comment': u'Pexpect only works on *nix.', 'title': u'not on Windows'}], 'desc': u'This is an EXTREMELY simple module for scripting a telnet session. It uses abbreviated versions of the commands exported by telnetlib followed by any necessary arguments.\n\nAn example of use would be:\n\nimport telnetscript\n\nscript = """ru Login:\nw %(user)s\nru Password:\nw %(pwd)s\nw cd ~/interestingDir\nw ls -l\nra\nw exit\nc\n"""\n\nuser = \'foo\'\npwd = \'bar\'\nconn = telnetscript.telnetscript( \'myserver\', vars() )\nlines = conn.RunScript( script.split( \'\\n\' ))\n\nThis assigns lines the value of the output of "ls" in "~/interestingDir" for user foo on myserver.'}, {'comments': [], 'desc': u'Build an index into a directory of xml files.\nSearch the index. Based around the indexing code \nfrom Alex Martelli, linux magazine, July 2002.'}, {'comments': [{'comment': u"This code uses modules in Mark Hammond's Windows Extenstions, which can be downloaded here:\nhttps://sourceforge.net/projects/pywin32/", 'title': u'You must have the windows extensions'}, {'comment': u'I think the win32file.ReadDirectoryChangesW function can be used to determine what has changed.', 'title': u'To find out which files were added / removed / modified'}], 'desc': u'Watch a folder for files added / deleted within it. Files renamed are listed as both added and deleted in the same notification. Changes to the folder itself are not picked up, but could be.'}, {'comments': [{'comment': u'The spirit of the above algorithm is to use the result array as \na double chained hash table, make repeated random picks, and query\nthe table to see if the number was already picked. The method works\nwell with large values of n, consumes memory space proportional to k,\nand runs with average time proportional to k when k is less than 2/3\'s\nof n. If k is closer to n, there will be many collisions and the\nalgorithm will thrash unacceptably.\n<pre></pre>\nThe following code adopts an equivalent method but takes advantage \nof the efficient C-coded hashing already built into Python\'s \ndictionaries. In cases where k is more than 2/3\'s of n, the code\nswitches to a shuffle algorithm which takes time proportional\nto k and space proportional to n.\n\n<pre>\nimport random\n\ndef ranksb1(n,k):\n if k > n: raise Exception, "N must be no less than K"\n if k > n * 2 // 3:\n pool = range(1,n+1)\n for i in xrange(n-1, n-k-1, -1):\n j = random.randrange(i+1)\n pool[i], pool[j] = pool[j], pool[i]\n return pool[-k:]\n selections = {}\n while k > len(selections):\n value = random.randrange(1, n+1)\n if value in selections: continue\n selections[value] = True\n return selections.keys()\n</pre>', 'title': u'Take advantage of dictionaries. Use alternate approach for difficult cases.'}, {'comment': u'The routine fails (or appears to fail) when n=k. Add a statement that returns the entire set when the subset size must be the same as the set size.', 'title': u'Error in algorithm'}, {'comment': u'After further development and peer review, the above code was refined to have a more parallel structure, have consistent variable names, use local variable optimization, and return selections in selection order. The new algorithm switchover point minimizes memory consumption while maintaining best speed. The new function name better indicates that the routine implements random sampling without replacement.\n\n<pre>\nfrom random import random\n\ndef sample(n, k, random=random, int=int):\n """Chooses k unique random elements from [0,n).\n\n Used for random sampling without replacement.\n """\n\n if not n >= k >= 0:\n raise ValueError, "sample larger than population"\n result = [None] * k\n if k * 6 > n: # if n len list takes less space than a k len dict\n pool = range(n)\n for i in xrange(k): # invariant: non-selected at [0,n-i)\n j = int(random() * (n-i))\n result[i] = pool[j]\n pool[j] = pool[n-i-1]\n else:\n selected = {}\n for i in xrange(k):\n j = int(random() * n)\n while j in selected:\n j = int(random() * n)\n result[i] = selected[j] = j\n return result\n</pre>', 'title': u'Refined version'}, {'comment': u"Isn't this just a bad implementation of the (more general) built-in random.sample?", 'title': u'random.sample?'}, {'comment': u'I think this is the implementation.', 'title': u'Re: random.sample?'}], 'desc': u'This is a translation of the Fortran subroutine RANKSB which appears on pp 38-9 of Nijenhuis & Wilk (1975) Combinatorial Algorithms, Academic Press.'}, {'comments': [{'comment': u'The class attribute is only referenced the first time an instance tries "self.counter+=1". From then on, the instance has its own "counter" attribute. Example:<br>\n<pre>\n\nPython 2.2.1 (#1, Sep 10 2002, 08:31:39)\n[GCC 2.95.3 20010315 (release)] on linux2\nType "help", "copyright", "credits" or "license" for more information.\n>>> class X:\n... counter = 0\n... def op(self):\n... self.counter += 1\n...\n>>> myx = X()\n>>> X.counter\n0\n>>> myx.op()\n>>> X.counter\n0\n>>> myx.counter\n1\n>>>\n</pre>\n\n<br><br>\nNote that this isn\'t the case for mutable attributes, however. Mutable attributes are shared if they\'re part of a class definition.\n<br><br>', 'title': u"Actually, There's a Subtle Difference"}, {'comment': u"As Troy Melhase explain in the previous comment, the recipe can cause some subtle bugs if it is used without care for mutable data initialization. And so it's probably better to not use it at all with mutable data.\n\nThis is rather similar to the problems raised by the use of mutable objects as\n default value for function parameters.\n\nhttp://www.python.org/doc/current/tut/node6.html#SECTION006710000000000000000", 'title': u'A potential pitfall'}], 'desc': u'You need to set some attributes to a constant value during object initialization.'}, {'comments': [{'comment': u' ', 'title': u'really nice ! :o) (nt)'}, {'comment': u"But define endl in the module with IOManip and OStream - don't want to have to reinvent it every time.", 'title': u'Much simpler to use than "The average of %d and %d is %f\\n" % ...!'}, {'comment': u'Better use <pre>self.output.write("%s" % thing)</pre> instead of <pre>self.output.write(str(thing))</pre>\n\n<br>str(thing) can fail, if the thing is an unicode string.', 'title': u'Nice, but'}, {'comment': u' ', 'title': u'very nice and surprisingly simple!'}], 'desc': u'A very simple proof-of-concept of an ostreams-like interface wrapping around\nfile-like objects, included a demonstration of manipulators.\n'}, {'comments': [{'comment': u"<pre>\nimport time, os\n\n#Set the filename and open the file\nfilename = 'security_log'\nfile = open(filename,'r')\n\n#Find the size of the file and move to the end\nst_results = os.stat(filename)\nst_size = st_results[6]\nfile.seek(st_size)\n\nwhile 1:\n where = file.tell()\n line = file.readline()\n if not line:\n time.sleep(1)\n file.seek(where)\n else:\n print line, # already has newline\n</pre>", 'title': u'How to make it usable'}, {'comment': u'Sometimes you actually just want the last 10 lines of the file. This will work quite happily on 10Meg files.<br>\n\nI would love to know if there is a more efficient method.\n<pre>\nimport sys\ndef tail_lines(filename,linesback=10,returnlist=0):\n """Does what "tail -10 filename" would have done\n Parameters:\n filename file to read\n linesback Number of lines to read from end of file\n returnlist Return a list containing the lines instead of a string\n\n """\n avgcharsperline=75\n\n file = open(filename,\'r\')\n while 1:\n try: file.seek(-1 * avgcharsperline * linesback,2)\n except IOError: file.seek(0) \n if file.tell() == 0: atstart=1 \n else: atstart=0\n\n lines=file.read().split("\\n")\n if (len(lines) > (linesback+1)) or atstart: break\n #The lines are bigger than we thought\n avgcharsperline=avgcharsperline * 1.3 #Inc avg for retry\n file.close()\n\n if len(lines) > linesback: start=len(lines)-linesback -1\n else: start=0\n if returnlist: return lines[start:len(lines)-1]\n\n out=""\n for l in lines[start:len(lines)-1]: out=out + l + "\\n"\n return out\n\nprint tail_lines(\'/etc/hosts\',5,1)\nsys.stdout.write(tail_lines(\'/etc/hosts\',5)) \n</pre>', 'title': u'What tail-10 would do'}, {'comment': u"This seems rather inefficient - suppose several lines are added to the file at once - this version will read them a line at a time; pausing for a second between each.\n\nI'm doing more or less the same, but seeking to EOF then using readlines:\ninfile,seek(0,2)\nwhile 1:\nlines=infile.readlines\nif not lines:\ntime.sleep(1)\nelse\n# print the line, or pattern match in it, etc.\nBetter? (New to Python, so I could be way off the mark!)", 'title': u"Err, unless I'm missing something"}], 'desc': u'A simple implementation of the standard UNIX utility tail -f in Python.\n'}, {'comments': [{'comment': u'This example generates the following traceback in Python 2.3.2:<br>\n<br>\nTraceback (most recent call last):<br>\n File "C:\\MyPython\\XMLexample.py", line 102, in -toplevel-<br>\n print doc<br>\n File "C:\\MyPython\\XMLexample.py", line 31, in __str__<br>\n return _encode(self.doc.toprettyxml())<br>\n File "C:\\Python23\\lib\\xml\\dom\\minidom.py", line 59, in toprettyxml<br>\n self.writexml(writer, "", indent, newl, encoding)<br>\nTypeError: writexml() takes at most 5 arguments (6 given)<br>', 'title': u'Broken in Python 2.3.2'}, {'comment': u"xml.dom.minidom.Document API changed between 2.2 and 2.3. There are two fixes:<br>\n1) add encoding argument to _Document.writexml in the recipe, or<br>\n2) don't use _Document at all because it is no longer needed, toxml() takes optional encoding argument in Python >= 2.3", 'title': u'Re: Broken in Python 2.3.2'}, {'comment': u'the easiest way to solve the problem is as below: <br><br>\n\nold code :<br><br>\n\nclass _Document(Document):\n\n def writexml(self, writer, indent="", addindent="", newl=""):\n writer.write(\'\\n\' % enc)\n for node in self.childNodes:\n node.writexml(writer, indent, addindent, newl)<br><br><br>\n\nnew code :<br><br>\n\nclass _Document(Document):\n\n def writexml(self, writer, indent="", addindent="", newl=""):\n writer.write(\'\\n\' % enc)\n for node in self.childNodes:\n node.writexml(writer, indent, addindent, newl, _encode)', 'title': u'correction of lightweight XML parser and reader'}, {'comment': u'This fix doesn\'t work with 2.3.4:\nTraceback (most recent call last):\n File "xml_inout.py", line 101, in ?\n print doc\n File "xml_inout.py", line 31, in __str__\n return _encode(self.doc.toxml())\n File "C:\\python23\\lib\\xml\\dom\\minidom.py", line 48, in toxml\n return self.toprettyxml("", "", encoding)\n File "C:\\python23\\lib\\xml\\dom\\minidom.py", line 60, in toprettyxml\n self.writexml(writer, "", indent, newl, encoding)\nTypeError: writexml() takes at most 5 arguments (6 given)', 'title': u"Fix doesn't work with 2.3.4"}, {'comment': u'I finally understood one of the previous comments. Forgive me, I\'m still learning Python.\n"Don\'t use _Document()"\nSo I changed:\nself.doc = _Document()\nto:\nself.doc = Document()\n\nand now it works correctly on 2.3.4!', 'title': u'Aha!'}, {'comment': u"Does this fix break the module on Python 2.2?<br>\nIf it does, would a simple version checking 'if' statement do the trick?<br>\n<br>\ni.e....<br>\nif (sys.version_info[0] is 2) and (sys.version_info[1] is 2):<br>\nself.doc = _document()<br>\nelif (sys.version_info[0] is 2) and (sys.version_info[1] > 2):<br>\nself.doc = Document()<br>", 'title': u'Version checking?'}], 'desc': u"XML is a wonderful buzzword, so clients often like to have exports of data in that format. But as a programmer you may not like to fiddle around with various XML Parsers. Here is a very easy solution, that doesn't offer all capabilities of XML but sufficient stuff for creating valid XML outputs and read them later."}, {'comments': [{'comment': u'What do I need to do to get this script to work with Python 2.1?\nI want to run it with Zope without having to connect via XML-RPC or something.\n\n(my knowledge of python is OK, but not in what the difference is between 2.1 and 2.2)', 'title': u'Python 2.1'}, {'comment': u'I had to use PortableUnixMailbox instead of UnixMailbox:<br>\n<br>\nbefore: mb = mailbox.UnixMailbox (file(mailboxname_in,\'r\'))<br>\nafter: mb = mailbox.PortableUnixMailbox (file(mailboxname_in,\'r\'))<br>\n<br>\nOtherwise, this script works great! You can return None from your filter-function to remove a message. I was able to delete a bunch of duplicate messages by adding this:<br>\n<br>\n<pre>\nfound_ids = {}\n\n# ...\n\ndef passthrough_filter (msg, document):\n """This prints the \'from\' address of the message and\n returns the document unchanged.\n """\n id = msg.getheader(\'Message-ID\')\n if found_ids.has_key(id):\n return None\n found_ids[id] = 1\n return document\n</pre>\n\nThanks,<br>\nDave<br>', 'title': u'Use PortableUnixMailbox'}, {'comment': u'Hi,\nI wrote a similar program for previewing mail and deleting it from the server without downloading it. It has a text-based interface using effbots console module. So it runs on Windows only.\n<br><br>\nLook at PyPi:\nhttp://www.python.org/pypi?:action=display&name=PyPosta&version=1.2', 'title': u'similar task, nicer user interface'}, {'comment': u'In order you can use this scrip with Python 2.1 change the following lines: <br>\n<pre>\n31 mb = mailbox.UnixMailbox (file(mailboxname_in,\'r\'))\n32 fout = file(mailboxname_out, \'w\')\n</pre>\nsuch that you replace class "file", it means:<br>\n<pre>\n fin = open(mailboxname_in,"r")\n mb = mailbox.UnixMailbox (fin)\n fout = open(mailboxname_out,"w")\n</pre>', 'title': u'Changes for Python 2.1'}, {'comment': u"If you use this on Windows, you'll need to change the 'r' argument to file() to an 'rb', to make sure Python doesn't munge the end-of-line characters.", 'title': u'Slight addition for Windows'}], 'desc': u'This script demonstrates reading and writing an mbox style mailbox. This script is an mbox filter. It scans through an entire mbox and writes the messages to a new file. Each message is passed through a filter function which may modify the document or ignore it.'}, {'comments': [], 'desc': u'This recipe combines the delicious PageTemplates package with the flavorful Medusa package to serve up rendered PageTemplates from the file system.\n\nWhy not just use Zope you say? As far as I know, the current Zope release isn\'t an option with Python 2.2 code. The project for which this recipe was devised requires Python 2.2.\n\nIngredients you\'ll need:\n\n1.\tPython 2.2. If you\'re using 2.1, try Zope instead, as it does everything this recipe can do plus a whole lot more.\n\n2.\tExtensionClass and friends. There is more than one way to get ExtensionClass installed, but the method I\'ve used successfully is to install StandaloneZODB. That package is available here: http://www.zope.org/Products/StandaloneZODB\n\n3.\tPageTemplates, TAL, and ZTUtils packages. These are available in the Zope source releases but must be installed manually. Again, there\'s more than one way to make these packages available in your system. The method I\'ve used is to copy the package directories from the Zope source archive into the Python lib/site-packages/ directory. The Zope source is available from this link: http://www.zope.org/Products\n\n4.\tMedusa. I used Medusa 0.5.2 to develop this recipe, but you may have an equally pleasant experience with other versions. You can get Medusa here: http://oedipus.sourceforge.net/medusa/\n\n5.\tA Medusa startup script. As with all Medusa handlers, you must explicitly construct a PageTemplates handler and associate it with an HTTP server. You can modify a copy of the sample startup script included with Medusa or create your own.\n\n6.\tSome PageTemplates. The code below reads PageTemplates markup from files stored in your file system. Give your markup files a ".pt" or ".ptx" extension, and the handler will try to render them as PageTemplates before returning their markup.\n\nOnce you have all these items in place, modify your Medusa start up script:\n\n1.\tSave the code below as "pagetemplate_handler.py", and bring it into your script: import pagetemplate_handler\n\n2.\tConstruct a pagetemplate_handler.pagetemplate_handler, pagetemplate_handler.pagetemplate_xml_handler, or both. These types need a filesystem object, just like the default_handler.\n\n3.\tAssociate your pagetemplate_handler with your HTTP server.'}, {'comments': [{'comment': u'By coincidence, I recently wrote a similar function. My solution aims to be simpler and more obvious (less magic) to the reader who encounters a usage. Here it is, with my docstrings:\n<pre>\ndef make_attributes_from_args(*argnames):\n """\n This function simulates the effect of running\n self.foo=foo\n for each of the given argument names (\'foo\' in the example just\n now). Now you can write:\n def __init__(self,foo,bar,baz):\n copy_to_attributes(\'foo\',\'bar\',\'baz\')\n ...\n instead of:\n def __init__(self,foo,bar,baz):\n self.foo=foo\n self.bar=bar\n self.baz=baz\n ... \n """\n \n callerlocals=sys._getframe(1).f_locals\n callerself=callerlocals[\'self\']\n for a in argnames:\n setattr(callerself,a,callerlocals[a])\n \n \n """\n ----------------------------------------------------------------\n More discussion:\n \n I feel that the non-standard function (this one) is justified even\n though it is less clear than the comb code above. The comb code\n version is as offensive to me as this is:\n mylist.append(\'a\')\n mylist.append(\'b\')\n mylist.append(\'c\')\n \n That code, while clear, punishes both the reader and programmer.\n I hope that none of you would ever write the above, and that you\'d\n use something like "mylist.extend([\'a\',\'b\',\'c\'])" instead. My\n make_attributes_from_args function is to be used in an analagous\n manner. (Yes, certain situations will warrant code that is\n repetitive in some way or another. But I\'m talking about\n self.foo=foo stuff, not those situations.)\n\n Another way to look at the attribute-assignment problem: There\'s\n only one \'program step\' going on in the block-- some locals are\n getting copied to instance variables. One thing deserves one line.\n\n The disadvantage of the function is that it makes ordinary code\n harder to read for programmers who haven\'t read these\n instructions. My only weapon against that problem is the choice\n of the function\'s name. I deliberately chose \'make\' and \'args\'\n instead of \'set\' and \'locals\' because I want the reader to\n immediately think of the new attributes that are (probably) being\n created out of the arguments to __init__. The fact that this\n function will operate on any locals and set existing attributes to\n new values is incidental.\n\n I would be interested to hear better names for the function. If I\n get a better one, I will convert all my code immediately.\n\n For another look at the same problem, see:\n http://twistedmatrix.com/users/acapnotic/keeparg.py.html\n """\n</pre>', 'title': u'another solution to the same problem'}, {'comment': u"Instead of\n\n<pre>\n exec 'defaults[self].%s = %s' % (arg, 'value')\n</pre>\n\na more Pythonic alternative might be\n\n<pre>\n setattr(defaults[self], arg, value)\n</pre>\n", 'title': u'More Pythonic alternative to using exec'}, {'comment': u'Here\'s a trimmed version with a suggested name change. I think the name __update__ works here for two reasons:<br>\n<br>\n1. The leading and trailing double underscores let users know that there\'s something special happening, and<br>\n<br>\n2. what this method is doing is updating the dictionary of an instance with another dictionary made up of key/value pairs from \n__init__\'s parameter list, i.e., something like this is going on:<br>\n    self.__dict__.update(initparamsdict)<br>\n<br>\nSo, since what we\'re doing is updating a dictionary, in a special way, and the method to do that is called \'update\', it seems like \'__update__\' would be a reasonable name.<br>\n<br>\n<br>\ndef __update__(include=[], exclude=[]):<br>\n    import inspect<br>\n    args, varargs, varkw, defaults = inspect.getargvalues(inspect.stack()[1][0])<br>\n    self = defaults[args[0]]<br>\n    if not include:<br>\n        include = args[1:] # skip \'self\'<br>\n        if varkw:<br>\n            include.extend(defaults[varkw].keys())<br>\n            defaults.update(defaults[varkw])<br>\n    for attrname in include:<br>\n        if attrname not in exclude:<br>\n            setattr(self, attrname, defaults[attrname])<br>\n<br>\n# some testing<br>\nclass c:<br>\n    def __init__(self, a, b, c=3, **kwargs):<br>\n        __update__()<br>\n<br>\n    def ignore_a_b(self, a, b, c, d):<br>\n        __update__(exclude=[\'a\', \'b\'])<br>\n <br>\n    def ignore_c_d(self, a, b, c, d):<br>\n        __update__(include=[\'a\', \'b\'])<br>\n<br>\n<br>\nx = c(1,2,d=4)<br>\nprint "x.__dict__ = %s"%x.__dict__<br>\nx.ignore_a_b(10,20,30,40)<br>\nprint "x.__dict__ = %s"%x.__dict__<br>\nx.ignore_c_d(100,200,300,400)<br>\nprint "x.__dict__ = %s"%x.__dict__<br>\n<br>\n<br>\n# outputs<br>\nx.__dict__ = {\'a\': 1, \'c\': 3, \'b\': 2, \'d\': 4}<br>\nx.__dict__ = {\'a\': 1, \'c\': 30, \'b\': 2, \'d\': 40}<br>\nx.__dict__ = {\'a\': 100, \'c\': 30, \'b\': 200, \'d\': 40}<br>\n<br>', 'title': u' '}, {'comment': u'Here\'s a somewhat more explicit version:<br>\n<br>\ndef params(include=[], exclude=[]):<br>\n    "returns a dictionary of parameter names and values"<br>\n    import inspect<br>\n    args, varargs, varkw, defaults = inspect.getargvalues(inspect.stack()[1][0])<br>\n    if not include:<br>\n        include = args[:]<br>\n        if varkw:<br>\n            include.extend(defaults[varkw].keys())<br>\n            defaults.update(defaults[varkw])<br>\n    return dict([(attrname, defaults[attrname])<br>\n        for attrname in include if attrname not in exclude])<br>\n<br>\nThis is used as follows:<br>\n<br>\nclass c:<br>\n    def __init__(self, a, b, c=3, **kwargs):<br>\n        self.__dict__.update(params(exclude=[\'self\']))<br>\n<br>\nThis method is less concise, but it makes it easier to understand what you\'re trying to do - add attributes to self\'s __dict__ using the names and values supplied in __init__\'s parameter list. Plus, you have the added benefit of a generally useful method "params()".\n', 'title': u' '}, {'comment': u"I like it - I've switched to this approach in my own code.", 'title': u' '}, {'comment': u"One thing to watch out for with this approach is that new style classes that make use of __slots__ don't have a __dict__ attribute.", 'title': u' '}, {'comment': u"After using this in quite a bit of code over the past 18 months I've noticed some pitfalls. I still like the idea of not having to type (or mis-type) instance variable names 3 times in the constructor, but these pitfalls should be weighed against that advantage to see if you like the balance.<br>\n<br>\nFirst, when inspecting old code it is sometimes nice to search for self.x to determine where the instance variable x was initialized. After scratching my head for a while as to why I can only find self.x being used and not being initialized, I eventually remember that this recipe is in use. This isn't a huge deal, but it can be distracting when you're trying to find a bug.<br>\n<br>\nAlso, the inspect module is not terribly fast at this kind of thing. This isn't a problem for instantiating objects a few times, but the time to run AssignMemberVariablesFromParameters can dominate the creation time of small objects. For example take this code:<br>\n<br>\n<pre>\nclass c:\n def __init__(self, a, b):\n AssignMemberVariablesFromParameters()\n\nfor i in xrange(100):\n x = c(i, i)\n a = x.a\n b = x.b\n</pre><br>\nProfiling this on Python 2.3.3 on Windows XP indicates that over 95% of the total run time is spent inside inspect.stack. So if you have a coordinate class and you need to create thousands of coordinates then you should keep an eye on how this approach impacts your performance requirements.<br>\n<br>\nFinally, source code analysis tools like PyChecker don't do well with this approach. Because of the magic involved, it appears that the parameters are never used and that the instance variables are never initialized.<br>\n<br>\nA more generally applicable version of techniques like this can be found in:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/201195", 'title': u'Some relections after long term use'}], 'desc': u'Writing code like this can be very repetitive:\n\nclass c:\n       def __init__(self, memberVariableNumberOne, memberVariableNumberTwo):\n               self. memberVariableNumberOne = memberVariableNumberOne\n               self. memberVariableNumberTwo = memberVariableNumberTwo\n\nThe above can be changed to:\n\nclass c:\n       def __init__(self, memberVariableNumberOne, memberVariableNumberTwo):\n               AssignMemberVariablesFromParameters()\n'}, {'comments': [{'comment': u'should have been:<br><br>\n\ndef set_baz(self, value): self.__baz = value<br>\nbaz = property(fset=set_baz)<br><br>\n\nnot "bar"<br><br>\n\nsorry for any confusion,<br>\nSean\n', 'title': u'correction'}, {'comment': u'should have been:<br><br>\n\ndef set_baz(self, value): self.__baz = value<br>\nbaz = property(fset=set_baz)<br><br>\n\nnot "bar"<br><br>\n\nsorry for any confusion,<br>\nSean\n', 'title': u'correction'}, {'comment': u'The corrections noted above have been made.', 'title': u're: correction'}, {'comment': u'mangle\'s reliance on obj.__class__ means that it\'ll be unable to find the private variable if someone attempts to fetch a property via a subclass. To fix it, we need to get the class name somehow. Fortunately, that\'s in the stack, too. :) \n\n<pre>\'\'\' \nwritten by: Sean Ross\ncreated: 10/21/02\n\nmodified to cope with inheritance by: Garth Kidd\nwhen: 1/9/03\n\'\'\'\nfrom traceback import extract_stack\n\ndef __classAndLeftOperands__():\n stack = extract_stack()\n argStack = stack[-3:][0][-1]\n className = stack[1][2]\n \n args = argStack.split(\'=\')\n args.pop()\n args = args[0].split(\',\') # handle csv\'s\n leftOperands = [arg.strip() for arg in args] # and, remove whitespace\n\n return className, leftOperands\n\ndef mangle(obj, name, className):\n \'\'\'mangles name according to python name-mangling \n conventions for private variables\'\'\'\n return \'_\' + className + \'__\' + name\n\n# based on code by Guido van Rossum, comp.lang.python 2001-07-31\ndef readonly():\n "returns a list of read-only properties, one for each left operand"\n className, args = __classAndLeftOperands__()\n def __readonly(name, className):\n def get(obj):\n return getattr(obj, mangle(obj, name, className))\n return property(get)\n props = [__readonly(name, className) for name in args]\n if len(props) == 1: props = props[0]\n return props\n\ndef writeonly():\n "returns a list of write-only properties, one for each left operand"\n args = __leftoperands__()\n def __writeonly(name):\n def set(obj, value):\n return setattr(obj, mangle(obj, name), value)\n return property(fset=set)\n props = [__writeonly(name) for name in args]\n if len(props) == 1: props = props[0]\n return props\n</pre>', 'title': u'Breaks on inheritance'}, {'comment': u"I've posted a source distribution for this [1], with an explanation on my blog [2]. To avoid treading on Sean's code, I've used distutils to give appropriate credit: him as the author, with me in as a maintainer. Sean, if you want to take back over and maintain at your site, let me know. <br>1: http://www.deadlybloodyserious.com/Python/files/prop-1.5.zip<br>\n2: http://www.deadlybloodyserious.com/Python/2003/01/09.html#a1047", 'title': u'Posted updated module as source distribution'}, {'comment': u"Hi.<br>\nFirst, thank you for pointing out this algorithms limitation with<br>\nregard to inheritance. I've taken your suggestions and incorporated<br> \nthem into the code(as you'll notice). I've made some changes; mostly<br> \nfor personal taste. For instance, I changed __classAndLeftOperands__()<br> \nto __outside__() (yours is more descriptive, but it is quite long)<br>\n<br>\nAnyway, there was one change I made that was not purely cosmetic:<br>\n<br>\nclassName = stack[1][2]<br>\n<br>\nbecame<br>\n<br>\ncls = stack[-3:][0][-2]<br>\n<br>\nThis is important. On my system, for instance, to gain access to the<br> appropriate stack frame from the front(?) of the stack, I need to<br> call:<br>\n<br>\nclassName = stack[6][2]<br>\n<br>\nto get the intended results. My system has more overhead, seemingly.<br> \nAnyway, accessing the data from the back of the stack seems more<br> reliable, as is evidenced by the original __leftoperands__() having<br>\nworked on your system.<br>\n<br>\nOther than that, this is a fine improvement. Thanks.<br>\n<br>\nNow, if you can figure out how to remove the requirement for having<br> to provide the private instance variables for each property, that'd<br> be great.<br>\n", 'title': u'Small Problem'}, {'comment': u"I'd noticed that my code was extremely brittle -- readonly() would fail if I compiled my application with py2exe, and intermittently if I tried to reload a module. I'll try it with your modifications! ", 'title': u'Aha!'}, {'comment': u"... so __outside__ can't get the source line. I'm exploring aloud on my blog, and will report back if I make any progress. Or, not. :)<br><br>http://www.deadlybloodyserious.com/Python/2003/01/10.html#a1050\n", 'title': u'No go. Py2exe strips source lines...'}, {'comment': u'Try something along these lines: \n\n<pre>def readonly2(*propList):\n "inserts definitions for local properties in the parent frame"\n stack = traceback.extract_stack()\n cls = stack[-2:][0][-2]\n targetFrame = sys._getframe(1)\n def __readonly(name): \n def get(self):\n return getattr(self, mangle(cls, name))\n return property(fget=get)\n for prop in propList:\n targetFrame.f_locals[prop] = __readonly(prop)</pre>... and then... <br><pre>readonly2(\'name\', \'colour\', \'eyes\')</pre>... to create the read-only attributes. Not depending on the source, it works properly under py2exe. That said, the syntax leaves a lot to be desired. ', 'title': u'Got it!'}, {'comment': u'This works under python, python -OO, and py2exe:<br><pre>def __outside__():\n \'\'\'retrieves list of names of left operands for calling function\n and the name of the class where that function was called.\'\'\'\n code = sys._getframe(2).f_code\n cls, names = code.co_name, list(code.co_names)\n names.reverse()\n caller = sys._getframe(1).f_code.co_name\n args = names[:names.index(caller)]\n return cls, args</pre><br>When you update the code, set __version__ to "1.7"; using a float also breaks py2exe. :) ', 'title': u'Better yet!'}, {'comment': u'Unfortunately, the new __outside__() doesn\'t work on my system.<br>\nUsing the test code I provide in the comments, but with all code <br>\nin __main__ below test = Test() commented out and the new<br>\n__outside__() with print statements, i.e.,<br>\n<br>\ndef __outside__():<br>\n    ...<br>\n    cls, names = code.co_name, list(code.co_names)<br>\n    print "class: ", cls<br>\n    print "names: ", names<br>\n    ...<br>\n    args = names[:names.index(caller)]<br>\n    print "args: ", args<br>\n    ...<br>\n<br>\nI get the following output:<br>\n<br>\nclass: Test<br>\nnames:[\'__name__\', \'__module__\', \'readonly\', \'foo\', \'bar\', \'writeonly\', \'fro\', \'boz\', \'__init__\']<br>\ncaller: readonly<br>\nargs: [\'__init__\', \'boz\', \'fro\', \'writeonly\', \'bar\', \'foo\']<br>\n<br>\nclass: Test<br>\nnames: [\'__name__\', \'__module__\', \'readonly\', \'foo\', \'bar\', \'writeonly\', \'fro\', \'boz\', \'__init__\']<br>\ncaller: writeonly<br>\nargs: [\'__init__\', \'boz\', \'fro\']<br>\n<br>\n\nYou\'ll notice that the args for readonly is _not_ [\'foo\', \'bar\'].<br>\nSo, unfortunately, __outside__() remains brittle, so long as <br>\nyour intent is to use py2exe.<br>\nVersion 1.6 seems ...ok..., otherwise.<br>\n', 'title': u'Sorry'}, {'comment': u"For the moment __outside__() remains brittle. I propose that it<br> be deprecated and that readonly2() replace readonly().<br>\nreadonly2() appears to be stable. The syntax is ok, for now.<br>\nI do have one minor change: <br>\n<br>\ndef __readonly(name):<br>\n    name = mangle(cls, name)<br>\n    def get(obj):<br>\n        return getattr(obj, name)<br>\n    return property(fget=get)<br>\n<br>\nI realized that mangle() was being called every time a property<br> was used, not just when the property is created, which is, of<br> course, unnecessary.<br>\n<br>\nUntil __outside__() can be made stable, I recommend that it not<br> be used.<br>\nLet me know what you think.<br>\nIf you agree, I will update the current version to reflect these<br> decisions.<br>\n<br>\nJust one more idea:<br>\nWhat I'd like to see is<br>\n<br>\ndef readonly(**kwds): ... <br>\n<br>\nso that the usage would be<br>\n<br>\nreadonly(foo=1, bar=2)<br>\n<br>\nMore importantly, I'd like to remove the requirement for<br> providing the private instance variables '__foo', '__bar',<br> \ni.e., I'd prefer not to have to do this:<br>\n<br>\nreadonly('foo', 'bar')<br>\n...<br>\ndef __init__(self):<br>\n    self.__foo = 1<br>\n    self.__bar = 2<br>\n    ...<br>\n<br>\nIn the meantime, readonly2() will suffice.<br>\nLet me know your thoughts.<br>\nSean<br>", 'title': u'deprecate __outside__()'}, {'comment': u'Try this:<br>\n<br>\ndef readonly(**kwds):<br>\n    "inserts definitions for local properties in the parent frame"<br>\n    stack = traceback.extract_stack()<br>\n    cls = stack[-2:][0][-2]<br>\n    frame = sys._getframe(1)<br>\n    def __readonly(name, default):<br>\n        name = mangle(cls, name)<br>\n        def get(obj):<br>\n            setattr(obj, name, default)<br>\n            return getattr(obj, name)<br>\n        return property(fget=get)<br>\n    for name,value in kwds.items():<br>\n        frame.f_locals[name] = __readonly(name, value)<br>\n<br>\nusage: readonly(foo=1, bar=2)<br>\nNote: does not require you to provide private instance variables<br> __foo and __bar (!)\n<br>\nIt\'s a bit of a bodge, because you have to set the private instance variable every time the property is called.\nIt\'s nicer in writeonly, where this bodge is not required.\n<br>\nI like this. Let me know what you think before I update the recipe.<br>\n', 'title': u'This works'}, {'comment': u'def __readonly(name, default):<br>\n    name = mangle(cls, name)<br> \n    def get(obj):<br>\n        value = default<br>\n        try:<br>\n            value = getattr(obj, name)<br>\n        except AttributeError:<br>\n            setattr(obj, name, default)<br>\n        return value<br>\n    return property(fget=get)<br>\n<br>\nThis avoids calling setattr() every time property is called.\nIt is only called if getattr() fails, i.e., on the first call. \nAll subsequent calls to getattr() will succeed, and setattr() will not be called.', 'title': u'fixed bodge'}, {'comment': u"I've decided to go ahead and post version 1.8. I've changed __outside__() so that now it simply takes care of the repetitive code that was in both readonly() and writeonly().<br>\nLet me know if this latest version gives you any problems. For now, I'm very happy with this version. This is what I was hoping to make all along. Thanks for your help.<br>\nSean", 'title': u'Version 1.8'}, {'comment': u"The problem with my __outside__ is that it assumes that readonly() or writeonly() are the LAST items called. In your test code, __init__ is defined lastish, hence the problem. I guess we could search through the frame above's locals to check to see whether the names are defined. \n<br><br>\nThe new keyword argument style certainly saves us having to grope around for the names, but can we stick with the use of sys._getframe()? Its results seem a little more deterministic than wading through the trace. ", 'title': u'Aah. I think I get it, now. '}, {'comment': u"code.co_stacksize might have the number of lvars we need.<br><pre>def __outside__():\n '''STILL A LITTLE BROKEN.'''\n code = sys._getframe(2).f_code\n cls, names = code.co_name, list(code.co_names)\n names.reverse()\n caller = sys._getframe(1).f_code.co_name\n args = names[:names.index(caller)][-code.co_stacksize:]\n args.reverse()\n return cls, args</pre><br>... but it's still breaking if I use readonly() twice, so I'm not quite there yet.<br><br>Note also that I missed that my earlier code was accidentally reversing the arguments. Whups.<br><br>I'm not so allergic to having to define the instance variables myself in __init__, especially as I'd be using self.__varname inside my class for performance reasons. I'm also worried about readability; with the first syntax, it's immediately obvious to the reader that variables are being defined, even if they're not sure exactly how.", 'title': u'co_stacksize?'}, {'comment': u"I've removed the traceback code, and have replaced it with sys._getframe() code.", 'title': u' '}, {'comment': u'You can still initialize the corresponding private instance variables(CPIVs) yourself, and you can still use them as self.__foo inside your class. But, the thing I like about how readonly() and writeonly() work now, is that you don\'t have to initialize those variables. What does this accomplish? Well, if you look at the test code I include in the discussion, you\'ll see a reduction from 18 lines to 5 lines of code(from defining read/writeonly props. the old way to defining them our way). In fact, you save 3 lines of code for each read/writeonly prop. If you init your CPIVs, you still save 2 lines/prop. It\'s up to you whether you want to declare them yourself or not.<br>\n<br>\nRegarding readability, I agree that<br>\n<br>\nfoo, bar = readonly()<br>\n<br>\nmore obviously appears to be assigning readonly properties to the class. Still, <br>\n<br>\nreadonly(foo=1, bar=2)<br>\n<br>\nhas the benefit of creating self.__foo and self.__bar, "automagically", with default values. The previous syntax would continue to require that CPIVs be hand-coded. That is not what I want.<br>\nExplicit may be better than implicit, but in this case, I would say:<br>\nIs it more obvious from<br><br>\nfoo, bar = readonly()<br><br>\nthat you must make CPIVs by hand, or<br>\nis it more obvious from<br><br>\nreadonly(foo=1, bar=2)<br><br>\nthat CPIVs have been created for you?<br>\n<br>\nWhen I think about it, neither is overly obvious, but I think the former is less so than the latter.<br>\nYou could combine them, I suppose.<br><br>\nfoo, bar = readonly(foo=1, bar=2)<br><br>\nThis does appear to be more explicit, if not entirely more obvious. And it allows you to supply default or initial values for your readonly properties.<br><br>\nNote: foo, bar, fro, boz = readonly(1,2,3,4), is just wrong<br><br>\nfoo, bar, fro, boz = readonly(foo=1, bar=2, fro=3, boz=4), <br><br>I think, is better. While<br><br>\nreadonly(foo=1, bar=2, fro=3, boz=4)<br><br>\nalone, without assignment, is acceptable to me. Or, perhaps<br>\n<br>\n__readonly__(foo=1, bar=2, fro=3, boz=4)<br>\n<br>\nto let people know there\'s "automagic" happening...', 'title': u' '}, {'comment': u"I think we're vectoring in on a choice between ``foo, bar = readonly(foo=2)`` (`foo` defaulted, `bar` requiring manual attribute creation) and something like ``__readonly__('bar', foo=2)``. I like the double-underscorage making it obvious that we're doing something a little different.<br><br>Aaaah. Of course. If we make initialisation mandatory, then we know how many items to kick out, and we don't need to grope through frames trying to figure out the names of our lvars...", 'title': u'I wish ASPN had stuck with linear, non-heirachial discussion threads'}, {'comment': u"It seems to me the ideas in this recipe could be accomplished more easily using a metaclass. First, suppose that __readonly__ creates one or more temporary instances of some class and stores them in its caller's locals dict. Assuming this dict is the locals of the class-defining function, it is the same dict which is passed to the metaclass's __new__ function, along with the new class's name. So in the __new__ function, you simply hunt through the dict to look for instances of your temporary class, and then replace them with properly formed property instances. E.g.:\n\n<pre>\nclass readonlypropmarker(object):\n def __init__(self, value):\n self.value = value\n\ndef __readonly__(**kwds):\n locals = sys._getframe(1).f_locals\n for name, val in kwds.items():\n locals[name] = readonlypropmarker(val)\n\ndef newreadonlyprop(clsname, name, marker):\n name = mangle(clsname, name)\n defvalue = marker.value\n def get(obj):\n #simplified version without setting attribute\n return getattr(obj, name, defvalue)\n return property(fget=get)\n\nclass ExtPropMeta(type):\n def __new__(meta, clsname, bases, attrs):\n for name, attr in attrs.items():\n if isinstance(attr, readonlypropmarker):\n attrs[name] = newreadonlyprop(clsname, name, attr)\n return super(ExtPropMeta, meta).__new__(meta, clsname, \n bases, attrs)\n\nclass ExtProp(object):\n __metaclass__ = ExtPropMeta\n</pre>\n\nThen real classes can use ExtProp as a mixin base class to get this special property support.\n", 'title': u' '}, {'comment': u"I like this solution. It's clever, and reading it was an education. The only advantage I see to Garth's and my solution over yours is the fact that our solution does not require users to make their classes subclass ExtProp to get the desired behaviour. If they put rowo.py in their path, they can just import the behaviour, e.g.<br>\n<br>\n    from rowo import *<br>\n<br>\nBut, that's not much of a difference. It's just a matter of taste, I suppose. I happen to prefer:<br>\n<br>\n    from rowo import *<br>\n    class MyClass(object):<br>\n        __readonly__(foo=1)<br>\n<br>\nto<br>\n<br>\n    from ExtProp import *<br>\n    class MyClass(ExtProp):<br>\n        __readonly__(foo=1)<br>\n<br>\nProbably because the latter gives me the impression that my class is dependent upon another class. The former does not leave me with this impression. Other than that, I really did enjoy reading your code. Thank you very much for your contribution.<br>\nSean", 'title': u' '}], 'desc': u'The following are a set of functions for creating simple properties - \nlike Ruby\'s attr_reader, attr_writer, and attr_accessor. \n\nIf, inside a class definition, you write:\n\n        attribute(foo=1, bar=2)\n\nsimple properties named \'foo\' and \'bar\' are created for this class.\nAlso, private instance variables \'__foo\' and \'__bar\' will be added \nto instances of this class.\n\nBy "simple properties", I mean something like the following:\n\n        \'\'\' assume we\'re inside a class definition and \n        self.__foo and self.__bar have been instantiated.\n        \'\'\'\n        def get_foo(self): \n                return self.__foo\n        def set_foo(self, value): \n                self.__foo = value\n        def del_foo(self): \n                del self.__foo\n        def get_bar(self): \n                return self.__bar\n        def set_bar(self, value): \n                self.__bar = value\n        def del_bar(self): \n                del self.__bar\n        foo = property(fget=get_foo, fset=set_foo, fdel=del_foo, doc="foo")\n        bar = property(fget=get_bar, fset=set_bar, fdel=del_bar, doc="bar")\n'}, {'comments': [{'comment': u'Sorry, I should have said:\n The idea of using an external properties file came\nfrom Danny Ayers, http://www.isacat.net/2001/code/CSVtoXML.htm\nand I used those ideas, \n until I found the ConfigParser python module,\nwhich makes use of the win32 ini file format.\n\n', 'title': u'Source Attribution.'}], 'desc': u'uses a python csv package, but adds configuration file, so that\nthe document, row and field tags can be specified.\nusage: \npython csv2xml.py -p propertyFile -i inputFile -o outputFile"'}, {'comments': [], 'desc': u'You want to wrap a general object to make any acess to it thread safe. The ThreadedProxy class accomplishes that.\n\nneeds Python 2.2'}, {'comments': [{'comment': u'Hmmmm................why are you using eval()?', 'title': u'eval() use'}, {'comment': u'Doing this on Unix is different. A couple of things Unix does makes it harder: by default, shell scripts are executed by a subshell, using a special syntax to tell the current shell to process a file itself. And you have to tailor the solution to the shell you are using. On the other hand, Unix shells provide features that make this easier - most notably command substituition and the eval command.\n\nThe following solution works for modern sh-derived shells.\n\nThe Unix version of setvar.py is:\n<pre>\n#!/usr/bin/env python\n\nimport sys\n\nargs = sys.argv[1:]\nwhile args:\n print \'export %s="%s"\' % tuple(args[:2])\n del args[:2]\n<pre>\nYou can use this from a shell with eval and command substiution as:\n<br>\neval $(python setvar.py var1 value1 var2 value3 var3 value3)\n<br>\nand it will set all the variables to the following values.\n\nYou can\'t just shove this into a shell script though, as it would just set the values for the script. You could put it in a shell script and require the user to do ". script", but that\'s a bit ugly. Fortunately, the target shells have functions, which give us the same effect. So adding\nthe following to your .profile (or .zprofile, or .bashrc, or ...) will do the trick:\n<pre>\nsetvar() {\n eval $(python ~/src/python/setvar.py "$@")\n}\n<pre>\nif you adjust the path to setvar.py appropriately.</pre></pre></pre></pre>', 'title': u'The Unix version'}, {'comment': u'I usually do the following check/hack:\n\n<pre>\nkeys = os.environ.keys()\nfrom re import search\nfor key in keys:\n if not search("MY_PATH", key):\n os.environ["MY_PATH"]="/path/to/program"\n</pre>\n\n...which sets the variable for the running instance, but it\'s not passed on to eg. programs run by the commands module.', 'title': u'Adding an environment variable on unix'}], 'desc': u'Writes environment variables using a batch file wrapper. Overcomes an operating system limitation.'}, {'comments': [{'comment': u"imp.load_modules will also put the imported module in sys.modules, using as a key the name determined in import_ (see below). If some other module was already there, it will be replaced. So to some extent you are loosing control of your program's state.<br>\nCustomized module import is not easy to do in clean way.\n\n<pre>\nimport imp, os.path, sys\n\ndef import_(filename):\n path, name = os.path.split(filename)\n name, ext = os.path.splitext(name)\n\n print 'Before: %s in sys.modules ==' % name, name in sys.modules\n file, filename, data = imp.find_module(name, [path])\n mod = imp.load_module(name, file, filename, data)\n print 'After: %s in sys.modules ==' % name, name in sys.modules\n return mod\n \nif __name__ == '__main__':\n rePath = imp.find_module('re')[1]\n import_ (rePath)</pre>", 'title': u'Potential name conflicts in sys.modules'}, {'comment': u'The important thing is to manage the names of your modules in a way that avoids namespace conflicts and always (re)loads a module in the same place in sys.modules. This recipe might work better like this: \n\n<pre>\nimport imp, os.path, sys\n\ndef import_(filename, prefix):\n path, name = os.path.split(filename)\n name, ext = os.path.splitext(name)\n\n modname = "%s_%s" % (prefix, name)\n\n print \'Before: %s in sys.modules ==\' % modname, modname in sys.modules\n print \'Before: %s in sys.modules ==\' % name, name in sys.modules\n file, filename, data = imp.find_module(name, [path])\n mod = imp.load_module(name, file, filename, data)\n print \'After: %s in sys.modules ==\' % modname, modname in sys.modules\n print \'After: %s in sys.modules ==\' % name, name in sys.modules\n return mod\n \nif __name__ == \'__main__\':\n rePath = imp.find_module(\'re\')[1]\n import_ (rePath, "example")\n</pre>\n\nThis produces the following output:\n\n<pre>\nBefore: example_re in sys.modules == False\nBefore: re in sys.modules == False\nAfter: example_re in sys.modules == True\nAfter: re in sys.modules == False\n</pre>\n\nIt\'s still tricky -- nothing prevents someone from importing a different \'example_re,\' and overwriting your entry in sys.modules, for instance. If you\'re not prepared to deal with this sort of thing, though, you shouldn\'t muck about with runtime module loading.', 'title': u'Managing sys.modules with load_module'}], 'desc': u"This recipe lets you import any file as a module. It's not required that the file is in the Python search path. This is done without having to modify sys.path (even temporarily)"}, {'comments': [{'comment': u'You already have an elegant solution that shows-off list comprehensions to good advantage.<br>\nThe similarity to SQL and speed of execution can both improve with a row match helper function that uses implicit indexing:\n<pre>\ndef rowmatches(table, col, value, cache={}):\n "Select * from table where col=value"\n cachekey = (id(table), col)\n try:\n return cache[cachekey].get(value, []) \n except KeyError:\n index = {}\n for row in table:\n index.setdefault(row[col], []).append(row)\n cache[cachekey] = index \n return index.get(value, [])\n\n</pre>\nHere are the old and new versions of restriction:\n<pre>\n# SQL: select * from agents where agent_famname=\'White\'\nres=[row for row in t1 if row[1]==\'White\']\nres=[row for row in rowmatches(t1,1,\'White\')]\n\n</pre>\nHere are the old and new versions of an inner join:\n<pre>\n# SQL: select agents.*, clients.* from agents,clients\n# where agents.agent_id=clients.agent_id\nres= [r1+r2 for r1 in t1 for r2 in t2 if r1[0]==r2[1]]\nres= [r1+r2 for r1 in t1 for r2 in rowmatches(t2,1,r1[0])]\n\n</pre>\nHere are the old and new versions of a left join:\n<pre>\n# SQL: select agents.*, clients.* from agents left outer join clients\n# where agents.agent_id = clients.agent_id\n\nres= [r1+r2 for r1 in t1 for r2 in t2 if r1[0]==r2[1]]+\\\n [r1+[None]*len(t2[0]) for r1 in t1 if r1[0] not in [r2[1] for r2 in t2]]\nres= [r1+r2 for r1 in t1 for r2 in rowmatches(t2,1,r1[0])]+\\\n [r1+[None]*len(t2[0]) for r1 in t1 if not rowmatches(t2,1,r1[0])]\n\n</pre>\nHere are old and new versions of a right outer join:\n<pre>\n# SQL: select agents.*, clients.* from agents right outer join clients\n# where agents.agent_id = clients.agent_id\nres= [r1+r2 for r1 in t1 for r2 in t2 if r1[0]==r2[1]]+\\\n [[None]*len(t1[0])+r2 for r2 in t2 if r2[1] not in [r1[0] for r1 in t1]]\nres= [r1+r2 for r1 in t1 for r2 in rowmatches(t2,1,r1[0])]+\\\n [[None]*len(t1[0])+r2 for r2 in t2 if not rowmatches(t1,0,r2[1])]\n\n</pre>\nHere are the old and new versions of a full outer join\n<pre>\n# SQL: select agents.*, clients.* from agents full outer join clients\n# where agents.agent_id = clients.agent_id\nres= [r1+r2 for r1 in t1 for r2 in t2 if r1[0]==r2[1]]+\\\n [r1+[None]*len(t2[0]) for r1 in t1 if r1[0] not in [r2[1] for r2 in t2]]+\\\n [[None]*len(t1[0])+r2 for r2 in t2 if r2[1] not in [r1[0] for r1 in t1]]\nres= [r1+r2 for r1 in t1 for r2 in rowmatches(t2,1,r1[0])]+\\\n [r1+[None]*len(t2[0]) for r1 in t1 if not rowmatches(t2,1,r1[0])]+\\\n [[None]*len(t1[0])+r2 for r2 in t2 if not rowmatches(t1,0,r2[1])]\n\n</pre>', 'title': u'Indexed Tables'}], 'desc': u'Sometimes it is needed to do set-like operations on database query results, or simple lists, without the burden of implementing a class for sets, or importing a separate module. List comprehensions are quick way to do this, here is a collection of them. Although most of them are banal, let us just collect them in one place. Also, they are not the fastest, nor the most elegant, but the quickest to drop into your code if you need a proof of concept.'}, {'comments': [{'comment': u'<pre>\ndef cross(*args):\n ans = [[]]\n for arg in args:\n ans = [x+[y] for x in ans for y in arg]\n return ans\n\nprint cross(s1,s2,s3)\n</pre>', 'title': u'Build the product set by set'}, {'comment': u'<pre>\ndef cross(*sets):\n wheels = map(iter, sets) # wheels like in an odometer\n digits = [it.next() for it in wheels]\n while True:\n yield digits[:]\n for i in range(len(digits)-1, -1, -1):\n try:\n digits[i] = wheels[i].next()\n break\n except StopIteration:\n wheels[i] = iter(sets[i])\n digits[i] = wheels[i].next()\n else:\n break\n</pre>', 'title': u'Iterator version'}], 'desc': u'If you need to generate the cross product of a variable number of lists, here is how to do it with an obscure one-liner instead of a nice and clean recursive function. I came to this while trying to find a short and simple solution for generating the cross product of a variable number of lists. Well, it might be short, but it is obscure as well. Maybe somebody can provide me with a more elegant solution. The function works on list of lists as well.\n '}, {'comments': [{'comment': u'Well, I thought the "Add" button meant add a discussion item, not "Add recipe to cookbook".\n<br><br>\nAnyway...\n<br><br>\nThe problem this code is meant to help with is hopefully familiar.\n<br><br>\nYou\'re editing a Python module in emacs (or vim or notepad or whatever). Let\'s say at some point it looks like this:\n<pre>\n-------- # mod.py --------\nclass Foo(object):\n def meth1(self, arg):\n print arg\n--------------------------\n</pre>\nIn another window, you have an interactive interpreter running to test your code:\n<pre>\n>>> import mod\n>>> f = mod.Foo()\n>>> f.meth1(1)\n1\n</pre>\nThat seems to be working. Good. Now you edit mod.py to add another method:\n<pre>\n-------- # mod.py --------\nclass Foo(object):\n def meth1(self, arg):\n print arg\n def meth2(self, arg):\n print -arg\n--------------------------\n</pre>\nHead back to the test session:\n<pre>\n>>> reload(mod)\n<module \'mod\' from \'mod.pyc\'>\n>>> f.meth2(1)\nTraceback (most recent call last):\n File "", line 1, in ?\nAttributeError: \'Foo\' object has no attribute \'meth2\'\n</pre>\nArgh! You forgot that \'f\' was an instance of the *old* mod.Foo!\n<br><br>\nThere are two things you can do about this: 1) regenerate the instance:\n<pre>\n>>> f = meth.Foo()\n>>> f.meth2(1)\n-1\n</pre>\nor 2) assign to f.__class__:\n<pre>\n>>> f.__class__ = mod.Foo\n>>> f.meth2(1)\n-1\n</pre>\n1) works easily enough in simple situations, but can become very tedious. 2) can be automated, which is what my code does.\n<br><br>\nThe first class is a metaclass that tracks instances of its instances (I hope you have your brain-splatter protection set up).\n<br><br>\nAs metaclasses go, this isn\'t too complicated. New classes of this metatype get an extra __instance_refs__ class variable (used to store weak references to instances) and an __instances__ method (which strips dead references out of the __instance_refs__ list and returns real references to the still live instances). When a class of metatype MetaInstanceTracker is instantiated, a weak reference to the instances is stored in the __instance_refs__ list.\n<br><br>\nWhen the definition of a class of metatype MetaAutoReloader is executed, the namespace of the definition is examined to see if a class of the same name already exists. If it does, then it is assumed that instead of a class defintion, this is a class REdefinition, and all instances of the OLD class (MetaAutoReloader inherits from MetaInstanceTracker, so they can easily be found) are updated to the NEW class.\n<br><br>\nProblems with this code:\n<br><br>\n1) there should be more error checking (e.g. that old_class is an InstanceTracker, change_class can fail). This was omitted through a mixture of a desire for clarity and laziness.\n<br><br>\n2) bad interaction with inheritance. Ideally, on redefinition a class should tweak subclasses of the old class to inherit from the new class. But in Python 2.2.X at least, assignment to __bases__ is not allowed, so this is impossible. This might change in Python 2.3.\n<br><br>\nIf this comment could magically become the discussion part of this recipe, I\'d appreciate it...', 'title': u'This was supposed to go in the discussion...'}, {'comment': u'I found the edit recipe bit.', 'title': u'Never mind...'}, {'comment': u'I wrote a patch to allow assignment to __bases__ of new style classes in Python 2.3 and it was accepted and checked in, so it will be possible to update this recipe to play nicely with inheritance in 2.3.', 'title': u'__bases__ *will* be assignable in 2.3'}, {'comment': u'This completely takes care of the reload() wart.', 'title': u'Nice recipe'}, {'comment': u'Can you show how to solve the subclass problem in 2.3? How would one find all subclasses, if the inheritance linkage is upward only?\n<br>\n<br>\nPerhaps the solution would involve tracking all instances of MetaAutoReloader. That implies that MetaAutoReloader should have a __metaclass__ of MetaInstanceTracker. :-)', 'title': u'Update for 2.3'}, {'comment': u"I've updated the recipe (finally) to take advantage of the new-in-2.3 features.", 'title': u'nah, use __subclasses__()'}, {'comment': u"I got rid of some inheritance cycle problems by inserting an IF statement inside MetaAutoReloader: \n<pre>\n :\n for subcls in old_class.__subclasses__():\n if subcls.__name__ != name \\\n or subcls.__module__ != ns['__module__']:\n newbases = ()\n :\n</pre>\nThis fix makes it possible to patch old instances like this:\n<pre>\n:\n>>> class Bar(Bar):\n... def mix(self, arg):\n... self.meth(arg)\n... \n>>> b2.mix(4)\n4</pre>", 'title': u'patch'}, {'comment': u"Interesting, but it's an extension of what I originally intended.", 'title': u'hmm'}, {'comment': u'Very cool. But objects are only one way you can capture code in Python- albeit the most common one. But you get the same kind of problemsanywhere a pointer to a function or method gets saved: callbacks inGUIs, closures, etc.<br><br>Anyone got solutions for those?', 'title': u'How about other methods of code capture?'}, {'comment': u"with\n\nhttp://aspn.activestate.com/ASPN/Mail/Message/python-list/907876\n\nThomas Hellers autoreload. That really will push up long running processes, won't it?\n\nHarald", 'title': u'that really crys for integration'}], 'desc': u"Anyone who's used reload() on a module that defines a class in the interactive interpreter must have experienced the frustration of then running around and making sure that all instances are updated to be instances of the new rather than the old class.\n\nThis metaclass tries to help with this."}, {'comments': [], 'desc': u"This is a way to tell if your timezone is currently in daylight savings time. (Hint: time.daylight doesn't do this)"}, {'comments': [{'comment': u"Of course, that should be 'stiletto'. But you get the point :-D", 'title': u"Engineers don't know their footwear"}], 'desc': u'You want to implement stateful objects, which have a different\nset of behaviours according to what state they are in.\n\nThis requirement can be achieved with the use of mix-ins. A mix-in\nis a class which is dynamically inherited by an object. The methods\nof the mix-in class are thus accessible through the object. This is a\nclean way of providing objects with standard interfaces.\n\nChuck Esterbrook has written a discussion of mix-ins, and their\nimplementation in Python, which can be found here:\nhttp://www.linuxjournal.com/article.php?sid=4540\n\nThe recipe draws from the famous "Lumberjack Song". If you\'re not\nfamiliar with it, all you need to know is that the passage of time\nmodifies the Lumberjack\'s behaviour.'}, {'comments': [{'comment': u'The above source file is available for download here:<br>\nhttp://ramenfest.com/ftypes.py', 'title': u'Download the source.'}, {'comment': u"This is ok:<br><br>\n\n>>> x = odict()<br>\n>>> x['a']=1; x['b']=2<br><br>\n>>> x.items()<br>\n[('a', 1), ('b', 2)]<br><br>\n>>> x.keys()<br>\n['a', 'b']<br><br>\n>>> x.values()<br>\n[1, 2]<br><br>\n\nBut this is not:<br><br>\n\n>>> y = odict(x)<br><br>\n>>> y.items()<br>\n[]<br><br>\n>>> y.keys()<br>\n[]<br><br>\n>>> y.values()<br>\n[]<br>\n", 'title': u'problems in the class odict()'}], 'desc': u'Dictionary, list, set, and histogram types for relational algebra, functional programming, list-oriented programming, and modelling data flow.'}, {'comments': [{'comment': u'This looks like a neat use of generators, but\nit needs an example of its use. Maybe give an example\nof converting all filenames to lowercase or something.\n', 'title': u'Neat, but give an example!'}, {'comment': u"I just noticed that Depthfirst is broken.\nIt still walks the tree breadth first.\nA fix is not easy as it would involve\nrecursion or an additional stack. I'm not sure\nhow recurssion works with generators.\n<br><br>\nFor example, take the following directory tree:\n<pre>\n AAA\n / \\\n BBB CCC\n / \\\n DDD EEE\n</pre>\nThis structure can be created using these commands:\n<pre>\n mkdir AAA\n mkdir AAA/BBB\n mkdir AAA/CCC\n mkdir AAA/CCC/DDD\n mkdir AAA/CCC/EEE\n</pre>\nThen run this python code to walk the tree:\n<pre>\n root = 'AAA'\n w = walktree (root, True)\n for (basepath, children) in w:\n print basepath, ':', children\n</pre> \nThe expected output for depth first tree traversal is this:\n<pre>\n AAA/BBB : []\n AAA/CCC/DDD : []\n AAA/CCC/EEE : []\n AAA/CCC : ['DDD', 'EEE']\n AAA : ['BBB', 'CCC']\n</pre>\nBut it does not produce this. The actual output is below. \nThis is actually still BREADTH first, but \nfollowing the RIGHTMOST path first.\n<pre>\n AAA : ['BBB', 'CCC']\n AAA/CCC : ['DDD', 'EEE']\n AAA/CCC/EEE : []\n AAA/CCC/DDD : []\n AAA/BBB : []\n</pre>\nWith depthfirst set to False you still get BREADTH first, but \nfollowing the LEFTMOST path first:\n<pre>\n AAA : ['BBB', 'CCC']\n AAA/BBB : []\n AAA/CCC : ['DDD', 'EEE']\n AAA/CCC/DDD : []\n AAA/CCC/EEE : []\n</pre>\n\nYours,\nNoah\n", 'title': u'Depth First is broken'}, {'comment': u'The depth first problem is important. Consider how\nwould you easily write a directory walker to rename all \nfiles AND directories to lower case?\nThe obvious code does not do what one would expect:\n<pre>\n from walktree import *\n for (basepath, children) in walktree():\n for child in children:\n \told_name = os.path.join(basepath, child)\n \tnew_name = os.path.join(basepath, child.lower())\n print old_name, "-->", new_name\n \tos.rename (old_name, new_name)\n</pre> \nThat will try to rename the directories in the wrong order.\nIt will try to rename a directory before it has visited the children\nof that directory. Given the following directory tree:\n<pre>\n AAA\n / \\\n BBB CCC\n / \\\n DDD EEE\n</pre>\nThat code will try to do this:\n<pre>\n os.rename (\'./AAA/CCC\', \'./AAA/ccc\')\n</pre>\nthen later:\n<pre>\n os.rename (\'./AAA/CCC/DDD\', \'./AAA/CCC/ddd\') # ERROR!\n</pre>\nBut AAA/CCC does not exist anymore. It was previously renamed to AAA/ccc!\n<br>\nThe easiest way to fix walktree() is to use recursion.\nIt\'s interesting to note that generators may be nested recursively.\nThe following code fixes walktree to make it work properly\nfor depth first tree walking.\n<br><br>\nYours,<br>\nNoah Spurrier\n<br><br>\n<pre>\nfrom __future__ import generators # needed for Python 2.2\nimport os\nimport stat\n\ndef walktree (top = ".", depthfirst = True):\n """This walks a directory tree, starting from \'top\'.\n This is somewhat like os.path.walk, but using\n generators instead of a visit function.\n One important difference is that walktree() defaults \n to DEPTH first with optional BREADTH first,\n whereas the os.path.walk function allows only BREADTH first.\n Depth first was made the default because it is safer if\n you are going to be modifying directory names. This avoids\n the problem of renaming a directory before visiting the children\n of that directory.\n\n """\n names = os.listdir(top)\n if not depthfirst:\n yield top, names\n for name in names:\n try:\n st = os.lstat(os.path.join(top, name))\n except os.error:\n continue\n if stat.S_ISDIR(st.st_mode):\n for (newtop, children) in walktree (os.path.join(top, name), depthfirst):\n yield newtop, children\n if depthfirst:\n yield top, names\n\ndef test():\n for (basepath, children) in walktree():\n for child in children:\n\t print os.path.join(basepath, child)\n\nif __name__ == \'__main__\':\n test()\n\n</pre>\n', 'title': u'Fix for depth first problem.'}, {'comment': u"Also, see 'os.walk', added in Python 2.3", 'title': u'os.walk'}], 'desc': u'A generator that does what os.path.walk does, without the need for a callback function.'}, {'comments': [{'comment': u'Ooops. I just noticed that I left some dead code: the send_content() function of that transport subclass should be omitted. Sorry about that!', 'title': u"there's some dead code in there"}], 'desc': u'This extension to xmlrpclib allows us to maintain a session with a JSP server, so that there appears to be a stateful session. It tries to maintain the JSESSIONID call between calls to the server.'}, {'comments': [], 'desc': u'Determine if a particular URL is of a particular type (i.e., "text" for HTML, "image" for gif). It supports either the URL in string form, or an open file (obtained from urllib.urlopen).'}, {'comments': [], 'desc': u"Xyaptu builts on Alex Martelli's generic and elegant module, YAPTU (Yet Another Python Template Utility), to instantiate XML/HTML document templates that include python code for presentational purposes. The goal is _not_ to be able to embed program logic in a document template. This is counter productive if a separation of content and logic is desired. The goal _is_ to be able to prepare arbitrarily complex presentation templates, while offering a simple and open-ended means to hook in application data. A page template may therefore contain anything that targeted clients will accept, with the addition of five XML tags and one 'pcdata' expression token, as mark-up for the python code that defines the coupling between the presentation to the application data. "}, {'comments': [{'comment': u'Using this:\n<pre>\n[p for p in range(2,N) if 0 not in [p%d for d in range(2,p/2+1)]]\n</pre>\nwe only taste the divisors up to p/2. We can do this because d>p/2 will surely not yield an integer result.\nSpeed increase for N=1000 on my Athlon 1333: 38s instead of 77s or roughly factor 2.', 'title': u'A faster version'}, {'comment': u'the above example is for illustration, not a critique of the original version', 'title': u'... an addition'}, {'comment': u'It is only necessary to check odd numbers after 2, so a 2X speedup can be achieved by having the first range statement step by two like this:\n\n[p for p in range(3,N,2) if 0 not in [p%d for d in range(2,p)]]\n\nA minor penalty is that the number 2 is not generated as the first prime.\n', 'title': u'Another speedup (David Lees)'}, {'comment': u"Instead of checking all odd divisors, how about checking only prime divisors that are half or less than the candidate:\n<pre>\naux = {}\nprint [aux.setdefault(p,p) for p in range(2,N) if 0 not in [p%d for d in aux if p>=d+d]]\n</pre>\nIf you're careful, psuedo-prime testing can speed-up the process even more:\n<pre>\nprint [p for p in range(2,N) if 0 not in [pow(w,p-1,p)==1 for w in [2, 3, 5, 7, 11] if p>w]]\n</pre>\n", 'title': u'More entries in the speed-up game'}], 'desc': u'The following expression generates the list of prime numbers strictly inferior to a given positive integer N.'}, {'comments': [{'comment': u'i like this idea a lot! i\'ve made a few cosmetic changes:\n\n<br><br>\nmoved the \'import time\' statement to the top of the module. i didn\'t see any need to execute the import on every call to \'delay\'.\n\n<br><br>\nreplaced every \'True\' with 1 and \'False\' with 0. the change should make the code backward compatible with older Python versions.\n\n\n<br><br>\nreplaced the \'self.thread=[]\' statement in GenericScheduler.__init__ with an assigment to the \'thread\' parameter. i favor allowing clients to specify as many attributes as possible.\n\n<br><br>\nmoved the try/except block inside the while loop in GenericScheduler.scheduler. \n\n\n<br><br>\n\n<pre>\nfrom __future__ import generators\n\nimport signal\nimport time\n\n# An implementation of cooperative multithreading using generators\n# that handles signals; by Brian O. Bush\n\n# credit: based off an article by David Mertz\n# http://gnosis.cx/publish/programming/charming_python_b7.txt\n\ndef empty():\n """ This is an empty task. """\n while 1:\n print ""\n yield None\n \ndef delay(duration):\n while 1:\n print "" % duration\n time.sleep(duration)\n yield None\n\nclass GenericScheduler:\n def __init__(self, threads):\n self.shutdownRequest = 0\n self.threads = threads\n signal.signal(signal.SIGINT, self.shutdownHandler)\n\n def shutdownHandler(self, n, frame):\n """ Initiate a request to shutdown cleanly on SIGINT."""\n print "Request to shut down."\n self.shutdownRequest = 1\n\n def scheduler(self):\n while 1:\n try:\n map(lambda t: t.next(), self.threads)\n if self.shutdownRequest:\n break\n except StopIteration:\n break\n\n\nif __name__== "__main__":\n ts = [delay(1), delay(2), empty()]\n s = GenericScheduler(ts)\n s.scheduler()\n\n</pre>\n\nas i said, the changes are mostly cosmetic. thanks for this recipie, i\'m sure i\'ll use it!', 'title': u'Cool Idea! Minor Changes...'}, {'comment': u'Since the code already uses the generators feature, it\'s pretty damn safe to assume that True and False exist. Moreover, anyone who has read the "Python Regrets" presentation from Guido (our fearless leader), will know to use the "list-builder" notation in preference to "map". (The generated code is actually faster, too!) Here are my picky changes:\n\n<pre>\nfrom __future__ import generators\n\nimport signal\nimport time\n\n# An implementation of cooperative multithreading using generators\n# that handles signals; by Brian O. Bush\n\n# credit: based off an article by David Mertz\n# http://gnosis.cx/publish/programming/charming_python_b7.txt\n\ndef empty():\n """ This is an empty task. """\n while True:\n print ""\n yield None\n \ndef delay(duration):\n while True:\n print "" % duration\n time.sleep(duration)\n yield None\n\nclass GenericScheduler:\n def __init__(self, threads):\n self.shutdownRequest = False\n self.threads = threads\n signal.signal(signal.SIGINT, self.shutdownHandler)\n\n def shutdownHandler(self, n, frame):\n """ Initiate a request to shutdown cleanly on SIGINT."""\n print "Request to shut down."\n self.shutdownRequest = True\n\n def scheduler(self):\n while True:\n try:\n [ thread.next() for thread in self.threads ]\n if self.shutdownRequest:\n break\n except StopIteration:\n break\n\n\nif __name__== "__main__":\n ts = [delay(1), delay(2), empty()]\n s = GenericScheduler(ts)\n s.scheduler()\n</pre>', 'title': u'More "improvements"'}, {'comment': u'Regardless of Regrets Guido may have, there doesn\'t appear to be a need to build a list of results from calling each thread / generator\'s next() method. So instead of using map() or "list-builder" notation, all that\'s needed is simply:<pre>\n for thread in self.threads: thread.next()\n</pre>\nin the scheduler() method.<br><br>\nIn IMHO the above is the most explicit statement of what needs and is being done (and is probably even faster, since it doesn\'t bother building a throw-away list nor incur any unnecessary function / method-call overhead).\n<br><br>\nBTW, some of the contents of the print statements in the original recipe\'s print statements do not show up in either commentator\'s code -- specifically those that contained text that looked like html tags.<br><br>\nFor example, the<pre>\n print "<sleep %d>" % duration\n</pre>\nstatement became<pre>\n print "" % duration\n</pre>\nwhich will cause a<pre>\n TypeError: not all arguments converted\n</pre>\ninterpreter error to occur when it\'s run.<br><br>\nFWIW, to put literal "<" and/or ">" characters in comments here, they need to be replaced with their HTML character entity reference names, which are "&lt;" and "&gt;" repectively (sans the quotes). HTH.', 'title': u'Re: More "improvements"'}], 'desc': u'Here is an implementation of cooperative multithreading using generators that handles signals (SIGINT only in this recipe). '}, {'comments': [{'comment': u' ', 'title': u'Nice.'}, {'comment': u'Can you update this so it works if you have DSL or Cable modem, or if you are behind a router ?\nGethostbyname() will only return the INTERNAL address of your machine, which is not addressable from the outside world, UNLESS you know your cable/DSL modem address.', 'title': u' '}, {'comment': u"This will give you the ip or the gateway, which is what you need. Just replace ip=socket.gethostbyname(blah) with this code.<br><br>\n\nimport os,string<br>\n\naddress={}<br>\ncmd = 'c:/windows/system32/ipconfig.exe /all' # whatever your path<br>\njunk, txtOut = os.popen2(cmd)<br>\nfor x in txtOut.readlines():<br>\n  if x.find('IP Address') != -1:<br>\n   address.setdefault('ip',x.split(':')[-1].strip())<br>\n  if x.find('Default Gateway') != -1:<br>\n   address.setdefault('gate',x.split(':')[-1].strip())<br>\nprint address['gate']<br>\nip=address['gate'] #replace the old ip way with this.<br>\nprint address['ip']<br>", 'title': u'Give this a try ;)'}, {'comment': u"I added this function to read the ip address from http://checkip.dyndns.org\n\ndef readip():\n\timport re, urllib\n\tf = urllib.urlopen('http://checkip.dyndns.org')\n\ts = f.read()\n\tm = re.search('([\\d]*\\.[\\d]*\\.[\\d]*\\.[\\d]*)', s)\n\treturn m.group(0)\n\nand changed the calls to socket.gethostbyname(name) by calls to the new function. The start() function ended up like this:\n\ndef start():\n def getIP(name, path):\n ip = readip()\n print 'Current ip: '+str(ip)\n open(path,'w').write(ip) #Save the current IP address.\n out(name,Path_dat)\n\n def out(name, path, stat=1):\n while stat:\n cur_ip = open(path,'r').readline()\n new_ip = readip()\n if cur_ip==new_ip:\n print 'Sleeping...'\n time.sleep(15) # Sleep in seconds - adjust polling interval to your taste.\n print 'Polling: '+new_ip+', '+time.ctime()\n else:\n print 'IP address has changed: '+new_ip\n open(Path_log,'a').write(time.ctime()+'\\nINFO: IP address has changed: '+new_ip)\n print 'sending notification...'\n for add in Address:\n mail(to=add,frm=Frm_add,subj='Message from '+name,body='New IP address: '+new_ip+' assigned to '+name, server=MailServer)\n getIP(name,Path_dat) \n stat=0\n\n getIP(Name,Path_dat)\n\n\nThanks for posting this useful program!\nLater I will work on updating the entry in www.dyndns.org, to have the complete package: detection of the IP change and update of the dns record in www.dyndns.org.\n", 'title': u'Detect current ip using http://checkip.dyndns.org'}, {'comment': u"<br>\nMy previous post did not display well, this is the fixed and shortened version.<br>\nI added this function to read the ip address from<br> http://checkip.dyndns.org<br>\nThere are other places that provide the same service (free); the function should work with many of them with minor o none modifications: it will parse the first occurrance of an ip-address like string and return it.\n<br>\n\n<br>\ndef readip():<br> \nimport re, urllib<br> \nf = urllib.urlopen('http://checkip.dyndns.org')<br> \ns = f.read()<br>\nm = re.search('([\\d]*\\.[\\d]*\\.[\\d]*\\.[\\d]*)', s)<br>\nreturn m.group(0)<br><br>\n\nI changed the calls to socket.gethostbyname(name) by calls to the new function readip()<br><br>\nThanks for posting this useful program! Later I will work on updating the entry in www.dyndns.org, to have the complete package: detection of the IP change and update of the dns record in www.dyndns.org.<br><br>\n", 'title': u'Detect current ip using http://checkip.dyndns.org - fixed format'}, {'comment': u'I have some 10 machines in my network, and two machines ip adresses are overlapping with each other, so i want to know which are the two machines among those 10 machines that have the same ip adresses.\nYogi\n', 'title': u'How can i check the change of ip adrress of a remote machine'}, {'comment': u"This piece of code is simpler and cleaner:\n<pre>\nIn [18]: import urllib2\nIn [20]: urllib2.urlopen('http://whatismyip.org').read()\nOut[20]: 'xxx.yyy.zzz.www'\n</pre>\n-- <br>\nAyaz Ahmed Khan", 'title': u'Re: Detect current ip using http://checkip.dyndns.org'}], 'desc': u'Use: To notify whomever that your IP address has\nchanged if you have a non-static IP address and run \na web server, game server, etc. Utilizes nested\nfunctions.'}, {'comments': [], 'desc': u' '}, {'comments': [{'comment': u'Here\'s a possibly improved version with basic GUID format checking, __eq__ implementation and a more pythonic ip implementation. Hope you like it. <br>\n\nthanks for sharing. <br>\n\n<pre>\n#!/usr/bin/python\n\n# A globally unique identifier made up of time and ip\n# Copyright (C) 2002 Dr. Conan C. Albrecht \n#\n# This library is free software; you can redistribute it and/or\n# modify it under the terms of the GNU Lesser General Public\n# License as published by the Free Software Foundation; either\n# version 2.1 of the License, or (at your option) any later version.\n#\n# This library is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n# Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public\n# License along with this library; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\nimport random\nimport socket\nimport time\n\nclass GUID:\n \'\'\'A globally-unique identifier made up of time and ip and 3 random digits: 35 characters wide\n \n A globally unique identifier that combines ip, time, and random bits. Since the \n time is listed first, you can sort records by guid. You can also extract the time \n and ip if needed. \n \n GUIDs make wonderful database keys. They require no access to the \n database (to get the max index number), they are extremely unique, and they sort \n automatically by time. GUIDs prevent key clashes when merging\n two databases together, combining data, or generating keys in distributed\n systems.\n \'\'\'\n rand = random.Random()\n ip = \'\'\n try:\n ip = socket.gethostbyname(socket.gethostname())\n except (socket.gaierror): # if we don\'t have an ip, default to someting in the 10.x.x.x private range\n ip = \'10\'\n for i in range(3):\n ip += \'.\' + str(rand.randrange(1, 254))\n hexip = \'\'.join(["%04x" % long(i) for i in ip.split(\'.\')]) # leave space for ip v6 (65K in each sub)\n lastguid = \'\'\n \n def __init__(self, guid=None):\n \'\'\'Constructor. Use no args if you want the guid generated (this is the normal method)\n or send a string-typed guid to generate it from the string\'\'\'\n if guid is None:\n self.guid = self.__class__.lastguid\n while self.guid == self.__class__.lastguid:\n # time part\n now = long(time.time() * 1000)\n self.guid = ("%016x" % now) + self.__class__.hexip\n # random part\n self.guid += ("%03x" % (self.__class__.rand.randrange(0, 4095)))\n self.__class__.lastguid = self.guid\n \n elif type(guid) == type(self): # if a GUID object, copy its value\n self.guid = str(guid)\n \n else: # if a string, just save its value\n assert self._check(guid), guid + " is not a valid GUID!"\n self.guid = guid\n\n def __eq__(self, other):\n \'\'\'Return true if both GUID strings are equal\'\'\'\n if isinstance(other, self.__class__):\n return str(self) == str(other)\n return 0\n \n def __str__(self):\n \'\'\'Returns the string value of this guid\'\'\'\n return self.guid\n \n def time(self):\n \'\'\'Extracts the time portion out of the guid and returns the \n number of milliseconds since the epoch\'\'\'\n return long(self.guid[0:16], 16)\n \n def ip(self):\n \'\'\'Extracts the ip portion out of the guid and returns it\n as a string like 10.10.10.10\'\'\'\n # there\'s probably a more elegant way to do this\n ip = []\n index = 16\n while index Here\'s a possibly improved version with basic GUID format checking, __eq__ implementation and a more pythonic ip implementation. Hope you like it. <br>\n\nthanks for sharing. <br>\n\n<pre>\n#!/usr/bin/python\n\n# A globally unique identifier made up of time and ip\n# Copyright (C) 2002 Dr. Conan C. Albrecht \n#\n# This library is free software; you can redistribute it and/or\n# modify it under the terms', 'title': u'Very good but I would add format checking and __eq__...'}, {'comment': u'Rodrigo -- Your code was cut off in the posting. Please send me the code to conan_albrecht@byu.edu and I\'ll integrate your changes back into the original and repost a new version. Thanks.\n<br>\nIn fact, if others have more "pythonic" ways of doing things, let me know. I\'m much more mature in other languages and relatively new to python.', 'title': u'Changes'}, {'comment': u'I updated the code based upon reviews from many users. The main difference is the new GUID code simply generates a regular String object, rather than a GUID object. Why did I create a separate object? It seemed everyone was using GUIDs as strings anyway, so I removed the class and made functions instead.\n<br>\nThe class now respects multiple threads, and it has been simplified somewhat.', 'title': u'Updated the code'}, {'comment': u'Under Python 2.2 the phrase <pre>import random; random.Random().randrange(0, 4294967296L)</pre> \nfails with \n\n<pre>\nTraceback (most recent call last):\n File "", line 1, in ?\n File "/usr/local/lib/python2.2/random.py", line 294, in randrange\n istop = int(stop)\nOverflowError: long int too large to convert to int\n</pre>\n\nwhile <pre>import random; random.Random().randrange(0, 4294967296L/2-1)</pre> succeeds.<pre></pre>\n\nPython 2.3 runs both successfully. <pre></pre>\n\nMaybe line 127 \n<pre>\n guid += ("%08x" % rand.randrange(0, 4294967296L)))</pre>\nshould better read \n<pre> guid += ("%08x" % rand.randrange(0, 2147483647L))<pre>\nto enable Python cross-version compatibility.</pre></pre>', 'title': u'int overflow under Python 2.2'}, {'comment': u'Instead of random bits, I use a descending sequence. This uses a simple generator to start that segment at sys.maxint, decrementing by one on each call. 2.2 or later.\n\n<pre>\nimport math, sys\ndef _unique_sequencer():\n _XUnit_sequence = sys.maxint\n while 1:\n yield _XUnit_sequence\n _XUnit_sequence -= 1\n if _XUnit_sequence <= 0:\n _XUnit_sequence = sys.maxint\n_uniqueid = _unique_sequencer()\n\ndef uniqueid(prefix=\'\'):\n frac, secs = math.modf(time.time())\n days, remain = divmod(secs, 86400)\n id = _uniqueid.next()\n return u"%s%s%s_%s" % (prefix, hex(int(days))[2:],\n hex(int(remain))[2:], hex(id)[2:])</pre>\n', 'title': u'Alternate version using descending sequence instead of random'}, {'comment': u'For another GUID-generator, but licensed under a very liberal MIT software license, look in the Pyro.util package of Pyro.\n(http://pyro.sourceforge.net).', 'title': u'Another implementation with MIT-license is part of Pyro'}, {'comment': u'16 bytes from a cryptographic-quality random number source like os.urandom() are just as good as a method of generating GUIDs.', 'title': u'Random GUIDs'}, {'comment': u"Rodrigo -- nice class version. I just modified my original code recipe so yours needs to be updated if you like my new changes. The reason I don't use a class as you suggest is because potentially thousands of GUIDs are loaded from the DB at a time. Your class constructor has to parse the GUID every time it is created, which adds processing time. In addition, you then convert it back to a string to compare, which adds more time. Keeping it as a string doesn't require any additional processing time at create. Yours could actually be modified to compare the raw numbers instead of the string representation (which would be more efficient), but I still think it's easier to keep it as a string from the start. In the end it's just preference.", 'title': u"Why I don't use the class version"}, {'comment': u'The recipe above now uses a variation of your method here. I use an increasing counter so its easier to sort them (why use a decreasing counter?), but otherwise I think this idea is now in the main recipe.', 'title': u'Recipe now uses counter'}, {'comment': u'Is it possible to convert the string to a number value and store in a NUMERIC type field in PostgreSql?', 'title': u'Best way to store in PostgreSql'}, {'comment': u'<pre>\n>>> import pythoncom\n>>> print pythoncom.CreateGuid()\n{600AFA7C-E537-424B-8EE2-A54A18102EFA}</pre>', 'title': u'If you have pywin32'}, {'comment': u'the ip arument in the generate() method is never used. could you please fix it?', 'title': u' '}, {'comment': u'I get "GUID.py:92: FutureWarning: hex/oct constants > sys.maxint will return positive values in Python 2.4 and up" from Python 2.3.5 (which is pre-installed on Mac OS X 10.4), and the counter seems to always be 0!\n\nI changed "MAX_COUNTER = 0xfffffffe" to "MAX_COUNTER = sys.maxint" which fixes the problem.\n', 'title': u'"GUID.py:92: FutureWarning: hex/oct constants > sys.maxint..."'}], 'desc': u'A globally unique identifier that combines ip, time, and random bits. Since the time is listed first, you can sort records by guid. You can also extract the time and ip if needed. GUIDs make wonderful database keys. They require no access to the database (to get the max index number), they are extremely unique, and they sort automatically by time.'}, {'comments': [{'comment': u'The dtuple module has similar aims. See recipe 81252 for an example of usage.', 'title': u'Existing module has similarities'}, {'comment': u'The OPAL Group (my company) has made available a more general\nand higher performance result set implementation that does not\nallocate a Python dictionary per row returned from a query. It \nallows tuple-like, dict-like, and object-like access to fields. \nThe implementation requires Python 2.2.1 or better, and includes\nboth pure-Python and C extension module implementations.\n<br>\nFor more information see: http://opensource.theopalgroup.com/', 'title': u'A more general and higher performance alternative exists...'}], 'desc': u"I created this class and related functions because I like accessing database results by field name rather than field number. Accessing by field number has many problems: code is less readable, code gets broken when field positions change or fields are added or deleted from the query, etc.\n\nThis class should have little overhead if you are already using fetchall().\nIt wraps each result row in a ResultRow class which allows you to retrieve results via a dictionary interface (by column name). The regular list interface (by column number) is also provided.\n\nI can't believe the DB-API 2.0 api didn't include dictionary-style results. I'd love to see the reasoning behind not requiring them of database connection classes."}, {'comments': [], 'desc': u'This function can be used to check if a string contain only ASCII characters.'}, {'comments': [{'comment': u'To make this recipe more extensible, it would be a good idea to have seperate functions for things like walking the directories, making the table, and inserting this into the rest of the HTML.\n\nIt would also be a good idea to have the table generating code put in CSS (like \'class="fileTable"\') instead of hard-coded values (which are depricated anyway), and then if the thing gets extended users can have more control over appearance.', 'title': u'CSS and extensibility'}, {'comment': u'Actually, this recipe looks worse the more I look at it. It so offended my sense of aesthetics that I made my own version, at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/200131', 'title': u'My version'}, {'comment': u"Alright, but who needs or would use something like this anyway? It's just an example of file searching on Windoze not a realistic application so people can have an html page of local files - who cares to have that? ", 'title': u' '}], 'desc': u'Searches your hard drive for all files specified \nand generates an HTML web page list of the \nfiles found and links to the file itself. \nThis search is fast and very little code to \ncomplete the task... '}, {'comments': [], 'desc': u"A discussion on python-dev ( http://mail.python.org/pipermail/python-dev/2002-November/030380.html ) came up with the idea of allowing arbitrary assignments::\n\n >>> a,b,*c = (1,2,3,4,5)\n >>> a\n 1\n >>> b\n 2\n >>> c\n (3, 4, 5)\n\nI didn't like the idea of adding this to the language for assignments, so I came up with a generator that basically does the above but assigns the last variable the used iterator, and all without any new syntax.\n\nThanks to Alex Martelli for simplifying the code and Oren Tirosh for coming up with better variable names."}, {'comments': [], 'desc': u'Open key in Win32 registry base like a file. All commands supported by StringIO are available.\n'}, {'comments': [{'comment': u"<pre>\n# would it not be easier to do the following:\n\nclass Generator(object):\n '''\n this is a generator class.\n '''\n def __call__(self):\n self.counter = 0\n while self.counter < 10:\n self.counter += 1\n yield self.counter\n\ngen = Generator()\n\nfor i in gen():\n print i\n\n# yes this adds the extra step of class instantiation but it removes\n# the need for outside-class parameter definition. and the advantage\n# is that this method allows for transparent way to create not only \n# parameters but special methods to manipulate internal generator\n# state.\n\n\n# Imagine a singleton generator:\n\nclass SingletonGenerator(object):\n '''\n this generator singleton class counts to ten and then resets.\n '''\n __state = 0\n def __call__(self):\n while self.__state < 10:\n self.__state += 1\n yield self.__state\n self.__state = 0\n def rest(self):\n self.__state = 0\n def __getattr__(self, name):\n return getattr(self.__class__, name)\n def __setattr__(self, name, val):\n return setattr(self.__class__, name, val)\n\n# usage:\n\ngen_a = SingletonGenerator()\ngen_b = SingletonGenerator()\n\nfor i, j in zip(gen_a(), gen_b())\n print i, j, \n\n## output:\n# 1 2 3 4 5 6 7 8 9 10\n</pre>\n\n", 'title': u'a class version with almost the same semantics..... but quite a bit more flexible!!!'}, {'comment': u' ', 'title': u'some might call what was done in the previous comment "the borg" pattern, I see them (borg and singleton) to be one and the same, they differ only in the side you chose to look from...'}, {'comment': u'Anyone interested in this recipe might also like to read a recent book, "Hackers and Painters: Big Ideas from the Computer Age", by Paul Graham (2004).\n<br><br>\nThough the book is mostly a non-technical discussion of programming principles and practices (generally lionizing Lisp) there is an appendix (pp. 195-99) which compares the __call__ version above to even simpler solutions in other languages.\n<br><br>\nThough his example is just a generated function with maintained state, rather than a "generator" (ie a function with a "yield" call), it explains exactly why some people appreciate other, more powerful languages.\n<br><br>\nI disagree with him: The Python example is only slightly more complicated, and it is vastly easier for a non-expert user to comprehend. The implicitly lexical variables do not exactly aid readability.\n<br><br>\nHowever, Graham is not unkind to Python, and this book is definitely worth reading for anyone with an interest in the utility of programming languages.\n<br><br>\nI\'m pointing that out because this recipe has caused some big ideas to gel in my mind. After studying this complicated recipe, I suddenly "get" what Python is doing with functions. Tes, the version in the comment is definitely the way I would code it in practice, but I\'m glad to see the complex one.\n<br><br>\nIn case you don\'t have the book, here are his examples. Python first:\n<pre>\nclass foo:\n def __init__(self, n): self.n = n\n def __call__(self, i): self.n +=1; return self.n\n</pre>\nObviously, this could yield self.n instead.\n<br><br>\nThe Java solution is a pain, but in Javascript:\n<pre>\nfunction foo(n) {\n return function(i) {\n return n += 1 }}\n</pre>\n<br><br>\nSmalltalk has strange syntax, but at least has the transparency of the Python version:\n<pre>\nfoo: n\n |s|\n s := n.\n ^[:i| s := s+i. ]\n</pre>\n<br><br>\nPerl has an implicit return statement:\n<pre>\nsub foo {\n my ($n) = @_;\n sub {$n += shift}\n}\n</pre>\n<br><br>\nRuby is the clearest, but with strange delimiters:\n<pre>\ndef foo (n)\n lambda {|i| n += i} end\n</pre>\n<br><br>\nAnd finally, Lisp is easily the least cluttered:\n<pre>\n(defun foo(n)\n (lambda (i) (incf n i)))\n</pre>\n<br><br>\nGraham claims that this cannot be done in C++, but of course C++ has its own analogue of __call__, operator():\n<pre>\nstruct foo {\n int n;\n foo(int N): n(N) {}\n int operator()(int i) {\n return n += i;\n }\n};\n\n// BUT BEWARE:\n#include \nint main() {\n foo f(7);\n foo g(30);\n cerr << f(2) << \' \' << g(2) << \' \' << f(2) \n << \' \' << g(2) << " hike!" << endl;\n}\n// Prints: 11 34 9 32 hike!\n// (if you replace the stream insertion operators,\n// which had formatting problems)\n// The stream-operator associates left-to-right,\n// but it is evaluated right to left!\n</pre>\nand this demonstrates the inherent dangers of this sort of programming.\n<br><br>\nThe author also lists 2 other Python solutions which work, and 2 which do not work:\n<pre>\ndef foo(n):\n class accumulator:\n def __init__(self, s):\n self.s = s\n def inc(self, i):\n self.s += i\n return self.s\n return acc(n).inc\n\n# and\n\ndef foo(n):\n s = [n] # The list holds a copy of n\n def bar(i):\n s[0] += i\n return s[0]\n return bar\n</pre>\n\nAnd these 2 do *not* work:\n<pre>\ndef foo(n):\n return lambda i: return n += 1\n\n# nor\n\ndef foo(n):\n lambda i: n += 1\n</pre>\n\nThe author guesses that Python will one day allow something like these, but only the Python class-based version allows easy access to n. So in fact, what to some is a flaw in Python can be a feature to others.\n<br><br>\nI hope somebody learns as much from these examples as I have. Functional programming suddenly makes much more sense to me.', 'title': u"A comparative example is found in 'Hackers and Painters'"}, {'comment': u'The C++ and Java versions work only on integers, which is what Graham meant to point out. But a template is possible. Anyway, the point of the present recipe is to have access into the function, and the Python version is quite nice that way.', 'title': u"Graham's examples are not 'statically typed'"}, {'comment': u'very nice recipe!', 'title': u'no comments'}], 'desc': u'Function to enable attribute access for generator instances. Simplifies data sharing for advanced uses of generators and provides much of the functionality sought by PEP 288.\n<br>\nMost uses of generators have no need for data sharing. This recipe is for the few tough cases which can be written more elegantly when attribute access is enabled.\n\n'}, {'comments': [], 'desc': u'When a function is expensive, it can be interesting to keep in cache the last computed values.'}, {'comments': [], 'desc': u'This function allow to use a slice like protocol on iterators.'}, {'comments': [], 'desc': u"In about 70 LOC's we give a simple implementation of (a concept of) interfaces for Python.\n\nNeeds Python 2.2"}, {'comments': [{'comment': u'One simplification. If you replace change the import statement to:\n<pre>\nfrom SimpleXMLRPCServer import SimpleXMLRPCServer\n</pre>\nEvery "SimpleXMLRPCServer.SimpleXMLRPCServer" can be replaced with just "SimpleXMLRPCServer".\n', 'title': u'SimpleXMLRPCServer.SimpleXMLRPCServer'}, {'comment': u'As discussed in \n\n<pre> http://www.python.org/security/PSF-2005-001/\n</pre>\n\nThere is a new known vulnerability in the standard XML-RPC library in Python 2.2 and later.\n\nPatches are available off of that URL, and new ActivePython builds or instructions on how to fix existing installations will be available shortly. (Python.org folks are also planning on providing updated builds).\n\n<br>\n<br>\n\n-- David Ascher', 'title': u'CAUTION: Security advisory affects this code'}, {'comment': u'Before you start any client or create a proxy, instruct the socket module to produce timeouts when connection is taking too long. Without this, your rpc call can hang indefinitely. \n\n<pre>\n socket.setdefaulttimeout(60) \n</pre>\n\nThis is a time out in seconds, after which you will get a socket.error. You can easily catch this error and decide to try again, but at least your program will not hang forever.', 'title': u'Another small nicety on the client side'}], 'desc': u"Just thought I'd share a few xmlrpc server niceties.\n- Simple (and not very secure) access controll\n- Port rebinding (If you code anything like me, this comes in handy)\n- register_instance with class"}, {'comments': [{'comment': u"The main speech class is tied in with Tkinter. It's going to need some hacking to turn it into a general purpose speech engine that one can just call from any code.", 'title': u'Nice, except...'}, {'comment': u'<pre>\nimport sys\nimport win32com.client\nimport pythoncom\n\ndefaultNamedOptArg=pythoncom.Missing\ndefaultNamedNotOptArg=pythoncom.Missing\ndefaultUnnamedArg=pythoncom.Missing\n\nprint "Enter text to be spoken or type \'exit\' to quit."\ndirectss = win32com.client.Dispatch("{EEE78591-FE22-11D0-8BEF-0060081841DE}")\n\nsaythis = raw_input()\nspeaking = 0\nspoken = 0\n\nwhile saythis != \'exit\':\n\tif speaking == 0:\n\t\tif spoken == 0:\n\t\t\tdirectss.Speak(saythis)\n\t\t\tspoken = 1\n\t\telse:\n\t\t\tsaythis = raw_input()\n\t\t\tspoken = 0\t\t\t\n\tpythoncom.PumpWaitingMessages()\n\tspeaking = directss.Speaking\n</pre>', 'title': u'Without Tkinter'}], 'desc': u'Example text-to-speech using wincom32 to plug into the Microsoft Speech API 4.0. '}, {'comments': [], 'desc': u'This call wrapper class enables throttling of function calls. You can control how many characters (or sequence elements) per second your function processes (with granularity of one sequence). The calls are asynchronous and the actual function call is done when the last operation has lasted/waited long enough to satisfy the characters/second limit.'}, {'comments': [{'comment': u'How can i implement this into my script?', 'title': u'How do you implement this into script?'}, {'comment': u'<pre>\nimport time\nprog = progressBar(0, 100, 77)\nfor i in xrange(101):\n prog.updateAmount(i)\n print prog, "\\r",\n time.sleep(.05)\n</pre>', 'title': u"If you want to ACTUALLY use it, you're going to have to think for yourself."}, {'comment': u'It can be a substantial performance hit to print the bar every iteration, whether it changes or not. At 100 iterations, like Josiah\'s example, it changes every iteration, so it won\'t matter. \nBut if you have more than a few thousand, it\'s worth checking and\nnot printing an unchanged bar:\n\n<pre>\nlimit = 1000000\n\nprog = progressBar(0, limit, 77)\noldprog = str(prog)\nfor i in xrange(limit+1):\n prog.updateAmount(i)\n if oldprog != str(prog):\n print prog, "\\r",\n oldprog=str(prog)\n</pre>\n\nIn this example (which is close to a real use I have, where I\'m processing a file with a little over a million lines), the wall-clock time on my system consistently drops by about 80% (from over 2 minutes down to 24 seconds).\n\nAlso, remember to print a newline after your last print of the progress bar, or your next print statement will overlay it:\n\n<pre>\nprint\n</pre>', 'title': u'Best not to print it every iteration'}, {'comment': u'This was a great example. Thanks.\nI\'m very new to curses programming, but I thought I\'d try implementing this in a curses panel.\n<br>This gives me the option of placing (or even moving) the panel to specific parts of the screen, independent of other UI elements in the curses window. Pretty cool - python makes a lot of things easy.\n<br>This could be implemented even more easily using pythondialog (http://pythondialog.sourceforge.net/)\n<br>which does all the work for you, but pythondialog is based on "dialog" (http://dickey.his.com/dialog/dialog.html)\n<br>which is GPL rather than LGPL so it restricts what you can do with it within a commercial setting.\n<br>\n<br>I was going to post my "cursified" version of this example code, but it\'s getting badly garbled and truncated (or "Preview" is broken.)\n<br>I guess it\'ll have to suffice to say that it can be done easily with the standard python curses modules.', 'title': u'curses version...'}, {'comment': u'I want to incorporate this class into my program which does the work of downloading debian based packages from the net. How to use it in that case ???', 'title': u'How to use this code for a file remotely'}, {'comment': u"I modified the class a little, mainly added self._old_pbar (initialized to '') and added draw() method:\n\n<pre>\ndef draw(self):\n\t# draw progress bar - but only if it has changed\n\n\tif self.pbar_str != self._old_pbar:\n\t self._old_pbar = self.pbar_str\n\t sys.stdout.write(self.pbar_str + '\\r')\n\t sys.stdout.flush()\t\t# force updating of screen\n</pre>\n\nI also created a new class AsciiProgressBar which derives from ProgressBar (draw() is an abstract method in the base class). I can send the code if somebody's interested.", 'title': u'Minor improvements'}, {'comment': u'Of course I am interested! Please paste the AsciiProgressBar class here or email it to walterbrunswick@sympatico.ca.\nThank you!', 'title': u'Interested? Am I!?'}, {'comment': u"Instead send the entire code of your module, please. Your 'draw' function is not compatible with the existing code.", 'title': u'Instead...'}, {'comment': u'it was nice to see a code that works efficiently.. but how to implement this progress bar code onto curses window with color..', 'title': u'progress bar using curses'}, {'comment': u'Please paste it here, or send to zz2liu@yahoo.com', 'title': u'Intested in your progress bar'}, {'comment': u'It was really good eg ,but its better to see the cursified versions of this.pls paste that code here...', 'title': u'cursified version'}, {'comment': u'hey pls paste code of cursified progressbar.. it was really cool to see this, waiting for curses display.', 'title': u'using curses'}, {'comment': u'this is the code for cursified progressbar.. \nimport curses\nif __name__ == "__main__":\n stdscr=curses.initscr()\n curses.start_color()\n \n curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)\n curses.init_pair(2, curses.COLOR_RED,curses.COLOR_WHITE)\n curses.init_pair(3,curses.COLOR_BLUE,curses.COLOR_WHITE)\n curses.init_pair(4,curses.COLOR_WHITE,curses.COLOR_WHITE)\n curses.init_pair(5,curses.COLOR_BLUE,curses.COLOR_BLUE)\n curses.init_pair(6,curses.COLOR_BLACK,curses.COLOR_WHITE)\n s=curses.newwin(48,156,0,0)\n s.bkgd(ord(\' \'),curses.color_pair(1))\n s.box()\n s.refresh()\n s=stdscr.subwin(3,52,26,41)\n s.bkgd(ord(\' \' ), curses.color_pair(3))\n s.box()\n \n s.refresh()\n \n \n s=stdscr.subwin(12,68,20,32)\n s.bkgd(ord(\' \' ), curses.color_pair(6))\n s.addstr(1, 27, "PROGRESS",curses.color_pair(2))\n # s.bkgdset(ord(\' \'), curses.color_pair(4))\n s.box()\n \n s.refresh()\n \n diff=42\n s=stdscr.subwin(1,50,27,42)\n s.bkgd(ord(\' \' ), curses.color_pair(4))\n #s.bkgdset(ord(\' \'),curses.color_pair(5))\n s.box()\n s.refresh()\n for x in range(26):\n \n s = stdscr.subwin(1, 2,27, diff)\n diff=diff+2\n s.bkgd (ord(\' \'), curses.color_pair(5))\n #limit = 10000\n #prog = progressBar(0, limit, 13)\n #oldprog =str(prog)\n #for i in xrange(limit+1):\n # prog.updateAmount(i)\n \n # print prog, "\\r",\n time.sleep(0.20)\n s.refresh()', 'title': u'moving progressbar in curses'}, {'comment': u'What a great class!\n\nI tried to avoid the use of string concatenations (especially useful for quick updating progress bars; or when you don\'t have control over the update rate), and slightly modified the class (and added docstrings and a __call__ :p).\n\nJust thought I\'d share.\n\n<pre>\nclass progressBar:\n """ Creates a text-based progress bar. Call the object with the `print\'\n command to see the progress bar, which looks something like this:\n \n [=======> 22% ]\n \n You may specify the progress bar\'s width, min and max values on init.\n """\n\n def __init__(self, minValue = 0, maxValue = 100, totalWidth=80):\n self.progBar = "[]" # This holds the progress bar string\n self.min = minValue\n self.max = maxValue\n self.span = maxValue - minValue\n self.width = totalWidth\n self.amount = 0 # When amount == max, we are 100% done \n self.updateAmount(0) # Build progress bar string\n\n def updateAmount(self, newAmount = 0):\n """ Update the progress bar with the new amount (with min and max\n values set at initialization; if it is over or under, it takes the\n min or max value as a default. """\n if newAmount < self.min: newAmount = self.min\n if newAmount > self.max: newAmount = self.max\n self.amount = newAmount\n\n # Figure out the new percent done, round to an integer\n diffFromMin = float(self.amount - self.min)\n percentDone = (diffFromMin / float(self.span)) * 100.0\n percentDone = int(round(percentDone))\n\n # Figure out how many hash bars the percentage should be\n allFull = self.width - 2\n numHashes = (percentDone / 100.0) * allFull\n numHashes = int(round(numHashes))\n\n # Build a progress bar with an arrow of equal signs; special cases for\n # empty and full\n if numHashes == 0:\n self.progBar = "[>%s]" % (\' \'*(allFull-1))\n elif numHashes == allFull:\n self.progBar = "[%s]" % (\'=\'*allFull)\n else:\n self.progBar = "[%s>%s]" % (\'=\'*(numHashes-1),\n \' \'*(allFull-numHashes))\n\n # figure out where to put the percentage, roughly centered\n percentPlace = (len(self.progBar) / 2) - len(str(percentDone)) \n percentString = str(percentDone) + "%"\n\n # slice the percentage into the bar\n self.progBar = \'\'.join([self.progBar[0:percentPlace], percentString,\n self.progBar[percentPlace+len(percentString):]\n ])\n\n def __str__(self):\n return str(self.progBar)\n\n def __call__(self, value):\n """ Updates the amount, and writes to stdout. Prints a carriage return\n first, so it will overwrite the current line in stdout."""\n print \'\\r\',\n self.updateAmount(value)\n sys.stdout.write(str(self))\n sys.stdout.flush()\n</pre>', 'title': u'Slightly improved'}, {'comment': u'I reviewed it last year, found that I had replaced all of the\noriginal code (aside from the boilerplate license comments),\nand released it with an LGPL license.', 'title': u'dialog is LGPL'}], 'desc': u"Here is a little class that lets you present percent complete information in the form of a progress bar using the '#' character to represent completed portions, space to represent incomplete portions, and the actual percent done (rounded to integer) displayed in the middle:\n\n[############# 33%                               ] \n\nWhen you initialize the class, you specify the minimum number (usually 0), the maximum number (your file size, for example), and the number of characters wide you would like the progress bar to be. Note that width includes the brackets [] on the ends of the progress bar as well.\n\nYou'd probably want to use this in conjuction with the curses module, or something like that so you can over-write the same portion of the screen to make your updates 'animated'."}, {'comments': [{'comment': u'list.sort, significantly, sorts the list object in place (as links to this recipe have mentioned). The method returns None, not the list object, to remind you of this side effect.\n\n<br><br>If you wish to constrain your sort implementation to behave as list.sort -- either to subclass list or merely to have your sort routines be consistent with list.sort -- use the function in the recipe, but at the end of the function, do\n\n<pre>\nlist[:] = [x[1] for x in tuplesList]\n</pre>\n\nand that will effect the sort "in place".\n\n<br>IIRC, list.sort in CPython, implemented natively in C, takes some precautions to avoid problems with concurrent use of the list by another thread while it\'s being sorted by the thread doing list.sort(). I don\'t know whether those precautions are important enough to use that they preclude using your sort function with a full-on replacement of the list contents at the end.\n\n<br><br>You could try using a compare function that uses a dict object to "memoize" the results of upper on each element.\n\n<pre>\ndef sort_case_insensitive(listobj):\n memodict = {}\n def compare(a,b):\n aval = memodict.get(a)\n if aval is None: aval = memodict.setdefault(a, a.upper())\n bval = memodict.get(b)\n if bval is None: bval = memodict.setdefault(b, b.upper())\n return cmp(aval, bval)\n listobj.sort(compare)\n</pre>\n\n<br>While correct, the above is about twice as slow as list.sort(lambda a,b: cmp(a.upper(), b.upper()) for a list of 52 unique strings sharing 26 unique upper-case representations.\n\n\n\n', 'title': u'you can amend the recipe to sort in-place as well'}, {'comment': u"This is an example of a Schwartzian Transform (a Perl concept that works in Python too). It's in the Python FAQ:\n\nhttp://www.python.org/cgi-bin/faqw.py?req=show&file=faq04.051.htp", 'title': u'Schwartzian Transform'}], 'desc': u"The default compare function used when sorting a list of strings uses the ordinal value of the string characters for comparison. This results in the typical ASCII sort result of 'B' < 'a'. If a user is going to see the list, it is generally better to do a case-insensitive comparison."}, {'comments': [{'comment': u"You've spend 16 lines with something that you could do with:\n<pre>numero=numero.rjust(9,'0')+numero</pre>", 'title': u'16 lines'}], 'desc': u'This is a little routine, one of my very firsts in Python, to print a sentence expressing a quantity, from a numeric input. This works in Spanish.\n\nEsta peque\xf1a rutina, de mis primeras en Python pero aun funciona, convierte a una oracion impresa, una cantidad numerica. Esto en Espa\xf1ol.'}, {'comments': [{'comment': u'When running there\'s an error message on my XP commandline caused by the two lines below:\n<pre>\nrem = """\nDo any custom setup like setting environment variables etc if required here ...\n</pre>\n\nwhich should be on the same line:\n<pre>\nrem = """ Do any custom setup like setting environment variables etc if required here ...\n</pre>\n\nIMHO: Very elegant way to start a script... - nice recipe!', 'title': u'Small "bug"'}, {'comment': u"There is a much simpler way. Simply add .py and .pyw to the PATHEXT environment variable on Windows NT, 2000, and XP (possibly Win9x and ME too, but I can't test that).<br>\n<br>\nOpen the System Control Panel, select the Advanced tab and then click the Environment Variables... button to bring up the dialog. PATHEXT is listed under the System variables. Once you've made the change, if you type set and press return in the command shell you should see your change:<br>\n<br>\nPATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.PY;.PYW<br>\n<br>\nNow if you have a program called hello.py in one of the directories on your PATH, you can invoke it by just typing hello and return.<br>\n<br>\nNote that you will won't be able to select a .py or .pyw file in the Explorer to open files of a particular extension. In order to do that, you'll need to use a variation of the instructions for associating .py and .pyw files with the codeEditor found at:<br>\n<br>\nhttp://wiki.wxpython.org/index.cgi/PythonCardEditor<br>\n<br>\nJust substitute your program for the codeEditor, and the extensions such as .txt, or .jpg, etc. you want to open.", 'title': u'instead add .py and .pyw to PATHEXT'}, {'comment': u'One thing to be aware of, if you follow the advice of adding .py;.pyw to PATHEXT:<br>\n<br>\nYou can call python scripts that are on the PATH or in the current directory by just typing the script name without the extebsion.<br>\n<br>\nBUT: if you add the extension, the default action for that extension is called.<br>\n<br>\nSo if, for example, you followed the above mentioned tip and configured PythonCardEditor to be opened, when a .py file is double-clicked in the explorer, then PythonCardEditor will also be opened when you type in the name of a Python file with extension at the command prompt!<br>\n<br>\nAt least, my Win2k box acts like this.', 'title': u'Caveat'}], 'desc': u'This recipe contains information on wrapping your python scripts in batch files on win2k. This will enable your scripts to appear as if they are batchfiles and get automatically picked up from the path. '}, {'comments': [], 'desc': u'Some useful functions which work on infinite lists, including generalized versions of map, filter, zip on gLists.'}, {'comments': [{'comment': u"I shy away from this one for big sets because each row is going to take up space with the dict keys. I do however combine this with Marteli's Struct class for struct like access\n...\ncursorclass=StructCursor)\n...\n\nc.execute(sql)\ns = c.fetchone()\ns.col1 + s.col2\n", 'title': u'Hmmmm...'}], 'desc': u'Accessing database results by field name rather than field number is easy. I prefer standard, stable library like MySQLdb rather than private solutions. Look at the following code.'}, {'comments': [], 'desc': u'Ensure that a name exists in a target namespace. If it does not, make it available in the target namespace using the given definition. The target should be a namespace dictionary (presumably for a module, see the discussion below otherwise). The default target is __builtins__ (specificially, __builtins__.__dict__).'}, {'comments': [{'comment': u'<pre>\n""" easy checksum """\ndef checksum(a):\n return (10 - sum([int(y)*[7,3,1][x%3] for x, y in enumerate(str(a)[::-1])])%10)%10\n</pre>', 'title': u'Checksum calculation'}, {'comment': u'<pre>\n# Return the "Luhn transform" of a digit.\nluhnify = lambda digit: sum(divmod( digit*2, 10 ))\n\ndef luhn_checksum( digits ):\n """Return the Luhn checksum of a sequence of digits.\n """\n digits = map( int, digits )\n odds, evens = digits[-2::-2], digits[-1::-2]\n return sum( map(luhnify,odds) + evens ) % 10\n</pre>', 'title': u'Another take...'}, {'comment': u'It does not match the other 2 listed here, and it returns "7" for my credit card. What is it for?', 'title': u'That checksum is wrong.'}, {'comment': u'Here is a integer-only version that avoids string casts.\nYou may need "from __future__ import division" to use the "//" floor operator.\n<pre>\ndef luhn(n):\n """luhnsum(int)->bool\n Mod 10 checksum by Hans Peter Luhn (1896-1964)\n """\n sum=0\n while n:\n r=n%100\n n//=100\n z=r%10\n r=r//10*2\n sum+=r//10+r%10+z\n return 0==sum%10\n</pre>', 'title': u'Integer only version'}, {'comment': u'<pre>\ndef nextLuhn(n):\n """nextLuhn(int) -> int\n Gets the smallest Luhn number greater than n.\n Uses a naive (exhaustive) algorithm that must try\n the Luhn checksum an average of 10 times.\n """\n n+=1\n while not luhn(n):\n n+=1\n return n\n\ndef biggerLuhn(n):\n """ biggerLuhn(int) -> int\n Gets a Luhn number greater than n.\n Uses a probability model that is very efficient if\n n passes the Luhn checksum. \n It may be possible to miss a Luhn number with this method.\n """\n for t in [8, 18, 7, 17, 6, 16]:\n if luhn(n+t):\n return n+t\n return nextLuhn(n)\n \ndef xluhn(seed,howmany):\n """xluhn(int,int) ->*int\n Yields Luhn numbers greater than the seed.\n Some numbers may be left out of the sequence.\n """\n while howmany:\n seed=biggerLuhn(seed)\n howmany-=1\n yield seed\n</pre>', 'title': u'generating many luhn numbers'}], 'desc': u'This is an industry standard algorithm I ported to python. It works on all major credit cards. You pass in the credit card number as a string and it returns 1 for a valid card or 0 for an invalid card'}, {'comments': [], 'desc': u'Wrap a file handle to allow seeks back to the beginning\n\nSometimes data coming from a socket or other input file handle isn\'t\nwhat it was supposed to be. For example, suppose you are reading from\na buggy server which is supposed to return an XML stream but can also\nreturn an unformatted error message. (This often happens because the\nserver doesn\'t handle incorrect input very well.)\n\nA ReseekFile helps solve this problem. It is a wrapper to the\noriginal input stream but provides a buffer. Read requests to the\nReseekFile get forwarded to the input stream, appended to a buffer,\nthen returned to the caller. The buffer contains all the data read so\nfar.\n\nThe ReseekFile can be told to reseek to the start position. The next\nread request will come from the buffer, until the buffer has been\nread, in which case it gets the data from the input stream. This\nnewly read data is also appended to the buffer.\n\nWhen buffering is no longer needed, use the \'nobuffer()\' method. This\ntells the ReseekFile that once it has read from the buffer it should\nthrow the buffer away. After nobuffer is called, the behaviour of\n\'seek\' is no longer defined.\n\nFor example, suppose you have the server as above which either\ngives an error message is of the form:\n\n  ERROR: cannot do that\n\nor an XML data stream, starting with "<?xml".\n\n   infile = urllib2.urlopen("http://somewhere/")\n   infile = ReseekFile.ReseekFile(infile)\n   s = infile.readline()\n   if s.startswith("ERROR:"):\n     raise Exception(s[:-1])\n   infile.seek(0)\n   infile.nobuffer() # Don\'t buffer the data\n   ... process the XML from infile ...\n\n\nThis module also implements \'prepare_input_source(source)\' modeled on\nxml.sax.saxutils.prepare_input_source. This opens a URL and if the\ninput stream is not already seekable, wraps it in a ReseekFile.'}, {'comments': [], 'desc': u'This implements two types of dictionary-like objects where there can be more than one entry with the same key. One is OrderedMultiDict, which preserves the order of all entries across all keys. The other is UnorderedMultidict, which only preserves the order of entries for the same key.\n\nDownload MultiDict.py\nExample:\n>>> import MultiDict\n>>> od = MultiDict.OrderedMultiDict()\n>>> od["Name"] = "Andrew"; od["Color"] = "Green"\n>>> od["Name"] = "Karen"; od["Color"] = "Brown"\n>>> od["Name"]\n\'Karen\'\n>>> od.getall("Name")\n[\'Andrew\', \'Karen\']\n>>> for k, v in od.allitems():\n... print "%r == %r", (k, v)\n...\n\'Name\' == \'Andrew\'\n\'Color\' == \'Green\'\n\'Name\' == \'Karen\'\n\'Color\' == \'Brown\'\n>>> ud = MultDict.UnorderedMultiDict(od)\n>>> for k, v in ud.allitems():\n... print "%r == %r", (k, v)\n...\n\'Name\' == \'Andrew\'\n\'Name\' == \'Karen\'\n\'Color\' == \'Green\'\n\'Color\' == \'Brown\'\n>>> '}, {'comments': [{'comment': u'This script is very useful to me. Great!', 'title': u'No problem with Windows XP and Office XP.'}], 'desc': u"This is a simple class and test code to read the Contacts from Outlook using win32com, which is part of Mark Hammond's win32all package."}, {'comments': [], 'desc': u'this recipe describes a tree backbone class that supports two modes of iteration and topological comparison.\nand it has a nice node access inteface.'}, {'comments': [{'comment': u'The last line of the function is:<br>\n<pre>\n return len(t)/len(s) < threshold\n</pre>\nThis will always indicate that the string is text, unless len(t) = len(s), because this is using the default integer division, and threshold is a float 0 <= threshold <= 1. If you change the last line to<br>\n<pre>\n return float(len(t))/len(s) <= threshold\n</pre>\nor (if you prefer -- tidier, but less obvious):<br>\n<pre>\n return len(t) <= len(t) * threshold\n</pre>', 'title': u'A bug will make this script unreliable...'}], 'desc': u"Here's a quick test to see if a file or string contains text or is binary. The difference between text and binary is ill-defined, so this duplicates the definition used by Perl's -T flag, which is:\n<br/>\n The first block or so of the file is examined for odd characters such as strange control codes or characters with the high bit set. If too many strange characters (>30%) are found, it's a -B file, otherwise it's a -T file. Also, any file containing null in the first block is considered a binary file."}, {'comments': [{'comment': u'I\'m using the "serial" module, which is supposed to have the same interface on *NIX, and Windows at least.\n\nEven though it is amazingly easy to use, it\'s possibly more work to install than your example. On Debian you just install the package however.', 'title': u'What about the serial module'}], 'desc': u'A limited, but simple and self-contained module giving basic access to the PC Com1 port. Useful for prototyping as it stands, but easily modified for other com ports and needs.'}, {'comments': [], 'desc': u'Deleted as it was a big source of memory leaks'}, {'comments': [{'comment': u'class RegistryDict(object):\n def __init__(self, keyhandle = win32con.HKEY_LOCAL_MACHINE, keypath = [], flags = None):\n """If flags=None, then it will create the key.. otherwise pass a win32con.KEY_* sam"""\n self.keyhandle = None # THIS should be this way, should it not?\n self.open(keyhandle, keypath, flags)\n\n\notherwise self.open leads to "... has no attribut "keyhandle")', 'title': u'self. missing'}, {'comment': u'I\'ve had occasion to use this class, and have found it quite nice. There are a few changes I\'ve had to make, though:\n<br><br>\nThe previous comment\'s correction, adding "self." to the first line of __init__ to make keyhandle an ivar, is correct.\n<br><br>\nChanged the definition of __cmp__ to the following:\n<pre>\n # Do the objects have the same state?\n return self.keyhandle == other.keyhandle\n</pre>\n<br>\nChanged the definition of clear to the following:\n<pre>\n keylist = list(self.iterkeys())\n # Two-step to avoid changing the set while iterating over it\n for k in keylist:\n del self[k]\n</pre>\n<br>\nIn iteritems_data, the call to "massage..." should be:\n<pre>\n yield s, self.massageIncomingRegistryValue((obj, objtype))\n</pre>\n<br>\nIn iteritems_children, changed the RegEnumKey line to read:\n<pre>\ns = win32api.RegEnumKey(self.keyhandle, i)\n</pre>\n<br>\nThe __delitem__ method only deletes string values. I changed it to the following:\n<pre>\n # Delete a string value or a subkey, depending on the type\n try:\n item = self[key]\n except:\n return # Silently ignore bad keys\n itemtype = type(item)\n if itemtype is str:\n win32api.RegDeleteValue(self.keyhandle, key)\n elif isinstance(item, RegistryDict):\n # Delete everything in the subkey, then the subkey itself\n item.clear()\n win32api.RegDeleteKey(self.keyhandle, key)\n else:\n raise ValueError, "Unknown item type in RegistryDict"\n</pre>\nNote the use of .clear() to delete the whole tree under the subkey. A more cautious approach would be to require the client code to manage that.\n<br><br>\nIn the "open" method, the "else" clause is one level too deep. The "else" should be paired with "if flags is None:"\n<br><br>\nIf desired, I can put a patch or the whole file somewhere around here.', 'title': u'Updates and fixes'}, {'comment': u'I just ran across another subtle bug: the dictionary key \'\' (the empty string) must mean the "default value" of a registry key, but it was returning a copy of "self" if there was no default value. The following updated __getitem__ fixes this:\n<pre>\n def __getitem__(self, key):\n # is it data?\n try:\n return self.massageIncomingRegistryValue(win32api.RegQueryValueEx(self.keyhandle, key))\n except:\n if key == \'\':\n # Special case: this dictionary key means "default value"\n raise KeyError, key\n pass\n # it\'s probably a registry key then\n try:\n return RegistryDict(self.keyhandle, key, win32con.KEY_ALL_ACCESS)\n except:\n pass\n # must not be there\n raise KeyError, key\n</pre>', 'title': u'Oops! one more fix'}, {'comment': u"This looks like a very cool recipe. It would help though to have the updated/fixed version of this recipe posted in it's entirety. Cutting and pasting the fixes from the comments is somewhat error prone. It'd also be nice if some simple test cases were constructed to act as a demonstration of the usage of this module.", 'title': u'Requests'}, {'comment': u"I agree with the previous post. Before or after applying the mentioned bug fixes, I've never gotten this to work. Without clear examples and tests in a main function like many other recipes, I wouldn't be sure if I were using it properly anyway. This looks like a very useful and promising recipe, but it definitely could be improved with unit tests and some refactoring.", 'title': u'I second that'}, {'comment': u'adding some checks would be nice. Anyways code is not bad :>\n<br>http://mortgage-calculator.teach-nology.com', 'title': u'agreed'}, {'comment': u"You can download the entire script with the fixes above from:\n\nhttp://mikebabcock.ca/code/registrydict.py\n\nYou're welcome :)\n\nPS, I'll update this with any other patches/fixes I notice from here. I made one change myself as well, by removing an unnecessary temporary variable in one of the other patches.", 'title': u'Fixed script, downloadable'}, {'comment': u"This script at http://mikebabcock.ca/code/registrydict.py also needs a wee fix (I've emailed the author about it):\n<br>Line26: def __getitem__(self, item): \n<br>should be (I think): \n<br>def __getitem__(self, key)\n<br> \n<br>Now, I wish someone could show me how it works!\n<br> \n<br>-ross", 'title': u'Still not quite right'}, {'comment': u"May be worth putting\n<pre>\n if isinstance(value,unicode): #unicode...\n value = value.encode()\n<pre>At line 186 in __setitem__ so that unicode strings get saved as a REG_SZ type (i.e. a string). Currently unicode string get stored as binary (which python handles transparently, but other apps might take offense...)\n<br>There's probably a neater way of doing this, I'm stilling learning the way of pythonic coding...</pre></pre>", 'title': u'Save unicode as REG_SZ'}, {'comment': u'I\'ve rewritten __delitem__ as it just plain didn\'t work...\n<pre>\n def __delitem__(self, item):\n # Delete a string value or a subkey, depending on the type\n key = self[item]\n keytype = type(key)\n if keytype is RegistryDict:\n # Delete everything in the subkey, then the subkey itself\n key.clear()\n win32api.RegDeleteKey(self.keyhandle, item)\n else:\n win32api.RegDeleteValue(self.keyhandle, item)\n</pre>\nIt\'s got slightly different behaviour: the old version looked like it was attempting to silently fail if you deleted a key that didn\'t exist.\n<br><br>\nThis version will raise a keyerror, which is more consistent with the behaviour of standard dictionaries, i.e. \n<pre>\ndel {}["foo"] \n</pre> Will raise a keyerror, not fail silently.', 'title': u'__delitem__ rewrite'}, {'comment': u'http://mikebabcock.ca/code/registrydict.py has been updated appropriately as per the updates above.', 'title': u'Updated my hosted copy'}, {'comment': u'I try to run this script with no success. Is this right?: Should be printed subkeys this way? Neither of these is working :-( \n<pre>\nprint RegistryDict()\nprint RegistryDict(flags=win32con.KEY_ALL_ACCESS)\nprint RegistryDict(keypath="HARDWARE", flags=win32con.KEY_ALL_ACCESS)\n</pre>\n<br><br>\n\nMoreover, here: http://mikebabcock.ca/code/registrydict.py is just part of updated script, so I am not sure, if I collect the right script of last version.\n\nThank you very much', 'title': u'doesnt work'}], 'desc': u'This class wraps most of the win32api functions for accessing a registry. It will read and write all win32 registry types, and will de/serialize python objects to registry keys when a string or integer representation is not possible.'}, {'comments': [{'comment': u'Another approach is to use the Import Export Wizard on the File menu in Internet Explorer. It exports bookmarks to an HTML file with a few clicks of the mouse.', 'title': u'Import Export Wizard'}], 'desc': u'Looks through the MS Explorer Favorites folders producing an HTML page with the corresponding URLs as links to them, conveniently formatted.'}, {'comments': [{'comment': u'import random, operator<br>\ntosses = [random.choice((0,1)) for toss in xrange(100)]<br>\nnheads = reduce(operator.add, tosses) # or sum(tosses) in Python 2.3<br>\nntails = 100 - nheads<br>\nprint "heads: %s tails: %s" % (nheads, ntails)<br>', 'title': u' '}], 'desc': u'This program is equivalent to tossing a coing for 100 times and for 100 attempts to obtain the number of heads and tails in the random order it also sums up the number of heads and tails that have formed so far....this is a simple program for random sample space analysis to show that even in the best of conditions the probability of a coin falling tails or heads is not exactly 1/2..but close to 1/2. The UINIVERSE is not perfect !'}, {'comments': [{'comment': u"This is a nice recipe, but I think it would be better if your class didn't need to parse the geometry strings. It would be cleaner just to pass the width and height as arguments or a tuple, and have your main() function handle interaction with the user.", 'title': u'X by Y'}, {'comment': u'If you have imagemagick installed, you can use this recipe:\n<pre>\nfilename="foo.jpg"\nx=60\ny=60\nnew_filename="foo_60.jpg"\n\nret=os.system("convert -geometry %sx%s \'%s\' \'%s\'" % (\n x, y, filename, new_filename))\nif ret!=0:\n print "File:", filename, "can\'t be converted"\n</pre>', 'title': u'Using imagemagick'}], 'desc': u'On the web and various purpose, we want to thumbnail images.'}, {'comments': [{'comment': u'This works great. Do you know where I can find a good and cheap solution to converting a Group 3/4 Tiff or jpg to PCL or PostScript code?\n\nThanks', 'title': u'Image Converter'}], 'desc': u'Simple GUI to allow converting images from one format to another.\nAvailable formats are: .gif .jpg .png .tif .bmp\nUses PIL.'}, {'comments': [{'comment': u"I tried your module but I think it didn't detect a blank DVD. That's what I need. Do you have any advice?", 'title': u'Any idea how to detect blank CDs or DVDs?'}], 'desc': u"This module provides easy control of cd drives on Win32 machines. Using the Python Win32 Extensions, the module automatically detects all cd drives and defaults to the first drive found or to a programmer specified drive. Methods include eject() to open the drive door, close() to close the drive door, and load() which tries to close the drive door and then make the drive available to the file system.\n\nTo test either import the WinCDRom module and create an instance of the Cdrom class:\n\nimport WinCDRom\ncd = WinCDRom.Cdrom()\ncd.eject()\ncd.close()\ncd.load()\n\nOr just run the script from a DOS prompt to use the test function:\n\nC:\\python WinCDRom.py\n\nListing drives:\n['D:']\nDefault drive: D:\nOpening drive door...\nClosing cd drive door... (CD read attempt will time out at 5 seconds.)\nLoaded cd successfully in drive D:\nWinCDRom Tests completed."}, {'comments': [], 'desc': u'Code to call a Windows Dll """void FAR PASCAL hllapi(int FAR *, char FAR *, int FAR *, int FAR *)""" with ctypes (trivial) and calldll (a nightmare).'}, {'comments': [{'comment': u'This recipe does not in any way use dictionary, just lists.\nFor doing this as it should be, one could do this:\n<br>\n<pre>\n stateList = [\'r\', \'p\', \'s\']\n\n# validStates = { \'User Wins\' : ((\'p\',\'r\'), (\'r\',\'s\'), (\'s\',\'p\')),\n# \'No One Wins\' : ((\'p\',\'p\'), (\'r\',\'r\'), (\'s\',\'s\')),\n# \'Computer Wins\' : ((\'r\',\'p\'), (\'s\',\'r\'), (\'p\',\'s\')),\n# }\n# This is not wise. Just the same as using a list.\n\n# The following is better:\n\n# First some handy aliases to save typing.\nwin = "User wins"\ndraw ="No one wins"\nlose = " Computer wins"\nvalidStates = { (\'p\',\'r\') : win,\n\t\t\t(\'r\',\'s\') : win,\n\t\t\t(\'s\',\'p\'): win,\n (\'p\',\'p\'): draw,\n\t\t\t(\'r\',\'r\'): draw,\n\t\t\t(\'s\',\'s\'): draw,\n (\'r\',\'p\'): lose,\n\t\t\t(\'s\',\'r\'): lose,\n\t\t\t(\'p\',\'s\'): lose\n }\n\n try:\n while 1:\n # testTuple = (None, None)\n # userInput = None\n # computerInput = \'?\'\n# These can safely be commented out. Pythons power is conciseness after all\n\n userInput = cli()\n computerInput = ( stateList[random.randint(0,2)] )\n\n testTuple = (userInput, computerInput)\n\n # for select in validStates:\n # if testTuple in validStates[select]:\n # print\n # print "You chose: ", userInput\n # print "The computer chose:", computerInput\n # print " ****", select, " ****"\n # print\n# Iterating over a dictionary makes really no sense. After all, it IS a dictionary\n# Instead we can:\n\nprint validStates[testTuple]\n\n# For the exact same effects.\n</pre>\n\nLess to type, faster to execute, easier to extend.', 'title': u'Doing this Right'}, {'comment': u"<pre>\nimport random\nuserPick=''\nwhile userPick not in ['r', 'p', 's']:\n userPick = raw_input('\\tPlease enter (r)ock, (p)aper or (s)cissors to play... ')[0]\n\ncomputerPick= random.choice(['r','p','s']) \npair = (userPick, computerPick)\n\nresult= { pair==('r','r') or pair==('p','p') or pair==('s','s'): 'draw!',\n pair==('p','r') or pair==('s','p') or pair==('r','s'): 'You won!',\n pair==('r','p') or pair==('p','s') or pair==('s','r'): 'Computer won!'}[1]\n\nprint 'You entered: ', userPick, ', Computer entered: ', computerPick\nprint result\n</pre>", 'title': u'A more concise way'}, {'comment': u"<pre>\nimport random\nuserPick=''\nwhile userPick not in ['r', 'p', 's']:\n userPick = raw_input('\\tPlease enter (r)ock, (p)aper or (s)cissors to play... ')[0]\n\ncomputerPick= random.choice(['r','p','s']) \npair = (userPick, computerPick)\n\nresult= { pair==('r','r') or pair==('p','p') or pair==('s','s'): 'draw!',\n pair==('p','r') or pair==('s','p') or pair==('r','s'): 'You won!',\n pair==('r','p') or pair==('p','s') or pair==('s','r'): 'Computer won!'}[1]\n\nprint 'You entered: ', userPick, ', Computer entered: ', computerPick\nprint result\n</pre>", 'title': u'A more concise way'}, {'comment': u"Your example is more concise than the original poster, but not significantly more concise than Ville Tirronen's.<br><br>\n\nAlso, your method is slower over the course of long-term execution because the dictionary needs to be computed in every pass. Ville Tirronen's example mechanism is far faster in practice.", 'title': u' '}], 'desc': u" Description: Rock, Scissors, Paper Game. \n Shows a clean way of implementing a 'switch'\n statement in Python via a dictionary container. \n The dictionary is made up of known 'named states' that\n are tested in sequence for their current 'state'."}, {'comments': [], 'desc': u'You can use the regular expression engine to parse binary files, especially those for which the struct module alone is inadequate.'}, {'comments': [], 'desc': u'A find command is able to size-oriented search files. This script is searching image files by geometry.'}, {'comments': [{'comment': u'This recipe is no longer necessary. Itamar Shtull-Trauring added twisted.internet.wxreactor, which is a full-fledged reactor and runs each of Twisted and wx in timeslices. Modal dialogs (and menus, which are secretly modal dialogs) will now work on MSWindows with no additional code. Update your wx projects to use wxreactor and rejoice! :-)', 'title': u'Twisted 1.1.1 has wxreactor'}, {'comment': u"wxreactor didn't make it into Twisted 1.1.1, although judging from the twisted-users mailling looks like it'll be in 1.1.2.", 'title': u' '}, {'comment': u"I've used the wxreactor in twisted and found that the gui was too unresponsive. The solution I found that worked best was to process twisted deferred's in wxPython's OnIdle() event.", 'title': u'Use OnIdle for better responsiveness'}], 'desc': u"When using wxPython with Twisted in the way described in the Twisted docs wxPython will be stuck on menus and modal dialogs. This is due to the fact that wxPython uses private eventloops for menus and modal dialogs. You can't run Twisted cleanly in a thread (meaning without modification) and though using wxPython in a thread is possible, it's often not a viable option. Best would be to write a threaded wxreactor for Twisted which is a major project due to the internal nature of wx - using whatever GUI toolkit is available on the target platform. \nThis recipe is simple and works nicely on platforms using the select reactor (linux and windows)."}, {'comments': [], 'desc': u'A simple program using Twisted Perspective Broker and showing \nuse of Twisted Deferreds and other callback mechanisms. Start\nthe server without arguments and the client with the host\nname of the server. \n'}, {'comments': [], 'desc': u"Delegation gives us monotonous codings.\nBut, special method '__getattr__' is called when a certain object does not have the called method.\n\nThis recipe solve the tiresome coding.\nThe object should call delegated object's method by argument 'name'."}, {'comments': [{'comment': u'Has anyone tries this code ?\nI\'ve tried running it on Windows XP, and Windows 98, both using Python 2.3. It doesn\'t run on my systems.\n\n\nPython 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bi\nType "help", "copyright", "credits" or "license" for more i\n>>> import dirwalk\nTraceback (most recent call last):\n File "", line 1, in ?\n File "dirwalk.py", line 38, in ?\n p = os.path.basename(x)\n File "C:\\Python23\\Lib\\ntpath.py", line 199, in basename\n return split(p)[1]\n File "C:\\Python23\\Lib\\ntpath.py", line 163, in split\n d, p = splitdrive(p)\n File "C:\\Python23\\Lib\\ntpath.py", line 118, in splitdrive\n if p[1:2] == \':\':', 'title': u'Dirwalk- does this code even work ?'}, {'comment': u'The code is just fine, on Windows just as well as elsewhere, except for the last couple of lines in the "sample" part at the end which seem to be weirdly and hopelessly mangled. Just change the last 2 lines to:\n<br>\n<pre>\n if p[0].lower() in \'aeiou\':\n print x\n</pre>\nand everything should work.\n<br>\n<br>\nAlex', 'title': u'there just seems to be some weird typo in the last two lines'}, {'comment': u'os.walk() does similar thing in Python 2.3<br>\nBefore 2.3 there is a somewhat unintuitive os.path.walk() that needs a callback. This directory iterator is more straight forward compare to it.', 'title': u'os.walk()'}, {'comment': u'http://www.jorendorff.com/articles/python/path/index.html\nhas a module the presents file paths as iteratable objects.\ni think this does everything the script does and more. only disadvantage is that i think it uses generators so will only work on python inc them (2.3+ i think)', 'title': u'look at the path module'}, {'comment': u'If you copy with the mouse and precede the indented sample with<pre>\n if __name__ == "__main__":<br>\nThe text.source version has tabs|spaces mixture and needs much\nediting to get right.</pre>', 'title': u'Worked for me, but not text.source '}], 'desc': u'This iterator can bee used to walk through directories.'}, {'comments': [{'comment': u"Uh, where's the rest of the explanation?", 'title': u'?'}], 'desc': u"When creating daemons on Unix-like systems, it's typical to close or redirect stdin,\nstdout, and stderr. This simple recipe demonstrates that it's not quite as obvious\nas it might first appear."}, {'comments': [], 'desc': u'You have some single-toplevel Tkinter apps that you want to organize in a notebook-like fashion, associating each tab to an app, in a way which requires minimal changes in your original apps. This simple notebook class allows that, also supporting different tab orientations (TOP, BOTTOM, LEFT & RIGHT).'}, {'comments': [{'comment': u"Couldn't you do all this more portably with anydbm? I think BSDDB has some special stuff, but I can't see it showing in your recipe.", 'title': u'anydbm'}, {'comment': u"Unfortunately, the anydbm works only for tiny tables (less than 1000 records). It experiences serious data loss after a session to DB has been closed with records > 1,500. I definitely need to try the one with Berkley's solution - thank you", 'title': u'anydbm'}, {'comment': u"There is also just the regular 'bsddb', with 'btopen', 'hashopen', and 'rnopen'...as has been listed and documented in the standard library for at least 5 years. What happened to reading the global module listing to discover what is available in standard Python?", 'title': u' '}, {'comment': u'From Python 2.4 module documentation...<br><br>\n\n"http://pybsddb.sourceforge.net/ \nWebsite with documentation for the new python Berkeley DB interface that closely mirrors the sleepycat object oriented interface provided in Berkeley DB 3 and 4. <br><br>\n\nThe following is a description of the legacy bsddb interface compatible with the old python bsddb module. For details about the more modern Db and DbEnv object oriented interface see the above mentioned pybsddb URL."', 'title': u"regular bsddb with btopen etc. are now 'legacy' code"}, {'comment': u'is how to lock, unlock records and detect deadlock.\n\nthe interface is a little obtuse and comments in dbutils leaves one with little confidence.', 'title': u'what this example really needs'}], 'desc': u'Berkeley DB is an open source database. Its most important advantages are its simplicity to use and its performance.\n\nThis is an introductory example, that shows how to create a database, add new elements in it (as Key/Value pairs) and finally how to print all content of the database. The example is divided in two independent part.\n'}, {'comments': [{'comment': u'Tenemos que poner esto:\n\n if event.LeftDown():\n\n self._canvas.CaptureMouse()\n ....\n\n elif event.LeftUp():\n ...\n self._canvas.ReleaseMouse()', 'title': u'Sugerencia Python2.4, wxPython2.6'}, {'comment': u'Hi everyone!\n\nEarlier I asked a question about mouse interaction with a GUI. I have found a pretty comprehensive script that is supposed to work from http://aspn.activestate.com/ASPN/Co...n/Recipe/189744 . The problem is I\'m not to savy with classes yet and I don\'t know how to call it and use it. Can someone guide me through this, I would be pretty grateful.\n\nThe main objective would be to set the image that is loaded as the canvas of the rubberbander and output the result.\n\nSays we start with some pseudocode:\n\nroot=Tk()\nim=Image.open("filename")\n\nrubberbandscript(........)\n\nprint output\n\nroot.mainloop()\n\n\n\nThanks alot,\nJP', 'title': u'Question for implementing'}], 'desc': u'This recipe talks about how to implement rubberbanding code for canvas\nobjects in a wxPython application. Canvas classes in wxPython include\nwxPanel, wxStaticBitmap, wxGlCanvas etc.'}, {'comments': [{'comment': u'I think we can agree than this is no encryption to rely on for serious use (even if Microsoft pretends that). For hiding data in a very simple way (corresponding to placing a letter in an envelope) good old rot-13 might be simpler. It\'s certainly less code! :)\n\n<pre>\n>>> "Hello There".encode(\'rot13\')\n\'Uryyb Gurer\'\n>>> \'Uryyb Gurer\'.encode(\'rot13\')\n\'Hello There\'\n>>>\n<pre></pre></pre>', 'title': u'Python already has ROT-13!'}], 'desc': u'Recipe which can be conveniently used to obfuscate a string of data\nusing simple xor without using any key.'}, {'comments': [{'comment': u'This could grow. You should put it on sourceforge.', 'title': u'Nice'}, {'comment': u"Hi<br>\n<br>\n Thanks Noah for encouragement.<br>\n<br><br>\n I have created the project 'pdfutils'<br>\non sourceforge.net. I havent got the<br>\nconfirmation from sourceforge.net. I will<br>\npublish the details here soon.<br>\n<br><br>\nRegards<br><br>\nAnand Pillai\n\nAnand Pillai", 'title': u'Project on sourceforge'}, {'comment': u"Hi<br>\n<br>\n Thanks Noah for encouragement.<br>\n<br>\n I have created the project 'pdfutils'<br>\non sourceforge.net. I will publish the<br>\ndetails of it here and on my webpage.<br>\n<br><br>\nRegards<br>\nAnand Pillai", 'title': u'Project on sourceforge'}, {'comment': u'I got this to successfully work on my machine, but when opening the PDF, Acrobat showed a message:\n"The file is damaged but is being repaired"\n\nI copied the above code into a file.\n\nI made a text file that said:\n<pre>\n"This is a pdf test"\n</pre>\n\nI then excuted the script from a DOS window:\n<pre>\nC:\\Python>pyText2Pdf.py tmp.txt\n[] [\'tmp.txt\']\nUsing font Courier size = 10\nInput file = tmp.txt\nWriting pdf file tmp.txt.pdf ...\nWrote file tmp.txt.pdf\n</pre>\n\nI\'m using Adobe Acrobat v4.05a 1124 on a Windows 2K machine. I\'m also using Python 2.3b1\n\n<br><br>\nAlso, in your help text, you say:\n<pre>\n_Fore_ more python scripts ...\n</pre>\nI think you mean: \n<pre>\n_For_ more python scripts ...\n</pre>\n\n', 'title': u'Bug in code?'}, {'comment': u"Seems to work fine for me on Win XP Pro (SP1) with Acrobat v5.0.5.<br>\n<br>\nNice work, Anand!<br>\n<br>\nP.S. The program's help says the default tab size is 8, but it's actually initialized to 4 in the code...which I prefer, but the usage info is inaccurate.", 'title': u'Re: Bug in code?'}, {'comment': u'Hi Ppl, <br>\n<br>\nThanks for the feedback. I have fixed the documentation\n(help-string) errors and uploaded a new version.<br>\n<br>\nRegards,<br>\nABP', 'title': u'Fixed documentation errors'}, {'comment': u'If you find this useful, mail me your suggestions/ideas to improve this. :-)\n<br><br>\nAnand<br>', 'title': u'*Very important!*'}, {'comment': u'If you replace False with 0 and True with 1, it would be downward compatible with Python version 2.1.', 'title': u'compatiblity with Python 2.1'}, {'comment': u"Now that we have boolean literals in Python, I really cannot see\nwhy we should not use them for new code.\n<br>\n<br>\nIf you need to run this code with an older version of Python,\nthen do a find/replace with your favorite text editor.\n<br>\n<br>\nWhat's the use of improving Python when the new language features\ncan not be used, because they are imcompatible with the older versions \nof the language?\n", 'title': u'Backward compability'}, {'comment': u"Is it possible to extend this txt2pdf creator to also work for unicode strings?\n\nI'd like to use it with some cyrillic texts I have. The text is un UTF-8, and its easy to convert to python unicode strings.", 'title': u'Unicode support?'}, {'comment': u'hello,\n\nI have a PDF file created from post script file using ps2pdf and i have a text file which has data regarding job success.\n\nI would like to append the text file to the already created pdf file. I can convert text to pdf using this utility.\n\nNow my challenge is to combine those 2 PDFs in one using python or any other utilities which can run on linux. There is a reportlab solutions which is not free.\n\nCan you suggest or can we trick this program to append to existing PDF file?\n\nThanks in advance,\nManisha K Kode.', 'title': u'Can i append the text file to existing PDF file'}, {'comment': u'pyPDF (pure Python) can merge PDF files: http://pybrary.net/pyPdf/\n<br>\n<br>\nA few other (non-Python) utilities for joining PDF files: gs (ghostscript), pdftk and pdfjam/pdfjoin.\n', 'title': u'joining PDF files'}], 'desc': u'Python port of a very popular implementation of\ntext2pdf in the C programming language. I ported this \nto python because it could be used as a script instead \nof executable which is the case with the original program. \nMost of the options remain the same.'}, {'comments': [], 'desc': u'Extract images (jpeg/gif) from screensaver files, webshots collection files \n,powerpoints, microsoft word documents etc.'}, {'comments': [{'comment': u'There is another pure python matrix implementation at\nhttp://users.rcn.com/python/download/python.htm .\n\nIt goes beyond the basics and provides least squares\nsolutions of matrix equations, QR decompositions, eigenvalues, and curve-fitting. ', 'title': u'See Also'}], 'desc': u'This recpie defines the Matrix class, an implementation of a linear algebra matrix. Arithmetic operations, trace, determinant, and minors are defined for it.'}, {'comments': [{'comment': u'why the \'while 1: ... buffer += data\' loop? Shouldn\'t the \'read()\' return all the data? For that matter, just use pickle.load to read from a file handle. And you might want to change the "bin = 1" to use -1; the pickle interface changed slightly in 2.3.', 'title': u"reading from the gzip'ed file"}], 'desc': u'This module saves and reloads compressed representations of generic Python\nobjects to and from the disk.\n'}, {'comments': [{'comment': u"To support other platforms,\n<pre>for path in paths.split(os.pathsep):</pre>\n\nI know UNIX generally has this functionality included, but just in case you want it python-native. Now I'm wondering if the mac uses a variable called PATH...", 'title': u'Cross platform tweak'}], 'desc': u'This utility searches all the paths in a semi-colon delimited environment variable list for files matching a given filespec. By default, PATH is used for the enviroment. For example, on my computer\n\nC:\\>where note*.exe\nC:\\WINNT\\system32\\notepad.exe\nC:\\WINNT\\NOTEPAD.EXE'}, {'comments': [{'comment': u'I notice that the bodies of xcombinations, xuniqueCombinations, xselections are almost identical. We could refactor as follows:\n\n<pre>\ndef generalized(f, items, n):\n if n==0: yield []\n else:\n for i in xrange(len(items)):\n for cc in generalized(f(items, i), n-1):\n yield [items[i]]+cc\n\ndef skipIthItem(items, i):\n return items[:i]+items[i+1:]\n\ndef afterIthItem(items, i):\n return items[i+1:]\n\ndef keepAllItems(items, i):\n return items\n\ndef xcombinations(items, n):\n return generalized(skipIthItem, items, n)\n\ndef xuniqueCombinations(items, n):\n return generalized(afterIthItem, items, n)\n\ndef xselections(items, n):\n return generalized(keepAllItems, items, n)</pre>', 'title': u'A simple refactoring'}, {'comment': u'<pre>\ndef xuniqueCombinations(items, n):\n if n==0: yield []\n else:\n for i in xrange(len(items)-n+1):\n for cc in xuniqueCombinations(items[i+1:],n-1):\n yield [items[i]]+cc\n</pre>', 'title': u'A faster xuniqueCombinations algorithm'}, {'comment': u'<pre>\ndef permutations(L):\n if len(L) == 1:\n yield [L[0]]\n elif len(L) >= 2:\n (a, b) = (L[0:1], L[1:])\n for p in permutations(b):\n for i in range(len(p)+1):\n yield b[:i] + a + b[i:]\n</pre>\n\nThe above is 6x faster on my Pentium P3 3.0 GHz, Python 2.4.1.', 'title': u'Faster permutations'}, {'comment': u'I meant to say: 6x faster for computing list(permutations(range(8))).', 'title': u'Appendum'}, {'comment': u'On the last line that should have been yield p[:i] + a + p[i:] .', 'title': u'Err'}, {'comment': u'... But it only works on lists:<br>\n<pre>\ndef permutations(L):\n if len(L) <= 1:\n yield L\n else:\n a = [L.pop(0)]\n for p in permutations(L):\n for i in range(len(p)+1):\n yield p[:i] + a + p[i:]\n</pre>', 'title': u'much faster...'}, {'comment': u'<pre>\nUnfortunately, it\'s a very poor example. The terminology is\nall wrong.\n\n"xpermutations takes all elements from the sequence, order matters."\nThis ought to be the Cartesian Product, but it\'s not (no replacement).\n\n"xcombinations takes n distinct elements from the sequence, order\nmatters."\nIf order matters, it\'s a PERMUTATION, period.\n\n"xuniqueCombinations takes n distinct elements from the sequence,\norder is irrelevant."\nNo such thing, a Combination is unique by definition.\n\n"xselections takes n elements (not necessarily distinct) from the\nsequence, order matters."\nAh, this allows a size operator, so if size = length, we get full\nCartesian Product.\n\nThe proper terminology for the Cartesian Product and\nits subsets is:\n\nPermutations with replacement\nCombinations with replacement\nPermutations without replacement\nCombinations without replacement\n\nAnd if the functions were properly labeled, you would get:\n\n permutation without replacement - size 4\n\nPermutations of \'love\'\nlove loev lvoe lveo leov levo olve olev ovle ovel oelv oevl vloe vleo\nvole voel velo veol elov elvo eolv eovl evlo evol\n\n\n permutation without replacement - size 2\n\nCombinations of 2 letters from \'love\'\nlo lv le ol ov oe vl vo ve el eo ev\n\n\n combination without replacement - size 2\n\nUnique Combinations of 2 letters from \'love\'\nlo lv le ov oe ve\n\n\n permutation with replacement - size 2\n\nSelections of 2 letters from \'love\'\nll lo lv le ol oo ov oe vl vo vv ve el eo ev ee\n\n\n full Cartesian Product, permutations with replacement - size 4\n\nSelections of 4 letters from \'love\'\nllll lllo lllv llle llol lloo llov lloe llvl llvo llvv llve llel lleo\nllev llee loll lolo lolv lole lool looo loov looe lovl lovo lovv love\nloel loeo loev loee lvll lvlo lvlv lvle lvol lvoo lvov lvoe lvvl lvvo\nlvvv lvve lvel lveo lvev lvee lell lelo lelv lele leol leoo leov leoe\nlevl levo levv leve leel leeo leev leee olll ollo ollv olle olol oloo\nolov oloe olvl olvo olvv olve olel oleo olev olee ooll oolo oolv oole\noool oooo ooov oooe oovl oovo oovv oove ooel ooeo ooev ooee ovll ovlo\novlv ovle ovol ovoo ovov ovoe ovvl ovvo ovvv ovve ovel oveo ovev ovee\noell oelo oelv oele oeol oeoo oeov oeoe oevl oevo oevv oeve oeel oeeo\noeev oeee vlll vllo vllv vlle vlol vloo vlov vloe vlvl vlvo vlvv vlve\nvlel vleo vlev vlee voll volo volv vole vool vooo voov vooe vovl vovo\nvovv vove voel voeo voev voee vvll vvlo vvlv vvle vvol vvoo vvov vvoe\nvvvl vvvo vvvv vvve vvel vveo vvev vvee vell velo velv vele veol veoo\nveov veoe vevl vevo vevv veve veel veeo veev veee elll ello ellv elle\nelol eloo elov eloe elvl elvo elvv elve elel eleo elev elee eoll eolo\neolv eole eool eooo eoov eooe eovl eovo eovv eove eoel eoeo eoev eoee\nevll evlo evlv evle evol evoo evov evoe evvl evvo evvv evve evel eveo\nevev evee eell eelo eelv eele eeol eeoo eeov eeoe eevl eevo eevv eeve\neeel eeeo eeev eeee\n\n\nAnd Combinations with replacement seems to be missing.\n</pre>', 'title': u'Wrong terminology'}], 'desc': u"Permutations and combinations are often required in algorithms that do a complete search of the solution space. They are typically rather large so it's best not to compute them entirely but better to lazily generate them.\nThis recipe uses Python 2.2 generators to create appropriate generator objects,\nthat can be use for example as ranges in for loops. "}, {'comments': [{'comment': u'Neat and simple recipe. I have a rather minor suggestion: since you don\'t need the "x" index, why not simply use "for file in files:" instead of "for x in range(...): file=files[x]"?', 'title': u'Nitpicking'}, {'comment': u'Nice suggestion.Actually the<br>\n"for x in range(0, len(..))" comes<br> \nmore out of habit than anything else :-)<br>\n<br><br>\nThanks<br>\n<br>\nAnand Pillai<br>', 'title': u'Re: Nitpicking'}, {'comment': u'I added a few lines to the original recipe to avoid backing up files that have not been modified since the previous backup. Here\'s the complete code:\n\n<pre>\n#! /usr/bin/env python\n#backup.py - backup versions of python source files\nimport sys, os\nfrom shutil import copy\nfrom string import lower\nfrom filecmp import cmp\n\ntargetdir=""\ntry:\n targetdir=sys.argv[1]\nexcept:\n targetdir="."\n \nfiles=os.listdir(targetdir)\n\n#Backup directory\nfor file in files:\n ext=lower((os.path.splitext(file))[1])\n \n if ext in (\'.py\', \'.ht\'):\n abspath=os.path.abspath(os.path.join(targetdir, file))\n print \'Backing up file \', file ,\'...\'\n #check for existence of previous versions\n index=0\n while os.path.exists(abspath + \'.bak.\' + str(index)):\n index += 1\n if not index==0:\n #no need to backup if file and last version are identical\n if cmp(abspath, abspath + \'.bak.\' + str(index-1), shallow=False):\n continue\n copy(abspath, abspath + \'.bak.\' + str(index))\n</pre>', 'title': u'Change recipe to avoid unnecessary backups'}, {'comment': u'Added the above suggestion to the recipe.\n\nAnand', 'title': u'Recipe updated'}, {'comment': u"Modified recipe to copy files to a directory<br>\nnamed 'bak' in the current directory. Also<br>\nmade to work on the entire tree than cwd.<br> \n<br>\n<br>\nAnand", 'title': u'Modified recipe'}, {'comment': u'I have made slight adjustments to this function:<br>\n- made types an optional parameter, with default value None meaning all types<br>\n- added files parameter to initail (non-recursive) backup call, \n to allow specifying files explicitly<br>\n- removed variable "bakuppath" (i was getting an error) and using "bakup" for copy()<br>\n<br>\nThe new backup(), modified in this way, becomes: \n\n<pre>\ndef backup(dir, types=None, files=None):\n "Back up files or files with extension in passed tuple types"\n\n if files is None:\n files=os.listdir(dir)\n\n # Backup directory\n for file in files:\n abspath = os.path.abspath(os.path.join(dir, file))\n\n if os.path.isfile(abspath):\n ext=lower((os.path.splitext(file))[1])[1:]\n if types is None or ext in types:\n # check for existence of previous versions\n index=1\n \n # create directory named \'bak\' in current directory\n newdir = os.path.join(dir, \'bak\')\n if not os.path.exists(newdir):\n os.makedirs(newdir)\n \n while 1:\n if index > MAXVERSIONS: \n break\n bakup = os.path.join(newdir, file + \'.bak.\' + str(index))\n if not os.path.exists(bakup): \n break\n index += 1\n \n if index>1:\n # no need to backup if file and last version are identical\n oldbakup = os.path.join(newdir, file + \'.bak.\' + str(index-1))\n try:\n if os.path.isfile(oldbakup) and cmp(abspath, oldbakup, shallow=0):\n print \'File \', file, \': file is unchanged\'\n continue\n except OSError, e:\n pass\n\n print \'Backing up file \\t\', file ,\' Version:\', index\n try:\n copy(abspath, bakup)\n except OSError, e:\n pass\n \n elif os.path.isdir(abspath):\n backup(abspath, types)\n pass\n</pre>', 'title': u'Ability to specify files by name'}, {'comment': u'Will break horribly if any of the backup files are not regular file types. Eg. fifo.', 'title': u'Will break horribly...'}], 'desc': u'Makes backup versions of files'}, {'comments': [{'comment': u"The example code doesn't execute -- there is no method <pre>ATTAlerter\n</pre> in the class.\n\nThe correct line should be: <pre>\nalerter = ATTAlerter('###-###-####','Test Message','Python Script')\n</pre>\n\nEven cooler when it works. :)", 'title': u"Example code doesn't execute"}, {'comment': u'Sorry I tested it with a seperate module, pasted the code in from there.', 'title': u'True that...'}, {'comment': u'You can also send a simple email to ##########@mobile.att.net for the same effect.', 'title': u'Email acccess to SMS'}], 'desc': u'This is a little class I banged together so I could have my app send me alerts on my cell phone. This could work for any provider but the only way to figure out what fields it wants is to go to the messaging page and search throught the source. Have fun with this, this class could be made really cool if it worked for all the major providers.'}, {'comments': [], 'desc': u"I've often needed to take out or reorder the columns in a list of lists. I'm embarrased to say it took me a while to think of this, it's so simple, but I looked around and have not found any examples of it, so..."}, {'comments': [{'comment': u'I was wondering if there is a lybrary that makes it easier to generate XML excel sheets with python.', 'title': u'I would like to do the contrary.'}, {'comment': u'<pre>\nTraceback (most recent call last):\n File "H:\\XML_Parser.py", line 5, in ?\n class ExcelHandler(saxutils.DefaultHandler):\nAttributeError: \'module\' object has no attribute \'DefaultHandler\'\n</pre>', 'title': u'Error'}, {'comment': u'Add "handler" to the "from xml.sax import" line.\n\nChange "saxutils.DefaultHandler" to "handler.ContentHandler".\n\nThen it works with Activestate\'s Python 2.4.', 'title': u'Needs to be updated for current Python'}], 'desc': u"This script parses an MS-Excel spreadsheet saved as XML.\n\nThe spreadsheet:\na1, b1\na2, b2\n\nwill be stored like this:\n\n[[u'a1', u'b1'], [u'a2', u'b2']]"}, {'comments': [{'comment': u'This code is wide open to race conditions. There are other, also portable, alternatives.', 'title': u'Race conditions'}], 'desc': u"this lock files by the use of lockfiles (IE a .lock appended to the locked file) very simple - supports directory locking and doesn't handle pids (though you're able to recieve and store them)"}, {'comments': [{'comment': u'I believe the function\n<pre>\nshutil.rmtree(path[, ignore_errors[, onerror]]) \n</pre>\ndoes the same thing. ', 'title': u'Check out the shutil module'}, {'comment': u"Yes, the shuti.rmtree() function does the same thing. But, the recipe supplied could be useful if you need to only delete files based on whether they meet some condition - in that case you don't want to just blow them all away with a single expression. \n\nS", 'title': u'yes, that works'}, {'comment': u'Although it is true you can use shutil.rmtree() in many cases, there are some cases where it does not work. For example, files that are marked read-only under Windows cannot be deleted by shutil.rmtree(). By importing the win32api and win32con modules from PyWin32 and adding line like "win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL" to the rmgeneric() function, this obstacle can be overcome. I used this approach to fix the hot-backup.py script of Subversion 1.4 so it will work under Windows. Thank you for the recipe.', 'title': u'shutil.rmtree has its shortcomings'}], 'desc': u'This recipe can be used to clean up a directory tree\nirrespective of whether the directory tree contains\nnon-empty directories. As long as the user has permission\nto remove the files, this will work.'}, {'comments': [{'comment': u'I tried your tip. But not runned well. So I wrote corresponded to version 0.2 tip. See also below code.\n\n<pre>-- begin code.\n\nfrom docutils import core\nfrom docutils.writers.html4css1 import Writer, HTMLTranslator\nfrom docutils.readers.standalone import Reader\nfrom docutils.parsers.rst import Parser\n\nclass NoHeaderHTMLTranslator(HTMLTranslator):\n def __init__(self, document):\n HTMLTranslator.__init__(self, document)\n self.head_prefix = [\'\',\'\',\'\',\'\',\'\']\n self.body_prefix = []\n self.body_suffix = []\n self.stylesheet = []\n\nclass Publisher(core.Publisher):\n def publish(self, data):\n self.set_options()\n self.options.stylesheet = \'\'\n self.options._destination = \'\'\n\n parser = Parser()\n reader = Reader(parser, None)\n writer = Writer()\n writer.translator_class = NoHeaderHTMLTranslator\n iodata = core.io.StringIO(self.options, source=data)\n xmldata = reader.read(iodata, parser, None)\n xmldata.options = self.options\n return writer.write(xmldata, iodata)\n\ndef reSTify(s):\n return Publisher().publish(s)\n\nif __name__ == \'__main__\':\n test = """\nTest example of reST__ document.\n\n__ http://docutils.sf.net/rst.html\n\n- item 1\n- item 2\n- item 3\n\n"""\n print reSTify(test)\n\n-- end of code.</pre>\n\nSo generate below HTML.\n<pre><div class="document">\n<p>Test example of <a class="reference" href="http://docutils.sf.net/rst.html">reST</a> document.</p>\n<ul class="simple">\n<li>item 1</li>\n<li>item 2</li>\n<li>item 3</li>\n</ul>\n</div></pre>', 'title': u'Is it version 0.2?'}, {'comment': u'I had a mistake. It seems that I downloaded the older thing.', 'title': u'Hmm, I had mistake.'}, {'comment': u'It seems that that is not right although considered. Your tip will operate, if it is somewhat old CVS revision.', 'title': u'It corrects'}, {'comment': u"A disadvantage of the method posted above is that it preserves the header while stripping it of context. Items that would be rendered as h1 in ReST also get rendered as title.\n\nThe function that finally writes out the page is the astext function. In the normal version, a bunch of lists are concatenated together, but we only care about the self.body list for our snippet. Thus we can avoid modifying any initialization steps and instead override the astext function, making our modification much simpler :\n\n<pre>\nclass NoHeaderHTMLTranslator(HTMLTranslator):\n def astext(self):\n return ''.join(self.body)\n</pre>\n\nThe rest of the recipe remains the same.", 'title': u'Easier method for using ReST'}, {'comment': u'And if you add\n\n<pre>\ndef visit_document(self, node):\n self.body.append(self.starttag(node, \'div\', CLASS=\'whatever\'))\n</pre>\n\nto the NoHeaderHTMLTranslator class, you can control the div class. "document" is a bit awkward if you only include snippets.', 'title': u'Controlling class'}, {'comment': u"There's now an official API (in CVS, as of version 0.3.2) that does this: docutils.core.publish_parts() (see the docstring for details). There's also a new module, docutils.examples, that exposes practical examples of Docutils client code, to be used as-is or as models for variations.<br>\n<br>\nA development snapshot is always available here:<br>\nhttp://docutils.sf.net/docutils-snapshot.tgz", 'title': u'Official API now exists'}], 'desc': u'This small recipe allows you to convert a reST text to HTML without creating a full HTML document but returning only a snippet that you can then put anywhere on a web page.'}, {'comments': [{'comment': u'I believe there is an error in code, it should be::\n\n<pre>\n w1, w2 = w2, word\n\ntable.setdefault( (w1, w2), [] ).append(nonword) # Mark the end of the file\n\n# GENERATE OUTPUT\n</pre>', 'title': u'an error in code?'}, {'comment': u'Some quick hacks to output sentences. Could have used a regular expression split (from re) instead of the \'if\' but this was easy, worked, and ran fast enough.\n<br><br>\nProblems and todo<br>\n- things like "Dr." are not the end of sentence<br>\n- quotes, brackets and other punctuation<br>\n- paragraphs, chapters <br>\n<br>\nSeems like using a parser would be the right way to proceed if trying to do all of the above. \n<br><br>\nExamples from Gutenbergs "Tao de Ching"\n<pre>\nProject Gutenberg to get the kingdom by force of arms.\n\nOnly he who overcomes himself is intelligent.\n\nHe who knows these two things finds in them ensued (in the same way) to accomplish the greatest things.\n\nTrees and plants, in their ordinary life; let them not thoughtlessly indulge themselves in their early growth, are soft and weak than water, and yet these are the designations which kings and princes use for themselves.\n\n\nimport random;\nimport sys;\n\nstopword = "\\n" # Since we split on whitespace, this can never be a word\nstopsentence = (".", "!", "?",) # Cause a "new sentence" if found at the end of a word\nsentencesep = "\\n" #String used to seperate sentences \n\n\n# GENERATE TABLE\nw1 = stopword\nw2 = stopword\ntable = {}\n\nfor line in sys.stdin:\n for word in line.split():\n if word[-1] in stopsentence:\n table.setdefault( (w1, w2), [] ).append(word[0:-1])\n w1, w2 = w2, word[0:-1]\n word = word[-1]\n table.setdefault( (w1, w2), [] ).append(word)\n w1, w2 = w2, word\n# Mark the end of the file\ntable.setdefault( (w1, w2), [] ).append(stopword) \n\n# GENERATE SENTENCE OUTPUT\nmaxsentences = 5\n\nw1 = stopword\nw2 = stopword\nsentencecount = 0\nsentence = []\n\n#note replace lessthan with the symbol\n# I was having trouble with aspn commets \nwhile sentencecount lessthan maxsentences: \n newword = random.choice(table[(w1, w2)])\n if newword == stopword: sys.exit()\n if newword in stopsentence:\n print "%s%s%s" % (" ".join(sentence), newword, sentencesep)\n sentence = []\n sentencecount += 1\n else: \n sentence.append(newword)\n w1, w2 = w2, newword\n</pre>', 'title': u'Not so minor changes to have sentence structured output.'}], 'desc': u'A classic algorithm which can produce entertaining output, given a sufficiently large input'}, {'comments': [{'comment': u'It is quite possible in python to compare strings against integers or other non strings. So in __cmp__ and __eq__ I have added a try:except block around the current line, and in the except part put the same line but without the call to lower() (as it is this that raises the exception). e.g.\n<pre>\ndef __cmp__(self, other):\n try:\n return cmp(self.__lowerCaseMe, other.lower())\n except:\n return cmp(self.__lowerCaseMe, other)\n</pre>', 'title': u'Make less restrictive to be more like python strings'}, {'comment': u'Use a case-insensitive dictionary instead.', 'title': u'Terrible idea'}], 'desc': u'This is a class you use in place of a string and it emulates a string in all practical ways except that comparisons and lookups are case insensitive. All uses of the string for assignments, however, yield the original case.'}, {'comments': [], 'desc': u'This extracts all of the To addresses from a file in standard mbox format.\nIt is used on a "Sent Items" mailbox to build an address white list.\nPresumably everyone you send email to is a candidate for an email white list.\n'}, {'comments': [{'comment': u'How is that better than multiple string.replaces? I tried it against this:\n<pre>\ndef mreplace2(s, chararray, newchararray):\n for a, b in zip(chararray, newchararray):\n s = s.replace(a, b)\n return s\n</pre>\nAnd it was a lot slower :P', 'title': u'hew'}, {'comment': u"There's this magical little thing call string.translate that does EXACTLY what both of you want.\n\n<pre>\nimport string\ndef mreplace3(s, chars, newchars):\n return s.translate(string.maketrans(chars, newchars))\n</pre>\n\nRunning this on 512k of random data, translating all 256 characters (chr(0) becomes chr(255), chr(1) becomes chr(254), etc.), the times to execute on my PII-400 are:<br>\nmreplace: 39.2030000687<br>\nmreplace2: 8.39099991322<br>\nmreplace3: 0.0149999856949<br><br>\n\nI believe translate is a C function call. Could be why it beats the other two by factors of almost 3000 and 600 respectively.", 'title': u'Something that is included AND better.'}, {'comment': u'There are differences in these algorithms. The maketrans() function requires that the characters mapped are the same length. The replace() function has no such requirement.', 'title': u'Not the same'}], 'desc': u'A hack to quickly replace multiple\ncharacters/strings in a string with\ncharacters from another string.'}, {'comments': [{'comment': u'<pre>\n>>> a = u\'α\'\n>>> a\nu\'\\xce\\xb1\'\n>>> print urllib.urlopen(a)\nTraceback (most recent call last):\n File "", line 1, in ?\n File "/usr/lib/python2.3/urllib.py", line 76, in urlopen\n return opener.open(url)\n File "/usr/lib/python2.3/urllib.py", line 154, in open\n fullurl = unwrap(toBytes(fullurl))\n File "/usr/lib/python2.3/urllib.py", line 939, in toBytes\n raise UnicodeError("URL " + repr(url) +\nUnicodeError: URL u\'\\xce\\xb1\' contains non-ASCII characters\n\nα should become %CE%B1 right?\nit\'s UTF-8: 0xCE 0xB1\n</pre>', 'title': u'uri_convert: cannot get it to work'}, {'comment': u'thank you', 'title': u'please remove the above comment'}], 'desc': u'Usually, although they are a character sequence, all the arguments when starting a program are making it a special format, and if they change an argument into various models and pass it, they are convenient.'}, {'comments': [], 'desc': u'Dependencies 1) Windows Machine, 2) Python2.2 with win32 extensions installed 3) Apache Webserver for win32\nThis code queries the Northwind Database\'s "Order Details" Table..Make sure the path of the DB is correct and the query u are using is also accurate cause this does not give any error outputs but writes it in Apache\'s error.log file...\ncopy this file in the cgi-bin directory and call it from the web browser as http://localhost/cgi-bin/ADO.py (file name). The only problem is the currency field, I cannot obtain the currency field properly it is obtained as a tuple !! hope u can help me ! :)'}, {'comments': [], 'desc': u'The MultiThread module provides a simple abstraction to execute a function on many sets of arguments in parallel using a bounded pool of threads.\n'}, {'comments': [], 'desc': u"The SpawnedGenerator class, initialised with a generator, will run that generator in a separate thread and either yield successive values obtained from it (when called) or let you iterate itself to get the same results. It's mainly useful for tasks which make blocking OS calls, e.g. traversing directory structures. The queue size may be specified to limit how far ahead of the main task the spawned generator can get. "}, {'comments': [{'comment': u'Why are you looping in the first two functions, waiting for kbhit()? Calling getch() should do the trick already.', 'title': u'Busy waiting'}, {'comment': u"Using mscvrt.kbhit() allows me to hit CNTL-C to abort a function. But you're right that it's not necessary to use it in conjunction with getch().\n\nRobert", 'title': u' '}], 'desc': u'Three functions useful for acting upon a key pressed in a Windows text only console application. Typical usage would be in the design of menu selections and escaping from loops.'}, {'comments': [], 'desc': u'Provides a mergeiter() function that can merge two iterators into a single iterator. Uses generators, and guarantees constant memory use.'}, {'comments': [{'comment': u'This a very good solution. I like it at least as much as my own.<br>\nSean Ross', 'title': u' '}, {'comment': u"Nice example of how metaclasses work.\n\nIt can be simplified a bit by eliminating the nested getmethod() helper function and replacing for-loop with:\n<pre>\nfor name,default in readonly.items():\n classdict[name] = property(lambda self, x=default:x)\n</pre>\n\nThough it is an instructive metaclass example, it isn't actually an improvement over non-metaclass code. The following is shorter, clearer, simpler, and faster.\n\n<pre>\ndef readonly(value):\n return property(lambda self: value)\n\nclass ROClass(object):\n a = readonly(1)\n b = readonly('text')\n</pre>", 'title': u'Simplified a bit and contrasted with non-metaclass programming'}, {'comment': u"One shortcoming of this solution is that the read-only properties that are created are not associated with any instance attributes. \nGenerally, the reason you would use a property is so that you can control how the values of your instance attributes are exposed to users of your classes. Since your read-only properties have no instance attribute association, what's being created here are, essentially, class constants. This is fine, if this is all you're looking for. However, you are losing part of the benefit of having a read-only property.<br>\nBy creating your read-only properties with an association to an instance attribute you remain able to change the value that property will return. For example, if you have a read-only property foo and it is associated with a private instance variable __foo, i.e. instance.foo returns the value of instance._classname__foo, then if the value of __foo is changed by some internal operation, say in some other method call, then the value returned by subsequent calls to instance.foo will also change. In other words, instance.foo is no longer just a constant, it's read-only, and these two things are not the same.<br>\nOf course, you could change the value of instance.__readonly__['foo'], internally, to accomplish the above behaviour. Still, why not just have instance.__foo available, if you want/need it?", 'title': u' '}, {'comment': u'<pre>\nIt is better to replace \n\ntype.__new__(cls,classname,bases,classdict)\n\nwith\n\nsuper(metaClass,cls).__new__(cls,classname,bases,classdict)\n\nin the case you anticipate to compose your metaclass \nwith another metaclass one via multiple inheritance. Also, \nI like to call the first argument of the metaclass __new__ \nmethod "meta" and not "cls", which is actually confusing,\nunless you are in the __init__ method. Actually, you could\nuse __init__ instead of __new__; it would work the same, but \nI feel that __init__ is somewhat simpler than __new__. Just \nmy 0.02 cents\n\n Michele\n\n</pre>', 'title': u'Make __new__ cooperative'}, {'comment': u'That\'s actually quite a nice point. ALL examples I\'ve ever encountered ware doing the "magic" stuff within the __new__ method of the metaclass. Since a class is more or less an instance of its metaclass, it might be better to use __init__ instead of __new__ as __init__ is much more natural for most python programmers.', 'title': u'Excelent point'}, {'comment': u'In this example __new__ and __init__ would be interchangeable, but\nin general overriding ``__init__`` has severe limitations with \nrespect to overriding ``__new__``, since the \'name\', \'bases\' and \n\'dic\' arguments cannot be directly changed. Let me show an example:\n\n<pre>\n\n from oopp import *\n\n class M(type):\n "Shows that dic cannot be modified in __init__, only in __new__"\n def __init__(cls,name,bases,dic):\n name=\'C name cannot be changed in __init__\'\n bases=\'cannot be changed\'\n dic[\'changed\']=True\n\n class C(object):\n __metaclass__=M\n changed=False\n\n print C.__name__ # => C\n print C.__bases__ # => (,)\n print C.changed # => False\n\n</pre>\n\nThe output of this script is ``False``: the dictionary cannot be \nchanged in the ``__init__`` method. However, replacing ``dic[\'changed\']=True`` with \n``cls.changed=True`` would work. Analougously, changing ``cls.__name__`` would work. On the other hand, ``__bases__`` \nis a read-only attribute and cannot be changed once the class \nhas been created, therefore there is no way it can be touched in ``__init__``. Nevertheless, ``__bases__`` could be\nchanged in ``__new__`` before the class creation.\n\nThese are the reasons why often people prefer __new__ over __init__.\n\n\n Michele ', 'title': u'__new__ vs __init__ in metaclasses'}, {'comment': u"I have an implementation that does something similar; it's actually a write-once implementation, since you have to set the value at least once. It doesn't use metaclasses, but instead uses a descriptor (similar to property):\n\nhttp://blog.colorstudy.com/ianb/weblog/2004/07/15.html#P131", 'title': u'Alternative descriptor implementation'}, {'comment': u'http://blog.colorstudy.com/ianb/weblog/2004/07/15.html#P131\n<br><br>\n==> Ianb/weblog/2004/07/15 \n<br>\n This page has not yet been created.', 'title': u'missing page'}], 'desc': u'This recipe is a rewrite of a portion of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/157768 .\nIt shows an easy way to write read-only attributes with the help of meta classes. '}, {'comments': [{'comment': u'You can perform the same task on the fly, on any object, without metaclasses. This means you can reroute object methods from outside the object itself. Just reproduce the body of LogTheMethods in a "normal" function. The only bit you need to change is, instead of assigning classdict[attr] = logmethod(attr), you use new.instancemethod(function, instance, class)\n\n<pre>if callable(item):\n anInstance = item.im_self\n attr = item.__name__\n anInstance.__dict__[\'_H_%s\' % attr] = item\n anInstance.__dict__[attr] = \\\n new.instancemethod(logmethod(attr),\n anInstance,\n anInstance.__class__)</pre>\n\nIn this example, I rewrote the block so that one needs only pass in a reference to any method, and the other properties are introspected. I use this technique to "lock" object methods at runtime: accessing the original method requires a corresponding key. None of the locked objects need a metaclass defined, or __metaclass__ declared.', 'title': u'Non-metaclass solution'}], 'desc': u'A metaclass is used to wrap all (or just some) methods for logging purposes. The underlying mechanism can be used as well to check pre/post conditions, attribute access,...\nThe basic point is, that the actual class must not be changed in any way to achive the desired effect. '}, {'comments': [], 'desc': u'Reduce average dictionary lookup time by making the internal tables more sparse.'}, {'comments': [], 'desc': u'It is not so easy to put template engine and the template itself together, and to separate logic and a template. This example should define the value substituted for the slot of the easy source code for using template engine, the function of template engine, a template, and a template, and they should operate well by calling using render function.\n\nBelow is an e-mail generate and sendings.'}, {'comments': [{'comment': u'Add the following def to onemax.py<br>\n<pre>\ndef sum(seq):\n def add(x,y): return x+y\n return reduce(add, seq, 0)\n</pre>\nand replace in genetic.py the line<br>\n<pre>class Individual(object):</pre>\n\nwith<br>\n\n<pre>\nclass Individual:\n chromosome = None\n score = None\n</pre>', 'title': u'Changes to make code executable'}], 'desc': u' '}, {'comments': [{'comment': u"<br>If you don't want to loose the elements in the longer lists,\n<br>you can pad the short ones with the following:\n<br>\n<pre>\ndef pad(l, padding=None):\n\t'''Add padding to short lists to make all \n\tlists in l have the same length.'''\n\n\tlengths = [len(li) for li in l]\n\tbig = max(lengths)\n\tif lengths.count(big)<br>If you don't want to loose the elements in the longer lists,\n<br>you can pad the short ones with the following:\n<br>\n<pre>\ndef pad(l, padding=None):\n\t'''Add padding to short lists to make all \n\tlists in l have the same length.'''\n\n\tlengths = [len(li) for li in l]\n\tbig = max(lengths)\n\tif lengths.count(big)</pre></pre>", 'title': u'you can pad the lists to prevent truncation'}, {'comment': u'... like described in this recipe:\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410687', 'title': u'... or you can use map to pad automatically ...'}], 'desc': u'By using the zip builtin function you can easily convert a list of lists into a transposed list of tuples. \nThis can be used for easily selecting columns.'}, {'comments': [{'comment': u'Does this have any advantage over the os.path.walk()<br>\nfunction<br>?\n<br><br>\nThanks<br><br>\n-Anand', 'title': u'Any advantages'}, {'comment': u'Does this have any advantage over the os.path.walk()<br>\nfunction<br>?\n<br><br>\nThanks<br><br>\n-Anand', 'title': u'Any advantages'}, {'comment': u"I am working on a framework/toolkit for file management (okay, here's a plug for it: pyfmf.sourceforge.net/default.html). I'm going to use some of the code in this recipe to generate an HTML listing. Thanks! I'll make sure to put in a credit for you, Peter.", 'title': u'I will use it'}, {'comment': u'I needed to retrieve all files named note[0-9]*.txt.\n\nBased on your work it is as below:\nI\'ve retained your function names for comparison.\n\nMany thanks. Much appreciated.\n\n<pre>\nimport sys\n\ndef walktree(top = ".", depthfirst = True):\n """Walk the directory tree, starting from top. Credit to Noah Spurrier and Doug Fort."""\n import os, stat, types\n names = os.listdir(top)\n if not depthfirst:\n yield top, names\n for name in names:\n try:\n st = os.lstat(os.path.join(top, name))\n except os.error:\n continue\n if stat.S_ISDIR(st.st_mode):\n for (newtop, children) in walktree (os.path.join(top, name), depthfirst):\n yield newtop, children\n if depthfirst:\n yield top, names\nimport re \n\ndef makeHTMLtable(top,filePattern, depthfirst=False):\n from xml.sax.saxutils import escape # To quote out things like &\n ret = [\'\\n\']\n for top, names in walktree(top):\n ret.append("%s\\n" %escape(top))\n for name in names:\n if (re.match(filePattern,name) is not None):\n ret.append(\'\\t%s\\n\'%escape(name))\n return \'\'.join(ret) # Much faster than += method\n\ndef makeHTMLpage(top, depthfirst=False):\n return \'\\n\'.join([makeHTMLtable(top, depthfirst)])\n \nprint makeHTMLpage("/home/dpawson/enotes/","note[0-9]*.txt$")\n</pre>', 'title': u'A slight modification'}, {'comment': u'I have a need for something similar in a documentation exercise.\nIf this code was refactored to use HTMLgen, that would be even better for future reporting possibilities, re. graphical extras such as bar charts, etc.', 'title': u'HTMLgen'}], 'desc': u'Walk a directory path, listing the files and directories in HTML format.'}, {'comments': [{'comment': u"Hi Sebastien,\nThis is not a comment but a pointer to a comment i made to your great recipe for Design by Contracts. I make it here because the odds are greater that you consult this page rather than the other one and i am quite in a hurry. The problem is that your recipe doesn't seem to work on overridden inherited method. \nKeep the good work!", 'title': u'Eiffel Contracts in Python'}], 'desc': u'Eiffel like loop variant assertion'}, {'comments': [], 'desc': u'Use reflection to generate lists of Python symbols. Use them to build a syntax coloring file for your preferred programmer\'s editor.\n\nThis is easier and less error-prone than updating your syntax file by reading "What\'s New In Version x" and other documentation.'}, {'comments': [{'comment': u'Idea: To avoid type checks, it might be possible to adapt Raymond Hettinger\'s "Metaclass for Interface Checking" recipe described at:<br><br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204349<br><br>\nto determine if something was "close enough" to a list/tuple/dict etc.', 'title': u'Interface Checking'}, {'comment': u'<pre>\n$ python\n>>> from mx import DateTime\n>>> print DateTime.now().ticks()\n# prints "1140120746.088465" (today is 2006-02-15)\n^D\n$ smjs # spidermonkey JS interpreter\n// let\'s parse the value we got from mx.DateTime.ticks() \njs> print(new Date(1140120746.088465));\n// prints "Wed Jan 14 1970 06:42:00 GMT+0200 (SAST)"\n// oops! how about:\njs> print(new Date(1140120746.088465 * 1000));\n// prints "Thu Feb 16 2006 22:12:26 GMT+0200 (SAST)",\n// which is right\n</pre>', 'title': u'Bad Date() Marshalling?'}], 'desc': u'When writing web applications with an application framework like SkunkWeb, it is sometimes desirable to make Python data available to client-side Javascript. This recipe creates a function, to_js, that marshals Python data into a Javascript string.'}, {'comments': [], 'desc': u'whoaminow() can be used inside a function to determine, at the time it is called, the name under which that function has been invoked.\n\nNOTE: This solution is *extremely* brittle and provides very limited utility, as it stands. However, it does serve to highlight an interesting avenue for introspection, namely, the dis module.'}, {'comments': [], 'desc': u' '}, {'comments': [{'comment': u"# based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/157572<br>\ndef __update__(include=[], exclude=[]):<br>\n    import inspect<br>\n    args, varargs, varkw, defaults = inspect.getargvalues(inspect.stack()[1][0])<br>\n    self = defaults[args[0]]<br>\n    if not include:<br>\n        include = args[1:] # skip 'self'<br>\n        if varkw:<br>\n            include.extend(defaults[varkw].keys())<br>\n            defaults.update(defaults[varkw])<br>\n    for attrname in include:<br>\n        if attrname not in exclude:<br>\n            setattr(self, attrname, defaults[attrname])<br>\n<br>\n# useage<br>\nclass c:<br>\n    def __init__(self, a, b, c=3, **kwargs):<br>\n        __update__()<br>\n<br>\nI think the name __update__ works here for two reasons:<br>\n<br>\n1. The leading and trailing double underscores let users know that there's something special happening, and<br>\n<br>\n2. what this method is doing is updating the dictionary of an instance with another dictionary made up of key/value pairs from __init__'s parameter list, i.e., something like this is going on:<br>\n    self.__dict__.update(initparamsdict)<br>\n<br>\nSo, since what we're doing is updating a dictionary, in a special way, and the method to do that is called 'update', it seems like '__update__' would be a reasonable name. Other naming suggestions include 'selfupdate()' or 'self_set()' [Alex Martelli - Python Cookbook p.106].<br>\n", 'title': u'A more magical version'}, {'comment': u"Sometimes, when you want to be quick and dirty, and when you're not using *arguments or **keywords, you can use the built in vars(), instead of params():<br>\n<br>\nclass c:<br>\n    def __init__(self, a, b, c=3):<br>\n        self.__dict__.update(vars())<br>\n<br>\nYou just have to use it before you bind any other variables inside __init__(), and you need to be aware that each of your instances will have an attribute 'self' that is bound to that instance.\ne.g.<br>\n>>>x = c(1,2)<br>\n>>>x.self<br>\n<__main__.c instance at 0x014F9100\\><br>\n>>> x<br>\n<__main__.c instance at 0x014F9100\\><br>\n<br>\nIt's up to you.", 'title': u'Sometimes you could just use vars()'}, {'comment': u"Now that I've had time to think about it, I don't care for __update__ (too magical)", 'title': u'nevermind'}], 'desc': u'This recipe is based on\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/157572.\n\nCalling parameters() inside a function will return that function\'s\nparameters as a dictionary. The dictionary does not include *varargs,\nsince *varargs items do not have a "name" that can be used as a key.\nHowever, **varkw is added to the dictionary, as an update.\n\nThere are three optional parameters that can be used to filter the\ninformation returned.'}, {'comments': [], 'desc': u'some simple functions for dynamically adding methods, properties,and classmethods to classes at runtime'}, {'comments': [], 'desc': u'We revisit our own recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/136529 for generalized trees, expanding on the functionality via some metaclass trickery.'}, {'comments': [], 'desc': u"A common way to create new compound widgets is to inherit Frame, create everything you need inside it and pack this base Frame on your application. Here's an alternative to this method, that sets geometry methods and options from a wiget to another..."}, {'comments': [{'comment': u'Again, don\'t use this in real code.\n<pre>\n>>> a = [1, 2, 9, 0]\n>>> n = iter(a).next\n>>> while [x for x in [n()] if x]:\n... \tprint "I have", x\n... \nI have 1\nI have 2\nI have 9\n>>> \n</pre>\n\n', 'title': u'an alternative using list comprehensions'}, {'comment': u' ', 'title': u'Very nice.'}, {'comment': u'<pre>Assignment statements and statements in general are anathema to<br>purely functional language and Lisp programmers but are sometimes<br>but rarely required. Assignment in an expression can also be achieved<br>like this:\n\n>>> ## Directly with the expressly designed function:\n>>> import __main__\n>>> setattr(__main__,\'aaa\', 300)\n>>> aaa\n300\n>>> ## Or again with the update method and dictionaries\n>>> locals().update({\'aaa2\':200})\n>>> aaa2\n200\n>>> globals().update({\'aaa4\':500})\n>>> aaa4\n500\n>>> __main__.__dict__.update({\'aaa5\':600})\n>>> aaa5\n600\n>>> ## Or with the update method and a list of 2-tuples\n>>> t= (\'bbb\',6)\n>>> locals().update([t])\n>>> bbb\n6\n>>> ## Or many at once\n>>> k= "v1 v2 v3 v4 v5"\n>>> v= "red blu grn yel brn"\n>>> locals().update(zip( *[ l.split() for l in (k,v)] ))\n>>> fmt= "The 5 color codes are %s, %s, %s, %s and %s"\n>>> print fmt % (v1,v2,v3,v4,v5)\nThe 5 color codes are red, blu, grn, yel and brn\n\nAdditionally, Dr. David Mertz\'s article at\n\nhttp://gnosis.cx/publish/programming/charming_python_19.html\n\naddresses "Expression Binding" and the Xoltar functional toolkit.<br>He offers the following:\n\n>>> list_of_list = [[1,2,3],[4,5,6],[7,8,9]] \n>>> [car_x for x in list_of_list for car_x in (x[0],)] \n[1, 4, 7]\n\n>>> car_x\n7</pre>', 'title': u'Alternative, safer methods'}, {'comment': u"<pre>\nS\xe9bastien is offering the utility and conciseness of the valued C code<br>assignment and *not just* expression assignment as in the preceding<br>comment of mine. His utility is of much greater value. It requires a<br>function definition by necessity. Here is an alternate function<br>definition and yet another example of the usefulness of S\xe9bastien's<br>idea in a compression that calculates factorials.\n\ndef sv(vnm='', vval=None, obj=__main__):\n setattr(obj, vnm, vval)\n return vval\n\n>>> import __main__ \n>>> fac =4\n>>> [ [ sv('j', j*i) for i in range(2,fac+1) ][-1] for j in (1,) ][0]\n24\n>>> fac=5\n>>> [ [ sv('j', j*i) for i in range(2,fac+1) ][-1] for j in (1,) ][0]\n120\n\nThe advantage of the setattr function is the variable variable which<br>allows many assignments is a single pass as in the preceding comment.<br>It is also the standard method of expression assignment in Python.</pre>", 'title': u'An alternative necessary function definition and example'}, {'comment': u"<pre>The list comprehension can set an initial value as in the latter<br>part of the factorial comprehension in my last comment. After being<br>set to 1, `j' then becomes the accumulator in the calculation. If a<br>list comprehension can set and return values as in a function can they<br>act as accumulators?\n\nIt is completly natural for them to do so. \n\n>>> fac =6\n>>> [ [ [ j for j in (j*i,) ][0] for i in range(2,fac+1) ][-1] for j in (1,) ]\n[720]\n\nWow! Andrew Dalke and David Mertz are my new hero's. It<br>seems like the awe inspiring list comprehension can do just about<br>anything. Does Python need function definitions at all much less lambdas?\n\nMaybe just for readability.</pre>", 'title': u'But then again'}, {'comment': u'Steven Bethard pointed out in recipe 436482 that<pre>\n\n[j for j in [1] for i in range(2,fac+1) for j in [j*i]] [-1]\n\nis equivalent but easier to write, read and use.</pre>', 'title': u'Better yet'}, {'comment': u"In future versions of python - list comprehensions won't expose the inner variable.", 'title': u"won't work in future versions"}, {'comment': u' ', 'title': u'Perlishly elegant'}, {'comment': u'so naming this function "set" is probably not the best idea', 'title': u'set() is now a builtin'}, {'comment': u'this won\'t work if you use set() anywhere but the toplevel.\n\ne.g:\n<pre>\ndef myfunc():\n seq = range(10)\n while set(var=seq.pop()):\n print var\nmyfunc()\n</pre>\n-> NameError: global name \'var\' is not defined\n<br>\nthe behaviour is also different if the loop variable is already bound:\n<pre>\ndef myfunc(var=\'x\')\n seq = range(10)\n while set(var=seq.pop()):\n print var\nmyfunc()\n</pre>\n-> equivalent to "while seq.pop(): print \'x\'"', 'title': u'Brittle solution'}, {'comment': u'class DataHolder( object ) :\n """A simple data holder.\n """\n \n def __init__( Self , Value = None ) :\n """The constructor.\n """\n Self.Value = Value\n \n def Get( Self ) :\n """Returns the value.\n """\n return Self.Value\n \n def Set( Self , Value ) :\n """Sets the value, as well as\n returns it.\n """\n Self.Value = Value\n return Self.Value', 'title': u'Another solution.'}], 'desc': u"An evil equivalent for C expression: 'while x=f()'."}, {'comments': [], 'desc': u'Sometimes you have a file-like object (such as what urllib.urlopen() returns), but you need to pass it to a function/method that insists on receiving a true file object (what the file or open built-in functions give you). What you need is a adapter to turn your file-like object into a true file object.'}, {'comments': [{'comment': u"Twisted now comes with built in wxsupport. Use:\n<pre>\nfrom twisted.internet import wxsupport\n</pre>\nand\n<pre>\nwxsupport.install(app) \nreactor.run()\n</pre>\nwhere app is your wxApp subclass. I don't know if there is any difference between this and your code, but wxsupport has always worked fine for me.", 'title': u'for the record...'}, {'comment': u'The problem Uwe\'s recipe addresses (and this one expands on) is that, on MS Windows, Modal dialogs (and therefore also menus) use a whole new event loop, which Twisted doesn\'t know about. Therefore, Twisted events stall waiting for modal dialogs to close. \n<br><br>\nUwe\'s recipe effectively turns wxsupport inside-out, and pumps Twisted events from inside the wx event loop instead of vice-versa. This is often good enough. Disadvantage: Twisted may not be as responsive; this would probably not effect the performance of many kinds of network clients, but it would certainly hurt you if you tried to use this recipe with a server attached to a wx GUI.\n<br><br>\nAnother solution, as discussed, is to put the whole wxPython app inside another thread; yet another is to avoid menus and modals in your wx Application. There is no "perfect" solution yet.\n<br><br>\nThe only real solution to this problem is a better win32eventreactor inside Twisted, to work with both kinds of events. (It doesn\'t exist yet, as of this writing.)', 'title': u'Event loop incompatibilities on Windows'}, {'comment': u'I get an unhandled Twisted exception running this sample code on Windows:\n<pre>\n File "C:\\...\\twisted-wxpython.py", line 187, in OnInit\n reactor.startRunning()\n File "C:\\Python22\\Lib\\site-packages\\twisted\\internet\\default.py", line 115, in startRunning\n self._handleSignals()\n File "C:\\Python22\\Lib\\site-packages\\twisted\\internet\\default.py", line 87, in _handleSignals\n signal.signal(signal.SIGINT, self.sigInt)\nSystemError: error return without exception set\n</pre>', 'title': u'error running this sample'}, {'comment': u'I tried bot the sample and simply running an application using wxsupport, but seem to be getting the same exception. I am using Twisted 1.0.7rc1 with wxPython 2.41 for Python 2.3 on Windows 2000.\n<br><br>\nHere is the snippet of offending code (class names changed):\n<br><br>\n<pre>\nif __name__ == \'__main__\':\n import myGUI\n app = myGUI.MyApp(0)\n wxsupport.install(app) \n f = Factory()\n f.protocol = MyProtocol\n reactor.listenTCP(7929, f)\n reactor.run()\n</pre>\nAnd here is the traceback:\n<br><br>\n<pre>\nTraceback (most recent call last):\n File "callDirector.py", line 206, in ?\n reactor.run()\n File "C:\\Python23\\Lib\\site-packages\\twisted\\internet\\default.py", line 121, in run\n self.startRunning(installSignalHandlers=installSignalHandlers)\n File "C:\\Python23\\Lib\\site-packages\\twisted\\internet\\default.py", line 115, in startRunning\n self._handleSignals()\n File "C:\\Python23\\Lib\\site-packages\\twisted\\internet\\default.py", line 87, in _handleSignals\n signal.signal(signal.SIGINT, self.sigInt)\nSystemError: error return without exception set\n</pre>\nI wonder if anyone can shed some light on:\n<br><br> \n1) What is the problem?<br>\n2) What platforms / versions of wxPython/Python wxsupport is expected to work on?<br> The problem with menus and modal dialogs is actually not an issue for us(we\'ll do without), but the exception obviously is :-) ', 'title': u'same problem when using wxsupport'}, {'comment': u'Twisted expects to handle signal handlers cleanly. Signal handlers are such things as ctrl-C, ctrl-Break, etc. They are handled on the main thread.\n\nEliminate the trapping of signal handlers by not using reactor.run(), but instead use reactor.run(installSignalHandlers=0).\n\nYou may want to consider putting reactor on its own thread and leaving wxPython on the main thread.', 'title': u' '}, {'comment': u'This recipe is no longer necessary. Itamar Shtull-Trauring added twisted.internet.wxreactor, which is a full-fledged reactor and runs each of Twisted and wx in timeslices. Modal dialogs (and menus, which are secretly modal dialogs) will now work on MSWindows with no additional code.\n\nUpdate your wx projects to use wxreactor and rejoice! :-)', 'title': u'Twisted 1.1.1 has wxreactor'}, {'comment': u"For me, wxreactor doesn't work on linux and wxsupport doesn't work on windows XP. And neither work with modal dialogs.\n\nI've posted another solution which I think is quite neat...\n\nIt's long because there's a demo chat app in there...\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286201", 'title': u'New Solution'}], 'desc': u'This expands on Uwe C. Schroeder\'s recipe titled "Using wxPython with Twisted Python" to show one way to implement a modal progress bar using Twisted to make an XML-RPC call.'}, {'comments': [{'comment': u'It is quite a nice idea. I used it for a intranet groupware in a Linux box. This allowed the users to have the same username and password for the Linux box, email and the groupware. Since in this case the pop server is the same for all users, we could ask just the username and password.<br>\n<br>\nAshish Shrestha<br>\nhttp://www.shrestha.net.np', 'title': u'Used it in a intranet groupware.'}], 'desc': u"Here's an example of how an existing POP-mail account can be used to provide authentication to a python application. \n\nThe user doesn't have to remember yet another password, and the administrator doesn't have to handle users who forgot... Instead, we associate all our users to some external POP-mail account. When they want to log in to our system, we ask them for the password to their email account. \n\nIf we can log in to the pop server using their password, and just get a status from their mailbox (we don't peek of course) we decide that the user has authenticated himself.\n"}, {'comments': [], 'desc': u'Here is one example each of a pre-checkin and a post-checkin trigger, as well as a program that can register your triggers in ClearCase.\n\nClearCase is a software configuration management tool similar to CVS, but slightly more advanced and not free.'}, {'comments': [{'comment': u'<pre>This is a nice script. It gave me all kinds of ideas. But in\nmember send_head(), you should have: </pre>\n<pre>\nself.send_header("Content-type", \'text/html\') in lieu of \'text/plain\'\nbecause in a W3C complient browser (!= IE), that\'s what you\'ll get: \nplain text (html tags and all).</pre>\n<pre> Also, the "h/head" tag in the first f.write() should be "/head"\n</pre><pre>\nAnd please don\'t forget the shabang (#!/usr/bin/env python). I know\nyou Win32 folks don\'t need it but Python is a multiplatform language \nand If your code is portable, use it. After all, if Bill-boy knew you\nwere using Python on *his* operating system instead of his baby (VB), \nhe would come take your End User License Agreement away. \n</pre>', 'title': u'Correction'}], 'desc': u'A demonstration of how the Python HTTP server classes can be used. \n'}, {'comments': [], 'desc': u'Checking for a keypress without stop the execution of the script (unix way).'}, {'comments': [{'comment': u'I like this implementation. It is compact, and<br>\nwell written. But do you really need the resize<br>\nlock, since the thread pool will mostly be initialized<br>\nwith a size ?<br>\n<br><br>\nAnand Pillai<br>', 'title': u'Nice'}, {'comment': u"You're correct--the resize lock isn't necessary if you don't use dynamic resizing of the pool. In that case, the setThreadCount() method could be removed as well.\n\nIt's not that often that you really need a dynamically-sized thread pool, but in some narrow cases (long-running servers on loaded machines, with very bursty workloads), it can make sense.", 'title': u'Correct...'}, {'comment': u"If you copy and run the code as written, python will error out with a traceback b/c 'True' and 'False' aren't defined (at least in python 2.2). Defining True and False fixed that and it works great :D", 'title': u'True / False'}, {'comment': u'True and False were added to __builtins__ in 2.2.1. I should either eliminate them or add code to cope with earlier versions.', 'title': u'Yes...'}, {'comment': u"I've added checks for True and False; this should now work on Python 2.2.", 'title': u'Done'}, {'comment': u"Using a Condition Object's wait() and notify() you could make ThreadPoolThread::run() block until there was work to do, rather than waking up every tenth of a second to probe the pool.\n\nThis will be more efficient than busy waiting, unless there is almost always something on the task queue.", 'title': u'Why busy wait?'}, {'comment': u"This is a great idea. Thank you for providing it. I'm currently using this code in a log rotation script that I've written.\n\nI've noticed, however, that the test you do at the beginning doesn't work in Python 2.3 (maybe others) if the code is imported to be used by other code. I replaced it with the following, which seems to work ok:\n<pre>\ntry:\n x = True\nexcept NameError:\n False = 0\n True = not False\n</pre>", 'title': u'Great Idea'}, {'comment': u"Notice that you zero out your threads list before you wait on your join. You zero it out at __setThreadCountNoLock(0). Therefore by the time you get to your loop there is NEVER anything to loop on.\n\n<br>\nI've mucked around with it. What I think you might need is, a WaitForEveryoneDone routine. Something that doesn't kill all your threads too. Your Code Your Choice, but I would like to see your new version. :-)\n<br>\nHappy Programming!\n\n\n\n", 'title': u"You JoinAll doesn't work."}, {'comment': u"I've implemented your version of the boolean test. Much more intuitive. Thanks!", 'title': u'Thanks!'}, {'comment': u'a little change to the joinAll method, and joinAll waits\nfor all threads to be deleted as it should be:\n\n<pre>\n def joinAll(self, waitForTasks = True, waitForThreads = True):\n\n """ Clear the task queue and terminate all pooled threads,\n optionally allowing the tasks and threads to finish."""\n \n # Mark the pool as joining to prevent any more task queueing\n self.__isJoining = True\n\n # Wait for tasks to finish\n if waitForTasks:\n while self.__tasks != []:\n sleep(0.1)\n\n # Tell all the threads to quit\n self.__resizeLock.acquire()\n try:\n # Wait until all threads have exited\n if waitForThreads:\n for t in self.__threads:\n t.goAway()\n for t in self.__threads:\n t.join()\n # print t,"joined"\n del t\n self.__setThreadCountNolock(0)\n self.__isJoining = True\n\n # Reset the pool for potential reuse\n self.__isJoining = False\n finally:\n self.__resizeLock.release()\n\nCarl\n\ncmkleffner (at) gmx (dot) de\n\n</pre>', 'title': u'joinAll reorganized'}, {'comment': u'<br>First, I changed the implementation to use Queue.Queue for task-queueing. This eliminates the busy-waiting in each worker thread. (To end a thread, you post a dummy task. Once the next availible thread picks up the dummy task, it ends itself).\n<br>\n<br>Second, instead of list, I use sets.Set to store the worker threads. One a thread ends itself, it can call a threadpool function to remove itself from the set.\n<br>\n<br>Third, instead of letting each worker thread call the callback function, I created another Queue for the pending callbacks. Periodically a main thread can call a function to process all pending callbacks. Letting the main thread process these callbacks makes more sense to me.\n<br>\n<br>Fourth, I added a counter for running tasks. (Those have been picked up by worker threads, but haven\'t finished).\n<br>\n<br>The final result: I\'m using the threadpool in a GUI web application (think of multitab/MDI browser). When the program needs to launch a web request, it adds a task.\n<br>In the OnIdle event handler, I call threadpool.processCallback() to handle all pending callbacks (all finished web requests). I also check the running task counter, so I can display a "working" message on the UI.\n\n<br>p.s. I would love to post my code. But its too long for a comment. But hope you get the idea from my description. :)', 'title': u'Several modifications'}, {'comment': u'Hi,\nAnyone knows about links to thread pool class in c++\nThanks,\n-Robert', 'title': u'thread pool class in c++ '}], 'desc': u'A thread pool class that takes arbitrary callables as work units, and supports callbacks when the work unit is complete.'}, {'comments': [{'comment': u'What is makecls() in the examples? (Perhaps I missed something)\n\nVery interesting/enlightening stuff.', 'title': u'Typo perhaps'}, {'comment': u'makecls should read classmaker (it was called makecls in the first version, classmaker in the printed version)', 'title': u'A typo indeed'}], 'desc': u'Any serious user of metaclasses has been bitten at least once by the \ninfamous metaclass/metatype conflict. Here I give a general recipe to\nsolve the problem, as well as some theory and some examples.'}, {'comments': [{'comment': u'I\'ve been enjoying this secret recipe, happily, for some times. Then I upgraded my python happily to 2.4 then my programs started to crash. The source of bug traced to this recipe:<br><br>\n\nTraceback (most recent call last):<br>\n File "", line 1, in ?<br>\nAttributeError: \'list\' object has no attribute \'__self__\'<br><br>\n\nObviously, python guys don\'t like this secret so they made the required feature disappear in the new release. <br><br>\n\nThe following is the python version I am using now:<br><br>\n\nPythonWin 2.4 (#60, Feb 9 2005, 19:03:27) [MSC v.1310 32 bit (Intel)] on win32.', 'title': u'Crash in python 2.4'}, {'comment': u'Try this instead (in Python2.4)\n<br>\n<br>\n<pre>\n[x for x in L if x not in locals()["_[1]"]]\n</pre>', 'title': u' '}, {'comment': u'There is no official or underground plan to stop this secret from functioning in 2.x (for any x > 3).\n<br>\nBTW, another way to find similar secrets (ie depending on the C implementation and not guaranteed to work on Jython, IronPython, PyPy etc):\n\n<pre>import dis\n\ndis.dis(compile("your expression here","","eval")</pre>\n\neg.\n\n<pre>dis.dis(compile("[x*2 for x in range(4)]","","eval")</pre>\n\nsecretly provided to you by the dis module :)\n\nIf you provide a block of statements instead of an expression, secretly substitute "exec" for "eval" in the examples above.', 'title': u'This secret?'}, {'comment': u"Hi, this one\n\n>>> L = [1,2,2,3,3,3]\n>>> [x for x in L if x not in locals()['_[1]']] \n[1,2,3]\n\nworks for me. Same with the thislist()-function - i just left the .__self__\n\ngreets, andreas", 'title': u'still does in 2.4'}], 'desc': u'Sometimes you want to have a list comprehension refer to itself, but you can\'t because it isn\'t bound to a name until after it is fully constructed. However, the interpreter creates a secret name that only exists while the list is being built. That name is (usually) "_[1]", and it refers to the bound method "append" of the list. This is our back door to get at the list object itself.'}, {'comments': [{'comment': u'The only change I would do is in the variable names in \nInterfaceChecker.__new__:\n\ncls -> mcl,\nobj -> cls.\n\nThey look nicer to me ;)', 'title': u'I like it for the nice usage of the set module.'}], 'desc': u"Checks a class definition for required attributes\n<br>\nTo use it, add two lines to your class, __metaclass__=InterfaceChecker and __implements__=[InterfaceName]. The example below generates the following error message:\n<br>\nInterfaceOmission: ['__delitem__']\n<br>\nVerifying interfaces for an object becomes trivial. For instance, if you need to validate that variable 'x' implements a minimal sequence interface, verify that: <br>\nMinimalSequence in x.__implements__"}, {'comments': [], 'desc': u'Saves the name of the managed attribute and uses the saved name\nin calls to the getter, setter, or destructor. This allows the\nsame function to be used for more than one managed variable.\n<br>\nUsing property() with more than one variable results in many\nlines of duplicate code for the individual getters, setters,\nand destructors. This recipe shows how to reuse these functions\nfor multiple variables. Also, it provides default functions so that\nthe only the interesting functions need to be specified.'}, {'comments': [{'comment': u'Nice use of an enclosing namespace.', 'title': u' '}, {'comment': u'property() accepts the keyword arguments fget, fset, fdel, and \ndoc. A variation would be to use those names and return locals()\nrather an explicit tuple. For example, \n\n<pre>def foo():\n doc = "property foo\'s doc string" # use doc rather than fdoc\n def fget(self):\n return self._foo\n def fset(self, value):\n self._foo = value\n def fdel(self):\n del self._foo\n return locals() # returns a dictionary\nfoo = property(**foo()) # pass in as keyword args</pre>\n\n\nReturning locals() does seem to violate "explicit is better than \nimplicit" but it simplifies the return value a little for read-only \nproperties. Here\'s the read-only property example:\n\n<pre>def bar():\n doc = "bar is readonly"\n def fget(self):\n return self._bar\n return locals() # rather than: return fget, None, None, doc\nbar = property(**bar())</pre>\n', 'title': u'A variation'}, {'comment': u'Using locals() is a clean solution, however, it must be used with care. The nested method names *must* be as David has prescribed, and you may not introduce any other names into the local scope, e.g.<br>\n<br>\ndef bar():<br>\n    doc = "bar\'s doc string"<br>\n    def fget(self):<br>\n        return self._bar<br>\n    x = 2 # here\'s a local name that property() won\'t handle<br>\n    return locals()<br>\nbar = property(**bar())<br>\n<br>\nwill give the following error:<br>\n    bar = property(**bar())<br>\nTypeError: \'x\' is an invalid keyword argument for this function<br>\n<br>\nMy idiom does not suffer from this restriction, however, you are required to return the get/set/del/doc in the correct order, and to not return anything other than those items.<br>\n<br>\nA possible compromise would be to return an explicit dictionary rather than a tuple or locals(), e.g. <br>\n<br>\n# requires python 2.3+<br>\nreturn dict(fget=fget, doc=doc)<br>', 'title': u'Just so users are aware'}, {'comment': u"If one has a lot of getter/setter methods, using a metaclass approach might be easier in the long run. Maybe something like the following.\nI have to admit though, that the code for the meta class is much more complicated than the original recipe.\n\n<pre>\ndef getmeth(attr):\n def _func(self):\n return getattr(self,'_%s' % attr)\n\n return _func\n\ndef setmeth(attr):\n def _func(self,value):\n return setattr(self,'_%s' % attr,value)\n\n return _func\n\ndef delmeth(attr):\n def _func(self):\n return delattr(self,'_%s' % attr)\n\n return _func\n\nclass attrib(object):\n def __init__(self,default=None,opt='rwd',doc='doc string for %(key)s'):\n self.default = default\n self.opt = opt\n self.doc = doc\n\nclass meta(type):\n def __new__(cls,classname,bases,classdict):\n argdict = {}\n\n # we need the appropriate attributes from superclasses\n # going reverse order (first base has highest priority)\n\n revbases = list(bases[:])\n revbases.reverse()\n for klass in revbases:\n if hasattr(klass,'__default_attr__'):\n for key,value in klass.__default_attr__.items():\n argdict[key] = value\n\n # look for attributes whos value we are interested in\n\n for key,value in classdict.items():\n if isinstance(value,attrib):\n argdict[key] = value\n fset = fget = fdel = None\n opt = value.opt\n if 'r' in opt:\n fget = getmeth(key)\n if 'w' in opt:\n fset = setmeth(key)\n if 'd' in opt:\n fdel = delmeth(key)\n classdict[key] = property(fget,fset,fdel,value.doc % locals())\n\n classdict['__default_attr__'] = argdict\n\n # look for __init__ method\n classdict['__original_init__'] = classdict.get('__init__')\n\n # define special init method that sets the default values\n def __init__(self,*argl,**argd):\n for key,value in self.__default_attr__.items():\n if value.default is not None:\n setattr(self,'_%s' % key,value.default)\n if self.__original_init__ is not None:\n self.__original_init__(*argl,**argd)\n \n classdict['__init__'] = __init__\n\n return type.__new__(cls,classname,bases,classdict)\n\n\nclass class1(object):\n __metaclass__ = meta\n b = attrib(7)\n\nclass class2(class1):\n a = attrib('hallo','rw','doc a')\n\nif __name__ == '__main__':\n c = class2()\n print c.b\n print c.a\n\n\n</pre>", 'title': u'using a metaclass?'}, {'comment': u'The solution you\'ve provided allows for the automated creation of simple properties. But that is not the issue being addressed here. While the examples provided above show only simple properties, the intended use for this idiom is to encapsulate the get/set/del methods of more complex properties, such as the following:<br>\n<br>\n# suppose we\'re inside a class, and we want to make<br>\n# a read-only property \'average\', that returns the<br>\n# average fitness of all individuals in a population<br>\ndef average():<br>\n    doc = "returns average fitness of individuals in population"<br>\n    def fget(self):<br>\n        return sum([individual.fitness for individual in \\<br>             self.population.individuals])/float(self.population.size)<br>\n    return dict(fget=fget, doc=doc)<br>\naverage = property(**average())<br>\n<br>\nThe idea is not about avoiding having to create the get/set/del methods yourself; rather it is about avoiding leaving those methods accessible to users of your class by removing those methods from the class space (where they are normally defined). For simple property creation alone, I would refer people to my own makeproperty recipe, or to your recipe using metaclasses. For a more related metaclass solution to this problem I would refer people to the following attempt:<br><br>\nhttp://aspn.activestate.com/ASPN/Mail/Message/python-list/1660895<br>\n', 'title': u' '}, {'comment': u'I guess I got carried away a bit and solved a problem that was not asked for :-)', 'title': u'You are right, of course'}, {'comment': u'Nice, indeed.', 'title': u' '}, {'comment': u"This appears to work:<br><br> <pre>class foobar(object):<br> def __init__(self):<br> self._foo='bar'<br> def _get_foo(self):<br> return self._foo<br> def _set_foo(self, val):<br> self._foo=val<br> foo=property(_get_foo, _set_foo)<br> del(_get_foo, _set_foo)<br></pre>", 'title': u"It seems you can use 'del'"}, {'comment': u"Yes, you can certainly use del to explicitly remove the get/set/del methods from the class' namespace (note: the parenthesis are not required). This idiom does that implicitly for you. There are a couple of other things it does for you: <br>\n<br>\nIt groups the methods together visually through indentation, offsetting them from other method definitions, and tying them more directly to the property definition.<br>\n<br>\nIt allows for a consistent and repeatable naming convention. The names of the get/set/del methods are, or can be, identical for every property. There's no need to have get_foo, set_foo, get_bar, set_bar for properties foo and bar when you can just use fget, fset for both.\n<br><br>\nWhether these provide any real benefit can be debated. Personally, I like grouping related things together, and seperating them out from unrelated things. And I like having every property definition look nearly identical, by being able to re-use the names fget, fset, fdel for each one. The fact that these auxiliary methods are also automatically removed from the class' namespace, reducing namespace pollution and unintended avenues for access, is a nice side benefit.", 'title': u' '}, {'comment': u'I like the idea to use enclosed namespace. Here is another solution:\n<pre>\nclass Property:\n\n class __metaclass__(type):\n def __new__(cls, name, bases, dict):\n if dict.get(\'_is_base\'):\n return type.__new__(cls, name, bases, dict)\n else:\n return type.__new__(cls, name, bases, dict)()\n\n _is_base = 1\n\n def __get__(self, inst, cls):\n if inst is None:\n return self\n else:\n return self.get(inst)\n\n def __set__(self, inst, value):\n self.set(inst, value)\n\n def __delete__(self, inst):\n self.delete(inst)\n\n def get(self, inst):\n raise AttributeError(\'unreadable property\')\n\n def set(self, inst, value):\n raise AttributeError("can\'t set attribute")\n\n def delete(self, inst):\n raise AttributeError("can\'t delete attribute")\n</pre>\nNow property definition is very simple:\n<pre>\nclass Test(object):\n class foo(Property):\n \'\'\'foo docstring\'\'\'\n def get(self, inst):\n return inst._foo\n</pre>\nUnnecessary self argument can be avoided by automatially aplying staticmethod decorator in metaclass.', 'title': u' '}, {'comment': u'There is ongoing discussion on python-dev about accepting PEP318 - Decorators for Functions, Methods and Classes - for inclusion into Python 2.4. If accepted, some small changes to the property descriptor\nwould allow this idiom to be re-expressed as follows:<br>\n<br>\n<pre>\n# eventual decorator syntax may differ\ndef foo()[property]:\n "property foo\'s doc string"\n def fget(self):\n return self._foo\n def fset(self, value):\n self._foo = value\n return locals()\n</pre>\n<br>\nThis is better, but still not ideal: it\'s still a function definition masquerading as a property definition; and it requires you to return locals() to gain access to the get/set/del methods. Perhaps, one day, the language will grow a property block, e.g.<br>\n<br>\n<pre>\nproperty foo:\n "property foo\'s doc string"\n def get(self):\n return self._foo\n def set(self, value):\n self._foo = value\n</pre>\n<br>\nAs an aside: Ruby\'s approach is interesting, though not applicable <br>\n<br>\n<pre>\ndef foo\n ...\ndef foo=(value)\n ...\n</pre>', 'title': u'Possible idiom after PEP318'}], 'desc': u'This recipe suggests an idiom for property creation that avoids cluttering the class space with get/set/del methods that will not be used directly.'}, {'comments': [], 'desc': u'This is a useful bit of code for removing whitespace from a list of strings. For example, if you split a string, there might be superfluous whitespace.'}, {'comments': [{'comment': u'Whoops; you will need this to run the fibonacci example:\n<pre>\nfrom math import *\n</pre>', 'title': u'errata'}, {'comment': u'You can submit a modified version of the recipe. Just find the recipe in "My Recipies" and click "Edit". It\'s handy when you goof up and, say, make a UI that puts quotation marks around everything (That would be me).', 'title': u'Change it you can.'}, {'comment': u"Do you have plans for the next release?\nIt's quite impressive with what you have here. It might be worth to make it a full-fledge version, to support all SDL features at version 3.5. For instance, adds 'global_settings', 'isosurface' etc. I'm very interested to know if you have plan or time on further works.", 'title': u'next release?'}, {'comment': u'This is a truly interesting project. But maybe to large for a python cookbook snippet, when you implement all that functionality.', 'title': u'Overkill'}, {'comment': u'Thanks so much for this excellent code. Nothing to install, no versions to maintain, just PovRay objects in python. Excellent!', 'title': u'Just what I was looking for!'}], 'desc': u" Here is a relatively simple framework for making povray files from your favourite programming language, python. It's good for creating structured/mathematical scenes and animations."}, {'comments': [], 'desc': u'Find out if the sound hardware on your windows PC is working\nproperly.'}, {'comments': [{'comment': u'This code runs unchanged under the NT family of operating systems. There is no need to change it to the unicode versions of functions/structures, although it would be possible.', 'title': u'Code runs unchanged on NT family'}, {'comment': u'Thanks!', 'title': u'Discussion changed.'}], 'desc': u'It is easy to call Windows API dlls using the \nctypes module with win32con defining the \nconstant values for message identifiers and \nparameter flags. The demo code shows a simple\nbut complete application that registers a \nwindow class and a Python WndProc callback function,\ncreates the window and pumps messages.'}, {'comments': [{'comment': u"ignore previous comment - characters didn't get escaped properly.\n\n<pre>\n\n""" Authors: Cimarron Taylor and Alan Ezust\n Version: 2.0\n Date: July 01, 2004\n (relpath.py v1 originally from Oreilly/Activestate Python cookbook 2003)\n\n helper functions for relative paths.\n This package includes rel2abs() and abs2rel(), \n based on the perl functions from cpan File::Spec\n"""\n\nimport os\nimport os.path\nimport re\n\n# matches http:// and ftp:// and mailto://\nprotocolPattern = re.compile(r&apos^\\w+://&apos)\n\ndef isabs(string):\n """ \n \n @return true if string is an absolute path or protocoladdress\n for addresses beginning in http:// or ftp:// or ldap:// - \n they are considered "absolute" paths.\n """\n if protocolPattern.match(string): return 1\n return os.path.isabs(string)\n\ndef rel2abs(path, base = os.curdir):\n """ converts a relative path to an absolute path.\n\n @param path the path to convert - if already absolute, is returned\n without conversion.\n @param base - optional. Defaults to the current directory.\n The base is intelligently concatenated to the given relative path.\n @return the relative path of path from base\n """\n if isabs(path): return path\n retval = os.path.join(base,path)\n return os.path.abspath(retval)\n \n\ndef pathsplit(p, rest=[]):\n (h,t) = os.path.split(p)\n if len(h) < 1: return [t]+rest\n if len(t) < 1: return [h]+rest\n return pathsplit(h,[t]+rest)\n\ndef commonpath(l1, l2, common=[]):\n if len(l1) < 1: return (common, l1, l2)\n if len(l2) < 1: return (common, l1, l2)\n if l1[0] != l2[0]: return (common, l1, l2)\n return commonpath(l1[1:], l2[1:], common+[l1[0]])\n\n\ndef relpath(p1, p2):\n (common,l1,l2) = commonpath(pathsplit(p1), pathsplit(p2))\n p = []\n if len(l1) > 0:\n p = [ &apos../&apos * len(l1) ]\n p = p + l2\n if len(p) is 0:\n return "."\n return os.path.join( *p )\n \n \ndef abs2rel(path, base = os.curdir):\n """ @return a relative path from base to path.\n \n base can be absolute, or relative to curdir, or defaults\n to curdir.\n """\n if protocolPattern.match(path): return path\n base = rel2abs(base)\n path = rel2abs(path) # redundant - should already be absolute\n return relpath(base, path)\n \n</pre>", 'title': u'abs2rel and rel2abs'}, {'comment': u'<pre>\ndef pathsplit(path):\n """ This version, in contrast to the original version, permits trailing\n slashes in the pathname (in the event that it is a directory).\n It also uses no recursion """\n return path.split(os.path.sep)\n</pre>', 'title': u'Better pathsplit'}], 'desc': u'Suppose your application needs to know the relative path from one path to another (say because you want to create a symbolic link, a relative reference in a URL, etc). These functions may be of help.'}, {'comments': [{'comment': u'The below modification to yours keeps the pop and append calls to a minimum, increasing speed slightly.\n<pre>\nclass Queue: \n """A sample implementation of a First-In-First-Out\n data structure."""\n def __init__(self):\n self.in_stack = []\n self.out_stack = []\n def push(self, obj):\n self.in_stack.append(obj)\n def pop(self):\n if not self.out_stack:\n self.in_stack.reverse()\n self.out_stack = self.in_stack\n self.in_stack = []\n return self.out_stack.pop()\n</pre>\n\nIf one isn\'t worried about using too much memory, the below is another variant that reduces the list reconstruction significantly, and still only uses one list. Even faster than the above, though as you can see, nothing is actually removed, it is merely \'hidden\'.\n<pre>\nclass UndyingQueue:\n def __init__(self, lst=[]):\n self.q = []\n self.out = 0\n def push(self, seq):\n self.q.append(seq)\n def pop(self):\n k = self.q[self.out]\n self.out += 1\n return k\n</pre>', 'title': u'A couple variants for better speed.'}, {'comment': u"There's also significant discussion at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68436", 'title': u' '}], 'desc': u"An easy First-In-First-Out queue class based on Python's List data structure."}, {'comments': [{'comment': u'Hy <br>\nAlways amazing how short and compact python is.\nHowever, I tested the script with several words, and saw that it does not show the first definition of the page. Try Viper for example. Result on the page are 4 hits, shown are only the last 3. The pagesource for the first hit is different, the hit beeing embedded in other html code.<br>\n\nGreetings<br>\nChris', 'title': u'Some Problems with the regular expression'}], 'desc': u'This recipe shows one how to retrieve word definitions from the website www.dictionary.com.'}, {'comments': [{'comment': u"dictionary.com may have added some arguments to their LI tags,\nwhich broke this script. A working regex is:\n\n\n LI_re = re.compile(r'<LI[^>]*>(.*)</LI>')", 'title': u'regex broken now, for dictionary.com'}, {'comment': u"Thanks for the comment.\nAlthough I haven't found cases where the original regex would not work, I have updated the recipe with your suggested regex (which seems a little more robust to changes in the list tags).", 'title': u'regex broken?'}, {'comment': u"First off, thanks for the clean code sample. I'm new to Python, and I learned a lot from this.\n<br>\n<br>\nI came across some minor regex problems when running this:\n<br>\n<br>\n1. When I looked up 'pig', several parts of the definition were left out. The problem appears to be that sometimes the <LI> and </LI> tags are on different lines. I modified the regex compile to allow '.' to match newline, which seemed to fix the problem:\n<br>\n<pre> LI_re = re.compile(r'<LI[^>]*>(.*)</LI>', re.DOTALL))</pre>\n<br>\n2. When I looked up 'octothorpe', I didn't get any definition. The problem appears to be that some definitions use the DD tag instead of the LI tag.", 'title': u'A few more regex problems'}], 'desc': u'This recipe shows one how to retrieve word definitions from the website www.dictionary.com.'}, {'comments': [{'comment': u"Did you try base64.decode(file(sys.argv[1],'rb'), file(sys.argv[2],'wb')) ?", 'title': u'base64.decode'}, {'comment': u" As a matter of fact I didn't. I sort of assumed decode only works with strings without line breaks. Well, I was wrong. \n\n I eschewed the use file(...) construct for better compatibility with older versions.\n\n I will modify the recipe and give you credit for the change.\n\nCheers,\nSarat\n", 'title': u'Cool!'}], 'desc': u'Often, emails, email text archives and various other Internet-related\napplications embed Base64 encoded text data. The encoded string is \nusually split into several lines and is not easily convertible back to \nthe orginal file. The following one-liner makes such a conversion a breeze.'}, {'comments': [], 'desc': u'Compiles a string of python code and returns a printable representation of the byte codes, the resulting string can then be restored back to a code object.'}, {'comments': [], 'desc': u'extract the texts from an XML-file and write it into an *.pot'}, {'comments': [{'comment': u'<pre>\nclass endings( object ):\n """I compare equal to all suffixes of a given string.\n """\n\n def __init__( Self, String ):\n Self.String = String\n\n def __eq__( Self, Othr ):\n return Self.String.endswith( Othr )\n\n\nfor filename in os.listdir(\'.\')\n if endings(filename) in ( \'.jpg\', \'.jpeg\', \'.gif\' ):\n print filename\n</pre>', 'title': u'A simpler approach'}], 'desc': u'A short idiom for\ns.endswith(ending1) or s.endswith(ending2) or s.endswith(ending3) or ...\nShows the goodies of the Python 2.3 itertools module and summarizes a \ndiscussion on c.l.py (thread "a better str.endswith", July 2003)'}, {'comments': [{'comment': u'<pre>\nimport itertools\n\ndef isplit(iterable):\n isplit.cnt = 0\n data = {}\n it = iter(iterable) \n def f(it):\n next = it.next\n for i in itertools.count():\n if i == isplit.cnt:\n item = data[i] = next()\n isplit.cnt += 1\n else:\n item = data.pop(i)\n yield item\n return f(it), f(it)\n\n\ntest = ["hello","how","are","you?"]\nx, y = isplit(test)\nprint list(x), list(y)</pre>', 'title': u"Here's a simpler and faster implementation"}, {'comment': u'<pre>\ndef multi_iter(iterable, n=2):\n "Return multiple iterators (default is 2) from a single iterable"\n\n def f(next, data, n, cnt):\n i = 0\n while 1:\n if i == cnt[0]:\n item = next()\n cnt[0] += 1\n data[i] = [item, n-1]\n else:\n item, refcnt = entry = data[i]\n if refcnt == 1:\n del data[i]\n else:\n entry[1] = refcnt - 1\n yield item\n i += 1\n data, cnt, next = {}, [0], iter(iterable).next\n return [f(next, data, n, cnt) for j in range(n)]\n\n# Example\nw, x, y, z = multi_iter("shrubbery", 4)\nprint zip(w,x), list(y), tuple(z)</pre>', 'title': u'Version that can return more than two iterators'}], 'desc': u'Implementation of isplit, a function that splits iterators into two equal ones, which return similar values, but are exact copies of one another.'}, {'comments': [], 'desc': u'This code shows an implementation of tunneling. Though this code uses ssl as an example. It would not be hard to modify it to work for other situations as well. \n\nThe reason I use ssl as an example is because the standard python libraries do not support tunneling ssl through a proxy. Import pytunnel and give it a function w/the code you want to tunnel and your off.\n\nFor the latest code try:\nhttp://ftp.gnu.org/pub/savannah/cvs/pytunnel-cvs-latest.tar.gz'}, {'comments': [], 'desc': u"Getting data back from a socket is problematic, because you do no know when it has finished. You'd either need to specify the number of bytes transferred or have some delimeter logic. The function recvall is useful in the case where you do not have knowledge about either or are too busy or lazy to think about it."}, {'comments': [{'comment': u"It's a tad faster if actually import socket...\n\nBeware the blanket exception.", 'title': u'socket missing...'}, {'comment': u"This algorithm does not appear to generate correct UUIDs. UUIDs are officially and specifically defined as part of the ISO-11578 standard [1]. The WebDAV spec [2] also defines, in section 6.4.1, a safe way to calculate the 'node' data required by the UUID algorithm in situations where a network address is either not available or could be a security risk. I have not seen ISO-11578 but I understand that it is very similar to the algorithm defined in the UUIDs and GUIDs Internet Draft [3] which does not appear to be similar to this code at all.<br>\n<br>\nAm I missing something obvious here?<br>\n<br>\n[1] ISO/IEC 11578 - Remote Procedure Call (RPC)<br>\nhttp://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=2229<br>\n<br>\n[2] HTTP Extensions for Distributed Authoring -- WEBDAV<br>\nhttp://www.ietf.org/rfc/rfc2518.txt<br>\n<br>\n[3] UUIDs and GUIDs<br>\nhttp://www.webdav.org/specs/draft-leach-uuids-guids-01.txt<br>\n", 'title': u'What about compliance with the UUID spec?'}, {'comment': u"You can use:\n\nimport commands\ndef uuidgen():\n return commands.getoutput('uuidgen')", 'title': u'If you are on a UNIX system with the uuidgen command'}, {'comment': u"<pre>\nimport commands\ndef uuidgen():\n return commands.getoutput('uuidgen')\n</pre>", 'title': u'That should be'}, {'comment': u'A uuid module is included in python 2.5+. 2.3 and 2.4 users can get the module from http://zesty.ca/python/', 'title': u'A UUID module is now included in the standard distribution'}], 'desc': u'This is a short & sweet UUID function. Uniqueness is based on network address, time, and random.\n\nAnother good point: does not create a "hot spot" when used in a b-tree (database) index. In other words, if your IDs look something like "abc100" and "abc101" and "abc102"; then they will all hit the same spot of a b-tree index, and cause the index to require frequent reorganization. On the other hand, if your IDs look more like "d29fa" and "67b2c" and "e5d36" (nothing alike); then they will spread out over the index, and your index will require infrequent reorganization.'}, {'comments': [{'comment': u'I tried to run this script by using the <br>\ntest code given at http://www.phyast.pitt.edu/~micheles/python/drawMRO.html <br> <br>\n\nD:\\OpensourceApps>testMROGraph.py <br>\nD:\\OpensourceApps\\MROGraph.py:69: Warning: \'yield\' will become a reserved keyword in the future <br>\nTraceback (most recent call last): <br>\n File "D:\\OpensourceApps\\testMROGraph.py", line 1, in ? <br>\n from MROGraph import testHierarchy <br>\n File "D:\\OpensourceApps\\MROGraph.py", line 69 <br>\n yield \'\'.join([\\ <br> <br>\n ^\nSyntaxError: invalid syntax <br> <br>\n <br> <br>\n-Anand', 'title': u'Error with script'}, {'comment': u'Since you get an error with "yield", I guess you are using\nPython 2.2. It requires Python 2.3, as stated in the docstring.', 'title': u'You need Python 2.3'}, {'comment': u'For a MRO graph such as\n\n<pre>\n A\n |\n B\n / \\\n C D\n</pre>\n\nMROgraph(C, D) will generate dot code with two lines that both read\n\n<pre>\n edge [style=solid]; A -> B ;\n</pre>\n\nand dot will draw two edges from A to B. If you prefer to not see duplicate edges in parts of the graph common to the MRO of more than one cls in classes, you can either filter duplicate lines out of the dot code\n\n<pre>\n #codeiter=itertools.chain(*[self.genMROcode(cls) for cls in classes])\n codeiter = []\n for line in itertools.chain(*[self.genMROcode(cls) for cls in classes]):\n if not line in codeiter:\n codeiter.append(line)\n</pre>\n\nor tell dot to ignore duplicate edges by making it a "strict digraph".\n\n<pre>\n self.dotcode=\'strict digraph %s{\\n%s%s}\' % ...\n</pre>\n\nI prefer the first since I\'ve been saving the dot code to a file and this makes it slightly nicer to look at (eliminates duplicate nodes as well).', 'title': u'Duplicate edges'}], 'desc': u'Dot is a very nice graph description language developed\nat MIT and available for free at http://www.graphviz.org/ .\nCombined with Python, it makes an ideal tool to automatically \ngenerate diagrams. \nI will describe here a short recipe which produces beautiful \ninheritance diagrams for Python classes (and metaclasses too). \nIn particular the recipe allows to display the MRO (Method \nResolution Order) for complicate inheritance hierarchies. '}, {'comments': [], 'desc': u'Sorting strings whith embeded numbers.'}, {'comments': [{'comment': u'In windows there is a useful tool called py2exe, it uses the distutils package to deal with all the required modules.<br><br>\n\nI am pretty sure there is something of a similar nature for linux that produces ELF binaries, handles all the required modules, etc.', 'title': u'Very Nifty...'}, {'comment': u'This appears to close stdin. The herefile in the shell script redirects\nstdin before python gets a chance to start. This disable raw_input()\nand anything else that reads sys.stdin.', 'title': u'Side effect: closes stdin'}, {'comment': u'But all is not lost. The "zipheader.unix" script can be rewritten \nto use the \'-c\' option of python instead of stdin and a herefile. \nThis fix also handles the case where Python may be even less\nthan version 2.0. This works the same,\n"cat zipheader.unix main.zip > main" then run "main".\n\n<pre>\n\n---- save as zipheader.unix ----\n#!/bin/sh\n# This is a self-extracting executable.\n# Execute this like any normal executable.\n# You may need to "chmod a+x" this file.\n# This is a binary ZIP file with a Python loader header.\n#\n# Bourne shell loader:\nPYTHON=$(which python 2>/dev/null)\nif [ ! -x "$PYTHON" ] ; then\n echo "Python not found!"\n exit 1\nfi\nexec $PYTHON -c "\n# Python loader:\nimport sys, os\nif int(sys.version[0])<2:\n print \'Python version 2.3 final or greater is required.\'\n print \'Your version is\', sys.version\n os._exit(1)\nmajor = sys.version_info[0]\nminor = sys.version_info[1]\nreleaselevel = sys.version_info[3]\nif (major==2 and minor<3) or (major==2 and minor==3 and releaselevel!=\'final\'):\n print \'Python version 2.3 final or greater is required.\'\n print \'Your version is\', sys.version\n os._exit(1)\nsys.path.insert(0, sys.argv[1])\ndel sys.argv[0:1]\nprint sys.argv[1]\nimport main\nmain.main()\n" $0 $@\n\n# Zip file:\n---- end of zipheader.unix ----\n\n</pre>\n\nYours,\nNoah', 'title': u'fix to stdin close problem'}, {'comment': u'First, these programs fail if the command line arguments or file name contains spaces etc. Use "$0" and "$@". (Or ${1+"$@"} for the latter to avoid an old Bourne shell bug, but that breaks on Zsh 3/4, which is used on Mac OS X.)<br><br>\n\nNext, what\'s the deal with all this testing?<br>\n\nThe exec shell command can find Python without help from $(which) - which is an unportable shell construct anyway, it should have been `which`. Though we might append an exit statement in case it\'s some shell which doesn\'t exit if exec fails.<br>\n\nThus, the first program could use\n\n<pre>\n#! /bin/sh\nexec python2.3 - "$0" "$@" << END_OF_PYTHON_CODE || exit 1\n...\n</pre>\n\nThe second program rejects e.g. 2.3.4 beta, which I suppose was not indented. But I don\'t suppose there is any need to test for 2.3 beta anymore, and since it tests sys.version anyway, it can just as well stick to that. Also, assert seems good enough for this purpose:\n\n<pre>\nexec python -c \'\nimport sys\nassert sys.version >= "2.3", sys.argv[1] + ": Python 2.3 or greater required"\nsys.path.insert(0, sys.argv[1])\ndel sys.argv[0]\nimport main\nmain.main()\n\' "$0" "$@"\nexit 1\n</pre>', 'title': u'Quoting and testing'}], 'desc': u'Some python applications contain a main skript and some additional modules. By using zipimport from python-2.3 and some help of the shell one may bind all needed files (except the python interpreter and its standard modules) into one executable. This eliminates the need for an expensive installation.'}, {'comments': [{'comment': u"I tried the script for windows and it worked like a charm.\nThe only thing i did not get to work however was watch on mapped folder's/Network directories. Trying to figure that out.", 'title': u'Good one'}, {'comment': u"if your using Linux 2.6.13+ there is a kernel interface for watching directory's and a python module for it at http://pyinotify.sourceforge.net/", 'title': u'inotify is similiar for linux 2.6.13+'}], 'desc': u'The watch_directories() function takes a list of paths and a callable object, and then repeatedly traverses the directory trees rooted at those paths, watching for files that get deleted or have their modification time changed. The callable object is then passed two lists containing the files that have changed and the files that have been removed.'}, {'comments': [{'comment': u"When counting the number of dictionary lookups (access and insertion), the union-find structure completely annhilliates the straightforward approach when we end up joining every individual set to the one larger set, as is appropriate for kruskal's minimum spanning tree algorithm.<br><br>\n\nThis is because while each operation on the union-find structure is known to be O(inverse_ackerman(n)), each operation using the straightforward approach is O(n).<br><br>\n\nEven with the C dict.update(), using the union-find structure is FAR faster.", 'title': u'For the actual data structure application, it is faster.'}, {'comment': u"I need a union-find structure for Edmonds' blossom-contraction algorithm for maximum matching in general graphs (unfortunately the graphs I need this for are not bipartite so I can't use my previous recipe) and this looks like a good implementation. I like the way you set up the API to allow arbitrary hashables to take part in the structure.<br><br>\n\nA few comments, though:<br><br>\n\n- What is the point of converting objects to numbers and back again? Does the performance gain really outweigh the added code complexity? And if you're going to do that, why do you use the numbers to index into a dict instead of into a list?<br><br>\n\n- Maybe it would be more pythonic to use __getitem__ instead of find? That is, instead of calling UF.find(x), simply write UF[x] to find the set associated with x, just like other data structures (e.g. dict) use the same notation for other values associated with x? I can't think of a similar neat and understandable syntax for union, though.<br><br>\n\n- You appear to have mixed up log* and alpha. log*(n) is the minimum height of a tower of powers of 2, 2^(2^(...)) that is at least n. alpha is the inverse of the Ackermann function, which can be defined by several recurrences but not the one you give -- a typical one is\n<pre>\n A(1,x) = 2x\n A(x,1) = 2\n A(x,y) = A(x-1,A(x,y-1))\n</pre>\nAlthough both alpha and log* are incredibly slowly growing, alpha is much slower than log*.", 'title': u'Looks useful'}, {'comment': u"- You make a good point about conversions between objects and integers. I used dictionaries purely out of personal preference. While parent pointers make little sense in using dictionaries, keeping a dictionary of child pointers end up helping considerably when I went about implementing the 'delete' operation for the Blossom Contraction algorithm you emailed me about (which is included below). In using dictionaries for child pointers, delete can be ammortized to O(1) per deletion, paid for by earlier union and find operations.<br><br>\n\n- In terms of being more pythonic, certainly using __getitem__ would be significantly more pythonic, no arguments here. I wrote them in terms of the operations performed on the structure (union, find) because it is explicit. It doesn't make sense to me to make something more pythonic, when it doesn't make sense to UF[x] = y. The addition of delete below, could also has a python equivalent __delitem__, but again, I shy away from using too many accessors when the structure is so different from what is offered in standard python, and doesn't help with understanding the use of the structure.<br><br>\n\n- My mistake.<br><br>\n\n<pre>\nclass BlossomContraction:\n def __init__(self):\n '''\\\nCreate an empty blossom contraction data structure.'''\n self.num_weights = {}\n self.parent_pointers = {}\n self.num_to_objects = {}\n self.objects_to_num = {}\n self.child_pointers = {}\n self.next = -1\n self.setcount = 0\n self.__repr__ = self.__str__\n def insert_objects(self, objects):\n '''\\\nInsert a sequence of objects into the structure. All must be Python hashable.'''\n for object in objects:\n self.find(object);\n def find(self, object):\n '''\\\nFind the root of the set that an object is in.\nIf the object was not known, will make it known, and it becomes its own set.\nObject must be Python hashable.'''\n if not object in self.objects_to_num:\n self.next += 1\n obj_num = self.next\n self.num_weights[obj_num] = 1\n self.objects_to_num[object] = obj_num\n self.num_to_objects[obj_num] = object\n self.parent_pointers[obj_num] = obj_num\n self.child_pointers[obj_num] = {}\n self.setcount += 1\n return object\n stk = [self.objects_to_num[object]]\n par = self.parent_pointers[stk[-1]]\n while par != stk[-1]:\n del self.child_pointers[par][stk[-1]]\n stk.append(par)\n par = self.parent_pointers[par]\n for i in xrange(1,len(stk)-1):\n self.num_weights[stk[i]] -= i\n par = stk.pop()\n for i in stk:\n self.parent_pointers[i] = par\n self.child_pointers[par][i] = None\n return self.num_to_objects[par]\n def union(self, object1, object2):\n '''\\\nCombine the sets that contain the two objects given.\nBoth objects must be Python hashable.\nIf either or both objects are unknown, will make them known, and combine them.'''\n o1p = self.find(object1)\n o2p = self.find(object2)\n if o1p != o2p:\n on1 = self.objects_to_num[o1p]\n on2 = self.objects_to_num[o2p]\n w1 = self.num_weights[on1]\n w2 = self.num_weights[on2]\n if w2 > w1:\n o1p, o2p, on1, on2, w1, w2 = o2p, o1p, on2, on1, w2, w1\n self.num_weights[on1] = w1+w2\n self.parent_pointers[on2] = on1\n self.child_pointers[on1][on2] = None\n self.setcount -= 1\n def delete(self, object):\n '''\\\nRemove an object from the Blossom Contraction structure.\nObject does not necessarily need to be a root.'''\n if not object in self.objects_to_num:\n return\n rootn = self.objects_to_num[self.find(object)]\n objectn = self.objects_to_num[object]\n #uncomment the following line to require object to be a root.\n #assert objectn == rootn\n self.nu", 'title': u'Why convert? More pythonic?'}, {'comment': u"This doesn't actually implement blossom contraction. It implements a related algorithm and structure, but it isn't really useful.", 'title': u'Note on blossom contraction...'}, {'comment': u'All well and fine... but where is the useful recipe, i mean the kruskal algorithm ?', 'title': u'help the needy ;-)'}, {'comment': u"so, i could be wrong here, but i think i'm not, so i thought i'd share... feel free to correct.\n<br><br>\nhey, maybe the reason the straightforward method wins in timings is that it is fundamentally broken. you have to reset all members of the list to point to the new, larger list, which you don't do...\n<br>\n<pre>\n self.objects[b].update(self.objects[a])\n self.objects[a] = self.objects[b]\n</pre>\n<br>\nthese lines are the problem. well, the first is okay, but the second one needs to iterate through the old members of self.objects[a] and set them all to point to the new bigger list.", 'title': u'straightforward method buggy'}], 'desc': u"The union find data structure is primarily used for Kruskal's Minimum Spanning Tree algorithm, though can be used whenever one only needs to determine of two items are in the same set, and be able to combine sets quickly."}, {'comments': [{'comment': u'This certainly has to be written idiom instead of ideom. [I was about to look it\nup in the dictionary but submitted before I got the result :-(] <br>\nSorry for my bad english.<br>\n\nThis is what I mean: <br>\n\n<pre>\n\\Id"i*om\\, n. [F. idiome, L. idioma, fr. Gr. ?, fr. ? to\nmake a person\'s own, to make proper or peculiar; prob. akin\nto the reflexive pronoun ?, ?, ?, and to ?, ?, one\'s own, L.\nsuus, and to E. so.]\n\n1. The syntactical or structural form peculiar to any\n language; the genius or cast of a language.\n\n2. An expression conforming or appropriate to the peculiar\n structural form of a language; in extend use, an\n expression sanctioned by usage, having a sense peculiar to\n itself and not agreeing with the logical sense of its\n structural form; also, the phrase forms peculiar to a\n particular author\n</pre>', 'title': u'ideom - idiom'}, {'comment': u"I like the idea, although in practice I can't think of a value that's unique in *every* case. This could sneak in some really creepy bugs.\n\nThere is another way to test the number of arguments fed to a function.\n<pre>\ndef function(*args):\n if args:\n # args is not the empty tuple\n something(args[0])\n else:\n # args is the empty tuple\n return args[0]\n</pre>", 'title': u'Uniques are evil'}], 'desc': u"This recipe presents an ideom for simplified accessors, that combines\ntypical getter and setter functionality of an attribute into a single\noverloaded method, that instead of getATTRIBUTE and setATTRIBUTE can\nnow just be called ATTRIBUTE. When called without arguments it acts as\na getter and retrieves the attribute's value. When called with\narguments, the attribute is set to this value.\n\nUses a neat trick of an exclusive unique value in default arguments."}, {'comments': [{'comment': u"Unfortunately this will only work in the simplest of cases where the contents of a is just text. Mixed content is allowed in so, you will get markup as well. The worst case is if you have nested lists, when you won't be pairing the correct tags.", 'title': u'Very simplistic'}, {'comment': u"Unfortunately this will only work in the simplest of cases where the contents of a is just text. Mixed content is allowed in so, you will get markup as well. The worst case is if you have nested lists, when you won't be pairing the correct tags.", 'title': u'Very simplistic'}, {'comment': u"The comment above should read:<br>\nUnfortunately this will only work in the simplest of cases where the contents of a li element is just text. Mixed content is allowed in li elements, so you will get markup as well. The worst case is if you have nested lists, when you won't be pairing the correct tags.", 'title': u'Sorry'}], 'desc': u"Just a snippet. I needed to grab the data between <LI> list item </LI> tags. Highly annoying that I couldn't find it anywhere else. "}, {'comments': [{'comment': u'FYI:<br>\n<pre>\nrpm -qi tree-1.2-7mdk\n\nName : tree Relocations: /usr \nVersion : 1.2 Vendor: (none)\nRelease : 7mdk Build Date: Wed May 5 14:05:49 1999Install date: Fri Nov 5 05:54:15 1999 Build Host: k6.microsoft.sucks.eu.org\nGroup : Applications/File Source RPM: tree-1.2-7mdk.src.rpm\nSize : 21607 License: GPL\nSummary : A utility which displays a tree view of the contents of directories.\nDescription :\nThe tree utility recursively displays the contents of directories in a\ntree-like format. Tree is basically a UNIX port of the tree DOS\nutility.\n\nInstall tree if you think it would be useful to view the contents of\nspecified directories in a tree-like format.\n</pre>', 'title': u'There is a utility....'}, {'comment': u'Oh darn. Looks like I did it again... reinventing the wheel. ;) Thanks for the info Keith.', 'title': u'Thanks...'}, {'comment': u'I find the following more concise (where find is available...).\n\n<pre>\ndef tree(dir, padding, print_files=False):\n cmd = "find \'%s\'" % dir\n files = os.popen(cmd).read().strip().split(\'\\n\')\n padding = \'| \'\n for file in files:\n level = file.count(os.sep)\n pieces = file.split(os.sep)\n symbol = {0:\'\', 1:\'/\'}[isdir(file)]\n if not print_files and symbol != \'/\':\n continue\n print padding*level + pieces[-1] + symbol\n</pre>', 'title': u'More concise output and code'}], 'desc': u"The following program displays the directory structure of a specified path using ASCII characters. The program can optionally display files in addition to directories. This program functions similar to the windows 'tree' command."}, {'comments': [{'comment': u'<pre>\nimport signal\nimport fcntl \nimport os \n</pre>\nThese are needed by the class. <br>\n\nNext, the "sighandler" he mentions is here: <br>http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/217830\n\n<br>\nAlso note that the argument passed to the object when a directory\'s contents change is a *list*, not a single filename. If you want to perform some action on each file, you will need to iterate over the argument "added" or "removed".', 'title': u'To use this recipe ...'}], 'desc': u'Inspired by another snippet here that watches a directory... Here is a directory watcher that only works on Linux, as it uses the asyncronous directory notify feature. It will generate a SIGIO on directory change. You should define a signal handler that calls this back (actaully, calls the instance).'}, {'comments': [], 'desc': u'On Linux, use this to manage objects that can cause a SIGIO to be generated. It calls all registered objects.'}, {'comments': [{'comment': u'Maybe I should explain in a little more detail how this works. If you have a partition of n, you can reduce it to a partition of n-1 in a canonical way by subtracting one from the smallest item in the partition. E.g. 1+2+3 => 2+3, 2+4 => 1+4. This algorithm reverses the process: for each partition p of n-1, it finds the partitions of n that would be reduced to p by this process. Therefore, each partition of n is output exactly once, at the step when the partition of n-1 to which it reduces is considered.', 'title': u'Explanation'}, {'comment': u'The number of partitions grows quickly.\n\n<pre>\ndef upper_bound(k):\n """Ramanujan\'s upper bound for number of partitions of k"""\n return int(exp(pi*sqrt(2.0*k/3.0))/(4.0*k*sqrt(3.0)))\n</pre>', 'title': u'Upper bound'}, {'comment': u'This recipe is really interesting.<br>\nI made two variations on this recipe.<br>\n<br>\n# tuple version\n<pre>\ndef partitions_tuple(n):\n # tuple version\n if n == 0:\n yield ()\n return\n\n for p in partitions_tuple(n-1):\n yield (1, ) + p\n if p and (len(p) < 2 or p[1] > p[0]):\n yield (p[0] + 1, ) + p[1:]\n</pre>\nEach partition is represented as a tuple instead of a list.<br>\nThis version runs faster than a list equivalent.<br>\n<br>\n# reverse order\n<pre>\ndef partitions_rev(n):\n # reverse order\n if n == 0:\n yield []\n return\n\n for p in partitions_rev(n-1):\n yield p + [1]\n if p and (len(p) < 2 or p[-2] > p[-1]):\n yield p[:-1] + [p[-1] + 1]\n</pre>\nEach partition is represented in descending order.<br>\nFor example:\n<pre>4 -> [1,1,1,1], [2,1,1], [2,2], [3,1], [4].</pre>\n', 'title': u'Two variations'}, {'comment': u"<pre>\ndef _yieldParts(num,lt):\n if not num:\n yield ()\n for i in range(min(num,lt),0,-1):\n for parts in _yieldParts(num-i,i):\n yield (i,)+parts\n\ndef yieldParts(num):\n for part in _yieldParts(num,num):\n yield part\n</pre>\n\nThis code works just like the given code, but does not create the list from smallest to largest, but rather the other way around. It doesn't need complicated fiddling, and could be sped up considerably by creating a cache for all parts yielded for each num,lt.", 'title': u'Slightly simpler example which generates the sequence from high to low'}, {'comment': u'Sometimes I do need speed, and then a multiset representation\nallows several efficiences, such as O(1) time per iteration (not\njust amortized O(1)), and compactness (the largest data structure\nconstructed takes O(sqrt(N)) space; the important part of that is\nthere\'s so much less the partition _consumer_ needs to examine\neach time -- something to remember next time you find your code\nendlessly crawling over long strings of ones):\n\n<pre>\ndef gen_partitions_ms(n):\n """Generate all partitions of integer n (>= 0).\n\n Each partition is represented as a multiset, i.e. a dictionary\n mapping an integer to the number of copies of that integer in\n the partition. For example, the partitions of 4 are {4: 1},\n {3: 1, 1: 1}, {2: 2}, {2: 1, 1: 2}, and {1: 4}. In general,\n sum(k * v for k, v in a_partition.iteritems()) == n, and\n len(a_partition) is never larger than about sqrt(2*n).\n\n Note that the _same_ dictionary object is returned each time.\n This is for speed: generating each partition goes quickly,\n taking constant time independent of n.\n """\n\n if n < 0:\n raise ValueError("n must be >= 0")\n\n if n == 0:\n yield {}\n return\n\n ms = {n: 1}\n keys = [n] # ms.keys(), from largest to smallest\n yield ms\n\n while keys != [1]:\n # Reuse any 1\'s.\n if keys[-1] == 1:\n del keys[-1]\n reuse = ms.pop(1)\n else:\n reuse = 0\n\n # Let i be the smallest key larger than 1. Reuse one\n # instance of i.\n i = keys[-1]\n newcount = ms[i] = ms[i] - 1\n reuse += i\n if newcount == 0:\n del keys[-1], ms[i]\n\n # Break the remainder into pieces of size i-1.\n i -= 1\n q, r = divmod(reuse, i)\n ms[i] = q\n keys.append(i)\n if r:\n ms[r] = 1\n keys.append(r)\n\n yield ms\n</pre>\n', 'title': u'Or if you do need speed ...'}, {'comment': u'This is the same approach as in my recipe 221132.\n\nSee also\nhttp://www.cs.sunysb.edu/~algorith/files/generating-partitions.shtml', 'title': u'list of tuples'}], 'desc': u'A "partition" is a way of representing a given integer as a sum of zero or more positive integers, e.g. the partitions of 4 are 1+1+1+1, 1+1+2, 2+2, 1+3, and 4. This recipe uses simple generators recursively to produce a stream of all partitions of its argument. Each partition is represented as a sorted list of the numbers to be summed, e.g. [1,1,1,1], [1,1,2], [2,2], [1,3], [4].'}, {'comments': [{'comment': u"Some of the text was eaten. For example, Point.mro() was munged. It's all those greater-than and less-than signs being mistaken for HTML tags.", 'title': u'some text was eaten...'}, {'comment': u"This has a slightly different interface, but is simple and fast:\n<br>\n<pre>\ndef SuperTuple(*fields):\n mapping = dict([(fname, fnum) for fnum, fname in enumerate(fields)])\n class Temp(tuple):\n def __getattr__(self, key, fields=mapping):\n return self[fields[key]]\n return Temp \n\nPoint = SuperTuple('x', 'y')\n\n>>> p = Point([1,2])\n>>> p.x\n1\n>>> p.y\n2\n</pre>\nIf the field names need to be visible, there is a more direct approach:\n<pre>\ndef SuperTuple(*fields):\n class AttrTuple(tuple):\n pass\n for i, name in enumerate(fields):\n def geti(self, i=i):\n return self[i]\n setattr(AttrTuple, name, property(geti))\n return AttrTuple\n\nPoint = SuperTuple('x', 'y')\n\np = Point([1,2])\n>>> p.x\n1\n>>> p.y\n2\n>>> 'x' in dir(p)\nTrue\n\n</pre>", 'title': u'Alternate Implementation'}], 'desc': u'A simple recipe for building tuple-like classes with attribute acessors.'}, {'comments': [{'comment': u"If you define a table: <pre>\n asbits = dict([(v[0], v[1:4]) for v in ['0000', '1001', \n '2010', '3011', '4100', '5101','6110','7111']])\n</pre> Then <pre>\n bstr_pos = lambda x: ''.join([asbits[ch] for ch in oct(x)]).lstrip('0')\n</pre> might do the job. But I don't understand why: <pre>\n def bstr_pos(x) return ''.join([asbits[ch] for ch in oct(x)]).lstrip('0')\n</pre> \nis worse.", 'title': u'If you can use a data table, use octal conversion.'}, {'comment': u'<pre>\ndef tobin(x, count=8):\n """\n Integer to binary\n Count is number of bits\n """\n return "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))\n</pre>', 'title': u'Binary with fixed length'}, {'comment': u'Inverse of the previous...\n\n<pre>def toDecimal(x):\n return sum(map(lambda z: int(x[z]) and 2**(len(x) - z - 1), \n range(len(x)-1, -1, -1)))\n</pre>', 'title': u'binary to decimal oneliner'}], 'desc': u'These one-liner lambdas convert integers to binary strings with no leading zeros.'}, {'comments': [{'comment': u'There is a NameError on meth, I believe line 13 should read:\n<pre>classdict[method] = wrapedmeth(classname,method)</pre>', 'title': u'Typo'}, {'comment': u"Yes, looks like a typo (I'm sure, I did test the code before posting :-)\nIt's corrected now.", 'title': u'Corrected'}, {'comment': u'<pre>\nReturning a modified list can be achieved with fewer code using <br>the "x or y" logic:\n\naList.method(arg) or aList\n\n>>> L = range(5)\n>>> L\n[0, 1, 2, 3, 4]\n>>> L.insert(3,10)\n>>> L\n[0, 1, 2, 10, 3, 4]\n>>> L.append(-10)\n>>> L\n[0, 1, 2, 10, 3, 4, -10]\n>>> L.extend([3,4,5])\n>>> L\n[0, 1, 2, 10, 3, 4, -10, 3, 4, 5]\n>>> L.sort()\n>>> L\n[-10, 0, 1, 2, 3, 3, 4, 4, 5, 10]\n\nThe above procedures can be achieved in one line of code without <br>involving any additional function:\n\n>>> m = range(5)\n>>> (((m.insert(3,10) or m).append(-10) or m).extend([3,4,5]) or m).sort() or m\n[-10, 0, 1, 2, 3, 3, 4, 4, 5, 10]\n\nCertainly, this is a lot more difficult to read. However, in <br>many cases, especially you perform only one or two operations <br>(but not a lot series like the example above):\n\nm.sort() or m\n(m.sort() or m).append(5) or m\n\nthis approach looks more handy.\n</pre>\n', 'title': u'another shortcut (Runsun Pan)'}], 'desc': u'Mutating list methods such as \'append\' or \'extend\' return None instead of the (mutated) list itself. Sometimes, this is not the desired behaviour.\nThe <a href="http://groups.google.de/groups?dq=&hl=de&lr=&ie=UTF-8&oe=UTF-8&threadm=I706b.17723%24hE5.626547%40news1.tin.it&prev=/groups%3Fdq%3D%26num%3D25%26hl%3Dde%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26group%3Dcomp.lang.python%26start%3D75"> Discussion</a> on comp.lang.python resulted in the following solution.\nThe shown code is my own, while two other solutions are presented in the discussion.'}, {'comments': [{'comment': u'There is absolutely no need to load the DTD yourself.<br>\n<br>\nIf you have defined a DTD in your xml file using:\n<pre><!DOCTYPE root-node SYSTEM "/path/to/filename.dtd"></pre>\nPython will find that DTD itself and load it to validate your XML file.<br>\n<br>\nIt would be very very odd if you would load a DTD in variable \'p\', not use that variable in any way and python will magically know that that is the DTD you want to validate with.', 'title': u'No need to load DTD'}, {'comment': u'If you really want to specify the DTD explicitly (as opposed to specifying it in the DOCTYPE declaration), use the following code:\n\n<pre>\n#!/usr/bin/env python\nfrom xml.parsers.xmlproc import xmlproc\nfrom xml.parsers.xmlproc import xmlval\nfrom xml.parsers.xmlproc import xmldtd\n\ndef validate_xml(xml_filename, dtd_filename):\n """Validate a given XML file with a given external DTD.\n\n If the XML file is not valid, an error message will be printed\n to sys.stderr, and the program will be terminated with a non-zero\n exit code. If the XML file is valid, nothing will be printed.\n """\n dtd = xmldtd.load_dtd(dtd_filename)\n parser = xmlproc.XMLProcessor()\n parser.set_application(xmlval.ValidatingApp(dtd, parser))\n parser.dtd = dtd\n parser.ent = dtd\n # If you want to override error handling, subclass\n # xml.parsers.xmlproc.xmlapp.ErrorHandler and do\n # parser.set_error_handler(MyErrorHandler(parser))\n parser.parse_resource(xml_filename)\n # If you have xml data only as a string, use instead\n # parser.feed(xml_data)\n # parser.close()\n\nif __name__ == \'__main__\':\n import sys\n validate_xml(sys.argv[1], sys.argv[2])</pre>', 'title': u'Specifying the DTD explicitly'}], 'desc': u'PyXML is a useful package for parsing XML. The xmlval and xmldtd modules let you validate XML docs against an external DTD file. This is a simple, straightforward recipe that illustrates how to use the xmlval and xmldtd modules for validated XML parsing.'}, {'comments': [], 'desc': u'An iterative equivalent to the recursive function given in the recipe "Generator for integer partitions" by David Eppstein.\n\nUses the representation\n\n7 = 1*7 = 1*6 + 1*1 = 1*5 + 1*2 = 1*5 + 2*1 = ...'}, {'comments': [], 'desc': u"This is an implementation of Edmonds' blossom-contraction algorithm for maximum cardinality matching in general graphs. It's maybe a little long and complex for the recipe book, but I hope it will spare someone else the agony of implementing it themselves."}, {'comments': [{'comment': u"<pre>\ndef A000069():\n '''Odious numbers: numbers with an odd number of ones in their binary representation.\nFor more info, see http://www.research.att.com/projects/OEIS?Anum=A000069'''\n yield 1\n for x in A000069():\n if x & 1 and x > 1:\n yield 2*x - 1\n yield 2*x\n if not (x & 1):\n yield 2*x + 3\n</pre>", 'title': u'Another one'}, {'comment': u'A003714() fascinates me because I don\'t understand how it works. But I do understand<br>\na little about its execution. It causes the "yield stack" depth to grow without bound.<br>\nWhen calculating the nth Fibbinary number the "yield stack" depth for A003714() is<br>\napproximately the log base 2 of n. For my own amusement I eliminated the recursion and<br>\nhence the unbounded "yield stack" as follows:<br>\n<pre>\ndef A003714nr():\n """\n Fibbinary numbers (no consecutive ones in binary representation).\n For more info see http://www.research.att.com/projects/OEIS?Anum=A003714\n http://www.research.att.com/~njas/sequences/A003714\n \n 2006/01/09 M - 2006/01/12 Th Bob Hossley\n Eliminate recursion and the "yield stack" depth growing without bound.\n When calcuating the nth Fibbinary number the "yield stack" depth for\n A003714() is approximately the log base 2 of n.\n\n The algorithm used by A003714nr() is simple: Begin with 0. To calculate\n the next integer in the Fibbinary sequence, add 1 to the previous Fibbinary\n number. Then skip all non-Fibbinary numbers by adding 2**n\n whenever the result contains ones in positions 2**n and 2**(n+1). Because\n the previous Fibbinary number is guaranteed not to have consecutive one\'s\n in its binary representaion, the consecutive ones check can stop as soon\n as three consecutive binary digits are encountered that do not contain two\n consecutive ones.\n\n Generator context saving preserves local variables Last, LoopCnt, Mask1,\n and Mask2 between yield and continue from yield but only variable Last\n needs to be preserved.\n """\n \n Last = 0\n LoopCnt = 2\n while (1):\n if (LoopCnt > 1):\n yield Last\n Last += 1\n Mask1 = 1\n Mask2 = 2\n LoopCnt = 0\n if (Last & Mask1) and (Last & Mask2):\n Last += Mask1\n LoopCnt = 0\n else:\n LoopCnt += 1\n Mask1 *= 2\n Mask2 *= 2\n</pre>', 'title': u'Non-Recursive A003714()'}, {'comment': u'<br>A003714() skips the zeroth Fibbinary number, which is zero.<br>\nI modified A003714()to make it return the zeroth Fibbinary number.<br>\nThis is an inelegant kludge:\n<pre>\n\ndef A003714x():\n """\n Fibbinary numbers (no consecutive ones in binary representation).\n For more info see http://www.research.att.com/projects/OEIS?Anum=A003714\n http://www.research.att.com/~njas/sequences/A003714\n\n 2006/01/17 Bob Hossley\n Change: Return A(0) = 0.\n """\n\n try:\n A003714x.A0\n except AttributeError:\n A003714x.A0 = True\n yield 0\n \n yield 1\n for x in A003714x():\n yield 2*x\n if not (x & 1):\n yield 2*x+1\n</pre>', 'title': u'A003714() and the zeroth Fibbinary number'}, {'comment': u'<br>A003714x() only includes A(0) in the first sequence it generates. <br>\nThis bug can be worked around in the code that uses A003714x() by deleting the<br>\ncontrol variable between each use of A003714x(). For example:<br>\n<pre>\n\nloops = 0\nfor seqVal in A003714x():\n print "Fibbinary(", loops, ")=", seqVal\n loops += 1\n if (loops > 10): break\n\ndel A003714x.A0\t# Kludge to delete control variable\nloops = 0\nfor seqVal in A003714x():\n print "Fibbinary(", loops, ")=", seqVal\n loops += 1\n if (loops > 10): break\n</pre>\n<br>\nBut this does not a fix the bug. I don\'t know how to change A003714()<br>\nto include A(0) in the sequence. I don\'t allow adding a function argument to<br>\nA003714(). The "yield statement" magic hides the generator initialization.<br>\nIf I knew how to rewrite A003714() without yield statements, then I would use<br>\nitertools and the generator initialization would be exposed. I would initialize<br>\na control variable in the generator initialization and this problem would solved.<br>\nBut at this time, I have no solution.', 'title': u'A003714x() Bug'}], 'desc': u'For a function without arguments, calling itself recursively is a quick way to get into an infinite loop. But for a generator, it can actually be useful...here are some simple numerical examples.'}, {'comments': [], 'desc': u'this recipe defines two sets of functional-style curry and rcurry (right curry).\n\nthis is a compliment to:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549'}, {'comments': [{'comment': u"I'm sorry, it belongs rather to the Algorithms Category.<br><br>See also here: Numeric base converter that accepts arbitrary digits<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/111286\n", 'title': u'--> Category: Algorithms'}, {'comment': u'Nicely written.<br>\n\nHere are a few nits to take it to industrial strength:<br>\n\n* rename the function to base() or some such to avoid overwriting __builtin__.str() <br>\n\n* only build abc once and do it outside the function <br>\n\n* use \'\'.join() on a list instead of quadratic time string addition. <br>\n\n* make divmod, abc, and result.append into locals for faster lookup in the loop. <br>\n\n<pre>\nimport string\nabc = string.digits + string.letters\n\ndef base(number, radix):\n """base(number, radix)\n inverse function to int(str,radix) and long(str,radix)\n """\n\n if not 2 <= radix <= 36:\n raise ValueError, "radix must be in 2..36"\n\n result = []\n addon = result.append\n if number < 0:\n number = -number\n addon(\'-\')\n elif number == 0:\n addon(\'0\')\n\n _divmod, _abc = divmod, abc\n while number:\n number, rdigit = _divmod(number, radix)\n addon(_abc[rdigit])\n\n result.reverse()\n return \'\'.join(result)\n</pre>', 'title': u'A few nits'}], 'desc': u'The function produces an arbitrary radix string representation of integer numbers.\n'}, {'comments': [], 'desc': u'This is a very short code snippet illustrating how to convert individual pages of PDF documents to TIFF files, one TIFF file per page. It works only on Mac OS X with PyObjC installed. As a recipe the code is compact and does not check for many error conditions, etc. The more extended version does so and can also be used as a command-line tool.'}, {'comments': [], 'desc': u'I wrote this method to be, first and foremost, flexible. This method implements what is referred to as a Schwartzian transform algorithm. This method does provide a mechanism to ensure stability in the sort. This version does a sort in place.'}, {'comments': [], 'desc': u'A lightweight method to access the field names from a database.'}, {'comments': [{'comment': u"I don't understand the utility of you wrapper class...", 'title': u'Why not use static method for fromLong'}, {'comment': u'I borrowed this wrapper class from another recipe, out of ignorance of "recent" Python features. "classmethod" would work just fine, I just didn\'t know it existed.', 'title': u'Legacy workarounds never die, they just keep cropping up in new code...'}, {'comment': u'(and I removed the extraneous commentary for the now unnecessary class)', 'title': u'So corrected...'}, {'comment': u'Not "classmethod" I meant "staticmethod". No reason to involve the class.', 'title': u'Ooops, still wrong...'}, {'comment': u"I think it's even better with classmethod. Your initializer then does not break when you rename the class.", 'title': u'Why not classmethod?'}], 'desc': u'Sometimes your class design warrants the definition of multiple construction methods for a class, such as rebuilding from a serialized form vs. normal internal construction with explicit parameters. This recipe gives an example of using class level methods to create such constructors.'}, {'comments': [], 'desc': u"By storing an object's data in a dictionary, you can easily create a Filter class which tests a given object against a set of nested inclusion rules. This works particularly well for database filtering."}, {'comments': [{'comment': u"For the sake of robustness I'd suggest using, e.g., isinstance(object, ClassType) rather than type(object) == ClassType.\n", 'title': u'Use isinstance rather than comparing types'}], 'desc': u'Python has an extremely flexible object model that allows for assignment of arbitrary objects to arbitrary attributes of instances. I would like to do something like this:\ndef button( self ): print "Pressed!"\nand then assign it to an instance:\nmywidget.bigred = button\nand call it:\nmywidget.bigred()\n\nHowever this doesn\'t work because the attribute needs to be a bound method, not a function. Also, the name of the installed function remains button (eg. in stack traces), when we would like it to be bigred. \n\nThis recipe provides the installmethod() and renamefunction() functions to solve this problem.'}, {'comments': [{'comment': u"You don't need to import the imp module, just sys. A previous version of this code used imp.", 'title': u'Oops'}, {'comment': u"You don't need to look in sys.modules and store imported module there. Built-in __import__ already do this. So, _get_mod can be simplified:\n<pre>\ndef _get_mod(modulePath):\n return __import__(modulePath, globals(), locals(), ['*'])\n</pre>", 'title': u' '}, {'comment': u'This may have been obvious to some people but it wasn\'t for me. The following is an example of how to get a new instance:<br><br>\n\nimport new<br><br>\n\ntmpClass = _get_class("command.TestCommand")<br>\ntestCommand = new.instance(tmpClass)<br><br>\n\nhttp://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html?page=1', 'title': u'getting a new instance'}], 'desc': u'Allows you to load modules from packages without hard-coding their class names in code; instead, they might be specified in a configuration file, as command-line parameters, or within an interface.'}, {'comments': [], 'desc': u'Problem:\nYou want to use urllib to fetch web pages.\nYou are not able to do it with the standard library functionality.\n\nSolution:\nIntercept the urllib.URLopener method.\n'}, {'comments': [{'comment': u'<pre>\n\n# Modified on 18th Oct\nI have modified this recipe to print a Usage string,\nand it now takes command line options. While combining\nit does not need the number of chunks and works with\nall the chunks in the current directory.\n\n-Anand\n</pre>', 'title': u'Refactored...'}, {'comment': u'I made a slight modification to the combine function. See how I appended "data" to the file from each chuck, instead of holding a large "data" object in memory.\n\n', 'title': u'Files larger than physical memory on machine'}, {'comment': u'Here is the code:\n<pre>\n try:\n cmbf = open(bname, \'ab\')\n for f in chunkfiles:\n\n try:\n print \'Appending chunk\', os.path.join(".", f)\n #data += open(f, \'rb\').read()\n data = open(f, \'rb\').read()\n cmbf.write(data)\n except (OSError, IOError, EOFError), e:\n print e\n continue\n cmbf.close()\n\n except (OSError, IOError, EOFError), e:\n raise FileSplitterException, str(e) \n\n #try:\n # f = open(bname, \'wb\')\n # f.write(data)\n # f.close()\n #except (OSError, IOError, EOFError), e:\n # raise FileSplitterException, str(e)\n\n print \'Wrote file\', bname</pre>', 'title': u'File size larger than Physical Memory available'}, {'comment': u"Here is the code to get 3 digits for numeration of each file (for split mode, near of line #107 for me):<br>\n<pre>\nchunkfilename = bname + ('-%03d' % (x+1)) + self.__postfix\n</pre>", 'title': u'constant filename length'}, {'comment': u'Here is the code to generate each files in the same directory the the source (near line #94 for me):<br>\n<pre>\n #bname = (os.path.split(self.__filename))[1]\n ## output to the same directory\n bname = self.__filename\n</pre>', 'title': u'Output to the same directory'}], 'desc': u'This module can be used to split any file, text or binary\nto equal sized chunks. It can also combine the chunks back\nto recreate the original file.'}, {'comments': [], 'desc': u"This code can be used in debugging phase to notice errors sooner. It is usually always desirable to visit all base class __init__-methods, but Python does nothing to ensure they will be visited. Set AssertInit as a metaclass in the base class of your class hierarchy, and all errors from not calling base class __init__s will be cleanly reported as AssertionErrors.\n\nThe solution should work properly with multiple inheritance and diamond-shaped inheritance graphs (see the example at the bottom of code).\n\nIt slows down object creation by a large amount (I'd assume but didn't do any tests)."}, {'comments': [{'comment': u'i did not find it in the code .\n\nthanks.', 'title': u'where did you define the load_params method ?'}], 'desc': u'Both ASP and mod_python allow you to deploy web applications written in Python. This recipe allows you to push that decision down to your deployers, rather than your programmers. By abstracting the webserver, the same Python application can be deployed on either platform without rewriting.'}, {'comments': [{'comment': u'str(x) can fail and throw an exception, if x is unicode', 'title': u'unicode'}, {'comment': u"I suggest the following (works for 2.3, don't know about earlier versions):\n\n<pre>\ndef is_a_number(x):\n try:\n float(x)\n return True\n except ValueError:\n return False\n</pre>", 'title': u'Different approach'}, {'comment': u'This method works nicely to detect strings, etc being passed as parameters into a function when only numeric values are allowed. It fails, however, if the parameter passed in is a list. To avoid problems there, augment the method a trifle:\n<pre>\ndef is_a_number(x):\n try:\n float(x)\n return True\n except ValueError:\n return False\n except TypeError:\n return False\n</pre>', 'title': u'Need to check for lists'}], 'desc': u'This recipe uses a regular expression to determine whether or not the argument to the function is in a numeric format (integer, floating point, scientific, or engineering). '}, {'comments': [{'comment': u"Here is an improved version that uses generators in Python 2.3.\nThis version will also handle subdirectories and directory names.<br>\n<pre>\n#!/usr/bin/env python\n\nimport os\n\ntop = raw_input('Enter directory name: ')\n\nfor root, dirs, files in os.walk(top, topdown=False):\n for filename in files:\n os.rename(os.path.join(root, filename), os.path.join(root, filename.lower()))\n for dirname in dirs:\n os.rename(os.path.join(root, dirname), os.path.join(root, dirname.lower()))\n</pre>", 'title': u'Improved version'}], 'desc': u'lowers the case of all the items found in a specified directory'}, {'comments': [{'comment': u"Note that if you change this example to have functions, you need to store the 'photo' variable somewhere. When photo has been garbage-collected once the mainloop starts, you won't see your picture.", 'title': u' '}], 'desc': u"Reads an image file from the filename specified as the 1st parameter on the command line and displays it on screen. Uses the PIL module so that it can load almost any image file type supported by that module and uses Tkinter to display the image on a Tkinter canvas.\n\nI'm new to Python so excuse the clunkyness of implementation."}, {'comments': [], 'desc': u'This article discusses how to use jython to connect to an MS Excel file via ODBC using the JDBC-ODBC bridge.'}, {'comments': [{'comment': u'Boiling down to the essentials I get this from your script<br>\n\n<pre>\nprio = {\'^\':5, \'*\':4,\'/\':4,\'+\':3,\'-\':3,\'(\':2,\')\':1}\n\ndef topostfix(infix_src):\n postfix = list()\n stack = list()\n for x in shlex.shlex( infix_src ):\n\tif x.isdigit():\n postfix.append(x)\n if x in \'+-*/^\':\n while len( stack ) and prio[x] <= prio[ stack[-1]]:\n postfix.append( stack.pop() ) \n stack.append(x)\n if x == \'(\':\n stack.append(x) \n if x == \')\':\n while stack[-1] != \'(\':\n postfix.append(stack.pop())\n stack.pop()\n \n while len(stack):\n if(stack[-1] == "("):\n stack.pop()\n else:\n postfix.append( stack.pop() )\n\n return postfix\n</pre>\n\nYour algorithm works so far, but not for expressions like -1-2 or 3*-1\n\nany idea how to fix this?', 'title': u'Shortification'}], 'desc': u'Use this to convert an infix expression to postfix and vice-versa. You can also evaluate infix and postfix expressions.'}, {'comments': [{'comment': u'If the idea is to return a list containing unique<br>\nrandom elements of the passed list, this code<br>\ndoes the same, albeit in much fewer lines.<br><br>\n\n<pre>\ndef pickNums2(nums, numArr):\n\n if (nums > len(numArr)):\n return -1\n\n Random().shuffle(numArr)\n return numArr[:nums]\n\nprint pickNums2(2, [1,2,3,4,5,6,7,8,9,10])\n</pre>\nMaybe I am missing something here. \nThen correct me.<br><br>\n\n-Anand<br>', 'title': u'Err, too much trouble?'}, {'comment': u">>> random.sample(['1','2','3','4','5','6','7'], 2)\n['2', '5']", 'title': u'For Py2.3, this function is already built in'}, {'comment': u'this script doesnt do a decend job in selecting random numbers, and like Raymond points out, is redundant. Also a highly inefficient way of doing this. Can we loose it?', 'title': u'not recommended'}], 'desc': u'Picks a number of unique random elements from a list.'}, {'comments': [{'comment': u"What is the point of using a class method instead of a normal instance method here? <br>\n<br>\nYou call the method loadList on the instance Animals() and not on the class Animals. Furthermore you don't use the cls passed to loadList.", 'title': u'Uhm..'}], 'desc': u'My script shows one use for class methods, i.e. to map Relational tables and rows to objects in python. class methods come in handy when you want all objects in a class to share one method, in this case to retrieve rows from a table.'}, {'comments': [{'comment': u'Is it really appropriate to put such platform-specific code here?', 'title': u' '}, {'comment': u"Simon's recipe is very powerful and fills a great need for anybody working on graphs and having to render them. Why deny this to the large number of Python users on Windows?\n\nRather than criticizing the platform dependency, build an equivalent recipe for your platform of choice!", 'title': u'Yes, we certainly need platform-dependent recipes like this'}], 'desc': u'Convert graphs in the DOT format to SVG on Windows.'}, {'comments': [{'comment': u"Neat trick, but be careful - it won't work if arg is None.\n", 'title': u'Caveat'}, {'comment': u'In curry2:\n<pre>\nreturn func(args, *args)\n</pre>\nshould be \n<pre>\nreturn func(arg, *args)\n</pre>\nI think.', 'title': u'Typo'}, {'comment': u"Very cool! I have been thinking about doing a C implementation of this partial application for a long time; this will hold me off for the time being :-) I still might, though, if I ever find a need for applying partially to keyword arguments or ordered arguments other than the first one.\n<br><br>\nIt's a neat hack, I just hope python-dev doesn't decide to break it ;-)", 'title': u'partial application'}, {'comment': u"If you still have 1.5.2 lying around somewhere, you could look at bytecodehacks.xapply. It works by rewriting the bytecode of a function with 'LOAD_FAST n' for small n into an appropriate LOAD_CONST.\n<br><br>\nIt was also by far the hairiest code I'd ever written at the time :-)", 'title': u'an old bytecodehack is probably faster still'}, {'comment': u"For binding a single argument, new.function has the same performance as new.instancemethod, and it can be used to bind arbitrarily many arguments with equal performance:\n\n<pre>\nimport new\n\ndef curry1(func, *args):\n return new.function(func.func_code, func.func_globals, argdefs=args)\n\ndef curry2(func, *args):\n if not len(args): return func\n\n arg = args[0]\n curried = new.instancemethod(func, arg)\n return curry2(curried, *args[1:])\n\ndef curry3(func, *args):\n def curried(*args2):\n\targs2 = args + args2\n\treturn func(*args2)\n return curried\n\ndef f(a, b, c):\n return a, b, c\n\ng1 = curry1(f, 23, 45)\ng2 = curry2(f, 23, 45)\ng3 = curry3(f, 23, 45)\n\n# oat (josh) ~$ python timeit.py -c -s'import curry' 'curry.g1(67)'\n# 1000000 loops, best of 3: 0.97 usec per loop\n# oat (josh) ~$ python timeit.py -c -s'import curry' 'curry.g2(67)'\n# 1000000 loops, best of 3: 1.4 usec per loop\n# oat (josh) ~$ python timeit.py -c -s'import curry' 'curry.g3(67)'\n# 100000 loops, best of 3: 2.1 usec per loop\n</pre>", 'title': u'Binding multiple arguments'}, {'comment': u"I might be dense, but, using 2.3.2 on Win2K SP4+:\n<pre>\n def triple(a, b, c): return (a, b, c)\n\n curry1(triple, 1) (2, 3)\n--> (2,3,1)\n curry1(triple, 1,2,3) (4, 5)\n--> (4,5,3)\n curry1(max, 1)(2)\n---> Failure: curry1 doesn't work on builtin_function_or_method.\n (nor type, nor ...) Seems to be user-defined functions.\n</pre>", 'title': u'I might be dense, but ...'}], 'desc': u'instancemethod provides a way to perform currying such that the curried function runs much faster than one produced by closure (the second-fastest way). [Currying is explained and covered in detail in other recipes]'}, {'comments': [{'comment': u"Doesn't the add method need to check if the new element is already in the set? As it's inserted with insort_left, it could be equal to its immediate successor in the list.\nKeith", 'title': u'Set.add problem?'}, {'comment': u'Yes. Will fix it. Thanks.', 'title': u' '}, {'comment': u"I didn't see any fix from Raymond, so I suggest:\n<pre>\n def add(self, elem): # fixed by KMB\n i=bisect_left(self.data,elem)\n if i==len(self.data):\n self.data.append(elem)\n else:\n if self.data[i]!=elem: self.data.insert(i,elem)\n</pre>", 'title': u'Fix for Set.add problem'}], 'desc': u"Inspired by Py2.3's TimSort, this implementation of sets.py uses sorted lists instead of dictionaries. For clumped data patterns, the set operations can be super-efficient (for example, two sets can be determined to be disjoint with only O(n) comparisons). Also note, that the set elements are *not* required to be hashable; this provides a great deal more freedom than dictionary based implementations."}, {'comments': [], 'desc': u'This snippet shows how to use of jython to create an interactive environment for querying an LDAP database, searching a user/group and listing the attributes of that User/Group.'}, {'comments': [], 'desc': u'A simple (but not hopelessly fragile) approach for string substitution.'}, {'comments': [{'comment': u"This is interesting, but what's it do? It's hard to follow the inputs to the outputs. These input data should be labeled more clearly and you should explain what is going to happen to the input. Like any good recipe it's nice to give hints on when you would want to serve it.", 'title': u'Needs a bit more explaination'}, {'comment': u'This might be ultra-cool, but even then it would benefit from a couple of comments explaining some things for people to read before running the code, or they might not run it at all.', 'title': u'Needs some comments '}], 'desc': u'Python implementation of DCT/DST.'}, {'comments': [{'comment': u"Note to user.. \n\nIf you copy the script and make it executable (i.e. chmod +x pyrobocopy.py) without adding a script interpreter declaration (#!/usr/bin/env python) at the top of the file, the script will not work.\n<br>\nHere is the error output \n<pre>\n$ pyrobocopy.py\n/usr/local/bin/pyrobocopy.py: line 15: pyrobocopy.py -\n\n Version: 0.1\n\n Report the difference in content\n of two directories, synchronize or\n update a directory from another, taking\n into account time-stamps of files etc.\n\n By Anand B Pillai\n\n (This program is inspired by the windows\n 'Robocopy' program.)\n\n: command not found\n/usr/local/bin/pyrobocopy.py: line 20: syntax error near unexpected token `('\n/usr/local/bin/pyrobocopy.py: line 20: `def usage():'\n</pre>", 'title': u'Missing the script interpreter declaration'}, {'comment': u"<pre>\nI normally work on a Windows 2000 box\nwhere '.py' and '.pyw' files are associated\nwith python <pre>\nI normally work on a Windows 2000 box\nwhere '.py' and '.pyw' files are associated\nwith python </pre></pre>", 'title': u' '}, {'comment': u"<pre>\nI normally work on a Windows 2000 box\nwhere '.py' and '.pyw' files are associated\nwith python <pre>\nI normally work on a Windows 2000 box\nwhere '.py' and '.pyw' files are associated\nwith python </pre></pre>", 'title': u' '}, {'comment': u"Nice script! I'll use this instead of rsync for simpler stuff!\n\nI think I see a bug. should all references be to dir2 in this code?\n<pre>\n if not os.path.exists(dir2):\n if self.__forcecopy:\n os.chmod(os.path.dirname(dir2), 0777)\n os.makedirs(dir1)\n</pre>\nAlso, what effect does the chmod have on Windows?\n\nI was very happy to see that on windows if I added my tools/python directory to my path, I could just type robocopy.py at a command line anywhere to use this! Very nice!", 'title': u'Very useful!'}, {'comment': u'My original comments got screwed up somehow by ASPN ;-).<br>\n<br>\nOn windows if you associate ".py" extension to python you<br>\ndont need to worry about running the program. Just type<br>\n\'robocopy.py\' at the command prompt, thats all.<br>\n<br>\nOn unix/linux you can add a line like the following at the<br>\ntop of the file.<br><br>\n<pre>#!/usr/bin/python</pre>\n<br>\nThe pointed out line is not a bug. The target directory is \'dir2\'<br>\nso the chmod tries to change its permissions. On windows this does<br>\nnot have any effect AFAIK.<br>\n<br>', 'title': u' '}, {'comment': u'I like the implementation, however I think the command structure would be more consise using the following format. \n<br>\n<pre>\n$ pyrobocopy.py [OPTIONS] sourcedir targetdir \n<br></pre>', 'title': u'Just a thought..'}, {'comment': u'Command structure now works both ways.<br><br>\n$pyrobocopy.py [OPTIONS] <sourcedir> <targetdir><br>\nas well as,<br><br>\n$pyrobocopy.py <sourcedir> <targetdir> [OPTIONS]<br><br>\n-Anand', 'title': u'Cmd structure modification'}, {'comment': u'Fixed an error in copying sub-directories that<br>\ndid not exist in target directory.<br>\nThe script was skipping some sub-directories earlier.<br>\n<br><br>\n-Anand<br>\n<br>', 'title': u'Fixed an error'}, {'comment': u"You may also be interested in dirssync project at Sourceforge.\n\n<br><br>\n\nDescription:<br>\nThe goal is to synchronize 2 directories. This application will synchronize all the files and all the sub-directories, and prompt the user to confirm all the moves. It's written in python and with wxPython.\n\n<br><br>\n\nLink:<br>\nhttp://sourceforge.net/projects/dirssync/", 'title': u'Dirssync at Sourceforge'}, {'comment': u'You might also be interested in the dfp project.\n<br>\n<br>\nDescription:<br>\nA frequent software pattern is processing files that have changed:<br>\n\n- an incremental backup system, which will add new and changed files to\nan archive or transfer them to another computer<br>\n\n- a website update with the latest changes<br>\n\n- automatic processing, like compiling changed source code<br>\n\n- software integrity check: detect changed files and raise an alert\n<br>\n\ndfp is a suite of components which permit to detect changed files and to\nprocess them.\n\n<br>\n\n<br>\nLink:<br>\nhttp://www.homepages.lu/pu/dfp.html\n\n', 'title': u'dfp project'}, {'comment': u'I found the PyRobocopier very useful, but my favorite client (my wife) wanted to have multiple versions backed up. I added a __backver method and some supporting code. The idea is that if a file has already been backed up, the old version is copied to a generation-numbered file; if that generation already exists, it is itself copied to a new backup and so on. A \'maxvers\' variable determines the oldest permitted generation (I use 3 in my code, which allows the current file and three past generations all to be stored in the backup directory). Not everyone would want this feature, so I also added a -v command-line switch that must be specified if versions are to be generated. \n\nThe versioned files are readily identifiable in the directory; they are named with this format: \n\'%s%d_%s\' % (self.backstr, vernum, original_name)\n... so that \'abc.jpg\' is backed up under the name \'_bak1_abc.jpg\', etc. The highest \'vernum\' digit is the oldest backup. When the limit is reached in a directory, no new files are created, but the generation-shuffling still takes place.\n\nIf anyone else happens to be interested, here is a WinXP fc between the original (labeled pyRobocopierPy_orig.txt) and the altered version (labeled PYROBOCOPIER.PY):\n\nComparing files pyRobocopierPy_orig.txt and PYROBOCOPIER.PY\n\n<pre>\n***** pyRobocopierPy_orig.txt\n 36: Additional Options:\\n\n 37: \\t-p, --purge - Purge files when synchronizing (does not purge by default).\n***** PYROBOCOPIER.PY\n 41: Additional Options:\\n\n 42: \\t-v, --versions - Create backup versions in same directories\n 43: \\t-p, --purge - Purge files when synchronizing (does not purge by default).\n*****\n\n***** pyRobocopierPy_orig.txt\n 60: \n 61: self.__copyfiles = True\n***** PYROBOCOPIER.PY\n 66: \n 67: # don\'t do version backups unless specified\n 68: self.__versions = False\n 69: # depth of version backups\n 70: self.maxvers = 3\n 71: # backup copy flag string\n 72: self.backstr = \'_bak\'\n 73: \n 74: self.__copyfiles = True\n*****\n\n***** pyRobocopierPy_orig.txt\n 92: \n 93: shortargs = "supncm"\n 94: longargs = ["synchronize=", "update=", "purge=", "nodirection=", "create=", "modtime="]\n 95: \n***** PYROBOCOPIER.PY\n 105: \n 106: shortargs = "supncmv"\n 107: longargs = ["synchronize=", "update=", "purge=", "nodirection=", "create=", "modtime=","versions="]\n 108: \n*****\n\n***** pyRobocopierPy_orig.txt\n 128: self.__modtimeonly = True \n 129: else:\n***** PYROBOCOPIER.PY\n 141: self.__modtimeonly = True \n 142: elif option.lower() in (\'-v\', \'--versions\'):\n 143: self.__versions = True \n 144: else:\n*****\n\n***** pyRobocopierPy_orig.txt\n 216: print \'Copying tree\', fulld2\n 217: shutil.copytree(fulld1, fulld2)\n***** PYROBOCOPIER.PY\n 231: print \'Copying tree\', fulld2\n 232: if self.__versions:\n 233: self.__backver(dir2,f1)\n 234: shutil.copytree(fulld1, fulld2)\n*****\n\n***** pyRobocopierPy_orig.txt\n 244: self.__dowork(fulld1, fulld2, copyfunc, updatefunc)\n 245: \n 246: \n***** PYROBOCOPIER.PY\n 261: self.__dowork(fulld1, fulld2, copyfunc, updatefunc)\n 262: \n 263: # Addendum by RZ 20051221\n 264: # The idea here is to make backup versions of existing files, to a \n 265: # depth specified by self.maxvers. The backup version names will be \n 266: # generated by prepending a string (self.backstr) and an int, which \n 267: # increases with each level, separated by underscores. As written,\n 268: # this means _bak1_xxx.xxx, _bak2_..., etc. The __backver me', 'title': u'How about multiple backup versions?'}], 'desc': u"This program is an advanced directory synchronization\nand update tool. It can be used to update content between\ntwo directories, synchronize them, or just report the\ndifference in content between them. It uses the syntax\nof the 'diff' program in printing the difference."}, {'comments': [{'comment': u"It appears that this recipe performs the same sequence of node expansions (that is, calls to children) as Korf's depth-first iterative deepening algorithm:\n<pre>\ndef dfid(T,children,callback):\n def visit(node,i):\n if i == 0:\n callback(node)\n else:\n for c in children(node):\n visit(c,i-1)\n i = 0\n while 1:\n visit(T,i)\n i += 1\n</pre>\nHowever, the recursion structure of the recipe is upside down compared to DFID: in DFID, we have a call chain from the root of the tree to each generated node, while here the call chain goes in the opposite direction. This inverted structure makes it possible to output the visited nodes as a simple generator stream, rather than passing them to a callback or otherwise processing them within the recursive visit. Also, I think the code in the recipe is much simpler than that for DFID, especially if T is infinite (as in most DFID applications) which would allow one to omit the recipe lines involving variable last.", 'title': u'Iterative deepening'}, {'comment': u'Hi, I\'m a python newbie and my head is spinning a bit from this recursive generator, so please forgive my naivety. I have some questions based upon a couple examples I\'ve tried:\n<pre>\n# --- Example 1 ---\n>>> tree = [0]\n>>> for x in breadth_first(tree):\n... print x\n... \n[0]\n0\nTraceback (most recent call last):\n File "", line 1, in ?\n File "", line 10, in breadth_first\nTypeError: iteration over non-sequence\n# -----------------</pre>\n\n- Should there be a try/except in the code to catch the case where a terminal element is not iterable?\n\n<pre># --- Example 2 ---\n>>> tree = [[\'00\'],[\'10\'],\'2\']\n>>> for x in breadth_first(tree):\n... print x\n... \n[[\'00\'], [\'10\'], \'2\']\n[\'00\']\n[\'10\']\n2\n00\n10\n2\n# -----------------</pre>\n- why is \'2\' output twice? Is this by design? e.g. also in the case of "tree = [\'0\',\'1\']", \'0\' is output twice.<br>\n- why aren\'t the strings \'00\' and \'01\' iterated through, since they are iterable? Is this algorithm only for trees of a uniform depth?\n', 'title': u'What kind of trees?'}, {'comment': u'To answer the last question first, \'2\' is output twice because, when you iterate through the items in a string such as \'2\', you get the characters in that string, and this string has one character in it, namely \'2\' again. Apparently the code then detects the infinite recursion and stops.<br><br>\nAnyway, re "what kind of tree": the child function needs to be callable on all the nodes of the tree, including any leaves it might have. One somewhat trivial example would be a nested list of lists, without any other kind of object in it: [[[][]][]].<br><br>\nOr, if you want to mix lists and other kinds of objects, you could use a child function something like this:\n<pre>\n def children(node):\n if isinstance(node,list):\n return iter(node)\n else:\n return []\n</pre>\n\nHere\'s another possible child function, which will do a breadth first traversal of a filesystem hierarchy:\n<pre>\n def children(path):\n if os.path.isdir(path):\n for filename in os.listdir(path):\n yield os.path.join(path,filename)\n</pre>', 'title': u' '}, {'comment': u'Ah, I see... it didn\'t occur to me to play with the "children" iterator to avoid the exception or redundant output. Now, of course, it seems obvious. Your usage examples helped me a lot. Thanks very much! :)\n', 'title': u'Thanks!'}, {'comment': u'I believe a bread-first search is normally understood to be non-backtracking, and that this code does not perform a valid breadth-first search.\n\nThe problem is that the \'last\' variable only prevents backtracking to the last visited node, not to any previously visited node. But if we are searching even a finite network with loops, we must beware of the latter condition. For instance, consider the network of only three points A, B, and C that form a triangle:\n\n<pre>\ndef children(ch):\n if ch == \'A\': return [\'B\',\'C\']\n elif ch == \'B\': return [\'A\',\'C\']\n elif ch == \'C\': return [\'A\',\'B\']\n else: return\n</pre>\n\nNow consider the resulting iterator object:\n\n<pre>\n>>> s = breadth_first(\'A\',children)\n\n>>> s.next()\n\'A\'\n\n>>> s.next()\n\'B\'\n\n>>> s.next()\n\'C\'\n\n>>> s.next()\n\'A\'\n</pre>\nThis is an infinite loop. Another error: the standard queue algorithm has O(h) space complexity (where h is the number of nodes), not something more as is stated above. \n\nHere is an implementation of a breadth-first search, which also returns an iterator object as above, but which uses the standard queue algorithm:\n\n<pre>\ndef bfs(root,visitable,children=iter):\n """Iterator traverses a tree in breadth-first order.\n \n The first argument should be the tree root; visitable should be an\n iterable with all searchable nodes; children should be a function\n which takes a node and return an iterator of the node\'s children.\n """\n queue = []\n # makes a shallow copy, makes it a collection, removes duplicates\n unvisited = list(set(visitable))\n \n if root in unvisited:\n unvisited.remove(root)\n queue.append(root)\n\n while len(queue) > 0:\n node = queue.pop(0)\n yield node\n\n for child in children(node):\n if child in unvisited:\n unvisited.remove(child)\n queue.append(child)\n return\n</pre>\nThis function returns an iterator object that will terminate:\n<pre>\n>>> s = bfs(\'A\',[\'A\',\'B\',\'C\'], children)\n>>> s.next()\n\'A\'\n>>> s.next()\n\'B\'\n>>> s.next()\n\'C\'\n>>> s.next()\n--------------\nexceptions.StopIteration\n</pre>\nBy the way, since bfs() calls set() without importing sets, it requires Python2.4.', 'title': u'Not a valid breadth-first search'}], 'desc': u'Uses a recursively called simple generator (with the same arguments as the outer call!) to traverse a tree in breadth first order.'}, {'comments': [], 'desc': u'Ever been frustrated at having to separately read data and then do minor processing by calling methods on the data? Find yourself writing lambda functions or short generators to do intermediate processing between iterators? If so, you can simplify your programming life by using imapmethod instead. Imapmethod calls a named method on each item it iterates through. For example, you can replace [x.rstrip() for x in iterable], which inefficiently generates the whole list at once before processing begins, or the more efficient imap(lambda x: x.rstrip(), iterable) with imapmethod("rstrip", iterable) or even the provided irstrip(iterable).\n\nThis recipe also illustrates some more brain-twisting uses of itertools.'}, {'comments': [{'comment': u'This: <pre>(first <= second + error) and (first >= second - error)</pre>\ncan be rewritten as <pre>second - error <= first <= second + error</pre>\n<br>\n<br>\nAnd this:\n<pre>(first > second + error) or (first < second - error)</pre>\ncan be rewritten as\n<pre>not (second - error <= first <= second + error)</pre>', 'title': u'Take advantage of chained comparisons'}], 'desc': u'a test case to use with an interval insted of a single value'}, {'comments': [{'comment': u'In order to clarify all comments in the source code, kindly uses epydoc (http://epydoc.sourceforge.net) to generate a documentation.', 'title': u'Documentation in the source code'}], 'desc': u'This module is the Template Macro module. It preprocesses a web template in which variables and blocks are contained. This package plays an important role as an explicit boundary between web template designing and script implementation.'}, {'comments': [{'comment': u"Good tip, *but*...\n\nIf it's not really an INI file, don't use the 'ini' extension.", 'title': u'Calling a spade a spade.'}, {'comment': u'I use something similar\n\nmydict = {}\nexecfile(filename,globals(),mydict)\n\n', 'title': u'What is the diference if I use execfile?'}, {'comment': u'try to write dialog driven software with check-boxes, drop-down-lists etc. to edit those ini-files.', 'title': u'Nice idea, BUT'}, {'comment': u'This may be "easy", but it\'s not necessarily "wise". Why even bother having config files, why not just put all configurable constants into the code? Well, because maintaining code, which can take actions and contain complicated logic is far harder than maintaining mere data, which can\'t take actions, can\'t modify itself or other things, and can\'t react to it\'s environment in unpredictable ways. Even when data is highly structured, it\'s still far simpler than code. That\'s why config files should almost always remain as pure data.', 'title': u'Not a good idea'}], 'desc': u'Traditional configuration files are static in their nature. Using Python as configuration language will give the application user a dynaimc environment to configure the application.\n\nUsing Python\'s build in "execfile" this is very easy to implement.'}, {'comments': [{'comment': u'Could you explain why a Python programmer would want Java-style inner classes? As far as I remember (admittedly not much) inner classes are used to fake closures, a non-issue in Python. So why would a Python programmer want them?', 'title': u'Why?'}, {'comment': u'Actually, I think anonymous classes are what Java uses to fake closures. Named inner classes, as far as I know, are used simply to express a constraint of the object-oriented design - that it makes no sense for an instance of the inner class to exist without an associated instance of the enclosing class.\n<br>\nThis recipe is just a way to express and enforce that same constraint in Python.\n<br>\nTo be honest, I haven\'t used this recipe myself - it just occured to me when I noticed in the documentation of new.instancemethod that the first agument can be any callable - it does not specifically have to be a function.\n<br>\nOff the top of my head, I can imagine using it for something like:\n<pre>\nfile = Menu("&File")\nopen = file.MenuItem("&Open")\nexit = file.MenuItem("E&xit")\n</pre>\n', 'title': u' '}, {'comment': u'I really don\'t see any reason to do this. When you created the class "Inner" which is constructed with an "Outer" reference, that sounded good. But going through a trick to prevent people from "cheating" by not passing a "Outer" instance where one is called for... that\'s not pythonic. If the user wants to shoot themselves in the foot, then allow them (but don\'t make it easy).\n\nBesides which, the design doesn\'t work. Python is flexible enough (and introspective enough) to allow a consumer to worm around nearly any restriction. In this case, it\'s trivial: here\'s one way to cheat:\n\n<pre>\n>>> out = Outer()\n>>> inner = out.Inner()\n>>> cheat = type(inner)()\n>>> type(cheat)\n<class \'__main__.Inner\'>\n>>> cheat.outer\n\'foo\'\n</pre>\n\nThe moral is that if, in Python, you want your users to pass in an instance of "Outer", then DOCUMENT IT, and then stop there. If they want to break the rules, they do so at their own peril.', 'title': u'Seems UnPythonic to me'}], 'desc': u"People used to Java often want Python to have inner classes - that is, classes that can not be instantiated without being associated with an instance of their containing class. There are probably a great many ways to do this. Here's one of them."}, {'comments': [{'comment': u"For the application for which this was written, the code given is OK, but it would creak a lot with a long string to convert. I'm sure the following is much faster:\n<pre>\nimport re\n\nxlate = {0xc0:'A', 0xc1:'A', 0xc2:'A', 0xc3:'A', 0xc4:'A', 0xc5:'A',\n... }\n\nnonasciire = re.compile(u'([\\x00-\\x7f]+)|([^\\x00-\\x7f])', re.UNICODE).sub\n\ndef latin1_to_ascii (unicrap):\n return str(nonasciire(lambda x: x.group(1) or xlate.setdefault(ord(x.group(2)), ''), unicrap))\n</pre>", 'title': u'Better method'}, {'comment': u"For the application for which this was written, the code given is OK, but it would creak a lot with a long string to convert. I'm sure the following is much faster:\n<pre>\nimport re\n\nxlate = {0xc0:'A', 0xc1:'A', 0xc2:'A', 0xc3:'A', 0xc4:'A', 0xc5:'A',\n... }\n\nnonasciire = re.compile(u'([\\x00-\\x7f]+)|([^\\x00-\\x7f])', re.UNICODE).sub\n\ndef latin1_to_ascii (unicrap):\n return str(nonasciire(lambda x: x.group(1) or xlate.setdefault(ord(x.group(2)), ''), unicrap))\n</pre>", 'title': u'Better method'}, {'comment': u"You can save a lot of time by using unicodedata.name and unicodedata.normalize.\n\nThe following code collects all unicode characters whose name starts with 'LATIN' in a dictionary:\n\n<pre>\nlatin_chars={}\nfor i in range(0xffff):\n u=unichr(i)\n try:\n n=unicodedata.name(u)\n if n.startswith('LATIN '):\n latin_chars[u]=n\n except ValueError:\n pass\n</pre>\n\nThis gives you a list of all the latin character names you might want to reduce to plain ASCII.\n\nRemember that you can use unicode character names in python unicode strings:\n<pre>\nunicode_a = u'\\N{LATIN SMALL LETTER A}'\nunicode_a_with_acute = u'\\N{LATIN SMALL LETTER A WITH ACUTE}'\n</pre>\n\nAlso, you could the use unicodedata.normalize function to decompose combinatorial unicode characters into their components. For instance,\n\n<pre>\n>>> unicodedata.normalize('NFKD', unicode_a_with_acute)\nu'a\\u0301'\n>>> unicodedata.name(u'\\u0301')\n'COMBINING ACUTE ACCENT'\n</pre>\n\nA possible approach to your problem might be:<br>\n1. Replace every unicode character in your text with its KD normal form using unicodedata.normalize;<br>\n2. Create a dictionary associating each unicode character that occurs in your text with its unicode name, using unicodedata.name;<br>\n3. Discard from the dictionary all items that correspond to plain vanilla ASCII characters;<br>\n4. Remove all unicode characters in the dictionary from your text, or replace them with some ASCII representation (e.g. u'\\u0301' -> u'\\N{COMBINING ACUTE ACCENT}');<br>\nHope that helps.", 'title': u'unicodedata is your friend'}, {'comment': u'If you don\'t want to make any changes to the behaviour of your code, you can still make it more readable by replacing the "xlate" dictionary with the following:\n<pre>\nxlate = {\n u\'\\N{ACUTE ACCENT}\': "\'",\n u\'\\N{BROKEN BAR}\': \'|\',\n u\'\\N{CEDILLA}\': \'{cedilla}\',\n u\'\\N{CENT SIGN}\': \'{cent}\',\n u\'\\N{COPYRIGHT SIGN}\': \'{C}\',\n u\'\\N{CURRENCY SIGN}\': \'{currency}\',\n u\'\\N{DEGREE SIGN}\': \'{degrees}\',\n u\'\\N{DIAERESIS}\': \'{umlaut}\',\n u\'\\N{DIVISION SIGN}\': \'/\',\n u\'\\N{FEMININE ORDINAL INDICATOR}\': \'{^a}\',\n u\'\\N{INVERTED EXCLAMATION MARK}\': \'!\',\n u\'\\N{INVERTED QUESTION MARK}\': \'?\',\n u\'\\N{LATIN CAPITAL LETTER A WITH ACUTE}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER A WITH CIRCUMFLEX}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER A WITH DIAERESIS}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER A WITH GRAVE}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER A WITH RING ABOVE}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER A WITH TILDE}\': \'A\',\n u\'\\N{LATIN CAPITAL LETTER AE}\': \'Ae\',\n u\'\\N{LATIN CAPITAL LETTER C WITH CEDILLA}\': \'C\',\n u\'\\N{LATIN CAPITAL LETTER E WITH ACUTE}\': \'E\',\n u\'\\N{LATIN CAPITAL LETTER E WITH CIRCUMFLEX}\': \'E\',\n u\'\\N{LATIN CAPITAL LETTER E WITH DIAERESIS}\': \'E\',\n u\'\\N{LATIN CAPITAL LETTER E WITH GRAVE}\': \'E\',\n u\'\\N{LATIN CAPITAL LETTER ETH}\': \'Th\',\n u\'\\N{LATIN CAPITAL LETTER I WITH ACUTE}\': \'I\',\n u\'\\N{LATIN CAPITAL LETTER I WITH CIRCUMFLEX}\': \'I\',\n u\'\\N{LATIN CAPITAL LETTER I WITH DIAERESIS}\': \'I\',\n u\'\\N{LATIN CAPITAL LETTER I WITH GRAVE}\': \'I\',\n u\'\\N{LATIN CAPITAL LETTER N WITH TILDE}\': \'N\',\n u\'\\N{LATIN CAPITAL LETTER O WITH ACUTE}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER O WITH CIRCUMFLEX}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER O WITH DIAERESIS}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER O WITH GRAVE}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER O WITH STROKE}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER O WITH TILDE}\': \'O\',\n u\'\\N{LATIN CAPITAL LETTER THORN}\': \'th\',\n u\'\\N{LATIN CAPITAL LETTER U WITH ACUTE}\': \'U\',\n u\'\\N{LATIN CAPITAL LETTER U WITH CIRCUMFLEX}\': \'U\',\n u\'\\N{LATIN CAPITAL LETTER U WITH DIAERESIS}\': \'U\',\n u\'\\N{LATIN CAPITAL LETTER U WITH GRAVE}\': \'U\',\n u\'\\N{LATIN CAPITAL LETTER Y WITH ACUTE}\': \'Y\',\n u\'\\N{LATIN SMALL LETTER A WITH ACUTE}\': \'a\',\n u\'\\N{LATIN SMALL LETTER A WITH CIRCUMFLEX}\': \'a\',\n u\'\\N{LATIN SMALL LETTER A WITH DIAERESIS}\': \'a\',\n u\'\\N{LATIN SMALL LETTER A WITH GRAVE}\': \'a\',\n u\'\\N{LATIN SMALL LETTER A WITH RING ABOVE}\': \'a\',\n u\'\\N{LATIN SMALL LETTER A WITH TILDE}\': \'a\',\n u\'\\N{LATIN SMALL LETTER AE}\': \'ae\',\n u\'\\N{LATIN SMALL LETTER C WITH CEDILLA}\': \'c\',\n u\'\\N{LATIN SMALL LETTER E WITH ACUTE}\': \'e\',\n u\'\\N{LATIN SMALL LETTER E WITH CIRCUMFLEX}\': \'e\',\n u\'\\N{LATIN SMALL LETTER E WITH DIAERESIS}\': \'e\',\n u\'\\N{LATIN SMALL LETTER E WITH GRAVE}\': \'e\',\n u\'\\N{LATIN SMALL LETTER ETH}\': \'th\',\n u\'\\N{LATIN SMALL LETTER I WITH ACUTE}\': \'i\',\n u\'\\N{LATIN SMALL LETTER I WITH CIRCUMFLEX}\': \'i\',\n u\'\\N{LATIN SMALL LETTER I WITH DIAERESIS}\': \'i\',\n u\'\\N{LATIN SMALL LETTER I WITH GRAVE}\': \'i\',\n u\'\\N{LATIN SMALL LETTER N WITH TILDE}\': \'n\',\n u\'\\N{LATIN SMALL LETTER O WITH ACUTE}\': \'o\',\n u\'\\N{LATIN SMALL LETTER O WITH CIRCUMFLEX}\': \'o\',\n u\'\\N{LATIN SMALL LETTER O WITH DIAERESIS}\': \'o\',\n u\'\\N{LATIN SMALL LETTER O WITH GRAVE}\': \'o\',\n u\'\\N{LATIN SMALL LETTER O WITH STROKE}\': \'o\',\n u\'\\N{LATIN SMALL LETTER O WITH TILDE}\': \'o\',\n u\'\\N{LATIN SMALL LETTER SHARP S}\': \'ss\',\n u\'\\N{LATIN SMALL LETTER THORN}\': \'th\',\n u\'\\N{LATIN SMALL LETTER U WITH ACUTE}\': \'u\',\n u\'\\N{LATIN SMALL LETTER U WITH CIRCUMFLEX}\': \'u\',\n u\'\\N{LATIN SMALL LETTER U WITH DIAERESIS}\': \'u\',\n u\'\\N{LATIN SMALL LETTER U WITH GRAVE}\': \'u\',\n u\'\\N{LATIN SMALL LETTER Y WITH ACUTE}\': \'y\',\n u\'\\N{LATIN SMALL LETTER Y WITH DIAERESIS}\': \'y\',\n u\'\\N{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}\': \'<<\',\n u\'\\N{MACRON}\': \'_\',\n u\'\\N{MASCULINE ORDINAL INDICATOR}\': \'{^o}\',\n u\'\\N{MICRO SIGN}\': \'{micro}\',\n u\'\\N{MIDDLE DOT}\': \'*\',\n u\'\\N{MULTIPLICATION SIGN}\': \'*\',\n u\'\\N{NOT SIGN}\': \'{not}\',\n u\'\\N{PILCROW SIGN}\': \'{paragraph}\',\n u\'\\N{PLUS-MINUS SIGN}\': \'{+/-}\',\n u\'\\N{POUND SIGN}\': \'{pound}\',\n u\'\\N{REGISTERED SIGN}\': \'{R}\',\n u\'\\N{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}\': \'>>\',\n u\'\\N{SECTION SIGN}\':', 'title': u'Improve readability by using unicode character names'}, {'comment': u"since the dictionary keys are now unicode characters, two lines must be changed to:\n<br>\n...\n<pre>\nif xlate.has_key(i):\n r += xlate[i]\n</pre>\n<br>\n...\n<br>\nit's even more readable now.\n<br><br>\nthanks a lot to both of you for the nice recipe.", 'title': u'almost. the code has to change a little bit ...'}, {'comment': u'Unicode strings have a \'translate\' function which takes the dictionary mapping unicode values to new text. If not present the character is left unchanged. If the mapped value is None then the character is deleted.\n<br>\n<br>\nHere\'s one way to use it to solve this problem. Call the fix_unicode() function \ndefined at the end of this comment. It takes the unicode string and returns\nthe hammered ASCII string.\n<pre>\n# If the character doesn\'t exist in the dictionary, add it as None\n# and also return None. This tells the translate to delete the character\n# and makes the next lookup for that character faster.\nclass XLate(dict):\n def __getitem__(self, c):\n try:\n return dict.__getitem__(self, c)\n except KeyError:\n self[c] = None\n return None\n\n# Define the translation table. I needed to hammer unicode going to\n# NCBI\'s web services (for Biopython\'s EUtils package) so I used the\n# table defined at\n# http://www.nlm.nih.gov/databases/dtd/medline_character_database.utf8\n# This is not as extensive as the original conversion set.\nclass XLate(dict):\n def __getitem__(self, c):\n try:\n return dict.__getitem__(self, c)\n except KeyError:\n self[c] = None\n return None\n\n# Convert these unicode characters into ASCII\nxlate = XLate({\n # The note at the bottom of the page says "the inverted question\n # mark represents a questionable character found as a result of\n # NLM\'s conversion from its legacy extended EBCDIC character set\n # to UNICODE UTF-8." I do not use it but leave it here for\n # completeness.\n ord(u"\\N{INVERTED QUESTION MARK}"): None,\n\n ord(u"\\N{LATIN CAPITAL LETTER O WITH STROKE}"): u"O",\n ord(u"\\N{LATIN SMALL LETTER A WITH GRAVE}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH ACUTE}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH CIRCUMFLEX}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH TILDE}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH DIAERESIS}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH RING ABOVE}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER C WITH CEDILLA}"): u"c",\n ord(u"\\N{LATIN SMALL LETTER E WITH GRAVE}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER E WITH ACUTE}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER E WITH CIRCUMFLEX}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER E WITH DIAERESIS}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER I WITH GRAVE}"): u"i",\n ord(u"\\N{LATIN SMALL LETTER I WITH ACUTE}"): u"i",\n ord(u"\\N{LATIN SMALL LETTER I WITH CIRCUMFLEX}"): u"i",\n ord(u"\\N{LATIN SMALL LETTER I WITH DIAERESIS}"): u"i",\n ord(u"\\N{LATIN SMALL LETTER N WITH TILDE}"): u"n",\n ord(u"\\N{LATIN SMALL LETTER O WITH GRAVE}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER O WITH ACUTE}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER O WITH CIRCUMFLEX}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER O WITH TILDE}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER O WITH DIAERESIS}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER O WITH STROKE}"): u"o",\n ord(u"\\N{LATIN SMALL LETTER U WITH GRAVE}"): u"u",\n ord(u"\\N{LATIN SMALL LETTER U WITH ACUTE}"): u"u",\n ord(u"\\N{LATIN SMALL LETTER U WITH CIRCUMFLEX}"): u"u",\n ord(u"\\N{LATIN SMALL LETTER U WITH DIAERESIS}"): u"u",\n ord(u"\\N{LATIN SMALL LETTER Y WITH ACUTE}"): u"y",\n ord(u"\\N{LATIN SMALL LETTER Y WITH DIAERESIS}"): u"y",\n ord(u"\\N{LATIN SMALL LETTER A WITH MACRON}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER A WITH BREVE}"): u"a",\n ord(u"\\N{LATIN SMALL LETTER C WITH ACUTE}"): u"c",\n ord(u"\\N{LATIN SMALL LETTER C WITH CIRCUMFLEX}"): u"c",\n ord(u"\\N{LATIN SMALL LETTER E WITH MACRON}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER E WITH BREVE}"): u"e",\n ord(u"\\N{LATIN SMALL LETTER G WITH CIRCUMFLEX}"): u"g",\n ord(u"\\N{LATIN SMALL LETTER G WITH BREVE}"): u"g",\n ord(u"\\N{LATIN SMALL LETTER G WITH CEDILLA}"): u"g",\n ord(u"\\N{LATIN SMALL LETTER H WITH CIRCUMFLEX}"): u"h",\n ord(u"\\N{LATIN SMALL LETTER I WITH TILDE}"): u"i",\n ord(u"\\N{LATIN SMALL LETTER I WITH MACRON}"): u"i",\n ord(u"\\', 'title': u'a cleaner solution'}, {'comment': u"A very simple, and obviously-correct way to do this is like so:\n<pre>unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')</pre>\n\nIt has the advantage that you don't need to enumerate any particular conversions-- any accented latin characters will be reduced to their base form, and non-ascii characters will be stripped.<br><br>\n\nBy normalizing to NFKD, we transform precomposed characters like \\u00C0 (LATIN CAPITAL LETTER A WITH GRAVE) into pairs of base letter \\u0041 (A) and combining character \\u0300 (GRAVE accent).<br><br>\n\nConverting to ascii using 'ignore' strips all non-ascii characters, e.g. the combining characters. However, it will also strip other non-ascii characters, so if there are no latin characters in the input, the output will be empty.", 'title': u'Using NFKD'}, {'comment': u'BTW this is very, very useful. Thanks for this thread.\n\nI had been solving this issue by using a modified version of Skip Montanaro\'s latscii, which creates a string encoding (a codec) that does that, but I like your unicodedata solution better::\n\n<pre>\n\n# -*- coding: latin-1 -*-\n""" Character mapping codec which removes accents from latin-1 characters\n\nWritten by Skip Montanaro (skip@pobox.com) using the autogenerated cp1252\ncodec as an example.\n\n(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.\n(c) Copyright 2000 Guido van Rossum.\n\n"""#"\n\nimport codecs\n\n### Codec APIs\n\nclass Codec(codecs.Codec):\n\n def encode(self,input,errors=\'strict\'):\n\n return codecs.charmap_encode(input,errors,encoding_map)\n\n def decode(self,input,errors=\'strict\'):\n\n return codecs.charmap_decode(input,errors,decoding_map)\n\nclass StreamWriter(Codec,codecs.StreamWriter):\n pass\n\nclass StreamReader(Codec,codecs.StreamReader):\n pass\n\n### encodings module API\n\ndef getregentry():\n\n return (Codec().encode,Codec().decode,StreamReader,StreamWriter)\n\n### Decoding Map\n\ndecoding_map = codecs.make_identity_dict(range(256))\nfor x in range(0x80, 0xa0):\n decoding_map[x] = ord(\'?\') # undefined\ndecoding_map.update({\n 0x00a1: ord(\'!\'), # A\xa1\n 0x00a2: ord(\'c\'), # A\xf8\n 0x00a3: ord(\'#\'), # A\xa3\n 0x00a4: ord(\'o\'), # A\x0f\n 0x00a5: ord(\'Y\'), # A\xd8\n 0x00a6: ord(\'|\'), # A\u258c\n 0x00a7: ord(\'S\'), # A\x15\n 0x00a8: ord(\'"\'), # A"\n 0x00a9: ord(\'c\'), # Ac\n 0x00aa: ord(\'a\'), # A\xaa\n 0x00ab: ord(\'BTW this is very, very useful. Thanks for this thread.\n\nI had been solving this issue by using a modified version of Skip Montanaro\'s latscii, which creates a string encoding (a codec) that does that, but I like your unicodedata solution better::\n\n<pre>\n\n# -*- coding: latin-1 -*-\n""" Character mapping codec which removes accents from latin-1 characters\n\nWritten by Skip Montanaro (skip@pobox.com) using the autogenerated cp1252\ncodec as an example.\n\n(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.\n(c) Copyright 2000 Guido van Rossum.\n\n"""#"\n\nimport codecs\n\n### Codec APIs\n\nclass Codec(codecs.Codec):\n\n def encode(self,input,errors=\'strict\'):\n\n return codecs.charmap_encode(input,errors,encoding_map)\n\n def decode(self,input,errors=\'strict\'):\n\n return codecs.charmap_decode(input,errors,decoding_map)\n\nclass StreamWriter(Codec,codecs.StreamWriter):\n pass\n\nclass StreamReader(Codec,codecs.StreamReader):\n pass\n\n### encodings module API\n\ndef getregentry():\n\n return (Codec().encode,Codec().decode,StreamReader,StreamWriter)\n\n### Decoding Map\n\ndecoding_map = codecs.make_identity_dict(range(256))\nfor x in range(0x80, 0xa0):\n decoding_map[x] = ord(\'?\') # undefined\ndecoding_map.update({\n 0x00a1: ord(\'!\'), # A\xa1\n 0x00a2: ord(\'c\'), # A\xf8\n 0x00a3: ord(\'#\'), # A\xa3\n 0x00a4: ord(\'o\'), # A\x0f\n 0x00a5: ord(\'Y\'), # A\xd8\n 0x00a6: ord(\'|\'), # A\u258c\n 0x00a7: ord(\'S\'), # A\x15\n 0x00a8: ord(\'"\'), # A"\n 0x00a9: ord(\'c\'), # Ac\n 0x00aa: ord(\'a\'), # A\xaa\n 0x00ab: ord(\'</pre></pre>', 'title': u'Another solution'}], 'desc': u'latin1_to_ascii -- The UNICODE Hammer -- AKA "The Stupid American"\n\nThis takes a UNICODE string and replaces Latin-1 characters with\nsomething equivalent in 7-bit ASCII and returns a plain ASCII string. \nThis function makes a best effort to convert Latin-1 characters into \nASCII equivalents. It does not just strip out the Latin-1 characters.\nAll characters in the standard 7-bit ASCII range are preserved. \nIn the 8th bit range all the Latin-1 accented letters are converted to \nunaccented equivalents. Most symbol characters are converted to \nsomething meaningful. Anything not converted is deleted.'}, {'comments': [{'comment': u'Would sorting the argument list work ?', 'title': u'C(T, U) is not C(U, T)'}], 'desc': u'This code implements the policy design pattern in Python by using metaclasses and multiple inheritance.'}, {'comments': [], 'desc': u'Data structures for solving the following two problems:\n\n- Range minimization: given an array X of data, quickly find min(X[i:j]) for different ranges i:j.\n\n- Least common ancestors: given a tree, quickly find the lowest tree node that is an ancestor of all of a given set of nodes.\n\nBoth problems are solved by data structures that take linear time and space to set up, after which queries can be answered in constant time.'}, {'comments': [{'comment': u"You can also take a mapping table from TeXML:<br>\nhttp://getfo.org/texml/<br>\n<br>\nTeXML has a mapping for ~2500 unicode characters. But it doesn't bother for a plain TeX and uses LaTeX constructions when it is reasonable.", 'title': u'mapping from a TeXML'}, {'comment': u'I\'m really poor unicoding despite being Swedish native. How do I use this?<br>\nI tried<br><br>\n>>> import latex<br>\n>>> latex.register()<br>\n>>> unicode("_pe$er_", "latex+latin1")<br>\nu\'_pe$er_\'<br>\n<br>\nI was expecting something like:<br>\nu\'\\_pe\\$er\\\'', 'title': u'How does one use it?'}], 'desc': u'Codec for converting unicodes to LaTeX markup and vice versa.'}, {'comments': [{'comment': u'Perl\'s Quantum::Superpositions is a superb package, and its functionality will be a core aspect of scalars in Perl 6.<br>\n\nBesides what\'s been stated in this module (I am not sure it does Q::S 100% but it returns the result of comparisons, when Q::S only returns a boolean result, an improvement I\'ll let the author know of), it allows you to make thins like this:<br>\n<pre>\n# example\nfrom Superposition import *\n\nallowedTtys = [\'tty1\', \'tty2\', \'stty10\']\nallowedApps = [\'admin\', \'remote\', \'web\']\n\ndef login(user, userApp, userTty, userApps):\n if Any(userApps) == Any(allowedApps):\n if userTty == Any(allowedTtys):\n print("GRANTED: user %s connected to %s running %s" % (user, userTty, userApp))\n else:\n print("ERROR: user %s not allowed to attach to secured Tty %s" % (user, userTty))\n else:\n print("ERROR: user %s not allowed to run %s" % (user, userApp))\n\nlogin(\'foouser\', \'web\', \'tty1\', [\'web\', \'proxy\'])\nlogin(\'baruser\', \'hack\', \'tty1\', [\'hack\', \'install\', \'backup\'])\nlogin(\'bazuser\', \'admin\', \'stty6\', [\'admin\'])\n\n# result:\nGRANTED: user foouser connected to tty1 running web\nERROR: user baruser not allowed to run hack\nERROR: user bazuser not allowed to attach to secured Tty stty6\n</pre>\n\nWithout it, those ifs would have had to be explicit fors, checking every option against the others, explicitely. Being implicit in the Any/All classes, it makes for easier to read code. And if makes room for a possible optimization if those loops can be run in parallel, it\'s not the case, but it could be...\n<br>\nCertainly a great module and it\'s great having it in Python as well. Top quality!', 'title': u'Excellent'}, {'comment': u"Thanks you liked it!!!\nI'm quite sure that the P::S package does not return boolean values as well, because I took that feature out of P::S's docstring (and it made\nsense to me).\n\nMyself, I would have used sets directly with your example.So, in a way,\nit's more a thing of personal taste if one finds\n<pre>\nAny(a) == Any(b)\n</pre>\nor\n<pre>\nSet(a) & Set(b)\n</pre>\nmore readable.", 'title': u' '}, {'comment': u"This is very cool. But the code-lines comparison to Perl's module is entirely unfair. Perl's lets you configure existing functions (including built-in core functions) to accept and return values in superposition _without modifying those functions_. I wonder if that would be possible in Python.<br><br>\n\nFurther, the fewer than 650 lines between the beginning of the module and the beginning of its POD include comments, and the author's style uses a lot more whitespace than necessary, both in blank lines and in putting his {'s on their own lines. But those are small points compared to the fact that most of the code is devoted to dealing with passing and receiving values in superposition to and from other functions.", 'title': u"Perl's Quantum::Superposition is so much longer because it does more"}, {'comment': u'Hope you are not too offended. The comparison is unfair and I have to admit that I know nothing about Perl internals. The way Python works, it is just not neccessary to change the interpreter. This solution will work with any other Python construct, be it builtin or not. ', 'title': u'Point taken'}, {'comment': u'Actually, I think you misunderstand my point. Perl\'s allows this:\n\n<pre>use Quantum::Superpositions UNARY => ["CORE::oct"];\nmy $s1 = any(\'123\', \'456\', \'765\');\nmy $o1 = oct($s1);\nprint join \' \', eigenstates($o1), "\\n";\n</pre>\n\nThis produces\n\n<pre>501 302 83</pre>\n\nAs opposed to:\n\n<pre>from Superposition import Any, All\ns1 = Any(\'123\',\'456\',\'765\')\no1 = oct(s1)\n</pre>\n\nwhich produces:\n\n<pre>Traceback (most recent call last):\n File "<stdin>", line 1, in ?\nTypeError: oct() argument can\'t be converted to oct\n</pre>\n\nThat\'s what the bulk of Perl\'s Quantum::Superpositions is going to -- allowing the transparent passing of superposition objects into and out of existing functions, even built-ins, without those functions needing any awareness-in-advance that superposition objects even exist. Unless you omitted this from your documentation and I\'ve grossly misread your code, this is not possible with your (admittedly shorter) module.<br><br>\n\nAnd Quantum::Superpositions doesn\'t "modify the interpreter" to do it.', 'title': u' '}, {'comment': u're: """Without it, those ifs would have had to be explicit fors, checking every option against the others, explicitely."""\n<br>\nThis message:\n<br>\nhttp://mail.python.org/pipermail/python-list/2003-February/148311.html\n<br>\nis about a similar module (at least re the Any, All predicates --that one was implemented using generators delegating comparisons etc to the members of the iterable). You can follow the thread.', 'title': u"Alex Martelli seems to find explicit for's clearer, though..."}], 'desc': u'This lets treat you a python sets.Set as a scalar (number,string,...)\nThe german linux magazine featured an article about the PERL module\n"Quantum::Superpositions": http://www.linux-magazin.de/Artikel/ausgabe/2003/12/perl/perl.html\nThis sounded like fun and I implemented it in Python (probably not everything).\nPerl code lines: over 700\nPython code lines: 100'}, {'comments': [{'comment': u"I've rewritten the maze generator. It's not recursive any more, so no dimension limitations, no MemoryError. Also some documentation added.<br><br>\n\nJust to mention some figures, a maze 100 x 100 is generated in I've rewritten the maze generator. It's not recursive any more, so no dimension limitations, no MemoryError. Also some documentation added.<br><br>\n\nJust to mention some figures, a maze 100 x 100 is generated in ", 'title': u'Improved version'}, {'comment': u'Sorry for the mess. Please visit http://zxw.nm.ru/maze.htm for the latest version. G-:', 'title': u'Updates'}, {'comment': u"I like it alot. I happened upon it while looking for ideas for maze traversal algorithms and now I can't stop playing with it. Way to go!", 'title': u'Very Nice'}], 'desc': u'The Maze class can create 2D mazes and return their ASCII or HTML representation.'}, {'comments': [{'comment': u'I change my approach to ImageJ-Jython integration. You can find an HOWTO at http://marcora.caltech.edu/jython_imagej_howto.htm. Using this approach you don\'t need to compile the Python/Jython source code using jythonc anymore. It makes life much much easier while developing the plugin. You can always compile it when you\'re done with the development if performance is an issue (but I haven\'t run any benchmark... it seems fast enough to me without compilation).\n\nHope this helps,\n\nEdoardo "Dado" Marcora', 'title': u'A different approach to ImageJ-Jython integration'}, {'comment': u"I've created some ImageJ plugins that play the role of jython utilities. Any Jython script placed under ImageJ/plugins/Jython appears listed in the Plugins/Jython menus, and further, another plugin works as a dynamic interpreter for ImageJ which provides full java and ImageJ access while scripting ImageJ in a pythonesque way. Check http://www.pensament.net/java/other_plugins.html for all details.", 'title': u'further jython integration into ImageJ'}], 'desc': u'ImageJ (http://rsb.info.nih.gov/ij/) is a very good image processing program which can be extended using plugins. It is also possible to write ImageJ plugins in jython and generate a class file. This plugin implements an image inverter.'}, {'comments': [{'comment': u"Should the Input Stream be a PythonObjectInputStream from org.python.util?\n\nI would love to see a recipe on using Java's RandomAccessFile with Jython\n\nEoghan", 'title': u'PythonObjectInputStream'}], 'desc': u'Using the pickle module under jython is a rather slow method for storing data. Using the ObjectOutputStream speeds it up. You can save and restore objects (jython and java) with these functions. '}, {'comments': [{'comment': u'The class Exec that invokes the jython interpreter sees all\nthe web application libraries (e.g. jython.jar), but when the\ninterpreter tries to load an imported java class (imported in a jython tag for example) from a jar from the included libraries, it does not find them.<br><br>\n\nWe saw that if before we create the interpreter we call\nPythonInterpreter.initialize, where we pass "java.class.path=$webapp_classpath" with the first Properties\nparameters, the interpreter finds libraries listed under the\n$webapp_classpath. We temporarily solved it by hard coding our class\npath in there. <br><br>\n\nWe can not find a (nice) way to get the webapp libraries from within the code, so that we can pass them to the initialize method.', 'title': u'Jython can not lod imports'}], 'desc': u'These java classes implement a jython taglib which can be used to embed jython code into jsp pages. It consists of two tags:\n<jython:exec> ...some code... </jython:exec>\nand \n<jython:get var=.../>\nWith these two tags you can write active jython pages.'}, {'comments': [{'comment': u'DictInvert = lambda d: dict(zip(d.values(), d.keys()))', 'title': u'My own solution'}, {'comment': u'Both of the solutions could benefit from using the iterator forms: iteritems, iterkeys, itervalues, izip.', 'title': u'Think iterator!'}, {'comment': u"Here's an iterator version that does turn all keys with a common value into a list when you invert the dictionary.<br>\n<br>\n<pre>\ndef dictinvert(d):\n inv = {}\n for k, v in d.iteritems():\n keys = inv.setdefault(v, [])\n keys.append(k)\n return inv<br>\n</pre>\nE.g.<br>\n>>> dictinvert({'a': 55, 'b': 55, 'c': 88})<br>\n{88: ['c'], 55: ['a', 'b']}", 'title': u'Iterator and common values'}, {'comment': u"Will the values of keys() and values() always be in the same order?\n\nThat is, your little lambda won't reorder the relationship between value and key?\n\nCiao!", 'title': u'keys() and values() will always be in order'}, {'comment': u'Just a small note: the keys to a dictionary must be hashable, so in the above, this must be enforced. For types that can be converted to strings, this can be the best method, but there can clearly be some loss of functionality.', 'title': u'Keys must be hashable'}], 'desc': u'Dictionaries map keys to values. Looking up a value is as simple as typing:\nmydict[key]. But what if you want to look up a key? The following one liner returns a new dictionary with the keys and values swapped:'}, {'comments': [], 'desc': u'The simple Jython function below accepts a url string for an image and displays it in a Swing window.'}, {'comments': [], 'desc': u'This is a recipe for new-style class proxies that can also delegate special methods.'}, {'comments': [{'comment': u'This is a very useful recipe, but it has one large wart...\n<br><br>\nIn order to define an instance variables, one must also define a class (static) variable of the same name, and vice versa.\n<br><br>\nA more pythonic solution would be adjust the frozen function to only allow attributes to be set when either:\n<br>\n1) They already exist\n<br>\n2) They are being set from within an __init__ method of either the Frozen class, or a derived class.\n<br><br>\nThis way, we are providing the python equivalent to C++ and Java\'s declarations, but we are doing it in a pythonic way, in the __init__ method of our object. After all, python objects do not have declarations, nor should they...\n<br><br>\nIn order to do this, we need to alter the freeze function as follows:\n<br><br>\n<pre>\ndef frozen(set):\n """Raise an error when trying to set an undeclared name, or when calling\n from a method other than Frozen.__init__ or the __init__ method of\n a class derived from Frozen"""\n def set_attr(self,name,value):\n import sys\n if hasattr(self,name): #If attribute already exists, simply set it\n set(self,name,value)\n return\n elif sys._getframe(1).f_code.co_name is \'__init__\': #Allow __setattr__ calls in __init__ calls of proper object types\n for k,v in sys._getframe(1).f_locals.items():\n if k=="self" and isinstance(v, self.__class__):\n set(self,name,value)\n return\n raise AttributeError("You cannot add attributes to %s" % self)\n return set_attr\n</pre>\nHere are a few examples of usage with the modified code\n<pre>\nclass Person(Frozen):\n def __init__(self,firstname,lastname):\n self.firstname=firstname\n self.lastname=lastname\n\nclass AgedPerson(Person):\n def __init__(self, firstname, lastname, age):\n Person.__init__(self, firstname, lastname)\n self.age = age\n self.firstname = " ".join(("Aged", firstname))\n\nme=Person("Michael", "Loritsch")\nagedMe = AgedPerson("Michael", "Loritsch", 31)\n</pre>\nWarmest Regards,\n<br><br>\nMichael Loritsch', 'title': u'Getting rid of the instance and class level variable dependency...'}], 'desc': u'This recipe is here for a couple of reasons:\n1) discourage a common misuse of __slots__;\n2) show how to restrict Python dynamism.\n'}, {'comments': [{'comment': u'I like this a lot, but I want it to stay up-to-date with the current source. I changed the recipie a bit so that you can specify a source-file instead of including source directly.\n\n<pre>\n#!/usr/bin/env python\n\nimport SilverCity\nimport docutils.parsers.rst\nimport StringIO\n\ndef code_block( name, arguments, options, content, lineno,\n content_offset, block_text, state, state_machine ):\n """\n The code-block directive provides syntax highlighting for blocks\n of code. It is used with the the following syntax::\n \n .. code-block:: CPP\n \n #include <iostream>\n \n int main( int argc, char* argv[] )\n {\n std::cout << "Hello world" << std::endl;\n }\n \n The directive requires the name of a language supported by SilverCity\n as its only argument. All code in the indented block following\n the directive will be colourized. Note that this directive is only\n supported for HTML writers.\n\n The directive can also be told to include a source file directly::\n\n .. code-block::\n :language: Python\n :source-file: ../myfile.py\n\n You cannot both specify a source-file and include code directly.\n """\n\n try:\n language = arguments[0]\n except IndexError:\n language = options[\'language\']\n\n if content and \'source-file\' in options:\n error = state_machine.reporter.error( "You cannot both specify a source-file and include code directly.",\n docutils.nodes.literal_block(block_text,block_text), line=lineno)\n return [error]\n \n if not content:\n try:\n content = [line.rstrip() for line in file(options[\'source-file\'])]\n except KeyError:\n # source-file was not specified\n pass\n try:\n module = getattr(SilverCity, language)\n generator = getattr(module, language+"HTMLGenerator")\n except AttributeError:\n error = state_machine.reporter.error( "No SilverCity lexer found "\n "for language \'%s\'." % language, \n docutils.nodes.literal_block(block_text, block_text), line=lineno )\n return [error]\n io = StringIO.StringIO()\n generator().generate_html( io, \'\\n\'.join(content) )\n html = \'<div class="code-block">\\n%s\\n</div>\\n\' % io.getvalue()\n raw = docutils.nodes.raw(\'\',html, format = \'html\')\n return [raw]\n\n#code_block.arguments = (1,0,0)\ncode_block.arguments = (0,2,1)\ncode_block.options = {\'language\' : docutils.parsers.rst.directives.unchanged,\n \'source-file\' : docutils.parsers.rst.directives.path,}\ncode_block.content = 1\n \n# Simply importing this module will make the directive available.\ndocutils.parsers.rst.directives.register_directive( \'code-block\', code_block )\n\nif __name__ == "__main__":\n import docutils.core\n docutils.core.publish_cmdline(writer_name=\'html\')\n</pre>\n\nThis also lets you specify language directly as an option.', 'title': u'Small feature addition'}, {'comment': u'small correction:\n\n<pre>\n if not content:\n try:\n content = [line.rstrip() for line in file(options[\'source-file\'])]\n except KeyError:\n # source-file was not specified\n pass\n</pre>\n\nshould be changed to\n\n<pre>\n if not content:\n try:\n content = [line.rstrip() for line in file(options[\'source-file\'])]\n except KeyError:\n # source-file was not specified\n pass\n except IOError:\n error = state_machine.reporter.error( "Could not read file %s."%options[\'source-file\'],\n docutils.nodes.literal_block(block_text,block_text), line=lineno)\n return [error]\n</pre>\n\nto be a little more graceful', 'title': u'oops'}, {'comment': u"SilverCity won't work with unicode strings.", 'title': u' '}, {'comment': u'\nWhen I tried to reuse this recipe in the latest SVN snapshot of Docutils (0.5\n[repository]), I discovered that the rst directive code has changed from a\nfunctional interface to a class-based interface. \n\nAfter a bit of fiddling I was able to get it to work. Here is the revised\ncode.\n\n<pre>#!/usr/bin/env python\n\nimport SilverCity\nfrom docutils import io, nodes, statemachine, utils\nfrom docutils.parsers.rst import Directive, directives\nimport StringIO\n\n# Modified to new class-based form by C.P. Jobling (C.P.Jobling@Swansea.ac.uk)\n\nclass CodeBlock(Directive):\n\n """\n The code-block directive provides syntax highlighting for blocks\n of code. It is used with the the following syntax::\n \n .. code-block:: CPP\n \n #include <iostream>\n \n int main( int argc, char* argv[] )\n {\n std::cout << "Hello world" << std::endl;\n }\n \n The directive requires the name of a language supported by SilverCity\n as its only argument. All code in the indented block following\n the directive will be colourized. Note that this directive is only\n supported for HTML writers.\n\n The directive can also be told to include a source file directly::\n\n .. code-block::\n :language: Python\n :source-file: ../myfile.py\n\n You cannot both specify a source-file and include code directly.\n """\n \n final_argument_whitespace = True\n option_spec = {\'language\' : directives.unchanged,\n \'source-file\' : directives.path,}\n has_content = True\n\n def run(self):\n\ttry:\n\t\tlanguage = self.arguments[0]\n\texcept IndexError:\n\t\tlanguage = self.options[\'language\']\n\n\tif self.content and \'source-file\' in self.options:\n\t\terror = self.state_machine.reporter.error( \n "You cannot both specify a source-file and include code directly.",\n nodes.literal_block(block_text,block_text), line=lineno)\n\t\treturn [error]\n \n if not self.content:\n try:\n self.content = [line.rstrip() for line infile(self.options[\'source-file\'])]\n except KeyError:\n # source-file was not specified pass\n except IOError:\n error = self.state_machine.reporter.error( \n "Could not read file %s." %self.options[\'source-file\'],\n nodes.literal_block(block_text, block_text), line=self.lineno)\n return [error]\n \n try:\n module = getattr(SilverCity, language)\n generator = getattr(module, language+"HTMLGenerator")\n except AttributeError:\n error = self.state_machine.reporter.error( "No SilverCity lexer found "\n "for language \'%s\'." %language, \n\t\t\t\t\t\t\tnodes.literal_block(block_text, block_text), line=self.lineno )\n return [error]\n io = StringIO.StringIO()\n generator().generate_html( io, \'\\n\'.join(self.content) )\n html = \'<div class="code-block">\\n%s\\n</div>\\n\' % io.getvalue()\n raw = nodes.raw(\'\',html, format = \'html\')\n return [raw]\n</pre>\n\nDuring my researches for this change I discovered that the original recipe has\nbeen adapted by the TRAC developers (http://trac.edgewall.org/) where it is\nused in both code pretty-printing and revision browsing and with an reST\ndirective in their wiki. Their solution is more sophisticated than the one\nhere because it makes use of GNU/Enscript to typeset languages other than\nthose supported by SilverCity. It would be nice if this code could be\nbackported into Docutils.\n\nAnother comment is that this recipe could usefully subclass the Raw directive\nwhich provides support for inserting code from URLs as well as files. This\nalso provides support for specifying text encoding of the code (although from\nthe above comment, this would appear to be unsupported by SilverCity).\nUnfortunately, this is beyond my current skills!\n', 'title': u'Update of recipe for new style Docutils directive'}], 'desc': u'Code samples in reStructuredText documents are normally shown as plain literal blocks. This recipe uses the SilverCity ( http://silvercity.sourceforge.net/ ) lexing package to generate syntax highlighted code blocks instead.'}, {'comments': [], 'desc': u'This receipe is a very handy utility to extract the attachments from your mail. Suppose you receive a good mail which has attachments. You want to store the mail but without the attachment.\n\n'}, {'comments': [{'comment': u'Consider factoring out the pairing logic into a generator. The result is fast, memory friendly, and works with any iterable.\n\n<pre>\ndef pairwise(iterable):\n itnext = iter(iterable).next\n while 1:\n yield itnext(), itnext()\n\n>>> dict(pairwise(["one", 1, "two", 2, "three", 3]))\n{\'three\': 3, \'two\': 2, \'one\': 1}\n</pre>', 'title': u'Generator version'}, {'comment': u'<pre>\nI love Python list compressions and prefer to use them as often as<br>possible especially as they allow inline generation of lists. I prefer<br>them over lambda, map, reduce, filter. \n\nHere\'s how it goes. \n\nls= "one ten two twenty three thirty four forty five fifty".split() \n\ndict( [ (ls[i], ls[i+1]) for I in range(0,len(l),2) ] ) \n\nwhich produces the dictionary \n\n{\'four\': \'forty\', \'three\': \'thirty\', \'five\': \'fifty\', \'two\': \'twenty\', \'one\': \'ten\'} \n\nIf two lists are correlated then you could do the following to<br>reduce quoting. \n\nls1="one two three four five six seven eight nine ten" \nls2="aa1 ab2 ac3 ad4 ae5 af6 ag7 ag8 ah9 ai0" \n\ndict( zip( *[ l.split() for l in (ls1, ls2) ] ) ) \n\nThis compression produces a nested list which zip interprets as a<br>single argument unless you precede the first bracket with an<br>asterisk (*) which separates it into multiple (2) argument lists.</pre>', 'title': u'Inline quote minimization method'}], 'desc': u'Simple oneliner to built a dictionary from a list'}, {'comments': [{'comment': u"I have a small problem with the proof you let to the user.<br>\nI'am even asking if it exist considering the example<br>\n<br>\n<pre>\nhipop<br>\nhapap</pre>\n<br>\nwhich leads to hpp and so become:<br>\n<br>\n<pre>\nhipop<br>\nhapap<br>\nhpp</pre>\n<br>\nwhich leads to hp which seems wrong.<br>\n<br>\n", 'title': u'problem with the proof'}, {'comment': u"I've changed the code to get a right result in these kind of cases (hope, I got it right this time)", 'title': u'You are right'}, {'comment': u'How about this ?\n\n<pre>\nimport operator\n\ndef allsame(seq):\n "Determines whether all the elements in a sequence are the same."\n\n # Compare all the elements to the first in the sequence,\n # then do a logical and (min) to see if they all matched.\n return min([elem==seq[0] for elem in seq]+[True])\n\ndef getcommonstart(seqlist):\n """Returns the common prefix of a list of sequences.\n \n Raises an exception if the list is empty.\n """\n # if not seqlist: return None\n m = [allsame(seq) for seq in zip(*seqlist)] # Map the matching elements\n m.append(False) # Guard in case all the sequences match\n return seqlist[0][0:m.index(False)] # Truncate before first mismatch\n</pre>', 'title': u' '}, {'comment': u"And you don't even need the operator module.<br>\nI originally had\n<pre>\ndef allsame(seq):\n return reduce(operator.and_,[elem==seq[0] for elem in seq],True)\n</pre>\nbut I changed it to use min() instead and forgot to remove the import.", 'title': u'import operator not needed'}, {'comment': u"What about a combined approach?:\n<pre>\ndef getcommonletters(strlist):\n def booltrigger(expr):\n if not booltrigger.truth: return False\n if not expr:booltrigger.truth = False\n return expr\n booltrigger.truth = True\n return ''.join([x[0] for x in zip(*strlist) if \\\n booltrigger(min([x[0]==elem for elem in x]))])\n</pre>\n\nThe 'booltrigger' is doing what should be possible with list comprehension anyway: Stop the iteration.", 'title': u"That's nice"}, {'comment': u"I believe that itertools.takewhile does something close enough to what you were trying to achieve with booltrigger.\n<pre>\nimport itertools\n\ndef allsame(seq):\n return min([elem==seq[0] for elem in seq]+[True]) \n\ndef getcommonstart(seqlist):\n letters = itertools.izip(*seqlist) # let's be lazy\n common = itertools.takewhile(allsame, letters) # still lazy\n return ''.join([letters[0] for letters in common]) # merge back\n</pre>", 'title': u'Or you could use itertools'}, {'comment': u'<p>... this:</p>\n\n<pre>\n>>> import os\n>>> os.path.commonprefix(["hippie", "hippo"])\n\'hipp\'\n>>> \n</pre>', 'title': u'What about ...'}, {'comment': u'<pre>def allsame(seq):\n\treturn not seq or False not in itertools.imap(seq[0].__eq__, seq)</pre>', 'title': u"Lazy 'allsame'"}, {'comment': u'Hmm, that\'s why I thought this should have been solved somewhere already. I\'m happy though that this was not the first comment :-)\nJust for the interested, the posixpath.commonprefix looks like this:\n<pre>\ndef commonprefix(m):\n "Given a list of pathnames, returns the longest common leading component"\n if not m: return \'\'\n prefix = m[0]\n for item in m:\n for i in range(len(prefix)):\n if prefix[:i+1] != item[:i+1]:\n prefix = prefix[:i]\n if i == 0:\n return \'\'\n break\n return prefix\n</pre>', 'title': u'Know thy libraries!'}, {'comment': u'Not that it is very interesting, but I amused myself by creating a one-line version of findcommonstart as follows:<br><br>\n<pre>\ndef findcommonstart(strlist):\n return strlist[0][:([min([x[0]==elem for elem in x]) \\\n for x in zip(*strlist)]+[0]).index(0)]\n<pre>\n\n</pre></pre>', 'title': u'One-line version of this code'}, {'comment': u'<pre>\ndef getcommonstart(seqlist):\n seq = seqlist.sort()\n s1, s2 = seq[0], seq[len(seq)]\n l = min(len(s1), len(s2))\n if l == 0 :\n return ""\n if s1[0] != s2[0] :\n return ""\n for i in range(l) :\n if s1[i] != s2[i] :\n return s1[0:i-1]\n return s1[0:l]\n</pre><br>', 'title': u'more speed ( sort is C-realised )'}, {'comment': u'<pre>\ndef getcommonstart(seq):\n if not seq:return ""\n seq.sort()\n s1, s2 = seq[0], seq[-1]\n l = min(len(s1), len(s2))\n if l == 0 :\n return ""\n for i in xrange(l) :\n if s1[i] != s2[i] :\n return s1[0:i]\n return s1[0:l]\n</pre>', 'title': u'corrected (and optimized) version'}, {'comment': u"The sort() could be expensive, and isn't really needed, since you're only interested in the first and last element of the sorted sequence, i.e. the minimum and maximum elements of the sequence. So, change\n<pre>\n seq.sort()\n s1, s2 = seq[0], seq[-1]\n</pre>\nto\n<pre>\n s1 = min(seq)\n s2 = max(seq)\n</pre>\n", 'title': u'Avoid sort()'}, {'comment': u"[Somehow, this comment went elsewhere in the comment-tree yesterday.]<br>\n\nThe sort() could be expensive, and isn't really needed, since you're only interested in the first and last element of the sorted sequence, i.e. the minimum and maximum elements of the sequence. So, change \n<pre>\nseq.sort()\ns1, s2 = seq[0], seq[-1]\n</pre>\nto \n<pre>\ns1 = min(seq)\ns2 = max(seq)\n</pre>", 'title': u'Avoid sort()'}, {'comment': u'There are even fewer trips around the Python eval loop if the longest match is found using binary search instead of sequential comparison.\n<pre>\n\ndef commonprefix(m):\n "Given a list of pathnames, returns the longest common leading component"\n if not m: return \'\'\n a, b = min(m), max(m)\n lo, hi = 0, min(len(a), len(b))\n while lo < hi:\n mid = (lo+hi)//2 + 1\n if a[lo:mid] == b[lo:mid]:\n lo = mid\n else:\n hi = mid - 1\n return a[:hi]\n</pre>', 'title': u'Binary search version'}, {'comment': u"Why should sort be slower than computing a min and a max? As far as my computational knowledge goes, in order to compute some minimum or maximum, the first thing to do is to sort anyway.\nComputing separate min and max actually slows things down.\n\nI've done some tests and it looks like Raymonds version with sort instead of min,max is indeed faster. (And by the way, is the quickest of all the shown algorithms)", 'title': u'sort not bad'}, {'comment': u'max,min seems indeed to be faster. I did the first test with presorted lists.', 'title': u'correction'}], 'desc': u"I came up with this when I tried to implement some autocompletion feature.\nThe problem is to find a common substring (beginning from the start) for all strings in a given list.\n\nI couldn't find an existing recipe that is doing this task, but I'm wondering\nif I just didn't look hard enough"}, {'comments': [], 'desc': u'Small function to generate every permutation of a given sequence. Works for lists and strings'}, {'comments': [], 'desc': u' '}, {'comments': [{'comment': u'Here\'s an alternative implementation of attribute() which does not require that self.attrname be initialized in __init__():<br>\n<br> \ndef attribute2(attrname, default=None, permit=\'rwd\',<br>\n            fget=None, fset=None, fdel=None, doc=\'\'):<br>\n    "don\'t need to initialize self.attrname in __init__()"<br>\n    def wrap(f):<br>\n        if f is None: return f<br>\n        def wrapped(self, *value):<br>\n            if not hasattr(self, attrname):<br>\n                setattr(self, attrname, default)<br>\n            try: return f(self) # fget/fdel<br>\n            except TypeError: return f(self, value[0]) # fset<br>\n        return wrapped<br>\n    fget, fset, fdel = wrap(fget), wrap(fset), wrap(fdel)<br>\n    if _isprivate(attrname):<br>\n        attrname = _mangle(_get_classname(), attrname)<br>\n    if \'r\' in permit and fget is None:<br>\n        def fget(self):<br>\n            value = default<br>\n            try: value = getattr(self, attrname)<br>\n            except AttributeError: setattr(self, attrname, default)<br>\n            return value<br>\n    if \'w\' in permit and fset is None:<br>\n        def fset(self, value):<br>\n            setattr(self, attrname, value)<br>\n    if \'d\' in permit and fdel is None:<br>\n        def fdel(self): # calling fget can restore this attribute!<br>\n            try: delattr(self, attrname)<br>\n            except AttributeError: pass<br>\n    return property(fget, fset, fdel, doc)<br>\n<br>\nif __name__ == "__main__":<br>\n<br>\n    class C(object):<br>\n        a = attribute2(\'_a\', "A", fget=lambda self: self._a*2)<br>\n<br>\n    c = C()<br>\n    print c.a<br>\n    c.a = "AA"<br> \n    print c.a<br>\n<br>', 'title': u' '}], 'desc': u'This recipe provides a function that will automate simple property creation, while allowing its users to provide specific fget/fset/fdel methods.'}, {'comments': [{'comment': u"<pre>\nimport difflib\n\ndiffer = difflib.SequenceMatcher()\ndiffer.set_seqs('firstMethod','methodFirst')\nmatch = differ.quick_ratio() > 0.8\n</pre>\n\nI used this very successfully to match contact details with existing contacts in a contact database with the typical spelling errors, punctuation and spacing discrepancies associated with this type of data.", 'title': u'How about using difflib?'}], 'desc': u"Provides a do-what-I-mean function, dwim_match, that takes two strings and returns True or False; the former if the two strings 'match', the latter if they don't.\nThe matching algorithm is taken from SWI-Prolog's dwim_match/2 function."}, {'comments': [], 'desc': u'A Turing Machine Simulator that allows an arbitrary machine to be loaded. Words (represented as strings) can be ran against the simulator producing a response: Accept or Crash.'}, {'comments': [], 'desc': u'Metakit is a reliable/lightweight/fast database library that python can use.\nMetakit has an extend mode that enables many simultaneous readers and one writer w/out needing a database server to synchronize things. Here is an example showing how to use that cool feature.'}, {'comments': [], 'desc': u'Cross-platform locking that works across multiple threads and processes can be complicated. A simple solution is to use 2 level locking based off of mkdir (which fails on all attempts except the first). It works across threads and processes (or even servers), since only one will get to do mkdir.'}, {'comments': [], 'desc': u'A simple example of a heap data structure as a C extension. This data structure can store and sort any python object that has a comparison function (i.e. strings, numbers, etc.).'}, {'comments': [{'comment': u"You don't need this - the built in iter() function allows you to do this:\n<br>\n<pre>\n for val in iter(queue.get, sentinel):\n # process val\n</pre>\nUntil I saw this recipe, I'd forgotten about it, though!", 'title': u'This is built in (but fairly obscure!)'}, {'comment': u"I want to pass arguments to Queue.get as well, so I added:\n<pre>\ndef iterQueue(queue, sentinel, **kwargs):\n...\n value = queue.get(**kwargs)\n...\n</pre>\nNow I can\n<pre>\niterQueue(queue, sentinel, timeout=10)\n</pre>\nto my heart's desire :-)", 'title': u'Cool!'}], 'desc': u"My Queue usage typically involves a producer thread and a consumer thread. The producer calls queue.put(value) until it's done at which point it calls queue.put(sentinel). My consumers almost always look like this:\n\nwhile True:\n    value = queue.get()\n    if value != sentinel:\n        # do something with value\n    else:\n        break\n\nThat logic can be abstracted away into a generator function that allows consumer code to look like this instead:\n\nfor value in iterQueue(queue, sentinel):\n    # do something with value\n"}, {'comments': [{'comment': u'Yes, this works on Linux. I just verified it, out of curiosity. But we already have standard command-line tools called zip and unzip, which work just fine.\n<br>\nThe real value of the zipfile module, as I understand it, is that you can go between memory and zip files easily. Extracting between files doesn\'t seem so useful.\n<br>\nAnyway, you failed to handle exceptions. This happens when I attempt to extract an encrypted file:\n<pre>\nTraceback (most recent call last):\n File "unzip.py", line 140, in ?\n if __name__ == \'__main__\': main()\n File "unzip.py", line 138, in main\n unzipper.extract(zipsource, zipdest)\n File "unzip.py", line 57, in extract\n outfile.write(zf.read(name))\n File "/_TOOLS_/plat/python-/2.3.3/lib/python2.3/zipfile.py", line 368, in read\n raise BadZipfile, "Bad CRC-32 for file %s" % name\nzipfile.BadZipfile: Bad CRC-32 for file log.tcl\n</pre>\nSo even as a simple utility, it needs work. I tested it only b/c I wanted to be sure that zipfile works on my system.', 'title': u'Yes, but...'}, {'comment': u"I had a problem with this code because my zipfile didn't have new paths defined as line-items. I changed it to just create the directory structure on the fly:\n<pre>\ndef create_necessary_paths(filename):\n try:\n (path,name) = os.path.split(filename)\n os.makedirs( path) \n except:\n pass \n</pre>\nAnd within the extract function:\n<pre>\n... \nif not name.endswith('/'):\n try:\n (path,name) = os.path.split(os.path.join(dir, name))\n os.makedirs( path) \n except:\n pass \n outfile = open(os.path.join(dir, name), 'wb')\n outfile.write(zf.read(name))\n...\n</pre>", 'title': u"Paths with \\ don't exist..."}, {'comment': u'merci Doug pour ton script, il marche bien, une fois pris en compte les commentaires!\nje l\'ai test\xe9 avec succ\xe8s sous MacOS 9.2.2 avec Python 2.2.3 dans le script, suivant:\n\n#! /usr/bin/env python\n\nimport base64, re, urllib, string, sys, zipfile, os, os.path\n\npattern_in_base64 = r"""\nmerci Doug pour ton script, il marche bien, une fois pris en compte les commentaires!\nje l\'ai test\xe9 avec succ\xe8s sous MacOS 9.2.2 avec Python 2.2.3 dans le script, suivant:\n\n#! /usr/bin/env python\n\nimport base64, re, urllib, string, sys, zipfile, os, os.path\n\npattern_in_base64 = r"""\n', 'title': u'le script marche bien, une fois pris en compte les commentaires!'}, {'comment': u'<pre>\nimport base64, re, urllib, string, sys, zipfile, os, os.path\n\npattern_in_base64 = r"""\ncf. rx cookbook, recipe 59864 de ken simpson et commentaires\n"""\n\nclass unzip: \n\n def extract(self, file, dir):\n\t\n if not dir.endswith(\':\') and not os.path.exists(dir):\n os.mkdir(dir)\n \n zf = zipfile.ZipFile(file)\n self._createstructure(file, dir)\n num_files = len(zf.namelist())\n\n for name in zf.namelist():\n if not name.endswith(\'/\'):\n try:\n (path,name) = os.path.split(os.path.join(dir, name))\n os.makedirs( path) \n except:\n pass \n outfile = open(os.path.join(dir, name), \'wb\')\n outfile.write(zf.read(name))\n\n def _createstructure(self, file, dir):\n self._makedirs(self._listdirs(file), dir)\n\n def create_necessary_paths(filename):\n try:\n (path,name) = os.path.split(filename)\n os.makedirs( path) \n except:\n pass\n\n def _makedirs(self, directories, basedir):\n for dir in directories:\n curdir = os.path.join(basedir, dir)\n if not os.path.exists(curdir):\n os.mkdir(curdir)\n\n def _listdirs(self, file):\n zf = zipfile.ZipFile(file)\n dirs = []\n for name in zf.namelist():\n if name.endswith(\'/\'):\n dirs.append(name)\n\n dirs.sort()\n return dirs\n\ndef main():\n\n pattern = base64.decodestring(pattern_in_base64)\n matcher = re.compile(pattern)\n print pattern\n the_string = urllib.urlopen(\'http://www.sophos.fr/downloads/ide\').read()\n matches = matcher.findall(the_string)\n matches.sort()\n matches.reverse()\n\n for match in matches:\n\t pos = string.find(str(match), \'_ides.zip\', 22)\n if pos >=0: break\n\n print pos\n print match[0]\n\n os.chdir(\'Classic:Desktop Folder:\')\n urllib.urlretrieve(match[0], \'ide.zip\')\n \n pwd = os.getcwd()\n print pwd\n print os.listdir(pwd)\n\n unzipper = unzip()\n zipsource = "Classic:Desktop Folder:ide.zip"\n zipdest = "Classic:Desktop Folder:ide"\n unzipper.extract(zipsource, zipdest)\n\nif __name__ == \'__main__\': main()</pre>', 'title': u'suite du pr\xe9c\xe9dent'}], 'desc': u"A Python class to extract zip files.\nIt's also written for easy use as a standalone script from the commandline."}, {'comments': [{'comment': u"You basically maintain a dictionary and a linked list. Dictionary accesses are not O(1). I believe the Python implementation uses a hash table, which has O(N) worst case behavior. The best you can hope for in a dictionary is O(log(N)).\n<br><br>\nFurthermore, your code is not correct and does not maintain LRU semantics, as your linked list is not updated to move the most recently accessed node to the end of the list when __getitem__ is called. You are actually implementing a FIFO.\n<br><br>\nIf you want to have good complexity behavior in a cache, you will have to use a priority queue algorithm like binomial heaps. I haven't tried the new Priority Queue class in Python 2.3 yet, but I have used the one at http://www.csse.monash.edu.au/hons/projects/1999/Andrew.Snare/ to good effect.", 'title': u'Not quite O(1) or LRU'}, {'comment': u'While saying "the best you can hope for from a dict is O(log n)" may be pedantically correct (and I\'m not even sure about that), in practice assuming dicts have O(1) access isn\'t going to get you into hot water.\n<br><br>\nPython\'s hash functions are pretty good.', 'title': u'over pedantry'}, {'comment': u'I\'m not quite sure I agree with Fazal\'s complaint about not being O(1), but he\'s right on that it isn\'t a LRU. The item deleted when the cache overflows is always the first added, NOT the least recently used. *IF* each "use" requires a call to __getitem__ (and for most applications this may not hold true), then the flaw can be fixed by modifying __getitem__ to move the item which was accessed to the front of the linked list. But I fear that even then you might have excellent big-O behavior but the overhead would be so large that performance would still suffer for normal-sized datasets. The 64 items you are handling sounds like a SMALL dataset to me. I would recomend trying the nieve solution (keep an ordinary list; move to the end of the list on each access; delete from the front of the list) and seeing if the performance works for you.', 'title': u'Certainly not a LRU'}, {'comment': u'Small bugfixes:\n<pre>\n self.first = a\n a.next = None\n del self.d[a[0]]\n</pre>\nShould be replaced by:\n<pre>\n self.first = a.next\n a.next = None\n del self.d[a.me[0]]\n\n</pre>', 'title': u'Bugfixes that slipped my mind.'}, {'comment': u"Check the Python distribution source code, namely dictobject.c. If you notice the probe sequence rules, unless every object has the same hash, it will not perform O(n). In fact, with a maximally 2/3 filled table, the odds of colliding more than 10 times is less than ~1%.<br><br>\n\nTo me, 10 probes is good enough. Heck, at 20 probes, we're talking about ~.01%.<br><br>\n\nPlus it has the benefit of not having to deal with pointers for a tree structure.", 'title': u'Hashing and O(1)'}, {'comment': u"After the bugfix I posted, it is indeed an LRU. Why?<br><br>\n\nIf you follow the flow of code, certainly it always deletes the 'first' item, but that is the oldest item...all the newer items are inserted as the 'last' item.<br><br>\n\nHere is some output (after my bugfix given in another comment):\n<pre>\n>>> a = LRU(4)\n>>> a[1] = 1\n>>> a[2] = 2\n>>> a[3] = 3\n>>> a[4] = 4\n>>> for i in a.iteritems():\n... print i,\n...\n(1, 1) (2, 2) (3, 3) (4, 4)\n>>> a[5] = 5\n>>> for i in a.iteritems():\n... print i,\n...\n(2, 2) (3, 3) (4, 4) (5, 5)\n>>> a[3] = 6\n>>> for i in a.iteritems():\n... print i,\n...\n(2, 2) (4, 4) (5, 5) (3, 6)\n</pre>\n\nSeems to work for me.", 'title': u'It is an LRU (it was buggy)'}, {'comment': u"That's what everyone is talking about.<br><br>\n\nI only update it when writing, everyone cares about reading.<br><br>\n\nThere is a bugfix in another comment.", 'title': u'I see...'}, {'comment': u'If you want to make it LRU on read, as well as write (which is all I had been concerned about), change:\n<pre>\n def __getitem__(self, obj):\n return self.d[obj].me[1]\n</pre>\n\nTo:\n<pre>\n def __getitem__(self, obj):\n a = self.d[obj].me\n self[a[0]] = a[1]\n return a[1]\n</pre>', 'title': u'Make LRU on read (as well as write)'}, {'comment': u"I've implemented both a standard binary heap, as well as a binomial heap in Python before. I was not impressed by my binomial heap implementation.<br><br>\n\nThe author that you link to claims to have creted a fibonacci heap that is fast...but how fast? The graphs for his distribution show that it is quite fast, but I wanted to test it myself, so I did.<br><br>\n\nBelow are some test runs against my sample implementations. dict_heap and list_heap are identical, except that dict_heap uses a dictionary and list_heap uses a Python list (which is really an array). Notice how the dictionary is only ever about 33% slower than list_heap during the removal of all the elements.\n<pre>\n init popall\n10000:\ndict_heap 0.265 1.829\nlist_heap 0.141 1.406\nBinomialHeap 0.484 4.25\nPQ0 0.047 0.734\nPQueue 0.359 1.594\nPQEquivBig 1.062 2.172\n20000:\ndict_heap 0.563 3.968\nlist_heap 0.281 3.047\nBinomialHeap 0.969 9.125\nPQ0 0.11 2.765\nPQueue 0.766 3.437\nPQEquivBig 2.218 4.625\n30000:\ndict_heap 0.844 6.234\nlist_heap 0.422 4.75\nBinomialHeap 1.469 14.313\nPQ0 0.172 8.859\nPQueue 1.125 5.407\nPQEquivBig 3.313 7.141\n40000:\ndict_heap 1.141 8.562\nlist_heap 0.578 6.531\nBinomialHeap 1.937 19.828\nPQ0 0.234 16.094\nPQueue 1.625 7.438\nPQEquivBig 4.563 9.797\n</pre>\n\nPQ0 gets slower as the sizes get larger because deleting the first item in a list (as PQ0 does) is O(n).<br><br>\n\nPQueue just seems to be poorly implemented.<br><br>\n\nPQEquivBig seems to be exactly 50% slower than list_heap during deletion, and much slower in insertion.<br><br><br>\n\n\nI'm not impressed.", 'title': u'A note on binomial heaps'}, {'comment': u"I was thinking about it for a bit; if Python's hash functions are good enough, and the dictionary was sparse enough, one can ammortize all accesses to O(1).<br><br>\n\nAssume Python dictionaries use double hashing; first for the start location, second for a probe sequence increment. If the dictionary is 1/2 full, then the probability of you not colliding in your first shot is 1/2. For those that collide, subsequent tests have a 1/2 chance of not colliding. If we sum up the probabilities to get to probe number k... 1*1/2 + 2*1/4 + 3*1/8 + 4*1/16 + ..., which ends up summing to 2.<br><br>\n\nVery nifty.", 'title': u'Ammortized O(1) when the dictionary is sparse enough.'}, {'comment': u'This recipie looks great for my application with a cache of about 1000 objects. However the doubly linked Nodes form reference cycles and will not get garbage collected when the LRU instance is deleted. Using a weakref for the Node.prev solves this. You could also use __slots__ on the Node class to save space - given that that there will be alot of them.', 'title': u'Needs to use weakref'}, {'comment': u"You make a good point about the use of slots. I've updated the recipe to reflect it.<br><br>\n\nAs for the reference cycles, since 2.2, Python has had a cycle-detecting garbage collector, so these reference cycles aren't a big deal. Also, only mangling the previous pointers ignores the fact that next pointers introduce their own reference cycle. To prove that reference cycles aren't a big deal, the following is a sample interaction using the LRU with Python 2.3 (as Python 2.2 is no longer supported by the PSF).<br><br>\n<pre>\n>>> import gc\n>>> import lru\n>>> x = lru.LRU(2000, zip(range(1000), range(1000)))\n>>> del x\n>>> gc.garbage\n[]\n>>> gc.collect()\n3000\n>>> gc.garbage\n[]\n>>>\n</pre>", 'title': u' '}], 'desc': u'Everyone knows about LRU. Here is an implementation that takes O(1) time to insert, update or delete.'}, {'comments': [{'comment': u'Notice that this approach creates two objects whenever you actually need one, and one object when you don\'t. Unless the initialization of the "real" object is quite costly, you might as well create the one object to begin with.<br>\n<br>\nA better approach for lazy object creation is to use descriptors that create an attribute\'s value on demand. This lets you have objects that don\'t do all their initialization in __init__: instead, the object\'s attributes are created as and when they are needed. Since this can include the creation of other objects, they are not created unless needed. There\'s no need for proxies in this circumstance, which is good, because proxies like your JIT object are *very* hard to get right in Python. (Note that your proxy doesn\'t correctly support any special methods such as __getitem__, __call__, __str__, etc.)<br>\n<br>\nPEAK (http://peak.telecommunity.com/) includes a package called peak.binding that supports creation of such descriptors. Specifically, the \'binding.Make()\' descriptor, which accepts a callable (such as a class). So, to redo your example using PEAK:\n\n<pre>\nfrom peak.api import binding\n\nclass TestIt:\n def __init__(self, arg, keyword=None):\n print \'In TestIt.__init__() -- arg: %s, keyword=%s\' % (arg, keyword)\n\n def method(self):\n print \'In TestIt.method().\'\n\nclass Holder(binding.Component):\n t = binding.Make(lambda: TestIt(\'The Argument\',\'The Keyword\'))\n\nh = Holder() # make a holder\nh.t.method() # accessing h.t creates a TestIt instance\nh.t.method() # accessing it again uses the created instance\n</pre>\n\n(Note that if "TestIt" had an expensive initialization itself, the initialization could be split into separate \'binding.Make\' calls to create its attributes. Also, you do not have to use \'binding.Component\' as a base class, you can also use \'binding.Activator\' as a metaclass, or explicitly tell \'Make\' what attribute name it will use.)', 'title': u"You're still creating at least one object, maybe two"}], 'desc': u'I frequently find myself adding "just in time" (JIT) object creation to avoid wasting cycles on objects that are never used. This class enables JIT object creation by basically currying the __init__ method. \n\nThe object is instianted only when an attribute is got or set. Then automatic delegation is used to front for the object (see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295)'}, {'comments': [{'comment': u'Error:\n<br>\n<br>I believe that in the following code:\n<br> def is_inbetween(self, l, elem):\n<br> """ Find out if an element is in between\n<br> in a list """\n<br>\n<br> index = l.index(elem)\n<br> if index == -1:\n<br> return False\n<br>the line:\n<br> if index == -1:\n<br>should read:\n<br> if index == 0:\n<br>\n<br>The way it currently reads, any | will always "or" with Null, and will thus always be true. (i.e. Guido | Larry is really: Null | Guido | Larry).\n<br>\n<br>Caveat:\n<br>There is also another caveat. In a boolean statement such as (Larry Error:\n<br>\n<br>I believe that in the following code:\n<br> def is_inbetween(self, l, elem):\n<br> """ Find out if an element is in between\n<br> in a list """\n<br>\n<br> index = l.index(elem)\n<br> if index == -1:\n<br> return False\n<br>the line:\n<br> if index == -1:\n<br>should read:\n<br> if index == 0:\n<br>\n<br>The way it currently reads, any | will always "or" with Null, and will thus always be true. (i.e. Guido | Larry is really: Null | Guido | Larry).\n<br>\n<br>Caveat:\n<br>There is also another caveat. In a boolean statement such as (Larry ', 'title': u'One Error and One more caveat.'}], 'desc': u'Very often we need to look for the occurence of words in a string or group of words. We rely on regular expressions for such operations. A very common requirement is to look for the occurence of certain words in a paragraph or string. We can group the occurence by boolean operators AND, OR and NOT, allowing to search for certain words using boolean logic. \n\nThis class is created to do exactly that. It wraps up a \ncomplex boolean word expression, creating an internal \nregular expression, and provides methods allowing you to \nperform matches and searches on it.'}, {'comments': [], 'desc': u'This script could be used when you want to generate a text fading effect for your web pages. The script will generate the HTML file with the faded text for any text and fades the text between any two valid HTML color codes.'}, {'comments': [{'comment': u'Indeed quick and dirty ;-)', 'title': u'extremely quick-and-dirty'}, {'comment': u'Just slightly less dirty:\n<pre>\ndef throws(exceptions, f, *a, **k):\n "Return True if f(*a,**k) raises these exceptions."\n try:\n f(*a,**k)\n except exceptions:\n return True\n return False\n</pre>\nYou can then use<pre>throws(AttributeError, ...)</pre> \nor <pre>throws((NameError, KeyError), ...)</pre>\nTo catch the exceptions you anticipate, while passing along those\nthat you _should_ avoid (such as SystemExit). If you want a very\nbroad exception class, use <pre>throws(Exception, ...)</pre>, \nwhich should cover all exceptions.', 'title': u'Slight improvement'}], 'desc': u'I use the following function to do extremely quick-and-dirty exception handling in an expression, without having to use try/except.'}, {'comments': [{'comment': u'Just use sqlite.Binary(). This is is the Right Way(tm).', 'title': u'Use the DB-API method'}], 'desc': u'This script demonstrates how to store binary data (aka BLOB or BINARY fields) in SQLite using the PySQLite extension.'}, {'comments': [], 'desc': u'I add this Python script as daily crontab or windows scheduled task to watch the foregin exchange rate from BankOfCanada web site. The file format is not fancy XML but a CSV. That can be easily parsed with Python. And you can configure the threshold rate, smtp server, toaddrs ( a list being alerted)'}, {'comments': [], 'desc': u'This short script allows a user to track the current status of a package sent through FedEx. It is meant to be run from the command line and takes 1 option argument (-v) to determine whether or not it shows all tracking information, or just the most recent entry. The user can enter multiple tracking numbers at run time.'}, {'comments': [], 'desc': u'This class replaces characters until there are no offending ones left.\n\nYou could you regex or translate. This is a method using dictionaries and replace method from strings.'}, {'comments': [], 'desc': u'When creating a class, we often end up writing lots get/set methods which essentially do the same thing e.g. get_name, get_age, ... , set_name, set_age, ...\n- each such method will simply set or return the value of its associated attribute. \n\nThis recipe is a stategy for automating the creation of such simple get/set methods and exposing them as properties.'}, {'comments': [], 'desc': u'Improved Gray Scale (IGS) codes are used for the elimination of false contouring in images, and image compression. This Python program generates the IGS codes for a set of input gray level values.'}, {'comments': [], 'desc': u"IDLE, an integrated development environment for Python written in 100% Python using Tkinter, is included in Python 2.3 standard library as `idlelib'.\n\nThis recipie, `domtree.py', is a simple example for using `idlelib.TreeWidget'. It is a simplistic DOM viewer."}, {'comments': [], 'desc': u'This recipe is really about using previously identified information in a web page--ie, state information--to decide how to use newly identified information. To view a page of the kind that can be scraped using the code below visit \nhttp://www.archives.ca/02/02012202_e.html\nselect "Ontario", enter "Cornwall" in the Geographic Location box, and select "MAX" in the Number of References per page list.\n\nTwo kinds of document images are offered within each page served by the census site, namely, schedule 1 document images and schedule 2. Only the schedule 1 \ndocuments provide information in which I have an interest at present (namely surnames, birthdates, etc). I would, therefore, like to extract information that identifies schedule 1 images and ignore the others.\n\nPut in terms of state, when my script notices that it has most recently seen HTML code indicating schedule 1 I want it to extract information in the URLs in the "option" tags; when it has found schedule 2 I want it to ignore the URLs. It might be that one of the simplest ways of doing this is to form a regular expression (RE) that alternates one RE that recognises schedule numbers and one RE that recognises the URLs, then use this whole RE with a "sub" function so that the matches can be processed in a purpose-built function.\n\nIncidentally, I have found that Phil Schwartz\' "Kodos" Python Regex Debugger makes it a lot faster to create and check REs. Many thanks, Phil!'}, {'comments': [], 'desc': u'A subclass of the list object for managing files system objects (files, directories, etc.)'}, {'comments': [{'comment': u"The write method of SocketStream can throw a message on long files, because 'the socket operation can not complete without blocking'.\n<br>\nTo fix that, the response should be written out asynchroneously. Not sure about the details.", 'title': u'socket blocking'}, {'comment': u"I'm running against this very problem now, sockets blocking while working with larger files..\n<br><br>\nSo I'm wondering: is there anyone who does know the details on how to approach this asynchronously? \n<br><br>\nI'm relatively new to Python and my otherwise wonderfully progressing project is getting stuck on this very point :-/\n<br><br>\nAny help, suggestions or comments would be *very* welcome! :)", 'title': u'socket blocking .. reloaded'}, {'comment': u'You have to buffer the output and set the socket to non-blocking.\n\nYou can see a working example of this if you download leo (at leo.sourceforge.net) and look at the http plugin. This code, adapted for Leo, is based on this recipe', 'title': u'Use non-blocking writes'}, {'comment': u"EWOULDBLOCK arrives when output buffer is full and can't accept your data. You should use select function to wait while OS sends your output buffer to other side...", 'title': u'EWOULDBLOCK'}, {'comment': u'I have modified the socketStream class following the comments above : the socket is set to non-blocking, the output is buffered, and before sending data a select() is done to check if it is writable\n<br>I have made some performance tests with openload and found that this server is very fast, even with big files. I would appreciate comments on its speed and stability', 'title': u'New version'}, {'comment': u"The recipe can be improved :<br>\n- speed up the writable() method :\n<pre> return select.select([],[self.sock],[])[1]</pre>\n(no use testing if self.sock is in the list)<br>\n- make it more stable : for *very* large files, buffering everything is not a good solution. It's better to buffer the chuncks that arrive and try to get rid of them as soon as possible, before all the data has been received<br>\nAn improved version can be found at http://clubs.voila.fr/vault/karrigell/Public/SimpleAsyncHTTPServer.py", 'title': u'Faster and faster'}, {'comment': u"Using a cSringIO as a buffer is still not terribly fast. In fact, it is not significantly better than using a plain string with slicing.<br><br>\n\nOne is far better off using a deque of strings (from 2.4, or this recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259179 ), with proper slicing and/or the use of buffer() objects.<br><br>\n\nYou are also not exploiting the asyncore.loop() mechanism to handle writing to the asynchronous sockets at all, so calling the server asynchronous is misleading.<br><br>\n\nI've started converting what you have into something that is actually asynchronous, but it probably won't be done tonight (various social engagements will remove me from the task).", 'title': u' '}, {'comment': u'I\'ve got a version that I know works for GET requests (no connection pipelining, there is something hokey with clients that request it). It handles all reads and writes to sockets using asyncore.loop(), and on the standard GET requests, doesn\'t read entire files from disk (allowing one to serve up unlimited-sized files without worry about memory consumption).<br><br>\n\nI ran my version in my personal projects folder, which contains around a gig of files, of sizes ranging from a few kilobytes, to 100 megabytes. I then performed two concurrent "wget -m http://localhost:8081" calls (in different paths) on Windows 2k (machine is a P4 2.8ghz with hyperthreading, 1.5 gigs memory...).<br><br>\n\nOn small files, it was able to serve up 15-30 files/second. On large files (the 10+ meg files), it was able to serve up at 15+ megs/second (so says adding the speed reported by wget). The server never broke 7 megs of resident memory, and tended to hang below 10% processor utilization.<br><br>\n\nThe fully async version is available here:<br>\nhttp://www.ics.uci.edu/~jcarlson/SimpleAsyncHTTPServer.py', 'title': u'Truely Asynchronous version.'}, {'comment': u"I take the opportunity of Josiah Carslon's more complete recipe to update this one. This is the version used in the current version of Karrigell (the link provided in my previous comment is broken)", 'title': u'Updated version'}, {'comment': u"- I can't get post working\n- there are unused modules imported\n\nis there a new version?", 'title': u'2 things..'}, {'comment': u'Hi, how to add a link to "Up to higher level directory" in the sub folders?', 'title': u'how to add "Up to higher level directory"'}], 'desc': u'A simple HTTP Server, intended to be as simple as the standard module SimpleHTTPServer, built upon the asyncore/asynchat modules (uses non-blocking sockets). Provides a Server (copied from medusa http_server) and a RequestHandler class. RequestHandler handles both GET and POST methods and inherits SimpleHTTPServer.SimpleHTTPRequestHandler\n\nIt can be easily extended by overriding the handle_data() method in the RequestHandler class'}, {'comments': [{'comment': u"fyi - using python 2.2.2 with wxPython 2.4.2.4 on Win2K i get:\n\nNameError: global name 'enumerate' is not defined", 'title': u'global undefined'}, {'comment': u"The undefined global is because enumerate isa new built-in with Python 2.3. The author should explicitly state that this recipe requires Python 2.3 or more recent. (Technically it's not hard to re-write enumerate for earlier Python versions. Subject of another recipe, perhaps? :-) )", 'title': u'Python 2.3 required'}, {'comment': u"OK, OK, Python 2.3 required because of the use\nof the 'enumerate' built-in. On older versions\nof Python there are alternatives to enumerate, see\nelsewhere in the cookbook :-)", 'title': u'Python Version'}, {'comment': u"Didn't get to see many of the moves: adding wxYield() to the end of Move() did the trick.", 'title': u'A slight improvement (on my PC anyway)'}, {'comment': u'When running this code with wxWidgets-2.5.3 or higher an error will be reported:<br><br>\n\npython wxHanoiApp.py<br>\nTraceback (most recent call last):<br>\n File "wxHanoiApp.py", line 139, in OnPlay<br>\n self.Move( 0, 2, 1, self.numDiscs )<br>\n File "wxHanoiApp.py", line 182, in Move<br>\n self.Move( src, temp, dst, n-1 )<br>\n File "wxHanoiApp.py", line 182, in Move<br>\n self.Move( src, temp, dst, n-1 )<br>\n File "wxHanoiApp.py", line 182, in Move<br>\n self.Move( src, temp, dst, n-1 )<br>\n File "wxHanoiApp.py", line 180, in Move<br>\n self.MoveDisc( src, dst )<br>\n File "wxHanoiApp.py", line 176, in MoveDisc<br>\n wxUsleep( 100 * self.sleepTime )<br>\nNameError: global name \'wxUsleep\' is not defined<br><br>\n\nWhen using wxWidgets-2.5.3 or higher the code needs to be updated <br>changing the function call wxUsleep() to wxMilliSleep(). The function wxUsleep() has been deprecated.<br><br>\n\nTHANX(MKD).', 'title': u'Change call to wxUsleep() to wxMilliSleep() when using wxWidgets-2.5.3 or higher'}], 'desc': u"A simple Towers of Hanoi demo using wxPython.\nThis sits with my Koch snowflake demo and Guido's\nsimilar demo using Tk. Credit to Martin Bernreuther\nfor inspiration."}, {'comments': [{'comment': u"I use a Zope installation that uses Python 2.1 and it doesn't support iterators. Also, it doesn't allow variable names that start with '_'. So I made a modification to use in Zope for use in creating web reports. \nJust create a new script or a function within a script with the parameters seq and key (just like __init__ in the recipe). Use this code inside the function or script:\n\n<pre>\ngroupdict = {}\nfor item in seq:\n k = key(item)\n groupdict.setdefault(k, []).append(item)\nreturn groupdict.items()\n</pre>\n\nSince the Zope version that I have uses Python 2.1, it can't use iteritems, so it has to return an actual list. This means that a copy of the list of key, value pairs is created. This could drop performance if you have a large sequence.", 'title': u'Zope Friendly Version'}, {'comment': u"Note that in this line\n\n<pre>\nself.setdefault(k, []).append(value)\n</pre>\n\nan empty list is instantiated on each iteration.\n\nI prefer to use for similar tasks a dict subclass with KeyError\ncatched inside, like follows:\n\n<pre>\nclass idict(dict):\n\t'''self-initializing dictionnary'''\n\tdef __init__(self,init):\n\t\tdict.__init__(self)\n\t\tself.init=init\n\tdef __getitem__(self,key):\n\t\ttry:\n\t\t\treturn dict.__getitem__(self,key)\n\t\texcept KeyError:\n\t\t\tif callable(self.init):\n\t\t\t\tself[key]=self.init()\n\t\t\telse:\n\t\t\t\tself[key]=self.init\n\t\t\treturn dict.__getitem__(self,key)\n</pre>\n\nThen the groupby could be defined as a function:\n\n<pre>\ndef groupby(seq, key=lambda x:x):\n\td=idict(list)\n\tfor value in seq:\n\t\td[key(value)].append(value)\n\treturn d.items()\n</pre>\n\nThis class also provides a simple way to count list entries:\n\n<pre>\ndef count_list_items(ll):\n\td=idict(0)\n\tfor l in ll:\n\t\td[l]+=1\n\treturn d.items()\n</pre>", 'title': u'redundant list creation'}, {'comment': u'Recently I have used the idict class a number of times. It seems useful enough to warrant its own recipe.\n\nThanks,\nJonathan.', 'title': u'Can someone put the idict in its own recipe?'}, {'comment': u'The cost of setdefault() instantiating an empty list is miniscule in comparison with the overhead of a __setitem__ call to idict().', 'title': u'idict() is pennywise and pound foolish'}, {'comment': u'An application of this nice recipe:<br>\n<br>\ngroupbyhead: Group a list of items according to the starting character(s) of items.<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259173<br>', 'title': u' '}], 'desc': u'Guido inspired SQL-like GROUPBY class that also encapsulates the logic in a Unix-like "sort | uniq". '}, {'comments': [{'comment': u"Finding this recipe has just saved me an hour or so -- thanks!\n<br>\nAPI: How about using subscripting to access the counts?\n<br>\n<pre>\n>>> b = bag('banana')\n>>> b['a']\n3\n</pre>", 'title': u'subscripting?'}, {'comment': u'I agree with previous comment from Matt R and prefer subscripting interface so i can:<br>\n<br>\n>>> mybag = bag("abacab")<br>\n>>> mybag[\'d\'] += 1 #automatically adds \'a\' to bag if doesn\'t exist<br>\n>>> mybag[\'c\'] -= 2 #clear (or throw exception) if less than 2 \'c\'s in bag<br>\n>>> mybag[\'a\'] = 0 #removes all \'a\' from bag<br>\n>>> mybag[\'e\'] #queries bag for the count of \'e\'<br>\n0<br>\n<br>\nThis gets rid of count, add, remove methods.<br>\n<br>\nSince I inheret my bag from dict, I redefine pop() to both return and remove all of a given item of bag. Also since I have to redefine dict.__setitem__() anyway, I use that opportunity to validate the dict(non-zero integer) values before insertion. This also makes it easy for subclasses to redefine the policy of how the bag should behave (like in example #2 above). (Alternatively, one could pass in a policy function or "filter" to the bag constructor.)<br>\n<br>\nI also allow add/subtract arithmetic on bags:<br>\n<br>\n>>> bag("word counts from file one".split()) + bag("word counts from another file".split())<br>\nbag({"word": 2, "counts": 2, "from": 2, "another": 1, "file": 2, "one": 1})<br>\n<br>\nMike<br>', 'title': u'API'}, {'comment': u"I should add that the suggested API allows me to easily create an weighted graph class as a dict of bags with a nice API for the graph:<br>\n<br>\n>>> g = graph()\n>>> g['here']['there'] #returns edge weight<br>\n>>> g['here']['newthere'] = 1 #add new vertex 'newthere' with weight=1<br>", 'title': u'addendum'}, {'comment': u"Shouldn't the __ne__() operator be:\n\n<pre>\ndef __ne__(self, other):\n if not isinstance(other, bag):\n return True\n return self._data != other._data\n</pre>\n\nI.e. if the other object is not a bag, it is *not* equal to the bag?", 'title': u'Inequality operator'}, {'comment': u'Why does __iter__ iterate over (item, count) pairs as opposed to just items like dict? That is, why not try to parallel the current Python objects more?', 'title': u'__iter__'}, {'comment': u"I think maybe remove needs renamed. If I called the remove method on a bag, I would expect the count to be zeroed, not decremented. Maybe 'decrement' is a better name? I would also like a remove method that really does zero the count -- this is useful for pruning a bag by count... Of course, a 'prune' method that removes all items with less than or equal to a given count would be even better for my purposes...", 'title': u'remove'}, {'comment': u"I don't think sortedbycount should be a method. As your implementation shows, this functionality is already available with sorted(). I'm not sure that sortedbycount actually gains us much here...", 'title': u'sortedbycount'}, {'comment': u'If you think of the bag as a key:count dict, then yes, "remove" should remove the whole key, and "decrement" could decrement until 0 (then remove).\n<br><br>\nOn the other hand, if you think of the bag as an unordered container for multiple possibly-equal things, then it is sensible for "remove" to remove just one element instead of all elements being equal to the one you happened to select.\n<br><br>\nCase in point: Suppose you have a bag of many black and white marbles. You remove a white marble. Would you expect the bag to not contain any white marble? The method to remove all elements of an equality class should be aptly named "removeAll" or something to this effect.\n<br><br>\n-- Andre<br>\nProviding high quality math zealotry since 1977 ;)', 'title': u'Thinking in abstract vs. implementation'}, {'comment': u"My typical use for a bag class would be to hold word counts, not marbles. ;) So my abstraction *is* keys with counts. Of course, it's a moot point since the remove method's been removed in favor of __getitem__ and __setitem__.", 'title': u' '}, {'comment': u'Thanks, I like mostcommon a lot better!', 'title': u'mostcommon'}, {'comment': u"I would expect to able to write\n\n<pre>\nb1 = Bag()\nb2 = Bag()\n...\nb2.update(b1)\n</pre>\n\nAs written, this turns out to be a fairly inefficient way of doing it. If b1[k] == 20, it will take 20 separate calls to the iterator, the length adjuster, and the dictionary's __setitem__ \n", 'title': u'specialcase update with another bag'}, {'comment': u'I was looking at this again today because I need to use something like this right now, and it strikes me that itercounts is kind of confusing. For my current task, I want just the counts (i.e. the equivalent of _data.itervalues()). To me, itercounts sounds like it does this, not iterate through the (item, count) pairs.\n\nSo I guess I have two suggestions:\n(1) Make itercounts iterate just through the counts, and\n(2) Rename itercounts to something like iteritems or iteritemcounts.\n\nThanks again!', 'title': u'itercounts is confusing'}, {'comment': u'Users coming from Smalltalk or Objective C, or users familiar with C++ multiset will expect that a collections.bag is a container that is capable of holding the same thing (say, a string) multiple times. Currently, there appears to be no .add method, which I think there should be. Also, .remove should remove a single item, not all copies of the same item. For convenience, .addAll might be useful, to implement a frequency count.', 'title': u'Still need add and remove'}, {'comment': u'If you decrement a value below 0 there is no logical meaning and you can break the validity of len(myBag).<br><br>\n\n>>> x =bag.bag()<br>\n>>> x[\'a\']<br>\n0<br>\n>>> x[\'a\']-=1<br>\n>>> x[\'a\']<br>\n-1<br>\n>>> len (x)<br>\n<br>\nTraceback (most recent call last):<br>\n File "", line 1, in -toplevel-<br>\n len (x)<br>\nValueError: __len__() should return >= 0<br>', 'title': u'Bags should do not have -ve quantities'}], 'desc': u"Implement Smalltalk's bag class (similar to MultiSets in C++ or bag's in Objective C or Haskell's Edison module)."}, {'comments': [{'comment': u'ConfigObj version 2 is available at :<br>\nhttp://www.voidspace.org.uk/atlantibots/pythonutils.html<br>\n<br>\nThe new version is very different. You can pass in a filename and it will automatically parse it, it behaves like a dictionary for reading the values it returns, list values can have lists as members if you want... and more.<br>', 'title': u'New Version'}], 'desc': u'# A simple class of config object - allowing simple configs to be read in, updated in the file or rewritten out\n# Preserves comments inline with the keywords\n# Allows for multiple values - defined by the programmer what type of value a keyword is expected to have\n# Will read only the specified values from a file - allows sections of a larger config file to be\n# easily read and updated whilst preserving the rest of the file.\n# outputs non-fatal error to the stout object - this could be turned into an exception handler if you wanted\n# errors to be fatal instead of non-fatal.\n#\n\n# Maintained at www.voidspace.org.uk/atlantibots/pythonutils.html'}, {'comments': [{'comment': u"There's a new version of StandOut available at :\nhttp://www.voidspace.org.uk/atlantibots/pythonutils.html<br>\n<br>\nIt's *much* more powerful and useful - but the code is 16k so I don't think I'll post it here.<br>\n<br>\nIt works by diverting sys.stdout - so messages/logging can be done with normal print statements. In addition, varying levels of 'verbosity' can be specified (by you or your user) and messages assigned a priority... (only messages of a high enough priority will be displayed or logged).", 'title': u'New Version Available'}], 'desc': u"A useful output object that can 'print' to various places (stdout, loggign file and potentially to a window as well) using a single command.\nBuilt to be used in conjunction with the ConfigObj - simpel config file parser.\n\n# maintained at http://www.voidspace.org.uk/atlantibots/pythonutils.html"}, {'comments': [{'comment': u"I converted this version from \n\nhttp://lists.boost.org/MailArchives/boost/msg27062.php\n\nIts a one liner with a list of data values as input. I'm in the process of checking for correctness. If there is a faster way to write this please comment\n<pre>\ndef CRC64(data):\n CRC64_Table = (0x0000000000000000L, 0x42F0E1EBA9EA3693L, 0x85E1C3D753D46D26L, 0xC711223CFA3E5BB5L,\n 0x493366450E42ECDFL, 0x0BC387AEA7A8DA4CL, 0xCCD2A5925D9681F9L, 0x8E224479F47CB76AL,\n 0x9266CC8A1C85D9BEL, 0xD0962D61B56FEF2DL, 0x17870F5D4F51B498L, 0x5577EEB6E6BB820BL,\n 0xDB55AACF12C73561L, 0x99A54B24BB2D03F2L, 0x5EB4691841135847L, 0x1C4488F3E8F96ED4L,\n 0x663D78FF90E185EFL, 0x24CD9914390BB37CL, 0xE3DCBB28C335E8C9L, 0xA12C5AC36ADFDE5AL,\n 0x2F0E1EBA9EA36930L, 0x6DFEFF5137495FA3L, 0xAAEFDD6DCD770416L, 0xE81F3C86649D3285L,\n 0xF45BB4758C645C51L, 0xB6AB559E258E6AC2L, 0x71BA77A2DFB03177L, 0x334A9649765A07E4L,\n 0xBD68D2308226B08EL, 0xFF9833DB2BCC861DL, 0x388911E7D1F2DDA8L, 0x7A79F00C7818EB3BL,\n 0xCC7AF1FF21C30BDEL, 0x8E8A101488293D4DL, 0x499B3228721766F8L, 0x0B6BD3C3DBFD506BL,\n 0x854997BA2F81E701L, 0xC7B97651866BD192L, 0x00A8546D7C558A27L, 0x4258B586D5BFBCB4L,\n 0x5E1C3D753D46D260L, 0x1CECDC9E94ACE4F3L, 0xDBFDFEA26E92BF46L, 0x990D1F49C77889D5L,\n 0x172F5B3033043EBFL, 0x55DFBADB9AEE082CL, 0x92CE98E760D05399L, 0xD03E790CC93A650AL,\n 0xAA478900B1228E31L, 0xE8B768EB18C8B8A2L, 0x2FA64AD7E2F6E317L, 0x6D56AB3C4B1CD584L,\n 0xE374EF45BF6062EEL, 0xA1840EAE168A547DL, 0x66952C92ECB40FC8L, 0x2465CD79455E395BL,\n 0x3821458AADA7578FL, 0x7AD1A461044D611CL, 0xBDC0865DFE733AA9L, 0xFF3067B657990C3AL,\n 0x711223CFA3E5BB50L, 0x33E2C2240A0F8DC3L, 0xF4F3E018F031D676L, 0xB60301F359DBE0E5L,\n 0xDA050215EA6C212FL, 0x98F5E3FE438617BCL, 0x5FE4C1C2B9B84C09L, 0x1D14202910527A9AL,\n 0x93366450E42ECDF0L, 0xD1C685BB4DC4FB63L, 0x16D7A787B7FAA0D6L, 0x5427466C1E109645L,\n 0x4863CE9FF6E9F891L, 0x0A932F745F03CE02L, 0xCD820D48A53D95B7L, 0x8F72ECA30CD7A324L,\n 0x0150A8DAF8AB144EL, 0x43A04931514122DDL, 0x84B16B0DAB7F7968L, 0xC6418AE602954FFBL,\n 0xBC387AEA7A8DA4C0L, 0xFEC89B01D3679253L, 0x39D9B93D2959C9E6L, 0x7B2958D680B3FF75L,\n 0xF50B1CAF74CF481FL, 0xB7FBFD44DD257E8CL, 0x70EADF78271B2539L, 0x321A3E938EF113AAL,\n 0x2E5EB66066087D7EL, 0x6CAE578BCFE24BEDL, 0xABBF75B735DC1058L, 0xE94F945C9C3626CBL,\n 0x676DD025684A91A1L, 0x259D31CEC1A0A732L, 0xE28C13F23B9EFC87L, 0xA07CF2199274CA14L,\n 0x167FF3EACBAF2AF1L, 0x548F120162451C62L, 0x939E303D987B47D7L, 0xD16ED1D631917144L,\n 0x5F4C95AFC5EDC62EL, 0x1DBC74446C07F0BDL, 0xDAAD56789639AB08L, 0x985DB7933FD39D9BL,\n 0x84193F60D72AF34FL, 0xC6E9DE8B7EC0C5DCL, 0x01F8FCB784FE9E69L, 0x43081D5C2D14A8FAL,\n 0xCD2A5925D9681F90L, 0x8FDAB8CE70822903L, 0x48CB9AF28ABC72B6L, 0x0A3B7B1923564425L,\n 0x70428B155B4EAF1EL, 0x32B26AFEF2A4998DL, 0xF5A348C2089AC238L, 0xB753A929A170F4ABL,\n 0x3971ED50550C43C1L, 0x7B810CBBFCE67552L, 0xBC902E8706D82EE7L, 0xFE60CF6CAF321874L,\n 0xE224479F47CB76A0L, 0xA0D4A674EE214033L, 0x67C58448141F1B86L, 0x253565A3BDF52D15L,\n 0xAB1721DA49899A7FL, 0xE9E7C031E063ACECL, 0x2EF6E20D1A5DF759L, 0x6C0603E6B3B7C1CAL,\n 0xF6FAE5C07D3274CDL, 0xB40A042BD4D8425EL, 0x731B26172EE619EBL, 0x31EBC7FC870C2F78L,\n 0xBFC9838573709812L, 0xFD39626EDA9AAE81L, 0x3A28405220A4F534L, 0x78D8A1B9894EC3A7L,\n 0x649C294A61B7AD73L, 0x266CC8A1C85D9BE0L, 0xE17DEA9D3263C055L, 0xA38D0B769B89F6C6L,\n 0x2DAF4F0F6FF541ACL, 0x6F5FAEE4C61F773FL, 0xA84E8CD83C212C8AL, 0xEABE6D3395CB1A19L,\n 0x90C79D3FEDD3F122L, 0xD2377CD44439C7B1L, 0x15265EE8BE079C04L, 0x57D6BF0317EDAA97L,\n 0xD9F4FB7AE3911DFDL, 0x9B041A914A7B2B6EL, 0x5C1538ADB04570DBL, 0x1EE5D94619AF4648L,\n 0x02", 'title': u'This one might be faster'}, {'comment': u"The above comment doesn't show right. Here is the rest of the code\n\n<pre>\nreturn reduce(lambda x,y, t=CRC64_Table: t[((x>>56) ^ y) & 0xFF] ^ (x << 8), data, 0xffffffffffffffffL) ^ 0xffffffffffffffffL\n</pre>", 'title': u'Comment too long'}], 'desc': u'The algorithm to compute the CRC is described in the ISO 3309 standard. The generator polynomial is x64 + x4 + x3 + x + 1.\nReference: W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery, "Numerical recipes in C", 2nd ed., Cambridge University Press. Pages 896ff.'}, {'comments': [{'comment': u'In theory, a single append() or pop() has O(logN) amortized time, where N is the total number of operations made on the deque since instantiation. This is because as N grows very large, self.left and self.right can take up to O(log(N)) words as long ints.<br><br>\n\nIn practice, you could call this "O(1) amortized time," since for any N that I can achieve on my 2005-era computer, the time spent incrementing, decrementing, and hashing integers is insignificant.<br><br>\n\nCool, practicality beats purity!<br><br>', 'title': u'Comments on runtime'}], 'desc': u'Pure python drop in replacement for collections.deque() from Py2.4. See documentation at: http://www.python.org/dev/doc/devel/lib/module-collections.html\n<br>\nUses a dictionary as the underlying data structure for the deque (pronounced "deck", short for "double-ended queue", a generalization of stacks and queues) which provides O(1) performance for appends and pops from either end.\n<br>\nRuns on PyPy, Jython, and older Pythons.\n'}, {'comments': [], 'desc': u'Traps exceptions - to be printed or displayed without actually raising the exception.\n\nSometimes useful to get the *full* error message from an exception - this code captures it as text - to be displayed, saved or whatever.\n'}, {'comments': [{'comment': u'The program is running without giving error .BuT I don see any output of the program.Can anyone tell me whats going on in this program??', 'title': u'scanning program '}, {'comment': u'<pre>\nalter this line to make sense on you pc \nself.FILE_PATH = "//masblrfs06/karcherarea$/workarea/nishitg/"+ win32api.GetComputerName()\neg : self.FILE_PATH = "c:/temp/info_logging.log"\n\nthen to get rid of the exceptions in preparefile do this\n\n def preparefile(self,printCaption,printString):\n try:\n printText = printCaption + " : " + printString\n print printText\n if self.fileHandle:\n self.fileHandle.write(printText + "\\n") \n except:\n print "In Exception of Prepare file"\nwhich means, only log to a file if you have a file open !!\n\nat this point get rid of the line\nprint "debug1" \nreally gives you confidence hey !\n\nwhat we have now is a class definition, but we don\'t use it yet so add this at the end\n\nif __name__ == "__main__":\n sysinfo=GetSysInformation()\n sysinfo.openFile()\n sysinfo.getSysInfo()\n sysinfo.getSoftwareList()\n\nremarks:\nopenFile and closeFile are things I would do in __init__ __del__ and hand a parameter to __init__ telling it to do logging or not ...\n\n{-- just my 2p--}\nI don\'t think this is a good example of getting the installed software, one should rather use the wmi interface ...\n{/-- just my 2p--}\n</pre>', 'title': u"hm, wouldn't call this a cookbook recipe, looks more like an ingredient"}, {'comment': u'Using the registry is sometimes the best option for retrieving the list of *ALL* installed applications on a machine.<br><br>\n\nSome application entries and their vendor names (weirdly) go missing\nwhen WMI is used for retrieving the entries. This seems to be an\nissue shared by PHP and Python COM interface.<br><br>\n\nAny input on this issue would be helpful, ofcourse.', 'title': u'Problems with using WMI'}], 'desc': u'Reading the System information and Softwares installed in Windows NT/XP/2000/9x'}, {'comments': [], 'desc': u'Rating with items sorted by value and accessed by key or rating index.'}, {'comments': [{'comment': u"The comment method is on LexicalHandler, which isn't filtered by XMLFilterBase.\n\nTo get comments flowing into the filter, modify as follows (approximately; my code's at work at the moment...)\n\n<pre>\nfrom xml.sax.saxutils import XMLFilterBase\nfrom xml.sax.saxlib import LexicalHandler\nfrom xml.sax.handler import property_lexical_handler\n\n# Deriving from LexicalHandler gets you default no-op impls\nclass text_normalize_filter(XMLFilterBase, LexicalHandler):\n # __init__ as before\n\n # Override comment() method in LexicalHandler\n def comment(self, body):\n # Impl as before\n\n # Override XMLFilterBase.parse to connect the LexicalHandler\n # Can only do this by setting the relevant property\n # May throw SAXNotSupportedException\n def parse(self, source):\n self._parent.setProperty(property_lexical_handler, self)\n # Delegate to XMLFilterBase for the rest\n XMLFilterBase.parse(self, source)\n</pre>\n", 'title': u"comment() won't be called"}, {'comment': u'Taking both upstream and downstream parameters in the __init__ makes it hard to chain this with other filters.\n\nI prefer to keep the XMLFilterBase __init__ signature:\n\n<pre>\ndef __init__(self, parent):\n XMLFilterBase.__init__(self, parent)\n self._accumulator = []\n</pre>\n\nand then, rather than calling handlers on the downstream handler directly, delegate to the default XMLFilterBase handlers. These call out to whatever handlers have been set on the filter (with setContentHandler, etc).\n\n<pre>\ndef startElement(self, name, attrs):\n self._complete_text_node()\n XMLFilterBase.startElement(self, name, attrs)\n</pre>\n\nThis lets you chain filters like so:\n\n<pre>\nparser = sax.make_parser()\nfiltered_parser = text_normalise_filter(some_other_filter(parser))\n</pre>\n\nand also lets you use a filter in contexts which call the parse method on your behalf:\n\n<pre>\ndoc = xml.dom.minidom.parse(input_file, parser=filtered_parser)\n</pre>\n', 'title': u'Hard to chain'}, {'comment': u'the Filter fails at this little File which contains an German Umlaut\n\n<pre>\n<?xml version="1.0" encoding="ISO-8859-1"?>\n<Hallo Welt = "sch\xf6n"/>\n</pre>\n\nTraceback\n\n<pre>\n...\nFile "C:\\Progs\\python\\lib\\xml\\sax\\saxutils.py", line 83, in startElement\nUnicodeError: ASCII encoding error: ordinal not in range(128)\n</pre>', 'title': u'Quite nice, but ...'}, {'comment': u'the Filter fails at this little File which contains an German Umlaut\n\n<pre>\n<?xml version="1.0" encoding="ISO-8859-1"?>\n<Hallo Welt = "sch\xf6n"/>\n</pre>\n\nTraceback\n\n<pre>\n...\nFile "C:\\Progs\\python\\lib\\xml\\sax\\saxutils.py", line 83, in startElement\nUnicodeError: ASCII encoding error: ordinal not in range(128)\n</pre>', 'title': u'Quite nice, but ...'}, {'comment': u'for posting two times my last comment.\nI think I was wrong. Its not a use case to print Unicode in the shell. So I will rate the recipe with a lot of stars :-) ', 'title': u'Sorry'}], 'desc': u'A SAX parser can report contiguous text using multiple characters events. This is often unexpected and can cause obscure bugs or require complicated adjustments to SAX handlers. By inserting text_normalize_filter into the SAX handler chain all downstream parsers are ensured that all text nodes in the document Infoset are reported as a single SAX characters event.'}, {'comments': [], 'desc': u'Explore the mysteries of floating point arithmetic. This class readily reproduces textbook examples and provides immediate demonstrations of representation error, loss of precision (subtractive cancellation), and the failure of the distributive, commutative, and associative laws. Beyond textbook work, this class is also useful for exploring the numerical robustness of alternative algorithms.'}, {'comments': [{'comment': u'This is a nice example of clean coding in Python.\n<br>\nThis particular example is already builtin to the standard library. See calendar.weekday().', 'title': u'Clean'}, {'comment': u'I wrote this function as part of a set of date handling functions, for an administrative tool I was making (which works very nicely thank you !). The rest of the functions can be found at :<br>\n<br>\nhttp://www.voidspace.org.uk/atlantibots/pythonutils.html<br>\n<br>\nI only recently discovered the calender module in the standard library - which has about a third of my functions already coded !! Python just has too many batteries............', 'title': u'More Functions and too many batteries '}], 'desc': u'This simple function returns the day of the week (as an integer from 1 to 7) from an input date.....'}, {'comments': [{'comment': u"If you're looking to convert colorspaces, there is a python builtin module colorsys that does that stuff: http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/python/lib/module-colorsys.html\n<br><br>\nAlso, there is a recipe for RGB to hex/HTML colors: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/266466", 'title': u'Python color stuff'}, {'comment': u"I didn't know about the colorsys module, useful for converting between the various tuple color models.\n\nYour other recipe link points to this page :-)", 'title': u'thanks'}], 'desc': u"You have colors in a number of formats (html-style #RRGGBB, rgb-tuples (r, g, b), and PIL-style integers). You want to convert between formats. It's pretty easy to do, but also pretty easy to forget; hence, this recipe.\n\nJust for kicks, we'll extract an RGB tuple from an image file at the end."}, {'comments': [{'comment': u"<br>\nI'm a Python newbie; excuse me if don't get it right but i thought Python was about simplicity ...\n\n<br>What's wrong with:\n\n<br>def abstract_method(self):\n<br> raise 'Abstract method, please override'\n", 'title': u"I don't understand"}, {'comment': u'For one thing: clarity. My version gives the exact class and method names where the abstract method was defined.<br>\n<br>\nSecond: certainty. With that metaclass, it is guaranteed that you will never accitentally instantiate a class with one or more abstract classes.', 'title': u'Complexity'}, {'comment': u'I have created an abstract class which (besides self) has one argument on the __init__ method.\n<br>\nLater, I\'ve created a subclass of that abstract one, which added one more parameter to the __init__.\n<br>\nWhen creating an instance of the later, the error below pops up:\n<br>\n<pre>\nTraceback (most recent call last):\n File "ConcreteClass.py", line 70, in ?\n cc = ConcreteClass(param1, param2)\nTypeError: new() takes exactly 2 arguments (4 given)\n</pre>\n<br>\nBug?\n<br>\nAm I restricted to __init__(self) only (no other parameters)?', 'title': u'Constructor of subclasses requires 2 arguments'}], 'desc': u'The point is that python doesn\'t have a notion of "abstract methods." Abstract methods are part of an base class that defines an interface, without any code. Abstract methods can\'t be called directly, because they don\'t contain any code in their definition.\n\nIn the definition of the base class, you may want to include a specific method that is part of the interface, but the specific implementation is still unknown. A popular example seems to be the drawing of a point or a line in a graphical application.\n\nThe classes Point and Line share several implementation details, but differ on other. In particular, the way they are drawn is completely different (you will want to optimize the drawing of a line). Suppose these two classes are derived from the same class, Object. It is possible to separate the implementation of the method draw of these two classes, while draw can still be called from the base class Object.'}, {'comments': [], 'desc': u'Simple Python script to automate the creation of Python executables using py2exe.'}, {'comments': [{'comment': u'The only suggestion I would make would be to change<br>\n<pre>\n input = raw_input("D to delete, any other key to leave message on server: ")\n if input=="D":\n</pre>\nto be case insensitive (input.upper() or raw_input("...").upper()), the first time I ran the script I used all lowercase d\'s and was suprised to see 0 messages were deleted.\n<br><br>\nAlso, the "D to delete, any other key to leave message on server:" doesn\'t wait for any key to be pressed, it only works after you press enter, you\'d have to use a getch() type function to do that (see recipe #134892 or search for "getch")', 'title': u'Nice script'}], 'desc': u'A simple script that shows the headers from messages in a popbox and allows the user to delete messages on the server before downloading them. Only works with pop-servers that support the TOP-command.'}, {'comments': [{'comment': u'There is a script with a similar function included in the Python distribution:\n\n..\\Python22\\Tools\\scripts\\md5sum.py', 'title': u'Similar utility is included in the distribution'}, {'comment': u'FYI, Mac OS X *does* have a built-in md5 checksum command. It is called "md5".\n\nIt\'s in /sbin/md5 on my copy of Mac OS 10.2.8. I\'m pretty sure it\'s there by default, but perhaps you need to install the Developer Tools CD for it to be there.', 'title': u'Use the "md5" command on Mac OS X'}], 'desc': u"I'm used to having the md5sum utility on Linux systems, so I was surprised that Mac OS-X doesn't seem to have it. Rather than finding and compiling the C code, I took advantage of the fact that 10.3 includes Python, and rolled my own."}, {'comments': [{'comment': u'> You might want to use this for simple file or comms encryptions.<br>\n<br>\nYou probably don\'t want to use this -- encryption with XOR is notoriously weak and methods for ciphertext-only cryptanalysis have been around for centuries: do a Google for "Vigenere", a similar scheme based on the 26-letter alphabet.\n<br>\n<br>\nLots of good algorithms are at <pre>http://www.amk.ca/python/code/crypto.html</pre>\n. If you really need a simple cipher, consider implementing something like RC5 or TEA/XTEA which can be described in just a few lines of code.\n<br><br>\n(Incidentally, it\'s faster to build up a string by sticking the pieces in a list and doing a "".join(list), rather than by repeated concatenation.)\n<br>', 'title': u'XOR-encryption is very weak'}, {'comment': u'XOR encryption is what is used in the "perfect" encryption scheme of the one-time-pad. Use this method with a random key the same length as the message and you have the perfect code -- Just remember to never\nre-use the key!', 'title': u'XOR and the one-time-pad.'}, {'comment': u'As a recipe for others to learn from, the original code leaves much to be desired. Foremost, don\'t build strings with "+" because every addition builds a whole new string (for longer inputs, this O(n**2) behavior is a disaster). \n<pre></pre>\nAlso, try to not bury the code in comments -- python code is capable of "saying what it does". IOW, don\'t make something hard out of something simple.\n<pre></pre>\nEncryption-wise, it is not wise to transmit the key\'s CRC because it shrinks the key search space by an order of magnitude.\n<pre></pre>\nInstead of Vignere, using the random module is equally pithy but is much harder to crack. If you want the make this revised version even stronger without much effort, then compress the input string with: aString = zlib.compress(aString).\n<pre></pre>\nHere is an improved version that is still in the spirit of the original (kept short and sweet instead of complex and secure).\n\n<pre>\nimport random\n\nclass TinyCode:\n def __init__(self, aKey):\n self.rng = random.Random(aKey)\n\n def Crypt(self, aString):\n rand = self.rng.randrange\n crypted = [chr(ord(elem)^rand(256)) for elem in aString]\n return \'\'.join(crypted)\n\nif __name__ == "__main__":\n\n def strToHex(aString):\n hexlist = ["%02X " % ord(x) for x in aString]\n return \'\'.join(hexlist)\n\n keyStr = "This is a key"\n testStr = "The quick brown fox jumps over the lazy dog!"\n\n print "String:", testStr\n testStr = TinyCode(keyStr).Crypt(testStr)\n print "Encrypted string:", testStr\n print "Hex : ", strToHex(testStr) \n testStr = TinyCode(keyStr).Crypt(testStr)\n print "Decrypted string:", testStr\n</pre>', 'title': u'Improvements'}, {'comment': u'Since the conversion is done is a single pass, there in no need to make this a class. Here is a short function that does the trick and adds compression:\n<pre>\nimport random\nimport zlib\n\ndef tinycode(key, text, reverse=False):\n rand = random.Random(key).randrange\n if not reverse:\n text = zlib.compress(text)\n text = \'\'.join([chr(ord(elem)^rand(256)) for elem in text])\n if reverse:\n text = zlib.decompress(text)\n return text\n\nif __name__ == "__main__":\n\n def strToHex(aString):\n hexlist = ["%02X " % ord(x) for x in aString]\n return \'\'.join(hexlist)\n\n keyStr = "This is a key"\n testStr = "which witch had which witches wrist watch"\n\n print "String:", testStr\n testStr = tinycode(keyStr, testStr)\n print "Encrypted string:", testStr\n print "Hex : ", strToHex(testStr) \n testStr = tinycode(keyStr, testStr, reverse=True)\n print "Decrypted string:", testStr\n</pre>\n', 'title': u'One other thought'}], 'desc': u'A very simple keyword encryption algorithm. Produces an encrypted string the same size as the orginal. Not very strong encryption but good enough for lightweight stuff. Works on bytes so could be used for binary streams if converted to and from strings - maybe!'}, {'comments': [], 'desc': u'This class allows for the export of messages, Contacts and notes from Outlook to a ZODB filesystem database.'}, {'comments': [{'comment': u"HTTP basic auth is implemented with a single header:\n\n<pre>Authorization: Basic [base64-encoded-string]</pre>\n\nThe base64-encoded string is constructed like:\n\n<pre>base64.encode('%s:%s' % (username, password))</pre>\n\nurllib2.HTTPPasswordMgrWithDefaultRealm also does what you want, allowing you to use None as a generic realm when no other realm matches.", 'title': u'HTTP Basic auth'}, {'comment': u'Thanks Ian, it works.\nThe following code, I use to access my E-Tech router HTML-page, which is authenticated:\n\n<pre>\nimport urllib2, base64\n\nrequest = urllib2.Request(\'http://192.168.1.1/Status.htm\')\nbase64string = base64.encodestring(\'%s:%s\' % (\'user\', \'password\'))[:-1]\nrequest.add_header("Authorization", "Basic %s" % base64string)\n\nhtmlFile = urllib2.urlopen(request)\nhtmlData = htmlFile.read()\nprint htmlData\nhtmlFile.close()\n</pre>', 'title': u' '}], 'desc': u"I wanted to touch a particular web page (in order to open/close a database connection inside of Zope) so I came up with this module which uses urllib2 to make the web connection\n\nI was not sure what a 'realm' was, so first I made the HTTPRealmFinder to find out what the realm is. \n\nThe HTTPinger calls my required page and acts according to the http return code."}, {'comments': [], 'desc': u'I wanted to get the list of rss feeds from AmphetaDesk (my desktop news aggregator www.disobey.com/amphetadesk ) into the aggregator in Drupal (web community site tool drupal.org).\n\nI settled on automation of the Drupal web form using pycurl - the Python bindings to libcurl.'}, {'comments': [{'comment': u"Readers should recall that string objects have an expandtabs() method that does this. There's no need to write real code like the above.\n<pre>\n>>> '\\t\\tfoo'.expandtabs()\n' foo'\n>>> '\\t\\tfoo'.expandtabs(2)\n' foo'\n</pre>", 'title': u'Built-in expandtabs() method'}, {'comment': u"* Avoid using str as a variable name\n<br>\n* Join strings with ''.join() instead of +\n<br>\n* Lambdas are much slower than doing computations in a for-loop\n<br>\n", 'title': u'Functional yes, but not a great teaching example'}], 'desc': u'Python allows some degree of functional programming. Using the reduce() function and the lambda form we can express the common tab ->spaces expansion routine in a simpler and more efficient way'}, {'comments': [{'comment': u'>> The function is only a little slower than other recursive or iterative implementations that I\'ve tried.\n\n<br><br>Really? I\'d like to see the benchmarking code.\n\n<br><br>Below are results of mine. It compares four algorithms:\n<pre> \n A1: the one-liner posted here;\n A2: the built-in "index" (stupidly traversing the array every time, even in C:-));\n A3: the built-in binary search (bisect);\n A4: the built-for-lookups hash.\n</pre>\n\nThe output might look like this (doing it 100 times for an array of 10,000 elements):\n\n<pre>\n% ./bsearch4.py 100 10000\nint:\n A1:lambda: 259.8651\n A2:index: 491.4040\n A3:bisect: 21.7780\n A4:dict: 1.8144\nstr:\n A1:lambda: 310.5880\n A2:index: 460.4716\n A3:bisect: 20.3987\n A4:dict: 1.7134\n% \n</pre>\n\nWhat it prints is number of seconds spent on doing the same thing four different ways on two types of data: array-of-ints and array-of-strings. Notes:\n<br>1) for real-world apps, if an array is huge (1,000,000?), bisect will beat the hash;\n<br>2) don\'t try it at home.\n\n<br><br>// How do I attach a file.py here?..\n\n<br>______\n<br>What I love about Python is: it doesn\'t *insist*, doesn\'t even encourage me to write:\n<br>total = reduce(lambda x,y: x+y, map(int, line.rstrip().split()))\n\n<br><br>It\'s OK in Python to write three lines instead of one:\n<pre>\n>>> total=0\n>>> for x in line.split():\n... total += int(x)\n\n</pre>\n:-).', 'title': u'oneliners vs. reali-word apps'}, {'comment': u"oops... Forgot to mention why I tried brute-force-dumb-C. It actually will beat lambda on considerably large arrays:\n\n<pre>\n% ./bsearch4.py 1 100000\nint:\n A1:lambda: 1910.2782\n A2:index: 1073.1970\n A3:bisect: 2.6692\n A4:dict: 0.4715\nstr:\n A1:lambda: 1699.1667\n A2:index: 958.5173\n A3:bisect: 2.3792\n A4:dict: 0.4485\n% \n\n</pre>\nIf you're patient enough to try, that is.", 'title': u' '}], 'desc': u"This is an implementation of the binary search algorithm in (almost) one line. Given a number 'n' and a list 'L', the function returns the index of the number on the list, or -1."}, {'comments': [{'comment': u'Nice recipe.\n<pre>\n</pre>\n\nOne small improvement would be to simplify the maxwidth calculation:\n<pre>\nmaxWidths = [max([len(str(item)) for item in column]) for column in columns]\n\n</pre>\n\nAlso, the justify logic can be simplified with a dictionary:\n<pre>\ndispatch = dict(center=str.center, right=str.rjust, left=str.ljust)\n . . .\njustify = dispatch[justify.lower()]\n</pre>', 'title': u'Nits'}, {'comment': u'I am using a similar function to output tables in restructured text format\n(I generate lots of reports in rst). I brushed it up a little, added comments ...\nHere it is for the case someone needs something like this.\n\n<pre>\ndef toRSTtable(self,rows, header=True, vdelim=" ", padding=1, justify=\'right\'):\n """ Outputs a list of lists as a Restructured Text Table\n\n - rows - list of lists\n - header - if True the first row is treated as a table header\n - vdelim - vertical delimiter betwee columns\n - padding - padding nr. of spaces are left around the longest element in the\n column\n - justify - may be left,center,right\n """\n border="=" # character for drawing the border\n justify = {\'left\':string.ljust,\'center\':string.center, \'right\':string.rjust}[justify.lower()]\n\n # calculate column widhts (longest item in each col\n # plus "padding" nr of spaces on both sides)\n cols = zip(*rows)\n colWidths = [max([len(str(item))+2*padding for item in col]) for col in cols]\n \n # the horizontal border needed by rst\n borderline = vdelim.join([w*border for w in colWidths])\n\n # outputs table in rst format\n print borderline\n for row in rows: \n print vdelim.join([justify(str(item),width) for (item,width) in zip(row,colWidths)])\n if header: print borderline; header=False\n print borderline\n</pre>', 'title': u'something similar for restructured text'}, {'comment': u'Thanks Raymond :) I included your suggestions in v1.1', 'title': u' '}], 'desc': u'A function for pretty-printing a table.'}, {'comments': [{'comment': u"One way to achieve something like a DocumentComplete event is to check the Busy attribute:\n<pre>\nsw = ShellWindows[0] # let's grab the first window\nsw.Document.Location = 'http://www.python.org/'\n\nwhile sw.Busy: # loop until the page is loaded\n time.sleep(.1)\nprint sw.LocationName\n</pre>", 'title': u'waiting for DocumentComplete (sort of)'}, {'comment': u"You would think there would be an 'active' attribute that exists in Shell.Windows. So if you wrote a toolbar item it would be easy to find out from what instance of Internet Explorer were you started from. Or being a child component (a button on the ie browser bar) of an ie instance, you should be able to instantly tell who your parent browser instance is.", 'title': u'You would think there would be an active attribute'}, {'comment': u"You would think there would be an 'active' attribute that exists in Shell.Windows. So if you wrote a toolbar item it would be easy to find out from what instance of Internet Explorer were you started from. Or being a child component (a button on the ie browser bar) of an ie instance, you should be able to instantly tell who your parent browser instance is.", 'title': u'You would think there would be an active attribute'}, {'comment': u"You would think there would be an 'active' attribute that exists in Shell.Windows. So if you wrote a toolbar item it would be easy to find out from what instance of Internet Explorer were you started from. Or being a child component (a button on the ie browser bar) of an ie instance, you should be able to instantly tell who your parent browser instance is.", 'title': u'You would think there would be an active attribute'}, {'comment': u'You can see a similar recipe done using ctypes.\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305273', 'title': u'Connecting to running instances of IE on your computer'}], 'desc': u'Various sources (but principally Hammond and Robinson) show how to instantiate Internet Explorer in order to have access to its interfaces. However, few places show how to connect to an instance that is already running, which is so easy in VB. \n\nThanks are due to someone called "gcash" for this idea. See http://dbforums.com/t867088.html.\n\nIt just seemed to me that this is a good recipe to have in this collection as a reference to a certain approach, rather than as a full solution.'}, {'comments': [{'comment': u"Your already using the 'or shortcircuit hack', so why not use the 'and shortcircuit hack' and skip the 1 element slice and lookup altogether:\n<br><br>\ntime=(2,5)<br>\nall_minutes=(len(time)>0 and time[0])*60 + (len(time)>1 and time[1])", 'title': u' '}, {'comment': u'And while where at it, we could factor "len(time)" out:<br>\n<pre>\ntime=(2,5)\nln=len(time)\nall_minutes=(ln>0 and time[0])*60 + (ln>1 and time[1])\n</pre>\nI probably should have used another example.\n The problem is, this last version only works for default values of 0.\n<br><br>\nBy the way here is another way of doing this, avoiding shortcircuit. Dunno if there is any benefit to it:<br>\n<pre>\nall_minutes=(time[0:1]+[0])[0]*60+(time[1:2]+[0])[0]\n</pre>', 'title': u'Looks fine'}], 'desc': u"'.get()' functionality of mappings for sequences"}, {'comments': [{'comment': u'This takes quadratic time when all items are equal, no?', 'title': u'Not always O(n)'}, {'comment': u'<pre>\n\n# Changed the algorithm slightly to count the number of pivot entries\n# so that O(n) can be achieved for identical values. Also note that \n# there is an early out condition when you ask for the Nth value, and \n# len(data) 3:\n swap = random.randrange(len(data))\n data[0], data[swap] = data[swap], data[0]\n\n it = iter(data)\n pivot, piviotcount = it.next(), 1\n under, over = [], []\n ua, oa = under.append, over.append\n for elem in it:\n r = cmp(elem, pivot)\n if r <pre>\n\n# Changed the algorithm slightly to count the number of pivot entries\n# so that O(n) can be achieved for identical values. Also note that \n# there is an early out condition when you ask for the Nth value, and \n# len(data) 3:\n swap = random.randrange(len(data))\n data[0], data[swap] = data[swap], data[0]\n\n it = iter(data)\n pivot, piviotcount = it.next(), 1\n under, over = [], []\n ua, oa = under.append, over.append\n for elem in it:\n r = cmp(elem, pivot)\n if r </pre></pre>', 'title': u'O(n) for a sequence of identical values'}, {'comment': u"Don't know what's up, but I can't post the entire modifed algorithm...", 'title': u'Invalid previous post'}, {'comment': u'Even within the <pre> block, some additional markup is necessary to post code that includes less than or greater than comparisons. The markup is &lt; and &gt; respectively.<pre></pre>\nThe idea you were starting to post looks like an attempt to use cmp() to avoid doing two comparisons. My benchmarks show that this runs more slowly than using two comparisons but that may be dependent on the type of data being selected.', 'title': u'Using cmp()'}, {'comment': u'My previous comment was for v1.2. v1.3 seems to fix the worst case performance, but at the expense of a larger number of comparisons. I wonder if something like the following code would be faster. I\'m not sure the ops[cmp(...)] trickery is very Pythonic, though, especially as cmp doesn\'t seem to be guaranteed to return -1,0,1.\n<pre>\nimport random\n\ndef select(data, n):\n "Find the nth rank ordered element (the least value has rank 0)."\n data = list(data)\n try:\n while True:\n pivot = random.choice(data)\n under, over, match = [], [], []\n ops = match.append, over.append, under.append\n for elem in data:\n ops[cmp(elem,pivot)](elem)\n if n < len(under):\n data = under\n else:\n lowcount = len(under) + len(match)\n if n < lowcount:\n return pivot\n else:\n data = over\n n -= lowcount\n except IndexError:\n raise ValueError(\'not enough elements for the given rank\')\n</pre>', 'title': u' '}, {'comment': u'This approach seems inspired but does not win in timings with integer data. Ultimately, it should win whenever comparisons are very expensive *and* the data objects implement a clever __cmp__() method (otherwise, the builtin cmp() function will end-up making two comparisons to differentiate the three cases).', 'title': u'Using cmp() and computed append reference'}, {'comment': u"I'm unclear as to what kind of data you would use this for. I did some very simple tests, on lists of integers and strings, and in all cases that I tried, the obvious solution runs faster:\n\n<pre>\ndef select(data, n):\n data = list(data)\n data.sort()\n return data[n]\n</pre>\n\nCan you give some guidelines as to when your solution would be better?\n", 'title': u'Why?'}, {'comment': u'The difference between an O(n) algorithm and an O(n lg n) algorithm becomes more pronounced with long list lengths. This is particularly important when the constant factor is large (perhaps due to an expensive compare function).\n<pre></pre>\nFor instance, try generating a million and one random points and find the median point using a custom ordering function (dist, angle):\n<pre>\nclass Point:\n def __init__(self, x, y):\n self.x = x\n self.y = y\n def __cmp__(self, other):\n # order by distance from orig and then by angle from the x-axis\n c = cmp(self.x ** 2 + self.y ** 2, other.x ** 2 + other.y ** 2)\n if c != 0:\n return c\n if self.x == 0 and self.y == 0:\n return 0\n return cmp(math.atan2(self.y, self.x), math.atan2(other.y, other.x)\n</pre>\nAlso, when you run comparisions with sort(), be sure to randomize the data beforehand (sort() will take shortcuts if the data is already partially ordered).', 'title': u'Why use select()?'}], 'desc': u'O(n) quicksort style algorithm for looking up data based on rank order. Useful for finding medians, percentiles, quartiles, and deciles. Equivalent to data[n] when the data is already sorted.'}, {'comments': [{'comment': u"http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/181064\n<pre>\nimport random\nuserPick=''\nwhile userPick not in ['r', 'p', 's']:\n userPick = raw_input('\\tPlease enter (r)ock, (p)aper or (s)cissors to play... ')[0]\n\ncomputerPick= random.choice(['r','p','s']) \npair = (userPick, computerPick)\n\nresult= { pair==('r','r') or pair==('p','p') or pair==('s','s'): 'draw!',\n pair==('p','r') or pair==('s','p') or pair==('r','s'): 'You won!',\n pair==('r','p') or pair==('p','s') or pair==('s','r'): 'Computer won!'}[1]\n\nprint 'You entered: ', userPick, ', Computer entered: ', computerPick\nprint result\n</pre>", 'title': u"A switch example in a 'Rock, Scissors, Paper' game"}, {'comment': u"http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/181064\n<pre>\nimport random\nuserPick=''\nwhile userPick not in ['r', 'p', 's']:\n userPick = raw_input('\\tPlease enter (r)ock, (p)aper or (s)cissors to play... ')[0]\n\ncomputerPick= random.choice(['r','p','s']) \npair = (userPick, computerPick)\n\nresult= { pair==('r','r') or pair==('p','p') or pair==('s','s'): 'draw!',\n pair==('p','r') or pair==('s','p') or pair==('r','s'): 'You won!',\n pair==('r','p') or pair==('p','s') or pair==('s','r'): 'Computer won!'}[1]\n\nprint 'You entered: ', userPick, ', Computer entered: ', computerPick\nprint result\n</pre>", 'title': u"A switch example in a 'Rock, Scissors, Paper' game"}, {'comment': u'You give the need not to call each function while constructing the dictionary as the reason for using strings containing the function names and eval(). However functions are first-class objects that you can pass around - they only get called when you use the () operator on them. Thus you can instead write:\n\n<pre>\nfunction = {\n x<0 : setup,\n 0<=x<1: loadFiles,\n 1<=x<2: importModules\n }[1] \n\nfunction()\n</pre>\n\n(For Python 2.2.1 and later it would also probably be more readable to use True rather than 1 as the index for the dictionary.)', 'title': u'No need to use eval'}, {'comment': u'Thx for the input. The code was modified accordingly.', 'title': u' '}, {'comment': u"... but just a further small point of style: since the values in the dictionary are no longer the *names* of functions but references to the functions themselves, perhaps 'functionName' is now a less appropriate variable name - hence my suggestion of 'function'.", 'title': u"You're welcome ..."}, {'comment': u"Compared to an if/elif equivalent, there's quite a bit of overhead involved because, in addition to the construction of the dictionary itself, *all* of the condition tests are executed during the process.\n<br><br>\nPerformance testing using a large number of random input values indicate than the technique is about 66-70% slower than using a simple if/elif series of logical expressions.\n<br><br>\nWhether or not the speed is important, of course, depends on many other factors and would need to be traded-off against the arguably cleaner-looking syntax.\n<br><br>\nAs for the other proposed uses (selecting function and non-fuction values) -- isn't that exactly the purpose of dictionary/mapping objects? Although using temporarily constructed ones in this manor is clever, I suppose.", 'title': u'Relatively high penalty for doing range comparisons'}, {'comment': u'http://simon.incutio.com/archive/2004/05/07/switch#comments', 'title': u'Some discussions about python switches:'}, {'comment': u'http://simon.incutio.com/archive/2004/05/07/switch#comments', 'title': u'Some discussions about python switches:'}, {'comment': u"In and/or style, at the position between 'and' and 'or', you cannot use 0 or any other values which python consider as False in boolean expression.<br>\n\nIn your example:<br>\n<pre>\ny = ( (x<0) and -1 ) or \\\n ( (0<=x<1) and 0 ) or \\\n ( (1<=x<2) and 1 ) or \\\n ( (2<=x<3) and 2 ) or 'n/a'\n</pre>\ny will get the wrong 'n/a' when x equals 0.5, not 0, the correct answer.", 'title': u'dangerous in and/or style!'}, {'comment': u'As long as the switch parameter contains no characters that are invalid in an identifier:<pre>\nfuncName = \'do_%s\' % x\nfunc = getattr( self, funcName, None )\nassert func, "Invalid switch value \'%s\'" % x\nfunc()\n</pre>\n...with a separate method for each option:<pre>\ndef do_A(self):\n\tpass\n\ndef do_B(self):\n\tpass\n\ndef do_C(self):\n\tpass\n</pre>', 'title': u'6. Dispatch style'}, {'comment': u'Since I am a fan of functional style, I always have the following cond function handy: <br>\n<pre>\ndef cond(*args):\n \'\'\'Lisp- (or Arc-) like cond.\n if tests and functions should be deferred (that is, not\n evaluated anyway), they have to be preceded with "lambda :"\n Use as follows:\n \n >>> # Normal lisp-style\n >>> cond(False, "Hello", False, "World", True, "ok", False)\n \'ok\'\n >>> cond(False, \'Hello\', \'ok\') # if single value, use as default.\n \'ok\'\n >>> cond(True, "ok", {}[1], "This is a KeyError")\n Traceback (innermost last):\n File "", line 1, in ?\n KeyError: 1\n >>> cond(True, "ok", (lambda : {}[1]), "This is not")\n \'ok\'\n \'\'\'\n pairs = lambda l: l[1:] and ((l[0], l[1]),) + pairs(l[2:]) or l and ((True, l[0]),)\n for test, result in pairs(args):\n if callable(test): test = test()\n if test:\n if callable(result): result = result()\n return result\n</pre>\nThe parenthesis allows us to write stuff like\n<pre>\ncond(\n lambda:x>0, 1,\n lambda:x<0, -1,\n 0)\n</pre>\nwhich is IMHO quite readable. And in this example, if x>0, it does not even evaluate the other branch. Thanks, lambda!', 'title': u'A functional approach:'}], 'desc': u"Python style switches. Showing several ways of making a 'switch' in python."}, {'comments': [{'comment': u"<pre>\nSomehow the submitting program went crazy by submitting 2 copies \nat the same time. This page is a duplication of:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/269708\n\nand will no longer be maintained. Please don't add comment on \nthis page. \n\n(does any one knows how to delete a recipe ?)\n</pre>", 'title': u'double posting'}, {'comment': u"<pre>\nSomehow the submitting program went crazy by submitting 2 copies \nat the same time. This page is a duplication of:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/269708\n\nand will no longer be maintained. Please don't add comment on \nthis page. \n\n(does any one knows how to delete a recipe ?)\n</pre>", 'title': u'double posting'}], 'desc': u"Python style switches. Showing several ways of making a 'switch' in python."}, {'comments': [{'comment': u'It can be a bit simplier if you use<br>\nhttp://tycho.usno.navy.mil/cgi-bin/timer.pl<br>\nand the time command. The full 47-line code is at<br>\nhttp://zxw.nm.ru/synch_time.py<br>\nHere it is without some comments:\n<pre>\nfrom urllib import urlopen\nfrom time import time\nfrom os import system\n\ndef ask_time( url, tzn, tz2=None ):\n """Get time form the Internet.\n # url must be e.g. http://tycho.usno.navy.mil/cgi-bin/timer.pl :-)\n # tzn must be UTC,EST,PST,etc.\n # UTC will return time like "22:30:40 UT"\n # Other options return like "05:30:40 PM" i.e. with AM/PM\n # tz2 can be another time zone, e.g. EDT,PDT,etc.\n #Returns "HH:MM:SS AA" or empty string if any failure.\n """\n try:\n doc = urlopen( url ).readlines()\n for line in doc:\n line = line.strip()\n if line.endswith( tzn ) or (tz2 and line.endswith( tz2 )):\n col = line.index(\':\')\n return line[col-2:col+9] # 04:01:28 PM (or 22:30:40 UT)\n except:\n pass\n return \'\'\n\ndef synch_time( url, tz, tz2=None ):\n time_str = ask_time( url, tz, tz2 )\n if time_str:\n try:\n before = time()\n system( \'time \' + time_str ) # do synchronize!\n delta = time() - before\n return "Time is %s\\nCorrected by %.1f sec" % (time_str,delta)\n except:\n pass\n return \'Not synchronized\'\n\nif __name__ == "__main__":\n from win32ui import MessageBox\n rc = synch_time( "http://tycho.usno.navy.mil/cgi-bin/timer.pl", "EST", "EDT" )\n MessageBox( rc, "synch_time" )\n\n# EOF\n</pre>', 'title': u'A bit simplier...'}, {'comment': u"I guess I must be a bit of a python pig as the thought of using perl inside python hasn't occurred to me. I guess if I had more patience I would have got the original perl module to work. Unfortunately I no longer feel comfortable doing awk like things; I used to love awk I guess I must be a bit of a python pig as the thought of using perl inside python hasn't occurred to me. I guess if I had more patience I would have got the original perl module to work. Unfortunately I no longer feel comfortable doing awk like things; I used to love awk ", 'title': u'Perls before swine :)'}, {'comment': u"This didn't quite work for me. I'm using cygwin's time.exe in Win98, and it doesn't take AM/PM suffixes.\n<br>\nI replaced the line\n<pre>\n return line[col-2:col+9] # 04:01:28 PM (or 22:30:40 UT)\n</pre>\nwith\n<pre>\n tval = line[col-2:col+9] # 04:01:28 PM (or 22:30:40 UT)\n hh = int(tval[0:2])\n if tval[9] == 'P':\n hh = hh + 12\n return str(hh) + tval[2:8]\n</pre>", 'title': u'This required fix on my system'}], 'desc': u'Simon Foster\'s recipe "Simple (very) SNTP client"\n(see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117211)\ninspired me to get SNTP to do something useful when our office\nmoved to an ISP that didn\'t do client 37 time setting.\nThis recipe uses SNTP to get an estimate of the time offset\nand uses Thomas Heller\'s wonderful ctypes module to allow\ngetting/setting the win32 system time. I apologise in advance\nfor the rather awful int vs long bit twiddling in _L2U32 etc.'}, {'comments': [{'comment': u'Hi <br><br>\n\nIts good to see these types of advanced recipes, but if you are\ninterested in this type of thing it would probably pay to have a look\nat the Unum module.\n<br><br>\nhttp://home.tiscali.be/be052320/Unum.html\n<br><br>\nTim', 'title': u'Have a look at Unum heaps of work already done.'}, {'comment': u"As you can guess, I didn't know of it; it looks neat indeed. Thanks, I'll check it out.\n\nGeorge\n", 'title': u' '}, {'comment': u'There was a very good HP/Agilent paper on the topic of units and unit maths. \n\nThis is very useful for interactive use. For programs you would often want to use it like an assert ie waste time doing unit computations during debug or first run.\n', 'title': u' '}], 'desc': u'Programs that deal with measured quantities usually make an implicit assumption of the measurement unit, a practice which is error prone, inflexible and cumbersome. This metaclass solution takes the burden of dealing with measurement units from the user, by associating each quantity to a unit of some measure. Operations on instances of these measures are unit-safe; moreover, unit conversions take place implicitly.'}, {'comments': [{'comment': u'Font names with more than one word should be quoted: "Trebuchet MS".', 'title': u'On font styles'}, {'comment': u'Using pt units in web pages is not a very good idea. px is good, em would be better (but you should check the results in several browsers in any case).', 'title': u'font size'}], 'desc': u'This is a simple command-line based, template driven, lightweight Python script to create an image album.'}, {'comments': [], 'desc': u'This recipe shows how to create linked OptionMenus in Tkinter. That is, how to ensure that when you select an item in the first list, the list contents change in the second list, which changes the contents in the third list. While this code is for Pmw OptionMenus, it should be easily adaptable to other types of picklist or radiobutton widgets.'}, {'comments': [{'comment': u'Is this really a recipe? Looks like an application-size piece of code to me...', 'title': u'Useful, but..'}], 'desc': u'HTTP Replicator is a general purpose, replicating HTTP proxy server. All downloads through the proxy are checked against a private cache, which is an exact copy of the remote file structure. If the requested file is in the cache, replicator sends it out at LAN speeds. If not in the cache, it will simultaneously download the file and stream it to multiple clients. No matter how many machines request the same file, only one copy comes down the Internet pipe. Very useful for maintaining a cache of Debian or Gentoo packages.'}, {'comments': [{'comment': u"Nice (although map can do nearly the same), here a small improvement:\n<pre>\nclass Repeat:\n def __rmul__(self,n):\n for i in range(n):\n if self.passCurrentIndex:\n self.kwargs.update({'currentIndex':i})\n self.func(*self.args,**self.kwargs)\n else:\n self.func(*self.args,**self.kwargs)\n def __call__(self,func,*args,**kwargs):\n self.func=func\n self.args=args\n self.passCurrentIndex=kwargs.pop('passCurrentIndex',None)\n self.kwargs=kwargs\n return self\nrepeat=Repeat()\n\n# PRINT usable as FUNCTION\ndef printf(*args):\n print ' '.join(args)\n\n# usage:\n5 * repeat(printf, 'Hello', 'World')\n\n# test index argument\ndef testRepeat(*args,**kwargs):\n print ' '.join(args), 'index=',\n print kwargs.get('currentIndex','USE passCurrentIndex=True TO ACTIVATE')\n\n5 * repeat(testRepeat, 'Hello', 'World')\n5 * repeat(testRepeat, 'Hello', 'World', passCurrentIndex=True)\n</pre>\nFrankly, Python is the best for me and I can't imagine a <br>\nbetter way to do language wraps like in Python.<br>\nPaul", 'title': u'Some improvements'}], 'desc': u'Ruby offers very nice language constructs for loops or for iterating over lists like the following: 5.times { print "Hello World" }. This recipe shows a hack how to implement these features in python.'}, {'comments': [{'comment': u'To make scalling works, this patch should be added:<br>\n<pre>\nclass ObjectMerger:\n def __hasattr__( self, attr ):\n return reduce( lambda x, y: x or hasattr( y, attr ), [self.___super, self.__self], 0 )\n</pre>', 'title': u'scalling fix'}, {'comment': u'Maybe you could change it to:\n\n<pre>\nclass ObjectMerger:\n """\n Object \'Merger\'.\n \n Returns an instance that takes methods from an arbitrary sequence\n of instances/objects, in order. The initial sequnce of objects\n is duplicated on construction, so future alterations will not\n affect the behavior of this class. Each object is tested for the\n required attribute in order, until a match is found.\n """\n def __init__(self, classes):\n self.___classes = tuple(classes)\n \n def __getattr__ ( self, name ):\n if not name.startswith(\'___\'):\n for cls in self.___classes:\n try:\n return getattr(cls, name)\n except AttributeError:\n pass\n return getattr(ObjectMerger, name)\n</pre>\n\nI believe this will allow you to fuse the attributes of any number of classes, without the explicit need for functional composition.<br>\n\nHere\'s a different version which is a bit more minimal, but may also be more efficent:\n\n<pre>\nclass ObjectMerger(tuple):\n def __getattr__(self, name):\n for obj in self:\n try:\n return getattr(obj, name)\n except AttributeError:\n pass\n return getattr(ObjectMerger, name)\n</pre>\n\nDave\n', 'title': u'What about more than two objects???'}, {'comment': u'Should have used __getattribute__ on this last example (for new style classes).', 'title': u'Oops...'}, {'comment': u"I'll try that with Javier's line too.\n\nI prefer using hasattr() instead of catch the exception, but don't know what is better of both ways.\n\nThanks!", 'title': u'Thanks'}, {'comment': u"I believe that using try/except is superior to testing with hasattr. Because it involves only one test (instead of using two), the code should execute faster.\n\nThere's nothing wrong with using hasattr() in principle, but I chose to use the try/except mechanism as a way of improving the performance of the algorithm, especially if it is searching through an arbitrary number of classes/instances.", 'title': u'Try/Except vs. using hasattr()'}], 'desc': u'The ObjectMerger class dynamically merges two given objects, making one a subclass of the other. The input elements could either be class instances or simple types, making this class particularly useful to derive native classes (for instance, cStringIO).\nThe resulting ObjectMerger instance acts as a proxy to the new type, allowing callers to work with it in the same way they would work with any other statically derived type.'}, {'comments': [], 'desc': u'Sample generator using only r calls to random.random().'}, {'comments': [{'comment': u"<pre>\nimport glob, os\nglob(os.path.join(directory, '*%s' % extension))\n\n[os.path.join(directory, fn)\n for fn in os.listdir(directory)\n if fn.endswith(extension)]\n\nfilter(lambda fn, ext=extension: fn.endswith(ext),\n map(lambda fn, dir=directory: os.path.join(dir, fn),\n os.listdir(directory)))\n</pre>\n\nOr get the path module from http://www.jorendorff.com/articles/python/path/\n\n<pre>\nfrom path import path\npath(directory).listdir('*.gif')\n[fn for fn in path(directory).listdir()\n where fn.ext = extension]\n[fn for fn in path(directory).listdir()\n if fn.fnmatch('*.gif')]\n</pre>", 'title': u'6 more (single-expression) implementations'}, {'comment': u'<pre>\n\nThe module glob lets you do all these kind of stuff\n\nSee: http://IvoNet.nl > Development for other Python stuff\n\n</pre>', 'title': u'Just use the module glob for this purpose'}, {'comment': u'Thanks for that. I esp like the list comprehension with the endswidth --> had never come across that before.<br>\nJames', 'title': u'Thanks'}], 'desc': u'--> returns a list of files with a given extension in a given directory'}, {'comments': [{'comment': u'It is faster still to use _int=math.floor for this situation (rounding positive numbers downward).', 'title': u'math.floor() beats int()'}, {'comment': u'The float result still needs to be converted back to an integer at some point.', 'title': u'Nix the previous comment'}, {'comment': u'In the next version of Python, list comprehensions have been super-optimized and cannot be beat by pre-allocating and using indices.\n<pre>\ndef sample_wr(population, k):\n "Chooses k random elements (with replacement) from a population"\n n = len(population)\n _random, _int = random.random, int # speed hack \n return [_int(_random() * n) for i in xrange(k)]\n\n</pre>\nAnd you can go bit faster using itertools:\n<pre>\ndef sample_wr(population, k):\n "Chooses k random elements (with replacement) from a population"\n n = len(population)\n _random, _int = random.random, int # speed hack \n return [_int(_random() * n) for i in itertools.repeat(None, k)]\n\n</pre>\n', 'title': u'In Py2.4, pre-allocation no longer rules'}, {'comment': u"return [population[_int(_random() * n)] for i in ... ]<br>\n<br>\nI've been following python-dev, so I'm aware of the optimizations you've been making. Congratulations on your results to date, and thank you for your time and efforts. <br>\n<br>\nI wonder, do you suppose the developers would accept changing random.sample to allow for sampling with replacement? <br>\n<br>\n# replacement=False by default (backwards compatible)<br>\nrandom.sample(population, k, replacement=True) \n", 'title': u'correction, accolades, and propositions'}, {'comment': u'For several reasons, probably not. \n<pre></pre>The straight-forward list comp does the trick pretty well. Anything that someone can bang out without much thought is rarely a good candidate for building into the library unless the pattern is very general and the use cases very common. The reasoning is that it is typically easier to bang out a couple of lines than to learn and remember dozens of method variations. Part of the justification for the inclusion of sampling without replacement is that it took a great deal of skill and time to implement correctly.\n<pre></pre>The other issue is that there are plenty of use cases that just do not need the whole sample all a once (those are best served by a simple for-loop). In contrast, sampling without replacement requires some state memory between calls.\n\n<pre></pre>Also, adding a new method is typically preferred to adding a keyword switch (for example, see itertools ifilter() and ifilterfalse()). However, for the reasons listed above, the inclusion of this as a separate method is unlikely.\n\n<pre></pre>I put all of this here because it is useful to a wider audience. Feel free to email me for any further discussion.', 'title': u'Adding a replace=False option to random.sample'}], 'desc': u'For taking k random samples (with replacement) from a population, where k may be greater than len(population).'}, {'comments': [], 'desc': u'Photographic document images are often rotated, if only slightly. This code mediates an input of a series of four points--assumed to be the corners of a rectangular document--in any order, as mouse clicks. Then it determines the orientation of the points and calculates a "quality" value, as an indication to the user of how well the four points s/he has chosen approximate to the corners of a rotated rectangle. Finally, it makes the information that it has been passed, or that it has been able to glean, available to the script that invoked it.'}, {'comments': [{'comment': u'It seems that on Windows, you have to switch to binary mode to be able to upload binary files like pictures\n<pre>\ntry:\n import msvcrt,os\n msvcrt.setmode( 0, os.O_BINARY ) # stdin = 0\n msvcrt.setmode( 1, os.O_BINARY ) # stdout = 1\nexcept ImportError:\n pass\n</pre> ', 'title': u' '}, {'comment': u'... and just to share my version: http://zxw.nm.ru/test_w_upload.py.htm', 'title': u'Sample'}, {'comment': u"drats! <br><br>this script (as well as the one by Georgy Pruss that's mentioned in the thread) looks easy enough to implement but i'm having no luck. <br><br>is there more documentation i can refer to for setting this up? thanks", 'title': u'documentation for upload.cgi ?'}, {'comment': u'<pre>\nIf I choose more than one file to upload only the fisrt file uploads.\nI commented the "form = cgi.FieldStorage" line in the "save_uploaded_file" fuction and put it just above the \nfuction . now all three file uploads take place.\n</pre>\n ', 'title': u'file upload problem'}, {'comment': u"I guess that's because they way the original script is written, FieldStorage gets instantiated three times, each time the save_upload() function is called. But probably already at the first time the FiledStorgae eats up alls data from sys.stdin where the uploaded files are provided.<br>\n<br>\nSo FieldStorage should be instantiated only once and then either made available, as you suggested, as a global variable or handed over as a third argument to the save_upload() function.<br>", 'title': u'cgi.FieldStorage instantiation'}, {'comment': u"How does the CGI module get a file from a client's computer?\nAlso, how does the CGI module get data from the POST method?\nI have written a lightweight version of the CGI module, but\ngetting files is something that it cannot do yet. The CGI\nprograms that currently work with it do not specify a\nmethod.", 'title': u'File Transfer'}], 'desc': u'This is a bare-bones cgi file upload. It will display an upload form and save the uploaded files to disk.'}, {'comments': [], 'desc': u'Using the Apache XPath API from Jython.'}, {'comments': [{'comment': u"http://www.i-technology.de/fivewins_en.htm\n<br>\nIt is not in Python but in JavaScript. The source is provided, perhaps you'd like to convert it to Python?", 'title': u'Have a look at 5-tic-tac-toe'}, {'comment': u'Hmm...I had written a JavaScript version with support for multiple board sizes long ago - http://www.premshree.resource-locator.com/javascripts/tic-tac-toe/', 'title': u' '}, {'comment': u'In tic-tac-toe, the board size is the same as the winning length of the line (3). In the Get5 (Gomoku) the board size is 19x19 and the winning length is 5', 'title': u'Slightly different game'}, {'comment': u'I made a gomoku game in python, that work in ascii or with pygame. 5 stones to align.\nSources are free.\nhttp://flibuste.net/libre/morpyon', 'title': u'gomuku with 5 stones'}], 'desc': u'A web-based Tic Tac Toe game in Python.'}, {'comments': [{'comment': u"Really fine piece of code, I just noticed some issues when addresses contain '.' or domains '-' as in jean-claude.gerard@solution-e-transactions.com\nCheers, P.", 'title': u'Issue with addresses containing dashes and dots '}], 'desc': u'A regular expression just-for-fun recipe for leeching email addresses.. even\nsome of those that are supposed to be only human readable.\n'}, {'comments': [], 'desc': u'Alternative way of extracting text from a WF XML source.'}, {'comments': [], 'desc': u'This recipe provides recursive nlst() behavior on top of a normal ftplib.FTP instance. The rnlst() method provided by the LocalFTP class returns a list of filenames under the path passed in as an argument. (One use for this list might be mirroring an ftp site. However, the python distribution contains a script called ftpmirror.py - use that instead.)\n\nBest suited for use on fast local connections, or for use on relatively small remote ftp directories. \n\nPlease see code comments for additional information.'}, {'comments': [{'comment': u"Why not just do this, assuming f is an open file?\n\n<pre>\n\nfor q in f.readlines()[::-1]:\n print q\n</pre>\n\nor if you want the last few lines of a file you can do something like\n\n<pre>\nfilelist = f.readlines()[-5:]\nfilelist.reverse()\n</pre>\n\nThis will give you the last 5 lines in a file and then reverse them.\n\nI'm not questioning the usefulness of your code. I'm just wondering what it buys me over the few lines above. Assuming that it uses less memory, how large a file do you need to read before it becomes worthwhile?", 'title': u'Reverse file'}, {'comment': u'I use it for reading big log files, I think 10Mb is big enough to warrant using it. Think "Do I want my program to increase in memory usage the size of this file?"\n<br><br>\nAlso if your program uses lots of log files, like if you want to search for error messages in the last day of 100x10mb log file, I imagine it would be slower to load each file into memory (create list objects), then free the memory again, than two do a few disk reads.\n<br><br>\nBasically it\'s a \'tail\' for python. I haven\'t done any speed or memory efficiency tests, it just seems like a cleaner way to do things.\n<br><br>\nEg. You could use \'less\' and \'G\' (go to end) to read the end of a log file, or you could use \'tail\'. If what you\'re looking for is probably in the last few lines, better to start looking there :)\n<br><br>\nBTW: I was given this code by Michael D. Stenner (the guy with the copyright) who wrote it to read mbox files or something, he posted it in IRC on #python on FreeNode network. He gave me permission to postit here. I hope everyone enjoys it :)\n<br><br>\nwww.sherborneinternational.com', 'title': u'Memory'}, {'comment': u"That's the part that would have been nice to have in the discussion. I had assumed there was a good reason for all that code vs. the much more succinct method available in normal python syntax.\n\nThanks for the explanation.", 'title': u'Aha'}], 'desc': u'Read a file line by line starting at the end'}, {'comments': [{'comment': u"Very nice recipe. I'm not very familiar with aspect oriented development, but I can see this being useful almost immediately as a convenient approach to keeping debug information. One question, open to the world. I'm still trying to get my head around the new @ style decorators, but it seems like they might be useful when combined w/ this recipe. With the current approach, you have to weave every function for which you want to keep debug information. Still an improvement, but tedious if you are obsessive about sanity checking/logging and have lots of factory functions. In 2.4, shouldn't it be possible define a wrapper function that simply returns its argument, decorate any functions for which we want to keep debug information with this wrapper function, and then weave debug aspects on the wrapper? This would seem to be a painless way to manage debug/release versions of functions throughout a large program as this way functions don't have to know about a global debug variable to control their behavior and the debug version code is consolidated in one or two functions. Admittedly, this would defeat part of the point of function decorators (i.e. since you are going to weave in the aspect later, the function ends up having a 'decorated' behavior (via the aspect) assigned after the main function block). However, ideology aside, this should be fine as long as we make sure we follow this order: define the wrapper function first, the functions to be decorated next, and then finally apply the aspect to the wrapper function, shouldn't it?", 'title': u"Question about aspects and 2.4 '@' function decorators"}, {'comment': u"Thanks for this recipe, this is really cool.\n<br><br>\nIt looks like it wouldn't be too hard to also add an unweave function. This would allow debugging to be added and removed at runtime.\n<br><br>\n<dreaming>It would be rather nice to be able to add and remove logging from specific instances rather than specific classes... It's a real shame that python doesn't support instance methods.</dreaming>", 'title': u'How about an unweave?'}], 'desc': u'Aspects can be used to add some extra behavior to functions or methods. This behavior is added at runtime and can be useful for things like logging, tracking references and even security.'}, {'comments': [{'comment': u'An easy way to expand the interface is to subclass from UserDict.DictMixin in Py2.3.', 'title': u'Full Dictionary Interface'}, {'comment': u'I will point to a similar recipe here:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252524<br><br>\n\nIt uses LRU and offers a fairly complete dictionary interface.', 'title': u'Similar recipe...'}], 'desc': u'This is a mapping-like object that attempts to efficiently hold a fixed number of previous entries, automatically discarding older entries.'}, {'comments': [], 'desc': u'A few simple discriptor classes to compute and cache attribute value on demand and to define attribute as alias to other.'}, {'comments': [{'comment': u'I\'d like to see a module along these lines as part of the standard \nlibrary. Add cut, uniq, sort, and a few others, and you\'d really \nhave something.<br><br>A wee fussy mod or two:<br><br><pre>class match:\n """keep only lines that match the regexp"""\n def __init__(self, pat, flags=0, method=\'match\'):\n self.fun = getattr(re.compile(pat, flags), method)\n def __ror__(self, input):\n return ifilter(self.fun, input)\n\nclass search(match):\n def __init__(self, pat, flags=0):\n match.__init__(self, pat, flags, method=\'search\')\n\ngrep = search\n</pre>... and then later...<pre>class writelines:\n "write each item to a file like object"\n def __init__(self, f):\n self.file = f\n def __ror__(self, input):\n for l in input:\n self.file.write(l)\n\nprintlines = writelines(sys.stdout)\n</pre>\nOne makes grep behave more commandliney (grep doesn\'t insist upon matching at the beginning of the first line by default) and the other adds a more generic writelines method and re-implements printlines with it -- also eliminating an issue in which cat(file)|printlines would double the newlines. <br><br>', 'title': u'Fantastic hack! '}, {'comment': u"We could define<pre>def cat(fname, mode='rtU'):\n return file(fname).xreadlines()</pre>but it's a little redundant as one can just as easily use file() as easily in Python 2.3, at least, thanks to iter(file-like-object) being suitabily equivalent to iter(file-like-object.xrealines()) in behaviour. ", 'title': u'Hmmm'}, {'comment': u'Thank you for your feedback. In fact, there was a similar hierarchy in the original module, but i did cut this off before posting here in order to be more easy-readable.\n\nThis receipe is, first of all, to demonstrate the new syntax, not to propose a complete module.\n\nOf course one can add analogs to other unix-tools, and the issues concerning enchancements in recent python versions, such as file() iterability, enumerate() function et cetera should be considered. Hovewer i prefer to avoid writing code before i really need it.', 'title': u'Re: fantastic hack'}, {'comment': u'I had put module text and related discussion to my personal wiki-page: http://lbss.math.msu.su/~krikun/PipeSyntaxModule', 'title': u'module URL'}], 'desc': u'This module introduces an alternative syntax a-la shell pipes for sequence-oriented functions, such as filter, map, etc., via certain classes that override __ror__ method.'}, {'comments': [], 'desc': u'This is a Python script to generate the OPML feed of your LiveJournal (http://www.livejournal.com/) Friends list.'}, {'comments': [{'comment': u'Technique described here: http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers\n\nScript found here http://www.phppatterns.com/docs/develop/twisted_aggregator - essential bit below;\n\n<pre>\nclass ConditionalHTTPPageGetter(HTTPPageGetter):\n \n def handleStatus_200(self):\n # If we\'re good, try recording the last-modified header\n if self.headers.has_key(\'last-modified\'):\n self.factory.lastModified(self.headers[\'last-modified\'])\n \n def handleStatus_304(self):\n # Close connection\n self.factory.notModified()\n self.transport.loseConnection()\n \nclass ConditionalHTTPClientFactory(HTTPClientFactory):\n \n protocol = ConditionalHTTPPageGetter\n \n def __init__(self, cacheDir, url, method=\'GET\', postdata=None, headers=None,\n agent="Twisted ConditionalPageGetter", timeout=0, cookies=None,\n followRedirect=1):\n \n self.cachefile = cacheDir+os.path.sep+self.getHashForUrl(url)\n \n if os.path.exists(self.cachefile):\n \n lastModified = open(self.cachefile).readline().strip()\n \n if headers is not None:\n headers[\'last-modified\'] = lastModified\n else:\n headers = {\'last-modified\': lastModified }\n \n \n HTTPClientFactory.__init__(self, url, method=method, postdata=postdata,\n headers=headers, agent=agent, timeout=timeout, cookies=cookies,\n followRedirect=followRedirect\n )\n \n self.waiting = 1\n self.deferred = defer.Deferred()\n \n \n def lastModified(self, modtime):\n f = open(self.cachefile,\'w\')\n f.write(modtime[0])\n \n def getHashForUrl(self, url):\n hash = md5.new()\n hash.update(url)\n return hash.hexdigest()\n \n def notModified():\n if self.waiting:\n self.waiting = 0\n \ndef conditionalGetPage(cacheDir, url, contextFactory=None, *args, **kwargs):\n scheme, host, port, path = client._parse(url)\n factory = ConditionalHTTPClientFactory(cacheDir, url, *args, **kwargs)\n if scheme == \'https\':\n from twisted.internet import ssl\n if contextFactory is None:\n contextFactory = ssl.ClientContextFactory()\n reactor.connectSSL(host, port, factory, contextFactory)\n else:\n reactor.connectTCP(host, port, factory)\n return factory.deferred\n</pre>', 'title': u'Conditional HTTP GETs'}], 'desc': u"This is a fully featured Rss aggregator with parsing included.\n\nIt's scalable too very high numbers of feeds and can be used in multi-client environment through web using twisted with a little code on top of Nevow (www.nevow.com), or can easily be integrated inside every app which uses some of the toolkits supported by Twisted."}, {'comments': [{'comment': u'Any special reason to prefer lst[0:0]= [obj] over lst.insert(0, obj)? I am asking out of curiosity.', 'title': u'[0:0] vs .insert(0,'}], 'desc': u'Pairing heap refinement for fewer comparisons.'}, {'comments': [{'comment': u'Your implementation takes a linear-time call to count for each member in the set. The somewhat less concise dictionary implementation takes only a single linear-time pass through a dictionary. Since when has conciseness been a virtue in Python?', 'title': u'Wrong tradeoff'}, {'comment': u'True, it is less efficient, but as a practical matter, I was using it for frequency counts on a list of ~5000 strings, and could not perceive a slowdown. Personally, I\'d prefer to have 1 line instead of 6, knowing that I can replace it if performance ever becomes a problem. Especially since this version is understandable at a glance.<br> \nAs Guido says in his optimization anecdote: "Rule number one: only optimize when there is a proven speed bottleneck."', 'title': u'For readability, not conciseness.'}, {'comment': u'So create a histogram function<pre>\ndef histogram( A, flAsList=False ):\n """Return histogram of values in array A."""\n H = {}\n for val in A:\n H[val] = H.get(val,0) + 1\n if flAsList:\n \treturn H.items()\n return H\n</pre>\n\nThen the call is self-documenting:<pre>\n freq = histogram( myList )\n</pre>', 'title': u'Create a function'}, {'comment': u"Guido almost certainly would find the OP's code to be abhorrent. Admonitions against premature optimization do not equate to a directive to write insanely inefficient code that does not scale. Compression to a single line is only a worthy goal if there is no sacrifice in clarity or performance.", 'title': u'Channeling Guido'}, {'comment': u"<pre>\n>>> from itertools import groupby\n>>> [(k, len(list(g))) for k, g in groupby(sorted(myList))]\n[('1', 4), ('2', 1), ('3', 2), ('4', 1)]\n</pre>", 'title': u'O(n log n) variation. Equivalent to: sort myList | uniq -c'}, {'comment': u'I have revised the recipe to match your implementation.', 'title': u'Thanks Raymond, for the improvement.'}], 'desc': u'You often see frequency counts done with dicts, requiring serveral lines of code. Here is a way to do it in one line using itertools and list comprehensions. This revised version was suggested by Raymon Hettinger. It is O(n log n). '}, {'comments': [], 'desc': u'An object in a program frequently has an internal "state", and the behavior of the object needs to change when its state changes.\nAs someone who tends to think of objects as "data structures on steroids", it came as quite a shock when Netscape\'s Steve Abell pointed out that an object need not contain any values at all -- it can exist merely to provide behaviors, in the form of methods.\nThis recipe demonstrates a networkcard that depends on its internal state connected/disconnected - to send/receive data.'}, {'comments': [{'comment': u'I too had the problem at work, several times in fact. The Unix tools that I knew made it fairly easy to write a one-liner that could make the changes to derived file names, but I didn\'t know enough ed or ex etc, to make my changes and save them to the same file.<br>\nOn discussing this with collegues, one piped up "just use perl dash pie". "You what"?? said I. "It\'s easy", he said, and went on to explain "use<br> perl -p -i -e \'s/change this/..to this/g\' ". <br>\nIt worked, and looking up the perl I found out why it worked. But then came my dilemma, I\'m the sites Python advocate (with not much to show at the moment). This one liner is very useful to me, but written in perl. What do I do?<br>\nI decided that I should be practical, perl-dash-pie is easier for me to remember than the syntax of the cut command, and all the sites Solaris and Linux boxes have perl so now I have added perl-dash-pie to my toolbag and squared it with my conscience.<br>\nBut I\'m still only a reluctant Perl programmer for the multi line stuff. ', 'title': u"WHy I have a toe in 'the dark side'."}, {'comment': u'I LOVE the "Perl Dash PIE" trick!! Can it be made to recursively "find and replace" as well?', 'title': u'Very Nice Trick...'}, {'comment': u'I made some changes to this code to make sure that it does not try to do search and replace on directories and allows the user to submit a list of extensions that should searched, so that not all files are checked. I\'d like to also adjust this to make and keep a backup of the changed files. Unfortunely, if you use fileinput.input\'s build in ability to save a backup, then you end up with a nackup of every file checked.\n<br>\n<br>\n---------------\n<br>\n<pre>\ndef searchreplace(req,path,search,replace,exts=None):\n\t\n\timport fileinput, glob, string, sys, os\n\tfrom os.path import join\n\t# replace a string in multiple files\n\t#filesearch.py\n\t\n\tfiles = glob.glob(path + "/*")\n\tif files is not []:\n\t\tfor file in files:\n\t\t\tif os.path.isfile(file):\n\t\t\t\tif exts is None or exts.count(os.path.splitext(file)[1]) is not 0:\n\t\t\t\t\tfor line in fileinput.input(file,inplace=1):\n\t\t\t\t\t\tlineno = 0\n\t\t\t\t\t\tlineno = string.find(line, search)\n\t\t\t\t\t\tif lineno >0:\n\t\t\t\t\t\t\tline =line.replace(search, replace)\n\t\t\t\t\t\tsys.stdout.write(line)\n</pre>', 'title': u'Updated Code'}, {'comment': u'if lineno >0: should be if lineno >=0:\n\nAlso, how would you make this recursively check directories?', 'title': u' '}], 'desc': u'A friend of mine needed to change the IP address in his DNS hosting bind configuration. Here is a quick script I wrote during lunch it interates all files in a directory and finds and replaces as string. In this case an IP address.'}, {'comments': [{'comment': u"This is a very cool decorator Raymond. I do have one small suggestion. Instead of hard-coding the various bytecode numbers, I'd import symbols from the opcode module just to future-proof it a little:\n\n<pre>\n from opcode import opmap, HAVE_ARGUMENT, EXTENDED_ARG\n LOAD_GLOBAL = opmap['LOAD_GLOBAL']\n LOAD_CONST = opmap['LOAD_CONST']\n</pre>\n\nSkip", 'title': u'Very cool ... One suggestion'}, {'comment': u'Incorporated the suggested change. Thanks!', 'title': u'Done'}, {'comment': u'I have a voxel rendering class, with several nested loops. It needs a very tight inner loop, and as such I have *17* _len = len style optimisations to avoid excessive dict lookups.<br><br>Thanks Raymond, this is brilliant stuff, and has tidied up my code very nicely indeed!', 'title': u'Exceedingly Cool.'}, {'comment': u'Since the constants are bound when the module is imported, the recipe should be named "BindingConstants at import time" or something like that, imo.', 'title': u'compile time?'}, {'comment': u"Here's a metaclass that calls make_constants for all methods of a class.\n\n<pre>\nclass OptimizingMetaclass(type):\n def __init__(cls, name, bases, dict):\n super(OptimizingMetaclass, cls).__init__(name, bases, dict)\n\n import types\n for name, attribute in dict.items():\n if type(attribute) is types.FunctionType:\n dict[name] = _make_constants(attribute)\n</pre>\n\nI know, decorators make you think about the right place to put them - but if it doesn't break the code, there should be nothig bad about optimizing everywhere.\n\n<br>\n\nBTW, if you still want to keep it configurable, try:\n\n<pre>\ndef build_optimizing_metaclass(builtin_only=False, stoplist=[], verbose=False):\n from types import FunctionType\n class _OptimizingMetaclass(type):\n def __init__(cls, name, bases, dict):\n super(_OptimizingMetaclass, cls).__init__(name, bases, dict)\n\n for name, attribute in dict.items():\n if type(attribute) is FunctionType:\n dict[name] = _make_constants(attribute, builtin_only, stoplist, verbose)\n\n return _OptimizingMetaclass\n\n__metaclass__ = build_optimizing_metaclass(verbose=True)\n</pre>", 'title': u'Metaclass makes things more handy'}, {'comment': u'bind_all misses\n<pre>from types import FunctionType, ClassType</pre>\n\nand, I guess, bind_all simplifies my last comment to\n\n<pre>\nclass OptimizingMetaclass(type):\n def __init__(cls, name, bases, dict):\n super(OptimizingMetaclass, cls).__init__(name, bases, dict)\n bind_all(cls)\n\ndef build_optimizing_metaclass(builtin_only=False, stoplist=[], verbose=False):\n class _OptimizingMetaclass(type):\n def __init__(cls, name, bases, dict):\n super(_OptimizingMetaclass, cls).__init__(name, bases, dict)\n bind_all(cls, builtin_only, stoplist, verbose)\n\n return _OptimizingMetaclass\n</pre>', 'title': u'bind_all misses imports'}, {'comment': u"I use closures fairly frequently, so I've found it useful to add code to this to also prebind constants in code objects in func_code.co_consts and functions under closures.\n\nThe code objects part is pretty simple; just split out the part of _make_constants that deals only with the code object into a separate function (say, code_make_constants) which takes the code object co, the environment dict env, stoplist, and verbose as arguments and do\n<pre>\n newconsts = [(isintance(c, CodeType)\n and code_make_constants(c, env, stoplist, verbose)\n or c)\n for c in co.co_consts]\n</pre>\nsomewhere up at the top.\n\nBinding the constants on functions in closures is a little more tricky, but it can be done using the get_cell_value and change_cell_value functions from some recipes I've posted.\n\nI have this code block in _make_constants, before the function object is created:\n<pre>\n for cell in (f.func_closure or []):\n value = get_cell_value(cell)\n if isinstance(value, FunctionType):\n change_cell_value(\n cell,\n _make_constants(value, builtin_only, stoplist, verbose)\n )\n</pre>\nFor those that wonder why I would do such a thing: Optimizing code objects in .co_consts is useful when you have subfunctions, i.e.\n<pre>\ndef foo(n):\n def bar():\n return n\n return bar\n</pre>\nbar will show up as a code object in foo.func_code.co_consts. Optimizing functions in a func_closure tuple is useful when you use wrapper functions in decorators, i.e.:\n<pre>\ndef the_decorator(f):\n def wrapper(*args, **kwargs):\n result = f(*args, **kwargs)\n return do_something_with(result)\n return wrapper\n\n@the_decorator\ndef baz():\n return do_stuff()\n</pre>\nWith this pattern, the original baz code will not be accessible except in a cell in baz.func_closure.\n", 'title': u'getting into closures as well'}, {'comment': u'I used to wrap all the functions and classes in a "main" function, which returned a dictionary of names to be exported for two reasons:<br>\n<br>\n1. speed (LOAD_DEREF was faster than LOAD_GLOBAL)<br>\n2. less namespace clutter (ie all the imported modules did not show up in the module\'s globals)<br>\n<br>\nThe first part is handled by the recipe. The second part can easily be dealt with by deleting the imported modules after running the bind_all function (assuming that all LOAD_GLOBALS have been replaced with LOAD_CONST, of course :)', 'title': u'Another side effect'}], 'desc': u'Decorator for automatic code optimization. If a global is known at compile time, replace it with a constant. Fold tuples of constants into a single constant. Fold constant attribute lookups into a single constant.'}, {'comments': [{'comment': u"reZip can be simplified, I think:\n\n<pre>def reZip(aList):\n return zip(*aList)</pre>\n\nI usually call this function 'pivot'.\n\nThis returns a list of tupes, rather than a list of lists. If that matters, you could do:\n\n<pre>def reZip(aList):\n return [list(tup) for tup in zip(*aList)]</pre>\n", 'title': u'reZip'}, {'comment': u"Is their an efficient way to split a list into two,\nequivalent to the code snippet below?\n<br>\n<pre>\na = [ x for x in List if 'a' in x ]\nb = [ x for x in List if not 'a' in x ]\n</pre>", 'title': u'What about splitting a list?'}], 'desc': u'A collection of some useful list-related functions.'}, {'comments': [{'comment': u"To convert: d = [[1, 5, 8, 3], [2, 2, 3, 9], [3, 2, 4, 6]]<br>\nto: [(1, 2, 3), (5, 2, 2), (8, 3, 4), (3, 9, 6)]<br><br>\n\nwe can use: zip(*d) in place of 'rezip(d)'. So the function rezip() is obsolete. I will still keep it here for biginners.\n", 'title': u'obsolete rezip ... '}, {'comment': u"To convert: d = [[1, 5, 8, 3], [2, 2, 3, 9], [3, 2, 4, 6]]<br>\nto: [(1, 2, 3), (5, 2, 2), (8, 3, 4), (3, 9, 6)]<br><br>\n\nwe can use: zip(*d) in place of 'rezip(d)'. So the function rezip() is obsolete. I will still keep it here for biginners.\n", 'title': u'obsolete rezip ... '}, {'comment': u'within python 2.3 there sum() is a buildin. so instead:\n\n<pre>\ndef sumList(L):\n return reduce(lambda x,y:x+y, L)\n</pre>\n\njust write\nsum(L)', 'title': u'sum now integrated'}], 'desc': u'A collection of some useful list-related functions.'}, {'comments': [], 'desc': u'A collection of some dictionary tools'}, {'comments': [{'comment': u'where does the findIndex in randomPickDict(d) comes from?', 'title': u'findIndex'}, {'comment': u'overlooked the links at the bottom.', 'title': u'Sorry'}], 'desc': u'A collection of some dictionary tools'}, {'comments': [], 'desc': u'This recipe allows to code SQL queries the same way independent on paramstyle of used DB module.'}, {'comments': [{'comment': u'Nicely documented recipe. But I can\'t see how opening file descriptors like this would correctly handle stdin, stdout and stderr:\n\n<pre>\n# Redirect the standard file descriptors to /dev/null.\nos.open("/dev/null", os.O_RDONLY) # standard input (0)\nos.open("/dev/null", os.O_RDWR) # standard output (1)\nos.open("/dev/null", os.O_RDWR) # standard error (2)\n</pre>\n\nObviously, you don\'t really want to close the existing ones, but I once saw a good trick in Python Standard Library (Lundh) for doing a similar thing:\n\n<pre>\nclass NullDevice:\n def write(self, s):\n pass\nsys.stdin.close()\nsys.stdout = NullDevice()\nsys.stderr = NullDevice()\n</pre>\n\nI\'ve used that quite a bit, with some success.', 'title': u'Problem with closing file descriptors'}, {'comment': u'Nicely documented recipe. But I can\'t see how opening file descriptors like this would correctly handle stdin, stdout and stderr:\n\n<pre>\n# Redirect the standard file descriptors to /dev/null.\nos.open("/dev/null", os.O_RDONLY) # standard input (0)\nos.open("/dev/null", os.O_RDWR) # standard output (1)\nos.open("/dev/null", os.O_RDWR) # standard error (2)\n</pre>\n\nObviously, you don\'t really want to close the existing ones, but I once saw a good trick in Python Standard Library (Lundh) for doing a similar thing:\n\n<pre>\nclass NullDevice:\n def write(self, s):\n pass\nsys.stdin.close()\nsys.stdout = NullDevice()\nsys.stderr = NullDevice()\n</pre>\n\nI\'ve used that quite a bit, with some success.', 'title': u'Problem with closing file descriptors'}, {'comment': u'<pre>\nIn general, when creating a daemon, you want to close all file\ndescriptors inherited from the parent process. createDaemon()\ncloses all file descriptors from 0 to maxfd. This isn\'t always\nnecessary, but it\'s good practice.\n</pre>\n\n<pre>\nNext, three calls to os.open() are made. This function returns,\nwhen successful, the lowest file descriptor not currently open\nfor the process. Since the standard fd\'s (0, 1, 2) were\npreviously closed, they\'re now recreated in the daemon process\nwith an association to /dev/null rather than the actual standard\nI/O streams.\n\nNow, anytime a reference is made to the standard I/O streams in\nthe daemon process, it\'s redirected to /dev/null.\n</pre>\n\n<pre>\nAs visual proof, try the following. Modify the os.open() calls\nto:\n\nos.open("/testlog", os.O_CREAT|os.O_APPEND|os.O_RDONLY) # stdin \nos.open("/testlog", os.O_CREAT|os.O_APPEND|os.O_RDWR) # stdout\nos.open("/testlog", os.O_CREAT|os.O_APPEND|os.O_RDWR) # stderr\n\nAnd add the following to the end of the file:\n\n...\n\n# won\'t be created and no errors will be reported.\nopen("createDaemon.log", "w").write("rc: %s; pid: %d; ppid: %d; pgrp: %d\\n"%\\\n (retCode, os.getpid(), os.getppid(), os.getpgrp()))\n\nsys.stdout.write("test stdout\\n")\nsys.stdout.flush()\nsys.stderr.write("test stderr\\n")\nsys.stderr.flush()\n\n...\n\nThe output contained in /testlog verifies the standard I/O streams,\nstdout and stderr, are redirected.\n</pre>\n\n<pre>\nHope this helps.\n</pre>', 'title': u'How it works'}, {'comment': u' ', 'title': u' '}, {'comment': u"Hi, I'm newish to Python and I'm wondering how this approach to writing a daemon is better than running a Python script in the background (run from a Linux or UNIX command line) as follows? :\n\n\n$ python myPython.py Hi, I'm newish to Python and I'm wondering how this approach to writing a daemon is better than running a Python script in the background (run from a Linux or UNIX command line) as follows? :\n\n\n$ python myPython.py ", 'title': u'How is this better than "&"?'}, {'comment': u"Good read.\n\nOne question. Why do you reopen fd's 1 and 2 using O_RDWR instead of \nO_WRONLY?", 'title': u'Why O_RDWR for stdout and stderr'}, {'comment': u'<pre>I guess it\'s a matter of habit and how I\'ve seen it done in the past.</pre>\n<pre>When programming a daemon in C, I tend to open/create a file descriptor to "/dev/null" (or any file)<br>[fd = open(DEVNULL, O_RDWR)] with the RDWR flag and then duplicate the standard descriptors:</pre>\n<pre>\ndup2(fd, STDIN_FILENO);\ndup2(fd, STDOUT_FILENO);\ndup2(fd, STDERR_FILENO);\n</pre>\n<pre>I just carried the idea/style to the pythonized daemon code.</pre>', 'title': u'RE: Why O_RDWR for stdout and stderr'}, {'comment': u'First off, this is some great advice for writting daemon applications.<br><br>\n\nProblem:<br><br>\n\nI am running a daemon application using your code to convert the process to a daemon. It works great, but shortly after running, it starts to occupy almost all the CPU as if the process is in spinlock. However, the process should be blocking (rather than spinning) as it is waiting to read from a named pipe. Any idea why the process is taking up most of the CPU and how to stop it from doing so? Here\'s the code after I call the "createDaemon()" function:<br><br>\n\n<pre>\n# Write process id to a file\nfp = open(pid_file, \'w\')\nfp.write(str(os.getpid()))\nfp.close()\n\nfpipe = open(pipe_path, \'r\')\n\nwhile 1:\n log_line = fpipe.readline()\n\n input_list = log_line.split(\'\\t\')\n\n if len(input_list) < 4:\n continue\n\n file_path = input_list[4]\n\n slash_pos1 = file_path.find(\'/\', 1)\n slash_pos2 = file_path.find(\'/\', slash_pos1 + 1)\n\n homedir_path = file_path[:slash_pos2]\n logs_path = homedir_path + \'/logs\'\n\n if debug_on:\n print \'Logging to \' + logs_path\n\n if os.path.exists(logs_path):\n fp = open(logs_path + \'/xferlog\', \'a\')\n fcntl.lockf(fp, fcntl.LOCK_EX)\n fp.write(log_line)\n fcntl.lockf(fp, fcntl.LOCK_UN)\n fp.close()\n\nfpipe.close()\n</pre>', 'title': u'The Daemon Process Is Using Most of the CPU'}, {'comment': u"<pre>My two cents -</pre>\n<pre>It looks like you're creating a busy while loop. The fpipe.readline()\nreturns immediately when there is nothing to read, it doesn't block,\ncreating the busy while loop until there is something to read. This is why\nyour CPU usage rises.</pre>\n<pre>You may want to look at using something like select and/or the low level\nopen, read, and write (and other tools) in the os module.</pre>", 'title': u'RE: The Daemon Process Is Using Most of the CPU'}, {'comment': u"I'm using this code, and it functioning very good. But sometimes (once a week) my application crashes. I tried to try/except everything, but somehow sometimes something goes wrong. \n\nI've created a function log(), that I can use for logging. At this moment it sends me an e-mail and writes and entry in syslog. I want to redirect stderr to this function, but the problem is that strerr is a stream, and I don't really know how you can convert this to a log() call. \n\nDoes anyone has an idea or am I thinking wrong?", 'title': u'error to syslog'}, {'comment': u"sorry, the answer is in the code I see now...\n\nI feel ashamed. I didn't implement the full code. _and_ I pushed the wrong 'add comment' button. \n\nSorry for wasting time!", 'title': u' '}, {'comment': u'The answer is quite simpel:\n\n<pre>\nimport sys\n\nclass LogErr:\n def write(self, data):\n print "log: " + data\n\nt = LogErr()\nsys.stderr = t\nsys.stderr.write("test stderr\\n")\n</pre>\n\nI\'ve put it here, maybe it can be usefull for somebody.', 'title': u' '}, {'comment': u'I don\'t see why 2 forks are needed. I think all that\'s needed is:\n if (os.fork()) == 0:\n os.setsid()\n maxfd = os.sysconf("SC_OPEN_MAX")\n for fd in range(0, maxfd):\n try:\n os.close(fd)\n except OSError: # ERROR (ignore)\n pass\n\n # Redirect the standard file descriptors to /dev/null.\n os.open("/dev/null", os.O_RDONLY) # standard input (0)\n os.open("/dev/null", os.O_RDWR) # standard output (1)\n os.open("/dev/null", os.O_RDWR) # standard error (2)\n\n else:\n sys.exit (0)\n ', 'title': u'Simplify'}, {'comment': u"Some UNIXes don't require it. It doesn't hurt to do it on all UNIXes. The reason some UNIXes require it is to make sure that the daemon process is NOT a session leader. A session leader process may attempt to aquire a controlling terminal. By definition a daemon does not have a controlling terminal. This is one of the steps that might not be strictly necessary, but it will eliminate one possible source for faults.", 'title': u'It always takes two forks to make a daemon. This is tradition.'}, {'comment': u'<pre>\n"How is this better than [background task]?"\n</pre>\n<p>\nFor long-running processes that are not tied to a terminal, for example. \n</p>', 'title': u'Depends On Use'}, {'comment': u'<pre>\n"I don\'t see why 2 forks are needed."\n</pre>\n\n<p>\nTo have a seperate, stand-alone process running that is abandoned by its parent to live its own life without ever knowing if its parant is alive or dead, for example.\n</p><br>', 'title': u'Depends On Use'}, {'comment': u"And don't forget that the parent process who double-fork()s their daemon child never has to worry about it turning into a Zombie when they die too.", 'title': u'Benifit To The Parent '}, {'comment': u"I have tried to implement this but I am having trouble.\nHere is what I have tried.\n\n<pre>\n#!/usr/bin/env python\nimport pyDaemon\nimport time\nimport sys\nimport os\npyDaemon.createDaemon()\ndef logit(self):\n fp = open('test.log','w')\n fp.write('Hello\\n')\n fp.close()\nwhile true:\n time.sleep(300)\n logit()\n<pre>\n\nI left the Daemon Code untouched and nothing happens.\n\nThanks,\n Josh holt</pre></pre>", 'title': u'Example of usage'}, {'comment': u'Because stderr is being redirected to /dev/null, you won\'t be informed of any errors in your program.\n\nIn this case, you have \'self\' as a parameter to logit, but it\'s not class member. Just remove \'self\' and it should work fine.\n\nAlso, you might want to use mode "a" rather than "w"; this way you\'ll see "Hello!" being added every 5 minutes, rather than just one "Hello!"', 'title': u'Error in your program'}, {'comment': u'When using the random module after daemonize, then the file description is not accessible anymore, and it produce this error:\n<br><br>\nTraceback (most recent call last):<br>\n File "/usr/share/mille-xterm/lbserver/main.py", line 332, in ?<br>\n main()<br>\n File "/usr/share/mille-xterm/lbserver/main.py", line 287, in main<br>\n random.seed()<br>\n File "/usr/lib/python2.4/random.py", line 110, in seed<br>\n a = long(_hexlify(_urandom(16)), 16)<br>\n File "/usr/lib/python2.4/os.py", line 728, in urandom<br>\n bytes += read(_urandomfd, n - len(bytes))<br>\nOSError: [Errno 9] Bad file descriptor<br>\n<br>\n<br>\nShould I preserve file descriptors? I don\'t see another way to do it.\n\nThanks for any hint, <br>\n\nFrancis', 'title': u'Random file descriptor'}, {'comment': u"This is python bug 1177468, it's apparently fixed in python cvs since 4th July 2005 but may not have made it to your distribution yet. Without the fixed os.py, your only option is to leave the file descriptors open.", 'title': u' '}, {'comment': u"Actually you do need to close 0,1,2 otherwise you won't get any stdout/stderr redirects from the os.open calls.", 'title': u' '}, {'comment': u"<pre>\nHello,\n\nI've been testing this with the following code:\n\n#!/usr/bin/python\nimport pyDaemon\nimport time\n\ndef logit():\n\tfp = open('test.log','a')\n\tfp.write('Hello\\n')\n\tfp.close()\n\npyDaemon.createDaemon()\nwhile 1:\n time.sleep(5)\n logit()\n\nThis is basically what one of the other folks earlier was doing.<br>I have it saves in a file called 'test.py'. I'm new to Python, and have<br>never done anything with daemons, so I wanted to see how it works.\n<br>\nIf I start this using 'python test.py', it seem to start, and I can <br>see it running as a process, but nothing gets written to the log<br>file. The file exists and I gave it permissions of 777.<br>\n\nIf I comment out the line that executes the createDaemon() function,<br>it works fine, aside from not being daemonized (naturally). Any ideas?\n\nThanks!\n\nBrandon\n</pre>", 'title': u"Can't quite get this to work"}, {'comment': u"The daemon code sets the current working dir of the process to /.\nYou're file is either here or you don't have permission to write here.\nIf you're doing serious logging check out syslog. There are some recipes on this site.", 'title': u'Check /'}], 'desc': u'The Python way to detach a process from the controlling terminal and run it in the\nbackground as a daemon.'}, {'comments': [{'comment': u"Parsing the module's docstring for the command line options is a brilliant idea. It feels really pythonic; most other languages, for example, treat indentation as purely documentary, and require you to repeat your code block delimitation using delimitation characters and using indentation, whereas Python treats the indentation as definitive, and doesn't require you to repeat yourself. Similarly, this recipe treats the docstring's definition of the supported command line options as definitive, and doesn't require you to repeat yourself.\n", 'title': u'Beautiful'}, {'comment': u"You could probably perform more complicated parsing, and introduce some additional syntax checking at the same time, by adapting parts of the CMDSyntax module's Syntax class:\n<br><br>\nhttp://www.boddie.org.uk/david/Projects/Python/CMDSyntax/", 'title': u'See also'}, {'comment': u'Just a reminder that the __doc__ string will be empty when Python is invoked with -OO. Otherwise, an excellent recipe.', 'title': u'__doc__ disappears with -OO'}, {'comment': u'With the code below, I\'m very much enjoying this recipe. I\'ve tweaked it slightly to allow default values, and thought that might be a useful change...\n\n<pre>\n"""\\\n:Author: M. Simionato\n:Date: April 2004\n:Title: A much simplified interface to optparse.\n:modified: Modified by Henry Crutcher to support default values\n\nYou should use optionparse in your scripts as follows.\nFirst, write a module level docstring containing something like this\n(this is just an example):\n\n\'\'\'usage: %prog files [options]\n -d, --delete: delete all files\n -e, --erase = ERASE: erase the given file\n -F, --fill_pattern = 0xFF: the fill pattern used to erase the given file\'\'\'\n \nThen write a main program of this kind:\n\n# sketch of a script to delete files\nif __name__==\'__main__\':\n import optionparse\n option,args=optionparse.parse(__doc__)\n if not args and not option: optionparse.exit()\n elif option.delete: print "Delete all files"\n elif option.erase: \n print "Delete the given file with %s" % option.fill_pattern\n\n\nNotice that ``optionparse`` parses the docstring by looking at the\ncharacters ",", ":", "=", "\\\\n", so be careful in using them. If\nthe docstring is not correctly formatted you will get a SyntaxError\nor worse, the script will not work as expected.\n"""\n\nimport optparse, re, sys\n\nUSAGE = re.compile(r\'(?s)\\s*usage: (.*?)(\\n[ \\t]*\\n|$)\')\n\ndef nonzero(self): # will become the nonzero method of optparse.Values \n "True if options were given"\n for v in self.__dict__.itervalues():\n if v is not None: return True\n return False\n\noptparse.Values.__nonzero__ = nonzero # dynamically fix optparse.Values\n\nclass ParsingError(Exception): pass\n\noptionstring=""\n\ndef exit(msg=""):\n raise SystemExit(msg or optionstring.replace("%prog",sys.argv[0]))\n\ndef parse(docstring, arglist=None):\n global optionstring\n optionstring = docstring\n match = USAGE.search(optionstring)\n if not match: raise ParsingError("Cannot find the option string")\n optlines = match.group(1).splitlines()\n try:\n p = optparse.OptionParser(optlines[0])\n for line in optlines[1:]:\n opt, help=line.split(\':\')[:2]\n short,long=opt.split(\',\')[:2]\n if \'=\' in opt:\n # unless the value on the other side of = is the same \n # (modulo case) it is used as the default\n \n action=\'store\'\n long, default=long.split(\'=\')[:2]\n if default.lower()==long:\n default=None\n else:\n action=\'store_true\'\n p.add_option(short.strip(),long.strip(),\n action = action, help = help.strip(), default=default)\n except (IndexError,ValueError):\n raise ParsingError("Cannot parse the option string correctly")\n return p.parse_args(arglist)\n\n</pre>', 'title': u'Can easily be enhanced to take default values'}], 'desc': u'The module optparse was a great addition to Python 2.3, since it is much more \npowerful and easier to use than getopt. Using optparse, writing command-line\ntools is a breeze. However, the power of optparse comes together with a certain\nverbosity. This recipe allows to use optparse with a minimum of boilerplate, \ntrading flexibility for easy of use. Still, it covers 95% of my common needs, \nso I think it may be useful to others.\n'}, {'comments': [{'comment': u'I tried running the py file it is throwing the following error (It is Python 2.3.3 on Win 2000)--\n\n\n>>> \nTraceback (most recent call last):\n File "C:\\Documents and Settings\\e176636\\Desktop\\docs_hem\\New Folder\\convert.py", line 1, in ?\n import fnmatch, os, pythoncom, sys, win32com.client\nImportError: No module named pythoncom\n>>> \n\n\n', 'title': u'ImportError: No module named pythoncom'}, {'comment': u"Sounds like you don't have the Python for Windows extensions. Get these from http://starship.python.net/crew/mhammond/", 'title': u"You don't have Python for Windows"}, {'comment': u'Traceback (most recent call last):\n File "C:\\Python23\\text.py", line 7, in -toplevel-\n wordapp.Documents.Open(doc)\n File "C:\\Python23\\lib\\site-packages\\win32com\\gen_py\\00020905-0000-0000-C000-000000000046x0x8x2\\Documents.py", line 79, in Open\n ret = self._oleobj_.InvokeTypes(18, LCID, 1, (13, 0), ((16396, 1), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17)),FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog)\ncom_error: (-2147352567, \'Exception occurred.\', (0, \'Microsoft Word\', \'This file could not be found.\\nTry one or more of the following:\\n* Check the spelling of the name of the document.\\n* Try a different file name.\\r (Doca.doc)\', \'C:\\\\Program Files\\\\Microsoft Office\\\\Office10\\\\1033\\\\wdmain10.chm\', 24654, -2146823114), None)\n<br>\n<br>\nI get this error every time i run the code. Please help me.', 'title': u'Error when using this code.'}, {'comment': u'Traceback (most recent call last):\n File "C:\\Python23\\text.py", line 7, in -toplevel-\n wordapp.Documents.Open(doc)\n File "C:\\Python23\\lib\\site-packages\\win32com\\gen_py\\00020905-0000-0000-C000-000000000046x0x8x2\\Documents.py", line 79, in Open\n ret = self._oleobj_.InvokeTypes(18, LCID, 1, (13, 0), ((16396, 1), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17)),FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog)\ncom_error: (-2147352567, \'Exception occurred.\', (0, \'Microsoft Word\', \'This file could not be found.\\nTry one or more of the following:\\n* Check the spelling of the name of the document.\\n* Try a different file name.\\r (Doca.doc)\', \'C:\\\\Program Files\\\\Microsoft Office\\\\Office10\\\\1033\\\\wdmain10.chm\', 24654, -2146823114), None)\n<br>\n<br>\nI get this error every time i run the code. Please help me.', 'title': u'Error when using this code.'}, {'comment': u'Traceback (most recent call last):\n File "C:\\Python23\\text.py", line 7, in -toplevel-\n wordapp.Documents.Open(doc)\n File "C:\\Python23\\lib\\site-packages\\win32com\\gen_py\\00020905-0000-0000-C000-000000000046x0x8x2\\Documents.py", line 79, in Open\n ret = self._oleobj_.InvokeTypes(18, LCID, 1, (13, 0), ((16396, 1), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17)),FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog)\ncom_error: (-2147352567, \'Exception occurred.\', (0, \'Microsoft Word\', \'This file could not be found.\\nTry one or more of the following:\\n* Check the spelling of the name of the document.\\n* Try a different file name.\\r (Doca.doc)\', \'C:\\\\Program Files\\\\Microsoft Office\\\\Office10\\\\1033\\\\wdmain10.chm\', 24654, -2146823114), None)\n<br>\n<br>\nI get this error every time i run the code. Please help me.', 'title': u'Error when using this code.'}, {'comment': u'Traceback (most recent call last):\n File "C:\\Python23\\text.py", line 7, in -toplevel-\n wordapp.Documents.Open(doc)\n File "C:\\Python23\\lib\\site-packages\\win32com\\gen_py\\00020905-0000-0000-C000-000000000046x0x8x2\\Documents.py", line 79, in Open\n ret = self._oleobj_.InvokeTypes(18, LCID, 1, (13, 0), ((16396, 1), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17), (16396, 17)),FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog)\ncom_error: (-2147352567, \'Exception occurred.\', (0, \'Microsoft Word\', \'This file could not be found.\\nTry one or more of the following:\\n* Check the spelling of the name of the document.\\n* Try a different file name.\\r (Doca.doc)\', \'C:\\\\Program Files\\\\Microsoft Office\\\\Office10\\\\1033\\\\wdmain10.chm\', 24654, -2146823114), None)', 'title': u'ERROR!!!!'}, {'comment': u"It seems MS Word tell's you something about the error:<br><pre>\n'Microsoft Word', 'This file could not be found.\\nTry one or more of the following:\\n* Check the spelling of the name of the document.\\n* Try a different file name.\\r (Doca.doc)'</pre><br>\nSo you might try to see if the file 'Doca.doc' exists, and it's not a directory. It could also be a locking problem, if you have word or any other program opening this document, it might well be word can't open it. This also sometimes happens when you have an explorer opened at the same time, with a focus on this file. [i guess explorer reads some details, using file locking]", 'title': u'Error'}, {'comment': u'Were you, perhaps, passing in "." as the required root directory? COM doesn\'t seem to like file names in the form ".\\mydoc.doc", even though from the command line you can open a document like this.<br>\n<br>\nI\'ve added a call to os.path.abspath to sort this out. I\'ve also put in a try/finally block to make sure that Word gets closed down properly.', 'title': u'Fixed!'}, {'comment': u'I got some troubles using this script. I do not want you to solve this (some RPC Server error) just would like to ask generally. Where can I found documentation to all these function in win32. I think it is the matter of API windows, so probably somewhere on MS. Could you help? Some pdf of donwnloadable html or chm is appreciated.\nThank you\nPavel', 'title': u'win32com'}, {'comment': u'Replying to myself: to make full power I have to change:\n\n<pre>\n<br> wordapp = win32com.client.Dispatch("Word.Application")\n<br> FileFormat=win32com.client.constants.wdFormatText\n<br> wordapp.ActiveDocument.Close()\n</pre>\n\nOtherwise there were too much errors on different kinds of docs ...\nPavel', 'title': u'SOLVED:'}, {'comment': u"Using pythonwin's COM Makepy utility makes the change unecessary. I believe when working with COM objects this is one of the first steps, but may not be absolutely necessary. That is how it gets into the gencache.\n\nThis FileFormat=win32com.client.constants.wdFormatText and the original above I believe are both valid. I also beleive this wordapp.ActiveDocument.Close() is more appropriate than closing the active window, however I think the same effect is achieved.", 'title': u'Replying to: to make full power I have to change:'}, {'comment': u'Using COM Makepy utility from PythonWin would fail right away. Not sure why, but you can use it as a test before trying the code.<br>\n<br>\nOnce I installed ActiveState 2.3.5 the below worked as advertised.\nPythonWin<br>\nTools->COM Makepy utility<br>\nselect Microsoft Word 11.0 Object Library (8.3)<br>\n\n>>> Generating to E:\n\\Python23\\lib\\site-packages\\win32com\\gen_py\\00020905-0000-0000-C000-000000000046x0x8x3.py\n>>> import fnmatch, os, pythoncom, sys, win32com.client<br>\n>>> wordapp = win32com.client.gencache.EnsureDispatch("Word.Application")<br>\n>>> wordapp.Documents.Open("c:\\\\a.doc")<br>\n\n>>> wordapp.ActiveDocument.SaveAs("c:\\\\a.txt", \nFileFormat=win32com.client.constants.wdFormatTextLineBreaks)<br>\n>>> wordapp.ActiveWindow.Close()<br>\n>>> wordapp.Quit()<br>\n>>><br>', 'title': u'ActiveState Python 2.4.1 and Word 2003, pywin32 build 204 did not work for me'}, {'comment': u"<p>What about this small solution?</p>\n<pre>\nimport win32com.client<br>\napp = win32com.client.Dispatch('Word.Application')\ndoc = app.Documents.Open('c:\\\\files\\\\mydocument.doc')\nprint doc.Content.Text\napp.Quit()\n</pre>\n<p>More examples to Office and win32com: http://www.win32com.de", 'title': u'A smaller solution'}, {'comment': u"Nice script -- worked great the first time.\nOnly bug was an error message I got once when executing wordapp.Quit(). But it hasn't happened again.", 'title': u'Nice'}], 'desc': u"Here's a script to save all Word documents in and below a given directory to text. "}, {'comments': [], 'desc': u'This function will split and (optionally) validate UK postcodes.'}, {'comments': [], 'desc': u'Prints the current line number, function name and some text. Useful for debugging.'}, {'comments': [{'comment': u'This version might be faster, it is shorter to write\n\n<pre>\ndef getReverseConnectivity(connectivity):\n """getReverseConnectivity(connectivity) -->\n resort connectivity dict with nodes as keys"""\n reverseConnectivity = {}\n for el, conn in connectivity.items():\n for node in conn:\n reverseConnectivity.setdefault(node, []).append(el)\n return reverseConnectivity\n\n\nsc = {70: [156, 159, 158, 155], 69: [155, 158, 157, 154], 68: [153, 156, 155, 152], 67: [152, 155, 154, 151]}\nprint getReverseConnectivity(sc)\n</pre>\n\nRegards\nBerthold', 'title': u'shorter (maybe faster)'}, {'comment': u'In addition, you can factor out the lookup for the setdefault method.\n\n<pre>\ndef getReverseConnectivity2(connectivity):\n """getReverseConnectivity(connectivity) -->\n resort connectivity dict with nodes as keys"""\n reverseConnectivity = {}\n setdef = reverseConnectivity.setdefault\n for el, conn in connectivity.items():\n for node in conn:\n setdef(node, []).append(el)\n return reverseConnectivity\n</pre>', 'title': u'Micro-optimization'}], 'desc': u'This takes a dictionary and reverses it so the that the integers in the value lists become the keys and the original keys are appended to value lists. \n\n'}, {'comments': [{'comment': u"Still a few bugs to sort out in this.\nI'll do some amendments (e.g. handling quotes in 'cd' commands).", 'title': u'Still Buggy'}, {'comment': u"'cd' should work now.\nHmm... IPython would be a better console if I could get it working - but this is ok - slight improvement over the windoze console.", 'title': u' '}, {'comment': u'I\'ve always wanted something like this but never got around to making it. Thanks! I only have 2 suggestions:\n<br><br>\n1.) For those with cygwin installed it doesnt make sense that "ls" runs "dir", it was easy enough for me to change the code, but it\'s up to you if you want to keep it that way\n<br><br>\n2.) one of the most important features (to me at least) in a command line interface is filename completion, something like the functionality from http://www.morearty.com/filec/ would be excellent\n<br><br>\nthanks again for such a cool program, i\'m sure i\'ll get some use out of it', 'title': u'pretty good...'}, {'comment': u"I've fixed a couple of minor problems with the variables (coping with quotes and I was adding an extra space).\n\nI'll look at filename completion - although I might need to move to a Tkinter window rather than a standard console window to achieve that.\n", 'title': u'Changed Again'}], 'desc': u"A simple console for windows.\nAny commands that don't make sense as python commands are sent to the system. Fully expandable !!\nYou can reference variables in system commands using %: \ne.g. echo %fish \nechoes the contents of the variable fish........."}, {'comments': [{'comment': u'You may be interested in this recipe: \nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/284528', 'title': u'I have an alternative way of doing that'}, {'comment': u"http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195\n<br>\n<br>Syntax is:\n<pre> self.super(*p, **kw)\n self.super.attribute</pre>\n\ne.g.\n<pre> def __init__(self):\n self.super()\n print self.super.__init__</pre>\n\nThere's a version with higher performance, etc at the web site linked from that recipe.", 'title': u'And another method ...'}], 'desc': u"Simple recipe for making it easier to call superclass method code. Instead of 'super(cls,self).methodName()' you may just use 'cls.doDefault()' for code that is easier on the eyes."}, {'comments': [], 'desc': u'Collects statistics on different algorithms for grouping thousands of tests for execution on a compute farm where you are limited to much less job slots, (tens). '}, {'comments': [{'comment': u'The following version works even in __init__ methods which have other logic and temporary variables:\n<pre>\ndef assignAttr(obj, dctLocals):\n codeObject = obj.__class__.__init__.im_func.func_code\n tupNames = codeObject.co_varnames[1:codeObject.co_argcount]\n for strName in tupNames:\n obj.__dict__[strName] = dctLocals[strName]\n\nclass After: \n def __init__(self, foo, bar, baz, boom=1, bang=2):\n assignAttr(self, locals())\n</pre>', 'title': u'A more robust approach?'}, {'comment': u'import inspect<br>\ndef init_attributes():<br>\n......d=inspect.currentframe().f_back.f_locals<br>\n......obj = d.pop("self")<br>\n......for n, v in d.iteritems():<br>\n............setattr(obj, n, v)<br>\n<br>\nclass After:<br>\n......def __init__(self, foo, bar, baz, boom=4, bang=5):<br>\n...........init_attributes()<br>\n', 'title': u'a simplification (no parameter needed)'}], 'desc': u"Did you ever have to write an initializer whose body consisted of little more than a suite of self.attr = attr style assignments? Here's a utility function that factors out this task."}, {'comments': [{'comment': u'I am using python 2.3.2, when I run the script I get an error about failing to import readline. Is this a third party lib and is there a windows version of it?<br><br>\n\nDave', 'title': u'Readline'}, {'comment': u'Try http://newcenturycomputers.net/projects/readline.html', 'title': u'readline.py for Windows'}, {'comment': u"If you don't have readline you can make the following 2 changes to console.py:<br>\n<br>\nDelete the line:\n<pre>\nimport readline\n</pre>After the line:<pre>\n cmd.Cmd.__init__(self)\n</pre>Add this line:<pre>\n self.completekey = None\n</pre>", 'title': u'Console without readline'}], 'desc': u'This recipe shows how to use the Cmd object to create a simple OS \nneutral console. It shows how to use many of the hooks provided\nby the Cmd object and also documents some errors and omissions\nin the official cmd documentation,'}, {'comments': [{'comment': u"I modified Matteo's original script so that isorted can take any iterable as an argument.\n<pre>\nfrom itertools import ifilter, count\n\ntry:\n from itertools import tee\nexcept ImportError, err:\n def tee(iterable):\n def gen(next, data={}, cnt=[0]):\n for i in count():\n if i == cnt[0]:\n item = data[i] = next()\n cnt[0] += 1\n else:\n item = data.pop(i)\n yield item\n it = iter(iterable)\n return (gen(it.next), gen(it.next))\n\ndef isorted(iterable):\n iterable = iter(iterable)\n try:\n pivot = iterable.next()\n except:\n return\n\n a, b = tee(iterable)\n for x in isorted(ifilter(lambda item:item<pivot, a)):\n yield x\n yield pivot\n for x in isorted(ifilter(lambda item:item>=pivot, b)):\n yield x\n</pre>\nNote : my generator-based quicksort does not construct a list.<br>\nI used itertools.tee, which will appear in Python 2.4.\n", 'title': u'generator-based quicksort'}, {'comment': u'This version guarantees stability by selecting the first element as the pivot (this results in poor performance if the list is already sorted, but is no worse than the original version). Also, unlike the original version, it never modifies the list that is passed into it.<br>\n\n<pre>\nMIN_SIZE = 128\n\ndef isorted(lst):\n if len(lst) <= MIN_SIZE:\n lst = lst[:]\n lst.sort()\n for x in lst:\n yield x\n else:\n pivot = lst[0]\n lst = lst[1:]\n lt = [x for x in lst if x < pivot]\n for x in isorted(lt):\n yield x\n yield pivot\n ge = [x for x in lst if x >= pivot]\n for x in isorted(ge):\n yield x\n</pre>', 'title': u'stable version'}, {'comment': u'George and Daniel, thanks for your comments. I did some test, and saw that the problem in all these versions is performance: python\'s builtin list.sort is so good that there are really few cases in which these solutions are better. The real performance bonus would be implementing this in C.<br>\nIf someone who has "the right to speak" :-) thinks this is worth the itertools package, I\'d be happy to study how to implement it.', 'title': u' '}, {'comment': u"In terms of use cases, lazy sorting is valuable only when you don't plan on consuming all of the output (otherwise, you might as well use a regular sort). Choosing the n smallest items out of a list would be a good application.\n<br>\nKeeping this in mind, a heap is a natural choice of underlying data structures:\n\n<pre>\nimport heapq\n\ndef isorted(iterable):\n lst = list(iterable)\n heapq.heapify(lst)\n pop = heapq.heappop\n while lst:\n yield pop(lst)\n</pre>\n\nisorted() is not an especially good candidate for itertools because it immediately manifests the whole input into memory and because most its use cases tend to be dominated by list.sort() and heapq.", 'title': u'Simplification and speedup with heapq'}, {'comment': u"Raymond, you're absolutely right. Although, I argue that a well-written lazy sort could be almost as efficient as list.sort. Not that it would matter, since heapsort is just fine. I'm adopting your modification for version 2. :-)", 'title': u' '}, {'comment': u'The timsort implementation used by sorted and sort is great. But laziness can still win out. In my experience, lazy sorting is significantly more efficient when a percentage of the query is being used as seen in top N type queries. Such queries very popular for user interfaces! Consequently I like the fact that 2.4 added this functionality in heapq.nlargest and heapq.nsmallest.<br>\nThere should be no surprise that lazy sorting can be more efficient, we are comparing O(n + k logn) = O(n) -- if k is a constant as it is with top 50 -- vs O(n logn).\n<br>\nOf course that percentage will vary with the constant overhead you will see in your code. As usual, try it both ways if the sorting is in a key piece of code, as it was in mine.', 'title': u"For 2.4 and later, consider using heapq's nsmallest or nlargest functions"}], 'desc': u'This generator will sort only the requested part of a list. Useful for getting just the first few elements of a list and avoiding the overhead of sorting the whole thing.'}, {'comments': [{'comment': u'After you create a "pedigree" table, you\'ll find lots of things can be expressed as joins:\n<pre>\nCREATE TABLE pedigree(\n node Node_Type,\n depth INTEGER NOT NULL,\n ancestor Node_Type,\n PRIMARY KEY (node, depth),\n UNIQUE (ancestor, node))\n</pre>\nI use entries for 0 (each node is its own 0-depth ancestor).\nThen queries like "all children of", or "all children including" are\nquite easy, and you can "ORDER BY depth" or "ORDER BY -depth" to \nget root-first or depth-first orders. Primary and unique can be \nswapped depending on what kinds of queries you do most often.', 'title': u'Another form for tree store'}], 'desc': u'Sometimes it can be hard to work out a way of efficiently representing a tree in the database. Combining modified preorder tree traversal with a parent child model allows most common queries to be represented in a single sql query. This example uses MySQLdb, but can easy be changed to use any DBI compatable module.'}, {'comments': [{'comment': u"That's a lot of work to avoid eval(s).", 'title': u'Whew!'}, {'comment': u"I can't stand eval.<br>\nPsyco doesn't handle eval very well.<br>\n<br>\nEval only works if the elements are all correctly quoted - as my main use is for reading in list values for *simple* config files I didn't want to enforce quoting.<br>\n<br>\nEval will also attempt to evaluate expressions in the list - as well as other possible bizarre things I didn't want to have to think about. (Including security risks I guess). I wanted to garuantee a straightforward string version of the text - but with the list elements properly handled... Which this does quite nicely.<br>\n<br>\nAnd it was a nice little parser to write - the quote, unquote and makelist functions I needed anyway.......<br>", 'title': u'Down With Eval'}, {'comment': u'Having a little parser to replace eval() sure helps with the security risks. I was surprised at how much code it took though.', 'title': u'Alternative to Eval'}, {'comment': u"<pre>Hmmm... the actual list parse function is about 70 lines - and could be reduced by putting some conditionals on single lines.\n\nI guess if I was a better coder it would be even smaller............\nHaving said that - it works fine, and does a nice job - it's useful to be able to have config files with keywords having a list of values.</pre>", 'title': u"It's only little.............."}], 'desc': u'Turn a string representation of a list back into a list. Including nested lists - list elements, can themselves be lists. Includes functions for quoting and unquoting list elements....'}, {'comments': [], 'desc': u'This is a simple Python script to watch a post.'}, {'comments': [{'comment': u'...because you\'ve obliterated the whole point of dictionaries by using a linear search in the "caseless find" operation. You might as well have used a list of (key,value) pairs, for all the value the dictionary is giving you.\n\nIf I needed a case-insensitive dictionary, but needed to preserve key case, I\'d simply do something like:\n\n<pre>\naDictionary[key.lower()] = key,value\n</pre>\n\nand then use aDictionary.values() (or itervalues) wherever I needed the dictionary\'s items. While this approach isn\'t a drop-in replacement for a dictionary, it\'s trivial to implement if you know from the beginning you need case insensitivity. And if you really need to abstract the data structure, then you can always subclass dict and still use the structure above for implementation.', 'title': u'This recipe is going to be incredibly slow...'}, {'comment': u"I got rid of the 'linear lookup' and replaced it with a dictionary of keys. This means it is now only twice as slow as an ordinary dictionary ! But *much* quicker than the previous version.<br>\n<br>\nFor every access it is basically two lookups, one to look up the 'real key' and one to do the access. I could implement your method in a 'drop-in' way if I explicitly defined all the iter methods (every method that did access as well - with my method I (basically) only have to implement methods that set items).<br>\n<br>\nFor what I need it for speed isn't a big issue anyway....", 'title': u'Now only twice as slow as a dictionary'}, {'comment': u'Right, that\'s how the other case-insensitive dictionary recipe works:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66315\n<br><br>\nOther than that, the only functional difference is that the recipe here only allows strings for keys. I.E., you can have mydict["abc"] but not mydict[3].\n<br><br>\nSo right now my preference is for the other recipe, although one might update it to directly subclass dict like this recipe (although that means you cannot use it with python versions before 2.2).', 'title': u'right, see the other case-insensitive dictionary recipe instead'}, {'comment': u'<pre>\n"""the only functional difference is that the recipe here only allows strings for keys"""\n\nIn actual fact I\'ve defined lot\'s of methods in my version that are simply missing in the alternative. Just subclassing dict for the alernative won\'t help; because of the details of the implementation - you\'ll need to define those methods to use the properties of dict. Mine is a drop in replacement for dictionaries. \n\nFor what I\'m using it for it\'s *far* more useful to have an object that behaves like a dictionary than to have the slight speed improvement.\n\n*However* I\'ve been working on iterators and think I understand enough to implement a dictionary with my own iterator. I\'ll use that first to do an ordered dictionary, then I\'ll reimplment the caseless dictionary. I can do a version that uses the faster method but is still a drop in replacement. As I will have to redefine *almost* all the dictionary methods I might as well do all of them and then I odn\'t *have* to subclass dict... although in practise Python 2.2 is pretty ubiquitous - I\'m using a free-host with Python on (Xennos) and thatr has Python 2.2 (and subclassing dict is useful for the isinstance test...)</pre>', 'title': u'Not the only difference....'}, {'comment': u"As I've now done a dictionary replacement with a custom iterator, http://www.voidspace.org.uk/atlantibots/pythonutils.html#odict , I could implement the suggested alternative.<br>\n<br>\nIn order to implement the suggested technique you need to overload all the methods that fetch values as well as set them - which is what I've done in my 'ordered dictionary'.<br>\n<br>\n*However* - that would make doing the keys method very expensive, you would need to look up every entry and fetch the real key.<br>\n<br>\nWhich is faster a dictionary lookup or an index operation ? I thought there wasn't much in it ! In which case my recipe here, which does two lookups for each access will actually be about *as* fast as a method that does one lookup *and* an index for each lookup.<br>\n<br>\nI think I'll leave it as it is !\n\n ", 'title': u'Alternative Implementation'}], 'desc': u'A dictionary with case insensitive keys - that retains the case of the keyword.\nOnly permits strings as keys.\nAn alternative implementation of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66315 \n'}, {'comments': [{'comment': u"<pre>\nAnother simple approach I've used is to create a config file that contains a dictionary:\n{\n'username': 'jsmith',\n#can include lists and dictionaries as substructure\n'hosts': ['host1.com', 'host2.org'],\n\n#can include comments and whitespace lines\n'subdict': {'key1': 'value1', 'key2': 'value2'}\n}\n\nThis approach is not as powerful and flexible as the above but it'll do in a pinch. To create your dictionary simple add the line:\nconfig = eval(open('configfile').read())\n\nThen iterating through your hosts is as simple as:\nfor host in config['hosts']:\n pass\n\nThanks for showing the (better) import approach.\n\n-Todd\n</pre>", 'title': u'the eval() approach'}, {'comment': u"if you are taking the basepath as in: config_file = os.path.basename(sys.argv[1])\nand then importing conif_file you will have problems if the config file resides in another dir. what you can do is:\n<br>\n\n<pre>\nconfig_path, config_file = os.path.split(sys.argv[1])\nif config_path != '':\n sys.path.append(config_path)\n</pre>\n<br>\nbut i don't really know if this is going to work, maybe it's better to just print an error message.", 'title': u'A litle problem'}], 'desc': u"Here's a snippet using import for reading Python-based configuration files that are specified at runtime."}, {'comments': [{'comment': u"I can rememer two places in my code where naming the class explicitly was helpful.\n\n1. In a class i needed to get not the super method but the grand-super method. I can't remember exactly why I needed it, but looking back, it must have been a case of bad design.\n\n2. The following is not bad design, but a real need that came up:\n\n<pre>\nclass SuperGetter(object):\n def __init__(self, cls, attrib):\n super(Super, self).__init__(cls)\n self.__cls__ = cls\n self.__attrib__ = attrib\n\n def get(self, inst):\n return getattr(super(cls, inst), self.attrib)\n</pre>\n\nAnd variations thereof.\n", 'title': u'What if you need to spell out the class?'}, {'comment': u"I have two use cases, where it actually was useful to be able to name the super class explicitly. One was, when I needed to get the grand-super implementation, that is\n\n<pre>\nclass A(object):\n def method(self, args):\n ...\n\nclass B(A):\n def method(self, args):\n super(B, self).method(args)\n ...\n\nclass C(B)\n\n def method(self, args):\n #We want the grand-super (B), not super (C).\n super(B, self).method(args)\n ...\n\n</pre>\n\nI can't remember the exact circumstances where I needed that, so quite possibly this was just a case of bad design. The following, I don't thing it is:\n\n<pre>\nclass SuperGetter(object):\n def __init__(self, cls, attrib):\n self.cls = cls\n self.attrib = attrib\n\n def __call__(self, inst, args):\n func = getattr(super(cls, inst), attrib)\n return func(args)\n</pre>\n\nAnd variations, thereof.", 'title': u'What if you need to spell out the class exactly?'}, {'comment': u"Maybe I was unclear. I am not advocating replacing the current\ntwo-argument syntax of 'super'. We need it. I am just advocating\nfor some syntactic sugar in the common cases where the first\nargument is the current class. No more than that.", 'title': u' '}], 'desc': u'Makes cooperative calls looks nicer: super.method instead of super(cls,self).method .'}, {'comments': [{'comment': u'Another way of achieving the same effect is to use a case insensitive string (much less code :-) and a normal list or dict. See recipe: <pre>http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/194371</pre>', 'title': u'A more flexible way of doing this'}], 'desc': u'A list that will only allow strings as members. Methods like count, __contains__ ( a in list ), remove, index etc are case insensitive.\nSee also the caselessDict - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/283455 '}, {'comments': [], 'desc': u"Bandwidth testing is easy with Python's built-in web access, HTML parsing, and threading modules.\n\nWhen Fedora Core 2 was released, I wanted to find which download mirror would be fastest when I tried downloading the CD images. It only took about an hour to whip up this mirror bandwidth tester.\n\nThis script demonstrates web download, HTML parsing, and some interesting threading issues."}, {'comments': [{'comment': u'Unfortunately, dict.copy makes a shallow copy. So this Transaction class will fail in all kinds of cases. Here is an example:<pre>\nclass TryOut(Transaction):\n def __init__(self):\n self.bnd1 = (1,2,3)\n self.bnd2=[self.bnd1]\n Transaction.__init__(self)\n self._commit()\n\nt = TryOut()\nt.bnd2=None\nt._rollback()\nprint t.bnd1, t.bnd2\nt.bnd1=None\nt.bnd2=None\nt._rollback()\nprint t.bnd1, t.bnd2</pre>', 'title': u'shallow copy'}, {'comment': u"I clicked on 'Add' too early. I wanted to explain more, so here I go again.\n<br><br>\nUnfortunately, dict.copy makes a shallow copy. So this Transaction class will fail in all kinds of cases. Here is an example:<pre>\nclass TryOut(Transaction):\n def __init__(self):\n self.bnd1 = (1,2,3)\n self.bnd2=[self.bnd1]\n Transaction.__init__(self)\n self._commit()\n\nt = TryOut()\nt.bnd2=None\nt._rollback() # This works\nprint t.bnd1, t.bnd2\nt.bnd1=None\nt.bnd2=None\nt._rollback() # This doesn't work\nprint t.bnd1, t.bnd2</pre>\nThe output from that:<pre>\n(1, 2, 3) [(1, 2, 3)]\nNone None</pre>", 'title': u'shallow copy'}, {'comment': u"I forgot to commit the transactions, that's why it was not working. I'm still trying to figure out if the shallow dict.copy can somehow cause a problem, but until then, I'm changing my opinion. Good recipe!", 'title': u'my bad'}, {'comment': u"Simon, I was wrong earlier and I strongly apologize. This recipe looked great to me the first time I looked at it, it's so simple and yet so powerful. On the other hand, instinctively I felt that there must be something wrong here with the shallow copy and that is why I've kept trying to find a hole in your recipe.\n\nI think I've got it now. Here is an example:<pre>\nclass TryOut(Transaction):\n def __init__(self):\n self.myList=[1,2]\n Transaction.__init__(self)\n\nt=TryOut()\nt._commit()\nprint t.myList,\nt.myList.append(3)\nt._rollback()\nprint t.myList</pre>\nAnd the output is:<pre>\n[1, 2] [1, 2, 3]</pre>\nBut now, here is a solution for the problem. Import the copy module and do a copy.deepcopy(self.__dict__) instead of the self.__dict__.copy(). I owed you that after the mistakes I've made.", 'title': u'back with a different example'}, {'comment': u"Thanks for the criticism Dan, I'll make those changes now.\n", 'title': u'Thanks for the feedback'}, {'comment': u"It seems I have lost control of this recipe...\n<br>\n'No recipes found in the Cookbook that belong to you. Please select a cookbook to add a recipe.'\n<br>\n...and cannot make any changes. ", 'title': u'DOH!'}], 'desc': u'This simple class allows sub-classes to commit changes to an instance to a history, and rollback to previous states.'}, {'comments': [{'comment': u'Functions are easiest to understand when they behave simply, not when they try to be clever.\n<br>Code like:\n<pre>\n x, y, z = getpoint()\n print \'x=%s, y=%s, z=%s\' % (x,y,z)\n ...\n</pre>\ncan be rewritten to be:\n<pre>\n x, y, z = point = getpoint()\n print \'x=%s, y=%s, z=%s\' % point\n ...\n</pre>\nNeither "x, y, z = point = cleverfunc()" nor "point = x, y, z = cleverfunc()" work.', 'title': u"Cute, but don't do this."}, {'comment': u"I tweaked your code a bit so it would work in all use cases, hopefully.\n\n<pre>\nimport sys\nimport dis\n\n\ndef expecting():\n f = sys._getframe().f_back.f_back\n i = f.f_lasti + 3\n bytecode = f.f_code.co_code\n instruction = ord(bytecode[i])\n while True:\n if instruction == dis.opmap['DUP_TOP']:\n if ord(bytecode[i + 1]) == dis.opmap['UNPACK_SEQUENCE']:\n return ord(bytecode[i + 2])\n i += 4\n instruction = ord(bytecode[i])\n continue\n if instruction == dis.opmap['STORE_NAME']:\n return 1\n if instruction == dis.opmap['UNPACK_SEQUENCE']:\n return ord(bytecode[i + 1])\n return 0\n\n\ndef test():\n def f():\n r = expecting()\n if r == 0:\n return None\n if r == 1:\n return 0\n return range(r)\n\n f()\n a = f()\n a, b = f()\n a, b = c = f()\n a, b = c = d = f()\n a = b = f()\n a = b, c = f()\n a = b = c, d = f()\n a = b, c = d = f()\n a, b = c, d = f()\n\ntest()\n</pre>", 'title': u'Evil!'}], 'desc': u'Sometimes you might want to make a function behave differently if the caller is expecting one or several values (e.g. x=func() versus x,y=func()). The expecting() function lets the function implementer find out how many values the caller wants as a function result.'}, {'comments': [{'comment': u'http://www.crockford.com/JSON/index.html\n\n"JavaScript Object Notation (JSON) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. This feature can also be found in Python."\n\n', 'title': u'check out json'}], 'desc': u'withdrawn'}, {'comments': [{'comment': u"I wrote something like this a while back, and it does numbers up to 100 digits long! :D\n\n<pre>http://epitaph.darkillustrated.org/bignums.php</pre>\n\nIt's in PHP, but it's nice and readable.", 'title': u'Fancier Algorithm!'}], 'desc': u'Converts numbers in to their english equivelents. It can spell out any integer between -999999999999999 and 999999999999999, inclusive.'}, {'comments': [{'comment': u'updated class at\n\nhttp://www.asiatica.org/~ludo/archive/2004/05/Python_smime_verify.html\n\n(aspn keeps crashing when I modify the recipe)', 'title': u'updated'}, {'comment': u'The updated version is here too.', 'title': u'updated'}], 'desc': u"A recipe to verify signed SMIME messages with M2Crypto if you don't have the signer's certificate, which is what usually happens when you have to verify Internet email."}, {'comments': [], 'desc': u'The prompt module is a simple embedded multiline python interpreter built around raw_input(). The interpreter can be started at any given location in a program by executing a tiny code object and is allways executed in the namespace of the caller. Objects in the current scope can easily be explored and modified. Intermediate interruption of the control flow for manual interaction is handy for debugging purposes. The ability of multiline commands was crucial for me, so I wrote this module. It is tested with python, jython and stackless. The prompt codeobject can also be started from the pdb prompt.\n'}, {'comments': [{'comment': u'The Description and Discussion sections are unreadable due to the super-long lines in the source code.\n<br>\nIt is not practical to evaluate this recipe because it is unreadable.\n<br>\nFrom what little I could make out, I could not determine the purpose of this recipe.', 'title': u'Need to break up super-long lines and improve Discussion'}], 'desc': u"These two scripts together allow packages to be migrated into a versioned directory structure, allowing a script to specify minimum version / interpretor / platform requirements at time of import, defaulting to the the newest/highest version when not specified, raising exceptions where necessary.\nSpecifying the level at which the PythonInterpretor or Package is Incompatible.\n\nversioner.py - recurses a site-packages directory managing __init__.py's\nversion_loader.py - when placed in a directory with versioning runs at time package is imported ensuring selection/compatibility of package from those avaliable"}, {'comments': [{'comment': u'Python classes can be passed around, so you can refer them to directly rather than by name:\n\n<pre>\ndef getObject(cond):\n\tif cond:\n\t\tcls = A\n\telse:\n\t\tcls = B\n\treturn cls()\n</pre>\n\nIf you need a multiway decision you can use a dictionary that has the candidate classes as its values.', 'title': u'You can specify the class directly rather than by name'}, {'comment': u"This assumes you know the names of the classes in advance. I needed to be able to create objects from classnames that were only known at runtime. The example isn't very good I guess but I wanted to provide a simple example. ", 'title': u' '}, {'comment': u"Had a situation where I needed this for an XML-RPC server to dispatch calls. May be a smarter way to do it but couldn't find it;\n\n<pre>\nclass Dispatcher:\n def _dispatch(self, method, params):\n # XML-RPC request method: MyClass.someMethod\n handler, method = string.split(method,'.',1)\n\n # Perhaps dynamically __import__() here...\n\n # Get the class\n clas = globals()[handler]\n\n # Get the method in the class\n func = class.__dict__[method]\n\n # Create the object\n obj = clas()\n\n # Shift the obj instance into the start of the params\n params.insert(0,obj)\n\n # Call the function...\n apply(func,params)\n</pre>", 'title': u'Call object method from string'}], 'desc': u'I sometimes want to create objects from various classes based on some condition (without using eval()). For example when parsing X(HT)ML files I want to handle some tags using specific classes. It is actually quite easy but I had a hard time finding out how to do that, no doubt due to my limited knowledge of python, so here\'s a simple example.\n\nEdit: See also <a href="http://www.faqts.com/knowledge_base/view.phtml/aid/2635/fid/242">http://www.faqts.com/knowledge_base/view.phtml/aid/2635/fid/242</a>'}, {'comments': [{'comment': u"Here's an alternative approach that also makes use of re but may be faster by using the decorate, sort, undecorate idiom:\n\n<pre>\nimport re\ndigitsre=re.compile(r'\\d+') # finds groups of digits\nD_LEN=3\n\ndef _decor(s):\n '''decorate function for sorting alphanumeric strings naturally'''\n return digitsre.sub(lambda s: str(len(s.group())).zfill(D_LEN)+s.group(),s)\n\ndef _rem_len(s):\n '''sub function for undecor - removes leading length digits'''\n return s.group()[D_LEN:]\n\ndef _undecor(s):\n '''undecorate function for sorting alpha strings naturally'''\n return digitsre.sub(_rem_len,s)\n\ndef natsort(list_):\n '''sort a list in natural order'''\n tmp=[_decor(s) for s in list_]\n tmp.sort()\n return [_undecor(s) for s in tmp]\n\ndef natsort24(list_):\n '''Python 2.4 version'''\n return [_undecor(s) for s in sorted([_decor(s) for s in list_])]\n</pre>\nThe re.sub method is used to prepend every numeric group with it's length, so 1 becomes 11, 25 becomes 325 and so on. This is done as a decorate step and the list can then be sorted with the standard sort() function (or sorted() in Python 2.4). Then the list is undecorated and left in sorted order.", 'title': u'How about a decorate, sort, undecorate technique?'}, {'comment': u'This uses newer features, like List Comprehensions [ http://www.network-theory.co.uk/docs/pytut/tut_38.html ] to make the code very small and fast.\n\n<pre>import re\n\n# dictionary: keys will be "natural" sorted: 1,2,3...9,10,11...\n#\nzoot = {\'indy1:11\':\'beer\', \'indy12:11\':\'coffee\', \'indy2:11\':\'doughnut\'}\n\n# list each item, prefixed with a number\n# based on its order\n#\nzoot\t= [ ( int(re.search(\'\\d+\', key).group(0)), key, value ) \n for key,value in zoot.items() ]\nzoot.sort()\nprint zoot\n\n\n# undecorate:\n#\nzoot\t= [ item[1:] for item in zoot ]\nprint zoot\n</pre>\n\nThe output is the original data, but sorted in natural order:<pre>\n[(\'indy1:11\', \'beer\'), (\'indy2:11\', \'doughnut\'), (\'indy12:11\', \'coffee\')]</pre>', 'title': u'short, modern alternative code'}, {'comment': u"For sorting lists:\n\n<pre>\ndef natsort(list_):\n # decorate\n tmp = [ (int(re.search('\\d+', i).group(0)), i) for i in list_ ]\n tmp.sort()\n # undecorate\n return [ i[1] for i in tmp ]\n</pre>", 'title': u'simplified version of list comprehensions code'}], 'desc': u"Sorts strings in a way that seems natural to humans. If the\nstrings contain integers, then the integers are ordered\nnumerically. For example, sorts ['Team 11', 'Team 3', 'Team 1']\ninto the order ['Team 1', 'Team 3', 'Team 11'].\n"}, {'comments': [{'comment': u'Updated to add attribution of quotes, and add support for embedded newlines.', 'title': u'Update'}], 'desc': u'A simple generator function to return an input string in fragments, each broken at spaces in the text.'}, {'comments': [{'comment': u"You should be careful with this in a threaded environment. Because of the way it is constructured, two threads *may* share an instance, but won't necessarily do so. Only with proper locking can you ensure that only one instance will exist for a particular set of parameters. \n<br><br>\nIf you do not want threads to share instances you must instead implement a pool mechanism, where you fetch objects from a pool, or if the pool has no appropriate instance you create the object. The objects themselves should probably be wrappers in that case, so that you can override __del__ so that it returns the instance to the pool just before it is garbage collected. Alternately, you can insist that any threads that fetch an object explicitly return it to the pool when they are done, or any classes implement a __del__ method themselves.", 'title': u'Threading'}, {'comment': u'you could just instantiate your instances with a factory function.\nIt would also be clearer to your users. Unless you want to hide the\nfact that instances are cached and you want your users use the standard\ninstantiation syntax. If this is your goal (for instance because\nthere is a lot of already written code using the standard calling\nsyntax) then the metaclass solution is justified. But I would not\nuse it if I was writing a new application from scratch.', 'title': u"You don't really need a metaclass here ..."}], 'desc': u'You need to cache instances based on what arguments are passed to them.'}, {'comments': [], 'desc': u'Often, we might want to let (untrusted) users input simple Python expressions and evaluate them, but the eval-function in Python is unsafe. The restricted execution model in the rexec module is deprecated, so we need another way ensure only "safe" expressions will be evaluted: analyzing bytecodes.'}, {'comments': [], 'desc': u'This small code demonstrates how state driven programming can be done in python.'}, {'comments': [{'comment': u"This is interesting, but wasn't Guido's proposal to put it immediately before function definition, not inside the function body?", 'title': u' '}, {'comment': u"True, but it was a bit cleaner to implement it the other way around, since this way the list ends up with the function object when compiled. I'll see if I can implement Guido's actual proposal by going through the module level bytecodes.", 'title': u' '}], 'desc': u'Wether or not PEP 318 makes it to Python 2.4, you can experiment with an alternative decorator syntax in Python 2.3 by hacking with bytecodes.'}, {'comments': [{'comment': u'The "leaves" should be "leafs" ...', 'title': u'typos'}], 'desc': u"In order to structure data, it makes sense to use hierarchical schemes, as for example filesystems structure files in nested directories. This recipe offers an easy to use class which shows an analog behavior as the 'super mkdir' os.makedirs."}, {'comments': [{'comment': u"('tilde', '='),I believe that one would be the correct--> ('tilde', '~')\n ", 'title': u'About the tilde'}, {'comment': u"That was initially the idea, but I couldn't get it to work. Since I couldn't use Ctrl-c for cedilla anyway (which would follow the pattern for TeX-like accents), I just gave up on the tilde.", 'title': u"Couldn't get it to work"}], 'desc': u'This module provides two standard Tkinter widgets, Entry and ScrolledText, modified for text editing with key bindings that allow entering accented letters, umlauts, etc.\n\nUsage: To enter an accented character, press Ctrl-symbol, then press the character key. Example: to enter U with umlaut, press Ctrl-", U. For accent symbols that need shift, press Ctrl-Shift-symbol (for example, Ctrl-Shift-\' if " is under Shift-\').\n\nAccent bindings are defined in the Diacritical.accent table. Not all accents exist on all letters. This is handled by gracefully falling back to the base letter.\n\nAdditional changes in default Tk key bindings: Ctrl-A is now select-all.'}, {'comments': [], 'desc': u"A *tiny* adjustment to the askstring dialog in the standard module tkSimpleDialog. The underlying code allows a default string to be passed to in, but the actual dialog function doesn't.. This one does."}, {'comments': [], 'desc': u'Indicates the essentials of creating keys, or otherwise manipulating the Windows registry, using ctypes; also of registering a DLL.\n\nHurrah for ctypes!'}, {'comments': [], 'desc': u'A very simple script that fetches a webpage for you. Useful for a cgiproxy in situations where web access is restricted - and to illustrate the basic case use of urllib2.'}, {'comments': [], 'desc': u'ilines is a generator that takes an iterable and produces lines of text. The input iterable should produce blocks of bytes (as type str) such as might be produced by reading a file in binary. The output lines are formed by the same rule as the "universal newlines" file mode [f = file(name, \'U\')] and are produced "on-line" -- when lines are discovered, they are produced.'}, {'comments': [], 'desc': u'Dump and load variables for exchanging data between matlab and numarray. \nThe variables are in a dictionary, and each key in the variable gets \ndumped into a file named after the variable. If the variable is complex,\nthe real and imag parts are dumped into separate files.\n\nLoading of files, created by matlab is also possible. In this case, the returned dictionary has the keys derived from the file names and values from the files.'}, {'comments': [{'comment': u"<pre>>>> import win32api\n>>> win32api.GetShortPathName('D:/share/from_roadwarrior/simon/python/RandomizeScreenSaver/RandomizeScreenSaver.pyw')\n'D:/share/FROM_R~1/simon/python/RANDOM~1/RANDOM~1.PYW'</pre>", 'title': u'win32api.GetShortPathName()'}, {'comment': u'Oops. I guess I was misinformed. I should have looked deeper in the docs. Thank you for clearing this up.', 'title': u'Re:win32api.GetShortPathName()'}, {'comment': u'Using the Windows API function only works if the file exists in the specified path.', 'title': u'Beware...'}, {'comment': u"Files that don't exist don't *have* short names. One might be able to put together a function that guesses what short name Windows would be likely to give a new file with a given long name, but it would be pretty unreliable, I reckon.", 'title': u'This is just as it should be...'}], 'desc': u'In Windows it is often useful to get the "Short Name" version (8.3) of a file or directory path. The Windows api does not provide a function that one can call for this.'}, {'comments': [{'comment': u"The following shows how:\n\n<pre>\n>>> class C:\n... def __init__(self, a=1, b=2, **kw):\n... c = 3\n... self.__dict__.update(kw)\n... del kw # We don't want this in attrs\n... self.__dict__.update(locals())\n... del self.self # We don't need this either\n... def dump(self):\n... print repr(self.__dict__)\n...\n>>> c = C(d=4)\n>>> c.dump()\n{'a': 1, 'c': 3, 'b': 2, 'd': 4}\n>>> c.a\n1\n>>> c.c\n3\n</pre>\n\nNote that the commented lines are there purely to tidy up the instance namespace, and if you don't need arbitrary keywords, the **kw stuff can go, leaving just self.__dict__.update(locals()).\n\nBut idiom or function, I agree, it's something that I need quite often. (And hadn't really thought about the best approach for, until now - so thanks!)", 'title': u'It\'s easy enough to do this "by hand"'}, {'comment': u'Often, I want to ignore locals when I set attributes. The following modification adds a parm to tell initFromArgs to do that. If bJustArgs is True, only parms to the __init__ method are turned into instance attributes. \n\nSo, for example, in the Animal class, the "pet" local would be ignored:\n\n<pre>\ndef initFromArgs(beingInitted, bJustArgs=True):\n codeObject = beingInitted.__class__.__init__.im_func.func_code\n tupNames = codeObject.co_varnames[1:codeObject.co_argcount]\n for k,v in sys._getframe(1).f_locals.items():\n if (not bJustArgs) or k in codeObject.co_varnames[1:codeObject.co_argcount]:\n setattr(beingInitted,k,v)\n</pre>', 'title': u'Ignoring locals'}, {'comment': u"THanks! I didn't know about the locals function. That is cool! I just like having it in a function, so I only have to look at one copy...., but that idiom is much cleaner than what was in my code :-).", 'title': u"Didn't know about locals()"}, {'comment': u"That is really cool... I'll add that to the recipe...\n\n Thanks!", 'title': u'Thanks for that modification!'}, {'comment': u'Very nice. \n\nAs an enhancement I would suggest using the actual name of the caller (instead of the hard-wired name "__init__").\n\nThe name of the caller can be found by\n<pre>\n callerName = sys._getframe(1).f_code.co_name\n</pre>\nLike your\'s, this code is also inspired by Alex Martelli (as far as I remember).\n\nThe code object can then be found by\n<pre>\n codeObject = beingInitted.__class__.__dict__[callerName].\n</pre>\n\nThe full function text would then look like this:\n\n<pre>\ndef initFromArgs(beingInitted, bJustArgs = True):\n callerName = sys._getframe(1).f_code.co_name\n codeObject = beingInitted.__class__.__dict__[callerName].func_code\n for key, value in sys._getframe(1).f_locals.items():\n if (not bJustArgs) or key in codeObject.co_varnames[1:codeObject.co_argcount]:\n setattr(beingInitted, key, value)\n</pre>', 'title': u'use the actual function name of the caller'}, {'comment': u'The following line is missing in version 1.1 of the code and should be inserted near the beginning of the body of the initFromArgs() function -- i.e. before the for loop where it is used:\n<br>\n<pre>\n codeObject = beingInitted.__class__.__init__.im_func.func_code\n</pre>', 'title': u'missing line of code'}, {'comment': u'The new code has that line added back in...', 'title': u'Fixed!'}], 'desc': u'This recipe assigns each parameter to an instance variable of the same name, automating a common pattern of object initialization, and making class definitions more compact. '}, {'comments': [], 'desc': u'A script to gather errors, warnings, and failures from Micrsoft SQL Servers and SQL Server Agents. Creates a single HTML file from multiple server logs. Used as a quick daily check to determine if particular servers require administrator intervention.'}, {'comments': [{'comment': u'sqlbuilder, a module in SQLObject (http://sqlobject.org) implements something like this. You can use Python expressions to create a where clause, and generate SQL or evaluate the expression with bound variables. There is a (somewhat obsolete) backend to SQLObject using dbm files, which simply iterates through a table evaluating the expression with each row, and returning those rows for which the expression is true. Anyway, similar idea.', 'title': u'SQL Generation'}], 'desc': u'This recipe implements a simple Table class which allows searching in a syntax similar to SQLs WHERE statement. So if t is Table, t.a == 3 finds all rows, where the column named "a" has the value 3. Intersection and unions of search results are possible too, for examples look at the __main__ part below.'}, {'comments': [{'comment': u'super is very hairy indeed. Your recipe goes in a direction (using\nsys._getframe, inspecting the MRO by hand, etc) which I discarded,\nbut seems to be working (I should really find the time to write \ndown a comprehensive suite of corner cases, anyway). It would be\ninteresting to try it with Jython (not sure about the status of\nJython, but they should have added super and Python 2.2 now, at\nleast at some alpha level).\n<br>\nAfter a lot of thinking I have decided that the simpler solution\nis to be very explicit\nand to pass the super object as an additional argument to the\ncooperative methods. I posted the idea here http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/284528\nbut that recipe is by no means complete. It takes a lot of\nwork to get a robust solution and I am kind of lazy ;)\n<br>\nAnyway this would work with my recipe\n\n<pre>\nclass B(Cooperative):\n def __init__(self):\n print "B.__init__"\n \nclass C(B):\n def __init__(self,super):\n print "C.__init__"\n def helper():\n print "C - helper"\n super.__init__()\n helper()\n\n</pre>\nwhereas it cannot work with your approach. There are dark hacks\nthat would allow me to pass the super argument implicitly, but\nthey are too ugly to be even mentioned and I feel kind of fine\nto have an additional argument. In this way users are prevented just \nfrom the argument line that they are going to read a cooperative method and they can prepare themselves ;)\n<br>\nNice work, but I would not want to be autosuper maintainer ! ;)\n\n\n Michele Simionato', 'title': u'very interesting'}, {'comment': u'Whilst it doesn\'t allow calling self.super from inside the nested helper function, you can pass self.super explicitly to the helper function.\n\n<pre> class B (autosuper):\n def __init__(self):\n print "B.__init__"\n \n class C (B):\n def __init__(self):\n print "C.__init__"\n\n def helper (super):\n print "C - helper"\n super()\n \n helper(self.super)</pre>\n\nThe most common case is to *not* use a helper function, so I don\'t see that it\'s an excessive amount of work to pass the bound super proxy explicitly in those cases that you want to.\n<br>\n<br>I also don\'t want to go down the track of the hacking required to determine which function is nesting this one, etc.', 'title': u'It deals with the most common case'}, {'comment': u"Another advantage of my recipe over Cooperative is that it doesn't give magic meaning to parameter names. The recent discussions on c.l.py over Paul Morrow's suggestion for using parameter names to determine static and class methods prompted me to add this.\n\nChanging parameter names should not cause change in behaviour.", 'title': u'Doesn\'t rely on "magic" parameter names'}, {'comment': u'Tim, I\'m really excited to see your improved autosuper. I tried to do exactly this back in April, and wound up giving up with a second-best solution of making it a classmethod instead and accepting the class as the parm instead of the self reference. My recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/279604) works really well but a solution that allows calling self.super() instead of class.super() is certainly superior.<br><br>\n\nI\'ve run into a couple problems with your recipe:<pre>\n\nif __name__ == "__main__":\n class A(autosuper):\n def fun1(self):\n print "A"\n self.super() #- TypeError\n\n class B(A):\n def fun1(self):\n print "B"\n self.super()\n\n class C(B): pass #- recursion\n\n # class C(B):\n # def fun1(self):\n # print "C"\n # self.super()\n t = C()\n t.fun1()\n\n</pre>Problem #1 is a TypeError that occurs when trying to call super() from A.fun1(). The caller shouldn\'t have to know when/where to use self.super().<br><br>\n\nProblem #2 is the real bugger: if class C doesn\'t provide fun1, and fun1 is called, infinite recursion will occur with:<pre>\n\nTraceback (most recent call last):\n File "autosuper.py", line 129, in ?\n t.fun1()\n File "autosuper.py", line 120, in fun1\n self.super()\n File "autosuper.py", line 38, in __call__\n return method(*p, **kw)\n File "autosuper.py", line 120, in fun1\n self.super()\n File "autosuper.py", line 38, in __call__\n return method(*p, **kw)\n File "autosuper.py", line 120, in fun1\n self.super()\n ...\nRuntimeError: maximum recursion depth exceeded\n\n</pre>I\'m not enough of a guru to figure out why this recursion is occuring, but I do know that the use case that causes it is not uncommon. If autosuper can be fixed to account for this case, it looks to be quite useful.', 'title': u"Great, but 2 common cases don't work"}, {'comment': u'Tim, I\'m really excited to see your improved autosuper. I tried to do exactly this back in April, and wound up giving up with a second-best solution of making it a classmethod instead and accepting the class as the parm instead of the self reference. My recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/279604) works really well but a solution that allows calling self.super() instead of class.super() is certainly superior.<br><br>\n\nI\'ve run into a couple problems with your recipe:<pre>\n\nif __name__ == "__main__":\n class A(autosuper):\n def fun1(self):\n print "A"\n self.super() #- TypeError\n\n class B(A):\n def fun1(self):\n print "B"\n self.super()\n\n class C(B): pass #- recursion\n\n # class C(B):\n # def fun1(self):\n # print "C"\n # self.super()\n t = C()\n t.fun1()\n\n</pre>Problem #1 is a TypeError that occurs when trying to call super() from A.fun1(). The caller shouldn\'t have to know when/where to use self.super().<br><br>\n\nProblem #2 is the real bugger: if class C doesn\'t provide fun1, and fun1 is called, infinite recursion will occur with:<pre>\n\nTraceback (most recent call last):\n File "autosuper.py", line 129, in ?\n t.fun1()\n File "autosuper.py", line 120, in fun1\n self.super()\n File "autosuper.py", line 38, in __call__\n return method(*p, **kw)\n File "autosuper.py", line 120, in fun1\n self.super()\n File "autosuper.py", line 38, in __call__\n return method(*p, **kw)\n File "autosuper.py", line 120, in fun1\n self.super()\n ...\nRuntimeError: maximum recursion depth exceeded\n\n</pre>I\'m not enough of a guru to figure out why this recursion is occuring, but I do know that the use case that causes it is not uncommon. If autosuper can be fixed to account for this case, it looks to be quite useful.', 'title': u"Great, but 2 common cases don't work"}, {'comment': u'The first case causes an AttributeError, and this is expected. I originally allowed missing attributes to pass silently, but Guido convinced me that this was the wrong way to go.\n\n<pre>Traceback (most recent call last):\n File "D:\\Development\\modules\\autosuper\\test.py", line 16, in ?\n B().fun1()\n File "D:\\Development\\modules\\autosuper\\test.py", line 12, in fun1\n self.super()\n File "D:\\Development\\modules\\autosuper\\autosuper.py", line 108, in __call__\n return method(*p, **kw)\n File "D:\\Development\\modules\\autosuper\\test.py", line 7, in fun1\n self.super() #- TypeError\n File "D:\\Development\\modules\\autosuper\\autosuper.py", line 116, in __call__\n method = getattr(super, method)\nAttributeError: \'super\' object has no attribute \'fun1\'</pre>\n\nI\'m not sure what cases the second problem yet (it\'s got to be scanning the MRO) but I\'ll post an updated recipe when I\'ve worked it out.', 'title': u'I think you mean AttributeError'}, {'comment': u'Comments are inline - basically, I was getting the base class method (and hence code object) at the subclass level, and so never getting past there.\n<br>\n<br>The solution is to continue searching the MRO until I fail to find a matching code object - that means that the previous class was where the code object was defined i.e. the real class I want to use.', 'title': u'Recursion problem solved'}], 'desc': u'Use self.super(*p, **kw) instead of super(cls, self).func(*p, **kw).\n\nLatest version (much faster, with docs, tests, Pyrex version) is available at:\nhttp://members.optusnet.com.au/tcdelaney/python.html#autosuper'}, {'comments': [{'comment': u"Don't be scared off by the size. There's a whole demo app in there.\n<br><br>\nLook for -------------------- 8< ------------------\n<br><br>\nfor between file cuts...\n<br><br>\nComments appreciated", 'title': u"Don't be scared"}, {'comment': u"I'm unable to locate information on the guinet module... am I missing something?", 'title': u'guinet module?'}, {'comment': u'Sorry, there are like three or four files in the recipe. The first file is guinet.py.\n<br><br>\nEach file is separated with a line break:\n-----------------8<------------------------ ', 'title': u'guinet.py'}, {'comment': u'<pre>\n"""This module enables wxPython and twisted to peacefully co-exist.\n\nIt does this by running wxPython in the main thread and starting a secondary thread for the twisted library.\n\nIt also provides a set of tools to enable communication between the two librarys\n\nWARNING: DON\'T use setTimeout on deferreds made/used in wx thread!\n"""\n\n# Imports\nimport wx\nfrom threading import Thread, Event\nfrom twisted.internet import reactor\nfrom twisted.python import threadable\nfrom twisted.internet.defer import maybeDeferred, Deferred\nfrom twisted.trial.util import deferredResult\nfrom time import sleep\n\n\n# Make our own wxEvent for responding to messages\nwxEVT_RESPONSE = wx.NewEventType()\n\nclass ResponseEvent(wx.PyCommandEvent):\n """This is our event used to pass net info\n (success, failure, progress, and status)\n to the gui"""\n\n def __init__(self, func, onSuccess, onFailure, *params, **kwparams):\n wx.PyCommandEvent.__init__(self, wxEVT_RESPONSE, 1)\n self.func = func\n self.onSuccess = onSuccess\n self.onFailure = onFailure\n self.params = params\n self.kwparams = kwparams\n\n\nclass TwistedThread(Thread):\n """Starts twisted in a secondary thread.\n It uses "commands" which are calls to the net thread from the gui thread\n and "responses" which are calls to the gui thread from the net thread\n but as both "commands" and "responses" have "onSuccess" and "onFailure"\n callbacks which must again cross the thread boundary, these are reversed\n so: A call from gui to net is a command, and its onSuccess call is a response\n but a call from net to gui is a "response" and its onSuccess call is a "command"\n so try not to get confused...\n """\n\n def __init__(self, app, twistedLogFileName=None, block=True):\n """\'app\' is a wx.App instance\n \'twistedLogFileName\' is the filename for twisted to log to. If ommited will log to stderr\n \'block\' means wait until the reactor is actually running before returning"""\n Thread.__init__(self)\n self.app = None\n self.twistedLogFileName = twistedLogFileName\n self.block = block\n self.setApp(app)\n ThreadCommand.twistedThread = self\n if app: self.start()\n\n def start(self):\n """Start the twisted reactor running in a different thread"""\n if self.block:\n self.startEvent = Event()\n Thread.start(self)\n self.startEvent.wait()\n else:\n Thread.start(self)\n\n def run(self):\n threadable.init(1)\n if self.twistedLogFileName:\n from twisted.python import log\n self.log = log\n self.log.startLogging(open(self.twistedLogFileName, \'w\'), 0)\n self.log.msg(\'Starting...\')\n reactor.callLater(0, self._onStart)\n reactor.run(installSignalHandlers=0)\n\n def _onStart(self):\n """Called once the reactor is actually running"""\n self.running = True\n if self.log: self.log.msg(\'Started\')\n if self.block:\n self.startEvent.set()\n \n # Methods called from gui thread\n\n def stop(self):\n """Call to cleanup the reactor"""\n ThreadCommand((self._doStop, (), {}), self._onStopped, self._onStopFailed)\n \n def _onStopped(self, res):\n """Called once the reactor has stopped"""\n self.running = False\n \n def _onStopFailed(self, reason):\n self.running = False\n raise Exception(\'Could not stop reactor: %s\' % reason)\n\n def setApp(self, app):\n """Call this first of all and every time you change\n your application object (like in some testing programs)\n It makes the app subscribe to our special events so that it can\n call your callback functions.\n """\n if app is not self.app:\n if self.app:\n self.app.Disconnect(1, 1, wxEVT_RESPONSE, self._doRunResponse)\n self.app = app\n self.app.Connect(1, 1, wx', 'title': u"I've update guinet.py"}], 'desc': u"This script allows using twisted with wxPython at the same time without them stepping on each others toes.\nI'm so sorry for the messyness of it. I haven't found the time to tidy it up.\nThe thing is it works, we use it in our kiosk administration program.\n<ad>http://www.sherborneinternational.com</ad>.\n\nwxPython has its own main loop, twisted has its own main loop.\nwxreactor allows them to work together unless you want to use modal\ndialogs (and in my case didn't work on two linux machines with wx2.4).\nwxsupport is about the same, but didn't work on windows (with wx2.5) for me.\n\nThis solution is taken from itamar's suggestion in the twisted mailing list.\nLet each run in its own thread."}, {'comments': [{'comment': u'It\'s a new style class, but it blows:\n\n<pre>\nTraceback (most recent call last):\n File "./sucker.py", line 24, in ?\n root = PickleUpgrader(open(sys.argv[1])).load()\n File "/usr/local/lib/python2.2/pickle.py", line 597, in load\n dispatch[key](self)\n File "/usr/local/lib/python2.2/pickle.py", line 817, in load_global\n klass = self.find_class(module, name)\n File "./sucker.py", line 22, in find_class\n return makeFakeClass(module, cname)\n File "./sucker.py", line 9, in makeFakeClass\n FakeThing.__name__ = name\nTypeError: attribute \'__name__\' of \'type\' objects is not writable\n</pre>\n<br>\nThis is python 2.2.<br>\nI tried using <br>\n<pre>\n FakeThing = type( name, (), {} )\n FakeThing.__module__ = \'(fake)\' + module\n</pre>\nbut I still get:<br>\npickle.UnpicklingError: < class \'(fake)XXX.YYY\' > is not safe for unpickling<br>\n<br>\nSimon.<br>', 'title': u'blows for me...'}], 'desc': u"The following code loads arbitrary pickles (well, there are probably some that it won't load, like ones which have object states which aren't dicts). It just loads their data into totally inert objects which you can then traverse and do what you like to. It's pretty similar to processing a DOM tree. "}, {'comments': [{'comment': u'See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/170242\n<br><br>\nThat solution is short but requires a list of strings. If heterogenous lists are possible adding a type check is easy enough, but I wonder at the practical applications of sorting lists of different types of objects.\n<br><br>\nGreg Jorgensen<br>PDXperts LLC<br>Portland, Oregon USA', 'title': u'This is already in the cookbook, only three lines of code'}, {'comment': u'Mine will also sort the list members where member1.lower() == member2.lower()<br>\n<br>\n*However* - the one you point to is still elegant. Mine is similar in principal but stores a dictionary of all the keys and then sorts the keys - but it does the type checking as well. ', 'title': u'Hmm....'}], 'desc': u"This is a recipe that does a case insensitive sort. The normal sort methods of lists has 'B'<'a', which means that it would sort 'Pear' to come before 'apple' in a list. You can pass in a function to the sort method to change this... but this can be slow. This is a function that transforms the list, uses the sort method and then transforms it back."}, {'comments': [], 'desc': u'NamedShare is a variation on the Singleton pattern (see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/102187). In effect, it provides for a set of quasi-singletons, identified by keyword. If no keyword is given, the default share is accessed.'}, {'comments': [], 'desc': u"The following KeyedSet class mirrors the builtin set class as closely as possible, whilst maintaining the general flexibility of a dictionary. The only requirement is that each set item has a distinct 'id' attribute. The usual set operations are implemented, but items can also be referenced via their id."}, {'comments': [{'comment': u"I don't believe this belongs here. Try including this example with the nevow download.", 'title': u'delete'}, {'comment': u'I have not read the ASPN standards, so maybe I\'m way out of line here, but:<br>\n1) This is python<br>\n2) Twisted is python (and excellent python at that)<br>\n3) Nevow is cool python.<br>\n<br><br>\nI could see where some might want to keep recipes here "pure" python... but what\'s pure? Stuff that was left field years ago is part of tomorrow\'s python release; twisted and nevow\'s not *that* far off the mark, don\'t you think?', 'title': u'I disagree...'}, {'comment': u"I don't mind this being here. I see your point, that this cookbook shouldn't become a soapbox for pet projects. But I think this is valid. I've been about to read the Nevow introduction three times now and I've gotten sidetracked each time. This gave me a really good overview very quickly. And developers looking for a Web framework shouldn't have to go running all over Google just to get some basic info.<br> <br>\n\nStill, don't forget Webware at http://www.webwareforpython.org. It's mature, as powerful as anything, and, for Java developers, a familiar paradigm built on servlets and templating. It's a good counterbalance to Nevow since, in many ways, they're very different.", 'title': u"Ah, don't get yourself in a twist ..."}, {'comment': u"I've downloaded and tested this recipe but nothing happened. The python program reported no error so it must be running correctly. But it (this recipe) doesn't provide any output to let the user know what is going on. I assume that a localhost http server be opened on port 8080 but calling http://localhost:8080 didn't return any page. ", 'title': u'What does this recipe do?'}, {'comment': u"I think the missing link is something like:\n\n<pre>\nhttpd = internet.TCPServer(8080, site)\nhttpd.setServiceParent(application)\nhttpd.startService()\n</pre>\n\nor just\n\n<pre>\n from twisted.internet import reactor\n backlog=5\n reactor.listenTCP(8080, site, backlog, '127.0.0.1')\n reactor.run()\n</pre>", 'title': u're: what does this do ?'}, {'comment': u"httpd = internet.TCPServer(8080, site)\nhttpd.setServiceParent(application)\nhttpd.startService()\n\nDoesn't seem to work for me,\nreactor does.\nAnybody know why it just exits? (no error, or anything)", 'title': u' '}], 'desc': u"Here you can find a very basic example of how nevow (twisted's new web toolkit) works. As you see the purpose of this example is to represent in a <ul> a list of dictionaries. I can translate a dict into some tags thanks to the built-in mapping render."}, {'comments': [], 'desc': u'Run an arbitrary string on the server as a shell command. Mimics a very basic shell environment on a server using CGI.'}, {'comments': [], 'desc': u'Run an arbitrary string on the server as a shell command. Mimics a very basic shell environment on a server using CGI.'}, {'comments': [{'comment': u'<pre>\n#!/usr/bin python \n\nimport sys\nfrom CoreGraphics import *\n\ndef pageCount(pdfPath):\n "Return the number of pages for some PDF file."\n \n pdf = CGPDFDocumentCreateWithProvider (CGDataProviderCreateWithFilename (pdfPath))\n return pdf.getNumberOfPages()\n\nif __name__ == \'__main__\':\n if len(sys.argv) == 2:\n print pageCount(sys.argv[1])</pre>', 'title': u'Two lines less, PyObj not required. Works with 10.3 or later... :-)'}], 'desc': u'Given that PDF is a "native" data format on Mac OS X, it is very easy to get access to some properties of such documents. One is the number of pages. Using Python the necessary code to do this is only about four lines, plus some import and command-line plumbing, etc.'}, {'comments': [], 'desc': u'Services subclassing ServiceFramework report to eventlog events source "PythonService". Here is another way of changing the source name'}, {'comments': [{'comment': u"In celsius_to_kelvin() and fahrenheit_to_kelvin() the global variable 'temp' is used in the return calculations instead of the local method parameters k_temp and k_temp2 respectively. This may lead to confusion.\nAlso, in fahrenheit_to_kelvin() there is no need to do the fahr2Celcius math again. Simply return fahrenheit_to_celcius(k_temp2) + 273. This seems cleaner.", 'title': u'use of globals'}, {'comment': u'<pre>\nprint \'Temperature converter (type "quit" to exit)\'\n\nprompt = \'Enter a conversion such as "10 C to F" or "459 F to K": \'\n\nwhile 1:\n line = raw_input(prompt).upper()\n if \'QUIT\' in line:\n break\n \n t, fromto = None, []\n for token in line.split(\' \'):\n try:\n t = float(token)\n except ValueError:\n pass\n if token[:1] in \'CFK\':\n fromto.append(token[0])\n if t is None or len(fromto) != 2:\n print \'Unsuccessful parse. Try again, using the format: 15 K to C\'\n \n # Convert to celsius\n if fromto[0] == \'F\':\n t = (t - 32) * 5 / 9\n elif fromto[0] == \'K\':\n t -= 273\n \n # Convert from celsius\n if fromto[1] == \'F\':\n t = t * 9 / 5 + 32\n elif fromto[1] == \'K\':\n t += 273\n print \'--> %.1f %s\' % (t, fromto[1])\n</pre>', 'title': u"Just for grins, here's an alternative approach the problem."}], 'desc': u'Code I got from a tutorial then edited . Changes fahrenheit to celsius , celsius to fahrenheit , fahrenheit to kelvin , and celsius to kelvin .'}, {'comments': [{'comment': u'it\'s good idea! thank you.\n\nbut it can only get the information for current process.\nin my Application, i want only to get the memory usage for\nchildren process(os.popen("children_process") \nor os.exec("children_process")).\n\nhow can i do?\n', 'title': u'RE: memory usage'}, {'comment': u'You can get the memory usage of any process by using the proper _process_status string: simply replace os.getpid() with the pid of the process. To get the pid of a spawned process, use the Popen3 class from the standard popen2 module.<br><br>\nFor more details, see recipe 6.6 "Capturing the Output and Error Streams from a Unix Shell Command" by Brent Burley on page 227 of the Python Cookbook by O\'Reilly, check the documentation of the popen2 module and source code in file .../lib/python.../popen2.py of your Python installation.', 'title': u'memory usage of child processes'}, {'comment': u'i think that the "proper_process_status" can be used only in Linux, it can\'t be runned in Unix (i.e.Solaris). because the file /proc/pid/sttus is a binary-file.\n\nperhaps the function "resource.getrusage(resource.RUSAGE_CHILDREN)" is a choice too. but I don\'t konw how use it. :(\n\n>>>import resoure\n>>>os.popen("command")\n>>> resource.getrusage(resource.RUSAGE_CHILDREN)\n(0.004999, 0.0089979999999999991, 0, 0, 0, 0, 444, 22, 0, 0, 0, 0, 0, 0, 40, 3)\n[2:4] is the memory usage, but "0"!, why!? \ncan you help me?', 'title': u' '}], 'desc': u'This recipe provides a number of functions to get the memory usage of a Python application on Linux.'}, {'comments': [], 'desc': u'A wrapper script for mysqldump that allows to dump a database excluding some tables.'}, {'comments': [], 'desc': u'I used this when trying to retrieve a site I could not access via the wayback machine (archive.org). Might require some tweaking to get it to work...'}, {'comments': [{'comment': u"I added this to allow for 302 responses, which are processed automatically by most (all?) browsers.\n\n<pre>\nelif responseOb.status == 302:\n found = httpExists(urlparse.urljoin(url, responseOb.getheader('location', '')))\n</pre>", 'title': u'Catch "302: Moved temporarily"'}, {'comment': u'Part of me thinks that either httplib should have stock code for handling 300 status code redirections, or urllib should handle HEAD requests. The fact that this isn\'t provided by the standard libraries is crappy in my opinion.\n\nHere\'s what I use to handle redirection. Recursion\'s a bad idea, it should be an iterative loop with a limit to avoid infinite redirection.\n\n<pre>\ndef head_url(url):\n """Perform HEAD, may throw socket errors"""\n\n import httplib, urlparse\n\n def _head(url):\n """Returns a http response object"""\n\n host, path = urlparse.urlparse(url)[1:3]\n\n connection = httplib.HTTPConnection(host)\n connection.request("HEAD", path)\n return connection.getresponse()\n\n # redirection limit, default of 10\n redirect = 10\n\n # Perform HEAD\n resp = _head(url)\n\n # check for redirection\n while (resp.status >= 300) and (resp.status <= 399):\n # tick the redirect\n redirect -= 1\n\n # if redirect is 0, we tried :-(\n if redirect == 0:\n # we hit our redirection limit, raise exception\n raise IOError, (0, "Hit redirection limit")\n\n # Perform HEAD\n url = resp.getheader(\'location\')\n resp = _head(url)\n\n if resp.status >= 200 and resp.status <= 299:\n # horray! We found what we were looking for.\n return (resp.status, url, resp.reason)\n\n else:\n # Status unsure, might be, 404, 500, 401, 403, raise error\n # with actual status code.\n raise IOError, (resp.status, url, resp.reason)\n\n</pre>', 'title': u'Hmmm...'}], 'desc': u'Quickly find out whether a web file exists.'}, {'comments': [{'comment': u'If you don\'t like to have magic numbers sprinkled through your code...<br>\n<br>\n<pre>\nclass Temperature(object):\nequations = {\'r\': [1.8, 0.0, 0.0], \'c\': [1.0, 0.0, -273.15], \'f\': [1.8, -273.15, 32.0]}\n\n\tdef __init__(self):\n\t\tself.k = 0\n\n\tdef __str__(self):\n\t\treturn "%g K" % self.k\n\n\tdef __repr__(self):\n\t\treturn "Temperature(%g K)" % self.k\n\n\tdef __getattr__(self, name):\n\t\tif self.equations.has_key(name):\n\t\t\treturn (self.k + self.equations[name][1]) * self.equations[name][0] + self.equations[name][2]\n\t\telse:\n\t\t\treturn object.__getattr__(self, name)\n\n\tdef __setattr__(self, name, value):\n\t\tif self.equations.has_key(name):\n\t\t\tself.k = (value - self.equations[name][2]) / self.equations[name][0] - self.equations[name][1]\n\t\telse:\n\t\t\tobject.__setattr__(self, name, value)\n</pre>', 'title': u'Alternatively'}, {'comment': u'Thanks. Added that, plus a couple of optimizations. Dropped get/set methods.', 'title': u'Good idea'}], 'desc': u'Assign temperature value in one scale and you have it available in others as respective attributes. Kelvin, Celsius, Fahrenheit, and Rankine are supported (k, c, f, r attributes).'}, {'comments': [], 'desc': u"I used a URLOpener to get the HTML file from some web-sites for some parsing. However, the returned data file had ^M everywhere, and it was pretty annoying. Before parsing this file, I want to strip it of all occurences of this control character ^M. Of course, I can use dos2unix or similar tools to do that offline, but I wanna do it the pythonic way.\n\nFirst, I need to find out the ascii value for '^M'.\n\n>>> import curses.ascii\n>>> ascii.ascii('^V^M')\n'\\r'\n\nThen, I can just do a search and replace '\\r' in any string.\n\n>>> string.replace( str, '\\r', '' )\n\nIn my code, I just have this line in the overriden method handle_data of my html parser class."}, {'comments': [{'comment': u'<pre>I modified this program to add a randomizer and to make it only add files that include at least one of the <br>(optional) words at the end of the command line and to also add ogg files.\n\nI have a couple more ideas for features including: \n - allowing python regular expressions instead of search terms\n - limiting the playlist to a certain number of songs\n - limiting the playlist to a certain length in minutes and/or seconds\n - better ogg support and possibly other formats\n - adding CD burning support\n\nI have a feeling I will also use this to make a CGI program to create a playlist and either play it in xmms <br>or burn it to a CD, possibly even create a batch file/shell script to download the songs from the playlist.\n\nAnyway here is my code with the mentioned additions\n\nBlake Revai\n-----------\npsycosys[a]gmail.com\nhttp://www.thenme.net\n\n*begin code*\n\n#!/usr/bin/python\n\nimport os, sys, re, random, getopt, mad, ID3\n\n__doc__ = "Generate m3u playlists (default: local dir, sorted)"\n__author__ = r"Lawrence Oluyede , modified by Blake Revai "\n__date__ = "Jul 12 2004, modified Dec 22 2004 to add randomize, search and to also add oggs as well as mp3s"\n__version__ = "0.2mod1"\n\n"""\nA simple m3u file is like this:\n\n#EXTM3U\n#EXTINF:111,Coldplay - In Myplace\n/path/to/the/song/Coldplay - In My Place.mp3\n\n- #EXTM3U is the format descriptor (unchanging)\n- #Extinf is the record marker (with extended info, unchanging)\n- : is the separator\n- 111 is the length of the track in whole seconds\n- , is the other separator\n- the name of the track (a good generator parses the ID3,\n if there isn\'t an ID3 use the file name without the extension)\n- /path/etc. etc. is the absolute (or relative) path to the file name\n of the track\n\nRequirements:\n\n- Python 2.2\n- pymad for track length - http://spacepants.org/src/pymad/\n- id3-py for reading ID3 infos - http://id3-py.sourceforge.net/\n\n\n"""\n\nFORMAT_DESCRIPTOR = "#EXTM3U"\nRECORD_MARKER = "#EXTINF"\n\n\ndef _usage():\n """ print the usage message """\n msg = "Usage: python pyM3U.py [options] playlist_name [path] [PATTERN]\\n"\n msg += __doc__ + "\\n\\n"\n msg += "Only include files with at least one word from PATTERN in ID3 artist, title or filename.\\n"\n msg += "Example: python pyM3U.py playlist_name.m3u /path/to/mp3s music good \\n"\n msg += "This example creates a sorted playlist called playlist_name.m3u from any mp3s in /path/to/mp3s/ with the word \\"music\\" or \\"good\\" in the ID3 artist, title, or filename.\\n\\n"\n msg += "Options:\\n"\n msg += "%5s,\\t%s\\t\\t%s\\n" % ("-n", "--no-sort", "do not sort entries by filename")\n msg += "%5s,\\t%s\\t\\t\\t%s\\n" % ("-r", "--rand", "randomize list")\n msg += "%5s,\\t%s\\t\\t\\t%s\\n" % ("-w", "--walk", "walk into subdirs (default: no walk)")\n msg += "%5s,\\t%s\\t\\t\\t%s" % ("-h", "--help", "display this help and exit")\n\n print msg\n\ndef generate_list(name="songs_list.m3u", path=".",\n sort=True, walk=False, regExp="", rand=False):\n """ generates the M3U playlist with the given file name\n\n and in the given path """\n\n output = None\n try:\n try:\n if walk:\n # recursive version\n mp3_list = [os.path.join(root, i) for root, dirs, files in os.walk(path) for i in files if i[-3:] == "mp3" or i[-3:] == "ogg"]\n else:\n # non recursive version\n mp3_list = [i for i in os.listdir(path) if i[-3:] == "mp3"]\n\n #print mp3_list\n\n if sort and not rand:\n mp3_list.sort()\n\n output = file(name, "w")\n output.write(FORMAT_DESCRIPTOR + "\\n")\n\n\t if rand:\n\t\trandom.shuffle(mp3_list)\n\n for track in mp3_list:\n if not walk:\n track = os.path.join(path, track)\n else:\n track = os.path.abspath(track)\n # open the track with mad and ID3\n mf = mad.MadFile(track)\n id3info = ID3', 'title': u'I modified this to add a few things.'}], 'desc': u'With this script you can walk into tree subdirectories and generate a playlist (m3u format) that can be read with players like xmms, winamp and so on. \n\nThe description of the format is here: http://hanna.pyxidis.org/tech/m3u.html'}, {'comments': [], 'desc': u'This is a very basic example of how to launch an editor from inside a program. \n NOTE: a real script would have all sorts of error management wrapped around it, \nusing this as is may cause baldness, impotence, priapism or worse. \nWill not work for windows.'}, {'comments': [{'comment': u'Nice example. IMHO you should just change the B-Tree comment to binary tree, although this code can hold multiple info per node, it does *not* implement a B-Tree structure neither has its properties (like being balanced, having a maximum number of buckets per node and short in height).', 'title': u'Small suggestion'}, {'comment': u'thanks :)', 'title': u'Fixed'}], 'desc': u'A simple example demonstrating the construction of binary trees.'}, {'comments': [], 'desc': u'Those are a couple of multithreaded portscanners, the second one use the Queue module.'}, {'comments': [], 'desc': u'This script extracts contents of all verbatim environments from the LaTeX file specified on command line. Modified LaTeX code with \\verbatiminput commands instead of verbatim is produced on the standard output.'}, {'comments': [{'comment': u"When I tried your code, it seemed to be a bit more than twice the speed of the prime generator I wrote in http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117119 and (a somewhat more elaborate version) http://www.ics.uci.edu/~eppstein/PADS/Eratosthenes.py\n<br><br>\nOn the other hand, yours needs to know N in advance, while mine doesn't, and the PADS version of mine uses much less memory if you don't need to keep a list of all the primes you're generating (O(sqrt N) instead of O(N)). So both might be useful in different situations.", 'title': u'Does seem to be fast'}, {'comment': u"I'd suggest rewriting this as a generator, which would reduce the memory requirement as well as the issue of having to know N in advance.", 'title': u'Suggest rewriting this as a generator'}, {'comment': u"It's a nice algorithm when N is not too large, but can\nstill be speeded up (by 40-50% on my machine):<br>\n* Split the list into [primes], [candidates] so the\n x == i test can be removed from the inner loop and to\n reduce the size of all the lists that are produced.<br>\n* filter() can move the x % i test from Python to C code.<br>\n* Special-case small primes to save some speed and memory.<br>\n* Convert max to int, since integer comparison is faster\n than floating-point comparison (i > max).<br>\n<br>\nWhile I was at it, I fixed prime_numbers_less_than(5.2), and\nrenamed max to top since there is a built-in function 'max'.\n\n<pre>\ndef primes_less_than(N):\n N = int(N) + bool(N % 1) # Round up floating-point N\n primes = [x for x in (2, 3, 5, 7, 11, 13) if x < N]\n if N > 17:\n candidates = [x for x in xrange((N - 2) | 1, 15, -2)\n if x % 3 and x % 5 and x % 7 and x % 11 and x % 13]\n top = int(N ** 0.5)\n while (top+1) * (top+1) <= N:\n top += 1\n while 1:\n p = candidates.pop()\n primes.append(p)\n if p > top:\n break\n candidates = filter(p.__rmod__, candidates)\n candidates.reverse()\n primes.extend(candidates)\n return primes\n</pre>\n", 'title': u'Can still be speeded up.'}, {'comment': u'I wonder if this could be sped up even more by noticing that all primes are congruent with either 1 or 5 mod 6 and none are congruent with 0 mod 5. This reduces the number of candidate primes by about 50%, i.e. these conditions apply to only about half of the odd integers. BTW, I tried posting some code in here and got weird results. Can someone tell me why that is?', 'title': u'more speed...?'}, {'comment': u'"None (above 5) are congruent with 0 mod 5" is caught by the x % 5 test. "Congruent with either 1 or 5 mod 6" = "not congruent with 0 mod 2 or 3", which is caught by xrange(,,-2) combined with the x % 3 test.', 'title': u'Already done'}, {'comment': u'ah, I see that now...cleverly done...:-)', 'title': u' '}], 'desc': u'This function return a list of numbers which is less than argument.\nIt is much faster than other implementations which I test. At my machine, prime_numbers_less_than(100000) takes about 0.78sec.\nThis code is tested at Python 2.3.4 only.'}, {'comments': [{'comment': u"<pre>md5.md5('..').digest().encode('hex')</pre> &darr <pre>md5.md5('..').hexdigest()</pre>", 'title': u'Simpler MD5'}, {'comment': u'True, its more concise, I updated the recipe.\nThanks for the note,\n Nick', 'title': u'True, its more concise, I updated the recipe'}, {'comment': u'First, a nitpick: you don\'t need to pass the factory explicitly to the Protocol, or override buildProtocol like that. The default buildProtocol implementation will set the .factory attribute for you.\n\n<br><br>\n\nYou seem to be assuming that you only receive exactly one message from the server at a time, and never get partial or multiple messages at once, but there\'s no guarantee of that (although with such small messages it\'s unlikely).\n\n<br><br>\n\nAt a glance, it appears that perhaps twisted.protocols.basic.LineReceiver would be a better base class DIPProtocol, because it would handle these issues for you, and only trigger the lineReceived method with single, complete lines. (It\'s not clear from the spec you link to that it is a line-delimited protocol, but I\'m guessing it is from your implementation).\n\n<br><br>\n\nAlso, your "reqnum" instance variable seems to be misleadingly named; what you really want is a variable to keep track of protocol state, e.g. are you expecting a salt, or expecting a response to a previous request?\n\n<br><br>\n\nFinally, you\'re mixing mechanism and policy in your DIPProtocol class, which makes it difficult to reuse.\n\n<br><br>\n\nHere\'s how I\'d write that class:\n\n<pre>\ndef hashPassword(password, salt):\n p1 = md5.md5(password).hexdigest() + \'.\' + data.strip()\n return = md5.md5(p1).hexdigest()\n\nclass DIPProtocol(basic.LineReceiver):\n """ Quick implementation of GnuDIP protocol (TCP) as described here:\n http://gnudip2.sourceforge.net/gnudip-www/latest/gnudip/html/protocol.html\n """\n\n delimiter = \'\\n\'\n\n def connectionMade(self):\n basic.LineReceiver.connectionMade(self)\n self.expectingSalt = True\n\n def lineReceived(self, line):\n if self.expectingSalt:\n self.saltReceived(line)\n self.expectingSalt = False\n else:\n self.responseReceived(line)\n\n def saltReceived(self, salt):\n """Override this."""\n\n def responseReceived(self, response):\n """Override this."""\n\nclass DIPUpdater(DIPProtocol):\n """A quick class to update an IP, then disconnect."""\n def saltReceived(self, salt):\n password = self.factory.getPassword()\n username = self.factory.getUsername()\n domain = self.factory.getDomain()\n\n msg = \'%s:%s:%s:2\' % (username, hashPassword(password, salt), domain)\n self.sendLine(msg)\n\n def responseReceived(self, response):\n code = response.split(\':\', 1)[0]\n if code == \'0\':\n pass # OK\n elif code == \'1\':\n print \'Authentication failed\'\n else:\n print \'Unexpected response from server:\', repr(response)\n\n self.transport.loseConnection()\n</pre>\n\nAnd then make DIPFactory use DIPUpdater instead of DIPProtocol.\n\n<br><br>\n\nA further improvement might be to implement "updateIP" and "removeIP" methods on DIPProtocol, to make subclasses like DIPUpdater even easier to write.\n\n<br><br>\n\nOf course, this level of generalisation might be overkill for the cookbook ;)', 'title': u'Your dataReceived looks potentially buggy to me'}, {'comment': u'It\'s always surprising how open collaboration can improve things fast.<br><br>\n\nMy recipe was put together "quickly" as the title suggested.<br>\nIndeed your refactoring makes it more elegant and reusable.<br>\nI integrated it, tested it again, and updated it.<br><br>\n\nI had to pass the factory to the Updater anyway otherwise it could not find it.<br><br>\n\nThanks,<br>\n Nick', 'title': u"It's always surprising how open collaboration can improve things fast"}, {'comment': u'I will update the recipe shortly.', 'title': u'Forget my last remark. Of course passing the factory is not needed...'}], 'desc': u'Command line prototype to update a Dynamic DNS Service that\naccepts the GnuDIP protocol (like yi.org):\n\npydyp.py [-u uname] -w password [-s dipserver] [-p dipserverport] [-d domain]\n\nIt shows the power of Twisted framework.'}, {'comments': [], 'desc': u'This example is a simplified version of the irenderer example inside Nevow distrib by Matt Goodall (who deserves most of the glory for this example). It makes use of interfaces and adapters to render objects on a web page.'}, {'comments': [{'comment': u'If you like this HTML scraper also check out another great Python HTML/XML scraper called BeautifulSoup at: http://www.crummy.com/software/BeautifulSoup/', 'title': u'Another good scraper...'}, {'comment': u'If you are extracting information from a page BeautifulSoup offers a lot more functionality.<br>\n<br>\nI was just amending the contents of some tags and found that BS (including StoneSoup) made changes to the page as it went - including mangling the pages !! This recipe should allow you to change pages a lot more easily.', 'title': u'BeautifulSoup is Good'}], 'desc': u"A simple HTML 'parser' that will 'read' through an HTML file and call functions on data and tags etc.\nUseful if you need to implement a straightforward parser that just extracts information from the file *or* modifies tags etc.\n\nShouldn't choke on bad HTML."}, {'comments': [{'comment': u"The version saved over at voidspace includes my updated take on authentication - which saves the username/password temporarily and will fetch another page and automatically authenticate. You can download the updated version or try the online one. I'm not putting the changes here as this is already too big to be called a recipe....<br>\n<br>\nhttp://www.voidspace.org.uk/atlantibots/recipebook.html#http\n", 'title': u'Updated to Include Proper Authentication'}], 'desc': u"This CGI script allows you to specify a URL. It fetches the URL and displays all the headers sent by the server.\nIt is based on approx.py the CGI-proxy I'm building. It includes authentication circuitry and I'm using it to understand http authentication.\n\nThis script demostrates using urllib2 to fetch a URL - using a request object with User-Agent header. It also demostrates basic authentication and shows the possible http errors - using a dictionary 'borrowed' from BaseHTTPServer.\n\nIt will also save cookies using the ClientCookie module, if it's available."}, {'comments': [{'comment': u'Disclaimer: This comment is for the recipe "Cache function/method results" (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/298337). If it gets placed wrongly by the comment system, well it\'s not my fault.\n<br>\n1. No, it won\'t work without the makeImmutable. The keys of a dict must be immutable. If you wanted to skip the makeImmutable function, you\'d need to use a different structure than a dict, for example a list of key, value tuples. But then you\'d have to search through the list, a time consuming operation, which would certainly defeat the purpose of the caching. I used inspect.getmembers to get something immutable from other objects. It seems to work for me, but if anyone has a better trick, I\'d appreciate that.\n<br>\n2. The cached class only works with plain functions. If you try to wrap a method of a class into a cached object, you will find that your method turns into a staticmethod, that is, you have to feed the instance to it as a first argument. \n<pre>\nclass X:\n def method(sef, *args):\n ...\n method = cached(method)\n\ni = X()\ni.method(i, arg1, ...) # ok\ni.method(arg1, ...) # error\n</pre>\nThis yields an error, because method is called without self argument. To avoid this, I created a method:\n<pre>\nimport new\ndef cachedmethod(method):\n return new.instancemethod(cached(method), None, method.im_class)\n</pre>\nI can call this like:\n<pre>\nclass X:\n def method(self, *args):\n ...\nX.method = cachedmethod(X.method)\n</pre>\nThis function has to be called outside the class, because if it is placed inside the class, the class is not built and thus can not be referenced by new.instancemethod. Is there a better way to do this?', 'title': u'makeImmutable, class & instancemethods, etc.'}], 'desc': u'I use this for my database lookup function to minimize sql execution.\nIt can also be useful in other contexts.\nI think it work even without "make_immutable", but it\'s probably safer this way.\nThe class "DictTuple" is ugly. However, AFAIK, there are no ImmutableDict.'}, {'comments': [{'comment': u'Hi,\n\nThis code really helped me get started with webdav. I also wrote a small python class to give the same functionality as the xmlhttp com object. Have tested the code on Windows XP Service Pack 2 and also Red Hat Linux. Both seem to work fine. Let me know if you encounter any issues!\n<br><br>\nClass File\n<pre>\n\n# Create a class with the same functionality\n# as XMLHTTP\n\nimport httplib, base64, urlparse\n\nclass xmlhttp:\n\n def __init__ (self):\n self.__headers = {}\n\n def addHeader (self, name, content):\n self.__headers[name] = content\n\n def sendRequest (self, verb, url, request, username, password):\n\n # Encode the username and password as base 64. Remove the newline\n # which base64 puts at the end of the string\n upB64 = base64.encodestring(\'%s:%s\' % (username, password))[:-1]\n\n # Add the Authorisation header\n self.__headers[\'Authorization\'] = \'Basic %s\' % upB64\n\n # Parse out the URL in to components\n (scheme, netloc, path, params, query) = \\\n urlparse.urlsplit (url)\n\n con = httplib.HTTPConnection(netloc)\n con.request(verb, path, request, self.__headers)\n\n response = con.getresponse()\n\n return (response.status, response.reason, response.read())\n</pre>\n\nExample Usage\n\n<pre>\nimport ... xmlhttp ...\n\n...\n\n dav = xmlhttp.xmlhttp()\n dav.addHeader("Content-type", "text/xml")\n status, statustext, responseText = \\\n dav.sendRequest(\'SEARCH\', url, req, user, pwd)\n</pre>', 'title': u'xmlhttp without using win32 com wrappers'}], 'desc': u'If you want to talk to a MS exchange server, webdav offers a convenient way to do so. The code below shows the very basics for searching, deleting, and creating.'}, {'comments': [{'comment': u'That only works for lists, the Python implementation works for arbitrary sequences (anything iterable).', 'title': u' '}, {'comment': u'\nThe O(n(d+log d)) time is for *exact* decimal/binary\narithmetic.\n\nIn some cases, floating point manipulations are done with\na fixed maximum precision. After this precision,\ndigits are truncated. This could be called \n*truncated arithmetic*, and it would take O(nd) time\nto perform a regular Python sum() in this mode.\n\n - Connelly', 'title': u'Note on asymptotic time'}, {'comment': u'Nice recipe!\n\nA simpler, more precise (with slowly varying numbers), but slower and more memory-consuming version would be:\n<br>\n<pre>\ndef sum_with_partials(elements):\n if len(elements) == 1: return elements[0]\n return sum_with_partials(elements[::2]) + sum_with_partials(elements[1::2])\n</pre>\n\nThe advantage of this scheme is that only numbers with similar values are summed together, for smoothly varying elements; this precedure minimizes numerical errors, in floating-point arithmetic. In the original recipe, lists with 2**n+1 elements especially suffer from a loss of precision when the last element is added to the sum of all the previous ones.\n\n<br>\n\n(Side remarks: Speaking of speed, the original recipe is about 5x slower than the built-in sum with Python 2.4.2, on my machine--but the cost in time is certainly worth the price, in some situations.)', 'title': u'Simpler, more precise, but slower version'}, {'comment': u"I haven't checked to see what impact this has on the whole algorithm's performace, but 1<<10 is about 30% faster than 2**10 for me (python ought to optimise that one!) Also, you might save a bit by importing ceil and log into the module's namespace, rather than looking up two symbols each time.", 'title': u'Speed tips'}], 'desc': u'Built-in "sum" function, as well as add.reduce functions in Numeric/numarray introduce a large error when summing large arrays of like elements. I got relative error of about 1e-9 after summing 10 million doubles between 0 and 1. Function below has error less than 1e-15, doesn\'t use any additional memory (although it destroys the data array), and also runs asymptotically faster for unlimited precision numbers.'}, {'comments': [{'comment': u'You can reach me(the author) at pyguy2 on yahoo', 'title': u'I am pyguy2 on yahoo'}, {'comment': u'Hi,\n\nThis code really helped me get started with webdav. I also wrote a small python class to give the same functionality as the xmlhttp com object. Have tested the code on Windows XP Service Pack 2 and also Red Hat Linux. Both seem to work fine. Let me know if you encounter any issues!\n<br><br>\nClass File\n<pre>\n\n# Create a class with the same functionality\n# as XMLHTTP\n\nimport httplib, base64, urlparse\n\nclass xmlhttp:\n\n def __init__ (self):\n self.__headers = {}\n\n def addHeader (self, name, content):\n self.__headers[name] = content\n\n def sendRequest (self, verb, url, request, username, password):\n\n # Encode the username and password as base 64. Remove the newline\n # which base64 puts at the end of the string\n upB64 = base64.encodestring(\'%s:%s\' % (username, password))[:-1]\n\n # Add the Authorisation header\n self.__headers[\'Authorization\'] = \'Basic %s\' % upB64\n\n # Parse out the URL in to components\n (scheme, netloc, path, params, query) = \\\n urlparse.urlsplit (url)\n\n con = httplib.HTTPConnection(netloc)\n con.request(verb, path, request, self.__headers)\n\n response = con.getresponse()\n\n return (response.status, response.reason, response.read())\n</pre>\n\nExample Usage\n\n<pre>\nimport ... xmlhttp ...\n\n...\n\n dav = xmlhttp.xmlhttp()\n dav.addHeader("Content-type", "text/xml")\n status, statustext, responseText = \\\n dav.sendRequest(\'SEARCH\', url, req, user, pwd)\n</pre>', 'title': u'xmlhhtp without win32com'}], 'desc': u'Webdav is useful to get information on something in exchange. Often you need to know what you can ask for. Here is a simple recipe to get a list of the attributes available for a specific item. '}, {'comments': [{'comment': u"This class, with some improvements and fixes, is now part of Amara's saxtools:\n\nhttp://www.xml.com/pub/a/2005/01/19/amara.html\n\n--Uche", 'title': u'Updated version of code in Amara XML Toolkit'}], 'desc': u'This module is similar to pulldom in that it takes a stream of SAX objects and breaks it down into chunks of DOM. The differences are that it works with any DOM implementation meeting the Python DOM conventions, and that it uses simple pattern expressions to declaratively set how the DOM chunks are partitioned, rather than requiring the user to write procedural code for this purpose. This is an updated/fixed version of code that appeared in an XML.com column.'}, {'comments': [{'comment': u' I updated this example to fix a bug in xmlElement.getFirstChildByName() and moved the depth-first-search into its own class making it a cleaner way to use it.', 'title': u'Updated on 2004/10/04'}], 'desc': u"I updated John Bair's xml2obj to allow better support of actually parsing xml files. Some of the information for this came from Uche Ogbuji's articles on the web. Enjoy."}, {'comments': [], 'desc': u'Make a wxPython application also acting as a XML-RPC server, listening to a dedicated port.\nFor example a GUI logging application, where logging messages come from other applications via xml-rpc calls.'}, {'comments': [], 'desc': u"The winnow class uses a heap for finding the best few out \nof several items. At this it is quicker and shorter than \npython 2.3's heapq module, which is aimed at queuing rather \nthan sifting. OTOH, it is unlikely to have any advantage over\n2.4's heapq, which (I hear) has expanded functionality and is\nimplemented in C. "}, {'comments': [{'comment': u'What is the advantage of this over base64? For instance:\n\n<pre>\n>>> src = hexstring2string("432cc46b5c67c9adaabdcc6c69e23d6d")\n>>> src.encode(\'base64\').replace(\'\\n\', \'\')\n\'QyzEa1xnya2qvcxsaeI9bQ==\'\n</pre>\n\nBase64 strings can contain \\n\'s, which is inconvenient in many contexts, but the decoding process ignores their presence so they can simply be removed.<br><br>\n\nIn hexstring2string, it is faster to turn a hex pair into a character with chr(int(s[i:i+2], 16)). My benchmarks show it makes that function almost 10x as fast with that change. Use of eval is usually a bad sign -- there\'s almost always a better (faster, safer) way to do it.', 'title': u'base64'}, {'comment': u"It's really only useful, when presenting digests to humans. bubblebabble looks like a series of words (of a strange language). base64 is even worse as one now has to differntiate between 1 and l, 0 and O....\nhexstring2string can also be replaced by binascii.unhexlify.", 'title': u' '}], 'desc': u'This module provides a bubblebabble function, which computes a (somewhat more) human readable format for message digests.'}, {'comments': [{'comment': u'Please ignore the classname comment at the top of this code. I copied the comments from another class and forgot to make the change.\n', 'title': u'Typo in comments'}], 'desc': u"I was finding that I needed a progress indicator for Linux and Windows console applications that could be used to show the user that work was progressing and how much of the total work that had been completed. I finally broke down and wrote this class that seems to do exactly what I wanted. Since I continue to see questions about how to write such a class on Comp.Lang.Python, I thought I'd donate it to this Cookbook archive."}, {'comments': [], 'desc': u'You want to always keep a copy of your config files, just in case...'}, {'comments': [{'comment': u'may i suggest you deemphasize the "chown root may i suggest you deemphasize the "chown root ', 'title': u'not a security measure'}, {'comment': u'may i suggest you deemphasize the "chown root; chmod 700" which removes the need for your recipe.\n<br><br>\nchown and chmod are real security measures. checking if a user is root is a courtesy. please don\'t confuse recipe users about the two.\n<br><br>\nif a script is owned by root and only accessible to root, there\'s no reason to check the uid of the executing user. and if the user can read the script, they can always copy it elsewhere, remove the uid check, and run the script. and then there\'s always debian\'s fakeroot which allows a user to execute an application impostering to the application (but not the operating system) as root.\n<br><br>\ni frequently see uid checks imployed within debian init scripts to avoid a user from starting a service which can partially run as non-root (writing temporary files, binding to a port greater than 1024), but in some way fail (unable to read privileged files), leaving the service started but in a broken state. i appreciate these checks when i stupidly try to run an init script from my normal user account, having forgotten to "su" or "sudo" first.\n<br><br>\nthanks for showing a python implementation of what is commonly done in shell, as i\'m familiar with the shell, but still learning how to do similar things in python.\n<br><br>\nps what\'s up with all the random comments from other recent python recipes (irc and tar)?', 'title': u"let's try again, dang it"}, {'comment': u'chown and chmod don\'t removes the need for this recipe, imho.\n\nif your script is readable by everyone they can just copy and paste in a new file for example and "maybe" do something they are not suppose to do....\n\nAs sysadmin I\'ve learned not to trust 100% users.... :)\n\nAnyway thanks for your comment, they are always appreciated.', 'title': u'explanation'}, {'comment': u'Checking for root can still be useful if, for example, you want to check whether a user has the privilege to bind a socket to a port less than 1024. In this case, you can generate a useful error message beforehand, rather than just trying and having the bind command fail.', 'title': u'Checking For Root Can Still Be Useful'}], 'desc': u"You don't want that a user can run a particular script, just add this two lines at the beginning of your code."}, {'comments': [{'comment': u"<pre>\nfrom twisted.internet import reactor, protocol\nfrom twisted.protocols import irc\n\nclass LoggingIRCClient(irc.IRCClient):\n logfile = file('/tmp/msg.txt', 'a+')\n\n nickname = 'logging_bot'\n\n def signedOn(self):\n self.join('#test_py')\n\n def privmsg(self, user, channel, message):\n self.logfile.write(user.split('!')[0] + ' -> ' + message + '\\n')\n self.logfile.flush()\n\ndef main():\n f = protocol.ReconnectingClientFactory()\n f.protocol = LoggingIRCClient\n reactor.connectTCP('irc.freenode.net', 6667, f)\n reactor.run()\n\nif __name__ == '__main__':\n main()\n</pre>", 'title': u'Shorter, more featureful example'}, {'comment': u"Thank's for you comment but the great twisted package is not part of the standard distribution, the meaning of this recipe is how to use sockets to connect an IRC server using only std python code.", 'title': u'twisted is not part of std python'}], 'desc': u"You want to connect to an IRC server, join a channel and store private message into a file on your hard disk for future reading.\nI haven't tried but I think you can execute this code from an hosting always connected to the internet and read the message through a web browser.\n"}, {'comments': [{'comment': u"<pre>\nimport tarfile, os\n\ndestination = 'F:/test.tar.bz2'\nfileorfoldertobackup = './pgaccess'\n\nout = tarfile.TarFile.open(destination, 'w:bz2')\nout.add(fileorfoldertobackup, arcname=os.path.basename(fileorfoldertobackup))\nout.close()\n\n\n\nRavi Teja Bhupatiraju.\n<pre></pre></pre>", 'title': u'Some Corrections!'}, {'comment': u'<pre>\nNot sure how my comment ended up here. I posted it for\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/299412\n</pre>', 'title': u'???'}, {'comment': u'I made some changes to the recipe to reflect your suggestions- most notably that I left out the import statements. Doh!', 'title': u'Changes Made'}, {'comment': u"The main change I was suggesting was the unbound variable dst ( as I remember ) in the previous script.\n\nAnother is addfile does not work on my system (XP Home, Python 2.3.2). Didn't check why. add works for me.\n\nA bug in the new script is you have os.path.base.basename. Should be os.path.basename.\n\nOne of those days! Huh?", 'title': u'More changes!'}], 'desc': u'I was working on a backup utility to compress files and folders into a .tar.bz2 file and found the documentation and internet info to be a bit lacking. So here is an example for those that tackle this in the future.\n\nI initially thought, "Hey, there is a \'tarfile\' module and a bz2 module, so I am good to go." Not that easy. The bz2 module does not accept tarfile objects for compression. I hunted around the documentation a and found that bzipping is part of an \'open\' class method for a tarfile. But once you make a tarfile.TarFile object, it is too late. Instead, you have to create the tarfile object with \'tarfile.TarFile.open(destination, \'w:bz2\'. So here is an example.'}, {'comments': [], 'desc': u'A parser I designed to work with HIPAA EDI files. It reads in files and spits out the individual segments without terminators.\n\nRequires Python 2.3 or greater. (Use can probably use Python 2.2 with from __future__ import generators at the top...)'}, {'comments': [{'comment': u"Consider Foo['keys'] == 5. Now you've clobbered your keys method. That's the reason why attribute access and dictionary lookup are separate mechanisms and have separate namespaces. Generally dictionaries should be used for arbitrary fields.", 'title': u'Care needed with allowing arbitrary attributes to be set'}], 'desc': u'Often you want to just create an instance with nothing in it, then modify arbitrary values. According to the standard you should do:\nclass Something:\n pass\nI propose the following better solution:'}, {'comments': [{'comment': u'What is implemented here is *not* coroutines, but rather what I called "weightless threads" in my article:<br><br>\n\n http://www-106.ibm.com/developerworks/library/l-pythrd.html<br><br>\n\nHowever, you *can* implement SEMI-coroutines using a slightly different technique; I described this in:<br><br>\n\n http://www-106.ibm.com/developerworks/library/l-pygen.html#h3<br><br>\n\nThe examples in both of these articles are quite a lot shorter than in this recipe, while being just as powerful (if not more so).<br>', 'title': u'NOT coroutines!'}, {'comment': u'I have expanded the description and the discussion of this recipe. I hope this leaves no doubt what this code is and what it does.', 'title': u' '}, {'comment': u'I think that as of now this recipes still is not talking about coroutines. <br>\nCoroutines, in my understanding, are just explainable like \n"functions that save control state between calls and can be called many times".\n<br><br>\nThere is not point at all in having a scheduler, cause that does not relates with the concept of coroutines. <br>\nThe only implementations of coroutines I can think of in python are available in Stackless, at least until GvR does not give us callcc :)', 'title': u'still not right, imo'}], 'desc': u'This recipe shows how you can emulate coroutines in pure Python using generators.\n\nWith coroutine I mean a construct as available, for example, in Simula 67 or Modula2. They are like threads with two additional restrictions: at most one coroutine can be running at any time, and each coroutine yields control only at very specific points. Other terms I have heard for this concept are "cooperative multitasking", "non-preemptive multitasking" or Fibers (on Windows).\n'}, {'comments': [], 'desc': u'Given an object, this tool throws up a gtk tree widget that maps all the references found. It dynamically builds the tree, which means it can handle large amounts of data and circular references.'}, {'comments': [], 'desc': u'equivalent to doing\n $ find -name "*ext" -exec (some python function) {} \';\''}, {'comments': [{'comment': u'When I execute this program, it shows me the following error...<br> <br>\n\n proxy.connect((phost,pport)) <br>\n File "", line 1, in connect <br>\ngaierror: (7, \'getaddrinfo failed\') <br>\n <br>\nHow should I fix this ?', 'title': u'Error...'}, {'comment': u"Did you change the following to a meaningful hostname?\n\n<pre>phost='proxy_host'</pre>", 'title': u' '}, {'comment': u"This code looks like soemthing I am trying to tackle, so I thought I would look at this code. In summary, we need to CONNECT to an HTTPS url via a proxy. Anyway, I tried this code, taking care to update the phost and pport to match the proxy I need to go through. I also updated the user name and password to my username and password on yahoo. Anyway, in short, the proxy socket connection works fine and the CONNECT request comes through with status 200, so far so good. But when the socket.ssl connection is attempted, I get the following error:\n\nsslerror (8, 'EOF occurred in violation of protocol')\n\nand of course the program aborts. Any idea as to the cause? Thanks.", 'title': u'Having problems creating ssl connection to proxy'}, {'comment': u'I had this problem using Python 2.4 / windows, through to a Microsoft ISA proxy. The problem turned out to be caused by later versions of SSL. I downloaded M2Crypto (windows installer available) thanks to Ng Pheng Siong, which provides SSL version 3. M2Crypto is compatible with the Microsoft ISA proxy server (and I believe squid). The M2Crypto distribution contains a working proxy client in the contrib directory.<br><br>\n\nI ran straight into a problem with authentication. Luckily the latest version of pywin (204) contains an SSPI library (windows only) which can authenticate with the proxy server. ', 'title': u'ssl connection problems'}, {'comment': u'This is a error message after i execute the program, where is problem ?<br>\n<br>\nTraceback (most recent call last):<br>\n  File "Q:\\urllib\\test2.py", line 23, in ?<br>\n    ssl = socket.ssl(proxy, None, None)<br>\n  File "C:\\Python\\lib\\socket.py", line 73, in ssl<br>\n    return _realssl(sock, keyfile, certfile)<br>\nsocket.sslerror: (8, \'EOF occurred in violation of protocol\')<br>', 'title': u'Error message'}, {'comment': u'Very sorry all, my problem is probably same as problem in previous comment.<br>\nNow I have problem with M2Crypto. If I want used it, I see folowing error:<br>\n<pre>Traceback (most recent call last):\n File "", line 1, in ?\n File "C:\\Python\\lib\\site-packages\\M2Crypto\\__init__.py", line 7, in ?\n import __m2crypto\nImportError: No module named __m2crypto</pre>\n\nI download M2Crypto from M2Crypto webpage, but __m2crypto.py not in build\\lib.win32-2.3\\M2Crypto directory.', 'title': u'Sorry'}, {'comment': u"Hello all, problem with this error is here:<br>\nproxy.sendall(proxy_pieces+'\\r\\n')<br>\n<br>\nThis is fixed:<br>\nproxy.sendall(proxy_pieces)<br>\n<br>\n<br>\nProblem is in three end of lines in request. The request must include only two end of lines.", 'title': u"(8, 'EOF occurred in violation of protocol')"}, {'comment': u'I removed that small bug, thanks for noticing it.', 'title': u'I removed redundant \\r\\n'}, {'comment': u'Would you care to post your solution? Or, alternatively, email me?\nThanks,\nVlad', 'title': u'The problem'}], 'desc': u'This is just about the most simple snippet of how to do proxy authentication with SSL using python. The current httplib only supports ssl through a proxy _without_ authentication. This example does basic proxy auth that a lot of proxy servers can support. This will at least give someone an idea of how to do it and then improve it and incorporate it however they want.'}, {'comments': [{'comment': u"For example:\n<pre>\n>>> nprint(1234.567)\n'1.0 234'\n>>> nprint(-1234)\n'-1234'\n</pre>", 'title': u'Problems with negative numbers and floating point values.'}, {'comment': u'But there is no correct way for printing floating point values so now only integers are allowed.', 'title': u'Thanks!'}], 'desc': u'Some examples:\n\n>>> nprint(9876543210)\n\'9 876 543 210\'\n>>> nprint(987654321, period=1, delimiter=",")\n\'9,8,7,6,5,4,3,2,1,0\''}, {'comments': [{'comment': u'Python should be simple. This python code is not simple enough.', 'title': u'This python is not simple enough'}, {'comment': u'I add the above comment to "Decorator for appending author info to the function docstring (Python 2.4)", but why it\'s here?', 'title': u' '}], 'desc': u'Some examples:\n\n<pre>\n>>> @author("John")\n... @author("Paul")\n... def test():\n... "Test function"\n...\n>>> help(test)\nHelp on function test in module __main__:\n\ntest()\n Author: John\n Author: Paul\n Test function\n</pre>'}, {'comments': [{'comment': u'another implementation:\n\n<pre>\ndef chop(lst,chunksize):\n\t\n\tx = 0\n\tret = []\n\twhile x another implementation:\n\n<pre>\ndef chop(lst,chunksize):\n\t\n\tx = 0\n\tret = []\n\twhile x </pre></pre>', 'title': u'another option...'}, {'comment': u'Not sure what happened there... ASPN seems to have mangled my post...', 'title': u' '}, {'comment': u"<pre>>>> cf= lambda s,p: [ s[i:i+p] for i in range(0,len(s),p) ]\n\n>>> cf('1a2b3c4d5e6f',2)\n['1a', '2b', '3c', '4d', '5e', '6f']\n\n>>> cfi= iter(cf('1a2b3c4d5e6f',2))\n>>> [ i for i in cfi ]\n['1a', '2b', '3c', '4d', '5e', '6f']</pre>", 'title': u'list comprehension (abstraction)'}], 'desc': u'Example:\n<pre>\n>>> list(splitIterator("102030405", 2))\n[\'10\', \'20\', \'30\', \'40\', \'5\']\n</pre>'}, {'comments': [{'comment': u"Being in the python email filter business for quite some years now,\nI have to admit, that this is a very nice receipt!<br><br>\n\nWhile studying it, I asked myself, what will happen, if a multipart mail contain some good and some bad attachments (given, one will keep the good one's...).<br><br>\n\nAs far as I understand the script, any good attachment will be lost in presence of a bad one, since then the type is forced to text/plain or am I plain wrong?", 'title': u'some good and some bad attachments'}, {'comment': u"I'm not sure I understand your example and I am not familiar with processing email. But anyway, thanks for the 'nice receipt' comment, I understood that.\n<br><br>\nIf I get it right, you are thinking of a handler stack filtering one email, with a different handler for each attachment type. This is as opposed to the handler stack filtering each attachment at a time.\n<br><br>\nWith that assumption, a filter that detects a bad attachment doesn't have to return 'False' and thus stop all the other filters above it from processing the email. It can return 'True' and if it cannot just remove the bad attachment (here is where my lack of knowledge on processing email shows) it can at least pass some data up to the other handlers. You then need a handler at the top of the stack that uses that data and knows what to do with bad attachments, independently of their type.\n<br><br>\nDoes this answer your comment?", 'title': u'Re: some good and some bad attachments'}, {'comment': u'"I\'m not sure I understand your example and I am not familiar with processing email." I think Peter-Hans\'s comments actually belong to another recipe (#302086). There have a number of occasions recently where the Cookbook system has mixed up comments in this way.', 'title': u'Mixed-up comments'}, {'comment': u'... for getting your name the wrong way round.', 'title': u'Sorry, Hans-Peter'}, {'comment': u"You're right. Hans-Peter's comment showed up in my recipe (#302422). All these comments now show in both recipes.\n<br><br>And I thought I got a positive comment. I'm crushed. ;-)", 'title': u'Re: Mixed-up comments'}, {'comment': u"Obviously, all comments appear in both recipes: #302422 and #302086 (at least). Until ActiveState fix up this mess, I urge everybody to mention the commented recipe in the title.<br><br>\n\n@Hamish: Thanks for uncover this problem. I'm not sure, if I would have figured this out myself.<br><br>\n\n@Dan: This hazard brought your recipe to my attention, and will soon fit some of my problems to solve, I'm sure ;-)<br><br>\n\nI very much like the idea of concatenating handler objects via an overloaded __add__ method. Well done! I vote for including your recipe into the second edition and hope, this comment will rectify the confusion a bit.<br><br>\n\nPete", 'title': u'#302422 is very nice, too'}, {'comment': u'I assume you mean what will happen if there\'s a multipart/alternative with one good and one bad subpart. In that case, the bad subpart will be replaced with a text/plain saying "Neener neener I ate your attachment" (or whatever value you choose to use for the ReplaceString). \n\nYou _could_ make it modify the message so that if there\'s only a single "good" alternative left, it gets rid of the multipart/alternative and moves the good subpart into the enclosing Message directly. I\'m not sure that\'s a good idea, as it hides information (that the message was modified).', 'title': u'multipart'}, {'comment': u'How would one go about saving the attachment instead of replacing it with text?', 'title': u'what about not deleting the attachment??'}], 'desc': u'This recipe shows a simple approach to using the Python email package to strip out attachments and file types from an email message that might be considered dangerous. This is particularly relevant in Python 2.4, as the email Parser is now much more robust in handling mal-formed messages (which are typical for virus and worm emails)'}, {'comments': [], 'desc': u'Python 2.4 introduces a new threading.local() type - a thread local storage. This is a simple demonstration of this.'}, {'comments': [], 'desc': u'A simple 94 lines of code "chat" server with various questions and tips for beginner pythoneers. '}, {'comments': [], 'desc': u'Handles arguments for small scripts that need to:\n- read some command line options\n- read some command line positional arguments\n- iterate over all lines of some files given on the command line, or stdin if none given\n- give usage message if positional arguments are missing\n- give usage message if input files are missing and stdin is not redirected'}, {'comments': [{'comment': u"The conception which proposed by candygram is look very attractive, but when i'm try to implement real application on it i'm face with the problem of integration two event loops: one in wxPython and one provided by candygram. How to vercome this difficulty.", 'title': u'Integration with GUI and event frameworks'}], 'desc': u'With the Candygram package [ http://candygram.sourceforge.net ], developers can send and receive messages between threads using semantics nearly identical to those in the Erlang language [ http://www.erlang.org ]. Erlang is widely respected for its elegant built-in facilities for concurrent programming.\n\nThe beauty of the Erlang system is that it is simple and yet powerful. To communicate with another thread, you simply send a message to it. You do not need to worry about locks, semaphores, mutexes, etc. to share information among concurrent tasks. Developers mostly use message passing only to implement the producer/consumer model. When you combine message passing with the flexibility of a Receiver object, however, it becomes much more powerful. For example, by using timeouts and message patterns, a thread may easily handle its messages as a state machine, or as a priority queue.\n\nFor those who wish to become more familiar with Erlang, http://www.erlang.org/download/erlang-book-part1.pdf [Concurrent Programming in Erlang] provides a very complete introduction. In particular, the Candygram package implements all of the functions described in chapter 5 and sections 7.2, 7.3, and 7.5 of that book. '}, {'comments': [{'comment': u'Did you see this sample on the cookbook done using raw ctypes?\nhttp://aspn.activestate.com/ASPN/Cookbook/PHP/Recipe/302089\nEric', 'title': u'Connecting to running instances of IE on your computer'}, {'comment': u'Is it possible to put a sample test after if __name__ == "__main__":\non how to use it?\n\nEric', 'title': u' '}, {'comment': u'No, but thanks for pointing me to it!\nI have another program Pamie that controls and instance of a browser\nso my example is just bacially using the same code.\n\nhttp://pamie.sourceforge.net', 'title': u'RE: Connecting to running instances of IE on your computer'}, {'comment': u'I know, the rest of the code for the test got cut off. Unfortunately\nI never went back to fix it. \n\nThanks\nRob', 'title': u'Is it possible to put a sample test after if __name__ == "__main__": '}, {'comment': u'I figured this example would be useful for those that are involved in browser testing. ', 'title': u' RE: Connecting to running instances of IE on your computer,'}], 'desc': u'This is an tool for automating the browser via shellwindows. \nThis class file will allow a user to find any "OPEN" browser window and automate it.\n\nYou can access an "open" browser window, set the text in the Textbox, Select a List item or Click a forms submit button.\n\nenjoy \nRLM\n'}, {'comments': [{'comment': u'The test.py authentication-handler needs a req.write() when return non-OK status code, otherwise, apache will deliver a header with a 401, but in the body return the requested document! (visible if you sniff the network, or using a custom browser, or more critically if you press "cancel" on the provided dialog box (Firefox/IE).\n\nI enclose the whole of the file, as it\'s easier to see with markup\n\n<pre>\nfrom mod_python import apache\n\nimport digestauth\n\nrealm = "Restricted Area"\n\nusers = {\n"user":"password"\n}\n\ndef authenhandler(req):\n authheader = req.headers_in.get("Authorization", "")\n da = digestauth.DigestAuth(realm, users)\n code, headers, req.user = da.authenticate(req.method, req.uri, authheader)\n for k, v in headers:\n req.headers_out.add(k, v)\n if code == 200:\n return apache.OK\n else:\n req.status = code\n req.write("""Sorry. \n You need to provide adequate credentials to view this.\n """) \n # or some other message to stop \n # apache from doing the default \n # - delivering the requested document anyway!\n return apache.OK\n</pre>', 'title': u'patch: authentication-handler needs req.write()'}, {'comment': u"If writing back your own error response content from an authenhandler in mod_python, you should be returning apache.DONE to avoid Apache adding its own on the end.\n\nYou don't specifically need to write your own error response content anyway. The reason the original code possibly failed is that it was adding the 'WWW-Authenticate' header to req.headers_out and not req.err_headers_out. As a consequence Apache would have ignored it when using its own error response.", 'title': u'Use req.err_headers_out.'}], 'desc': u'(Incomplete) Python implementation of Digest Authentication \n\nUpdate: It works now (with IE as well) and all relevant code has now been wrapped into the class so basically all you need is feed it the Authorization-header. Unfortunately this means no CGI on apache.'}, {'comments': [{'comment': u"Have you considered working up a patch to add this to the stdlib's textwrap module?", 'title': u'adding this to the stdlib'}, {'comment': u'Args is about input, textwrap is about output. They have very different purposes.', 'title': u' '}, {'comment': u'Considered? Yes. Found the time to? No.', 'title': u' '}, {'comment': u"George Sakkis submitted a similar recipe ( http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/267662). I gussied it up a bit, added some features and more comments. I think it's quite usable now. (I didn't want to just paste the text into a comment, though). There's likely other simialr recipes as well. If there's talk of adding to the standard lib, how 'bout trying to get the best of all our efforts?", 'title': u'Combining efforts'}], 'desc': u'This code formats a number of columns of text into fixed widths. Each column may also be aligned independently. Whitespace is collapsed, though line breaks are retained (they may optionally be ignored).'}, {'comments': [{'comment': u'Great code. I picked up a few new Python tricks, thanks! I hope your fmf project goes well.\n\nDerrick', 'title': u'Great Contribution'}, {'comment': u"Thanks, Derrick. From your mentioning my project I figured that this time the comment is really addressed to me (for recipe #302422). But these comments are still getting posted also to another recipe (#302086). I sent a comment to Support and let's hope that they will fix it. I also hope that Derrick's comment will not get lost with the fix. Hear that, Support people? ;-)", 'title': u'RE: Great Contribution'}, {'comment': u'Looks like a powerful use of overloading, but a single, perhaps obvious, question: all handlers in a stack have as their "data" member an alias to the same dictionary, right? Would be a useful clarification for some of us. Thanks in advance.', 'title': u'Question on #302422 Handler Stack'}, {'comment': u"You're right about the 'data' dictionary and you're right that it deserves an explanation, so I have changed the 'Discussion' to include that. Thanks for your comments.\n<br><br>\nWhile we are on the topic of changes, I should mention that I have made a few changes to the code since the initial submission. The more important ones are that I got rid of 'nextHandler' and 'data' as class attributes and I initialize them only as instance attributes. I decided it's better to avoid the class attributes altogether and initializing 'data' as a class attribute was actually a bug. I also added the raise of an exception in the __add__ operator if the argument is not a Handler instance. Such a wrong use of the __add__ operator was raising an exception anyway, but that exception was kind of confusing for debugging.", 'title': u'Re: Question on #302422 Handler Stack'}, {'comment': u'First, Dan, thanks. Second, a couple small things have popped into mind:\n\n1) The class looks much better now that data is an instance variable...as you mention on your fmf project site, in some ways this shares a lot in common with a "chain of responsibility" pattern, but with a shared dictionary, no "buck stops here rule" and the possibility of additional handler-specific data this "handler stack" is nicely suited for broader situations. \n\n2) A small, somewhat quibbling thought, for C++ users this would seem like an appropriate place to use an iostreams style bit shift operator overload... perhaps less confusing to leave the code as is, but unlike the addition operator, the bitshift operator makes it visually clearer (for c++ or shell script users, anyway) which element is where in the hierarchy of handlers. Obviously you use __add__ in your fmf project, but having __lshift__ = __add__ in the recipe might be a possibility if you aren\'t reserving the operator.\n\n3) Depending on how confident you are in your users\' capabilities, you might want to throw in an exception check to make sure that a handler never becomes its own parent. The occasional sanity check never hurts...\n\n4) Again, this may be more trouble than it\'s worth--or run against the grain of your idea--but let\'s say that I want to create a complex set of handlers that, say, logs to a logfile (handler "l") and fills in class data (handler "c") based on file input (read in by handler "f"). Currently, I could stack handlers so that l = l + c + f and get the desired results. But what if I wanted to log all commands in the file but eliminate unsupported inputs by means of an intermediate (handler "p", proxy) that failed on encountering unsupported file data chunks. It would be nice to be able to do l + f and then c + p + f with the result that I create a complex, branched handler stack sharing a dictionary and instance of handler f\'s class between two filter chains. However, the current setup causes f to take c + p \'s data dictionary instead of l\'s so that I would be forced to create a seperate instance of f\'s class for the second stack. If the size of the data dictionary grows large (i.e. reading in large data sets from nested file formats), keeping multiple copies or running multiple pass through input data could quickly start chewing up lots of memory/time. It might be helpful if the Handler and the nextHandler took on a merged value if their dictionaries differed rather than Handler dictating the contents of nextHandler\'s dictionary outright. Alternately, you could create a way to initialize new handler instances so that they used a preexisting stack\'s data. This way we could initialize handler c with its data dictionary set to be the same as handler l\'s and thereby avoid needless duplication of data in memory, though multiple passes through data might still be necessary. (Obviously you could force this by simply setting data equal to the desired dictionary, but if you decide to obscure access to the data dictionary at a later point, it would be easier to have an approved way to do this now). These adjustments would allow users to build up some fairly elaborate "filter graph" style setups very elegantly. \n\nJust some thoughts,\nLJ', 'title': u'Thanks, and a few more thoughts...'}, {'comment': u"All great comments. The suggestions you're making are more relevant for my fmf project, I think the recipe is long and complex enough as it is. BTW, thanks for taking a look also at my project and this gives me a clue that I should add a contact info on the web site. Everyone, please use that contact for comments on my project if they are beyond the scope of this recipe.\n<br><br>\nGood point about the '__lshift__' vs. the '__add__' operators. The direction of the flow is not obvious with '+'. I'm not going to change it yet though, let's see what other people suggest. I agree that '__lshift__' would be more suggestive than '__add__' (at least to some people), but maybe someone will come up with something even better. Anyway, I would keep only one of them, it is confusing to have 2 operators for the same thing.\n<br><br>\nThe elaborate 'filter graph' is something that I will probably have to address in the future, in my project. For now, I have a configuration mechanism that needs work even with a simple stack like this. Very good point about the need for more flexibility in setting the common 'data' dictionary and therefore the need for a method to set it outside of the '+' operator. Thanks, LJ.", 'title': u'Re: a few more thoughts...'}, {'comment': u'You have changed the meaning of the + operator here. The accepted meaning is "add these two items together without modifying either one, and return the result." The way you are using it means "modify B by adding A". As there is already an accepted operator for that (+=), I strongly suggest you implement __iadd__ (for A += B) instead of __add__.', 'title': u'+ is confusing and unnecessary'}, {'comment': u"I am beginning to see even more that using the '+' operator may be confusing to some people. LJ's suggestion to use '__lshift__' is becoming more tempting, but an argument similar to yours can be made also against that operator.\n<br><br>\nBTW, I agree with you that this use of '+' is changing its sense and that may be a source of confusion. However, I would not replace it with '__iadd__' either because that would eliminate the creation of an entire stack in one line, like 'a+b+c+d+e'. And if I would go that way, I would rather just use a function, like a.append(b) or a.setNextHandler(b).\n<br><br>\nI guess that a compromise would be to change '__add__' to create a new Handler instead of changing the existing one in-place. That would eliminate some of the usages in the discussion, but that would be preferred if it also eliminates some confusion. The issue then is how to create a copy of a Handler. A copy constructor should be useful anyway and such a complete solution should definitely be considered in a real case implementation, but I think it would be too much for this recipe.\n<br><br>\nI'll still leave it as an open issue for now.\n<br><br>\nSide note: This discussion has given me the idea of making the stack iterable and adding an iterator for it (or making it its own iterator), but this would also be too much for the recipe.", 'title': u'Re: + is confusing and unnecessary'}, {'comment': u"I am adding an alternative to the + (__add__) operator because that seems to be an element of confusion:<pre>\n def makeStack(self,*args):\n hList=[self]\n hList.extend(args)\n for i, h in enumerate(hList):\n # finish if h is the last handler in the arguments list\n if i==len(hList)-1:\n break\n otherHandler = hList[i+1]\n # check only the type of the next handler in the arguments\n # list, the first handler (self) is automatically checked\n if not isinstance(otherHandler, Handler):\n raise TypeError(\n 'method makeStack() must be called with Handler instances')\n if h.nextHandler:\n Handler.makeStack(h.nextHandler, otherHandler)\n else:\n h.nextHandler = otherHandler\n while otherHandler:\n otherHandler.data = h.data\n otherHandler = otherHandler.nextHandler\n return hList[0] # same as self, but the method may be called unbound\n</pre>\nThis alternative also has many usages:<pre>\n d=Handler.makeStack(a,b,c) # d==a\n d=Handler.makeStack(a,Handler.makeStack(b,c)) # d==a\n d=Handler.makeStack(Handler(a,b),c) # d==a\n a.makeStack(b,c)</pre>\nand so on.\n<br><br>\nI will not change the code in the recipe yet, but I am offering both alternatives for now. I will eventually change the code based on feedback and especially if the editors request it.", 'title': u'alternative to + operator'}, {'comment': u'Correction on usages (3rd line: Handler.makeStack(a,b), not Handler(a,b)):<pre>\n d=Handler.makeStack(a,b,c) # d==a\n d=Handler.makeStack(a,Handler.makeStack(b,c)) # d==a\n d=Handler.makeStack(Handler.makeStack(a,b),c) # d==a\n a.makeStack(b,c)</pre>', 'title': u'Re: alternative to + operator'}, {'comment': u'My preference would be to provide __iadd__ and chain methods. __iadd__ would be the same as the __add__ defined above. chain would look like:<pre>\ndef chain( self, *args ):\n for arg in args:\n if not isinstance(arg, Handler):\n raise TypeError(\'All arguments to Handler.chain() must be Handlers\')\n self.__iadd__( arg )\n</pre>This would provide the following possibilities:<pre>\n # "atomic" handlers\n a = Handler()\n b = Handler()\n\n w = Handler()\n w += a\n w += b\n\n x = Handler()\n x.chain( a, b )\n\n y = Handler().chain( a, b )\n</pre>or (getting a little carried away):<pre>\n c = C_Handler()\n d = D_Handler()\n e = E_Handler()\n z = Handler().chain( a, b, x, c, y, d, z, e )\n</pre>\nThat seems to me to be a good compromise, and is less confusing (to me, at least).<pre>\n</pre>\nDesign note:\nFor efficiency, I would also eliminate the duplicate type check introduced in chain(). I would extract all of __iadd__ except the type check into a separate method (maybe __iadd_no_typecheck), and have both __iadd__ and chain call the new routine.<pre>\n</pre>\n- Sam', 'title': u"For what it's worth..."}, {'comment': u'I have finally discovered a pattern that is well described and matches the architecture described in this recipe. It\'s the Pipes and Filters pattern described in "Pattern-Oriented Software Architecture, Volume 1" by Frank Buschmann and others. It was published in 1996 so I guess they were first ;-).', 'title': u'pipes and filters'}], 'desc': u'Design pattern that is highly reusable. Simple handlers implement one specific task from a complex set of tasks to be performed on an object. Such handlers can then be layered in a stack, in different combinations, together achieving complex processing of an object. New handlers are easy to implement and add.'}, {'comments': [], 'desc': u'This recipe shows a way to generate section numbers for a nested document structure. It can be used within a recursive algorithm to build a table of contents.'}, {'comments': [], 'desc': u'Performes the backup of all private and checked out files in all local clearcase views.'}, {'comments': [{'comment': u'Isn\'t a list-returning version somewhat redundant? If a list is required it can be easily obtained by materialising the output of xcombine: list(xcombine((1,2),(3,4))). (And if you have just this one version, you could rename it to "combine").', 'title': u'Why not provide just the generator version?'}, {'comment': u"Thanks for the comment.\n<br>\nI wrote combine first and then wrote xcombine for completeness. I've used combine for a couple of things and haven't had an application that would have been better off using xcombine.\n<br>\nI did a couple of crude tests with large inputs, and in these cases combine is roughly twice as fast as list(xcombine). On the other hand, if you only need to loop over the combinations and never create the whole list, it looks like xcombine is twice as fast as combine. On the third hand, for lots of combining of just a handful of small sequences, combine is faster than xcombine, even when you don't need the list! Of course if the number of combinations is really large, xcombine should save some memory. I'd say if speed matters, test with your inputs on your system.\n<br>\nAs for the names, I was just following the range, xrange precedent.", 'title': u'Either way is OK.'}, {'comment': u'This is known as a cartesian product[1]<br>\nI wrote a C module to do this quickly a couple years ago which still works with current versions of python[2].<br>\nCheck comp.lang.python for discussions about combinations and permutations, a thread starts about once a year to find the fastest way to do combinatorics in pure-python.<br>\n<br>\n[1] http://mathworld.wolfram.com/CartesianProduct.html<br>\n[2] http://probstat.sourceforge.net/<br>', 'title': u'Cartesian Product'}, {'comment': u'Now that I know the proper name, I was able to find some interesting versions, including one that is very similar to what I did, one that shrinks it into a few lines using reduce and lambda, and one from Tim Peters that I need to think about a bit more in order to understand!', 'title': u'So I see ...'}, {'comment': u'Mmmm .... I like this. \n I can imagine this approach being used in a parser, where you have a sequence/stream of tokens, each of which can be followed by another sequence. \n ( A finite state machine may be another way of doing this, but this recipe certainly gives me some very useful ideas! Thanks for this, David.) \n\n ', 'title': u'Very interesting example! '}], 'desc': u"The function combine takes multiple sequences and creates a list in which each item is constructed from items from each input sequence, and all possible combinations are created. If that description is confusing, look at the example in the docstring. It's a pretty simple transformation. The function xcombine is similar, but returns a generator rather than creating the output all at once."}, {'comments': [], 'desc': u'This recipe demonstrates how you can do regular expression matching and replacing with operators.'}, {'comments': [{'comment': u'This library is not able to flatten sets. Easy fix should help!', 'title': u'No set support'}], 'desc': u'Common python services such as pickle, deepcopy and comparison tests either fail entirely or do not scale for highly recursive data structures. This recipe presents a reversible "flatten" transformation that allows for such operations.'}, {'comments': [{'comment': u'This obviously only works on windows, but I should have mentioned it anyway.', 'title': u'Oops...'}], 'desc': u'If you use the command prompt here powertoy, you might find this useful. Right click on any folder and select Python Shell Here, and an that opens up in the directory you selected.'}, {'comments': [], 'desc': u'Script to download multiple directories from remote FTP servers and copy these to local machines under multiple threads. '}, {'comments': [{'comment': u'You should take the filename case into account:\n\ninstead of: \nif base_list[i] You should take the filename case into account:\n\ninstead of: \nif base_list[i] ', 'title': u'Correct for os.path.normcase'}, {'comment': u'I think it is bad form to do any existance checking in this kind of\nroutine. If you have been walking a directory structure and therefore\nknow (as well as you can) the files exists it is just wasteful to\ncheck again.<br>\n<br>\nI\'ve written something which I think does the job and doesn\'t use\nrecursion like the lisp-ish recipe also in the cookbook. See if \nyou like some or all of this. :)\n\n<pre>\n\ndef relpath(path, reldir):\n """Returns \'path\' relative to \'reldir\'."""\n\n # use normpath to ensure path separators are uniform\n path = os.path.normpath(path) \n\n # find length of reldir as prefix of path (or zero if it isn\'t)\n prelen = len(os.path.commonprefix((\n os.path.normcase(path),\n # add a separator to get correct prefix length\n # (normpath removes trailing separators)\n os.path.normcase(os.path.normpath(reldir)) + os.sep\n )))\n return path[prelen:]\n\n</pre>', 'title': u'some assumptions are helpful, some are not'}], 'desc': u'Another version of the relative path script already posted on the cookbook website. This one is somewhat shorter (at only 8 lines, excluding the data checks) and is (I hope!) clearer and more elegant.\nIt also includes a unit testing script.'}, {'comments': [], 'desc': u'OpenOffice is very popular. Some people may be interested in indexing the contents of their documents written with OpenOffice. Here is a very simple solution for that.'}, {'comments': [{'comment': u'You should really be using Decimal for this kind of math. See PEP 327 for further info.', 'title': u'Data type'}], 'desc': u'This class can be used to do interest rate calculations much like a financial calculator, and demonstrates the use of Python properties.'}, {'comments': [], 'desc': u'Superclass for cache value objects by its constructor arguments (see the Date class for example).'}, {'comments': [], 'desc': u'This is a way to grab a web page containing images\nand save this page and selected images to the same directory.'}, {'comments': [], 'desc': u'The IsChangedMixin can be added to any class and queried to determine if the class instance contents, or any other instances contained in the class instance, have been altered.'}, {'comments': [], 'desc': u'This is your standard vanilla range functions, converted to work as an iterator:\nUPDATE: xrange already does that. So feel free to ignore this.'}, {'comments': [{'comment': u'<pre>\nimport threading,Queue\nimport socket\n\nimport socket\n#import time,random # temp\n\nclass Threader:\n def __init__(self, numthreads):\n self._numthreads=numthreads\n\n def get_data(self,):\n raise NotImplementedError, "You must implement get_data as a function that returns an iterable"\n return range(10000)\n def handle_data(self,data):\n raise NotImplementedError, "You must implement handle_data as a function that returns anything"\n time.sleep(random.randrange(1,5))\n return data*data\n def handle_result(self, data, result):\n raise NotImplementedError, "You must implement handle_result as a function that does anything"\n print data, result\n\n def _handle_data(self):\n while 1:\n x=self.Q.get()\n if x is None:\n break\n self.DQ.put((x,self.handle_data(x)))\n\n def _handle_result(self):\n while 1:\n x,xa=self.DQ.get()\n if x is None:\n break\n self.handle_result(x, xa)\n\n def run(self):\n if hasattr(self, "prerun"):\n self.prerun()\n self.Q=Queue.Queue()\n self.DQ=Queue.Queue()\n ts=[]\n for x in range(self._numthreads):\n t=threading.Thread(target=self._handle_data)\n t.start()\n ts.append(t)\n\n at=threading.Thread(target=self._handle_result)\n at.start()\n\n try :\n for x in self.get_data():\n self.Q.put(x)\n except NotImplementedError, e:\n print e\n for x in range(self._numthreads):\n self.Q.put(None)\n for t in ts:\n t.join()\n self.DQ.put((None,None))\n at.join()\n if hasattr(self, "postrun"):\n return self.postrun()\n return None\n</pre>\n\nThen you can use it like:\n\n<pre>\nfrom threader import Threader\nimport time\n\nclass ttest(Threader):\n def get_data(self):\n return range(100)\n\n def handle_data(self,data):\n return data*data\n\n def handle_result(self, data, result):\n self.res.append((data,result))\n #print "%d: %d" % (data, result)\n\n def prerun(self):\n self.res=[]\n def postrun(self):\n return self.res\n\n\n\na=ttest(10)\nfor n,ns in a.run():\n print n,ns\n</pre>\n\nsilly example, but you get the point :-)', 'title': u'I like my version better :-)'}, {'comment': u'My example has 2 purposes.\n1)to have as little knowledge overhead as possible -- so no use of classes\n2)To show how to have a thread pool -- which means, I want the starting and stopping of the pool to be explicit ', 'title': u'good example but I wanted to show a simple thread pool'}, {'comment': u'Great example, thanks!\n<br>\nMy favourite implementation of Threader has optional data_queue and result_queue as constructor arguments, and numthreads as an argument to run().', 'title': u'exercise left to the reader....'}], 'desc': u"You can find examples on how to do threading, but they do not show off a thread pool. My goal was to get as small and simple as possible working thread pool example to show off the basic ideas without having extraneous things to understand. To show off the thread pool, I want stopping and starting of the threads to be explicit. This means the pool won't start until you are ready and will run forever until you are ready for it to stop. The main thread puts into the input queue and removes data from the output queue. The thread pool simply does the converse. Errors are also managed with another queue, so there is a clean distinction between errors and successful results."}, {'comments': [{'comment': u'Is cookielib backward compatible to older versions of Python? Or can it be ported if not? This seems easier than dealing with both ClientCookie and cookielib.', 'title': u'backporting cookielib'}, {'comment': u"The new cookielib uses a modified urllib2 - so it's not as straightforward as just making cookielib available. ClientCookie also has various other 'goodies' that weren't included in cookielib - which is another reason for someone still wanting to use ClientCookie rather than cookielib.<br>\n<br>\nHaving said that... it still might be possible,. I already have ClientCookie installed on the server I use, and am more than happy with it. the above chunk of code means my script will run with the same functionality on a machine with Python 2.4 *and* will work fine on a machine with neither.", 'title': u'Backporting cookielib'}, {'comment': u"and you shouldn't mind the whole 2 libs being checked.\nNicely done.<br>\n<br>\nsome small proposals:<br>\ni) very often one needs to spool the referer header, so you could have added that header too, except from adding the UserAgent:<br>\ntxheaders = {'User-agent' : 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7)', 'Referer' : refererUrl}<br>\n<br>\nii) eventhough you describe it, you don't say exactly how *exactly* is it done if you want to POST and not GET. something like this in a comments could be better [not sure though u decide]<br>\n<br>\nparams = {'DomainNumber':'0', 'PhoneNo':PHONE_NO, 'Password':PASSWD}<br>\ntxdata = urllib.urlencode(params) <br>\n<br>\nanyways. excellent code [I voted for you 5 out of 5] and I just put the above stuff here, just if anyone was wondering [as I did]", 'title': u'This code is magnificent and just works as it should be :)'}, {'comment': u'Thanks for the appreciation !<br>\nI also like your additional examples.... - Fuzzy<br>', 'title': u'Thanks'}, {'comment': u"Think there's a lil' typo in the article.\n\nShouldn't <pre>Request = urlib2.Request</pre> be <pre>Request = urllib2.Request</pre> (urlib2 -> urllib2)?", 'title': u'Typo?'}, {'comment': u'and it became obvius to me too while using Python 2.4 :)', 'title': u"yes, it's a typo.."}, {'comment': u'Sorry about that... typos belatedly corrected.', 'title': u'Oops..'}, {'comment': u'Hi Michael,\n\nWhen running the cookie_example.py my cookies.lwp get updated but it only has the following line in it "#LWP-Cookies-2.0". I checked the log and I do see the output for: "for index, cookie in enumerate(cj): print index, \' : \', cookie".\n\nAny ideas why the file would be writing just "#LWP-Cookies-2.0" on first line and not the cookie entries?\n\nRegards,\n-Alen\n\n\n ', 'title': u'Empty cookies.lwp file when save() called'}], 'desc': u"cookielib is a library new to Python 2.4\nPrior to Python 2.4 it existed as ClientCookie, but it's not a drop in replacement - some of the function of ClientCookie has been moved into urllib2.\n\nThis example shows code for fetching URIs (with cookie handling - including loading and saving) that will work unchanged on :\na machine with python 2.4 (and cookielib)\na machine with ClientCookie installed\na machine with neither\n(Obviously on the machine with neither the cookies won't be handled or saved).\n\nWhere either cookielib or ClientCookie is available the cookies will be saved in a file.\nIf that file exists already the cookies will first be loaded from it.\nThe file format is a useful plain text format and the attributes of each cookie is accessible in the Cookiejar instance (once loaded).\n\nThis may be helpful to those just using ClientCookie as the ClientCookie documentation doesn't appear to document the LWPCookieJar class which is needed for saving and loading cookies.\n"}, {'comments': [{'comment': u'Changes :<br>\n<br>\n- added a WeakCache abstract class<br>\n- all short member names such a entry._p, cache._d and so on have been renamed to longer, more explicit names. Hopefully the code is more readable now.<br>\n- Cache.extract is renamed to Cache._unpack, and must return NOT_INITIALIZED if the entry is invalid. Cache._pack does the opposite of Cache._unpack. See WeakCache for an example use.<br>\n- ModuleCache now return Module objects, which still are placeholder classes but with a better repr().', 'title': u'Update'}, {'comment': u'In __setitem__, an entry lock was forgotten when setting the value on an already existing entry.', 'title': u'Update'}, {'comment': u'Updated the code to the latest version I\'m using. The API for check() and build() has slightly changed : the "key" parameter has been added. The ModuleCache class now uses real module objects instead of fake ones.', 'title': u'Update'}, {'comment': u"Compatibility improvements : this latest version is compatible with Python 2.2, and with Python versions which do not include thread support.<br>\n<br>\nPerformance improvements : FileCache stat() the file to test if it is modified, and open() it only if it is the case. Previously it opened the file each and every time, even if it wasn't modified.", 'title': u'Update'}, {'comment': u"I think you need to put in the following in the __delitem__ before the del self._dict[key] since otherwise you'll keep leaking your access list.\n<pre>\nif self._maxsize:\n\tentry = self._dict[key]\n\tentry._previous._next = entry._next\n\tentry._next._previous = entry._previous\n\tentry._next = None\n\tentry._previous = None\n</pre>", 'title': u'Cleaning up the access list in __delitem__'}], 'desc': u'Implementation of an abstract, thread-safe cache with minimal locking. Four concrete implementations : a validating file cache, a validating HTTP cache, an experimental Python module cache and a function cache. Plus, an abstract cache with weak references to its values.'}, {'comments': [{'comment': u' Python kicks ass!', 'title': u'Wow!'}, {'comment': u'If Python has an ass, he kicks it!', 'title': u'I think you meant...'}, {'comment': u"Hello everyone,\n\nI know that this is a pretty old recipe but I just wanted to draw your attention to the Reasonable Python projects which uses some of the concepts stated above at (http://reasonablepy.sf.net). I'm trying to use F-Logic in Python which is a kind of object-oriented logic programming.\n\nBest regards", 'title': u'Reasonable Python'}], 'desc': u"Some of Python's powerful meta-programming features are used to enable writing Python functions which include Prolog-like statements. Such functions load a Prolog-like database. When coupled with a suitable inference engine for logic databases, this is a way to add logical programming -- the last unsupported major paradigm -- to Python. Start at the bottom of the code for an example of the enabled syntax."}, {'comments': [], 'desc': u'This is a straight port of tiny.m, from Garfinkel and Mahoney\'s "Building Cocoa Applications: A Step By Step Guide." It shows how to build a Cocoa application without using Interface Builder (or loading .nib files).'}, {'comments': [{'comment': u"Using super to call next method might be useful in this case. It reduces complexity of the derived __new__ when multiple inheritance is involved. Here is an updated version.\n\n<pre>\n# Simple inheritance case\nclass super1 (object):\n def __new__(typ, *args, **kwargs):\n obj = super(super1, typ).__new__(typ, *args, **kwargs)\n obj.attr1 = []\n return obj\n\n# Multiple inheritance case\nclass super2 (object):\n def __new__(typ, *args, **kwargs):\n obj = super(super2, typ).__new__(typ, *args, **kwargs)\n obj.attr2 = 222\n return obj\n\nclass derived2 (super1, super2):\n def __new__(typ, *args, **kwargs):\n obj = super(derived2, typ).__new__(typ, *args, **kwargs)\n obj.attr3 = 333\n return obj\n\n def __init__(self, arg4, **kwargs):\n self.attr1.append(111)\n self.attr4 = arg4\n self.attr5 = kwargs['arg5']\n\nif '__main__'==__name__:\n d1 = derived2(444, arg5=555)\n print d1.attr1, d1.attr2, d1.attr3, d1.attr4, d1.attr5,\n print isinstance(d1, super1),\n print isinstance(d1, super2)\n\n</pre>", 'title': u'Using cooperative super call useful'}, {'comment': u"I contemplated using super() at some point before submitiing the recipe, but I was not clear yet on the behavior of super and of cooperative classes. I have finally read more on the topic and now I get it. You're right, Shalabh, this is a better solution and it actually makes the recipe kind of trivial.\n<br><br>\nI am not going to make the changes yet on the recipe and I will wait for a verdict from the editors (i.e., whether they would still be interested in the recipe). If there is still an interest, here is what I suggest.\n<br><br>\nShalabh's code would be the preferred solution and should be presented first. That solution depends however on the superclasses to be cooperative classes. I tried it, and if super1 does not invoke super(...), the implementation of derived2 breaks (derived2.attr2 is missing).\n<br><br>\nMy original code can then follow with the argument that it should be used when the superclasses may not be cooperative classes. This second solution offers also more control on the order in which attributes are inherited. A note that should be added is that changing that order may be dangerous however, because the order of inheritance for methods is not changed and a dependence of the methods on the attributes may cause trouble.", 'title': u'Re: Using cooperative super call useful'}, {'comment': u'I find this recipe to still be useful and educational even after the addition of the super function. Until now, I have not seen much discussion on the __new__ method. And in this recipe, Dan does a great job of exposing the usefulness of the __new__ method. As a result, I am definitely encouraged to exploit the __new__ method in my Python code. And kudos also to Shalabh as well for his contribution of the super function as well! Thanks!\n', 'title': u'Super or no super, still useful'}], 'desc': u'Whenever a superclass implements a __init__ method to initialize its attributes, subclasses derived from it have to invoke the __init__ method of the superclass. This recipe is a different mechanism of initializing the attributes of a superclass with default values, achieved by overriding the __new__ method.'}, {'comments': [{'comment': u'You can do this with a generator and avoid creating the intermediate lists:\n<pre>\ndef group(lst, n):\n for i in range(0, len(lst), n):\n val = lst[i:i+n]\n if len(val) == n:\n yield tuple(val)\n\n>>> list(group([0,3,4,10,2,3], 2))\n[(0, 3), (4, 10), (2, 3)]\n>>> list(group(range(10), 3))\n[(0, 1, 2), (3, 4, 5), (6, 7, 8)]\n</pre>', 'title': u'Solution using a generator'}, {'comment': u"This requires that the input be a sequence rather than just an iterable. For a generator-based version that can take any iterable (and which doesn't discard incomplete tail items) see my own recipe at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303279.", 'title': u'Requires input to be a sequence rather than just an iterable'}, {'comment': u"There is a speed vs memory vs flexibility trade-off that needs to be made here (along with the correct semantics regarding the final incomplete tuple). Here are my timings for the 4 functions that have been presented (group2 and batch2 are the alternate implementations suggested in comments). As you can see, I've skewed the test in favor of the iteration implementations by using a fairly large input list and starting with an iterable input.\n<br>\n<pre>\nimport timeit\n\nfor fn in ['group1', 'group2', 'batch', 'batch2']:\n if fn.startswith('group'):\n call = '%s(list(x), 3)' % fn\n else:\n call = '%s(x, 3)' % fn\n \n timer = timeit.Timer(\n 'for y in %s: pass\\n' % call,\n 'x = xrange(10000); from __main__ import %s' % fn)\n print timer.timeit(1000)\n\nResults:\n\n5.60028100014\n13.2801439762\n16.8175079823\n19.8542819023\n</pre>\n<br>\nIn the code that I designed this function for [len(lst) ~= 1000, list input], my algorithm is more than 10x faster than the next fastest alternative.", 'title': u'Speed comparison'}, {'comment': u'<pre>\ndef group(lst, n):\n """group([0,3,4,10,2,3], 2) => iterator\n \n Group an iterable into an n-tuples iterable. Incomplete tuples\n are discarded e.g.\n \n >>> list(group(range(10), 3))\n [(0, 1, 2), (3, 4, 5), (6, 7, 8)]\n """\n\nTimings:\n\n6.01822805405\n14.5682420731\n2.44970393181 # this version\n18.8882629871\n21.9563779831\n\nI\'m leaving the original recipe here because it is still appropriate if:\n\no you are starting with a sequence\no you need list output\no the size of your list/iterable is small\n</pre>', 'title': u'Fastest iterable version'}, {'comment': u'<pre>\ndef group3(lst, n):\n """group([0,3,4,10,2,3], 2) => iterator\n \n Group an iterable into an n-tuples iterable. Incomplete tuples\n are discarded e.g.\n \n >>> list(group(range(10), 3))\n [(0, 1, 2), (3, 4, 5), (6, 7, 8)]\n """\n return itertools.izip(*[itertools.islice(lst, i, None, n) for i in range(n)])\n</pre>', 'title': u'Now with code!'}], 'desc': u'This function returns a list of n-tuples from a single "flat" list.'}, {'comments': [{'comment': u'<pre>Should:\n\n elif child.hasChildNodes():\n remove_whilespace_nodes(child)\n\nRead:\n\n elif child.hasChildNodes():\n remove_whilespace_nodes(child, unlink)\n\n?\n\n\nDavid.</pre>', 'title': u'Error?'}, {'comment': u"Yes, I've updated the recipe.", 'title': u'Right you are'}], 'desc': u"XML parsers consider several conditions when deciding which whitespace-only text nodes should be preserved during DOM construction. Unfortunately, those conditions are controlled by the document's DTD or by the content of document itself. Since it is often difficult to modify the DTD or the XML, this recipe simple removes all whitespace-only text nodes from a DOM node."}, {'comments': [], 'desc': u'This recipe describes how to create a fade-in window using IronPython. Several applications use fade-in windows for temporary data e.g. new Outlook XP mail messages are shown through a fade-in/fade-out pop-up window. \n\nFading in can be best accomplished using the Form.Opacity property and a Timer. Pop-up windows should also set the "topmost" window style. '}, {'comments': [{'comment': u'Hi,\n\nI tried the recipe on my Mac, it\'s giving me this error:\n\n====\nTraceback (most recent call last):\n File "sys_profile.py", line 137, in ?\n main()\n File "sys_profile.py", line 134, in main\n print \'%s: %s\' % (k, info[k][0])\n File "sys_profile.py", line 91, in __getitem__\n from xml import xpath\nImportError: cannot import name xpath\n====\n\ndid I need to do some setup before using the recipe?\n\nThanks.', 'title': u'xpath error'}], 'desc': u'This recipe uses the system_profiler application to retrieve detailed information about a Mac OS X system. There are two useful ways to use it: the first is to ask for a complete Python datastructure containing information about the system (see OSXSystemProfiler.all()) and the other is two ask for particular keys in the system information database.'}, {'comments': [], 'desc': u'I am trying to show how to have a thread pool\nbuilding on the recipe in http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302746.\nThis is a python class that essentially makes a thread pool for a function you define. Like the earlier example, I want to show off the power of having a thread pool that you can stop and start at will. Interestingly, you can mimic more standard thread use with the pool -- which I show off in as little as 3 lines of simple code.'}, {'comments': [{'comment': u'I was very pleased with this recipe, but wanted it to do a little more. Here is my version, which only works on windows; you\'ll need to override getchar for other operating systems. See Recipe 134892 for more on how to do that. \n<pre>\nfrom decimal import *\nimport msvcrt #Windows only!\nimport sys\n\nclass TenKey:\n def __init__(self):\n #set up for fixed decimal places (change .01)\n getcontext().rounding = ROUND_HALF_UP\n self.zero = Decimal(\'0\').quantize(Decimal(\'.01\'))\n\n self.total = self.zero\n self.EnteredOnce = False\n self.currLine = \'\'\n\n def clear(self):\n self.total = self.zero\n self.currLine = \'\'\n print "c"\n\n def onOperator(self, char):\n print char\n self.EnteredOnce = False\n self.currLine = \'\'\n \n def getchar(self):\n """Override or replace this function for Unix or MacOS\n see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/134892\n for example"""\n self.lineDelim = \'\\r\'\n return msvcrt.getch()\n\n def run(self):\n while True:\n char = self.getchar()\n if char == \'q\':\n break\n elif char == \'c\':\n self.clear()\n elif char == self.lineDelim:\n if self.EnteredOnce:\n self.clear()\n else:\n sys.stdout.write(\'=======\\n\' + str(self.total) + \'\\n\')\n self.EnteredOnce = True\n continue\n elif char == \'+\':\n self.total += Decimal(self.currLine)\n self.onOperator(char)\n elif char == \'-\':\n self.total -= Decimal(self.currLine)\n self.onOperator(char) \n elif char == \'*\':\n self.total *= Decimal(self.currLine)\n self.onOperator(char)\n elif char == \'/\':\n self.total /= Decimal(self.currLine)\n self.onOperator(char)\n elif char in \'0123456789\':\n self.EnteredOnce = False\n sys.stdout.write(char)\n self.currLine += char\n elif char == \'.\':\n if char not in self.currLine:\n self.currLine += char\n sys.stdout.write(char)\n \nif __name__ == "__main__":\n calc = TenKey()\n calc.run()\n</pre>', 'title': u'Improvements - no return needed, clear function, arbitrary decimal places'}], 'desc': u"One of the signs that you love Python is when you start to use it as a simple calculator. The problem with that is beyond the usefulness of 'sum' the interactive interpreter is not optimal for any calculations beyond a few numbers. This mostly seems to stem from the numbers not being formatted in a nice fashion; ``2345634+2894756-2345823`` is not the easiest thing to read. That's where an accountant's calculator comes in handy; the tape presents numbers in a column view that is very uncluttered. And thanks to the decimal package a *very* simple one can be implemented quickly.\n\nTo use this recipe you input the number, an optional space, and then the operator (/, *, -, or +; everything you would find on the numeric keypad on your keyboard) and then press return. This will apply the number to the running total using the operator. To output the total just enter a blank line. To quit enter the letter 'q' and press return. This simple interface matches the output of a typical accountant's calculator, removing the need to have some other form of output."}, {'comments': [{'comment': u" <pre>\n > new_name = ' '.join((name_parts[-1], name_parts[0]))\n > if len(name_parts) == 3:\n > new_name = ' '.join((new_name, name_parts[1]))\n\nI would do it like this:\n\nnew_name = ' '.join([name_parts[-1]] + name_parts[0:-1])\n\nShorter, and it eliminates one point of failure for singleton names.\n</pre>", 'title': u' '}], 'desc': u"When you write a directory for a group of people, you want it grouped by last name initial and then sorted alphabetically. This recipe does just that; it creates a dictionary keyed by last name initial with a value of a tuple of names sorted in alphabetical order.\n\nThe input to 'groupnames' should be an iterable that returns strings that contain names written in first-middle-last fashion with each part separated by whitespace. The resulting names in the grouped dict will have normalized whitespace."}, {'comments': [{'comment': u"Python 2.4's email module uses the FeedParser by default so if you use the Parser class's parse() method or the from_file() or from_string() functions, you'll get the FeedParser's functionality for free.", 'title': u'Not actually necessary to use FeedParser explicitly'}], 'desc': u"For good reasons, the email module's new feed parser can return a message that's internally inconsistent. This recipe fixes up one sort of inconsistency that I've seen in the wild."}, {'comments': [{'comment': u'A slightly shorter version:\n<pre>def batch(iterable, size):\n iterable = iter(iterable)\n while True:\n result = list(itertools.islice(iterable, size))\n if not result:\n break\n yield result\n</pre>', 'title': u'know your itertools =)'}, {'comment': u"Soon after submitting the recipe I began thinking of alternatives to building a list in memory for each batch. islice is just what I needed to do the basic batching, which I've incorporated in my revised version, but I keep the result of islice as an iterator rather than convert it to a list as I want to keep memory requirements to a minimum.", 'title': u'islice is just what I needed'}, {'comment': u'You should add a warning that a batch has to be entirely consumed before you can proceed to the next one. Otherwise users may be puzzled by the following:\n\n<pre>\n>>> len([bi for bi in batch(range(19), 3)])\n19\n\n>>> list([bi for bi in batch(range(19), 3)][3])\n[3]\n</pre>\n\nCatching the StopIteration is not necessary when you are essentially reraising it:\n\n<pre>\n>>> def batch(iterable, size):\n... it = iter(iterable)\n... while True:\n... bi = islice(it, size)\n... yield chain([bi.next()], bi)\n...\n>>> map(list, batch(xrange(10), 3))\n[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]\n</pre>', 'title': u'All batches must be exhausted immediately'}, {'comment': u'The groupby() function is somewhat versatile if some imagination goes into defining the key= function.\n<pre>\nfrom itertools import groupby\n\ndef batch(iterable, size):\n def ticker(x, s=size, a=[-1]):\n r = a[0] = a[0] + 1\n return r // s\n for k, g in groupby(iterable, ticker):\n yield g\n</pre>', 'title': u'Another approach'}, {'comment': u"Duh! Yes, catching and reraising StopIteration is redundant. Thanks! I've removed it.", 'title': u'Removed handling of StopIteration'}, {'comment': u'Your comment about unconsumed batches got me to thinking about what the right behaviour should be. Compensate for a batch iterator not getting exhausted by internally consuming the source iterator? Or have each batch iterator begin where the last one finished, so producing an infinite number of batch iterators if none of them get exhausted?', 'title': u'What to do about batches not being consumed?'}], 'desc': u'You want to get the items from a sequence (or other iterable) a batch at a time, including a short batch at the end if need be.'}, {'comments': [{'comment': u"I have used this lib a bit and it is pretty easy, but I haven't tried to use it asyncronously. I looked through the samples that came with the code, but didn't find a good complete example of using the async methods.\n\nMaybe you can post a quick one?", 'title': u'Great example, but are there any good async examples?'}, {'comment': u'Watch out the python-ldap docs for the sub-module ldap.async which is meant for stream processing of large result sets. The docs solely contain a single example. But that should be sufficient to get the idea.', 'title': u'ldap.async'}, {'comment': u"You should not mess with l.protocol_version unless you really know what you're doing!!!<br>\nLDAPv2 is a deprecated protocol version (RFCs marked as historic). LDAPv3 is what most LDAP servers implement today.<br>\nTherefore python-ldap's default for l.protocol_version is ldap.VERSION3 which sets LDAPv3 for binds.", 'title': u'Do not use LDAPv2'}], 'desc': u"The ldap library at http://python-ldap.sourceforge.net wraps the Openldap C api.\nIt can talk to various versions of ldap servers not just the Openldap servers.\nNote the use of the '_s' methods like search_s which all are synchronous.\nHere are some simple examples showing one how to use the library. "}, {'comments': [], 'desc': u'One of the few perks one can have when developing on Windows (at least NT or newer) is the use of the Performance Data Helper (the PDH can be found on Windows XP under the Control Panel at Administrative Tools -> Performance) for system statistics gathering. There is a bevy of counters available that can greatly help you measure the impact your code has on the current system.\n\nAnd luckily win32all provides a wrapper to create counters. The only drawback, though, is that the API is not the best in the world. So, to help deal with that I wrote a subclass to help with adding counters and formatting the output in a more usable fashion as either CSV or a dict that can be pickled.'}, {'comments': [{'comment': u'I had done a similar recipe but using PSAPI.DLL and ctypes:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305279\nEric', 'title': u' '}, {'comment': u'This just worked. Thanks!\n\n~Matt', 'title': u'Sweet and relatively simple'}], 'desc': u"To get process information for both NT and W2K (but not the 9x family) you can use the Performance Data Helper library(PDH). The is a simple example that shows you how to get a process list and their ids. It provides a convenient interface to performance information stored fundamentally in the registry. The basic process of using the PDH encompasses the following:\n\n 1. Get a list of all the objects you want\n 2. Get a list of the object's instances and data available for each instance: called 'items' or 'counters'\n 3. Get a group of performance data for each counter \n\nIn the case here we want the process object, the object's instances are it's list of processes, and the counter we want for the processes is 'ID Process'. "}, {'comments': [], 'desc': u"The following code is an example of how one would use python's win32net module to create a share on windows. "}, {'comments': [{'comment': u"Nice utility!\n<pre></pre>\nHere is a drop-in replacement using functions and nested scopes instead of class logic. It is a little bit less wordy and runs a bit faster:\n\n<pre>\nimport string\n\ndef Translator(frm='', to='', delete='', keep=None):\n allchars = string.maketrans('','')\n if len(to) == 1:\n to = to * len(frm)\n trans = string.maketrans(frm, to)\n if keep is not None:\n delete = allchars.translate(allchars, keep.translate(allchars, delete))\n def callable(s):\n return s.translate(trans, delete)\n return callable\n</pre>", 'title': u'Alternate implementation using nested functions'}, {'comment': u"<pre>The string module is being depreciated so you need to \nstart using list comprehensions to do these things:\n\n>>> str = 'Chris Perkins : 224-7992'\n>>> set = '0123456789'\n\n1) Keeping only a given set of characters.\n\n>>> ''.join([c for c in str if c in set])\n'2247992'\n\n2) Deleting a given set of characters.\n\n>>> ''.join([c for c in str if c not in set])\n'Chris Perkins : -'\n\n</pre>", 'title': u'Try a list comprehension'}], 'desc': u'It seems like every time I want to use string.maketrans and str.translate, I have to stop for a minute and think really hard about how to accomplish what I want to do. Eventually, I wrote this little wrapper class to ease my pain.\n'}, {'comments': [], 'desc': u'The win32api module offers SetFileAttributes whiles allows you to make changes to a file in windows. You can set a file to be read only, archive, hidden, etc. The function is simple and convenient to use.'}, {'comments': [], 'desc': u"In Win32 often you'll find time stored in 100-nanosecond intervals since January 1, 1600 UTC. It is stored in a 64-bit value which uses 2 32 bit parts to store the time. The following is a function that returns the time in the typical format the python time libraries use (seconds since 1970). "}, {'comments': [{'comment': u'You could also connect the user to an existing Exchange Mailbox Store by adding the following after the last SetInfo()\n<br>\n<br>\n<pre>\nimport pythoncom\n\ntry:\n ad_user.CreateMailbox(\'LDAP://\'+store_ldap_path)\n ad_user.EmailAddress = user+\'@email.address.com\'\n ad_user.SetInfo()\n ad_user.Put(\'msExchUserAccountControl\', 2)\n ad_user.SetInfo()\nexcept pythoncom.com_error,(hr,msg,exc,arg):\n print "Problem...."\n print hr, msg, exc, arg\n</pre>\n\nYou will need to figure out the LDAP string to the mailbox store. The LDAP string will look something like this (very generally speaking):\n<pre>\n\'CN=MyStore,CN=MyStorageGroup,CN=InformationStore,CN=MyServer,<br>CN=Servers,CN=First Administrative Group,CN=Administrative Groups,<br>CN=MySite,CN=Microsoft Exchange,CN=Services,<br>CN=Configuration\'+location\n</pre>\n', 'title': u'Connecting to Exchange Mailbox'}], 'desc': u"This is the basic code to create an account in active directory that shows how to do things like set your own exension attributes, force a reset of the password when the user logs in, and set the home directory. It makes used of python's excellent COM support in win32com."}, {'comments': [{'comment': u'The BunchDict class can be implemented in a much simpler (and faster) way by taking advantage of Alex Martelli\'s original idiom:\n\n<pre>\nclass BunchDict(dict):\n\n def __new__(cls, **kwargs):\n self = dict.__new__(cls, kwargs)\n self.__dict__ = self\n return self\n</pre>\n\nThere\'s no need to implement the __getattr__ and __setattr__ methods. They\'re taken care of automagically by "self.__dict__ = self". The behavior of this class is identical to that of the original code.', 'title': u'simpler implementation of BunchDict'}], 'desc': u'In recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52308 Alex Martelli showed how a collection of stuff can be organized as a "Bunch". This recipe recommends a specialized dictionary to reach the same goal. Since Python 2.2 the new dictionary-class can easily be created by subclassing the built in \'dict\' type. Adding a special method to (re)present the proposed BunchDict()-class we arrive at CfgBunch(), which is very well suited to contain bunches of configuration data.\n\nIt is further shown how these - in itself - rather unspectacular components gain considerable power when applied in a programming technique where "all sorts of sets of parameters" are stored in separate CfgBunch()-instances. Referencing a parameter according to the proposed technique makes as little difference as writing "self.clevername" versus "self.cfg.clevername". The benefits are:\n- having as many namespaces as needed to organize parameters\n- ease of use\n- possibility to easily pass sets of parameters around\n- great help in documentation'}, {'comments': [], 'desc': u"Sometimes it is useful to know what attributes are available to you for an object in active directory. You cannot ask the object directly for that, instead you need to use the schema of the object. All of this is done with python's COM support using win32com. By default only attributes that have values are returned."}, {'comments': [{'comment': u'Any chance of getting a short sample snippet of how to use it (e.g. to connect to an Access DB)?', 'title': u'Examples?'}, {'comment': u'Here is a class/example main program that reads/writes data from/to a<br> TimePilot (electronic timeclock application) MS Access database files.<br>\n<br>\nHope it helps.<br>\nLarry Bates<br>\n<br>\n<br>\nimport os<br>\nimport daoBaseClass<br>\n<br>\nclass TimePilot(daoBaseClass):<br>\n    \'\'\'<br>\n    This class is used to read/write data from/to TimePilot data files (MS Access).<br>\n    \'\'\'<br>\n    def __init__(self, timepilotdatapath,         SQL_query=None):<br>\n        #<br>\n        # Call base class\' __init__ method<br>\n        #<br>\n        daoBaseClass.__init__(self, timepilotdatapath, <br>SQL_query=SQL_query)<br>\n        return<br>\n<br>\nif __name__ == "__main__":<br>\n    SQL_query=\'SELECT [USER ID] as userid, [ACTIVE], \' \\<br>\n            \'[OT1 Total] as ot1, [OT2 Total] as ot2, \' \\<br>\n            \'[Week0] as hours, [In Late Count] as latecount \' \\<br>\n            \'FROM Employee \'<br>\n<br>\n    timepilotdatapath=r"C:\\Timepilot\\TA\\Test\\TimePilot.mdb"<br>\n    #<br>\n    # Create a TimePilot class instance by passing it the path<br>\n    # to where data is stored.<br>\n    #<br>\n    TP=TimePilot(timepilotdatapath, SQL_query=SQL_query)<br>\n<br> \n    while not TP.EOF:<br>\n        print "userid=",TP[\'userid\'], "hours=", TP[\'hours\'], \\<br>\n            "OT1=",TP[\'ot1\'], "OT2=",TP[\'ot2\'], \\<br>\n            "latecount=",TP[\'latecount\']<br>\n        TP.MoveNext()<br>\n        if TP.EOF:<br>\n            break<br>\n<br>\n    TP.close()<br>\n    #----------------------------------------------------------------------<br>\n    # Create a TimePilot class instance by passing it the path<br>\n    # to where master data is stored.<br>\n    #----------------------------------------------------------------------<br>\n    timepilotdatapath=r"C:\\Timepilot\\TA\\Test\\TimePilot.mdb"<br>\n    TP=TimePilot(timepilotdatapath)<br>\n    #----------------------------------------------------------------------<br>\n    # Create a new SQL_query that positions us at test record<br>\n    # (userid=2) and updates some information there.<br>\n    #----------------------------------------------------------------------<br>\n    SQL_query="SELECT * FROM employee WHERE [USER ID]=2"<br>\n    TP.execute(SQL_query)<br>\n    TP[\'Address1\']="111 Fair Oaks Lane"<br>\n    TP[\'City\']="Birmingham"<br>\n    TP[\'State\']="AL"<br>\n    TP[\'Zip\']="35406"<br>\n    TP[\'Social Security\']="421XXXXXX"<br>\n    TP[\'Title\']="Vice President"<br>\n    #----------------------------------------------------------------------<br>\n    # Create a new record in the database.<br>\n    #----------------------------------------------------------------------<br>\n    TP.Ad', 'title': u'Example of using DAO class'}, {'comment': u'when I put the example in a file called test.py and but the daoBaseClass in a file called daoBaseClass.py I get the following error:\nTraceback (most recent call last):\n File "C:\\mypythontest\\test.py", line 4, in ?\n class TimePilot(daoBaseClass):\nTypeError: Error when calling the metaclass bases\n module.__init__() takes at most 2 arguments (3 given)\\\n\nI made a sample access db called db1 and it doesn\'t work. any ideas? below is the code that I have..\nimport os\nimport daoBaseClass\n\nclass TimePilot(daoBaseClass):\n \'\'\'\n This class is used to read/write data from/to TimePilot data files (MS Access).\n \'\'\'\n def __init__(self, timepilotdatapath, SQL_query=None):\n #\n # Call base class\' __init__ method\n #\n daoBaseClass.__init__(timepilotdatapath, SQL_query=SQL_query)\n return\n\nif __name__ == "__main__":\n SQL_query=\'SELECT [Field1] as sample1 FROM Employee \'\n\n timepilotdatapath=r"C:\\db1.mdb"\n #\n # Create a TimePilot class instance by passing it the path\n # to where data is stored.\n #\n TP=TimePilot(timepilotdatapath, SQL_query)\n\n while not TP.EOF:\n print "sample1=",TP[\'sample1\']\n TP.MoveNext()\n if TP.EOF:\n break\n\n TP.close()\n #----------------------------------------------------------------------\n # Create a TimePilot class instance by passing it the path\n # to where master data is stored.\n #----------------------------------------------------------------------\n timepilotdatapath=r"C:\\Timepilot\\TA\\Test\\TimePilot.mdb"\n #TP=TimePilot(timepilotdatapath)\n #----------------------------------------------------------------------\n # Create a new SQL_query that positions us at test record\n # (userid=2) and updates some information there.\n #----------------------------------------------------------------------\n #SQL_query="SELECT * FROM employee WHERE [USER ID]=2"\n #TP.execute(SQL_query)\n #TP[\'Address1\']="111 Fair Oaks Lane"\n #TP[\'City\']="Birmingham"\n #TP[\'State\']="AL"\n #TP[\'Zip\']="35406"\n #TP[\'Social Security\']="421XXXXXX"\n #TP[\'Title\']="Vice President"\n #----------------------------------------------------------------------\n # Create a new record in the database.\n #----------------------------------------------------------------------\n #TP.AddNew()\n #TP[\'User ID\']=5\n #TP[\'Display Name\']="Unit test"\n #TP[\'Company\']="Test"\n #TP[\'Department\']="test1"\n #TP[\'Pay Type\']="Hourly"\n #TP[\'Shift\']="test"\n #TP[\'Holiday\']="Holidays"\n #TP[\'Active\']=-1\n #TP.Update()\n #TP.close()', 'title': u'example error'}], 'desc': u"This is a simple base class that can be used to quickly get connected to any database that has DAO interface. I've used it quite a lot with MS Access databases and it has worked quite well for me. It really is just a Python wrapper around the DAO COM object. Hasn't been tested extensively, but worked in the projects that I've used it in so far.\n\nLarry Bates\n"}, {'comments': [], 'desc': u'This is a little equation solver somewhat modelled on the solvers available in some scientific calculators. You pass it a function which returns zero when the desired relation is true. Once you create a solver object, you can solve for any variable. '}, {'comments': [], 'desc': u"An example showing how Python's features can be used to optimize the construction of tree-like data structures in order to produce directed acyclic graphs (DAGs) instead."}, {'comments': [{'comment': u"Andrew, this is great! I started working with it and came up with a few mods. Unfortunately I don't know how to appropriately paste code in the comments yet, so I submitted a new recipe (#303770) that details the mods I made. I hope you'll check it out and let me know what you think. Basically, I moved the _names dict to a 'base' class so that all derivations don't need to specify the attribute names at instantiation time. This helps to reduce the clutter when instantiating the tuples. Thanks for sharing!", 'title': u'Kudos and a Mod.'}], 'desc': u'NamedTuple is a tuple subclass that allows its elements to be named. Elements can be accessed by index and by name.'}, {'comments': [], 'desc': u'This recipe provides a decorator for keeping mutable default function values fresh between calls.'}, {'comments': [{'comment': u'There are some libraries atop of datetime...<br>\n<br>\nespecially <br>\n<pre>\nhttps://moin.conectiva.com.br/DateUtil\n</pre>\nwith Gustavo Niemeyer\n\nand \n<pre>\nhttp://www.voidspace.org.uk/atlantibots/pythonutils.html#dateutils\n</pre>\nwith Michael Foord\n<br>\n(please note also the powerfull python on his site)\n<br>\nHarald', 'title': u'Did you look at the various dateutils present?'}], 'desc': u'The datetime module only accepts inputs of time it understands. For example,\nthe months given to it have to be in range of values 1-12. This wrapper works around that issue and enables you to move forward or backward more arbitrary units of time. It does that by changing the year, month, and day to fit the requirements of datetime. '}, {'comments': [{'comment': u'The examples of usage should have included using the factory function, and accessing the named members:\n<br>\n<pre>\nPersonTuple = NamedTuple("name", "age", "height")\nperson1 = PersonTuple(["James", "25", "185"])\nprint person1.name, person1.age, person1.height\n</pre>', 'title': u'Not enough examples'}, {'comment': u'It struck me that, since the members of the tuple are immutable, the best implementation would just keep another reference to them for each attribute. This not only ends up being simpler, but from my calculations about 1400% faster -- a very significant increase:\n<br>\n<pre>\nclass NamedTupleMetaclass(type):\n """Metaclass for a tuple with elements named and indexed.\n\n NamedTupleMetaclass instances must set the \'names\' class attribute\n with a list of strings of valid identifiers, being the names for the\n elements. The elements can then be obtained by looking up the name or the index.\n """\n\n def __init__(cls, classname, bases, classdict):\n # Must derive from tuple\n if not tuple in bases:\n raise ValueError, "\'%s\' must derive from tuple type." % classname\n\n type.__init__(cls, classname, bases, classdict)\n\n\n def instance_setattr(self, name, value):\n raise TypeError, "\'%s\' object has only read-only attributes (assign to .%s)" % (self.__class__.__name__, name)\n\n cls.__setattr__ = instance_setattr\n\n\n def cls_new(cls, seq_or_dict):\n # Accept either a sequence of values or a dict as parameters.\n if isinstance(seq_or_dict, dict):\n seq = []\n for name in cls.names:\n try:\n seq.append(seq_or_dict[name])\n except KeyError:\n raise KeyError, "\'%s\' element of \'%s\' not given" % (name, cls.__name__)\n else:\n seq = seq_or_dict\n\n instance = tuple.__new__(cls, seq)\n\n # Create attributes corresponding to the names with the same values (it\'s an immutable object, after all!)\n for i, name in enumerate(cls.names):\n tuple.__setattr__(instance, name, seq[i])\n\n return instance\n\n cls.__new__ = staticmethod(cls_new)\n</pre>', 'title': u'Great speed improvement'}, {'comment': u'http://just.letterror.com/ltrwiki/JustVanRossum_2fNamedTuple', 'title': u'More prior art'}, {'comment': u"http://www.sil-tec.gr/~tzot/python/ (TupleStruct.py)\n\nThe improvement for speed I have used was to set property gets for the members using the operator.attrgetter function. I didn't set separately members since that would mean extra memory usage.\n\nOldest article referencing this module from Dec 27, 2002, in a thread where Alex Martelli was involved too:\n\nhttp://groups.google.com/groups?selm=735o0vk4uciifl692o51fk9om87o37bo6k%404ax.com", 'title': u'Even more prior art'}], 'desc': u'NamedTupleMetaclass is a metaclass for creating tuples with named elements that can be accessed by index and by name.\n\nNamedTuple is a class factory for NamedTupleMetaclass instances.\n\nThis is an improved version of recipe #303439'}, {'comments': [{'comment': u'In a language like PHP, the integer value of a string like "123 blah blah" is 123; it ignores extra text. You can do this in Python as well, assuming you require whitespace after the number, like:\n\n<pre>\ntry:\n number = int(source.strip().split()[0])\nexcept (ValueError, IndexError):\n number = None\n</pre>\n\n\'\'.split() returns [], so you may get an IndexError when the string is empty or contains only whitespace.', 'title': u'More permissive'}, {'comment': u'don\'t use a bare "except:", use "except ValueError".\n\nWhy? Well, I\'ve done that and managed to mistype the variable\nname. The resulting NameError was caught mistakenly.\n\nAlso consider what happens if someone hits KeyboardInterrupt\nin the middle of that try block. It gets ignored.', 'title': u'ValueError'}], 'desc': u'Many times I needed to check if a string represented a number or not. This is a very short recipe that uses Python int() function to do the check, instead of looping on the single characters.'}, {'comments': [], 'desc': u'EasyDialogs give you the chance to connect a light Gui to your script, \nso user can interact and pass parameters to the script without using terminal.'}, {'comments': [{'comment': u"This is the new version that work very well into my projects:\n\nhttp://unipex.it/vario/RealPyOdbc.py\n\nThis can work on all the platforms where ctypes work.\nIn the future I'll make it db-api 2.0 compliant.\nIf you have some question, email me directly.", 'title': u'New version'}], 'desc': u'This class implement the features of retrieve dsn and tables list on win32. win32all not include this features.'}, {'comments': [], 'desc': u'The "xmlcharrefreplace" encoding error handler was introduced in Python 2.3. It is very useful when encoding Unicode data for HTML and other XML applications with limited (but popular) encodings like ASCII or ISO-Latin-1. The following code contains a trivial function "encode_for_xml" that illustrates the "xmlcharrefreplace" error handler, and a function "_xmlcharref_encode" which emulates "xmlcharrefreplace" for Python pre-2.3.\n\nAn HTML demonstration is included. Put the code into a file, run it with Python, and redirect the output to a .html file. Open the output file in a browser to see the results.\n\nA variation of this code is used in the Docutils project. The original idea for backporting "xmlcharrefreplace" to pre-2.3 Python was from Felix Wiemann.'}, {'comments': [{'comment': u'I re-did my original implementation to use a metaclass and a class factory function, in recipe #303481. This "spawning" recipe is much easier to understand than the metaclass implementation; however, my tests show that the metaclass version is about 40% faster for named attribute access.\n<br>\nIf that\'s not enough, I just added an improved version of the metaclass implementation which reduces memory consumption and adds another 1400% speed improvement. You could probably get most of the same speed benefits in this recipe by using the same optimization of creating an actual attribute for each member and forgoing __getattr__.', 'title': u'Class construction'}, {'comment': u'The idea is far from being nove. See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/218485.', 'title': u'Not new'}, {'comment': u'In a footnote to recipe \nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52313 \n"Method for constructing a dictionary without excessive quoting"\n\nGanesan Rajagopal introduced the the attrdict...upon which I have become quite dependent: here it is again (in its entirety)\n\n<pre>\nclass attrdict(dict):\n def __getattr__(self, name):\n return self[name]\n\n def __setattr__(self, name, value):\n self[name] = value\n\ndata = attrdict(red=1, green=2, blue=3)\nprint data.red\ndata.black = 4\n</pre>\n\nDoesn\'t this do everything the named tuples (do with additional power?) ', 'title': u'attrdicts'}, {'comment': u'It depends on what you mean by "it does everything named tuples do (but additional power)". They are different. For one named tuples are immutable. Also, in all of the variants, they have a tuple-like interface (e.g. they allow getting the elements by index) not a dict-like interface. I would guess that name access is also faster. Prolly they also eat less memory.', 'title': u'Depends'}, {'comment': u'Thanks for mentioning your recipe. And while the named tuple, meta-class concept is not novel, there are certainly several different implementations available to readers now (at least recipes: 218485, 303481, and this recipe). ', 'title': u'Not novel indeed'}], 'desc': u"In recipe 303439 (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303439) Andrew Durdin presents a customized tuple class that permits individual item access via a named attribute. I think this concept is quite novel and, as Andrew points out, can greatly improve readability of code. In this recipe I implement his tuple concept in a slightly different manner. \n\nInstead of requiring the named attributes list for each instantiation of the tuple, my implementation 'Spawns' a derived tuple class that is taylored to the named attributes specified. And it is this Spawned class that is then used to instantiate tuples. My approach effectively separates the definition of the attribute names from the data specification. And in doing so, this approach diminishes instantiation hassles and further improves clarity."}, {'comments': [{'comment': u"The strict_sizing=True case is easy with itertools.izip:\n\n<pre>\ndef chunks(thing, chunk_length):\n return izip(*[iter(thing)]*chunk_length)\n</pre>\n\nUnfortunately, the strict_sizing=False case isn't as easy this way because itertools.imap aborts as soon as the first iterator is exhausted. You can make this work by redefining imap appropriately, but at this point, your solution is probably the cleaner one.\n\n<pre>\nfrom itertools import izip\n\ndef imap(*iterables):\n while True:\n args = []\n try:\n for i in iterables:\n args.append(i.next())\n except StopIteration:\n yield tuple(args)\n raise StopIteration\n else:\n yield tuple(args)\n\ndef chunks(thing, chunk_length, strict_sizing=True):\n return (strict_sizing and izip or imap)(*[iter(thing)]*chunk_length)\n</pre>\n", 'title': u'Another solution for iterables'}, {'comment': u'Thanks .. those itertools versions are definately nice, especially the first one. I also noticed this similar recipe using islice:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303279', 'title': u'more ways with itertools'}], 'desc': u'This is a simple recipie to iterate through data as a series of chunks of a given size.'}, {'comments': [{'comment': u'<pre>\n>>> from locals import local_dict as __dict__\n>>> def f():\n... \t__dict__[\'a\'] = \'a\'\n... \tprint a\n... \t\n>>> f()\nTraceback (most recent call last):\n File "", line 1, in ?\n File "", line 3, in f\nNameError: global name \'a\' is not defined\n>>> def f():\n... \t__dict__.a = \'a\'\n... \tprint a\n... \t\n>>> f()\nTraceback (most recent call last):\n File "", line 1, in ?\n File "", line 3, in f\nNameError: global name \'a\' is not defined\n\n\nYou _can_ do this:\n>>> def f():\n... \t__dict__[\'a\'] = \'a\'\n... \tprint __dict__[\'a\']\n... \t\n>>> f()\na\n\nBut that is not adding \'a\' to f\'s local namespace.\n</pre>', 'title': u'flocals are read-only'}, {'comment': u'Would rewording "any modifications are not guaranteed to be reflected" as "any modifications are guaranteed not to be reflected" better convey what you mean? The first wording implies that modifications might be reflected in the local namespace, whereas the second states that they won\'t be, which is what I understand you are after.', 'title': u'Suggested rewording in description'}, {'comment': u'Sean, thank you for pointing this out. It was truly careless of me to not test the cases you posted. I have spent the past few days looking into other ways to access (or mimic access of) a local namespace. To date, I have found none. \n\nI will leave the recipe as it is for now because there is some useful information in how I remapped the dict class. If and when a means of accessing a particular local namespace is found, it would only modify the __setitem__ method. ', 'title': u'Some other means needed'}, {'comment': u'Hamish, the wording I used originally does accurately convey what I was intending. The reason is that in certain circumstances, I am able to modify that dict returned by locals(), and those modifications will be reflected in the local namespace. It turns out that the solution I have presented here succeeds and fails exactly where the locals() function does. Thank you for sharing your concern.', 'title': u'locals() mods can succeed'}], 'desc': u"Accessing the local namespace dict is already done by calling the builtin method locals(). However, the limitation of doing this is that modifying the dict returned by locals() is not considered 'safe'. Safe in the sense that any modifications are not guaranteed to be reflected in the actual namespace.\n\nIn order to implement a 'safe' reference and modification of the local dictionary, I use sys._getframe().f_locals. This gives me direct access to the local dict each time I use it. But beyond just having safe access to the local dict, I also would like a local __dict__ dict that acts exactly the way a class __dict__ would. Currently, there is not a local __dict__ available. So here is a way to create your own:"}, {'comments': [{'comment': u'In the current CVS version SafeTemplate has been removed, see this:\nhttp://mail.python.org/pipermail/python-checkins/2004-September/043214.html', 'title': u'No more SafeTemplate'}, {'comment': u"Discussions on the Python development mailing list have led to changes in the structure of string templates.<p>\n<p>\nAt the time of this posting, CVS uses a single Template class, with separate, standard methods that implement the operations of the Template and SafeTemplate mod operators in this recipe, but I wouldn't consider the format settled until at least the first beta.", 'title': u'String templates will not take this form in Python 2.4'}, {'comment': u'I made the change in my comments to reflect this.', 'title': u'Thanks'}, {'comment': u'If you want to reach me (the author) you can find me at pyguy2 on yahoo', 'title': u'my email is pyguy2 on yahoo'}, {'comment': u'Which means the Template API can now be considered stable.<br>\n<br>\nA simple example of the new interface:<br>\n<pre>\nfrom string import Template\nt = Template("test = $test")\ntest = 5\n\nprint t.substitute(locals()) # prints "test = 5"\n\ndel test<br>\nprint t.safe_substitute(locals()) # prints "test = $test"\nprint t.substitute(locals()) # throws KeyError\n</pre>\n<br>\nAnd the simplest form of customisation:<br>\n<pre>\nfrom string import Template\nclass Percent_Template(Template):\n delimiter = \'%\'\n # Set idpattern to change what constitutes an \'identifier\'\n\np = Percent_Template("test = %test")\ntest = 5\nprint p.substitute(locals()) # prints "test = 5"\n</pre>\n<br>\nIt\'s also possible to change the pattern completely:<br>\n<pre>\nfrom string import Template\nclass Quote_Template(Template):\n """Substitute anything inside double quotes"""\n # Template expects four named groups in the pattern\n # We use empty named groups at the end for the\n # ones we don\'t need\n\n pattern = r"""\n "(?P.*)" # Replace anything between double quotes\n (?P)(?P)(?P)"""\n\nq = Quote_Template(\'test = "test"\')\ntest = 5\nprint q.substitute(locals()) # prints "test = 5"\n\nq = Quote_Template(\'tricky = "1 x z"\')\nprint q.substitute({"1 x z" : "tricky!"})\n# prints "tricky = tricky!"\n</pre>', 'title': u'The beta is out!'}], 'desc': u'New to python 2.4 is the string.Template class. It is similar to the formatting python already had in which the % operator with strings was used in a recognizable sprintf style of formatting from C. In addition to format types, you also had a choice with a tuple or dictionary mapping. String.Template simplifies it to only the string format type and dictionary mapping. This makes string formatting easier to remember and use. This example shows you the basics of using the template and the difference with the old style.'}, {'comments': [{'comment': u'When I tried posting the first the the web browser said it failed.\nI simply resubmitted it. I should have checked to see if it actually _did_ fail.', 'title': u'oops, previous posting seemed to fail sorry for the duplicate'}], 'desc': u'New to python 2.4 is the String.Template class. It is similar to the formatting python already had in which the % operator with strings was used in a recognizable sprintf style of formatting from C. In addition to format types, you also had a choice with a tuple or dictionary mapping. String.Template simplifies it to only the string format type and dictionary mapping. This makes string formatting easier to remember and use. This example shows you the basics of using the template and the difference with the old style.'}, {'comments': [], 'desc': u'A script to compare and diff two md5 files.'}, {'comments': [{'comment': u'This is a great little snippet of code - well done! \n As a relative newcomer to Python, I would be *very* keen to see an example of this algorithm using the built-in "csv" module to read a file and summarise the data. That would be a very nice "next step" for this algorithm, making it even more applicable to real-world use (given that csv or similar formats are widely used). \n ', 'title': u'Very nice example!'}, {'comment': u'Pretty simple: with a file sales.dat something like\n\n<pre>\nScotland,Edinburgh,20000\nScotland,Glasgow,12500\nWales,Cardiff,29700\nWales,Bangor,12800\nEngland,London,90000\nEngland,Manchester,45600\nEngland,Liverpool,29700\n</pre>\n\nall you do is change the definition of sales to\n\n<pre>\nsales = csv.reader(open("itert.dat"))\n</pre>\n\nOne other change is required - because the csv module returns all values as strings, you need to convert the values to integers - the value argument has to change to \n\n<pre>value=lambda r: int(r[2])</pre>\n\nrather than using itemgetter(2).\n<br>\nAdd error handling and explicit closing of files to taste...', 'title': u' '}], 'desc': u'Lists of data grouped by a key value are common - obvious examples are spreadsheets or other tabular arrangements of information. In many cases, the new itertools groupby function introduced in Python 2.4 can provide a means of easily generating summaries of such information.'}, {'comments': [], 'desc': u"You need to store arbitrary objects in a PostgreSQL database without being\nintrusive for your classes (don't want inheritance from an 'Item' or \n'Persistent' object)."}, {'comments': [], 'desc': u' '}, {'comments': [{'comment': u'note that the example creates a list, not a dictionary.', 'title': u'not a dictionary'}, {'comment': u"I'm not sure how new this feature is, but in Python 2.5 i use this:\n<pre>\ndi = d.items()\nif b_sorted:\n\tdi.sort() # by first item\n\nif b_ranked:\n\tdi.sort(key=lambda x: x[1]) # by second item\n</pre>", 'title': u' '}], 'desc': u'Python 2.4 adds a new builtin function sorted(), which can make obtaining the items of a dictionary sorted by key or value a single line operation.'}, {'comments': [], 'desc': u"The following code shows why you would want to use a heap instead of a list and the basics of using heapq in python with some additions for python 2.4( I've cleaned this up from earlier to make it hopefully clearer.)"}, {'comments': [], 'desc': u'Encapsulates lookups into a series of namespaces.'}, {'comments': [{'comment': u'Sorting must check already sorted parts in initial path, then make a merging between them.\nSeems, just need to expose merging stage of sorting algorithm to users in builtin function or lists method. ', 'title': u'This is good for inexpencive comparison'}], 'desc': u'New take on merging. Uses Python\'s "timsort" to merge in O(n) time.\n'}, {'comments': [], 'desc': u"This enumerated-values class is intended for use in module-level constants, such as an employee type or a status value. It allows simple attribute notation (e.g., employee.Type.Serf or employee.Type.CEO), but also supports simple bidirectional mapping using dictionary notation (e.g., employee.Type['CEO']-->1 or employee.Type[1]-->'CEO')."}, {'comments': [], 'desc': u'This sample connects to the running instances of IE on your computer and prints out the URL, Cookie- if any, and the HTML content of the site.\nIt can be extended to connect to running instances on another computer using DCOM and particularly using CoCreateInstanceEx():\nExtend it as you wish and let me know how useful it has been to you!'}, {'comments': [{'comment': u'This could be extended to allow remote modules to be imported through an import hook. The xhtmlhook module enables this by allowing URLs to be specified in the sys.path lists:\n\nhttp://www.boddie.org.uk/python/xhtmlhook/\n\nThere are obviously lots of other things being done in that module, but the remote importing could be stripped out and reused here.', 'title': u'Remote importing'}, {'comment': u'This one uses path hooks to import remote modules: http://urlimport.codeshift.net/.', 'title': u'urlimport'}], 'desc': u'Storing modules in a central location, which are used by remote, seperate clients has obvious benefits. This recipe describes a method by which modules can be fetched from a remote server and compiled into bytecode modules which are used by the client.\n\nThe recipe has 3 sections (server.py, client.py, test.py) which need to be copied into 3 files.'}, {'comments': [{'comment': u"Eric, great admin tool! I seemed to have a problem: if a modname was shorter than one earlier in the list, it left part of the name behind. I'm running XP, if that makes a difference. My quick and dirty fix is to copy the line: <br><pre>\n modname = c_buffer(260)\n</pre>between the psapi.EnumProcessModules and the psapi.GetModuleBaseNameA lines.<br>This is possibly overkill, creating a new c_buffer, but on a single machine, it's hard to run enough processes to make this noticeable.\n\n<br>Cheers,<br>\nGordon Hennesy", 'title': u'modname not getting cleared'}, {'comment': u'Thanks Gordon. Fixed the bug by cleaning up the contents of modname variable', 'title': u' '}, {'comment': u"I need to match both user name and process name to correctly identify the process I'm interested in, so I've added this snippet of code (called when the process name is the targetted process):\n<pre>\nimport win32api, win32con, win32security\nfrom ntsecuritycon import TokenUser\nappname = 'Name of target application'\ncurrentUserName = None\n\n...\n\nif appname==procName:\n if not currentUserName:\n tok = win32security.OpenProcessToken(win32api.GetCurrentProcess(),\n win32con.TOKEN_QUERY)\n sid, attr = win32security.GetTokenInformation(tok, TokenUser)\n win32api.CloseHandle(tok)\n currentUserName, dom, typ = win32security.LookupAccountSid(None, sid)\n\n hToken = win32security.OpenProcessToken(hProcess, win32con.TOKEN_QUERY)\n if hToken:\n sidObj, intVal = win32security.GetTokenInformation(hToken, TokenUser)\n if sidObj:\n accountName, domainName, accountTypeInt = win32security.LookupAccountSid(None, sidObj)\n if accountName==currentUserName:\n print 'accountname=%s'%accountName\n else: print 'NOT current user'\n win32api.CloseHandle(hToken)\n</pre>", 'title': u'Need user name, process name'}], 'desc': u'This recipe will enumerate active processes as seen under windows Task Manager on Win NT/2k/XP using PSAPI.dll (new api for processes) and using ctypes.\nUse it as you please'}, {'comments': [], 'desc': u'A script demonstrating how to manually do basic authentication over http.'}, {'comments': [], 'desc': u'Doctest and unittest are like 2 extremes of testing your python\ncode. One is simple and intuitive and the other is powerful and\nrequires more formality. In Python 2.4, doctest, builds in some of the\npower of unittest, perhaps bridging the gap between the two. This\nexample shows you how to use doctest and the doctest.DocFileSuite\nfeature.'}, {'comments': [], 'desc': u'A function to detect the presence of Microsoft Cluster Services on a server, and return the proper Windows network name of the server. Useful in scripts targeting Microsoft SQL Servers, where determining the two part Server\\Instance naming convention is necessary.'}, {'comments': [], 'desc': u'A script to automate the movement of databases from one Microsoft SQL Server to another. Designed to detach, copy, and reattach database files with a single call. Used to move databases with a minimum of downtime.\n\nProcess contains examples of Windows Cluster detection, and the querying of physical database characteristics and operations (default directories, list of files comprising database, detach/attach, login/SID matching).'}, {'comments': [], 'desc': u'Reads the Microsoft Baseline Security Analyzer 1.2.1 XML output and sends it to standard output in a readable text format.'}, {'comments': [{'comment': u'This recipe might be an even better introduction to sorting in Python 2.4 if you were to user operator.itemgetter and operator.attrgetter instead of defining your own functions to do their work.', 'title': u'user itemgetter and attrgetter'}, {'comment': u"I wanted to specifically show off some basics of how list.sort() changed, to keep things simple and understandable. Way back, when I was teaching people perl, I tended to lose people if I wasn't careful. Python may not suffer as much from that, but I am still cautious. I'll put up another post adding to it some other ideas.", 'title': u'wanted to limit what you had to know -- but you are right '}, {'comment': u'I changed my mind and put it all together.', 'title': u'decided to put it all in one big one'}, {'comment': u'sorted() is a builtin, rather than a static method of list.<br><br>\n\nCheers,<br>\nNick.', 'title': u' '}, {'comment': u'Thanks, I fixed that.\n\njohn', 'title': u'thanks'}, {'comment': u'<pre>def mycmp(a, b):\n return cmp(a[1], b[1])</pre>\nwill do.', 'title': u'Also, why do you build your own cmp?'}, {'comment': u"I was trying to make it easier to see what is happening when you look at cmp1 and cmp2. But, I should have mentioned the builtin cmp. Thanks for bringing that up. I'll fix that.", 'title': u'good point, should have mentioned it'}], 'desc': u'Python 2.4 has added a new feature to handle the problem where you needed to do\na sort based off of part of the data. In effect, it has simplified the Schwartzian Transform \n(which I learned many years ago from an perl article \nwritten by Randall Schwartz). The following code will start with the older style\npython sorting approaches, and then show the bisect and heapq modules, and \nfinally the key,cmp,reverse methods newly added to sort. The sort method of the\nlist is an in-place sort. There is also a new sorted() function which\nreturns a copy of the list sorted for you. '}, {'comments': [{'comment': u'Just for folks who might be searching for recipes, you probably want to correct the spelling of the last word of the name to "substitution".', 'title': u' '}, {'comment': u"Nice idea. Makes templates much more new-user friendly. But so that you don't have problems with templates that contain percent signs, you might want to change the return statement to be\n<pre>\n return re.sub(pattern, r'%(\\1)s', template.replace('%','%%'))\n</pre>\n\nThen you can do things like\n\n<pre>\n >>> s = 'People of [planet], take 15% of us to your leader.'\n >>> print convert_template(s) % d\n People of Earth, take 15% of us to your leader.\n</pre>", 'title': u'Small change to support percent signs already in the template.'}], 'desc': u'Replaces %(name)s style formatting with [name] style formatting. Custom open and close delimiters can be specified. Useful for templates exposed to end-users.'}, {'comments': [], 'desc': u'Here we will demonstrate a technique that will make it possible to semi-transparently proxy an object and override/proxy methods or data including special methods like __call__.\nthis module will define several general tools and components that can be used as a basis for creation of various proxy classes...'}, {'comments': [], 'desc': u'Builds a directory tree in XML format. Demonstrates how to use xml.dom.minidom to rapidly construct nested XML with multiple element types and attributes. Serves as a model for building model complex documents.'}, {'comments': [], 'desc': u"These are just some simple examples of how you can leverage the operator module to help gain performance with something like map (it works great with sort too). There are times where techniques like this may be necessary. Generally, you'd want to avoid doing this simply because it makes python ugly and harder to debug. "}, {'comments': [{'comment': u'Is the first parameter to super() correct in the mytuple and mydict classes? Thanks for sharing this!', 'title': u'super() use in class mytuple and mydict?'}, {'comment': u'In Numeric/numarray, ar[5,7] would be the element in the two dimensional position (5,7), and etc.\nFor someone used to numarray, like me, seeing code using your mytuple would be rather confusing.', 'title': u'nice. but confusing for numarray users'}, {'comment': u"Randy wrote:<br><br>\n\nIs the first parameter to super() correct in the mytuple and mydict classes? Thanks for sharing this!<br><br>\n\nNo, it's not, but the problem won't show up until you try to subclass it. In general, using self.__class__ as the first argument to super() is a Very Bad Idea. Here's a quick example. We start with this:\n\n<pre>\nclass A(object):\n def f(self,x): print x\nclass B(A):\n def f(self,x): super(self.__class__,self).f(x+1)\n</pre>\n\nWhich appears to work just fine. But then we subclass B, we get trouble:\n\n<pre>\nclass C(B):\n def f(self,x): super(self.__class__,self).f(x+2)\n</pre>\n\nNow, when we call C().f(5), we get a maximum recursion error. Why? Because the call to super(self.__class__,self) in B finds the superclass of self *relative to self.__class__*. But self.__class__ is C. So it returns B. \n\nBottom line: you should *always* specify the class containing a method explicitly when using super -- if it could be done automatically, then that first argument wouldn't be there. :)", 'title': u'Re: super() use in class mytuple and mydict?'}], 'desc': u'The following recite shows a small addition to the tuple, list, and dictionary classes to allow for a simpler way to retrieve a number of independant items. By allowed for the subscripting to use tuples some very annoying cases becomes much simpler.'}, {'comments': [{'comment': u'<pre>\ndef orderBy(sortlist, orderby=[], desc=[]):\n for i in reversed(orderby):\n sortlist.sort(key=operator.itemgetter(i), reverse=(i in desc))\n return sortlist\n</pre>', 'title': u'and in Python 2.4'}, {'comment': u'can you please explain the code which Steve Lucy has written.\nwhat is the use of *\nhow is the cmp function working inhis code\nthanks', 'title': u'please explain'}, {'comment': u"The * causes the tuple we choose, (x[i], y[i]) or (y[i], x[i]), to be mapped to the function's arguments, instead of being passed as a single argument (i.e., cmp(x[i], y[i]) and not cmp((x[i], y[i]))\n<br><br>\nLet's say you have a function:\n\n<pre>def Add(a, b):\n return a + b\n</pre>\nand a list of values you want added:\n<pre>w = [(1, 2),\n (2, 2),\n (3, 4)]</pre>\n\ninstead of saying something like:\n<pre>for a, b in w:\n print Add(a, b)</pre>\nYou could say:\n<pre>for i in w:\n print Add(*i)</pre>", 'title': u' '}], 'desc': u'This function allows you to easily sort a list by multiple columns in ascending and descending orders similar in function to the ORDER BY clause in SQL.'}, {'comments': [], 'desc': u'Itertools.tee offers an interesting way to "remember" things that have happened.\nItertools.tee makes multiple iterators from one (if you still have an the original iterator you do not use it). When you advance iterator 1 but not iterator 2, iterator 2 stays behind. Which means, if you later advance iterator 2, it the goes forward through the same data.\n\nIn this example, I use iterator.tee to make 2 iterators, to allow an action to affect data that has been processed in the past. The first iterator, it_main, is what is used to process data normally in this case to do something like display an image selected. The second iterator, it_history, stays behind the first and only advances when a specific action arrives. In effect, it rolls forward through the data that it_main has already processed.'}, {'comments': [], 'desc': u'This script enumerates printer jobs from a specified default printer. This information includes Jobid, Document name,\nusername of person submitting the job etc and if you are lucky would be able to get the spool file (SPL file format) from\nthe printer. It could be used as a printer monitor for job accounting.'}, {'comments': [{'comment': u"You can also print errant floats like '%.4f' % aFloat. There's a bunch of other ways to control float printing using %f, like '%10.4f' means left-pad (right justify) it out to ten characters (including .####), using spaces. Note the 10 applies to the entire length, including the decimal part and the -. '%010.4' means left-pad it with zeros. I think tehre's some other options as well, e.g., '%-10.4' will right-pad (left justify).", 'title': u'printing floats'}, {'comment': u"I've used them myself before and forgot about that. Thanks for the idea!", 'title': u'good idea'}], 'desc': u"Below you will find a simple python class that I wrote to test performance of\nvarious different sorting techniques. In this cas: list, heapq, and bisect. For printing out data, I make use of the very cool decimal module to limit errant floating point numbers with many digits. It helps me decide when I want to think about different types of sorts.\n\nPython's list.sort is so good that generally you are not going to want to write\nyour own sort, and instead use it and some of the new features recently added to it. However, with a list.sort you pay for sorting at retrieval time. A different type of sort using data structures to sort at creation time instead of retrieval can offer some performance characteristics, that may make one consider them instead. "}, {'comments': [{'comment': u"The is callable builtin is planned on becoming obsoleted in Python 3000.\n\nAlso, why should I care if an object has a callable called index? I can just try and call it, and if it isn't an exception will be called for me?", 'title': u'callable becoming obsolete'}, {'comment': u"I thought operator.isCallable was deprecated. I'll have to check about callable.\n\nWith regards to index in string, you can put in there whatever you find is sufficient to be stringlike for your uses. I happened to use index as one of the requirements. If it reaches that point it is not am instance of a native native python string, so, how string-like you want it to be is up to you.", 'title': u'callable obsolete?'}], 'desc': u'Managing types is normally simple in python, since it does typing as late as possible during runtime. Sometimes the issues of type still rears it\'s head, especially among programmers used to the "type at compile time" variants.\n\nYou want to resist doing a naive approach like type(obj)==str, since you then ignore subclasses.\n\nWhat this recipe does is make a distinction between objects that _are_ are certain type or it\'s subclass and objects that act good enough. Most of the time\nthe difference will not matter. If it is a certain python type or in some cases like with a sequence, possible among a few python types, it returns a 1, if it is good enough it returns a -1, and finally it returns zero if it is not good enough.\n\nGood enough is enabled by checking for attributes and callables instead of explicit type and sometimes by checking for success of certain actions. In cases where it can be good enough, you simply check for just a true value which both 1 and -1 will evaluate to.\n\nI put in typical checks for many things ranging from generators to lists to file handles.'}, {'comments': [{'comment': u'This is based upon the format spec:\n\nhttp://www.respmech.com/mym2qifw/qif_new.htm', 'title': u'format spec'}, {'comment': u'First, thanks Brian for this. Google found it for me just like that.\n\nAlso, in the __repr__ method don\'t titles and tmpstring need to be joined by a newline, not a comma? Something like:\n<pre>\n return titles + "\\n" + tmpstring #changed "," to "\\n"\n</pre>\nCheers,\nBill', 'title': u'Thanks and a possible change'}, {'comment': u'I found I had to change \'AttributeError\' to \'TypeError\' to get the split parsing to work properly eg\n\n<pre>\ntry\n curItem.categoryInSplit.append(";" + line[1:-1])\nexcept TypeError:\n curItem.categoryInSplit = line[1:-1]\n<pre></pre></pre>', 'title': u'Small Issue with splits'}], 'desc': u"A simple class to represent a Quicken (QIF) file, and a parser to\nload a QIF file into a sequence of those classes.\n\nIt's enough to be useful for writing conversions."}, {'comments': [], 'desc': u'it use to fetchmail & distribute into every user...for now only use for local\nbut...only in class form..for now that i can present.\nuse "class fetch_mail first" -> "class re_ex"'}, {'comments': [], 'desc': u'it use to fetchmail & distribute into every user...for now only use for local\nbut...only in class form..for now that i can present.\nuse "class fetch_mail first" -> "class re_ex"'}, {'comments': [], 'desc': u'it use to fetchmail & distribute into every user...for now only use for local\nbut...only in class form..for now that i can present.\nuse "class fetch_mail first" -> "class re_ex"'}, {'comments': [], 'desc': u'Another way to read lines from file backwards from the end to the beginning'}, {'comments': [], 'desc': u'A simple but slow way of compression using arithmetic coding.'}, {'comments': [], 'desc': u'A simple script which queries a rpm package and prints few important rpm tags.'}, {'comments': [], 'desc': u'A strftime implementation that supports proleptic Gregorian dates before 1900'}, {'comments': [{'comment': u'Using indexing operation of lists is O(N). You should use dictionary instead.\n\nI myself went into trouble, when manipulating a graph of over 3,00,000 vertices!', 'title': u'O(n) access!'}, {'comment': u' ', 'title': u"I don't understand what's meant by the first sentence of the discussion."}, {'comment': u'TEST\n\n<pre>\nfrom time import time\nshort = [1]*1000\nmedium = [1]*100000\nlong = [1]*10000000\nfor L in [short, medium, long]:\n j = 0\n t = time()\n for i in xrange(1000000):\n _ = L[j]\n t1 = time()-t\n j = len(L)-1\n t = time()\n for i in xrange(1000000):\n _ = L[j]\n t2 = time()-t\n print "len=%08d, %f, %f" % (len(L), t1, t2)\n</pre>\n\nOUTPUT\n<br>\n<pre>\nlen=00001000, 1.901750, 1.935451\nlen=00100000, 1.913299, 1.920121\nlen=10000000, 1.960430, 1.937439\n</pre>\n\nIt doesn\'t seem to be O(n) for either n = length of list, or n = index value. Indeed, it would be quite mystifying if it were so as Python "Lists" are not lists in the LISP or "Linked List" sense but rather a sort of array that grows as necessary.\n<br>\n// Ben', 'title': u'O(n) list indexing? I think not.'}, {'comment': u"...the efficiency of an operation (for example, the time required, or memory consumed) as a function of some measure of the size of the input. \n<br>\nO(n) means that the time require grows at the same rate as the size of the input. In this concrete example, it's unclear if the original poster meant n to reflect the size of the array or the index within the array being accessed.\n<br>\nMore information can be found at: http://en.wikipedia.org/wiki/Big_O_notation", 'title': u'(Big "O" notation) expresses...'}, {'comment': u'"permutaton" -> "permutation" in the title, and fixed first sentence.', 'title': u'fixed typos'}], 'desc': u'Given a list, find the indices used to get the elements from the list in sorted order'}, {'comments': [], 'desc': u'Sometimes it is nice to print a banner line in the output of a command line script to group a section of output (say, in a log file). This little banner() function will center a given string in a line (using a character and length you can specify). '}, {'comments': [], 'desc': u'This recipe implements an observer pattern for dictionaries and lists. It does not support a one-many relation. The observer is sent enough information so that the change can be undone.'}, {'comments': [], 'desc': u'This recipe uses descriptors of new style classes to implement the observer pattern. This implementation supports exactly one observer (no one-many relation).\n\nThis recipe builds on recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/306864. It assumes that the text of the recipe is stored as "list_dict_observer.py".'}, {'comments': [], 'desc': u'Providing undo has become a standard feature for interactive programs. One approach to implement undo is to code each user level operation in three variants: a "do" version, an "undo" version, and a "redo" version.\n\nIf you can meet the requirements of this module, you only have to code the "do" variant.\n\nThis recipe builds on recipes http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/306864 and http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/306865. It assumes that those recipes are stored as list_dict_observer.py and scalar_observer.py, respectivly.\n'}, {'comments': [{'comment': u'<pre>\n def enumerate(iterable, start=0, enumerate=enumerate):\n for idx, obj in enumerate(iterable):\n yield idx + start, obj\n</pre>', 'title': u'Why so complex?'}, {'comment': u"Well, for one thing it takes about twice as long as the proposed solution would (if it wasn't buggy). On my system enumerating a list of 10000000 takes between 7.8 and 8.8 seconds with the solution described in the article versus 18 seconds with your solution. This is because you've introduced an extra layer of iterator.", 'title': u'Why not...'}, {'comment': u'<pre>\ndef enumerate(a, b=None):\n "enumerate([start,] iterable)"\n if b is None:\n start, iterable = 0, a\n else:\n start, iterable = a, b\n return izip(count(start), iterable)\n</pre>', 'title': u"return is incorrectly part of the 'else' clause"}], 'desc': u'Adds an additional start argument to the built-in enumerate function.'}, {'comments': [], 'desc': u'A class whose objects can handle undefined method calls, passing them on to a \ndefault handler.'}, {'comments': [{'comment': u'If this script is saved as p.py in sys.path somewhere, one could even pretend there were an extended -m switch ;-)\n<pre>\npython -mp pychecker.checker mymodule\n</pre>', 'title': u'Works great.'}, {'comment': u"Why isn't this functionality part of the built in support?", 'title': u'Silly question but...'}, {'comment': u"Mainly due to the fact that the top-level module support was easy to build in to the interpreter (basically a single call to _PyImport_FindModule, plus error checking), but you can see for yourself that the full-fledged version is at least moderately complicated (even when written in Python!).<br>\n<br>\nThere's an SF patch (#1043356) based on the idea of automatically invoking this Python module from C if the search for a top-level module fails, but the current implementation of the switch has been kept fairly simple. This might have been different if we were further from the first Python 2.4 beta.<br>\n<br>\nSufficient support/demand on c.l.p. could still result in the interpreter getting native support for executing scripts inside packages. Given how long Python has gone without this feature at _all_, I'm not expecting that to happen before Python 2.5 (if it happens at all)", 'title': u' '}, {'comment': u"My last comment touched on the practical and political reasons, but there was a design reason too.<br><br>\n\nThe original pitch for the behaviour of the '-m' switch is that it is exactly like executing the located module by specifying its full filename on the command line.<br><br>\n\nThat doesn't hold true for modules inside packages - the containing packages have to be imported in order to reliably locate the modules they contain. The problem is that this doesn't match the behaviour obtained by directly supplying the full path to the script.<br><br>\n\nExpanding the description of the semantics to cover modules inside packages is certainly possible - but see the previous comment for why that isn't as straightforward as it might first seem.", 'title': u'The design reason for it'}, {'comment': u'Well this is what I use as my "pyrun" script.. it seems a bit simpler than what you\'ve got there:\n\n<pre>\n#!/usr/bin/env python\ndef _run():\n import sys, os, imp\n def imp_find_module(name):\n """same as imp.find_module, but handles dotted names"""\n names = name.split(\'.\')\n path = None\n for name in names:\n result = imp.find_module(name, path)\n path = [result[1]]\n return result\n path = imp_find_module(sys.argv[1])[1]\n sys.argv[:2] = [path]\n sys.path[0] = os.path.dirname(path)\n execfile(path, globals(), globals())\n_run()\n</pre>', 'title': u'pyrun'}, {'comment': u"The additional complexity in my version is due to the following properties:<br>\n- respect package __path__ variables<br>\n- mimic execfile argument handling<br>\n- mimic the standard '-m' error responses<br>\n<br>\nFor my own use, I would probably have written a version more like yours (aside from the __path__ variable issue). However, I'm proposing this as an addition to the standard library for 2.5, so its a bit more polished than most of my personal-use-only scripts.", 'title': u' '}, {'comment': u"In fact, I just realised that the original attempt at allowing dotted names with -m implemented something very similar to this, only in C, rather than Python.<br><br>\n\nThe concept was dropped for Python 2.4 after I realised it didn't actually follow Python's import semantics correctly.", 'title': u' '}], 'desc': u'Python 2.4 provides the \'-m\' option to run a module as a script. However, "python -m <script>" will report an error if the specified script is inside a package.\n\nPutting the following code in a module called "execmodule.py" and placing it in a directory on sys.path allows scripts inside packages to be executed using "python -m execmodule <script>".'}, {'comments': [{'comment': u'This version 1) fixes the inconsistency between the printed strings and the code and 2) shows how the TimedOutException can be caught to do any cleaning up required:\n\n<pre>\nimport signal, time\n\nclass TimedOutExc(Exception):\n def __init__(self, value = "Timed Out"):\n self.value = value\n def __str__(self):\n return repr(self.value)\n\ndef TimedOutFn(f, timeout, *args):\n def handler(signum, frame):\n raise TimedOutExc()\n \n signal.signal(signal.SIGALRM, handler)\n signal.alarm(timeout)\n\n return f(*args)\n\n signal.arlam(0)\n\ndef timed_out(timeout, *args):\n def decorate(f):\n def handler(signum, frame):\n raise TimedOutExc()\n \n def new_f(*args):\n signal.signal(signal.SIGALRM, handler)\n signal.alarm(timeout)\n return f(*args)\n signal.alarm(0)\n new_f.func_name = f.func_name\n return new_f\n return decorate\n\n\ndef fn_1(secs):\n time.sleep(secs)\n return "Finished"\n\n@timed_out(4)\ndef fn_2(secs):\n time.sleep(secs)\n return "Finished"\n\n@timed_out(2)\ndef fn_3(secs):\n time.sleep(secs)\n return "Finished"\n\n@timed_out(2)\ndef fn_4(secs):\n try:\n time.sleep(secs)\n return "Finished"\n except TimedOutExc:\n print "Caught TimedOutExc, and re-raising it"\n raise TimedOutExc\n \nif __name__ == \'__main__\':\n\n try:\n print "fn_1 (sleep 2, timeout 4): ",\n print TimedOutFn(fn_1, 4, 2)\n except TimedOutExc:\n print "took too long"\n \n try:\n print "fn_2 (sleep 2, timeout 4): ",\n print fn_2(2)\n except TimedOutExc:\n print "took too long"\n\n try:\n print "fn_1 (sleep 4, timeout 2): ",\n print TimedOutFn(fn_1, 2, 4)\n except TimedOutExc:\n print "took too long"\n \n try:\n print "fn_3 (sleep 4, timeout 2): ",\n print fn_3(4)\n except TimedOutExc:\n print "took too long"\n\n try:\n print "fn_4 (sleep 4, timeout 2): ",\n print fn_4(4)\n except TimedOutExc:\n print "took too long"\n\n\n~/src/python caw$ python sig_test.py\nfn_1 (sleep 2, timeout 4): Finished\nfn_2 (sleep 2, timeout 4): Finished\nfn_1 (sleep 4, timeout 2): took too long\nfn_3 (sleep 4, timeout 2): took too long\nfn_4 (sleep 4, timeout 2): Caught TimedOutExc, and re-raising it\ntook too long\n\n</pre>\nI\'d be grateful if the editors could perhaps replace the code I submitted with this (perhaps more useful and less confusing) version!', 'title': u'ack!!! print strings and code not in sync!'}, {'comment': u"Go to My Recipes and click the recipe's edit link.", 'title': u'You can edit the original'}, {'comment': u"I've been hit by a clue stick, so have edited (and slightly improved) the recipe (by adding in **kwargs). My above comment is superfluous.", 'title': u'Ignore the above comment!'}, {'comment': u"You have this code:\n\n<pre>\n return f(*args)\n signal.arlam(0) # sic\n</pre>\n\nDoes the typo'd signal.arlam() serve any purpose? I don't see how it could ever get executed.", 'title': u'reset alarm?'}, {'comment': u"I would modify the try block in the wrapper function as below adding also signal.alarm(0) in the finally clause to reset the timer. Else the signal could trigger TimedOutExc in some outside block if 'f' raises some other exception.\n<pre>\ntry:\n result = f(*args, **kwargs)\nfinally:\n signal.signal(signal.SIGALRM, old)\n signal.alarm(0)\n</pre>", 'title': u'Alarm remains active in case of exception'}], 'desc': u"This recipe presents two ways to time out the execution of a callable. It relies on signal.SIGALRM; I've only tested in on MacOSX. One way (TimedOutFn) works on Python 2.3.4, and the second uses the decorator syntax introduced in 2.4a. In this version, I've used the code from John Speno's page (http://www.pycs.net/users/0000231/). He's done a better job of handling the signals, and I like the try/finally expression."}, {'comments': [{'comment': u'This is the implementation of a similar idea that I use in SQLObject ( http://sqlobject.org ). This function simply looks for appropriately-named methods, and creates properties based on that.<br><br>\n\nWhile it\'s just a builder function, that function can be used in a metaclass fairly easily to automatically call the function with the new class as an argument. To make a read-only attribute, you simply don\'t create a _set_attr method for that attribute.\n\n<pre>\ndef makeProperties(obj):\n """\n This function takes a dictionary of methods and finds\n methods named like:\n * _get_attr\n * _set_attr\n * _del_attr\n * _doc_attr\n Except for _doc_attr, these should be methods. It\n then creates properties from these methods, like\n property(_get_attr, _set_attr, _del_attr, _doc_attr).\n Missing methods are okay.\n """\n\n if isinstance(obj, dict):\n def setFunc(var, value):\n obj[var] = value\n d = obj\n else:\n def setFunc(var, value):\n setattr(obj, var, value)\n d = obj.__dict__\n\n props = {}\n for var, value in d.items():\n if var.startswith(\'_set_\'):\n props.setdefault(var[5:], {})[\'set\'] = value\n elif var.startswith(\'_get_\'):\n props.setdefault(var[5:], {})[\'get\'] = value\n elif var.startswith(\'_del_\'):\n props.setdefault(var[5:], {})[\'del\'] = value\n elif var.startswith(\'_doc_\'):\n props.setdefault(var[5:], {})[\'doc\'] = value\n for var, setters in props.items():\n if len(setters) == 1 and setters.has_key(\'doc\'):\n continue\n if d.has_key(var):\n if isinstance(d[var], types.MethodType) \\\n or isinstance(d[var], types.FunctionType):\n warnings.warn(\n "I tried to set the property %r, but it was "\n "already set, as a method (%r). Methods have "\n "significantly different semantics than properties, "\n "and this may be a sign of a bug in your code."\n % (var, d[var]))\n continue\n setFunc(var,\n property(setters.get(\'get\'), setters.get(\'set\'),\n setters.get(\'del\'), setters.get(\'doc\')))\n</pre>', 'title': u'using naming conventions'}, {'comment': u'In this example you cannot overload the generated accessors. \nYou ca do this by adding a line to the _addMethod function:\n<pre>\ndef _addMethod(fldName, clsName, verb, methodMaker, dict):\n """Make a get or set method and add it to dict."""\n compiledName = _getCompiledName(fldName, clsName)\n methodName = _getMethodName(fldName, verb)\n if not dict.has_key(methodName):\n dict[methodName] = methodMaker(compiledName)\n</pre>\nthen:\n<pre>\nif __name__ == "__main__":\n class Employee:\n __metaclass__ = Accessors\n _READ_WRITE = [\'name\']\n def __init__(self, name):\n self.name = name\n \n def getName(self):\n return \'my name is: %s\' % self.name\n\n e = Employee(\'Machin chose\')\n print e.getName()\n</pre>', 'title': u'overloading accessors...'}], 'desc': u'This is an example of metaclass-as-code-generator. The metaclass writes the requested get/set methods automatically.'}, {'comments': [], 'desc': u"When writing unit tests for Python using the standard unittest.py system the assertRaises() (aka failUnlessRaises()) method is used to test that a particular call raises the given exception. This recipe if for assertRaisesEx() that adds three things: (1) the ability to assert the raised exception's args; (2) the ability to test that the stringified exception matches a given regular expression; and (3) much better failure messages."}, {'comments': [{'comment': u'IT SEEMS TO ONLY PRODUCE A PS FILE FOR THE FIRST PAGE OF THE DOCUMENT. This has not to do with the script itself but with the method used in the script because I could obtain the same result by printing the word document to a file.', 'title': u'ONLY THE FIRST PAGE ???'}, {'comment': u'"If someone know how to start multiple instances o Powerpoint 2000/XP with COM under Python and Pywin please let me know whow to solve that."<br><br>\n\nSome MS Office applications, such as Word and Excel, are capable of opening multiple instances. Others, including PowerPoint and Outlook, can only open a single instance.<br><br>\n\n- Jon<br>\n-------<br>\nJon Peltier, Microsoft Excel MVP<br>\nPeltier Technical Services<br>\nTutorials and Custom Solutions<br>\nhttp://PeltierTech.com/<br>\n_______<br>\n', 'title': u'msoffice2ps - a Microsoft Office to Postscript converter'}], 'desc': u"This Python module converts Microsoft Office documents to Postscript via an installed Postscript printer driver. For example you can build your own Microsoft Office to PDF Converter with Ghostscript. Ready to run applications (webbased or batch converter) you can find at http://www.goermezer.de .\n\nThis script needs Pywin32 from Marc Hammond (http://sourceforge.net/projects/pywin32/) and an installed Postscript printer driver.\n\nSimply import msoffice2ps and make a msoffice2ps.word('c:\\\\testfile.doc', 'c:\\\\testfile.ps', 'ps_printername') to convert a Wordfile to Postscript."}, {'comments': [], 'desc': u"This CGI will generate a simple text 'hit counter' for several sites.\nUseful to ocunt visitors to the 'front door' of your website."}, {'comments': [{'comment': u'Maybe I have a version problem. When set up as recommended I get:\n<pre>\nChecking in gorey.txt;\n/home/cvs/repository/tgncvstests/cshapiro/gorey.txt,v <-- gorey.txt\ninitial revision: 1.1\ndone\nTraceback (most recent call last):\n File "/home/cvs/utils/scripts/commit2rss.py", line 93, in ?\n Publisher(rssFilename, repositoryName)\n File "/home/cvs/utils/scripts/commit2rss.py", line 44, in __init__\n self.write(filename)\n File "/home/cvs/utils/scripts/commit2rss.py", line 88, in write\n open(filename, "w").write( str(self.channel) )\n File "/usr/local/lib/python2.3/site-packages/RSS.py", line 248, in __str__\n return self.output(self.listItems())\n File "/usr/local/lib/python2.3/site-packages/RSS.py", line 275, in output\n {(ns.rdf, \'about\'): channelMD[(ns.rss10, \'link\')]})\n File "/usr/local/lib/python2.3/xml/sax/saxutils.py", line 116, in startElementNS\n name = self._current_context[name[0]] + ":" + name[1]\nTypeError: unsupported operand type(s) for +: \'NoneType\' and \'str\'\n</pre>\n\nI\'m pretty green at python, but I did check the xml "__init__.py"\nfile and it seems to show that I\'m on version 0.8.2 of the xml stuff.', 'title': u'Ouch, dang it'}, {'comment': u'with pyXML version >= 0.8.3 the script is working', 'title': u' '}, {'comment': u'Yep, that was it. After a great deal of bureaucratic wrangling,\nI got 0.8.4 installed on the server in question. Now it runs\njust fine.', 'title': u'Requires XML 0.8.3 or better'}, {'comment': u"I have absolutely no plan about Python but I want to use commit2rss.py for my project BioWeka on Sourceforge. I installed and configured it as described:\n\n- copied both RSS.py and commit2rss.py to /home/groups/b/bi/bioweka/\n- changed DROP_DIR to /home/groups/b/bi/bioweka/htdocs/rss\n- added this line to loginfo: /home/groups/b/bi/bioweka/commit2rss.py\n- commited loginfo\n- made /home/groups/b/bi/bioweka/htdocs/rss writeable\n\nBut: There are no files within this directory after I commited changes to the repository. What did I wrong or what didn't I? How to debug it? E.g. call commit2rss.py manual from shell?", 'title': u'How to set up/debug commit2rss.py on Sourceforge'}, {'comment': u"If you're using this script with cvs-1.12.x, you need to change '%{}' to '%{p}' in your CVSROOT/loginfo file. Also make sure that 'UseNewInfoFmtStrings=yes' is set in your CVSROOT/config file if you are upgrading from an earlier version of CVS. This will get rid of the warnings about use of deprecated format strings.", 'title': u'Using with cvs-1.12.x'}], 'desc': u'Track commits to CVS repositories as RSS feeds.'}, {'comments': [], 'desc': u'When running unit tests, using the verbose flag often provides an extra level of protection against mistakes. When running from the command line, this simply means adding the -v option. If you use an IDE, matters become more complicated. While you can often set your IDE to pass in the -v option when running a file, this has a number of drawbacks. This code will ensure that your tests will run with the verbose option.'}, {'comments': [], 'desc': u"Parse the online documentation for compiler.ast and generate code for a skeletal ASTVisitor class that includes stubs for all of the various visitNODE functions you might need in a visitor, along with comments in each function that list that node type's attributes."}, {'comments': [], 'desc': u'ASTVisitor with stub functions for all of the ast.Node types list in the compiler.ast documentation, with comments describing Node attributes.'}, {'comments': [{'comment': u"Note that this code is quite simple thanks to the existence of the Global Interpreter Lock and the fact that the methods are natively implemented. This means that not two threads will ever run concurrently the native methods of Lock and RLock, except where I said it could using the (equivalent of) Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros.<br><br>\nThe GIL is required because I make some tests on self.locked, then do something based on the its value (same thing with self.locker). If I was in a truly multithreaded environment, things could change between the test and its consequences, so I would have to think about putting locks in my locks...<br><br>\nAnyway, this is the result of an hour and a half of discovering Pyrex and the (partly hidden) PyThread C API. From now on, I'm going to try to minimize the dependencies on the GIL, if it's possible.", 'title': u'Many thanks to the GIL'}, {'comment': u"AFAIK, locking is not time-critical. It is critical, in the sense that the manipulation of the lock object should be atomic (i.e. no other thread should manipulate it at the same time), but the time factor shouldn't matter.\n<br>\nOf course, making it faster helps for general performance, but it doesn't automatically make it safer. If the locking mechanism is flawed, speeding it up will only lower the probability that it fails, but it will still fail eventually.\n<br>\nAfter all this rambling, I still want to thank you for this useful example of Pyrex, it makes me want to look more into it.", 'title': u'Nitpicking?'}, {'comment': u'...it can be nitpicking indeed since I have to confess that I have yet to see the result of a Python profile showing "ha ! RLock.acquire() is an hotspot !". Anyway, I usually use locks on time critical paths (all the more critical that they are contention points for threads) and I feel much better with a native, lightweight implementation than the current threading.RLock implementation (which is not so lightweight).', 'title': u'Well...'}], 'desc': u'Locks or mutexes are very basic primitives used to coordinate threads operations in multi-threaded programs. Unfortunately, even if Python provides a low-level implementation of locks in the thread module, the high level implementation of threading RLock is still in Python code, which is a bit worrying since locking is always a time critical task. This recipe implements both locks in Pyrex to get the speed of native code, and gives an example of how great Pyrex is.'}, {'comments': [{'comment': u'very useful.', 'title': u'thanks!'}], 'desc': u'A port of Poul-Henning Kamp\'s MD5 password hash routine, as initially found in FreeBSD 2. It is also used in Cisco routers, Apache htpasswd files, and other places that you find "$1$" at the beginning of password hashes.'}, {'comments': [{'comment': u"to make this more generic I'd update the __call__ method to:\n<pre>\n def __call__(self, *args, **kw):\n cache = self._cache\n try: \n return cache[(args, kw)]\n except KeyError:\n cachedValue = cache[(args, kw)] = self._callable(*args, **kw)\n return cachedValue\n\n</pre> ", 'title': u' '}, {'comment': u'Memoization is nice technique. But making it implicit will lead to programmers forgetfullness in controlling memory usage the cache takes. \n\n"Explicit is better than Implicit"', 'title': u'Memory boom!'}, {'comment': u"Unfortunately it's not that straightforward; a dict is not hashable, so you can't use it as a key in the cache. One way to make this work is to define an ImmutableDict subclass that is (__hash__)able. Then wrap **kwds into such an ImmutableDict before caching them. However I wanted to keep this recipe simple, hence the less general solution. \n\nAnyway, I updated the recipe for handling keyword arguments too.\n\n", 'title': u'Handling **keywords'}, {'comment': u"That's what is neat about decorators; they make it explicit at the point of method definition. It is also straightforward to replace the dict used for cache with any other appropriate class to address issues such as memory consumption, efficiency or anything else that is important for the application:\n\n<pre>\ndef cachedmethod(cache = dict()):\n return lambda function: types.MethodType(Memoize(function,cache), None)\n\nclass Memoize:\n def __init__(self, function, cache = dict()):\n self._callable = function\n self._cache = cache\n \n # rest methods \n # (...) \n\n# uses a dict\n@cachedmethod()\ndef example1(x,y,z):\n pass\n\n# uses an LRU policy with a cache of size 1000\n@cachedmethod(cache = LRU(size=1000))\ndef example2(x,y,z):\n pass\n\n</pre>\n\n", 'title': u' '}, {'comment': u'<pre>\nimport pickle, copy\ndef memoize(f, cache={}):\n d = copy.copy(cache)\n def g(*args, **kwargs):\n key = pickle.dumps((args, kwargs))\n if not key in d:\n d[key] = f(*args, **kwargs)\n return d[key]\n return g\n</pre>\n\nWorks with builtin dicts, lists, allows arbitrary cache objects.\nYes, this will use up your memory and crash your system if the cache gets too big.', 'title': u'Simple is better than complex'}, {'comment': u'This doesn\'t work with Python 2.4.\n\n<pre>\nTraceback (most recent call last):\n File "memo-test.py", line 48, in ?\n class Example:\n File "memo-test.py", line 54, in Example\n @cachedmethod\n File "memo-test.py", line 4, in cachedmethod\n return types.MethodType(Memoize(function), None)\nTypeError: unbound methods must have non-NULL im_class\n</pre>', 'title': u'Broken'}, {'comment': u'This will corretly decorate a method:\n<pre>\ndef memoize(function):\n return Memoize(function)\n\nclass Memoize(object):\n def __init__(self, fn):\n self.cache={}\n self.fn=fn\n\n def __get__(self, instance, cls=None):\n self.instance = instance\n return self\n \n def __call__(self,*args):\n if self.cache.has_key(args):\n return self.cache[args]\n else:\n object = self.cache[args] = self.fn(self.instance, *args)\n return object\n</pre>', 'title': u'A working example'}, {'comment': u'You can use set instead of ImmutableDict', 'title': u'set'}, {'comment': u"The function below is a nice compromise between simplicity and power. Unlike the version above you can use this decorator to safely decorate more than one function (thanks to the fact that functions are hashable).\n\n<pre>\ndef memoize(f, cache={}):\n def g(*args, **kwargs):\n key = ( f, tuple(args), frozenset(kwargs.items()) )\n if key not in cache:\n cache[key] = f(*args, **kwargs)\n return cache[key]\n return g\n</pre>\n\nNote that *args list is converted to a tuple (which is hashable, unlike the list) and the dictionary **kwargs is converted to a frozenset (which is, as opposed to a set, hashable). If you don't have frozenset (pre-2.4), you can use tuple(kwargs.items())", 'title': u'Beautiful is better than ugly'}], 'desc': u'The latest version of Python introduced a new language feature, function and method decorators (PEP 318, http://www.python.org/peps/pep-0318.html). This recipe show a common callable transformation that can benefit from the new syntax, often referred to as Memoization pattern.\n'}, {'comments': [{'comment': u'hi\non Fedora Core 3 this is what happens to me with the above code:\n\n$ python blah.py\nTraceback (most recent call last):\n File "blah.py", line 1, in ?\n from OpenGL.GLUT import *\n File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 26, in ?\n\n File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 2, in ?\n # The Python Imaging Library.\nImportError: No module named GL__init__\n\nthat\'s with python-opengl and freeglut installed.\ni\'m hoping that somebody has seen this error before and has a clue what it might be.\ni have python-imaging and python-numeric installed also, which i read are important here.\n\nbest \njon', 'title': u'ImportError: No module named GL__init__'}], 'desc': u"This code snippet uses Python/OpenGL (http://pyopengl.sourceforge.net) to open a window using GLUT, and draw a sphere into it. I've used this many times as the starting point for more complicated applications."}, {'comments': [{'comment': u'Which versions of what do I need? I think I have everything, but I get the following errors:\n\n\n<br>\nC:\\jimc\\bin>python C:\\jimc\\bin\\openGLSphere.py\nTraceback (most recent call last):\n<br> File "C:\\jimc\\bin\\openGLSphere.py", line 1, in ?\n from wxPython.glcanvas import wxGLCanvas\n<br> File "C:\\Python23\\Lib\\site-packages\\wxPython\\glcanvas.py", line 6, in ?\n from misc2 import *\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\misc2.py", line 4, in ?\n from windows import *\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\windows.py", line 6, in ?\n<br> from gdi import *\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\gdi.py", line 7, in ?\n import wx\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\wx.py", line 22, in ?\n from mdi import *\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\mdi.py", line 14, in ?\n from frames import *\n<br> File "C:\\Python23\\lib\\site-packages\\wxPython\\frames.py", line 14, in ?\n from stattool import *\n File "C:\\Python23\\lib\\site-packages\\wxPython\\stattool.py", line 14, in ?\n from controls import *\n File "C:\\Python23\\lib\\site-packages\\wxPython\\controls.py", line 16, in ?\n class wxControlPtr(wxWindowPtr):\nNameError: name \'wxWindowPtr\' is not defined', 'title': u'Which versions do I need'}, {'comment': u'Change the import order and try again:<br>\n<pre>\nfrom wxPython.wx import *\nfrom wxPython.glcanvas import wxGLCanvas\n</pre>', 'title': u'Re: Which versions do I need'}], 'desc': u'A simple wxPython/OpenGL application to draw a sphere.'}, {'comments': [{'comment': u"Great recipe!<br>\nI have a question though. <br>How can i do the following:<br>\n\nassert (ANY,'x')==('a','b','c',....,'x')<br><br>\n\nMy problem is that i have a list of tuples and i want to find the one that ends with 'x'<br><br>\nmylistoftuples=[('w',),('r','t'),....,('a','b','c')]<br>\nidx=mylistoftuples.index((ANY,'x'))<br><br>\nThanks for helping<br>", 'title': u'a simple (?) question'}, {'comment': u'sorry for not answering for so long... been a bit off ASPN for some time :)\n<br>\n<br>\nwell, in python 2.5 this just works :)\n<pre>[(1,2),(3,0),(4,)].index((ANY, 0)) # returns 2</pre>', 'title': u' '}], 'desc': u'here we will see an example of template comparisons based on a logical ANY object.\nalso this recipe provides alternative implementations of the absolute maximum and minimum objects (for more details on them see PEP326 http://www.python.org/peps/pep-0326.html).\n'}, {'comments': [{'comment': u'Using the same name for the class and the instance is confusing:\n\n<pre>\nform = form(cgi.FieldStorage())\n<pre></pre></pre>', 'title': u'bad style'}, {'comment': u'generate_hash() is quite insecure: The returned hash only depends on time which can be easily guessed.\n<br>\nNice example anyway...', 'title': u"Don't use that Session ID in Real live "}, {'comment': u"Asside from the obvious security implications of using un-signed cookies there is another problem with this example: There's no locking to stop multiple requests accessing the same session file. It's very easy to get corrupt sessions with code like this.", 'title': u'Not safe'}, {'comment': u'I have made a session handling with Cookies + SQL. You can find the source on my Homepage:<br>\nhttp://www.jensdiemer.de/?Python', 'title': u'nice, but...'}, {'comment': u'> The returned hash only depends on time which can be easily guessed.\n<br>\n<br>Up to the millisecond? Remember time.time() returns a float!', 'title': u'Guessing time?'}], 'desc': u'This is a very simple session handling example that uses plain Python CGI (tested only under Python 2.2+). Its goal is to show how cookies are set via HTTP and how easily they can be used for session management.'}, {'comments': [{'comment': u"'ajout_message' can be translated by 'add_message', excuse me for my poor english\n\nReagards", 'title': u'bad translation'}], 'desc': u'Simple recipe for representing a list of messages with their responses like in a forum.'}, {'comments': [], 'desc': u'Often I get data to import in MS Excel files, and the column headers are not very useful for column names. They contain spaces, punctuation, and special characters that make a simple import difficult.\n\nThis script opens the file in Excel, and applies some simple formatting rules to the first row and addresses duplicate names. Then when the file is imported (SQL Server DTS in my case), the column names are somewhat usable.'}, {'comments': [{'comment': u'Ok, they may be simple, too, but you can make quite complex things out of them ;)', 'title': u'SVG = Scalable Vector Graphics, not Simple Vector Graphics'}], 'desc': u'This script draws simple SVG images composed of circles, squares, lines, text, etc. '}, {'comments': [], 'desc': u'This simple decorator is different to other memoize decorators in that it will only cache results for a period of time. It also provides a simple method of cleaning the cache of old entries via the .collect method. This will help prevent excessive or needless memory consumption.'}, {'comments': [{'comment': u'And how exactly is this "static" when the types are checked at runtime? My (and I guess many other\'s) idea of static is that it is done _before_ the code has a chance to run, that is during compilation stage. ', 'title': u'Where is static?'}, {'comment': u"This recipe only guarantees that arguments which are passed to a function are of a certain type.\n\nIt does not guarantee anything else. Perhaps using the word 'static' in the title is not strictly correct.", 'title': u"True, it's a half hearted static..."}], 'desc': u'This fun little recipe uses Python 2.4 decorators to force function arguments to be of a specified type. If a type mismatch occurs, a TypeError is raised.\n\nIt fun, cheap, and dirty. And probably nasty.'}, {'comments': [], 'desc': u'The Trigram class can be used to compare blocks of text based on their local structure, which is a good indicator of the language used. It could also be used within a language to discover and compare the characteristic footprints of various registers or authors. As all n-gram implementations should, it has a method to make up nonsense words.'}, {'comments': [], 'desc': u'A thread-like interface for those who want to "use" threads in Python with PyGTK. I use it when loading files and display a nice progress bar. The function or method you give to GIdleThread should "yield" every now and then. This makes it simpler to write code, since you do not have to care about nasty locks.'}, {'comments': [{'comment': u"Where's the definition of ZzWw?", 'title': u'huh?'}, {'comment': u'Sorry about that - it appears my pop-up blocking/ad munching software killed that line when I submitted (and tried to re-edit) the code.\n\nThe line has been changed to "open"', 'title': u'Rats'}, {'comment': u'I can\'t get this working\n<br>\nthis is what I get:<br>\n<br>\n<br>\n-- Retreiving Files----\n<br>\nCouldn\'t find server\nTraceback (most recent call last):<br>\n File "C:\\Python24\\projects\\zipstuff\\ftp.py", line 66, in ?<br>\n moveFTPFiles(ftpServerName,ftpU,ftpP,remoteDirectoryPath,localDirectoryPath,<br>\ndeleteAfterCopy,onlyNewFiles)<br>\n File "C:\\Python24\\projects\\zipstuff\\ftp.py", line 10, in moveFTPFiles<br>\n ftp.login(userName,passWord)<br>\nUnboundLocalError: local variable \'ftp\' referenced before assignment<br>\n<br>\nThe ftpservername is correct, as is the ftpU and ftpP. <br>\nWhat could I be doing wrong?', 'title': u'stumped'}, {'comment': u"ah I see, you don't include the ftp:// in the address, just the address without the ftp://\nduh", 'title': u'got it'}], 'desc': u'This script filled the need to have a scheduled directory synch occur via FTP. I also realized I could use it to clean out a directory without much effort. There are probably more robust examples out there, but this one should be easily modifiable for FTP newbies. It uses Sets to speed up finding missing files from the local directory.'}, {'comments': [], 'desc': u'prnDict is a function to return a structural representation of a dictionary. '}, {'comments': [{'comment': u"Hi,<br>\nwith os function wrappers this task will be more pleasant, especially for smart file handling (gaps in BAK filenames) and using rename instead of copy.<br><br>\n\n<pre>\ndef rename_to_backup(fn, backup_amount=5, backup_ext='BAK'):\n\n import os.path, os\n\n def bak_name(i):\n if i < 1: return fn\n return '%s.%s%d' % (fn, backup_ext, i)\n def exists(i):\n f = bak_name(i)\n return os.path.exists(f)\n def unlink(i):\n f = bak_name(i)\n try: os.unlink(f)\n except IOError: pass\n def rename(i, j):\n fi = bak_name(i)\n fj = bak_name(j)\n try: os.rename(fi, fj)\n except IOError: pass\n\n for i in range(backup_amount - 1, -1, -1):\n if exists(i):\n if exists(i-1): \n if exists(i+1): unlink(i+1)\n rename(i, i+1)\n</pre>", 'title': u'my version may be cleaner ;)'}, {'comment': u"this version doesnt allow 'gaps' between backup file names, and not perform extra file renames:\n\n<pre>\ndef rename_to_backup(fn, backup_amount=5, backup_ext='BAK'):\n\n import os.path, os\n\n def bak_name(i):\n if i < 1: return fn\n return '%s.%s%d' % (fn, backup_ext, i)\n def exists(i):\n f = bak_name(i)\n return os.path.exists(f)\n def unlink(i):\n if not exists(i): return\n f = bak_name(i)\n try: \n print 'bpc.file> delete %s' % (f)\n os.unlink(f)\n except IOError, OSError: \n pass\n def rename(i, j):\n fi = bak_name(i)\n fj = bak_name(j)\n try: \n print 'bpc.file> rename %s => %s' % (fi, fj)\n os.rename(fi, fj)\n except IOError: \n pass\n\n def rename_one(index):\n print 'rename_one> index=%d' % index\n if index == backup_amount:\n print 'rename_one> Last Index' \n unlink(index)\n else:\n if exists(index):\n print 'rename_one> next index: %d' % index\n rename_one(index + 1)\n rename(index, index + 1)\n \n rename_one(0)\n\n</pre>", 'title': u'And smarter...'}], 'desc': u' '}, {'comments': [], 'desc': u'A function similar to the builtin reduce for reducing dictionaries.'}, {'comments': [], 'desc': u'wxApp usually sends error messages to a wxWindow. This can be a problem if you are trying to debug a crash, the window disappears before you can see the traceback. The first argument to wxApp is redirect=True, the second is filename=None. You specify a filename to write to that file, or specify false to redirect to write to the console.'}, {'comments': [{'comment': u"dbrow does something like this, though it probably wouldn't work in a pickle. But it is memory efficient and speed efficient. Available at:\n\nhttp://opensource.theopalgroup.com/", 'title': u'dbrow'}], 'desc': u'I often return result sets from a database call using a list of dictionary objects. When transmitting the pickled list object over the wire, the size of the pickle greatly effects the speed of the transmission.\n\nI wrote this small class to emulate a list of dictionary objects without the memory and pickle storage overhead which occurs when storing every item in the list as a dictionary.'}, {'comments': [], 'desc': u'The os.startfile() sometimes fails to open a URL under Windows. This recipe provides a dependable function for opening a URL.'}, {'comments': [{'comment': u'<pre>\nHi, I tried the pivot function on a csv file that has both missing data and unordered fields, and I found that it misplaces all the values.\nI modified the function to take care of these problems.\nI commented the few lines that I have added or modified, and changed the example at the top.\nI hope this can help.\nGiovanni Ulivi\n\n\ndef pivot(table, left, top, value):\n """\n Creates a cross-tab or pivot table from a normalised input table. Use this\n function to \'denormalize\' a table of normalized records.\n\n * The table argument can be a list of dictionaries or a Table object.\n (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/334621)\n * The left argument is a tuple of headings which are displayed down the\n left side of the new table.\n * The top argument is a tuple of headings which are displayed across the\n top of the new table.\n Tuples are used so that multiple element headings and columns can be used.\n\n E.g. To transform the list (listOfDicts):\n\n Name, Year, Value\n -----------------------\n \'Simon\', 2004, 32\n \'Simon\', 2005, 128\n \'Russel\', 2004, 64\n \'Eric\', 2004, 52\n \'Russel\', 2005, 32\n\n into the new list:\n\n \'Name\', 2004, 2005\n ------------------------\n \'Simon\', 32, 128\n \'Russel\', 64, 32\n \'Eric\', 52, NA\n\n you would call pivot with the arguments:\n\n newList = pivot(listOfDicts, (\'Name\',), (\'Year\',), \'Value\')\n\n """\n rs = {}\n ysort = []\n xsort = []\n for row in table:\n yaxis = tuple([row[c] for c in left]) # e.g. yaxis = (\'Simon\',)\n if yaxis not in ysort: ysort.append(yaxis)\n xaxis = tuple([row[c] for c in top]) # e.g. xaxis = (\'2004\',)\n if xaxis not in xsort: xsort.append(xaxis)\n try:\n rs[yaxis]\n except KeyError:\n rs[yaxis] = {}\n if xaxis not in rs[yaxis]:\n rs[yaxis][xaxis] = 0\n rs[yaxis][xaxis] += row[value]\n\n """\n In the following loop we take care of missing data,\n e.g \'Eric\' has a value in 2004 but not in 2005\n """\n for key in rs:\n if len(rs[key]) <pre>\nHi, I tried the pivot function on a csv file that has both missing data and unordered fields, and I found that it misplaces all the values.\nI modified the function to take care of these problems.\nI commented the few lines that I have added or modified, and changed the example at the top.\nI hope this can help.\nGiovanni Ulivi\n\n\ndef pivot(table, left, top, value):\n """\n Creates a cross-tab or pivot table from a normalised input table. Use this\n function to \'denormalize\' a table of normalized records.\n\n * The table argument can be a list of dictionaries or a Table object.\n (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/334621)\n * The left argument is a tuple of headings which are displayed down the\n left side of the new table.\n * The top argument is a tuple of headings which are displayed across the\n top of the new table.\n Tuples are used so that multiple element headings and columns can be used.\n\n E.g. To transform the list (listOfDicts):\n\n Name, Year, Value\n -----------------------\n \'Simon\', 2004, 32\n \'Simon\', 2005, 128\n \'Russel\', 2004, 64\n \'Eric\', 2004, 52\n \'Russel\', 2005, 32\n\n into the new list:\n\n \'Name\', 2004, 2005\n ------------------------\n \'Simon\', 32, 128\n \'Russel\', 64, 32\n \'Eric\', 52, NA\n\n you would call pivot with the arguments:\n\n newList = pivot(listOfDicts, (\'Name\',), (\'Year\',), \'Value\')\n\n """\n rs = {}\n ysort = []\n xsort = []\n for row in table:\n yaxis = tuple([row[c] for c in left]) # e.g. yaxis = (\'Simon\',)\n if yaxis not in ysort: ysort.append(yaxis)\n xaxis = tuple([row[c] for c in top]) # e.g. xaxis = (\'2004\',)\n if xaxis not in xsort: xsort.append(xaxis)\n try:\n rs[yaxis]\n except KeyError:\n rs[yaxis] = {}\n ', 'title': u'how to take care of missing or unordered data'}, {'comment': u'<pre>\nSorry for the badly formatted previous post.\nI didn\'t think of the minus sign in the middle of the program.\n\nI tried the pivot function on a csv file that has both missing data and unordered fields,\nand I found that it misplaces all the values.\nI modified the function to take care of these problems.\nI commented the few lines that I have added or modified, and changed the example at the top.\nI hope this can help.\nGiovanni Ulivi\n\n\ndef pivot(table, left, top, value):\n """\n Creates a cross-tab or pivot table from a normalised input table. Use this\n function to \'denormalize\' a table of normalized records.\n\n * The table argument can be a list of dictionaries or a Table object.\n (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/334621)\n * The left argument is a tuple of headings which are displayed down the\n left side of the new table.\n * The top argument is a tuple of headings which are displayed across the\n top of the new table.\n Tuples are used so that multiple element headings and columns can be used.\n\n E.g. To transform the list (listOfDicts):\n\n Name, Year, Value\n -----------------------\n \'Simon\', 2004, 32\n \'Simon\', 2005, 128\n \'Russel\', 2004, 64\n \'Eric\', 2004, 52\n \'Russel\', 2005, 32\n\n into the new list:\n\n \'Name\', 2004, 2005\n ------------------------\n \'Simon\', 32, 128\n \'Russel\', 64, 32\n \'Eric\', 52, NA\n\n you would call pivot with the arguments:\n\n newList = pivot(listOfDicts, (\'Name\',), (\'Year\',), \'Value\')\n\n """\n rs = {}\n ysort = []\n xsort = []\n for row in table:\n yaxis = tuple([row[c] for c in left]) # e.g. yaxis = (\'Simon\',)\n if yaxis not in ysort: ysort.append(yaxis)\n xaxis = tuple([row[c] for c in top]) # e.g. xaxis = (\'2004\',)\n if xaxis not in xsort: xsort.append(xaxis)\n try:\n rs[yaxis]\n except KeyError:\n rs[yaxis] = {}\n if xaxis not in rs[yaxis]:\n rs[yaxis][xaxis] = 0\n rs[yaxis][xaxis] += row[value]\n\n """\n In the following loop we take care of missing data,\n e.g \'Eric\' has a value in 2004 but not in 2005\n """\n for key in rs:\n if len(rs[key]) < len(xsort):\n for var in xsort:\n if var not in rs[key].keys():\n rs[key][var] = \'\'\n\n headings = list(left)\n headings.extend(xsort)\n\n t = []\n\n """\n The lists \'sortedkeys\' and \'sortedvalues\' make sure that\n even if the field \'top\' is unordered, data will be transposed correctly.\n E.g. in the example above the table rows are not ordered by the year\n """\n\n for left in ysort:\n row = list(left)\n sortedkeys = rs[left].keys()\n sortedkeys.sort()\n sortedvalues = map(rs[left].get, sortedkeys)\n row.extend(sortedvalues)\n t.append(dict(zip(headings,row)))\n return t\n</pre>', 'title': u'how to take care of missing or unordered data'}], 'desc': u"This function creates a cross-tab or pivot table from a normalised input table. Use this function to 'denormalize' a table of normalized records."}, {'comments': [{'comment': u'A very nice entertainment, indeed!<br>\n\nThe imports of the Numeric an random modules\nseem to be unnecessary.<br>\n\nGregor', 'title': u'two imports superfluous'}, {'comment': u'On OS X this crashes unless you replace\n\npygame.display.init()\n\nwith\n\npygame.init()', 'title': u'Correction for OS X'}], 'desc': u'An old-school demo effect, using sine wave interference patterns. Entertaining for at least a few minutes :) \n\nModify the freq variable for different patterns.'}, {'comments': [], 'desc': u'In the UK, Indian subcontinent, South Africa, Australia, West Indies and New Zealand, cricket is widely played. This is a GUI to calculate the estimated final score for a fixed overs inninings. It does also show a Duckworth Lewis score for 50 over games.'}, {'comments': [{'comment': u"<pre>\nHey Fadli, world. This is great code!\nI have some suggestion so the code is even cleaner\n\ndelete:\n\n def remove(self, *args):\n self._message_map = {}\n self.remove_notify_icon()\n self = None\n\nyou have it double.\nAlso delete\nimport gobject the main_loop() you do\nand use gtk.main()\n\nalso delete .realize() cause show_all() is enough\nthen hook destroy to wnd to gtk.main_quit()\nthis is a start for cleanup\nI'm gonna use this class so if you care about more cleanups tell it here.\n\nThanks again for the *GREAT* code\n</pre>", 'title': u'Updates'}, {'comment': u"Hi Nikos, \n<br>\n<br>\nGreat to hear that you find it useful and I've noticed you've created a patch for Gajim http://gajim.org. Its rocks! I've always wanted to see a Gaim built on python. \n<br>\n<br>\nThere are many improvements that can be done on the code (the extension) but I can't get down to doing it because of lack of time. Why don't u send me a patch (fadlydottabraniatgmaildotcom) and I'll merge it here. Do include your name.\n<br>\n<br>\nOne on my wish list:\nBitorrent Win32 with a Tray Icon ;)", 'title': u"You're welcome :)"}, {'comment': u"<pre>\nsome constants like GWL_WNDPROC are already in win32con (comes with pywin32) so no need to have them global\n\nmoreover, it not clear one can set a custom image\neither write a set_icon() or anyways help:\n\n\nhinst = win32gui.GetModuleHandle(None)\nicon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE\nhicon = win32gui.LoadImage(hinst, path_to_ico, win32con.IMAGE_ICON, 0, 0, icon_flags)\n\nand then you can gloriously do:\nadd_notify_icon(self.systray_context_menu, hicon, 'Gajim')\n</pre>\nanother interesting project is http://sourceforge.net/projects/pysystray", 'title': u'more cleanups'}, {'comment': u'self.remove in _redraw maybe you mean remove() ?<br>\n<br>\nmoreover in _get_nid you first have nid a tuple and then you make it a list and then you return it as tuple? why all that?<br>\n<br>\nyou have to return tuple but you do not have to make it list with list() I mean you just do nid = [self._hwnd, self._id, ...]', 'title': u'yet another cleanup post'}, {'comment': u'I am using this recipe in Gajim.org and I was having serious problem with my main window because when I tried to move it I was getting a python crash. After a lot of blind testing, I now have:<br>\n<pre>\nfake_window = gtk.Window()\nfake_window.realize()\n</pre>\n<br>\nand I pass fake_window as window for systray class<br>\n<br>\nmy main window is other and everything works ok now..<br>\nI would appreciate some comments on this if you knew. Thanks', 'title': u'magical workaround'}], 'desc': u'This module enables pyGTK developers on the windows platform to handle native windows messages and take advantage of features such as notification icons and window transparency (Win2000 and above). Requires pywin32 extensions by Mark Hammond.'}, {'comments': [], 'desc': u'This recipe finds the complement of a set of indices from a specific arange(n) array. Suppose, for example, you are given a linear array with 10 elements and you want to extract the elements from this array that have indices other than [1, 3, 5]. You can then use this recipe to first find the complement of [1, 3, 5], and you can then use numarray.take() to extract the elements of interest.'}, {'comments': [], 'desc': u'I use this iterator when I need to iterate over an image, working on regions or subsets of the image at a time. It returns regions from a 2D range, left to right, top to bottom.'}, {'comments': [{'comment': u'Not to rain on your parade or anything, but is there a good reason to use this instead of the included textwrap module? It has several options for handling indentation.', 'title': u' '}, {'comment': u"I don't think textwrap supports handling multiple paragraphs.", 'title': u'textwrap?'}, {'comment': u"Then perhaps the problem you may want to focus on instead is that of splitting a text into a sequence of paragraphs, which you then feed in turn to 'textwrap'. That way you wouldn't be duplicating the functionality that 'textwrap' already provides.", 'title': u'Splitting into paragraphs'}], 'desc': u'I needed to send out emails about content and when quoting the content I wanted to indent it with a few spaces. (see example output below) \nThis recipe is clever in that it also allows for a maxwidth parameter so that the indentation is never broken.'}, {'comments': [{'comment': u'Hi, why not add keywords to the interp() function ?<br>\n<br>\n<pre>def interp(s, dic = None, **kw):\n caller = sys._getframe(1)\n if dic:\n m = Chainmap(kw, dic, caller.f_locals, caller.f_globals)\n else:\n m = Chainmap(kw, caller.f_locals, caller.f_globals)\n return Template(s).substitute(m)</pre>\n<br>\nThis way you can write :<br>\n<br>\n<pre>print interp("My $opinion language is $language, said $name.",name="Raymond")</pre>', 'title': u'Adding keywords ?'}, {'comment': u'Then you can rip out the if-then-else', 'title': u'Default dic to {}'}, {'comment': u'<pre>\ndef interp(s, dic={}, *args, **kw):\n caller = sys._getframe(1)\n argdic = dict([(str(i),v) for i,v in enumerate(args)])\n m = Chainmap(argdic, kw, dic, caller.f_locals, caller.f_globals)\n return Template(s).substitute(m)\n\nprint interp("My $0 language is $1.", "favorite", "Python")\n</pre>\n\nYes yes, I know this is getting a little silly, but I couldn\'t resist.', 'title': u'And the cycle completes with the addition of positional args...'}, {'comment': u'Using a mutable object as a default argument is a common\n*mistake* in Python. Consider this example for instance:\n<pre>\ndef print_default(dic, default={}):\n default.update(dic)\n print default\n\nprint_default({1:"hello"}) # the result is what you expect\n\nprint_default({2:"world"}) # the result could be not what you expect,\n# unless you understand mutable objects and default arguments pretty well\n</pre>\nThe default argument is shared trough all the function calls.\n\n Michele Simionato', 'title': u'please, no dic={}'}, {'comment': u'cat = lambda _ : Template(_).substitute(sys._getframe(1).f_locals, **sys._getframe(1).f_globals)\n<br> <br>\nthis works just like the old Itpl module, I think. I\'ve used it for a couple of days, only, but it seems quite handy.\n<br> <br>\nx= \'interpolate\'\n<br>\ncat("I can $x to my heart\'s content.")', 'title': u'one-liner'}, {'comment': u"need to swap the .f_locals and the .f_globals to keep globals from hiding locals:\n<br> <br><pre>\n>>>cat = lambda _ : Template(_).substitute(sys._getframe(1).f_globals, **sys._getframe(1).f_locals)\n>>>x = 'global_x'<br> \n>>>def func():<br> \n>>> print cat('$x')<br> \n>>> x ='local_x'<br> \n>>> print cat('$x')<br> \n>>>test = func()<br> \n'global_x'<br> \n'local_x'<br> </pre>", 'title': u'whoops!'}], 'desc': u'Regular string interpolation in Python requires the user to pass an explicit\nkeyword dictionary. This recipe adds a little bif of magic, so that if\na name is not found in the passed dictionary, it is looked up in the\nlocals and globals dictionaries. It is also possible not to pass any \nexplicit dictionary, then the names is searched in the locals and globals\ndictionaries only.'}, {'comments': [], 'desc': u' Find the set of elements in input_array that are closest to\n elements in target_array. Record the indices of the elements in\n target_array that are within tolerance, tol, of their closest\n match. Also record the indices of the elements in target_array\n that are outside tolerance, tol, of their match.\n\n For example, given an array of observations with irregular\n observation times along with an array of times of interest, this\n routine can be used to find those observations that are closest to\n the times of interest that are within a given time tolerance.'}, {'comments': [{'comment': u"PrefixStorage is ultimately a kind of dict, so it should subclass dict.\nBy overriding the get, __getitem__ and __setitem__ methods one could create a drop-in-replacement, so that:\n<br><br>\n>>> x=prefixStorage()<br>\n>>> x['12'] = '1234Server'<br>\n>>> x['123'] = '12345andnowforsomethingcompletelydifferent'<br>\n>>> x['125']<br>\n'1234Server'", 'title': u'subclass dict'}, {'comment': u"If you want PrefixStorage subclass dict then it should override most of dict methods for maintaining self._sizes. Better way is to subclass UserDict.DictMixin. But I think you should always distinguish get/__getitem__ and getByPrefix, so:\n<pre>\n>>> x.getByPrefix('125')\n'1234Server'\n</pre>\nbut\n<pre>\n>>> x.get('125', 'No such prefix')\n'No such prefix'\n</pre>\nBTW someone may set self._mapping on some persistent dict-like object.", 'title': u'just an algorithm example'}], 'desc': u'Storage for store information about domains determined by key prefixes. See the docsting for details.'}, {'comments': [{'comment': u'Excellent recipe!\nSome improvment ideas may be taken from Twisted Versioned\nhttp://twistedmatrix.com/documents/current/howto/upgrading\nPersonally, I prefer to have methods like UpgradeXXXtoYYY() to do chained updates.', 'title': u'Twisted Versioned'}], 'desc': u"One of the problems with persistent objects is that one often needs a mechanism to keep them in sync with the codebase. This provides such a mechanism for pickled objects under the control of CVS via the magic CVS $Revision$ string, which CVS will automatically update to match a file's revision number. "}, {'comments': [], 'desc': u"Based on RawConfigParser, the usage and implementation is almost the same, however this is not a subclass of it because it doesn't need to."}, {'comments': [{'comment': u"If you use a machine behind a router connected to a cable/dsl modem, you most likely will get a LAN-internal IP address for the host (e.g. 192.168.1.2) using the above script. You want instead the WAN address of your LAN. This can be obtained by a number of means. My script (sorry it's in Perl b/c I had been doing similar work for my job as of late) will do this:\n\n<br><br>\n\nhttp://brianhammond.com/realip.pl\n\n<br><br>\n\nThat script doesn't redirect you to the host with the dynamic ip. Instead, it updates your local hosts file so you can connect to the host with the dynamic IP (for any service [ssh, www, etc]) using a name. Run this script periodically using cron and you can always refer to the host by name. I find it very handy.\n\n<br><br>\n\nCheers!", 'title': u'Behind a router...'}, {'comment': u'the following code gets the IP from behind a firewall, cablemodem, ...\n<pre>import re\nimport httplib\n\n_ip_regex = \'([\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3})\'\ndef get_IP():\n conn = httplib.HTTPConnection("checkip.dyndns.org")\n conn.request("GET", "")\n res = conn.getresponse()\n if res.reason == "OK":\n ip = re.split(ip_regex, res.read())[1]\n else:\n ip = None\n conn.close()\n return ip\n</pre>\n\nDookie', 'title': u'get IP from the Internet'}], 'desc': u"Many users get a dynamic ip address when they sign on to the internet (e.g., cable modem). If you run a server on your home network, you probably know that you can't point a webpage address to that server with a dynamic ip b/c DNS servers need a static ip. However, if you get a home page with your ISP (e.g., users.someisp.com/myusername), this script will allow you to automatically update your home page with a web page that will redirect your users to your dynamic ip.\n\nRun the code whenever you get a new ip address, and your users will always get to see your website. Best part of all - YOU CONTROL YOUR SERVER! You want to add PHP and MySQL support on your Linux server, go right ahead. The sky's the limit :)"}, {'comments': [{'comment': u"I have several questions and/or suggestions.<br><br>\n\nI have been wondering about the way you use this server in httptest.start_server().<br><br>\n\nFor test suites, I'd like to be able to run the server that can bind to the port that OS will assign. I mean using the fixed port number in the test suites is not safe. So, I will need to pass the port 0 (that does the trick). However, then I need to know which port the OS has given to the server in order to stop it: I need to access the server instance.<br><br>\n\nGiven the fact I had the server instance, I could use another technique to prevent the server from getting stuck. I could wait for a fixed amount of time (e.g. 10secs) and then kill it with server_instance.socket.close().<br><br>\n\nOr, this might be a completely different use case, please comment.", 'title': u'Anonymous port'}, {'comment': u'Yes, the HTTP port in this example is fixed. I think finding a free port and using it is a different problem and is subject for other recipes ;) For unit test suites the port number could also be given as a command line parameter.\n<br><br>\nAs to your stop suggestion: accessing the server instance outside of the HTTP server thread needs thread locking which I wanted to avoid. But yes it would be possible.\n<br><br>\nAnother problem in the example is how to tell if the HTTP server is started. I just wait for a couple of seconds and assume it is there. A clean approach would be using the waitfor module at http://www.hennessynet.com/waitfor/.', 'title': u'Re: port and stop questions'}], 'desc': u'Starting a SimpleHTTPServer instance in a separate thread makes it run forever. To solve this problem the server is augmented with a QUIT command. If sent it makes the server stop serving requests.'}, {'comments': [{'comment': u'First, thanks for the recipe, Rick. While I have not read A New Kind of Science, I had the chance to see Wolfram lecture in support of the book and found myself amused and intrigued. I am eager to sit down and see what I can do with your code. That being said, here are bitwise arithmetic versions of the ca_data and pil_render functions.\n\n<pre width="80">\ndef ca_data_bwa(height,width,dorandom,rulenum):\n \n # Ensure that we are working with long integers, otherwise bitwise\n # operations will not work properly for widths greater than 31 on most\n # python implementations. \n height = long(height)\n width = long(width)\n rulenum = long(rulenum)\n \n # Create the first row, either randomly, or with a single 1\n if dorandom:\n first_row = randint(0, (1 << width) - 1)\n else:\n first_row = 1L << width/2L\n results = [first_row]\n \n rule = rulenum\n \n for i in range(height-1L):\n data = results[-1]\n\n # Determine the new row based on the old data. We create appropriate\n # bitmasks to allow us to read/write to a particular bit and then use\n # bitwise operations to do the actual reading/writing.\n new = 0L\n for j in range(width):\n \n # Create a bitmask and then access the \'upper left\' bit\n ul_bitmask = 1L << ((j - 1L) % width)\n ul_bit = (data & ul_bitmask) / ul_bitmask\n \n # Create a bitmask and then access the \'above\' bit\n above_bitmask = 1L << j\n above_bit = (data & above_bitmask) / above_bitmask\n \n # Create a bitmask and then access the \'upper right\' bit\n ur_bitmask = 1L << ((j + 1L) % width)\n ur_bit = (data & ur_bitmask) / ur_bitmask \n \n # Create a bitmask and then access the rule \n rule_bitmask = 1L << ((ul_bit << 2L) + (above_bit << 1L) + ur_bit)\n new_bit = (rule & rule_bitmask) / rule_bitmask \n \n # Create a bitmask and then adjust the value of new at j \n new_bitmask = new_bit << j\n new = new | new_bitmask\n \n results.append(new)\n return results\n\ndef pil_render_bwa(data,height,width,fname="bs_bwa.png"):\n import Image, ImageDraw\n img = Image.new("RGB",(width,height),(255,255,255))\n draw = ImageDraw.Draw(img)\n \n for y in range(height):\n for x in range(width):\n if (data[y] & (1L << x)) / (1L << x): draw.point((x,y),(0,0,0))\n img.save(fname,"PNG")\n return\n</pre>\n<br>\nUnfortunately, bitwise ops are rather slow under Python, so the bitwise versions take roughly 6 times as long to run on my machine. So, no speed optimization for me, though your mileage may vary. I tried to optimize with various different approaches to bit shifting, but found that the << (left shift) operator was almost universally faster than pow and a number of other approaches.\n<br><br>\nOn another dimension, these routines may provide an optimization. While I have not yet investigated the matter thoroughly, I suspect that the bitwise versions probably perform better than the originals with regard to memory consumption. While I am ignorant of the actual memory representation of Python long integers, it seems that, unless they are *grossly* inefficient, a list of arbitrarily long Python long integers must take up less space than an equivalent representation using a list of lists of 32-bit integers. Of course, the phrase "it seems reasonable that" often has very little to do with actual performance, so it would be nice if someone would check this out.\n<br><br>\nRegardless of their efficiency, these alternate versions should serve as basic examples of bit arithmetic in Python. With the exception of the randomization function (where using long integers opened up obvious optimizations too good to pass up) I have attempted to keep the ', 'title': u'Bitwise Versions'}, {'comment': u'I got fascinated by Wolfram\'s 1d automata experimentation as well. I went back to the math he presented in one of his papers, and came up with this implementation, which I profiled and tweaked until I got it as fast as I could make it without dropping into C:\n\n<pre>\nimport Image\nimport ImageOps\nimport random\n\ndef step(a, rule, k=2, r=1):\n nbrs = [a[c:] + a[:c] for c in range(-r, r+1, 1)]\n l = []\n for t in apply(zip, nbrs):\n result = 0\n for i in t:\n result = (result * k) + i\n l.append(result)\n return [((rule / (k ** v)) % k) for v in l]\n\ndef basicRun(rule, steps, stepper, seed=[1], k=2, r=1):\n seed = ([0] * steps) + seed + ([0] * steps)\n result = seed[:]\n for i in range(steps):\n seed = stepper(seed, rule, k=k, r=r)\n result += seed[:]\n return result, (len(seed), steps + 1)\n\ndef showResult(result, dims, k=2):\n i = Image.new("L", dims)\n i.putdata(result, (255 / (k - 1)))\n i = i.crop(i.getbbox())\n i = ImageOps.invert(i)\n i.load()\n i.show()\n\ndef runTest():\n lines = 400\n result, dims = basicRun(110, lines, step)\n showResult(result, dims)\n\nif __name__ == "__main__":\n runTest()\n</pre>\n\nstep() is where all the real action occurs. That\'s where most of the tweaking happened. And while bitwise manipulation is slow, basic math seems to be fast.', 'title': u'profiled and speedy'}, {'comment': u'Thanks, Dan. Go list comprehensions.', 'title': u'Nice'}, {'comment': u' ', 'title': u'Er, Dave, sorry'}], 'desc': u'This is a little script that uses Python to generate the cellular automata that Wolfram discusses in his book "A New Kind of Science". The script uses the Python Imaging Library to render the output, but you could replace this with text or any other method of visualization.'}, {'comments': [], 'desc': u'This recipe shows how to build an xmlrpc multithread server that exposes a COM component as a web service.'}, {'comments': [], 'desc': u'This recipe shows how to build an xmlrpc multithread server that exposes a Pyro remote object as a web service. Be careful to the remote object state: two different ways (a global and a thread local) are shown.'}, {'comments': [], 'desc': u'This is small application shows how to automate the CAD/PLM Software CATIA V5 via win32com. CATIA V5 must be installed and should be running when testing the application. Other examples you can find on http://www.goermezer.de .'}, {'comments': [{'comment': u'Note that the ctypes solution is only available to you if you are using Python 2.3 or higher. You can find it here: http://starship.python.net/crew/theller/ctypes/', 'title': u'Only on Python > 2.2'}, {'comment': u"# Kill the process with windows TASKKILL utility<br>\nimport os<br>\nos.popen('TASKKILL /PID '+str(process.pid)+' /F')<br>\n", 'title': u'You can add this method'}, {'comment': u"# Kill the process with windows TASKKILL utility<br>\nimport os<br>\nos.popen('TASKKILL /PID '+str(process.pid)+' /F')<br>\n", 'title': u'You can add this method'}], 'desc': u'The new subprocess module in Python 2.4 (also available for 2.2 and 2.3 at http://effbot.org/downloads/#subprocess) allows access to the handle of any newly created subprocess. You can use this handle to terminate subprocesses using either ctypes or the pywin32 extensions.'}, {'comments': [], 'desc': u'Essentially a sorted bag.'}, {'comments': [], 'desc': u'Simple versions what Hamish Lawson ("getting items in batches") and Brian QUinlan ("group list into n-tuples") submitted. \n\nIterables must support indexing and len(); doesn\'t use itertools.'}, {'comments': [], 'desc': u"This little application generates Mandelbrot/Frame's fractal trees in Python (see http://www.math.union.edu/research/fractaltrees/). Given an iteration depth, a trunk length, and a branching angle, this algorithm generates the corresponding tree. PIL is used to draw the tree."}, {'comments': [{'comment': u'<p>Sorry if this is a silly question, but wouldn’t it be better to use the webbrowser module?', 'title': u'webbrowser?'}, {'comment': u"Tried this recipe today during debugging, using it to display the HTML output of difflib.HtmlDiff. If you haven't used this new feature of difflib, this recipe makes it very easy to use the webbrowser to show a graphical representation of the differences between two text files.", 'title': u'Works great with difflib.HtmlDiff'}, {'comment': u"Ah, I hadn't realized that os.startfile was Windows only. Replacing os.startfile with webbrowser.open should provide equivalent functionality on Windows and make the recipe work on other platforms as well. I don't believe there is anything Windows specific about the technique used for serving up the data. I undertand that the specification of port 0 in order to dynamically find an available port might not work on some platforms.", 'title': u'webbrowser'}], 'desc': u'It is often nice to display something in a web browser, perhaps as an easy way to display rich output or for testing purposes. Sometimes the baggage of a temporary file is not desired when doing this.'}, {'comments': [{'comment': u'<pre>\n\nThe line\n\n if inetaddr == 0 or -1:\n raise Exception\n\nwill throw an exception for any value of inetaddr other than 0. It should probably be\n\n if inetaddr == 0 or inetaddr == -1:\n\nor\n\n if inetaddr in (0, -1):\n\n</pre>', 'title': u' '}, {'comment': u'Thanks Jean for pointing that out. Silly of me.', 'title': u'Changes made'}, {'comment': u"Python 2.5 has a new module in its standard library (uuid), which exports a function to get the MAC address:\n\n<pre>\n>>> import uuid\n>>> uuid.getnode()\n67474971543L\n>>> hex(uuid.getnode())\n'0xfb5d25b97L'\n</pre>", 'title': u'uuid.getnode()'}], 'desc': u'Uses the Internet Protocol Helper functions on Win32.'}, {'comments': [{'comment': u'This is an example of why I like languages with "eval". ;)\nTo be on the safe side, you may want not to use globals() as a simple\n<pre>\ns = Spreadsheet()\ns["a1"] = \'exec("import os; os.unlink(\\"really_important_file\\")")\'\nprint s[\'a1\']\n</pre>\nwill delete an important file. \n<br>In short, if you are not very careful with evaluation, a bad spreadsheet may really mess up your system. <br>\nIf you want to allow this depends on how much you trust your users.', 'title': u'You may or may not want to use globals()'}, {'comment': u'But I had to move things around a bit to determine that the math module wasn\'t part of the class. Here\'s how I have it rearranged it right now - this way I could also obviously use it with decimal or datetime or whatever I need to, but that I don\'t have to import *anything* for the class itself. \n<br>\n\n\n<pre>\nclass SpreadSheet:\n _cells = {}\n def __setitem__(self, key, formula):\n self._cells[key] = formula\n def getformula(self, key):\n return self._cells[key]\n def __getitem__(self, key ):\n return eval(self._cells[key], globals(), self)\n\nif __name__ == "__main__":\n\n from math import sin, pi\n\n ss = SpreadSheet()\n ss[\'a1\'] = \'5\'\n ss[\'a2\'] = \'a1*6\'\n ss[\'a3\'] = \'a2*7\'\n print "a3: ", ss[\'a3\']\n ss[\'b1\'] = \'sin(pi/4)\'\n print "b1: ", ss[\'b1\']\n print "b1 formula: ", ss.getformula(\'b1\')\n</pre>', 'title': u'really kewl!'}, {'comment': u'By catching NameError, you can make this work even under Python 2.3. It would also be possible to modify it a bit to easily detect infinite loops. The code below shows how to further restrict what kind of formulas you use in a cell by setting __builtins__ to None in the tools dict. (This disallows the nastiness Andreas pointed out above.)\n\n<pre>\nclass SpreadSheet:\n _cells = {}\n tools = {}\n _cache = None\n def getformula(self, key):\n return self._cells[key]\n def __setitem__(self, key, formula):\n self._cells[key] = formula\n def __getitem__(self, key ):\n bCache = self._cache is None\n if bCache: self._cache = {}\n while True:\n try:\n rv = eval(self._cells[key], self.tools, self._cache)\n break\n except NameError, ne:\n name = ne.args[0][6:-16] # Extract name from NameError\n if name in self._cells:\n self._cache[name] = self[name]\n else:\n raise\n if bCache: self._cache = None\n return rv\n\nif __name__ == "__main__":\n\n from math import sin, pi\n from pprint import pprint\n ss = SpreadSheet()\n ss.tools.update({\'sin\':sin, \'pi\':pi})\n ss.tools.update({\'__builtins__\':None}) \n ss[\'a1\'] = \'5\'\n ss[\'a2\'] = \'a1*6\'\n ss[\'a3\'] = \'a2*7\'\n ss[\'a4\'] = \'__import__("sys").path\'\n print "a3: ", ss[\'a3\']\n try:\n print \'a4: \', ss[\'a4\']\n except NameError, ne:\n print ne\n del ss.tools[\'__builtins__\']\n print \'a4: \', ss[\'a4\']\n ss[\'b1\'] = \'sin(pi/4)\'\n print "b1: ", ss[\'b1\']\n print "b1 formula: ", ss.getformula(\'b1\')\n\n</pre>', 'title': u'Make it work in Python 2.3 & restrict eval'}, {'comment': u'It works on 2.3, it supports cell dependencies, automatically recalculates when needed, caches compiled versions of the formulae, and a couple of other things.\n<br>\nSadly, that bloats it to about 100LOC, but I don\'t think that\'s too bad for a almost-working spreadsheet!\n<br>\nIt has some PyQt-ism somewhere, feel free to ignore them. And feel free to fix what may be broken ;-)\n<br>\n\n\n<pre>\n\nclass SpreadSheet(QObject):\n\t_cells = {}\n\t_compiledcells={}\n\ttools = {}\n\t_cache = None\n\t_lastval={}\n\t\n\t#Reverse dependencies: if cellA is in _deps[cellB], then cellA depends on cellB\n\t_deps={}\n\t\n\t#What cells I am evaluating right now\n\t_eving=[]\n\t\n\tdef __init__(self,parent):\n\t\tglobal obj\n\t\tQObject.__init__(self,parent)\n\t\tfor name in dir(math):\n\t\t\tif name[0]<>"_":\n\t\t\t\tself.tools[name]=eval(\'math.\'+name)\n\t\t\n\t\t\n\tdef getformula(self, key):\n\t\tif key in self._cells:\n\t\t\treturn self._cells[key]\n\t\telse:\n\t\t\treturn \'\'\n\n\tdef reCalculate(self,key):\n\t\t#recalculates all the dependencies of the key\n\t\tif key in self._deps:\n\t\t\tfor dep in self._deps[key]:\n\t\t\t\tself.emit(PYSIGNAL("cellChanged"),(dep,self[dep]))\n\t\t\t\tself.reCalculate(dep)\n\t\t\n\tdef __setitem__(self, key, formula):\n\t\tif formula.strip()==\'\': #Empty formula\n\t\t\tif key in self._cells:\n\t\t\t\tdel self._cells[key]\n\t\t\t\tdel self._compiledcells[key]\n\t\t\tif key in self._deps:\n\t\t\t\tdel self._deps[key]\n\t\telse:\n\t\t\tself._cells[key] = formula\n\t\t\tself._compiledcells[key] = compiler.compile(formula,"Formula for %s"%key,\'eval\')\n\t\t\tif key not in self._deps:\n\t\t\t\tself._deps[key]=[]\n\t\t\t\n\t\t#Since this a new formula, it doesn\'t yet depend on \n\t\t#any other cells. The dependencies will be\n\t\t#calculated when it\'s evaluated\n\t\tfor k in self._deps:\n\t\t\tif key in self._deps[k]:\n\t\t\t\tself._deps[k].remove(key)\n\t\t\n\tdef __getitem__(self, key ):\n\t\t#Dependency tree\t\t\n\t\tif key in self._eving:\n\t\t\t#Evaluating a cell in a loop\n\t\t\t\tself._eving=[]\n\t\t\t\traise "Loop1"\n\t\t\t\t\n\t\t#whatever I am evaluating is a dependency\n\t\t#for the last key I was evaluating\n\t\tif len(self._eving)>0:\n\t\t\tif self._eving[-1] not in self._deps[key]: #But only once\n\t\t\t\t\tself._deps[key].append(self._eving[-1])\n\t\t\t\t\n\t\tself._eving.append(key)\n\t\n\t\tbCache = self._cache is None\n\t\tif bCache: self._cache = {}\n\t\twhile True:\n\t\t\ttry:\n\t\t\t\ttry:\n\t\t\t\t\tf=self._cells[key]\n\t\t\t\t\tif f.strip()==\'\':\n\t\t\t\t\t\trv=\'\'\n\t\t\t\t\telse:\n\t\t\t\t\t\trv = eval(self._compiledcells[key], self.tools, self._cache)\n\t\t\t\texcept KeyError: #key not in _cells\n\t\t\t\t\trv=\'\'\n\t\t\t\tbreak\n\t\t\texcept NameError, ne:\n\t\t\t\tname = ne.args[0][6:-16] # Extract name from NameError\n\t\t\t\t\t\n\t\t\t\tif name in self._cells:\n\t\t\t\t\tself._cache[name] = self[name]\n\t\t\t\telif name[0]==\'_\' and name[1:] in self._cells:\n\t\t\t\t\tself._cache[name] = self[name[1:]]\n\t\t\t\telif isKey(name): #Default value is \'\'\n\t\t\t\t\tself[name]=\'\'\n\t\t\t\t\tself._cache[name] = self[name]\n\t\t\t\telse:\n\t\t\t\t\tself._eving=[]\n\t\t\t\t\traise\n\t\tif bCache: self._cache = None\n\t\tif self._lastval.has_key(key):\n\t\t\tif self._lastval[key] <> rv:\n\t\t\t\tself.emit(PYSIGNAL("cellChanged"),(key,rv))\n\t\t\t\tself._lastval[key]=rv\n\t\tself._eving.remove(key)\n\t\treturn rv\n\t\t\n\t\t\ndef isKey(key):\n\tif (key[0].isalpha() and key[1:].isdigit()) or (key[0:1].isalpha() and key[2:].isdigit()):\n\t\treturn True\n\treturn False\n\t\ndef coordKey(x,y):\n\tif x< 26:\n\t\tkey=chr(97+x)\n\telse:\n\t\tkey=chr(97+int(x/26))+chr(97+x%26)\n\tkey=key+str(y+1)\n\treturn key\n\t\n\t\ndef keyCoord(key):\t\t\n\tif key[1].isalpha():\n\t\tx=(ord(key[0])-97)*26+ord(key[1])-97\n\t\ty=int(key[2:])-1\n\telse:\n\t\tx=ord(key[0])-97\n\t\ty=int(key[1:])-1\n\treturn (x,y)</pre>', 'title': u"Here's my take on it"}], 'desc': u'Use eval() to drive spreadsheet style logic. The sleeper feature of Py2.4 is the ability to use any object with a mapping interface as the locals argument to eval().'}, {'comments': [], 'desc': u'Using pygtk and glade you can easily write all you need to provide a log text buffer to output the data dropped.'}, {'comments': [{'comment': u'To make it work it needs:\n\n<pre>import sys\nfrom code import InteractiveConsole</pre>\n', 'title': u"It's missing the import statements"}, {'comment': u'The return code of InteractiveConsole.push() should be returned by Shell.push(). Otherwise sys.ps2 is not displayed.', 'title': u'Return code of InteractiveConsole.push()'}], 'desc': u'The code module provides the ability to write your own Python shell, which you can use to filter out input or output, and embed it in another application. This recipe shows how this module can be used.'}, {'comments': [], 'desc': u'This receipe arose when I wanted to add a larger blob (some autocad data) to a xml document. As I did not want to get a large xml document and as I wanted to avoid CDATA sections I wrote the functions below.'}, {'comments': [{'comment': u'I had trouble with unpickle unicode type so I added it to the _easyToPickle list and it seems to work.\n<pre>\n_easyToPickle = [ "int", "float", "str","unicode" ]\n</pre>', 'title': u'Adding unicode type to _easyToPickle'}], 'desc': u'This receipe provides lightweight functions for pickling objects to a DOM structure and vice versa. I use it in connection with <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286150">Hierarchical Objecs</a> from receipe #286150.\n\n<strong>This receipe makes use of eval(), so do not unpickle untrusted xml documents !!!</strong>. I add some secret checksums to my documents which I check before unpickling.'}, {'comments': [], 'desc': u'Simple script for generating all the string described by a pattern passed on the command-line:'}, {'comments': [{'comment': u'Why not add a little *view* to the viewer? ;)\n<br>\n<br>\nIn __init__ add:<br>\n<pre>\n self.tc = wx.TextCtrl(self, -1\n , style=wx.TE_MULTILINE\n |wx.TE_READONLY)\n\n</pre>\nNow add the method:<br>\n<br>\n<pre>\n def GetTextFromClipboard(self):\n """\n """\n clipboard = wx.Clipboard()\n if clipboard.Open():\n if clipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):\n data = wx.TextDataObject()\n clipboard.GetData(data)\n s = data.GetText()\n self.tc.AppendText("Clip content:\\n%s\\n\\n" % s )\n clipboard.Close()\n else:\n self.tc.AppendText("")\n</pre>\n<br>\n<br>\nSubsequently, change your OnDrawClipboard method to something like:<br><br>\n<pre>\n def OnDrawClipboard (self, msg, wParam, lParam):\n if self.first:\n self.first = False\n else:\n self.tc.AppendText("[Clipboard content changed:]\\n")\n self.GetTextFromClipboard()\n if self.nextWnd:\n # pass the message to the next window in chain\n win32api.SendMessage (self.nextWnd, msg, wParam, lParam)\n</pre>\n<br>', 'title': u'Add a view to the viewer'}], 'desc': u'With the "SetClipboardViewer" function you can add a window to the chain of clipboard viewers. Whenever the content of the clipboard changes, a message is send to the clipboard viewer windows. A clipboard viewer window must process two messages and pass them to the next window in the chain. \nWith a sample about hooking the window procedure of a wxPython Frame, I made up the following clipboard viewer.'}, {'comments': [], 'desc': u'Here is how to use the new decorator feature of python 2.4 to systematically check the argument types for type-sensitive functions.'}, {'comments': [{'comment': u'This recipe:\n<br>\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/84317\n<br>\n<br>\ndoes the same thing, but also handles exceptions in the thread. Perhaps some of those ideas can be used here?', 'title': u'What about Exceptions?'}, {'comment': u'Deferred now catches exceptions and re-throws them at an appropriate time. \n\nThanks for the input and pointing out the similar recipe. If any advantage is gained here it is the fact that client code need not be concerned with the tricky business happening behind the scenes. The client calls the function, and treats the result as though it was an ordinary value.\n\n', 'title': u'Exceptions Caught'}, {'comment': u'The idea behind Deferreds in Twisted is to provide a sensible interface for asynchronous return values, i.e. those which you have to allow your code to return to a main-loop to retrieve. In other words, it is an interface for retrieving results without using threads.\n\nI cannot see a place where this code example would be useful in practice, but even if it is, it is *extremely* misleading to claim that this code is in any way related to the concept of Deferreds in Twisted.\n\nPlease re-name the class so as to avoid such confusion.', 'title': u'Missing the point completely'}, {'comment': u'Despite the title, this code _does_ wait around for the result; thread.join blocks until the thread produces a value. This is completely different from the way Deferred works in Twisted, where you register callbacks instead of waiting.', 'title': u'Misleading description'}, {'comment': u'As several have pointed out this recipe is does not implement deferred. I have made several changes to the code to avoid the mayham that was narrowly avoided.<br><br>\n\nThanks for all the watchful eyes!\n\n\n', 'title': u'Not deferred'}, {'comment': u'As several have pointed out this recipe does not implement deferred. I have made several changes to the code to avoid the mayhem that was narrowly avoided.<br><br>\n\nThanks for all the watchful eyes!\n\n\n', 'title': u'Not deferred'}, {'comment': u'It may not be a *Twisted* Deferred, but it is a deferred result. A common name for this type of object is a "Future" object (the object isn\'t \'real\' when the function returns, but it will be real in the future when you need it).', 'title': u' '}, {'comment': u'Thanks for the comment. Thats a good name for it that wont offend any one.\n\nJustin', 'title': u'Future'}, {'comment': u'There\'s a good description of various kinds of futures in the "Alice" tour: http://www.ps.uni-sb.de/alice/manual/tour.html', 'title': u' '}, {'comment': u'Excellent recipe.\n<br>\nBut note that recipe num 84317 is also about futures.\n<br>\nIn there the usage is more explicit.\n<br>\nAlso the category for this recipe should really be Threads like there', 'title': u'Other recipe about futures'}], 'desc': u'How to kick off a slow process without waiting around for the result. The process is run in the background until the value is actually needed at which time it blocks until the value is ready.'}, {'comments': [], 'desc': u'Modeled after the key= argument to list.sort() and sorted(). '}, {'comments': [{'comment': u"There are at least two errors in this recipe.\n\n<pre>\nclass DocStringCoverageVisitor(compiler.visitor.ASTVisitor):\n symbolcount = 0 # add this line\n ...\n\n def visitClass(self, clazz):\n ...\n isDoc = clazz.doc is not None and clazz.doc.strip() != '' # was func.clazz.strip()\n ...\n</pre>\n\nThe second change may not be correct. There may be other issues.\n\n", 'title': u' '}, {'comment': u'thanks very much for spotting these.', 'title': u'Thanks!'}], 'desc': u'Tool to examine lack of docstrings in a module.'}, {'comments': [], 'desc': u'This decorator can be used to cast argument types automatically, using a pre-specified list of types, when a function is called. '}, {'comments': [{'comment': u"The method sounds crude. Any idea on the accuracy?<br>\n<br>\nThe program TextCat sounds like a promising tool.<br>\n<br>\nhttp://odur.let.rug.nl/~vannoord/TextCat/<br>\n<br>\nTextCat is an implementation of the text categorization algorithm presented in Cavnar, W. B. and J. M. Trenkle, ``N-Gram-Based Text Categorization'' In Proceedings of Third Annual Symposium on Document Analysis and Information Retrieval, Las Vegas, NV, UNLV Publications/Reprographics, pp. 161-175, 11-13 April 1994.", 'title': u'Any idea on the accuracy?'}, {'comment': u'Seems to work fine with long texts. A good base for comparison is important, e.g. the charta of human rights or the bible that is translated in almost all languages.', 'title': u'accuracy'}], 'desc': u'A small tool for language and author identification of textfiles. More ore less a proof-of-concept of an article that I found in 2002 on "Heise Newsticker". For more informations visit:\n\n\nhttp://www.heise.de/newsticker/data/wst-28.01.02-003/ \nhttp://xxx.uni-augsburg.de/format/cond-mat/0108530'}, {'comments': [{'comment': u'Chiese version of this recipe is here:\n\nhttp://blog.czug.org/panjunyong/mail-line-wrap', 'title': u'Chinese version of this recipe'}], 'desc': u"There are many cool word-wrap recipes, but most don't support unicode, such as Chinese characters. Note: you should use python2.4 to test the recipe for the 'gbk' encoding."}, {'comments': [], 'desc': u'textwrap is a very handy module. The problem with it, though, is that it expects to be used with individual paragraphs. But what if you want to wrap an entire document? It will still wrap the lines, but it will improperly consider it all a single paragraph.\n\nThis recipe alleviates that issue by overriding textwrap.TextWrapper.wrap with an implementation that handles spiltting a document into paragraphs and processing each individually. This allows things such as initial_indent to work as expected.'}, {'comments': [], 'desc': u'This code will compute the checksum as used by GPS message strings ( $GPRMC, etc)'}, {'comments': [], 'desc': u"-1.234e+018 --> '-1234000000000000000.0'"}, {'comments': [{'comment': u"As I see, remote_Save() was written badly and failed at files, which name ends with 'zip': '123zip', 'zipzipzip', 'zip', that are not *.zip.\n\n<pre>backups[-3:].lower() == 'zip'</pre>\n\nwill be\n\n<pre>os.path.splitext(backups)[1].lower() == 'zip'</pre>\n\nAfter this error I placed entire recipe in my own blacklist.", 'title': u'Errors..'}], 'desc': u'Windows backup utility, with remote copy, and auto cleanup. Uses zip libs.\nUsed in a production network environment and works very well dumping both \ntarget files and remote target files over the network so you are not limited to saving a copy local. '}, {'comments': [{'comment': u'Great stuff. The Mac address can also be in the 000D9DD95A4B format.\nIs there anything like shutdown on LAN (SOL)?', 'title': u' '}, {'comment': u'Thanks for pointing that out Eric. I\'ve included it in the example. \n\nFor "SOL" ;) though, afraid that can\'t be done. There are ways however to shutdown remote computers. On Windows (NT-based only), it can be done using RPC/WMI calls. I\'ll post a recipe on that soon, look out for it.', 'title': u'Mac Address Format'}, {'comment': u'See: <br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/360649', 'title': u'Remote Shutdown'}, {'comment': u'It is not clear to me why I get this error on my MacBook Pro:\n<br><br>\nshaneg@shane-gs-computer:~\\ 21:25:57$ sudo python /tmp/wol.py<br>\nTraceback (most recent call last):<br>\n File "/tmp/wol.py", line 34, in <br>\n wake_on_lan(\'0F:0F:DF:0F:BF:EF\')<br>\n File "/tmp/wol.py", line 30, in wake_on_lan<br>\n sock.sendto(send_data, (\'\', 7))<br>\nsocket.error: (49, "Can\'t assign requested address")<br>\nshaneg@shane-gs-computer:~\\ 21:26:02$<br>\n\n<br>\nI assume \'<broadcast>>\' should be replaced with the broadcast address for your LAN--which is usually the IP address after the last usable IP address in your network range. In a 192.168.1.0/24 network, the broadcast address would be 192.168.1.255 (unless configured otherwise). <br>\n<br>\n\nAnwyay, that\'s my assumption, so I now changed one line to look like this: sock.sendto(send_data, (\'192.168.1.255\', 7)) The script does not give me errors when I run it that way. I haven\'t yet tested it to see if it actually does WOL, as advertised. (If I am correct, then passing in the broadcast_addr would be a nice change of the function.)\n\n', 'title': u'problem running script'}], 'desc': u'Switches on remote computers using WOL.'}, {'comments': [{'comment': u"The code is faster and more concise when expressed as a generator rather than as a class based iterator. Most of the gains arise from using local variables rather than instance variables.\n\nOn Windows platforms, timer resolution is improved by using time.clock instead of time.time (taking a lesson from the timeit module).\n\nReadability is further improved by use of clearer variable names.\n\n<pre>\nimport sys\n\ndef GovernedRange(low, high, speed=1.0):\n high, speed = float(high), float(speed)\n if sys.platform == 'win32':\n timer = time.clock\n else:\n timer = time.time\n now = timer()\n timelimit = now + (high - low) / speed\n while now < timelimit:\n yield (now - timelimit) * speed + high\n now = timer()\n</pre>", 'title': u'Various improvements'}, {'comment': u'The last recipe can be modified so that speed gets multiplied by a global variable to allow for smooth accelerations.', 'title': u'Acceleration'}, {'comment': u'This is actually the reason I used a class, rather than a generator. \n<br>\n<br>\nIf I have multiple GovernedRange generators , I would need multiple global variables. Using a class to implement the GovernedRange creates a more usuable, encapsulated object.', 'title': u'Acceleration, with global variable'}], 'desc': u'This class implements a generator, which returns consecutive floats which are incremented by a speed * (time between calls).'}, {'comments': [], 'desc': u'This recipe automates the creation and lookup of objects passed from and to xmlrpc server methods so that incoming calls arguments are automatically replaced by their respective objects, and returned objects get mapped and their ids returned.'}, {'comments': [{'comment': u'How is this different from the shuffle function in the random module?<br>\nhttp://www.python.org/doc/2.4/lib/module-random.html', 'title': u' '}], 'desc': u'Randomly shuffle elements of an array'}, {'comments': [{'comment': u"If you shut down the box remotely (as opposed to restarting it), who is going to hit the power button and turn it back on for you?<br><br>\n\nUnless you're totally decommissioning a machine, this sounds like a bad idea.", 'title': u'think it through'}, {'comment': u"Hi Joe, I couldn't agree with you more but any smart administrator wouldn't run it against critical machines if that's what you meant.\nThere are scenarios when u need this, if you actually thought it through. One example is the management of desktop machines. I manage a few hundred of them and it is company's policy to switch off ya machines over the weekend. We didn't have that policy before the blaster worm came and the desktops that were left running broke the network including the critical servers. <br>And if that doesn't get you thinking, somebody actually asked me before if it could be done. http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/358449.\n\nAnyway, if you actually read the code, it has options for rebooting. Cheers.", 'title': u'Think it through, again...'}, {'comment': u'See: <br>http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/358449\n<br>\n(Clarification of previous comment)', 'title': u'Wake On Lan is the other side of this'}, {'comment': u'I have 2 issues when using this script:<br><br>\n\n1) Computer doesn\'t power off like a regular shutdown does. It stays on the "Safe to power off" screen and I have to push the power button to power off.<br><br>\n\n2) After using this script to shutdown a computer and power off by pushing power button, I can\'t wake it up using wake-on-lan. I have to physically push the power button.<br><br>\n\nAnyone know why these things happen with this script? Thanks.', 'title': u"Doesn't power off"}, {'comment': u'I use MS Remote Desktop and have had problems with the remote machine failing to accept a connection. I started a ping with <br>\n<pre>ping -t <hostname></pre>\nand ran the script in restart mode, and watched as the machine restarted (ping started timing out) and as it came back online (ping started succeeding). Saves me a trip to work to physically restart the machine. Thanks!', 'title': u'Worked great!'}, {'comment': u"I'm working on client/server software that runs, on the client side, while the machine boots. I wanted to verify that I didn't have resource leaks on the server side. Within minutes of finding your code, I was able to modify it by putting the reboot in a loop (and adding a test user id to the client), and ran the test overnight, with my server rebooting the client every ten minutes. What a productivity boost!", 'title': u'Thank you -- very helpful'}, {'comment': u'I wonder If there is a way to check first to see if a user is signed on. In some cases you could have say a 24 hour lab, and not want to shut down a machine someone is doing work on.', 'title': u'Check for Users'}], 'desc': u'Shuts down or reboots a remote computer.'}, {'comments': [{'comment': u'See http://www.logilab.org/projects/python-logic and http://christophe.delord.free.fr/en/pylog/ and http://www.logilab.org/projects/constraint', 'title': u'Did you know about python-logic SIG and pylog ?'}, {'comment': u' ', 'title': u'Yes, and pylog is a better "prolog-in-python"...'}, {'comment': u'Hi,<br><br>\n\nFirst of all, thank you for the compliment. Seeing this was a very nice and welcome surprise.<br><br>\n\nSecond, there are a few comments I want to make, to help improve the recipe.<br><br>\n\nOne is in the Python implementation: Look up Generators. The list of solutions to a Prolog-like query simply begs for lazy evaluation. Generators have been in Python since 2.2, I think, and 2.4 has "generator expressions", which are the generator parallels of list comprehensions.<br><br>\n\nAnother is that the decorator in my recipe has a couple of advantages over the overloaded operator. One is documentational: with a decorator, the logical function declares itself up-front as special, whereas with your implementation this is left for comments and code after the function. More importantly, the decorator hides the reference to the original function, where your code does not (the relevant line can be fixed to "func = db << func" but that is a lot less pretty).<br><br>\n\nAlso, I think putting the queries in the database for them to be solved is a little odd. I expect a database to be usable for answering several queries, one at a time, with no interactions between them, and this way I can\'t solve a new query without solving all the past queries. Or am I missing something? (my first thought was "he wants all queries to be defined in advance?!", but, of course, queries can be added later because more logical functions can be appended).<br><br>', 'title': u'Thanks and suggestions'}], 'desc': u'This extends the previous "pythologic" recipe with resolution, based on unification and greattly inspired by the AIMA books and examples.\n\nThe author is *not* a python expert and expects to see this contribution further discussed and developed.'}, {'comments': [], 'desc': u'This recipe shows how to insert java code into a jython program. The java code is automatically compiled and the resulting class is imported and returned. Compilation only occurs after a change of the java source. '}, {'comments': [{'comment': u'Is\n<pre>\nfinally:\n del frame\n</pre>\nreally needed? If so, why?', 'title': u'try...finally?'}, {'comment': u'...because it expects __new__ to be called from the frame where the function is defined. But, if you subclass this metaclass, __new__ will be called via \'super()\' in the subclass, so this will inspect the wrong frame.<br><br>\n\nThis problem isn\'t fixable within a metaclass; the only way to fix it is to use an explicit metaclass that wraps the real metaclass, or conversely to use a "class advisor" function (see PyProtocols\' \'protocols.advice\' module, or Zope 3\'s \'zope.interface.advice\' module). Such advisor functions can identify the correct frame *before* the class is even constructed, and then get a callback with the constructed class.<br><br>\n\nA class advisor isn\'t inherited, so you have to use it in each class you want to be updateable, but the approach *is* combinable with other metaclasses and advisors, while the technique shown here will not work correctly with other metaclasses.', 'title': u'This metaclass will not co-operate with other metaclasses, nor is it subclassable'}, {'comment': u'I read so that in the documentation, \nhttp://docs.python.org/lib/inspect-stack.html', 'title': u"Ans: It's for GC"}, {'comment': u'Thanks for the information, pyprotocols and zope\'s code,\nI had not ever seen them. Both projects has interesting codes I have to learn.\n\nAbout the stack frame scope, that was as I expected. But, I haven\'t\nseen the exception case, when the \'__new__\' is called by \'super\',\nCan I see the minimum code ?\n\nSub-classing, I\'ve tested was ...\n\nclass C:\n def foo(self): print "C.foo method is called"\nclass C(RubyObject):\n def bar(self): print "C.bar method is called"\nclass D(C):\n pass\nd = D()\nclass D(RubyObject):\n def baz(self): print "D.baz method is called"\nd.foo()\nd.bar()\nd.baz()\n\nand it worked in this case.\n \nBut I am not sure it with other metaclasses.\nabout multi meta-classes, and how it works.\nWhen I declared \'__metaclass__\' with subclass of RubyObject,\nit just shown this error:\n\nTypeError: Error when calling the metaclass bases\n metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases\n\nThis is seem another problem.', 'title': u'with other metaclasses? I did not know how to do it.'}], 'desc': u'It brings Ruby-like class behavior.\nWhen a class is declared, it extends the old class if the class name exists already.'}, {'comments': [], 'desc': u'An example done to solve this problem:\n\nhttp://acm.uva.es/p/v1/101.html\n\nAnimation by vpython (visual python): http://vpython.org/\n\nProvides some 3d coolness for new pythonists. Shows some stack usage. Probably should be shorter.\n\nIn the __main__ statement at the bottom, replace test2() with parse(), then type something like this on each line:\n10\nmove 5 onto 1\npile 1 onto 3\nmove 6 over 2\npile 3 over 2\netc.\n\nSee the problem link at the top for full instructions...'}, {'comments': [{'comment': u'Hi!\n<br>\nTo just check if the number is in money format and valid money formats are "123" and "123.04" I would do something like this:\n<pre>\ndef isMoney(money):\n money = str(money)\n if money.isdigit(): return True\n else: \n try: \n new = "%.2f" % float(money)\n return new == money\n except: return False\n\nif __name__ == \'__main__\':\n print isMoney("123.004") # False\n print isMoney(123) # True\n print isMoney("123.04") # True\n print isMoney("1.2.3") # False\n print isMoney("hello") # False\n</pre>', 'title': u' '}, {'comment': u'Hi Markus!\nyeah! your code is looks smartter Hi Markus!\nyeah! your code is looks smartter ', 'title': u' '}, {'comment': u'Hi Markus!\nyeah! your code is looks smartter Hi Markus!\nyeah! your code is looks smartter ', 'title': u' '}, {'comment': u'but it cant function when i key in "123.4". i expect it return $123.40 as the answer; but it return false!!', 'title': u' '}, {'comment': u'Hi!\n<br>\nMy function just checks if the data is in money-format. If you want to convert it to this format, you can do this:\n<pre>\ndef to_money(data):\n try:\n return "$%.2f" % data\n except:\n return False # or some error message\n\nprint to_money(123.4) # -> $123.40\n</pre>', 'title': u' '}, {'comment': u'<pre>\nHi! \nhow do you think about the following code?\n\ndef isMoney(money):\n money = str(money)\n if money.isdigit():\n return "%.2f" % float(money)\n else: \n try: \n new = "%.2f" % float(money)\n return new\n except: return False\n\nif __name__ == \'__main__\':\n print isMoney("123.4") # True\n print isMoney(123) # True\n print isMoney("123.04") # True\n print isMoney("1.2.3") # False\n print isMoney("hello") # False\n\nit\'s looks better <pre>\nHi! \nhow do you think about the following code?\n\ndef isMoney(money):\n money = str(money)\n if money.isdigit():\n return "%.2f" % float(money)\n else: \n try: \n new = "%.2f" % float(money)\n return new\n except: return False\n\nif __name__ == \'__main__\':\n print isMoney("123.4") # True\n print isMoney(123) # True\n print isMoney("123.04") # True\n print isMoney("1.2.3") # False\n print isMoney("hello") # False\n\nit\'s looks better </pre></pre>', 'title': u' '}, {'comment': u'In some countries the default delimiter on decimal value is the , comma character. Not the . dot.', 'title': u'What about , comma'}, {'comment': u"<pre>\ndef isMoney(str):\nimport re\nre_money = re.compile(r'\\$([0-9]{,3}\\,?)+(\\.[0-9]{,2})?$')\n if(re_money.match(str)):\n print 'true'\n else:\n print 'false'\n\nisMoney('0.2') #false\nisMoney('$0.2') #true\nisMoney('$0.20') #true\nisMoney('10.234') #false\nisMoney('$1,100.0.001829') #false\nisMoney('$1,000,000.20') #true\nisMoney('$1.1,0') #false</pre>", 'title': u'isMoney with re'}], 'desc': u'just a simple little program that able to check the data key-in is in form of money or not.'}, {'comments': [{'comment': u"This doesn't try to solve the threading problem, but I think I prefer a solution that keeps 'args' in the 'fn' namespace, like:\n\n<pre>class fn(object):\n class args(object):\n def __iter__(self):\n return self\n def next(self):\n args = self.args\n del self.args\n return args\n args = args()\n def __new__(self, gen):\n def anonymous(*args):\n fn.args.args = args\n return gen.next()\n return anonymous</pre>\n\nwhich would then be used like:\n\n<pre>>>> foo = fn(a + b * c for a, b, c in fn.args)\n>>> foo(3, 4, 5)\n23\n>>> foo(4, 5, 6)\n34</pre>\n\nThat way 'args', which is intimately joined with 'fn', appears as such namespace-wise.", 'title': u'using namespace for args'}, {'comment': u'Perhaps a little prettier:\n\n<pre>class fn(object):\n class args(object):\n def __iter__(self):\n return self\n def next(self):\n args = self.args\n del self.args\n return args\n args = args()\n def __init__(self, gen):\n self._gen = gen\n def __call__(self, *args):\n fn.args.args = args\n return self._gen.next()</pre>\n\nAlso has the benefit of naming "functions" generated by fn as "fn":\n<pre>>>> foo = fn(a + b * c for a, b, c in fn.args)\n>>> foo\n<__main__.fn object at 0x01150090></pre>', 'title': u' '}, {'comment': u'I originally used a class for the "portable" version but got stuck because I didn\'t remember __new__. I\'ll update the recipe when I get a few tuits; thanks!', 'title': u'Good points'}], 'desc': u'Replacement for lambda that uses language features new to Python 2.4.\nOne implementation has a neat (ab)use of sys._getframe(); the other is portable.'}, {'comments': [], 'desc': u"This function makes it easier to use the timeit module from the interactive interpreter.\n\nJust specify function with (optional) arguments to run, optional number of runs, and optional name of module (which if not specified defaults to the name of the function). \n\nExample:\n\n>>> timefunc.timefunc('r()', 20)\n20 loops, best of 3: 6.91e+004 usec per loop\n\n>>> timefunc.timefunc('rx()', 20, 'r')\n20 loops, best of 3: 2.23e+004 usec per loop"}, {'comments': [], 'desc': u'A function which enables you to connect to and emit signals from (almost) any python object without having to subclass qt.QObject in PyQT.'}, {'comments': [{'comment': u'Member storage is as easely archieved with an empty class, without the hazards of dressing up like a dict but not beeing one.<br><br>\n\nAll these members are belonging to a dict:<br>\n__class__, __cmp__, __contains__, __delattr__, __delitem__, __dict__, __doc__, __eq__, __ge__, __getattribute__, __getitem__, __gt__, __hash__, __init__, __iter__, __le__, __len__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __setitem__, __str__, __weakref__, clear, copy, fromkeys, get, has_key, items, iteritems, iterkeys, itervalues, keys, pop, popitem, setdefault, update and values.<br>\nCan you be sure that you can keep all in your head? Much more make sure that none of your perhaps external data isn\'t using any of these keys. Worst kind of errors are those which pop up and say at some point "TypeError: \'str\' object is not callable" because somewhere within your zigillion of kv pairs there\'s an error.<br><br>\n\nYou\'re providing two near and similar interfaces to modify the same data, that that\'s against "preferably one way" of doing things.<br><br>\n\nMessing with __dict__ is not guaranteed to work in the future as it\'s an implementation detail that\'s stated as beeing subject to change by the language-devs if need be.<br><br>\n\nConfusing and intermixing storage-semantics with member-semantics bears bad code.\n\nUsing members for data collections from outside of the class code can be used in a good manner, but is more often associated with bad code ( nothing that couldn\'t be remedied in a normal class however with automatic setter/getter methods and accepting the members as interfaces )', 'title': u'Bad idea because...'}, {'comment': u"Here's an alternate implementation (not really the same thing, but similar):\n<pre>\nclass AttrDict(dict):\n def __init__(self, *args, **kwargs):\n dict.__init__(self, *args, **kwargs)\n def __getattr__(self, name):\n return self[name]\n</pre>\nIn this one you can read dict entries as attributes, but attributes and dict entries are not the same thing. So, this one has the advantage that dict entries won't mask attributes, but the disadvantage that you can't read attributes using the dict subscript (d[k]) notation.\n<br><br>\nYou could more fully emulate the original by defining __getitem__(), __setitem__(), etc. (container special methods.)", 'title': u'Alternate Implementation'}, {'comment': u"This idea keeps cropping up; perhaps (as one commenter says) it's a bad mixing of semantics, but it's also extremely *useful* on many occasions. I wrote an implementation before finding one already in Zope:<br>\nhttp://www.livejournal.com/users/benlast/12301.html\n\n", 'title': u"It's that wheel again..."}, {'comment': u"Rather than a confusing mash of both objects and dicts, why not just add iteration over the attibutes? Leave setting and getting alone. <br><br>\n\nTBH, I don't want a dict object, I just want an object with named attributes, but I want to be able to iterate over those attributes. I can test for existance of an attribute with a has_attr function. You can just map the desired functions across to the __dict__ object.<br><br>\n\neg.\n\n<pre>\nclass iterobject(object):\n\n keys = self.__dict__.keys\n values = self.__dict__.values\n items = self.__dict__.items\n iterkeys = self.__dict__.iterkeys\n itervalues = self.__dict__.itervalues\n iteritems = self.__dict__.iteritems\n __iter__ = self.__dict__.__iter__\n\n def has_attr(self, attr):\n return self.__dict__.has_key(attr)\n</pre>", 'title': u'Do you need key access?'}], 'desc': u'Sometimes accessing dictionary items as if they were member variables can be convenient.'}, {'comments': [{'comment': u'This is good, but I would change this:<br>\n"Python has a first class unicode type which you can use in place of the plain byte-string str type."\n<br><br>\nTo:<br>\n"Python has a first class unicode type which you should always use instead of str to represent text." :)', 'title': u' '}, {'comment': u'Excellent article, with one typo: A unicode obj has an encode() method but not a decode() one.\n<br>\n<pre>\n>>> german_ae.decode(\'latin1\')\nTraceback (most recent call last):\n File "", line 1, in ?\nAttributeError: \'unicode\' object has no attribute \'decode\'\n>>> german_ae.encode(\'latin1\')\n\'\\xe4\'\n</pre>', 'title': u'Typo: unicode object has no decode() method'}, {'comment': u'i incoporated your suggestions in version 1.1.', 'title': u'thanks to Bob and Wade'}, {'comment': u'Unicode objects have a decode method in Python2.4.', 'title': u're: unicode.decode()'}, {'comment': u'Two points:<br>\n(1) there is nothing specifically German about the letter; it is used in other languages<br>\n(2) It\'s very hard to imagine in practice anybody writing code in terms of utf8 constants. Where do you look up what what code to use? Much more practical is using (wait for it!) Unicode -- can be looked up on the unicode.org website, or using the "charmap" accessory on Windows [presumably similar on other OSes], ...<br>\n<br>\nSo:\n\nlatin_small_letter_ae = u\'\\u00e6\' # or u\'\\xe6\'', 'title': u'First example with "german ae" could be better'}], 'desc': u'You need to deal with text strings which include non-ASCII characters. Python has a first class unicode type which you should always use instead of str to represent text.'}, {'comments': [{'comment': u'please see the discussion here http://bob.pythonmac.org/archives/2005/01/29/clever-use-of-pythons-complex-numbers/', 'title': u'Related Idea'}, {'comment': u'There is a similar polynomial class in scipy (http://www.scipy.org): scipy.poly1d <br>\n\nHere are some examples: <br>\n\n<pre>\n>>> import scipy \n>>> a = scipy.poly1d([1,2,3]) \n>>> print a \n 2\nx + 2 x + 3 \n>>> a = scipy.poly1d([10,20,30])\n>>> print a \n 2\n10 x + 20 x + 30 \n>>> print a * a \n 4 3 2\n100 x + 400 x + 1000 x + 1200 x + 900 \n</pre>\n\nIt has many of the same features and more (also can find the roots of the polynomial). ', 'title': u'A similar Polynomial class is in scipy'}], 'desc': u"This package does simple polynomial manipulation: adding, multiplying, taking to powers, evaluating at a value, taking integrals and derivatives. Nothing as sophisticated as Mathematica, but useful all the same. I find that I make lots of dumb errors in multiplying out polynomials by hand (when I don't have Mathematica at my disposal), and this little script helps prevent those errors."}, {'comments': [{'comment': u'I strongly disagree with these kind of recipes. Python has its own way for doing things and a Python programmer should adopt those views right form the beginning. Letting people programming in Python the way they do in [other language] is the worst thing you can do.\nOf course, we have to make a strong distinction between things like this which can make your code look like [other language] and between extending Python with features from [other language]. The latter can be useful.<br><br>Sandor', 'title': u'Disagree with the approach'}, {'comment': u'I did something similar a couple of years ago (inspect.getsource +\nmetaclass) but I never had the courage to publish it ;-)\n\nBTW, the textwrap module has a dedent function which you may want to\nuse.\n\n Michele Simionato', 'title': u'you are courageous'}, {'comment': u"I was thinking of adding a comment similar to Sandor's. There is always some uncomfortableness when encountering change. That's the pain of growoth. This recipe is like apsirin that helps the symptom but not the root cause. Although I must say I do find it clever. But it really is not doing people new to the language justice. If you are learning python then learn python and the *philosophy* of python, one is better served by staying with the legacy language that they already know.", 'title': u"Please don't publicize this recipe"}], 'desc': u'People used to statically typed languages coming to Python often complain that you have to use "self" (or whichever name you want, but self is most common) to refer to a method or variable in that object. You also have to explicitly pass a reference to the method\'s object in every call to it. Many people new to Python are annoyed by this and feels that it forces a lot of unnecessary typing. This recipe presents a method which makes "self" implicit.'}, {'comments': [{'comment': u'This is really cool, i was going to write something very similar. My application: I have made backups for the last ten years, and many times complete backups, which have now been copied on a single hdd for safety. Much of these files are identical. I wanted to hardlink them together to save the disk space. I can now just modify your app! thanks,', 'title': u'Hard links?'}, {'comment': u"http://www.iol.ie/~padraiga/fslint/ does this, as well as other useful things (and in shorter code too, I believe). I haven't investigated the various file-compare optimizations of each system.\n<br>\nBTW, a common use of the fslint tools is to find dups on the same filesystem and replace them with hardlinks. If you don't care about the once-identical files being forever identical, you can avoid needless space waste.", 'title': u'fslint'}], 'desc': u'Point this script at a folder or several folders and it will find and delete all duplicate files within the folders, leaving behind the first file found of any set of duplicates. It is designed to handle hundreds of thousands of files of any size at a time and to do so quickly. It was written to eliminate duplicates across several photo libraries that had been shared between users. As the script was a one-off to solve a very particular problem, there are no options nor is it refactoring into any kind of modules or reusable functions.'}, {'comments': [], 'desc': u'This is a strange one. Strange, and interesting. This class creates an object which returns a logarithmic progression of numbers over a period of time. It allows the target value to change, causing the progression of values to speed up, slow down, or even reverse. Why is this useful? Read on below for more...'}, {'comments': [{'comment': u'With a visual foxpro dbf file I get an AssertionError regarding the terminator.<br>\n<pre>\n>>> db = list(dbfreader(f))\nTraceback (most recent call last):\n File "", line 1, in ?\n File "dbf.py", line 29, in dbfreader\n assert terminator == \'\\r\'\nAssertionError\n</pre>\nCan your recipe be modified easily to work with Visual FoxPro?', 'title': u'Visual FoxPro'}, {'comment': u'there is a small typo in the example code: main function is written twice and the second "version" has a bug in it (a missing argument in dbfwriter()); the first version works though', 'title': u'small typo'}, {'comment': u"Attempting to run the DBF reader portion of the code results in the following invalid syntax error ...<br>\n<br>\n yield [field[0] for field in fields]\n<br>\n<br> \nan accompanying warning message is issued indicates that 'yield' will become a reserved word.\n", 'title': u'yield statement syntax error using ActiveState Python V2.2'}, {'comment': u'Generators were still an optional feature in Python 2.2.<br>\n<br>\nJust add "from __future__ import generators" to the top of the module.', 'title': u'Generators in Python 2.2'}, {'comment': u'Great code, as a newbie I would love to write code this tight. When I ran this on a DBF file it was one byte out , adding a new line to grab an extra byte sorted this out.\n<br> <br> \n terminator = f.read(1) <br>\n assert terminator == \'\\r\'<br>\n <br>\n fields.insert(0, (\'DeletionFlag\', \'C\', 1, 0))<br>\n fmt = \'\'.join([\'%ds\' % fieldinfo[2] for fieldinfo in fields])<br>\n fmtsiz = struct.calcsize(fmt)<br>\n hamish = f.read(1) ----NEW LINE <br>\n<br> <br>\nThen I had no problems. I dont know if this is due to an extra byte<br> after the terminator \'\\r\' ???. Anyway, that helped.<br> \nThe other problem I had was empy dates. If the value was \' \'<br> then I would get errors ie a=int(\' \') gives an error<br>\nChangeing the code for the Date record to this<br>\n<br><br>\n elif typ == \'D\':<br>\n y, m, d = value[:4], value[4:6], value[6:8]<br>\n value=d+"/"+m+"/"+y<br>\n<br> <br>\nworked and gave me the date in a dmy format.<br> If the string was \' \' then I get \' / / \' which is ok.<br>\nHamish<br>', 'title': u'1 byte out....'}, {'comment': u"File handlers for dbfwriter must be open in 'wb' mode, especially on Windows platform, because write method will convert 0xA to 0x0A 0x0D (CR to CRLF) and you'll get corrupted DBF.", 'title': u'Note that'}, {'comment': u"I am butting my head against a wall trying to do something very simple\nwith this: write a dbf file to disk (on XP). E.g modifying the sample script:\n\n filename = 'c:\\MyDBF.dbf'\n g = open(filename, 'wb')\n f = StringIO()\n dbfwriter(f, fieldnames, fieldspecs, records)\n g.write(f.getvalue())\n g.flush()\n\nAccess doesnt like the resultant file. And DBFReader function also\ncomplains about it.\n\nAny insight would be appreciated.\n\nDennis Christopher", 'title': u'problem writing dbf file to disk'}], 'desc': u'Reader iterates over records in Dbase or Xbase files.\nWriter creates dbf files from Python sequences.'}, {'comments': [{'comment': u'"""raise ImportError("The _imaging C module is not installed")\nImportError: The _imaging C module is not installed\n"""\ni\'m test under win2k3, ActivePython 2.4 Build 243 + PIL-1.1.4.win32-py2.3\n\n"C module" what is ??', 'title': u'error when running...'}, {'comment': u"The problem is at a lower level than I can solve easily, but it sounds like PIL is not installed correctly. Try reinstalling PIL, then test it using an interactive prompt, like this:\n\n<pre>\n>>> import Image\n>>> Image.open('overlay.png').show()\n</pre>", 'title': u'PIL might not be fully installed'}, {'comment': u'>> ActivePython 2.4 Build 243 + PIL-1.1.4.win32-py2.3<br><br>\n\nYou are using Python 2.4 with PIL compiled for Python-2.3.\nThat will not work.', 'title': u' '}, {'comment': u'Shane, thanks for this recipe. I needed to put together a routine to add an imprint of a date to digital photos (my wife likes the date to appear, but I don\'t; so this keeps us both happy), and your recipe gave me a great starting point.\n\n<pre>\ndef Imprint(im, inputtext, font=None, color=None, opacity=.6, margin=(30,30)):\n """\n imprints a PIL image with the indicated text in lower-right corner\n """\n if im.mode != "RGBA":\n im = im.convert("RGBA")\n textlayer = Image.new("RGBA", im.size, (0,0,0,0))\n textdraw = ImageDraw.Draw(textlayer)\n textsize = textdraw.textsize(inputtext, font=font)\n textpos = [im.size[i]-textsize[i]-margin[i] for i in [0,1]]\n textdraw.text(textpos, inputtext, font=font, fill=color)\n if opacity != 1:\n textlayer = reduce_opacity(textlayer,opacity)\n return Image.composite(textlayer, im, textlayer)\n</pre>\n\nI use the following to get the date to be added:\n\n<pre>\ndef GetFileDate(file):\n """\n Returns the date associated with a file.\n For JPEG files, it will use the EXIF data, if available\n """\n try:\n import EXIF\n # EXIF.py from http://home.cfl.rr.com/genecash/digital_camera.html\n f = open(file, "rb")\n tags = EXIF.process_file(f)\n f.close()\n return str(tags[\'Image DateTime\'])\n except (KeyError, ImportError):\n # EXIF.py not installed or no EXIF date available\n import os.path, time\n return time.ctime(os.path.getmtime(file))\n</pre>', 'title': u'Great for adding dates on digital photos, too'}], 'desc': u'Apply a watermark to an image using the Python Imaging Library. Supports color, tiling, scaling, and opacity reduction.'}, {'comments': [{'comment': u'I think everyone carries around a version of flatten. Search examples on groups.google.com for "flatten list python" to see people golfing for the shortest/fastest/clearest solutions.', 'title': u'Flatten'}, {'comment': u'There is a very simple and quick flattener that can be found in the basictypes folder in the latebind.py script by Mike C. Fletcher. The source can be downloaded from <br>\nhttp://sourceforge.net/project/showfiles.php?group_id=87034&package_id=90541&release_id=288585<br><br>\nHere it is:<pre>\nimport sys\ndef flatten(inlist, type=type, ltype=(list,tuple), maxint= sys.maxint):\n\t"""Flatten out a list."""\n\ttry:\n\t\t# for every possible index\n\t\tfor ind in xrange( maxint):\n\t\t\t# while that index currently holds a list\n\t\t\twhile isinstance( inlist[ind], ltype):\n\t\t\t\t# expand that list into the index (and subsequent indicies)\n\t\t\t\tinlist[ind:ind+1] = list(inlist[ind])\n\t\t\t#ind = ind+1\n\texcept IndexError:\n\t\tpass\n\treturn inlist\n</pre>\n\nI\'m not sure why the "type=type" argument is present since "type" is not used in the function. \nAlso, if you omit the last line a copy will not be returned; the modification will only be done in place.', 'title': u'a simple non-recursive version that modifies in-place'}, {'comment': u"Fletcher's version is really cool! I have a (slight) improvement to make it even simpler:\n\n<pre>def flatten(l, ltypes=(list, tuple)):\n i = 0\n while (i < len(l)):\n while (isinstance(l[i], ltypes)):\n l[i:i+1] = list(l[i])\n i += 1\n return l</pre>\n\nSince len(l) is evaluated each time through the loop, we can just run to the dynamic size of the list, no need to run to maxint and catch the index error.", 'title': u'a further simplification...'}, {'comment': u'<pre>>>> flatten([1, 2, [3, []]])\nTraceback (most recent call last):\n File "", line 1, in \n File "", line 4, in flatten\nIndexError: list index out of range\n\nor simply...\n\n>>> flatten([[]])\nTraceback (most recent call last):\n File "", line 1, in \n File "", line 4, in flatten\nIndexError: list index out of range\n\nneed to do something with the inner while loop so that it doesn\'t crash when the last element to be flattened is an empty list.\n\nnoah </pre>', 'title': u'Too simple?'}, {'comment': u'OK, good point. So here is a fixed version to support empty lists (in any position):\n\n<pre>\ndef flatten(l, ltypes=(list, tuple)):\n i = 0\n while i OK, good point. So here is a fixed version to support empty lists (in any position):\n\n<pre>\ndef flatten(l, ltypes=(list, tuple)):\n i = 0\n while i </pre></pre>', 'title': u'Yup, good point...'}, {'comment': u'err, it messed up my post...\n\n<pre>def flatten(l, ltypes=(list, tuple)):\n i = 0\n while i < len(l):\n if not l[i]:\n l.pop(i)\n continue\n while isinstance(l[i], ltypes):\n l[i:i+1] = list(l[i])\n i += 1\n return l</pre>', 'title': u' '}, {'comment': u' >>> flatten([[[]]])\n<br>\nTraceback (most recent call last):\x0c<br>\n File "", line 1, in \x0c<br>\n File "/tmp/python-2596k4V", line 7, in flatten\x0c<br>\nIndexError: list index out of range\x0c', 'title': u'Still problems with empty lists'}, {'comment': u'OK, this should fix it.\n\n<pre>def flatten(l, ltypes=(list, tuple)):\n i = 0\n while i < len(l):\n while isinstance(l[i], ltypes):\n if not l[i]:\n l.pop(i)\n if not len(l):\n break\n else:\n l[i:i+1] = list(l[i])\n i += 1\n return l</pre>\n', 'title': u'Another fix...'}], 'desc': u'Function for flattening sequences (currently works on tuples and lists, potentially works on user-defined sequences as well, since it only explicitly disallows strings and dictionaries as sequences). [Edit]: added a "Thinking . . . " progress measurement of sorts, and a (probably inaccurate) timer.'}, {'comments': [], 'desc': u"Use Jython to time java code. An inexpensive solution to measure Java code's performance. In the following example, jtimeit.py is created to measure Main.doHttpGet()'s performance. Used google and yahoo as examples. "}, {'comments': [{'comment': u'I think you are looking for rlwrap:\n\nhttp://freshmeat.net/projects/rlwrap/\n\n(never used it, however)\n\n M.S.', 'title': u'rlwrap'}, {'comment': u'Thanks for the clever idea! Wolfram Inc should have supplied line-editing themselves long ago. <br>\n\nUnder Unix you can invoke your python-wrapped mathematica via a single command as follows.<br>\nCopy your Wolfram.py to a directory in your path such as /usr/local/bin, and put the following script (call it "mathcom", say) in the same directory:\n\n<pre>\n#!/bin/csh\nsetenv PYTHONPATH /usr/local/bin\npython -i -c "import Wolfram"\n</pre>\n\nTyping "mathcom" gets you a nice line-editable mathematica command line interface.', 'title': u'Mathematica with readline input'}], 'desc': u'This is a simple way to use the text interface to Mathematica and get\nthe advantages of the editing capabilities of the GNU readline. The\nPython script makes use of the builtin function raw_input(), which in\nLinux uses GNU readline.'}, {'comments': [{'comment': u"Now, after one execution calc-function lost. It's interesting to add some method to invalidate and recalculate property.", 'title': u'Elegant method to invalidate calculated value'}, {'comment': u'Just delete the attribute of the object. Using the sample above:\n<pre>\n>>> o = SomeClass()\n>>> o.someprop\nActually calculating value\n13\n>>> o.someprop\n13\n>>> del o.someprop\n>>> o.someprop\nActually calculating value\n13\n>>> o.someprop\n13\n\n</pre>', 'title': u'Retracting a value is very simple'}], 'desc': u'Lazy properties can be easily built in Python 2.4 -- properties whose value may require some effort to calculate, but whose values remain constant once calculated. This recipe uses decorators to implements such properties.'}, {'comments': [], 'desc': u'If you have an instance "db", then accessing "db.Foo"\nautomatically imports, instantiates, caches, and returns an instance of "Foo"\nfrom the "db" package.'}, {'comments': [], 'desc': u'BASIC IDEA: Using this class as a base class, you can quickly create new\nclasses that know what its attributes are. This is useful for simple,\nstruct-like classes that have no methods of their own. Afterall, class syntax\nis more convenient than dict syntax.'}, {'comments': [], 'desc': u'Clear "sys.modules" of stale code without having to restart your\nserver. It\'s a hell of a lot harder to do right then it sounds.'}, {'comments': [{'comment': u'Check out the Xoltar Toolkit at http://www.xoltar.org/languages/python.html\n<br><br>\nThe "functional" module has a better implementation of curry that allows you to do things like curry parameters out of order. The other methods in there are quite useful as well.', 'title': u'Xoltar Toolkit'}, {'comment': u"I'm not sure how this differs much from:<br>\n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549\n<br>\nFrom the reactions I've had from that, I'd change the first few lines of each method to:\n\n<pre>\nclass Curry:\n def __init__(*args, **initKargs):\n self = args[0]\n self.f = args[1]\n self.initArgs = args[2:]\n ...\n def __call__(*args, **kargs):\n self = args[0]\n updatedArgs = self.initArgs + args[1:]\n ...\n\n</pre>\n\nThis allows keyword currying or providing of _all_ parameters\nas named parameters.", 'title': u'Matches recipe 52549. Remove any explicitly named parameters.'}], 'desc': u'Suppose you have a function "sum(a, b)". This class lets you \ndo things like:\n\n plus4 = Curry(sum, 4)\n print plus4(5)'}, {'comments': [], 'desc': u'A million things can go wrong, and there are several ways to\nsucceed. You want to check for the ways that can succeed and continue on as\nsoon as one of them does. You want the non-local flow of control that\nexceptions provide, but you need it for both success *and* failure.'}, {'comments': [], 'desc': u'This is a proxy for an instance of some class called Foo. Any\nthread can use the one proxy, and the proxy will automatically look up the\nthread specific instance of Foo. This is great if you have a global function\nin someone else\'s code that you need to swap out for something "thread safe".'}, {'comments': [], 'desc': u'Calling the "forward" method transfers processing to a new screen.\nIt never returns. This code is taken from multiple places, so I haven\'t\nbothered to keep the classes intact, I\'ve just taken the meat. More generally,\nthis is an example of state machine with a main loop. At any point, you can\nsay, "I\'m ready to change state. Do it. Go back to the loop. Don\'t\nreturn--just throw away my current stack."'}, {'comments': [], 'desc': u'Use a function decorator to tell when and how a function should be\nlogged. All kinds of things can be logged automatically, including the\nfunction arguments and (theoretically) even the stack.'}, {'comments': [], 'desc': u'Permit anyone to add methods to a class in a library without having\nto change the name of the class by subclassing. This is like having a plugins\ndirectory. Also, given a normal function, treat it as a method of an arbitrary\nclass (i.e. mimic a bound method).'}, {'comments': [], 'desc': u'If you have a hierarchy of packages in a library, permit the user\nof your library to have his own hierarchy of packages that "overlays" yours.\nThat means he can even have classes named the same as your classes, and have\nhis classes "shadow" yours. It also means that a project can be broken up into\nseveral top-level directories, all of which have the same package hierarchy\nwithin.'}, {'comments': [], 'desc': u"This is the same as InverseExtend, except it uses a yield for\nnon-local flow of control in a way yield wasn't really meant to be used ;)"}, {'comments': [], 'desc': u'This is like the object oriented concept of extending a super\nclass. However, instead of starting at the furthest subclass and working your\nway up, you start at the top super class and work your way down.'}, {'comments': [], 'desc': u'In some code I have to work with but don\'t have much control over,\nthere are a bunch of strings declared at the module level. I need to figure\nout what all those strings are, and wrap them in something. Once they are\nwrapped, they must behave as strings, but lazily "translate" themselves\nwhenever used in order for internationalization to work. Since each Web\nrequest might request a different language, I can\'t just do this once and be\ndone with it.'}, {'comments': [], 'desc': u"Hack a class's __init__ method without subclassing the class\nbecause a) you can't modify the original class and b) you can't modify other\nclasses already using the first class. This is a gross hack that should only\nbe used to work around flaws in libraries you have no control over. I've\nchanged the names to protect the innocent."}, {'comments': [{'comment': u'Very nice little recipe, but I\'m not sure it does what you intended it to (or I misunderstood it). It doesn\'t actually add (numerically) each new input. I\'ve modified it a bit to correct this, and added a simple clear/quit pair of key commands.\n\n<pre>\nimport sys\n\nprint \'Type c to clear, otherwise all input is added to the running total.\'\nprint \'Type q to quit.\'\n\ncurrent = 0.0\nwhile True:\n try:\n cmd = raw_input("$ %s > " % current)\n if cmd==\'c\':\n current = 0.0\n print \'*** Running total cleared ***\'\n continue\n elif cmd==\'q\':\n raise EOFError\n current = eval("%s + %s " % (current,cmd))\n except (KeyboardInterrupt, EOFError):\n print\n sys.exit(0)\n except Exception, e:\n sys.stderr.write("Error: %s\\n" % e)\n</pre>', 'title': u'A few improvements...'}, {'comment': u"I'm sorry, I should have been more clear. Here is an example:\n\n<pre>\n$ 0.0+500 # Set initial balance.\n$ 500.0-5 # Start subtracting amounts.\n$ 495.0-3\n$ 492.0*1.08 # Set tax, or something interesting.\n$ 531.36*0 + 500 # Start over with a new balance.\n$ 500.0*0 + len(filter(lambda x: x > 5, range(10)))\n$ 4.0\n^D\n</pre>\n\n^D (i.e. end of input) exits.", 'title': u'Hmm, yes, my version is clever...'}, {'comment': u'I like the print statments, but your version is not a "calculator shell"\nany more, it dose not take * 10 or / 5 etc..', 'title': u'A few improvements..., Tony Ha'}], 'desc': u'This is a trivial calculator "shell" with a running total.\nAs trivial as it is, I find it to be more useful than a normal calculator when\ndoing my checkbook because of the ever-present running total.\n\nSed is to Vi as\nRunningCalc is to Python\n\npython ~/programming/python/hacks/RunningCalc.py\n$ 0.0+50\n$ 50.0-10\n$ 40.0*0\n$ 0.0+5\n$ 5.0-2\n$ 3.0'}, {'comments': [], 'desc': u'A function analyzing an open xml file for its character encoding by\n- checking for a unicode BOM or (on failure)\n- searching the xml declaration at the beginning of the file for the "encoding" attribute'}, {'comments': [{'comment': u"Why don't you put this all into a class?\n\n<pre>\npy> class ShortForm(object):\n... def __init__(self, max_size=100):\n... self.displayhook = None\n... self.max_size = max_size\n... self.clip_size = (max_size - 3)//2\n... def load(self):\n... self.displayhook = sys.displayhook\n... sys.displayhook = self\n... def unload(self):\n... if self.displayhook is not None:\n... sys.displayhook = self.displayhook\n... def __call__(self, value):\n... if value is not None:\n... r = repr(value)\n... if len(r) > self.max_size:\n... sys.stdout.write('%s...%s\\n' % (r[:self.clip_size],\n... r[-self.clip_size:]))\n... else:\n... sys.stdout.write('%s\\n' % r)\n... \npy> '1'*60\n'111111111111111111111111111111111111111111111111111111111111'\npy> sf = ShortForm(20)\npy> sf.load()\npy> '1'*60\n'1111111...1111111'\npy> sf.unload()\npy> '1'*60\n'111111111111111111111111111111111111111111111111111111111111'\n</pre>\n\nNote that storing the old displayhook like this also works correctly in the recursive case (whereas restoring sys.__displayhook__ doesn't).", 'title': u'reformulate as a class'}, {'comment': u"Sigh. I knew that wasn't the most elegant way. Putting it in a class is clearly cleaner. Thanks. May I publish your class based version under the BSD license in the same places I'm now publishing my old version?", 'title': u"That's clearly better. Thanks!"}], 'desc': u"Short Form prevents the Python shell from printing out giant piles of text.\nIt is a hack that ties into the display system. When you are working with a multi-megabyte text file, referenced under the name `txt`, which takes 10 minutes to be printed in full (if you accidentally type '>>> txt') it's really nice to have this."}, {'comments': [], 'desc': u"The fetch_relative() function downloads a file, reproducing the directory structure from the server. After downloading, additional callback function can be performed on the file's contents. If the local copy already exists, the file is not re-refetched, and the callback is performed on the local copy."}, {'comments': [{'comment': u"in order to handle None change visitName to start with\n<pre>\n if node.name == 'None':\n return None\n</pre>", 'title': u'None'}, {'comment': u'cache is not effective because getattr is called every time.', 'title': u'cache'}, {'comment': u'Good point. Cache now removed.', 'title': u'cache'}, {'comment': u'Instead of:\n<pre> return tuple(self.visit(i) for i in node.nodes)</pre>\nI think you want:\n<pre> return tuple([self.visit(i) for i in node.nodes])</pre>', 'title': u'Minor fix to visitTuple'}, {'comment': u'The tuple constructor will iterate along the returned generator; no need to construct an intermediate list. (Python>=2.4)', 'title': u'Not really'}], 'desc': u'Evaluate constant expressions, including list, dict and tuple using the abstract syntax tree created by compiler.parse. Since compiler does the work, handling arbitratily nested structures is transparent, and the implemenation is very straightforward. '}, {'comments': [{'comment': u'How about:<pre>\n__builtin__.enumerate = lambda seq: zip(xrange(len(seq)), seq)\n</pre>\n\nBTW, the "iterable" argument should be named "sequence" because the recipe only works with arguments supporting __len__().', 'title': u'Shorter and faster with improved parameter name'}, {'comment': u'If you want to make enumerate an iterator like it is in Python 2.3, you could use a class:\n\n<pre>\npy> class enumerate:\n... def __init__(self, seq):\n... self.seq = seq\n... def __getitem__(self, i):\n... return i, self.seq[i]\n... \npy> enumerate([5, 7])\n<__main__.enumerate instance at 0x0114D4E0>\npy> list(enumerate(xrange(4)))\n[(0, 0), (1, 1), (2, 2), (3, 3)]\npy> list(enumerate(\'abcde\'))\n[(0, \'a\'), (1, \'b\'), (2, \'c\'), (3, \'d\'), (4, \'e\')]\n</pre>\n\nNote that I used the old sequence protocol to be "really" backwards compatible - __iter__, etc. was only introduced in 2.2 IIRC.', 'title': u'using a class'}], 'desc': u'Python 2.3+ "enumerate" function is pretty handy. This bit of code should allow you to use it transparently in pre-Python 2.3 systems.'}, {'comments': [], 'desc': u'This module provides a simple criteria-based priority queue with "priority cascading".'}, {'comments': [], 'desc': u'This script looks for files with identical file names. If requested, file sizes are also compared. You can search current directory or a list of directories specified on the command line. Search can be restricted to files with names containing a string, or with names matching a regular expression. Paths to duplicates are printed in groups separated by empty lines.'}, {'comments': [], 'desc': u'Just a little bit of hack: a linear equations solver using eval and built-in complex numbers:\n>>> solve("x - 2*x + 5*x - 46*(235-24) = x + 2")\n3236.0'}, {'comments': [{'comment': u'Hello, I can\'t understand how use this code. I get the follow message:\n \n \nTraceback (most recent call last):\n File "ejemplo.py", line 62, in ?\n print s.exception()\n File "/var/tmp/python2.4-2.4-root/usr/lib/python2.4/xmlrpclib.py", line 1096, in __call__\n return self.__send(self.__name, args)\n File "/var/tmp/python2.4-2.4-root/usr/lib/python2.4/xmlrpclib.py", line 1383, in __request\n verbose=self.__verbose\n File "/var/tmp/python2.4-2.4-root/usr/lib/python2.4/xmlrpclib.py", line 1147, in request\n return self._parse_response(h.getfile(), sock)\n File "/var/tmp/python2.4-2.4-root/usr/lib/python2.4/xmlrpclib.py", line 1284, in _parse_response\n p.close()\n File "/var/tmp/python2.4-2.4-root/usr/lib/python2.4/xmlrpclib.py", line 530, in close\n self._parser.Parse("", 1) # end of data\nxml.parsers.expat.ExpatError: unclosed token: line 1, column 0\n \n \nI think that isn\'t correct. \n \nPD: sorry for my english, I only speak good spanish.', 'title': u"I can't understand"}], 'desc': u"Python's xmlrpclib only raises the xmlrpclib.Fault exception, but it can be convenient to allow more different kinds of exceptions to be raised. This recipe provides a customized subclass of xmlrpclib.ServerProxy that looks for Fault exceptions where the message is of the form <exception name>:<message>, and raises the corresponding exception."}, {'comments': [{'comment': u"Isn't it possible for an AsyncResult to complete before a client has had a chance to addCallback?\n<br><br>\nThat aside, this recipe is clean and concise. Thanks for providing it!", 'title': u'Callback Race Condition?'}, {'comment': u'I take your point. We need to synchronize calls to complete(), addCallback() and addErrback():\n\n<pre>\nfrom threading import Thread, Event, RLock\nfrom Queue import Queue\n\nclass AsyncResult:\n """Represents an asynchronous operation that may not have completed yet."""\n def __init__(self):\n self.completed = False\n self.failed = False\n self.__wait = Event()\n self.__callbacks = []\n self.__errbacks = []\n self.__retval = None\n self.__error = None\n self.__lock = RLock()\n\n def complete(self):\n self.__lock.acquire()\n self.completed = True\n self.__wait.set()\n self.__lock.release()\n\n def succeed(self, retval):\n self.__retval = retval\n self.complete()\n for callback in self.__callbacks:\n callback(retval)\n self.clearCallbacks()\n \n def fail(self, error):\n self.__error = error\n self.failed = True\n self.complete()\n for errback in self.__errbacks:\n errback(error)\n self.clearCallbacks()\n\n def clearCallbacks(self):\n self.__callbacks = []\n self.__errbacks = []\n\n def addCallback(self, callback, errback=None):\n self.__lock.acquire()\n try:\n if self.completed:\n if not self.failed:\n callback(self.retval)\n else:\n self.__callbacks.append(callback)\n if not errback == None:\n self.addErrback(errback)\n finally:\n self.__lock.release()\n\n def addErrback(self, errback):\n self.__lock.acquire()\n try:\n if self.completed:\n if self.failed:\n errback(self.error)\n else:\n self.__errbacks.append(errback)\n finally:\n self.__lock.release()\n \n def __getResult(self):\n self.__wait.wait()\n if not self.failed:\n return self.__retval\n else:\n raise self.__error\n result=property(__getResult)\n</pre>', 'title': u'Race condition'}, {'comment': u'Now I come to test it, the error handling is incorrect also. __processQueue should read as follows:\n\n<pre>\n def __processQueue(self):\n while True:\n message = self.__queue.get()\n retval = None\n failure = None\n if message==StopIteration:\n self.stopped = True\n break\n try:\n retval = message.call()\n except Exception, e:\n failure = e\n if failure==None:\n message.result.succeed(retval)\n else:\n message.result.fail(failure)\n</pre>\n\nand, also, callback(self.retval) and errback(self.error) should be callback(self.__retval) and errback(self.__error) in addCallback and addErrback.\n\nGnah. The lesson staring me in the face here is: write tests! Do it *first*!', 'title': u'Also'}], 'desc': u'Based on the recipe for active objects given in "Concepts, Techniques, and Models of Computer Programming", by Peter van Roy and Seif Haridi, the ActiveObject class wraps an instance of a passive object and forwards messages to this object via a thread-safe message queue. The passive object processes the messages on its own thread, and returns the results to the caller via an AsynchResult object that can be used to block whilst waiting for a result, or to register callbacks to be called when a result is available.'}, {'comments': [], 'desc': u'The function <code>num_in_base</code> can be used to print a number using an arbitrary base. It allows numbers to be padded to a minimum field width, and can display negative numbers in a complemented format instead of with a leading negative sign.\n\nThe digits used can be overriden with an arbitrary sequence.'}, {'comments': [{'comment': u'That last bit should have been\n<pre>\n python -m SimpleHTTPServer PORTNO\n</pre>', 'title': u' '}, {'comment': u'A python CGI program can run on linux but not on\nwindows. By looking at CGIHTTPServer.py, we found out the reason: on windows, the\nparent cannot pass os.environ to child demonstrated\nas below:\n\nmain.py\n<pre>\nimport os, sys, shutil\n\nenv = {}\n\nenv["AAA"] = "111"\nos.environ.update(env)\nprint os.environ["AAA"] # ok, updated successful\n\nfiles = os.popen3(sys.argv[1], "b")\n\nfi, fo, fe = files[0], files[1], files[2]\n\nshutil.copyfileobj(fo, sys.stdout)\n\nerrors = fe.read()\n\nfe.close()\n\nif errors: print errors\n\nsts = fo.close()\n\nif sts:\n\n print "exit %#x" % sts\n\nelse:\n\n print "exit ok"\n\n\ntest.py\n\nimport os, sys\n\nif os.environ.has_key["AAA"]:\n\n print "ok, got AAA"\n\nelse:\n\n print "failure"\n</pre>\n<br>\nc:\\www\\cgi-bin>main.py test.py<br>\nit will print failure<br>\n\nmain.py is adopted from CGIHTTPServer.py ?! ', 'title': u'why os.environ can not be passed to child ?'}], 'desc': u'The standard library modules SimpleHTTPServer and CGIHTTPServer are extremely\nuseful, but the documentation hides their virtues. I hope to improve the \nsituation with this recipe. '}, {'comments': [], 'desc': u'A class that contains a dictionary of named queues, with read requests blocking until a message has been added to any one of a supplied list of queues.'}, {'comments': [], 'desc': u'This is an extension for the Button class of Tkinter. This class creates a tip-window when the mouse is entering a button widget.'}, {'comments': [{'comment': u'According to the xhtml specification, html tags must be in lowercase. This makes them compatible with xml. ', 'title': u'Tags should be in lowercase'}, {'comment': u"Something very similar was done some years ago by Andy Dustman in his HyperText package :\n<br>\nhttp://dustman.net/andy/python/HyperText\n<br>\nI use it instead of HTMLgen to create web pages in cgi scripts, and it works very well. Too bad it's not better known ! Its object-oriented approach (nesting calls like you nest tags in HTML) makes it simpler and more natural to use than Pierre's solution above, IMHO.", 'title': u'"Prior Art" - not patentable :-)'}, {'comment': u'The idea is so simple that I was surprised no-one had done this before, I googled for "generate HTML in Python" which returned HTMLGen and templating systems, but not HyperText. It is indeed almost the same, with only a slight difference in the syntax (it uses TAG(*args,**attrs) instead of TAG(arg1+arg2+...,**attrs) ) ; besides, it\'s a complete package, also supporting SGML, XHTML etc. Thanks for mentioning it, it deserves to be better known\n<br>By the way, nesting tags - TABLE(TR(TD(\'foo\')+TD(\'bar\'))) - is also supported by HTMLTags', 'title': u'HyperText'}, {'comment': u"Some times ago I've just written a similar python module called pyhtmloo.\nIt does more or less the same as yours.\nI've even write a parser, that build pyhtmloo objects from an html page. This way the circle is closed ;-).\n\nYou can check it at: http://pyhtmloo.sourceforge.net", 'title': u'Pyhtmloo'}, {'comment': u'Just yesterday I wrote nearly the same module - it\'s easier to write it than to find it :) I also added ability to add and access items and attributes with shift and indexing, and __str__() for converting to text, e.g.:\n<pre>\nhtml = HTML() # there is also general TAG(\'type\',...)\nhtml << HEAD( TITLE( \'The Title\' ) ) # same as HEAD() << TITLE(...)\n# html[0] will be HEAD, and html[0][0] - TITLE, html[0][0][0] - \'The Title\'\n# indexing with numbers sets/gets items, with strings -- attributes\nbody = BODY( bgcolor="#E0E0E0" ) << P( \'Para 1\' ) << P( \'Para 2\' )\nbody[\'text\'] = \'black\' # can get/set attribute any time\nbody[\'link\'] = \'blue\'\nhtml << body # can add itme any time\n# etc ...\nprint html\n<html>\n<head>\n<title>The Title</title>\n</head>\n<body bgcolor="#E0E0E0" text="black" link="blue">\n<p>\nPara 1</p>\n<p>\nPara 2</p>\n</body>\n</html>\n</pre>', 'title': u'Did it myself too'}, {'comment': u"HyperText does have it's root's in HTMLGen. It's not based on HTMLGen, but it does borrow a few ideas. Another more modern package which is similar, but has much more support for XML in general is XIST. http://www.livinglogic.de/Python/xist/", 'title': u"HyperText's roots"}], 'desc': u'The HTMLTags module defines a class for each valid HTML tag, written in uppercase letters. To create a piece of HTML, the general syntax is :\n\n t = TAG(innerHTML, key1=val1,key2=val2,...)\n\nso that "print t" results in :\n\n <TAG key1="val1" key2="val2" ...>innerHTML</TAG>\n\nFor instance :\n\n print A(\'bar\', href="foo") ==> <A href="foo">bar</A>'}, {'comments': [], 'desc': u"Use this recipe to provide simple function/method coverage analysis within your unit test suites using the following steps within a unit test file:\n\nimport myModule\n<b>import coverage</b>\n\n<b>coverage.ignore=[</b>myModule.myClass1,myModule.function7,...<b>]</b>\n<b>coverage.watch(</b>myModule<b>)</b>\n\nclass TestMyModule:\n    def test_one(self):\n     .\n     .\n    .\n    def test_coverage(self):\n        assert <b>coverage.uncovered()</b>==[]\n\n where:\n '<i>myModule</i>' is the module being tested.\n '<i>coverage</i>' is the name given to the module containing this recipe.\n '<i>coverage.ignore</i>' is an optional list of functions/methods/classes to be excluded from the coverage analysis.\n '<i>coverage.watch(module_or_class)</i>' is called for each module and/or class to include in the coverage analysis.\n '<i>coverage.uncovered()</i>' returns a list of functions/methods that were not called over the course of the unit test and that are not covered by the ignore list.\n"}, {'comments': [{'comment': u"If the reviewer see this, please delete that second reason. Also please indent Alex Martelli's code. thanks.", 'title': u'Oops! The second reason I gave is not correct'}, {'comment': u'Thanks for making progress.\nI think another reason why your code is faster is old (my) recipe was create lists each steps, but your code just rewrite numbers to 0. ', 'title': u'another reason '}, {'comment': u'Very nice recipe, thanks. A slight improvement : the function raises exceptions for some odd numbers (primes(13) for instance). It is safer if you change the value of "half" to len(s)', 'title': u'Improvement'}, {'comment': u"Here's the same algorithm with simpler indexing:\n\n<pre>\ndef primes2(n): \n if nHere's the same algorithm with simpler indexing:\n\n<pre>\ndef primes2(n): \n if n</pre></pre>", 'title': u'Nice speed, but the indexing is a little opaque...'}, {'comment': u"I've tried surrounding it in pre tags. I give up...", 'title': u'How do you add code in the comments'}, {'comment': u"You say the function returns primes that are less than the argument. Did you mean less than or equal to the argument?\n<br><br>\nIn fact, as it stands, the function can return a prime higher than the argument (try it for 3000, for instance). Changing 's=range(3,n+2,2)' to 's=range(3,n+1,2)' would ensure you get all primes up to and including the argument.", 'title': u'Out by 1?'}, {'comment': u'For some reason, I get an IndexError for certain prime or prime-power values of n. For example, try n=25, n=251.', 'title': u'Seems to be a bug'}, {'comment': u'Would it be possible to implement an analogous \nso efficient algorithm as primes(n), but with two \ninputs, primes(s,n), where s is the starting number \nfrom which the primes begin to be calculate?\nInstead of beginning always from 2.\nThank you!\n\n', 'title': u'purpose for better implementation'}, {'comment': u"as many of you coders have noticed that with this code there are some values that fail, such as 13, 25, 251, and 3000. there is a simple solution to this problem, the line reads\n\nhalf = (n+1) / 2\n\nshould read\n\nhalf = (n+1) / 2 - 1\n\nthis variable seems to be the size of the list considering it should be 1/2 of the original list's size because we are working only with odd numbers. however, the coder forgot to take into account that he skipped the odd value of 1 and started straight at three. so half really was the size of the list + 1. most numbers, when looping, had increments that we greater than this + 1, but sometime it fell in it, hence giving an element doesnt exist error.", 'title': u'bug fix'}, {'comment': u'Thank all the commentors and your suggestions. I have made the correction:\ns=range(3,n+1,2)\n and\nhalf=(n+1)/2-1\n\nThanks.', 'title': u'thank all'}], 'desc': u'This is a fast prime number list generator using sieve algorithm. This function return a list of prime numbers which <= argument.'}, {'comments': [{'comment': u'In all the method calls that take *args and **kwds as arguments, you should replace "name" by "_name" and "func" by "_func" in the formal parameters. Otherwise if the delegated method already has a "name" parameter, then the function get "name" twice: once with the normal actual parameter, and once in the "kwds" dict, and this results in::\n\n TypeError: _method_call() got multiple values for keyword argument \'name\'\n\nUsing _name fixes the common case (hopefully you don\'t use "_name" for your formal parameters).', 'title': u'a subtle bug, and a fix'}, {'comment': u'You might be interested in the following module which is more generic as it does aspect-oriented programming in Python.\n\nhttp://www.logilab.org/projects/aspects', 'title': u'see also aspects'}, {'comment': u'I improved my copy with a small but useful improvement: when calling the _post and _post_ functions, I pass the return value from the delegated call.\n\nhere is the diff\n\n<pre>\ndiff -u -3 -p -r1.2 hookproxy.py\n--- hookproxy.py 11 Feb 2005 04:20:26 -0000 1.2\n+++ hookproxy.py 12 Mar 2005 21:39:38 -0000\n@@ -112,7 +112,7 @@ class HookProxy(object):\n \n # post-call hook for specific method.\n try:\n- postfunc = getattr(self, \'_post_%s\' % _name)\n+ postfunc = getattr(self, \'_post_%s\' % _name, rval)\n except AttributeError:\n pass\n else:\n@@ -120,7 +120,7 @@ class HookProxy(object):\n \n # post-call hook for all calls.\n try:\n- postfunc = getattr(self, \'_post\')\n+ postfunc = getattr(self, \'_post\', rval)\n except AttributeError:\n pass\n else:\n@@ -145,16 +145,16 @@ def test():\n "Proxy for Foo."\n def _pre( self, _name, *args, **kwds ):\n print >> sys.stderr, \\\n- "LOG :: %s" % self._call_str(name, *args, **kwds)\n+ "LOG :: %s" % self._call_str(_name, *args, **kwds)\n \n- def _post( self, _name, *args, **kwds ):\n- print \'after all\'\n+ def _post( self, _name, retval, *args, **kwds ):\n+ print \'after all\', retval\n \n def _pre_foo( self, *args, **kwds ):\n print \'before foo...\'\n \n- def _post_foo( self, *args, **kwds ):\n- print \'after foo...\'\n+ def _post_foo( self, retval, *args, **kwds ):\n+ print \'after foo...\', retval\n \n f = BabblingFoo(\'f\', Foo())\n print \'rval = %s\' % f.foo(17)\n</pre>', 'title': u'one more improvement'}, {'comment': u'indeed, very interesting stuff, thx for the pointer\n\nthe difference between the two could be summarized like this:\n\n- logilab-aspects modifies the original object methods, setting them to wrapped methods, whereas hookproxy only keeps a reference to the original object\n\n- hookproxy is a simple one-file solution, logilab-aspects is more involved, and more powerful. (i suppose if you like simplicity hookproxy still has some value.)\n\n(i don\'t quite see how logilab-aspects is more generic, plz define "generic")', 'title': u'different approach'}, {'comment': u"damnit, i'm getting ahead of myself. what we need for this cookbook thing is a svn repository...\n\nthere are some bugs in the diffs sent. also, i added a way to catch exceptions for all method calls. i will write some more tests and send the new versions after some more testing.", 'title': u'new version'}], 'desc': u'A proxy object that delegates method calls to an instance, but that also calls hooks for that method on the proxy, or for all methods. This can be used to implement logging of all method calls and values on an instance.'}, {'comments': [{'comment': u"Perhaps I don't fully understand what the purpose or effects of this recipe -- but the best way I've found to accompish something similar is to modify your PATHEXT environment variable to include .py files. Then you can just enter the name of the .py file at the command line (with or without the '.py' extension), and it will treat it as an executable.\n\nOn Win XP Pro you can modify the PATHEXT environment variable by clicking the Environment Variables button on the Advanced tab in My Computer's properties dialog (or via the 'System' Control Panel).", 'title': u'Simpler Way?'}, {'comment': u"I use ActiveState's ActivePython distribution and this is handled automatically for me on Windows by the installation. All I have to do to run a python file called 'something.py' is type 'something' or 'something.py', followed by any other arguments.", 'title': u'Even simpler...'}, {'comment': u'I agree with you. However, up to my knowledge, there is still some \ncase where a .cmd wrapper could be usefull.<br>\nIf you plan to redirect \nthe input of your script the pathext trick seems not adequate and the .cmd yes.<br>\n<pre>\n my_prog.py < new_input.txt > new_output.txt</pre>\nis not the same as:\n<pre>\n C:\\Python24\\Python.exe my_prog.py < new_input.txt > new_output.txt</pre>\nthat could be wrapped into:\n<pre>\n my_prog.cmd < new_input.txt > new_output.txt</pre>\n', 'title': u'I agree but'}, {'comment': u'<pre>1) rename the file.py to file.cmd\n2) insert the following code into line 1 \n@python -x %~f0 %* <pre>1) rename the file.py to file.cmd\n2) insert the following code into line 1 \n@python -x %~f0 %* </pre></pre>', 'title': u'it is possible to do it MUCH shorter'}, {'comment': u'3) be sure that python is within your path<br><br>\n4) enjoy<br><br>\n<br>Harald Armin Massa<br>\n(I do not take credit for this, I googled it up some loooong time ago, pls do not ask where; I assume "unfrequently asked questions")', 'title': u'and the 2 lines that zope did cut'}, {'comment': u'As written, cmd.exe will run the python script, then continue trying to interpret the rest of the .cmd file as batch commands. To prevent this, use this header instead:\n<br>\n<pre>@python -x %~f0 %* & exit /b</pre>\n<br>\nA few notes:\n<br>\n * The single ampersand ("&") means that the "exit /b" clause runs no matter what the python script returns as an exit code; the more commonly-used "&&" will not run the exit clause if the python script ends with a nonzero return code.\n<br>\n * The /b on exit means "exit the current batchfile"; without /b, the instance of cmd.exe will exit.', 'title': u'Need to add one bit...'}, {'comment': u'Tim, you are more than correct.\n<pre>\nCutting and Pasting failed, orginally there was:\n\ngoto :EOF\n</pre>\nadded, but I could not get it through the filters :((', 'title': u'correct...'}, {'comment': u'<pre>\n@python -x "%~f0" %* & exit /b\n</pre>\nI had to add quotes to deal with scripts that are in folder with spaces in they pathname.\nI\'am glad of this receipt it works perfectly redirecting input and output the right way and returning the right return code.\nApart from the fact that it isn\'t platform dependent it is wondefull ;-).', 'title': u' '}, {'comment': u"I saw that when I previewed my post as well... it's not a question of filters; ASPN's site doesn't properly escape certain characters. If you want an ampersand, you have to escape it yourself, HTML-style, using &amp;", 'title': u'Ahh...'}, {'comment': u'I usually use a batch file for this purpose. Simply edit a file with the following:<br><br>\n\n\npython myfile.py %1<br><br>\n\n\nand save it as something like m.bat. Run it under command window. That gives me a quick and easy way of executing py programs.', 'title': u'Using batch file'}], 'desc': u"Generate a Windows command file that executes a Python program. Typing\n'my_prog arg1 is easier than typing 'python C:\\PyLib\\my_prog.py arg1'.\nNeeded because Windows does not support '#!/bin/env python' as the first\nline of the program."}, {'comments': [{'comment': u'This gets my vote for best hack of 2005. ;-) <pre></pre>\nBe sure to add notes on associativity and precedence so it is clear that: <pre>3 ** 2 *x* 4 ** 3 == (3 ** 2) *x* (4 ** 3)</pre>\nTo change the precedence, try other operators: | ^ & ** etc. \n\n', 'title': u'Associativity and Precedence'}, {'comment': u'> I wonder whether it would be possible to use decorators for the definition of the infixes and one could omit the stars around the infix?<br>\n\ni believe this is not possible, unless there is a new explicit binary operator,\napplied when there is a whitespace between two terms.<br>\n\nSo far this works for string literals only (("A" "B")=="AB")', 'title': u' '}, {'comment': u"Because '|' is the operator with the lowest precedence that's still practical to use with this technique.<br>\n<br>\nThat having been said, I also have to say that this is probably the best Python hack *ever*, because the ability to do this has been in the language for many generations and nobody thought of it (or at least shared their invention) before. I ran the recipe on Python 1.5.2 and it worked once I changed the __class__ tests to type()!", 'title': u"Using '|' would work better for many situations"}, {'comment': u'Adjacent string literals are treated as a single string. This is only true of literals. You can use it for stuff like:\n\n<pre>\nassert something, (\n "There is a problem with your something or another "\n "and you should do something about it.")\n</pre>\n\nSo it\'s not an operator at all, and there\'s no concatenation -- that\'s *parsed* as a single string.', 'title': u'adjacent strings'}, {'comment': u'I agree that this is a fascinating hack -- unfortunately the new\ninfix operator is not reentrant. I\'m using your "div" example but\nwith __or__ and __ror__ methods instead:\n<pre>\n>>> 8 |div| (2 |div| 2)\n2\n</pre>\nWith a slight modification, however, it works as expected -- just\nreturn a new (actually monadic) operator as the result of the first\noperation:\n<pre>\nclass Infix(object):\n def __init__(self, function):\n self.function = function\n def __ror__(self, other):\n return Infix(lambda x: self.function(other, x))\n def __or__(self, other):\n return self.function(other)\n</pre>\nNow we get the conventional result:\n<pre>\n>>> div = Infix(operator.div)\n>>> 8 |div| (2 |div| 2)\n8\n</pre>', 'title': u'Not reentrant'}, {'comment': u'<pre>\n"""\nSee: http://www.nomaware.com/monads/html/index.html\n"""\n\nclass Infix(object):\n\tdef __init__(self, function):\n\t\tself.function = function\n\tdef __ror__(self, other):\n\t\treturn Infix(lambda x: self.function(other, x))\n\tdef __or__(self, other):\n\t\treturn self.function(other)\n\nclass Just:\n def __init__(self, value):\n self.value = value\n\t\ndef mbind(maybe, func):\n if maybe is None:\n return None\n else:\n return func(maybe.value)\n\nmbind = Infix(mbind)\n\ndef mreturn(value):\n return Just(value)\n\nclass Sheep:\n def __init__(self, name):\n self.name = name\n self.mother = None\n self.father = None\n\ndef father(sheep):\n if sheep.father is None:\n return None\n else:\n return Just(sheep.father)\n\ndef mother(sheep):\n if sheep.mother is None:\n return None\n else:\n return Just(sheep.mother)\n\ndef mothersPaternalGrandfather(sheep):\n return mreturn(sheep) |mbind| mother |mbind| father |mbind| father\n\nshawn = Sheep("Shawn")\ngertrude = Sheep("Gertrude")\nernie = Sheep("Ernie")\nfrank = Sheep("Frank")\n\nshawn.mother = gertrude\ngertrude.father = ernie\nernie.father = frank\n\nprint mothersPaternalGrandfather(shawn).value.name # Should return "Frank"\nprint mothersPaternalGrandfather(ernie) # Should return None\n</pre>', 'title': u'Monad combinators'}, {'comment': u'If, like me, you are just getting familiar with Python, you may be distracted, as I was, by the format of the examples. I had to realize that |myop| is not an atomic unit. It is the myop variable with the \'|\' operator (which is redefined in the Infix class) on either side. \n<br>\n<pre>\nSo we can have (using the bar version):\n>>> myop = Infix(lambda x,y: "Look: %s myop %s!!!"%(x,y) )\n>>> 4 | myop | 3 \n\'Look: 4 myop 3!!!\'\n\nWe could have typed \n>>> 4 |myop| 3\nor \n>>> 4|myop|3\ner even \n>>> 4| myop |3\n</pre>\nThe important operator overloading is happening on the instance named myop, for which the bar, |, has been redefined. \n<br>\nAlso, notice that it is redefined such that it requires a right and left operand (almost obviously), which is why it must be sandwiched so.\n\n<pre>\nBy the way:\n>>> 4 | myop | \'dog\'\n\'Look: 4 myop dog!!!\'\n</pre>', 'title': u'observation from a novice'}, {'comment': u'C:\\jython>jython<br>\nJython 2.1 on java1.4.1_02 (JIT: null)<br>\nType "copyright", "credits" or "license" for more information.<br>\n>>> class Infix(object):<br>\n... def __init__(self, function):<br>\n... self.function = function<br>\n... def __ror__(self, other):<br>\n... return Infix(lambda x: self.function(other, x))<br>\n... def __or__(self, other):<br>\n... return self.function(other)<br>\n...<br>\n:4:[SyntaxWarning]: local name \'other\' in \'__ror__\' shadows use as global in nested scopes<br>\n:4:[SyntaxWarning]: local name \'self\' in \'__ror__\' shadows use as global in nested scopes<br>\nTraceback (innermost last):<br>\n File "", line 1, in ?<br>\nNameError: object', 'title': u'1st form works on Jython, 2nd form does not :-('}, {'comment': u"I'm guessing that's because Jython doesn't have nested scopes. Use this definition instead (__ror__ changed):\n\n<pre>\nclass Infix(object):\n def __init__(self, function):\n self.function = function\n def __ror__(self, other):\n return Infix(lambda x, other=other: self.function(other, x))\n def __or__(self, other):\n return self.function(other)\n</pre>", 'title': u'nested scopes'}, {'comment': u'I think that it would be good to add a __call__ method to the infix object so that the object can act, more or less, like the original function object.\n\n<pre>\nclass infix:\n ... magic ...\n def __call__(self, value1, value2):\n return self.function(value1, value2)\n\ndef myfunc(x, y):\n ...\n\nmyfunc = infix(myfunc)\n\nmyfunc(1, 2) == 1 |myfunc| 2\n</pre>\n\nAnd I agree with everyone else who said that this is an extremely cool hack.', 'title': u'Add __call__ method'}, {'comment': u'It\'s easy to define a corresponding decorator @infix.\n<br>\n\n<pre>def infix(f):\n return Infix(f)</pre>\n\nThe decorator can be applied to any function definition and simply returns a new Infix object that wraps the original function definition.\n\n<pre>@infix\ndef x(x, y):\n return x * y\n\n@infix\ndef isa(x, y):\n return x.__class__ == y.__class__</pre>\n\nNote that since the Infix class provides an appropriate __call__ method, @infix-decorated functions can still be called like "ordinary" functions.\n\n<pre>print x(2, 4)\nprint 2 |x| 4</pre>', 'title': u'@infix Decorator '}, {'comment': u'...because classes can be used as decorators. Just use @Infix, or rename the Infix class to lower case.<br>\n<br>\nThe class also needs __getattr__ and __setattr__ routines that delegate to self.function, as well as __class__ and __doc__ delegates (so that anInfix.__class__ returns function.__class__) in order to complete the illusion that Infix instances are functions.', 'title': u"You don't even need the 'def infix' part..."}, {'comment': u'You just need the line:\n<pre>from __future__ import nested_scopes</pre>', 'title': u'Nested scopes work in Jython'}, {'comment': u"Unfortunately string (and sundry other) objects don't play well with this hack. They raise a TypeError which prevents the __rop__ method from getting called.<br><br>\n\nStill very cool though - and all the more reason to try and make standard classes play more nicely with others.", 'title': u' '}, {'comment': u'Masterful.', 'title': u'hah!'}, {'comment': u'Instead of using a neat hack, try requesting custom infix operators as a feature for python (good luck), or use LiveLogix which runs on top of the CPython VM and already has this feature: http://logix.livelogix.com', 'title': u'try livelogix instead'}], 'desc': u'Python has the wonderful "in" operator and it would be nice to have additional infix operator like this. This recipe shows how (almost) arbitrary infix operators can be defined.'}, {'comments': [{'comment': u"<pre>\nimport re\ndef unwiki (word):\n m = re.search ('[a-z]', word)\n if not m: return word.lower()\n p = m.start(0) - 1\n return word[:p].lower() + word[p:]\n</pre>", 'title': u'a variant using re'}], 'desc': u'This function converts the first word in a CamelCase work to lowercase. I.e. "CustomerID" becomes "customerID", "XMLInfo" becomes "xmlInfo"'}, {'comments': [{'comment': u'Here are couple of minor suggestions.<pre></pre> \n\nThe joined() method can return True, False, or None (when "a" is not known). It can fixed and simplified to:\n<pre>\n def joined(self, a, b):\n """Returns True if a and b are members of the same set."""\n mapping = self._mapping\n try:\n return mapping[a] is mapping[b]\n except KeyError:\n return False\n</pre>\nThe get() method should be renamed to __iter__(). Its logic can also be simplified:\n<pre>\n def __iter__(self):\n """Returns an iterator returning each of the disjoint sets as a list."""\n seen = set()\n for elem, group in self._mapping.iteritems():\n if elem not in seen:\n yield group\n seen.update(group)\n</pre>', 'title': u'Nicely done.'}, {'comment': u'The most time consuming part of join() is merging two existing sets. That time is kept to a minimum by keeping the larger set and merging in the smaller:\n<pre>\n def join(self, a, *args):\n """Join given arguments into the same set."""\n mapping = self._mapping\n set_a = mapping.setdefault(a, [a])\n\n for arg in args:\n set_b = mapping.get(arg)\n if set_b is None:\n set_a.append(arg)\n mapping[arg] = set_a\n elif set_b is not set_a:\n if len(set_b) > len(set_a):\n set_a, set_b = set_b, set_a\n set_a.extend(set_b)\n for elem in set_b:\n mapping[elem] = set_a\n</pre>\nAlso, it is faster to test "a is not b" than "not a is b".', 'title': u'Small Algorithmic Improvement'}, {'comment': u"The __init__() method should accept a series of join pairs: [('a', 'b'), ('c', 'd'), ...]. That makes more sense than accepting a list of elements which initially define distinct groups but can become paired later. Thinking in terms of use cases, it would be odd for this application to have a list of elements without any information to link them, and if it did have the links, it would be odd to not use that information during initialization.", 'title': u'API suggestion for __init__()'}, {'comment': u"Thanks. I really appreciate the feedback.\n\nI agree wholeheartedly with the first two suggestions.\n\nHowever, for this one, I disagree. In my own use case, I generally know all the elements first, and then determine their grouping later. If I knew their grouping already, I wouldn't have a need for this class ;)\n\nWhile I can conceive of use cases where your suggestion would be more convenient, it makes my use case more inconvenient (I would have to pass a list of lists, rather than just a list.)\n\nPerhaps a couple different factory functions with either case would be better?", 'title': u' '}, {'comment': u"Wow, this is a great class. In the two uses I've had for groupings, it makes more sense for __init__ to take a list of elements than a list of pairs. I've stopped using my own (less Pythonic) grouping class, and now I use yours. Thanks!", 'title': u'Nice class'}], 'desc': u'This recipe provides a lightweight way to group arbitrary objects together into disjoint sets when a full-blown graph data structure would be overkill.'}, {'comments': [], 'desc': u'Socket.sendall is very handy for sending. It would be nice if there was a socket.recvall.\nUnfortunatelty, receiving data is hard. One way to to do a recvall, is to use timeouts that get reset if any amount of data arrives. Useful, if you know almost nothing about what you are receiving.\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/213239\n\nAnother, if you can control the sender, is to use a sentinal or marker, and send when the end has arrived.\n\nThis example, shows a really simple way, to do that. The assumption is that you have a unique enough string as an end marker. You pass a socket to either of these functions. The sender takes on the end marker and the receiver looks for it.'}, {'comments': [{'comment': u"This could also be done with:\n<pre>\nimport random\nword = raw_input('Word: ')\nprint ''.join(random.sample(word, len(word)))\n</pre>", 'title': u'Another way'}, {'comment': u"Heres something I whipped up just then <br>\n\ndef randomize(string):<br>\n\tstring = list(string)<br> temp = string[:]<br><br>\n\tfor i in range(len(string)):<br>\n\t\trandomnum = int(random.random()*len(temp))<br>\n\t\tstring[i] = temp[randomnum]<br>\n\t\ttemp.remove(string[i])<br><br>\n\treturn ''.join(string)<br>\n\nBasically, what it does is just take in a string, convert it to a list, and make a temporary copy.<br>\nOnce it has done this, it then iterates in a loop equal to the length of the original string, and in each loop, takes a random value from the temporary array, and replaces the next position in the original string with this value.<br>\nAt the end, the value is removed from the temporary array.", 'title': u'Heres another way.'}], 'desc': u'Scramble word re-arrange characters of word by using simple string manipulation and Random.\n'}, {'comments': [{'comment': u'Why is a Java program listed in the Python Cookbook?', 'title': u'Not Python'}], 'desc': u' This program is a game in which someone will try and guess a number between\n1-100 in 4 tries. It will also give out instructions of how to play using methods and will also tell the person if their guess was too low or too high.'}, {'comments': [], 'desc': u'A subclass of String that allows simple handling of pango markup or other simple XML markup. The goal here is to allow a slice of a python markup string to "do the right thing" and preserve formatting correctly. In other word, MarkupString(<i>Hello World</i>)[6:] = "<i>World</i>"'}, {'comments': [{'comment': u"This is an interesting and creative idea; however, for a control application such as this, a continuously-updated incremental approach would likely be better.\n<pre></pre>\nThe nature of the video data is that the input stream changes over time and is subject to noise. Both factors tend to invalidate the assumption that the mean pixel value changes monotonically with the exposure time.\n<pre></pre>\nIt may be better to continuously adjust the exposure up or down a percent or two at a time. That would result in smoother transitions, adaptation to changing inputs, and in stability against noise spikes (light/dark flashes, reflectivity, objects moving across the the field of view, digitization errors, etc). \n<pre></pre>\nAlso, photographically speaking, the mean pixel value is problematic as an objective function -- both high key and low key scenes would end-up with improper exposures. A professional photographer with a spot meter would average the values from the brightest and darkest part of the scene so that all the values in between are captured -- the idea is to make the most of the camera's dynamic range.\n", 'title': u'Bisect not suited for control applications'}, {'comment': u'In this particular example, the lo, hi arguments are used to restrict the range of values to 0, 1000.\nA more general list-like object also needs an implementation of the __len__ member function.', 'title': u'Masquerading as a "list"'}], 'desc': u'Writing a binary search algorithm is surprisingly error-prone. The solution: trick the built-in bisect module into doing it for you.\n\nThe documentation for bisect says that it works on lists, but it really works on anything with a __getitem__ method. You can exploit this fact to make bisect work in ways that you may not have thought of.\n\nExample: Using a library that controls a digital video camera, I wanted to do a poor-man\'s auto-exposure. The goal is to find the exposure time, in milliseconds, that makes the mean pixel value about 128 (out of 0 to 255).\n\nThe trick is to create an object that "looks like" a list to the bisect module.\n'}, {'comments': [{'comment': u'<pre>\nclass DB(object):\n def __init__(self, *k):\n import MySQLdb\n conn = MySQLdb.connect(*k)\n self.cursor = conn.cursor()\n\n def create_table(self):\n # use self.cursor when cursor is needed\n ...\n\n def populate_table(self, feeds):\n # use self.cursor when cursor is needed\n ...\n</pre>', 'title': u"isn't this what classes are for?"}, {'comment': u'Check out PEP 309:\nhttp://www.python.org/peps/pep-0309.html\n<pre>\n def foo(a, b, c):\n print a, b, c\n\n def bar(a, b, c):\n print a, b, c\n\n foo1 = partial(foo, 1)\n foo1(2, 3)\n bar1 = partial(bar, 1)\n bar(4, 5)\n</pre>', 'title': u'see PEP 309'}], 'desc': u'A simple object wrapper that allows you to define pre-defined parameters for functions (global for all functions associated with the object).'}, {'comments': [{'comment': u'Since the condition, process, and counter do not share a namespace, lambdas have to be used to specify the expression variable. This is slow, verbose, and clumsy compared to equivalent generator expressions.\n<pre></pre>\nIf itertools.count is used to generate the series inputs, you get the additional advantage of being able to specify the starting count (from zero, from one, or anywhere else).\n<pre></pre>\nAlso, itertools.islice() is a flexibile tool for extracting the first n elements of a series. However, more versatility can come from a design that allows an infinite series to be generated simply by dropping the enclosing islice().\n\n<pre>\n>>> from itertools import count, islice\n>>> def take(n, iterable):\n\treturn list(islice(iterable, n))\n\n>>> take(10, (x for x in count(1) if prime(x)))\n[1, 2, 3, 5, 7, 11, 13, 17, 19, 23]\n>>> take(10, (x for x in count() if x%2))\n[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n>>> take(10, (x*x for x in count(1)))\n[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n>>> import random\n>>> take(10, (random.random() for x in count()))\n[0.94710345491708259, 0.4736249879152532, 0.059853883359122562, 0.65141323268525519, 0.60859729173749066, 0.82585367661224152, 0.91566522952506124, 0.43985135483694404, 0.43158061837573281, 0.16226950910826099]\n\n# Combined example: first ten squares of primes over 4\n>>> take(10, (x*x for x in count(4) if prime(x)))\n[25, 49, 121, 169, 289, 361, 529, 841, 961, 1369]\n\n# Example of flexibility and simplicity of an infinite generator:\n>>> zip(xrange(5), (x*x for x in count(2) if prime(x)))\n[(0, 4), (1, 9), (2, 25), (3, 49), (4, 121)]\n</pre>', 'title': u'Generator expressions offer better flexibility, speed, and economy of expression'}], 'desc': u'An example which shows the power of decorators when combined\nwith generators. \n\nThis recipe allows to generate different kinds\nof series of numbers by applying a decorator over an infinite\ninteger generator. A processing function and a condition function\ncan be used to specify the rules.'}, {'comments': [{'comment': u'There is a easier to read, standard solution to this problem using the itertools module:\n\n<pre>\nfrom itertools import count, islice, imap, ifilter\n\nimap(proc, ifilter(cond, islice(count(), num)))\n</pre>', 'title': u'Better way'}, {'comment': u'I have not used itertools. This returns a generator, does<br>\nyour solution also return a generator?<br><br>\nThis recipe was written to show how to combine a generator with<br>\na function decorator to make another generator.<br>', 'title': u'Does this return a generator?'}, {'comment': u'Yes, the itertools version returns a generator.<br><br>\n\nAs for wrapping generators with decorators, since your goal is to show how it works, maybe you should provide an example without unnecessary frosting. Maybe something like:<br>\n\n<pre>\ndef squared(f):\n def wrapper(*args, **kw): \n for i in f(*args, **kw):\n yield i ** 2\n return wrapper\n\n@squared\ndef series(n):\n i = 0\n while i != n:\n yield i\n i += 1\n</pre>', 'title': u'Yep, its a generator'}, {'comment': u"If you're using Python 2.4 or later, generator expressions make an even more readable solution:<br>\n<br>\n<pre>\n(proc(x) for x in xrange(num) if cond(x))\n</pre>", 'title': u'Another way, for simple sequences'}, {'comment': u'The recipe was written to show how to extract a custom series<br>\nout of *any* infinite generator. Though the code shows the simplest<br>\ngenerator, i.e the one which returns a sequence of positive numbers\nit can be extended to any complex generator<br>. The generator expression can do it only for the simplest generator.<br>\n<br><br>\nAgain, your solutions are (probably) more readable and faster(I <br>\ntimed the itertools one with my code and it performs at least 3 times\nfaster), but the purpose of the recipe is not to add a lot of code in your original generator, but to make it do something else by<br> decorating.', 'title': u'Not the same problem...'}, {'comment': u'I only added the generator expression for the sake of people who are looking to solve the problem your recipe explicitly addresses, rather than the one you meant to address. My apologies for not making that clear.<br>\n<br>\nYou are incorrect in the limitations you place on the use of the generator expression. While I used xrange, any generator could have been put there. Further, the expression as written can technically produce any series in which the values are a function of the index, which is to say any series at all. You just need the right proc() function or expression.', 'title': u'OK, but...'}], 'desc': u'This is a rewrite of my previous recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389202. Instead of returning the series as a list, this one creates another generator instead.'}, {'comments': [{'comment': u"John,\nI really appreciate this mx.ODBC example. It's one of the only examples I've found out there for beginners. Do you have anymore examples that use mx.ODBC (in Access or in Oracle) to manipulate data? I'm sure other people out there who would appreciate other examples also.\n\nThanks\nGreg Corradini", 'title': u'Any more?'}], 'desc': u'Mx.odbc is cross platform and very fast, I have used it to go through a few hundred thousand rows of an access database in seconds where pure ADO would take 30 min (or 3 min if you use the ADO type library). Here is a simple example of how to talk to a database, in this case an access file, get the columns of a table and get data from the table.'}, {'comments': [{'comment': u"I might be wrong, but I would assume that a __init__ function should by default call the parent class' __init__.", 'title': u'Should __init__ call dict.__init__?'}, {'comment': u'Using keyword arguments in the constructor, one could simplify the code even more.\nSo, including my first advice, here\'s the code:\n<pre>\nimport copy\n\nclass DefaultDict(dict):\n """Dictionary with a default value for unknown keys."""\n def __init__(self, default, **items):\n dict.__init__(self, **items)\n self.default = default\n\n def __getitem__(self, key):\n if key in self: \n return self.get(key)\n else:\n ## Need copy in case self.default is something like []\n return self.setdefault(key, copy.deepcopy(self.default))\n\n def __copy__(self):\n return DefaultDict(self.default, **self)\n</pre>', 'title': u'Another minor improvement: Simplify your code with kwargs'}, {'comment': u'What about "try .. except" instead of "if key in self"?', 'title': u' '}, {'comment': u"**kwds is a dict where *all* of the keys are legal python identifiers. Since we can not count on that in the general case, we can't use that trick here in the __copy__ method. However, the dict constructor accepts an argument which can be a dict or a list of pairs. We do not need **self in the __copy__ method. If the __init__ constructor omits the ** before the items parameter, I think everything would work. Or better yet, support both approaches.\n\n<pre>\nclass DefaultDict(dict):\n def __init__(self,default,list_or_dict=None,**kwds):\n super(DefaultDict, self).__init__(list_or_dict)\n self.update(kwds)\n self.default = default\n \n def __getitem__(self, key):\n return self.get(key, self.default)\n \n def __copy__(self):\n return DefaultDict(self.default, self)\n </pre>\n\nI think this works OK.", 'title': u'**kwds has a trap'}, {'comment': u'That was accidental. For a quick test I was not using a mutable default and did not bother with saving keys back into self. I did not mean to remove that feature. I was focused on the ** parameter issue.', 'title': u'**the change in __getitem__**'}, {'comment': u'You are right - try/except would be better in this case, because it conveys more clearly that "usually" we just return dict[key], and use the other way out only as an afterthought.\n<br>\nAlso it is faster in the "usual" case, since setting up the trap is faster than the double lookup to see if the key is in the dict before fetching it.', 'title': u'try/except vs. if/then'}, {'comment': u'Thanks, just what I need.\nI think this could be a standard feature of the dictionary, since it is needed for constructing sparse "functions", which, I guess, is one of the key motivations for dictionaries. To be a useful abstraction, the function should know all its values. Currently, using get-method, the caller(!) has to know the default value and this is not good for modularity. Lately, I have been using:<br>\n<pre>\ndef sparse_func(d, val):\n return lambda k: d.get(k, val)\n</pre>\nbut then I loose all the dictionary-operations. I wonder if this "sparse function" viewpoint would be better addressed by adding a __call__ method to the dictionary.', 'title': u'Good Recipe'}, {'comment': u'This recipe is extremely useful, but suffers from the efficiency/generality\ntradeoff: in many important applications, the default value\nis immutable (0, \'\', or None), but calling "in", "setdefault", and\n"deepcopy" for new entries looks rather wasteful, given that one\ncall to "setdefault" would suffice.\n<br>\nThe following code tries to remedy this (at the expense of\nsome elegance), and also allows additional constructor arguments in\nthe style of the dict() function in 2.3 and later.\n<br>\nInsertion of defaults w/o copying is about 7 times faster than in the\noriginal version.\n<br>\nLeft out the copy method, as I am not sure a simple update is sufficient (wouldn\'t we have to copy the values recursively?)\n\n<pre>\nimport copy\n\nclass DefaultDictBase(dict):\n """Dictionary with a default value for unknown keys."""\n def __init__(self, default=None, *args, **kwargs):\n self.default = default\n self.update(dict(*args, **kwargs))\n\nclass DefaultDictCopy(DefaultDictBase):\n """DefaultDict that copies its default value."""\n def __getitem__(self, key):\n if key in self: return self.get(key)\n return self.setdefault(key, copy.deepcopy(self.default))\n\nclass DefaultDictNoCopy(DefaultDictBase):\n """DefaultDict that uses its default value as is."""\n def __getitem__(self, key):\n return self.setdefault(key, self.default)\n\ndef defaultDict(default=None,*args,**kwargs):\n "create a DefaultDict suitable for the given default"\n if id(default)==id(copy.deepcopy(default)):\n return DefaultDictNoCopy(default,*args,**kwargs)\n return DefaultDictCopy(default,*args,**kwargs)\n</pre>', 'title': u'Make it faster for simple cases'}, {'comment': u'Python 2.5 added the __missing__ hook to the standard dictionary type "for letting subclasses provide a default value when a key isn\'t contained in the dictionary. When a key isn\'t found, the dictionary\'s __missing__(key) method will be called. "', 'title': u'use __missing__ in Python 2.5'}], 'desc': u'A dictionary with a default value (such as 0 or [], or whatever you want) for unassigned keys'}, {'comments': [{'comment': u'argmin is essentially min with a key argument like what list.sort and sorted have. Note that min and max now take such \'key\' arguments in the current Python cvs:\n<pre>Python 2.5a0 (#60, Nov 30 2004, 15:53:08) [MSC v.1310 32 bit (Intel)] on win32\nType "help", "copyright", "credits" or "license" for more information.\nyou need the ctypes module to run this code\nhttp://starship.python.net/crew/theller/ctypes/\n>>> sequence = [\'one\', \'to\', \'three\']\n>>> min(sequence, key=len)\n\'to\'</pre>\n\nOf course, most people can\'t use the current CVS version of Python, so here\'s a substitute:\n<pre>py> class _minmax(object):\n... def __init__(self, func):\n... self.func = func\n... def __call__(*args, **kwargs):\n... self = args[0]\n... key = kwargs.pop(\'key\', None)\n... if kwargs:\n... raise TypeError("only \'key\' accepted as a "\n... "keyword argument")\n... if key is None:\n... return self.func(*args[1:])\n... else:\n... if len(args) == 2:\n... seq = args[1]\n... else:\n... seq = args[1:]\n... return self.func((key(item), i, item)\n... for i, item in enumerate(seq))[-1]\n... \npy> min = _minmax(min)\npy> max = _minmax(max)</pre>\nNow you should be able to use key arguments to min and max just like in CVS:\n<pre>py> min(\'ab\', \'c\')\n\'ab\'\npy> min(\'ab\', \'c\', key=len)\n\'c\'\npy> d = dict(a=2, b=1)\npy> max(d)\n\'b\'\npy> max(d, key=d.__getitem__)\n\'a\'</pre>', 'title': u'essentially min with a key argument'}], 'desc': u'Implement the argmin function from math, in a form that makes use of generator expressions in 2.4.'}, {'comments': [], 'desc': u'Adds a key= argument to min and max modeled after that of list.sort and sorted.\n\nThese will become obsolete in Python 2.5. when the builtin min() and max() functions gain the key= argument.'}, {'comments': [{'comment': u"<pre>\n>>> def x(): pass\n...\n>>> import inspect\n>>> inspect.getmodule(x).__name__\n'__main__'\n>>>\n</pre>\nFurther I'd probably iterate over sys.modules to find the name.\n(modules sometime do not know their name where they were loaded from.)\n\nAndreas", 'title': u'Consider autofetching the module name:'}], 'desc': u'A simple, easy to use wrapper function for doing quick tests\nof your functions using the timeit module.'}, {'comments': [{'comment': u"By putting the setattr code in __init__, you change all instances with each new instantiation of C:\n<pre>\npy> class C:\n... def __init__(self, methodNames):\n... for name in methodNames:\n... setattr(C, name, self.methodClosure(name))\n... def methodClosure(self, name):\n... def method(*args, **kwargs):\n... print name, args, kwargs\n... return method\n... \npy> c1 = C(['m1'])\npy> c2 = C(['m2'])\npy> hasattr(c1, 'm2')\nTrue\npy> hasattr(c2, 'm1')\nTrue\n</pre>\nIs this intentional? Seems like maybe you want a separate type for each set of methods instead. Perhaps something like:\n<pre>\npy> def c_factory(method_names):\n... def method_closure(name):\n... def method(*args, **kwargs):\n... print name, args, kwargs\n... return method\n... class C(object):\n... pass # define methods here if necessary\n... for name in method_names:\n... setattr(C, name, method_closure(name))\n... return C\n... \npy> C = c_factory(['m1'])\npy> c1 = C()\npy> C = c_factory(['m2'])\npy> c2 = C()\npy> hasattr(c1, 'm2')\nFalse\npy> hasattr(c2, 'm1')\nFalse\n</pre>", 'title': u'setting methods for all instances'}], 'desc': u'I needed to define a universal class with some methods known at construction time. It has to be possible to check whether a method exists in the instance.\n'}, {'comments': [], 'desc': u'An example of overloading __setattr__ and __getattr__ in classes. This example maps attribute names to dicitonary members.'}, {'comments': [{'comment': u'I had to make a small tweak to pcolor_matrix_pil() to get it to work with Numarray:<br>\n\n<pre> # For Numeric\n #mina = min(min(A))\n #maxa = max(max(A))\n \n # For Numarray\n mina = A.min()\n maxa = A.max()</pre>\n\nOtherwise, it seems to work nicely. I am using your recipe to visualize coefficients of inbreeding and relationship in pedigrees. Thanks for the cool recipe -- it took me about fifteen minutes to drop it into my app and get it working.', 'title': u'Tweak for Numarray'}, {'comment': u"Take a look at the matplotlib package:<br>\n\nhttp://matplotlib.sourceforge.net/<br>\n\nIt's a recreation (ongoing) of the matlab plotting system in python using a variety of rendering packages (backends) and non-GUI and GUI front ends. I believe that it implements pcolor and spy (as well as most 2-D matlab plotting)", 'title': u'Check out matplotlib'}], 'desc': u"I really like the 'spy' and 'pcolor' functions, which are useful in viewing matrices. 'spy' prints colored blocks for values that are above a threshold, and 'pcolor' prints out each element in a continuous range of colors. \nThe attached is a little Python/PIL script that does these functions for Numpy arrays."}, {'comments': [{'comment': u"I'm not sure what the author try to do, but the code is indeed broken.", 'title': u'Broken for sure...'}, {'comment': u"Abusing syntax is fun! This is almost like having Ruby code blocks.\n<pre>\ndef each(seq):\n def _each(func):\n for item in seq: func(item)\n return _each\n\n@each(range(3))\ndef _(i):\n print 'Item: %r' % i\n\nItem: 0\nItem: 1\nItem: 2\n</pre>\n", 'title': u'Love it'}, {'comment': u"First, it requires Python 2.4. I've added a note. Second, there was a slight bug in it, which I corrected.", 'title': u'two possibilities'}], 'desc': u'One can (ab)use this decorator to get the effect of a Lisp-like with_open_file block in Python. Kind of. Requires Python 2.4.'}, {'comments': [], 'desc': u'A Python 2.4 (or later) decorator can be used to watch for unhandled exceptions,\neven in hybrid environments like wxPython. You place the decorator around methods that will be invoked by the wxWidgets code. The only big trick is a dance that may be necessary to provide access to values only available after the wxPthon app is started.'}, {'comments': [{'comment': u'If you add stacklevel=2 to the warnings.warn() call, then the printed warning will indicate and show the call site to the deprecated function rather than to the location of the warnings.warn() call.', 'title': u'add stacklevel=2'}], 'desc': u'Java has the "@deprecated" flag (in javadocs) which is used to mark a method as no-longer-current and generates a warning if the method is used. Python can do the same thing.'}, {'comments': [{'comment': u'One could also use...\n<pre>\nimport random\nrandom.seed(STRING)\nval = random.random()\n</pre>\n\nOr even bypass all modules entirely...<br>\n<pre>\ndef r(STRING):\n return (hash(STRING)+2.0**31)/2**32\n</pre>', 'title': u' '}, {'comment': u"random()'s or hash()'s results are not reproducible in other languages, nor necessarily in different versions of Python where implemenatations may change. MD5, or any other standard hash function, does guarantee reproducible results.", 'title': u'True, but...'}], 'desc': u'Convert strings to floats in the range [0, 1), using a hash function'}, {'comments': [{'comment': u'Using the threaded runner is great for suites of high-latency tests that aren\'t CPU-bound.\n<br><br>\nAn example suite is below.\n<br><br>\nOutput for running examples(suite()):\n<br><br>\n---- begin output ----\n<pre>\n== sequential ==\n.......\n----------------------------------------------------------------------\nRan 7 tests in 16.415s\n\nOK\n== threaded ==\n.......\n----------------------------------------------------------------------\nRan 7 tests in 5.869s\n\nOK\n== filtered ==\n..\n----------------------------------------------------------------------\nRan 2 tests in 2.444s\n\nOK\n</pre>\n---- end output ----\n<br><br>\nThe suite:\n\n<pre>\nimport unittest, urllib\n\nclass NewsSitesTestCase(unittest.TestCase):\n def testSlashdot(self):\n urllib.urlopen("http://www.slashdot.org").read()\n def testWired(self):\n urllib.urlopen("http://www.wired.com").read()\n def testTheOnion(self):\n urllib.urlopen("http://www.theonion.com").read()\n\nclass OtherSitesTestCase(unittest.TestCase):\n def testYahoo(self):\n urllib.urlopen("http://www.yahoo.com").read()\n def testGoogle(self):\n urllib.urlopen("http://www.google.com").read()\n def testPython(self):\n urllib.urlopen("http://www.python.org").read()\n def testThinlet(self):\n urllib.urlopen("http://thinlet.sourceforge.net").read()\n\ndef suite():\n result = unittest.TestSuite()\n result.addTest( unittest.makeSuite(NewsSitesTestCase) )\n result.addTest( unittest.makeSuite(OtherSitesTestCase) )\n return result\n</pre>', 'title': u'High-latency test suites'}], 'desc': u"Note: This recipe is superceded by TestOOB, a Python unit testing framework that extends unittest and provides many new features - including running tests in threads! http://testoob.sourceforge.net\n\nTrying to extend unittest to provide extra features wasn't easy.\nThis scheme allows easy extensions for running existing test suites."}, {'comments': [], 'desc': u'This code has been released as a module called "arrayterator".'}, {'comments': [{'comment': u'This recipe requires the socket library to be compiled with ssl support. See http://docs.python.org/lib/module-httplib.html. The ssl support is already in the Python install on Fedora Core 3 (and I guessing other Linux installs as well). Based on a report by a Python user under Windows, at least on version of Python for Windows does not have ssl support.\n<br><br>\nWithout ssl support you get an exeption that looks, in part, like:<br>\n File "C:\\Python24\\lib\\urllib2.py", line 1053, in unknown_open<br>\n raise URLError(\'unknown url type: %s\' % type)<br>\nURLError: urlopen error unknown url type: https\n<br><br>\nGeorge\n ', 'title': u'ssl support is required'}], 'desc': u"Use John J. Lee's ClientCookie and ClientForm classes to easily access password-protected web applications. A group on yahoo.com is used as an example."}, {'comments': [], 'desc': u'An method to detect the last item in a loop.'}, {'comments': [{'comment': u"<pre>\ndef myMakeSigDigs(num, digits, debug=False):\n digs, order = ('%.20e'%num).split('e') \n order = int(order)\n if type(num) is long: digs = str(num) # Not needed for current tests\n digs = (digs.replace('.', '') + '0'*digits)[:digits]\n\n if debug: print 'num=%r, order=%d, digits=%s'%(num, order, digs)\n\n if 0<=order<5 and order<len(digs)-1:\n return '%s.%s'%(digs[:order+1], digs[order+1:])\n elif -5<=order<0: \n return '0.%s%s'%('0'*(-order-1), digs)\n else:\n return '%s.%se%+d'%(digs[0], digs[1:], order)\n</pre>\nThis code passes your unit test. If you work only with floats, and don't want add to tests\n<pre>[1234567890123456789012L, 19, '1.234567890123456789e+21']</pre>\ncode may be even one line shorter (see comments).", 'title': u"Your code is monstrous, if I will need this I'll write that"}, {'comment': u"when not using longs calculating order and digits can be written with following one-liner: <br>digs, order = [[lambda x, d=digits: (x.replace('.', '') + '0'*d)[:d], int][func](arg) for func, arg in enumerate(('%.20e'%num).split('e'))]<br>I didn't saw such trick before. It is a map() which applies different functions to record fields.", 'title': u'Just for fun'}, {'comment': u'When I ran this recipe i got:\n<pre>======================================================================\nFAIL: MakeSigDigs should return known values for known inputs.\n----------------------------------------------------------------------\nTraceback (most recent call last):\n File "C:\\Usr\\Sav\\wrk\\prj\\digs\\digicalc.py", line 118, in testKnownValues\n self.assertEqual(makeSigDigs(el[0], el[1], debug=True), el[2])\nAssertionError: \'3.3e-010\' != \'3.3e-10\'\n\n----------------------------------------------------------------------</pre>', 'title': u'minor bug in your code'}, {'comment': u"When I have a moment, I'll see if I can refactor my code based on your ideas. I'm fairly new with python, hence the monstrosity. ;) Thanks.", 'title': u'Thanks for the tips'}, {'comment': u'When asked for two significant digits of 0.9999, both of the above recipes return the wrong result of 0.99, rather than the correct result of 1.0.', 'title': u'Neither of the above recipes actually works'}, {'comment': u"Try Tim Peters' solution http://mail.python.org/pipermail/tutor/2004-July/030324.html", 'title': u'Better for some'}], 'desc': u'Method to find significant digits for any given number. Accounts for scientific notation. Returns a numeric string.\n\nA unit test is included.'}, {'comments': [], 'desc': u'This recipe provides a buffered stream that supports multiple forward-only readers. The buffer enables readers that are behind the front-runner to access values that have already been read from the stream. Values that are no longer accessible by any reader are cleared from the buffer.'}, {'comments': [{'comment': u"This one's a little shorter :-) (but less readable :-/)\n<pre>\ndef pascal(n):\n l = [[1]]\n for i in xrange(n-1):\n l.append([1,1])\n for j in xrange(len(l[-2])-1):\n l[-1].insert(-1,l[-2][j]+l[-2][j+1])\n return l\n\nif __name__ == '__main__':\n for i in mypascal(20): print i\n</pre>", 'title': u' '}, {'comment': u"In my example above it should be \n<pre>\nif __name__ == '__main__':\n for i in pascal(20): print i\n</pre>", 'title': u' '}, {'comment': u'def pascal2(n, t=[1], z=[[1]]):\n for i in xrange(1, n):\n z+=[[1]+[z[i-1][j]+z[i-1][j+1] for j in range(len(z[i-1])-1)]+[1]]\n print z', 'title': u'Shorter? Take this'}, {'comment': u'This highlights how the calculation is done.\n<pre>\ndef nextrow(lst):\n lag = 0\n for element in lst:\n yield lag + element\n lag = element\n yield element\n\nrow = [1]\nfor number in range(12):\n row = nextrow(row)\n print row\n</pre>', 'title': u'Row by Row'}, {'comment': u'def pas(n=10):\n line=[1]\n for i in range(0,n):\n print line\n line=[0]+line\n for j in range(len(line)-1): line[j]+=line[j+1]', 'title': u'Another try'}], 'desc': u'this script prints a few lines of Pascal`s triangle ;-)'}, {'comments': [{'comment': u'I\'m not entirely sure I see the point. You can get 90% of the effects by directly capturing the next() method of the generator, like so:\n<pre>\n>>> class T:\n... def foo(self):\n... yield 1\n... yield 2\n... yield 3\n...\n>>> t = T()\n>>> f = t.foo().next\n>>> f()\n1\n>>> f()\n2\n>>> f()\n3\n>>> f()\nTraceback (most recent call last):\n File "", line 1, in ?\nStopIteration\n>>> f = t.foo().next\n>>> f()\n1\n</pre>\nYou get a StopIteration exception rather than None and an automatic reset, and the reset is a bit more explicit, but it seems a lot clearer to me.\n\nOf course, clarity is very personal, so if you like this form, that\'s fine.', 'title': u' '}, {'comment': u"The real purpose of this recipe is to hide the fact that a method is actually a generator. A client object invoking a method probably should not have to worry about whether the method can be called directly or if next should be invoked instead. This recipe allows the caller to use the normal method invocation syntax without knowing anything about that method's implementation.", 'title': u'Encapsulation'}, {'comment': u'Nice recipe. How can I wrap a function instead of a method?', 'title': u'What about generator functions'}], 'desc': u"This recipe enables the use of the yield statement within a method by decorating that method with a wrapper for a generator object. The purpose of using this decorator is to allow the method to be invoked using the normal calling syntax. A caller need not know the method is actually a generator and can focus solely on the method's interface rather than how it is implemented."}, {'comments': [{'comment': u'Does anyone know where can I have python script for GetExtendedTcpTable?', 'title': u'How about GetExtendedTcpTable?'}], 'desc': u"This function will return a list of ports (TCP/UDP) that the current machine is listening on. It's basically a replacement for parsing netstat output but also serves as a good example for using the IP Helper API.\n"}, {'comments': [{'comment': u"How about this simpler solution:\n\n<pre>\ndef vunpack(t, n, defaults=[]):\n ''' variable-length tuple unpacker\n \n by Greg Jorgensen, gregj@pdxperts.com, 3/31/2005\n \n return a tuple of the first n items from iterable t\n missing elements are populated from defaults if supplied,\n otherwise missing elements are None\n \n tests:\n vunpack((1,2,3,4), 3) => (1,2,3)\n vunpack((1,), 3) => (1,None,None)\n vunpack((1,2), 5, ('a','b','c','d','e')) => (1,2,'c','d','e')\n \n examples:\n (x,y) = vunpack((1,2,3,4), 2, (43,44)) => x=1, y=2\n (x,y) = vunpack((,), 2, (43,44)) => x=43, y=44\n for (x,y,z) in [vunpack(t, 3, (0,0,0)) for t in [(1,2,3),(4,5),(6,7,8,9,10)]]:\n print x, y, z\n '''\n \n result = list(defaults) + [None] * n\n result[0: len(t)] = list(t)\n return tuple(result[0: n])\n</pre>", 'title': u'simpler variable-length tuple unpacking'}, {'comment': u'I can reduce that function even more:\n\n<pre>\ndef vunpack(t, n, defaults=[]):\n return tuple( (list(t) + list(defaults)[len(t):] + [None] * n)[0:n] )\n</pre>\n\nOne of the examples in my first posting has a typo. It should be:\n\n<pre>\n# x,y = vunpack((), 2, (43,44)) => x=43, y=44\n</pre>\n\nGreg Jorgensen\nPDXperts LLC\nPortland, Oregon USA', 'title': u'even simpler variable-length tuple unpacking'}, {'comment': u"There are several simplifications and differences in your solutions:<br><br>\n\n-Is this a bug or a feature ?<br>\n>>> vunpack((1,2), 5, ('c','d','e'))<br>\n(1, 2, 'e', None, None)<br>\nI would expect the answer to be (1,2,'c','d','e'). Essentially you\nassume that all the elements of t are optional, which corresponds\nto setting minLength=0 in my solution. However if len(defaults) < n, you pad the missing defaults with None.<br><br>\n\n- Extra items (i.e if len(t) > n) are always ignored; this corresponds to calling mine with extraItems=None, but the other options (extraItems=True or extraItems=False) are also useful in practice.<br><br>\n\n- It cannot be used with arbitrary iterables since it uses len(t).<br><br>\n\n- It's probably slower as it creates longer than required lists and then truncates them.<br><br>\n\nGeorge\n", 'title': u'Not quite the same'}, {'comment': u"> There are several simplifications and differences in your solutions:\n<br><br>\nYes. I intended to show a general technique only.\n<br><br>\n> -Is this a bug or a feature ?<br>\n> >>> vunpack((1,2), 5, ('c','d','e'))<br>\n> (1, 2, 'e', None, None)<br>\n<br><br>\nFeature. My function always returns a tuple of n elements. If the tuple passed to it (t) is longer than n, the first n elements are returned. If the tuple t is shorter than n, the missing elements are filled first with the corresponding elements from default, and then with None if there are no defaults.\n<br><br>\nObviously it would be easy to change my function to behave differently if that's what's wanted:\n<br>\n<pre>\n return tuple((list(t) + list(defaults) + [None] * n)[0:n])\n</pre>\n<br>\nwould have the effect you describe.\n<br><br>\nI've actually had a need for that kind of thing several times. A similar case is the pad/justify a string problem in languages that don't have functions to do it. Some programmers write loops to add the pad character. Another way is to just prepend/append the maximum padding to the string and truncate the result.\n<br><br>\n> Extra items (i.e if len(t) > n) are always ignored; this corresponds to<br>\n> calling mine with extraItems=None, but the other options (extraItems=True<br>\n> or extraItems=False) are also useful in practice.<br>\n<br><br>\nThe problem I thought we were solving was generating fixed-length tuples from a list (or iterable) of variable-length tuples, so the tuples could be unpacked.\n<br><br>\nIf the extra items are needed my function would need some additional functionality. The extra items are still there in list(t)[n:].\n<br><br>\n> It cannot be used with arbitrary iterables since it uses len(t).\n<br><br>\nIt could if it converted t to a list first:\n<br>\n<pre>\n a = list(t)\n return tuple((a + list(defaults)[len(a):] + [None] * n)[0:n])\n</pre>\n<br>\n> It's probably slower as it creates longer than required lists and then<br>\n> truncates them.\n<br><br>\nI guess that might be relevant for some applications, but I would be surprised if one line of code that uses only simple operations on built-in types is slower than a function that includes multiple conditional tests, a loop, exceptions, and a closure.\n<br><br>\nAgain, the point of posting my recipe is to show a technique, not a solution to every possible problem. In some circumstances a more general solution like yours would be appropriate.\n<br><br>\nGreg Jorgensen", 'title': u'Re: Not quite the same'}, {'comment': u"> > Extra items (i.e if len(t) > n) are always ignored; this corresponds to<br>\n> > calling mine with extraItems=None, but the other options (extraItems=True<br>\n> > or extraItems=False) are also useful in practice.<br>\n> <br>\n> <br>\n> The problem I thought we were solving was generating fixed-length tuples <br>\n> from a list (or iterable) of variable-length tuples, so the tuples could be<br>\n> unpacked.<br>\n<br>\nYes, the output is a generator of fixed-length tuples, but with the possibility of constraining the set of valid inputs, instead of accepting all variable-length iterables. More specifically, the problem was to simulate the argument passing rule used for callables, as in the following syntactically incorrect examples:<br>\n<pre>\nfor (x,y,z=0) in [(1,2,3), (4,5), (6,7,8,9,10)]:\n print x,y,z\nfor (x,y,z=0,*rest) in [(1,2,3), (4,5), (6,7,8,9,10)]:\n print x,y,z,rest\n</pre>\n<br>\nIn the first example, only iterables of length 2 or 3 would be accepted, so a ValueError would be raised when trying to unpack (6,7,8,9,10). In the second, iterables of length greater or equal to 2 are valid, and the output would be length-4 tuples, with the last element being also a tuple.<br>\n<br>\n> > It cannot be used with arbitrary iterables since it uses len(t).<br>\n> <br>\n> It could if it converted t to a list first:<br>\n> <br>\n> a = list(t)<br>\n> return tuple((a + list(defaults)[len(a):] + [None] * n)[0:n])<br>\n<br>\nOne more argument for the last point ;-)<br>\n <br>\n> > It's probably slower as it creates longer than required lists and then<br>\n> > truncates them.<br>\n> <br>\n> I guess that might be relevant for some applications, but I would be<br>\n> surprised if one line of code that uses only simple operations on built-in<br>\n> types is slower than a function that includes multiple conditional tests, a<br>\n> loop, exceptions, and a closure.<br>\n<br>\n- The closure is created only once for a given binding of the parameters; it can then be used for iterating over different loops as a normal function. Of course, it's trivial to have a function pad(iterable,minLength,defaults,extraItems) instead of a padfactory(minLength,defaults,extraItems) if this is preferable.<br>\n- The exceptions are there for enforcing the constraints I mentioned above. Besides, the first try/except block is entered only if extraItems is False and the second attempts to return an instance of the same type as the input instead of returning always a tuple (this may or may not be desirable).<br>\n- Perhaps you're right in that in most practical cases with small input sequences, the one-liner would be as fast or even faster than the larger function. I was commenting more on the algorithmic performance, especially as len(t) >> n, rather than the expected in real cases.<br>\n", 'title': u' '}, {'comment': u"Since the number of variables on the left side of the assignment are known at compile time, typical cases can be handled without much fuss.\n<br><br>\nUnpacking from a list or tuple that may be too long:\n<br>\n<pre>\n>>> t = range(10)\n>>> a,b,c = t[:3]\n>>> a, b, c\n(0, 1, 2)\n</pre>\n<br>\nUnpacking and catching all excess elements into a tuple:\n<br>\n<pre>\n>>> t = range(10)\n>>> a,b,c,z = list(t[:3]) + [t[4:]]\n>>> a,b,c,z\n(0, 1, 2, [4, 5, 6, 7, 8, 9])\n</pre>\n<br>\nUnpacking from a list/tuple that may be too short:\n<br>\n<pre>\n>>> t = range(2)\n>>> a,b,c,d,e = (t + [99] * 5)[:5]\n>>> a,b,c,d,e\n(0, 1, 99, 99, 99)\n</pre>\n<br>\nEtc. There are plenty of variations on this, but the key point is that the number of items you need for assignment is known at compile time; it doesn't vary at runtime.\n<br><br>\nThere are also some functions in itertools for doing things like this, and they work on any iterable:\n<br>\n<pre>\n>>> import itertools\n>>> t = range(10)\n>>> a,b,c,d,e = itertools.islice(t, 5)\n>>> a,b,c,d,e\n(0, 1, 2, 3, 4)\n</pre>", 'title': u'simple unpack idioms'}], 'desc': u'Python tuple unpacking works only for fixed length sequences, that is one cannot write something like:\nfor (x,y,z=0,*rest) in [(1,2,3), (4,5), (6,7,8,9,10)]: print x,y,z,rest\n\nThis recipe returns a pad function that implements this functionality (albeit with less concise syntax). Using the recipe, the example above then can be written as:\npad = padfactory(minLength=2,defaults=(0,),extraItems=True)\nfor x,y,z,rest in map(pad, [(1,2,3), (4,5), (6,7,8,9,10)]): print x,y,z,rest\n\n'}, {'comments': [], 'desc': u'For those who want to start dynamic web programming, but don\'t know what to choose among the many Python web frameworks, this program might be a good starting point\n\nScriptServer is a minimalist application server, handling both GET and POST requests, including multipart/form-data for file uploads, HTTP redirections, and with an in-memory session management. It can run Python scripts and template files using the standard string substitution format\n\nThe scripts are run in the same process as the server, avoiding the CGI overhead. The environment variables are provided in the namespace where the script runs\n\nTo start the server, run <pre style="font-size:12"> python ScriptServer.py</pre>In your web browser, enter http://localhost, this will show you a listing of the directory. Add the scripts in the same directory as ScriptServer\n\n\n\n\nA simple example of how to use the session management and the exception HTTP_REDIRECTION\n\n====================\nhome page : index.py\n====================\n\nprint "<h3>Simple portal</h3>"\n\nso = Session()\nif hasattr(so,\'user\'):\n    print "User :", so.user\n    print \'<br><a href="logout.py">Logout</a>\'\nelse:\n    print \'<a href="login.html">Login</a>\'\n\nprint "<p>Your content here..."\n\n=======================\nlogin page : login.html\n=======================\n\n<form action="login.py">\nUser <input name="user">\n<input type="submit">\n</form>\n\n=======================\nlogin script : login.py\n=======================\n\n# set the attribute \'user\' of the session object\nso = Session()\nso.user = request[\'user\'][0]\n# redirect to the home page\nraise HTTP_REDIRECTION,"index.py"\n\n=========================\nlogout script : logout.py\n=========================\n\n# logout : remove the attribute \'user\' of the session object\ndelattr(Session(),\'user\')\n# redirect to the home page\nraise HTTP_REDIRECTION,\'index.py\''}, {'comments': [{'comment': u"Well, hectares aren't an English measure, to be sure... ;)", 'title': u' '}, {'comment': u'This is similar to generic functions (PyProtocol\'s dispatch: http://peak.telecommunity.com/DevCenter/CombiningResults), which might look like:\n\n<pre>\n@dispatch.generic()\ndef convert(value, source_unit, dest_unit):\n "Convert value from the source to dest units"\n\n@convert.when("source_unit == \'inch\' and dest_unit == \'feet\'):\ndef tofeed(v, s, d):\n return v / 12.0\n\n@convert.when("source_unit == \'feet\' and dest_unit == \'inch\'):\ndef toinch(v, s, d):\n return v * 12\n</pre>', 'title': u'Generic functions'}], 'desc': u"Decorators can be used to load data structures with a function. Using this technique can reduce the 'lots of declarations; large table definition; startup' structure of some larger programs. The insight is remembering that a decorator can return the original function unchanged."}, {'comments': [{'comment': u'In the recipe where you have used partials[i] and partials[i:], could not you have used partials.append()? Am I missing something subtle here?\n\n--Hemanth Sethuram', 'title': u'Do you need list indexing'}, {'comment': u'Please credit or note earlier recipes (e.g. 298339) that perform similar functions.', 'title': u'Credit earlier recipes'}, {'comment': u'p[i:] = [x] appends after deleting all elements beyond i. If you print the partials array after each iteration, you will see that sometimes it grows, sometimes it shrinks, and sometimes keeps the same length. All of that logic is captured by the slice assignment.\n<br> Dozens of variations of the code were tried out -- this was by far the simplest and fastest.', 'title': u'Reason for not using append.'}, {'comment': u'Those recipes are not exact. They mitigate round-off issues but do not eliminate them. Certain datasets will completely defeat those efforts. In contrast, this recipe is provably exact in all cases.\n<br>\nThis recipe was not derived from those other recipes. It is a direct tranlation from the cited research paper which pre-dates the other postings.', 'title': u'Why there is no reference to other recipes'}, {'comment': u'Your points are well taken (and your implementation of the cited work is excellent), but as the cookbook grows (and functionally-similar recipes multiply), it becomes more and more difficult for non-experts to determine which recipe to choose to carry out a particular task. Analogous to journal articles, it would be highly useful to users of the cookbook to see (in the recipe explanation) citations of existing related recipes and the improvements provided by the present code.', 'title': u'References are useful for people who want to discriminate between recipes'}, {'comment': u'I don\'t understand the point of having a non-zero "start" arg; it doesn\'t participate in the round-off error elimination. Why not initialise partials = [start] ?', 'title': u' '}, {'comment': u'"This one goes beyond mitigation and is provably exact."\nThis is subject to some quite delicate assumptions about the underlying FP arithmetic. I have done similar things in C which either work or don\'t work depending on the CPU rounding mode setting and compiler optimization flags. How do we know python has all the settings correct? In particular, all intermediate results must be correctly rounded to the 53-bit mantissa length. How do we know the analog of this for decimal arithmetic holds?\n\n', 'title': u'provably exact?'}, {'comment': u'"This one goes beyond mitigation and is provably exact."\nThis is subject to some quite delicate assumptions about the underlying FP arithmetic. I have done similar things in C which either work or don\'t work depending on the CPU rounding mode setting and compiler optimization flags. How do we know python has all the settings correct? In particular, all intermediate results must be correctly rounded to the 53-bit mantissa length. How do we know the analog of this for decimal arithmetic holds?\n\n', 'title': u'provably exact?'}, {'comment': u'Exactness is proved in the referenced paper:\n<pre>\nhttp://www-2.cs.cmu.edu/afs/cs/project/quake/public/papers/robust-arithmetic.ps\n</pre>\nSee the FAST-TWO-SUM primitive (theorem 6) and the GROW-EXPANSION algorithm (theorem 10). These theorems follow from IEEE-754 arithmetic guarantees.\n\n\n', 'title': u'Exactness'}, {'comment': u'"How do we know the analog of this for decimal arithmetic holds?"\n<br><br>\ndsum() increases the precision, and retries, so long as the inexact exception is raised. Therefore no info is lost.', 'title': u"Because dsum() doesn't round at all"}, {'comment': u'"This is subject to some quite delicate assumptions about the underlying FP arithmetic"\n<br><br>\nAll the routines assume Python floats store no more than 53 significant mantissa bits, although fancier code could remove that assumption for the methods based on Decimal and longs.\n<br>\nThe routine using native fp arithmetic also assumes IEEE-754 nearest/even rounding is in effect. Python does nothing to force that, but 754 requires that nearest/even be the starting rounding mode in a conforming system, and Python inherits that from the platform C (if the latter is in fact conforming).', 'title': u'754 is assumed'}, {'comment': u'Keith had made his comment on an earlier revision of the recipe which erroneously claimed that msum() worked on Decimal inputs as well as binary floating point. That claim was subsequently removed from the description.', 'title': u' '}, {'comment': u"Why not stay with binary arithmetic, taking the mantissa as being exactly as presented? The multi-precision array spanning the dynamic range of the floating-point numbers could work in base 2 (bits), base 16 (four bits), or in bytes; whatever is least inconvenient when aligning each incoming number's bits ready for the addition.", 'title': u'Why use decimal arithmetic and incur conversion costs?'}], 'desc': u'Completely eliminates rounding errors and loss of significance due to catastrophic cancellation during summation. Achieves exactness by keeping full precision intermediate subtotals. Offers three alternative approaches, each using a different technique to store exact subtotals.'}, {'comments': [{'comment': u'Good zip data (aka Postleitzahlen) in various formats and free of payment for Germany, Austria and Switzerland can be found here: http://opengeodb.sourceforge.net/', 'title': u'German zip codes'}, {'comment': u"Unless there's a fee or subscription involved. Get a permission-denied error when I try it.", 'title': u'US Zip Code Site Not Apparently Valid'}, {'comment': u"Rather then posting a direct link,<br>\n<br>\nappend zips.txt to the url:<br>\nhttp://www.census.gov/tiger/tms/gazetteer/<br>\n<br>\nand you'll get what you want ;)", 'title': u'zips.txt'}, {'comment': u"Thank You ... I also noted that they've updated their site. You can get more information from:\nhttp://www.census.gov/geo/www/gazetteer/gazette.html\nsuch as file layout, other data sets, etc.", 'title': u' '}, {'comment': u"This code doesn't work correctly. try getting the distance between New York City and San Francisco...\nThe number will be over 5000, and that's not right even in kilometers.\n\nCorrect code is available at from http://www.zachary.com/blog/2005/01/12/python_zipcode_geo-programming\n\nOh, and a great zip code DB is available at http://www.cfdynamics.com/cfdynamics/zipbase/index.cfm\n\n/LT>", 'title': u'this code is WRONG'}, {'comment': u'I tried your mythical San Fran vs. NY problem ... in the dB I gave reference to, SF has Long / Lat coordinates (zip 94134) of -122.409577 / 37.718969, respectively. This translates into -2.13645 / 0.65832 (rounded, again respectively) in radians (which the recipe calls for). NY (zip 10011) is -73.99963 / 40.740225 => -1.291537 / 0.711051. Pumping the radian values into the formula I provided (dist) gives me a distance of ~ 2,564. Using the same coordinates in your formula produces 2,601 (diff ~ 37 mi\'s). Therefore, not sure why you would consider my code as "WRONG" unless your code is wrong as well. So until you can reproduce your error, please don\'t criticize my work and then try to promote your blog through such weak rhetoric.', 'title': u'Not from what I can see'}, {'comment': u"The code on www.zachary.com is bogus. Calculate the distance between -90/89 and 90/89, two locations near the north pole, and you get the same distance as if it were two locations on opposite sides on the equator.<br>\n<br>\nI don't understand the formula Kevin Ryan is using. I wrote the code below, that gives 2565 miles for the distance between SF and NY, only one mile off from Kevin's result.\n<pre>\nimport math\n\nclass Position:\n\n def __init__(self, longitude, latitude):\n 'init position with longitude/latitude coordinates'\n llx = math.radians(longitude)\n lly = math.radians(latitude)\n self.x = math.sin(llx) * math.cos(lly)\n self.y = math.cos(llx) * math.cos(lly)\n self.z = math.sin(lly)\n\n def __sub__(self, other):\n 'get distance in km between two positions'\n d = self.x * other.x + self.y * other.y + self.z * other.z\n if d < -1:\n d = -1\n if d > 1:\n d = 1\n km = math.acos(d) / math.pi * 20000.0\n return km\n\nif __name__ == '__main__':\n\n d = Position(-122.409577, 37.718969) - Position(-73.99963, 40.740225)\n\n print d, 'kilometers'\n print d / 1.609, 'miles'\n\n</pre>\nOutput:\n<pre>\n 4127.21644987 kilometers\n 2565.08169662 miles\n</pre>", 'title': u' '}, {'comment': u'Actually, the difference is only 0.4 miles.', 'title': u' '}, {'comment': u'Awesome, thanks!', 'title': u'thanks :)'}, {'comment': u'The code on zachary.com is not bogus. Be sure you call the <pre>calcDistance</pre> function with longitude and latitude passed correctly. If you do, the code on zachary.com gives an answer of about 217 nautical miles for your example, which is entirely reasonable.', 'title': u'zachary.com code is not bogus'}, {'comment': u'There\'s a bug in the code, but another bug in the code compensates for it.\n\nExecutable lines 4-5 of __init__ should be:\n<pre>\n zip, state, city, lon, lat = line.split(",")[1:-2]\n self.zips[zip] = _Zip_Code_Record(zip, state, city, lon, lat)\n</pre>\n\nJohn\n', 'title': u'Bug in the code'}, {'comment': u'<pre>\n# geopy - http://exogen.case.edu/projects/geopy/\nfrom geopy import geocoders \nfrom geopy import distance\n\ng = geocoders.Google(resource=\'maps\', output_format=\'js\') \n\n#(\'57350\', \'58368\', 286.182054428), # HURON, SD ... PLEASANT LAKE, ND\n\nplace, (lat, lng) = g.geocode("57350")\nplace1, (lat1, lng1) = g.geocode("58368")\n\nprint "%s: %.5f, %.5f" % (place, lat, lng) \nprint "%s: %.5f, %.5f" % (place1, lat1, lng1)\nprint "dist: ", distance.distance((lat, lng), (lat1, lng1)).miles\n\n Output: \n SD 57350: 44.35902, -98.21629\n ND 58368: 48.31726, -99.99895\n dist: 286.367102557\n</pre>', 'title': u'use Google, simple...'}, {'comment': u'The Google EULA excludes many uses. So simple, but sometimes also illegal.', 'title': u'Simple, but...'}], 'desc': u'I came across the mention of a formula labeled "The Great Circle Distance Formula" that purported to calculate the distance between any two points on the earth given their longitude and latitude points (the reference was in a Linux Magazine article). So, I looked up some information and cooked up a Python version of the calculation. There are references in the code where you can obtain approximate zip code data for free (e.g., if you wanted to enhance your website by adding a "Search within x mi\'s" feature), as well as references to the GCDF if you have further interest. Enjoy!\n\n04/25/2006 update: I\'ve decided to update this recipe with an object oriented bent where the information is cached once the object is instantiated. I\'ve also added command line access to automatically download the zipcode file from the census website (just use \'python zips.py -d\' and it will download a copy to your harddrive under \'zips.txt\'). Lastly, I\'ve added some unit testing so that if any future changes are made this will automatically run and tell me if anything pops out as wrong.'}, {'comments': [], 'desc': u'Evaluate using Decimals instead of floats.'}, {'comments': [{'comment': u"<pre>def update_meta (self, other):\n self.__name__ = other.__name__\n self.__doc__ = other.__doc__\n self.__dict__.update(other.__dict__)\n return self\n\nclass LateBindingProperty (property):\n\n def __new__(cls, fget=None, fset=None, fdel=None, doc=None):\n\n if fget is not None:\n def __get__(obj, objtype=None, name=fget.__name__):\n fget = getattr(obj, name)\n return fget()\n\n fget = update_meta(__get__, fget)\n\n if fset is not None:\n def __set__(obj, value, name=fset.__name__):\n fset = getattr(obj, name)\n return fset(value)\n \n fset = update_meta(__set__, fset)\n\n if fdel is not None:\n def __delete__(obj, name=fdel.__name__):\n fdel = getattr(obj, name)\n return fdel()\n \n fdel = update_meta(__delete__, fdel)\n\n return property(fget, fset, fdel, doc)\n\nclass C(object):\n \n def getx(self):\n print 'C.getx'\n return self._x\n\n def setx(self, x):\n print 'C.setx'\n self._x = x\n\n def delx(self):\n print 'C.delx'\n del self._x\n\n x = LateBindingProperty(getx, setx, delx)\n\nclass D(C):\n\n def setx(self, x):\n print 'D.setx'\n super(D, self).setx(x)\n\n def delx(self):\n print 'D.delx'\n super(D, self).delx()\n\nc = C()\nc.x = 1\nc.x\nc.x\ndel c.x\n\nprint\n\nd = D()\nd.x = 1\nd.x\nd.x\ndel d.x</pre>\n\nThis has the advantages that:\n<br>\n<br>a. You get back an actual property object (with attendant memory savings, performance increases, etc);\n<br>\n<br>b. It's the same syntax as using property(fget, fset, fdel, doc) except for the name;\n<br>\n<br>c. It will fail earlier (when you define the class as opposed to when you use it).\n<br>\n<br>d. It's shorter ;)\n<br>\n<br>e. If you inspect the property you will get back functions with the correct __name__, __doc__, etc.", 'title': u'Another approach - pass the actual methods, and extract the names from them'}, {'comment': u"Reasonable enough. The one disadvantage is that you can't specify that a subclass may implement one of the methods even though the superclass hasn't. Not sure how often this is actually desirable though...", 'title': u' '}, {'comment': u'The simplest way to deal with this is to have the base class implement the property function to just raise NotImplementedError.', 'title': u'NotImplementedError'}], 'desc': u'This recipe provides a LateBindingProperty callable which allows the getter and setter methods associated with the property to be overridden in subclasses.'}, {'comments': [], 'desc': u'Here is a handy function to use the timeit module from a script, creating a nice overview of the runtimes of one or more code snippets.\n\nAll command line flags that the timeit module accepts can be used.\n\nThe output can easily be customized.'}, {'comments': [], 'desc': u'An issue with socket.recv is how to know when you are done receiving data. A TCP stream guarantees the bytes will not arrive out of order or be sent more than once. But you do not know the size of the data that will be sent to you. 100 bytes could be sent as group of 10 bytes or maybe in one shot. Ultimately, this means you have to use a loop in some fashion until you know it is done.\n\nThe basic recv returns an empty string when the socket is disconnected.\nFrom that you can build a simple loop that will work as long as the sender manages to disconnect the socket at the appropriate time. However, there could be situations where a local error will mask as a clean shutdown or maybe a close() is never called. \n\nThree very basic methods are shown below that try to fix that problem. They use either a time-based, end marker, or size of payload method. Since you cannot be sure just what you are going to receive, you have to be careful that you get enough of a message to determine the size of payload or end marker. \n\nI updated the recv_size method to allocate data in larger chunks if it gets a large stream of data, which can increase performance.'}, {'comments': [{'comment': u"I like this recipe a lot, but it's really just trapping and printing the indicated exception types, not handling in general. So I would want to enhance this recipe with a means of confuring and providing handler code. The simplest idea would be to change the decorator argument to a dict (**posargs) and where the keys are the exception types that each map to their own callable handler. I'm sure somebody could come up with something better but that would be a start.", 'title': u'Not really "handling" but close..'}, {'comment': u'I know I should have made in more clear in my comment, but I was in fact sort of responding to the last statement in your recipe discussion, not overlooking it.', 'title': u'RE: Not really "handling" but close..'}, {'comment': u'Move the posargs parsing out into the wrapper (as it does not need to be done more than once per "decorating"), use a generator display instead of a list comprehension (notice I skipped the [] within tuple()) and use shortchanging or instead of if/then. Also call f correctly with positional and keyword arguments, which requires no if/then either.\n<pre>\ndef ExpHandler(*posargs):\n """exception handling decorator"""\n def wrapper(f):\n t = tuple(item for item in posargs[0]\n if issubclass(item,Exception)) or (Exception,)\n def newfunc(*pargs, **kwargs):\n try: \n f(*pargs, **kwargs)\n except t, e:\n # Only inform the user that the exception occured\n print e.__class__.__name__,\':\',e\n return newfunc\n return wrapper\n</pre>', 'title': u'Even better:'}, {'comment': u'The logic of the code remains same here, however partial is used here and default Exception class is added when no input is given. I have also made some modifications in the way handlers and exception classes are passed to the decorator. \n<pre>\n#!/usr/bin/env python2.5\n\nimport functools\ndef ExpHandler(*pargs):\n """ An exception handling idiom using decorators"""\n\n def wrapper(f):\n if pargs:\n (handler,li) = pargs\n t = [(ex, handler)\n for ex in li ]\n t.reverse()\n else:\n t = [(Exception,None)]\n\n def newfunc(t,*args, **kwargs):\n ex, handler = t[0]\n\n try:\n if len(t) == 1:\n f(*args, **kwargs)\n else:\n newfunc(t[1:],*args,**kwargs)\n except ex,e:\n if handler:\n handler(e)\n else:\n print e.__class__.__name__, \':\', e\n\n return functools.partial(newfunc,t)\n return wrapper\ndef myhandler(e):\n print \'Caught exception!\', e\n\n# Examples\n# Specify exceptions in order, first one is handled first\n# last one last.\n\n@ExpHandler(myhandler,(ZeroDivisionError,))\n@ExpHandler(None,(AttributeError, ValueError))\ndef f1():\n 1/0\n\n@ExpHandler()\ndef f3(*pargs):\n l = pargs\n return l.index(10)\n\nif __name__=="__main__":\n f1()\n f3()\n</pre>', 'title': u'rewritten using functools.partial '}], 'desc': u'A basic exception handling idiom using decorators which allows you to \nre-use the exception handler for different functions, while customizing your\nhandlers using arguments passed to an exception handling "decorator".'}, {'comments': [{'comment': u'This is much simpler with a generator:<pre>\ndef grange(b, g, n):\n for i in xrange(n + 1):\n yield b + g**i\n</pre>', 'title': u'much simpler version using generators'}, {'comment': u'but the main goal is to work with iterable class, not to create a sequence. It`s a lot of other ways to do it\nSteven : and yours is the clear one, thank you!', 'title': u'that`a all right'}, {'comment': u'If you want to work with iterable classes, you should define __iter__ (and possibly next), not __getitem__. Use of __getitem__ in the iterator protocol is deprecated. Try something like:<pre>\nclass grange(object):\n def __init__(self, b, g, n):\n self._b = b\n self._g = g\n self._n = n\n self._i = -1\n def __iter__(self):\n return self\n def next(self):\n if self._i >= self._n:\n raise StopIteration\n self._i += 1\n return self._b + (self._g**self._i)\n</pre>or simply<pre>\nclass grange(object):\n def __init__(self, b, g, n):\n self._b = b\n self._g = g\n self._n = n\n def __iter__(self):\n for i in xrange(self._n + 1):\n yield self._b + self._g**i\n</pre>Of course, I would still just use the generator. ;)', 'title': u'__getitem__ in the iterator protocol is deprecated'}, {'comment': u'i`ve just read http://www.python.org/doc/2.4.1/ref/sequence-types.html there`s nothing said`bout deprecated __getitem___', 'title': u'deprecated???'}], 'desc': u' '}, {'comments': [{'comment': u"This is a very cool hack. Quite a number of times, I have resorted to the Google cache when a web site is off line, and I need a critical bit of information. This proxy makes such web browsing easy.<br><br>\n\nHowever, I have a number of web services I use for development running on my system. Of course, port 8000 is among the first to go. The following modifications allow you to specify a the port you wish to run the proxy server on. Here I run it on port 9080. \n\n<pre>\ndef test(port = 8000, \n HandlerClass = googleCacheHandler,\n ServerClass = BaseHTTPServer.HTTPServer):\n ServerAddress = ('', port)\n httpd = ServerClass(ServerAddress, HandlerClass)\n httpd.serve_forever()\n\nif __name__ == '__main__':\n port = 9080\n test(port)\n<pre></pre></pre>", 'title': u'Set your own port'}], 'desc': u'This is a simple implementation of a proxy server that fetches web pages\nfrom the google cache. It allows you to view the internet through the eyes of google ! Fire it up and point your browser at localhost:8000'}, {'comments': [{'comment': u'The consistancy (and efficiency in some cases) of your version is lacking. The below fixes those cases.<br>\n\n<pre>\n def readlines(self):\n """ Line iterator """\n return iter(self._fw)\n \n def readwords(self):\n """ Word iterator. Newlines are omitted """\n \n # \'Words\' are defined as those things\n # separated by whitespace.\n for line in self._fw:\n for w in line.split():\n yield w\n\n def readchars(self, linebuff=True):\n """ Character iterator """\n\n # By default, handle a line-at-a-time, like\n # everything else in this class does, otherwise\n # only byte-at-a-time.\n\n if linebuff:\n for line in self._fw:\n for ch in line:\n yield ch\n else:\n fr = self._fw.read\n a = 1\n while a:\n a = fr(1)\n if a:\n yield a\n</pre>', 'title': u'Better versions...'}, {'comment': u"Why not add wspacere as a class member, so that the regex isn't recompiled each method invocation?\nOr does python optimize that?\n", 'title': u'readwords'}, {'comment': u"1. If self.__dict__ contains name, __getattr__ won't get called\n<br>\n2. If the named attribute is not found, you MUST raise AttributeError.\n<br><br>\nThis version addresses both issues:\n\n<pre>\n def __getattr__(self, name):\n return getattr(self._fw, name)\n</pre>", 'title': u'bogus __getattr__'}, {'comment': u'Given that file object is its own iterator, and iter(f) returns f (unless f is closed), plus the fact that a file object iterator\'s next() method returns the next input line, all means that the readlines() method can be simplified a litte bit further, to just:<br>\n<pre>\n def readlines(self):\n """ Line iterator """\n return self._fw</pre>', 'title': u'Re: Better versions...'}, {'comment': u"SOME SUBTLETIES NOTED:<br>\n<br>\nThe behavior of the readlines() method of this file-object proxy/iterator class differs from the one with the same name in a standard file object, which reads until EOF and returns a list containing all the lines thus read.<br>\n<br>\nSince the class effectively hides the conventional method in the wrapped file-object, it's not -- pedantically -- a true proxy class...", 'title': u'readlines'}, {'comment': u"On further reflection, the best and simplest thing to do would be to just leave out the FileIterator class's readlines() method. It doesn't add any desired functionality and leaving it out will allow/cause the underlying file's readline to be used (given the definition of the __getattr__() method). <br>\n<br>\nDoing this will also make the class a true proxy class (see my other earlier comment about subletites below).", 'title': u'Re: Re: Better versions...'}], 'desc': u'This recipe presents a general purpose file object iterator cum file object proxy class.\nIt provides a class that gives several iterator functions to read a text file by characters,\nwords, lines, paragraphs or blocks. It also acts as a proxy for the wrapped file object.'}, {'comments': [], 'desc': u'This recipe presents a general purpose file object iterator cum file object proxy class.\nIt provides a class that gives several iterator functions to read a text file by characters,\nwords, lines, paragraphs or blocks. It also acts as a proxy for the wrapped file object.'}, {'comments': [{'comment': u'So...data gets broken up into pieces over a socket. This is a known issue with sockets, and usually happens when you are trying to send something larger than ethernet frames or the buffer size of your TCP/IP stack. Sometimes bits of data are also concatenated.<br><br>\n\nPeople who really care about getting their data, generally use protocols which are precise about where certain kinds of data separate themselves. Whether this be that you prefix your data with the amount of data that is going to be sent, or you use some sort of data terminator. Both of these cases are handled properly by the asynchat module, which is a better start than raw sockets.', 'title': u'And? Why bother making this into a recipe?'}, {'comment': u"The issue isn't that data is broken up, in fact I have another recipe the talks exactly what you talk about. Perhaps I emphasized that point too much. Using this method may help avoid having to write the code you (and I) talked about with a prefix or some such to say when you are done. (though you of course need to be aware that python can do an implicit close on your socket object)\n\nThis primary issue is how you shutdown sockets. Because it is bi-directional communication, closing and sending data at the same time can can result in subtle bugs. So, it is important to know about how you can be explicit, since I do not see any talk of it in the python books I have.\n\nIf you want to talk about it off this site you can send me email at pyguy2@yahoo.com. It is obvious I should probably elaborate more on the issues in this recipe when I get time.", 'title': u'good socket practice'}, {'comment': u'Everything you say assumes that the socket will be "shutdown" or something equivalent. The only time such things happen is if one builds it into the protocol. Real socket connections that fail randomly don\'t get shutdown(), and causes errors that your code isn\'t even addressing.<br><br>\n\nAs I said before, one could use asyncore (and/or asynchat) and overload handle_error(), which handles all of the crap, and lets you implement your protocol (if you take the proper cues from other available modules). Part of one\'s protocol could be to send an empty \'packet\' (when using a length/data pair, the length would be 0), which could signal a shutdown/close/whatever. Alternatively, Twisted includes features that make handling errors and implementing arbitrary protocols easier than raw sockets (I tend to prefer asyncore, because it comes with Python, and it fits the way my brain works).', 'title': u' '}, {'comment': u'Yes, asyncore is good and I have used it before. I have also played with twisted. I too prefer asyncore since, mainly because I can assume it is present.\n\nThe point of the recipe is to show why one may want to use shutdown since almost no one talks about it. With standard close, since the client closes the socket and finishes up sending, the server cannot tell the client that something is wrong. (For example, if the end marker is wrong, or the byte count is wrong). \n\nDid you see my example with the broken server? \nIf a bug forces the client to exit and python calls close() automatically on the socket, the server would know something is wrong since it always gets the last word.\n\nIf the client screws up and ends the discussion incorrectly but still calls shutdown. In this case the client is leaving the communication channel open so the server can tell the client something is wrong, since the socket is gone.\n ', 'title': u'I am still missing the point (did you look at the changes in my code)'}, {'comment': u'Using socket.shutdown(0/1/2) is no better at communicating the fact that the client no longer wants to send any more data than an explicit protocol saying the same. In fact, in the absense of a protocol saying that the client /will/ shutdown their sending portion of the socket (the server\'s recieving portion) when a request is finished, the server generally /will/ close the connection, thinking that the client disconnected.<br><br>\n\nWhat do I mean?<br>\n<pre>\n>>> import socket\n>>> import threading\n>>> import select\n>>> def l():\n... global incoming, addr\n... a = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n... a.bind((\'localhost\', 9999))\n... a.listen(1)\n... incoming, addr = a.accept()\n... a.close()\n... print addr\n...\n>>> def c():\n... global outgoing\n... a = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n... a.connect((\'localhost\', 9999))\n... outgoing = a\n... print "connected"\n...\n>>> threading.Thread(target=l).start()\n>>> c()\nconnected\n>>> (\'127.0.0.1\', 2202)\n\n>>> outgoing.send(\'hello\')\n5\n>>> outgoing.shutdown(1)\n>>> incoming.recv(5)\n\'hello\'\n>>> select.select([incoming.fileno()], [], [], 0)\n([656], [], [])\n</pre>\n\nNow, that incoming socket, which select just said was readable, has no data waiting. According to asyncore, twisted, and every other asynchronous package I\'ve seen, when a socket is readable(), but has no data waiting, then the remote machine has disconnected. So /any/ server written using such a semantic will do a socket.close(), and the client, which thought it was doing a good thing by using shutdown() to signal to the server that "no more information is coming your way", actually killed itself.', 'title': u'shutdown() and select()'}, {'comment': u"With a socket.close the client assumes that it does not matter how the server reacts to it's last bit of data (when the data arrives successfully).\n\nIf all you had available to you was close(), you then _force_ all clients to have to assume that it never matters how the server reacts to the final bit of data.\n\nSure, asyncore does not take advantage of a client doing a shutdown(1). But that does not mean a shutdown is not useful.", 'title': u'if all you have is close, you force _all_ clients to assume'}, {'comment': u'I should respond more directly, when you say the client "killed itself" when it thought it was doing a good thing. The client was in fact irrevocably _done_ sending. So, what happned wasn\'t a bad thing. The sever just didn\'t care to send anything back, the sever didn\'t care that the socket was left open for it.\n\nIf all you have is close() then the client is forced to assume that it does not matter how the sever reacts the the final bit of data that arrives successfully. Sometimes that is an ok assumption to make, but when it is not you need shutdown semantics or the client will have to start up another socket connection to find out how the sever reacted to the last thing it sent.\n\nHow can a higher level protocol fix that?', 'title': u"the client still a good thing the sever just didn't care"}, {'comment': u'I\'ll just answer your final question...\n<pre>\nSometimes that is an ok assumption to make, but when it is not you need\nshutdown semantics or the client will have to start up another socket\nconnection to find out how the sever reacted to the last thing it sent.\nHow can a higher level protocol fix that?\n</pre>\nEasy, the client should never use shutdown. When the client gets a response to the last request it wants to make, it can just close its socket and be on its way. Heck, if it wants to make another request, and the connection is still open, it can! Amazing how it works. After the client has closed its connection (because it has all the requests and responses it wants), the server gets a \'readable without data\' on the socket, and closes its end, as it should. That\'s how everyone writes socket clients and servers (though some have explicit "close the connection" requests or "closing the connection" responses). Don\'t change semantics just to change semantics when the current semantic runs most (if not all) of the TCP/IP backed protocols on the internet.', 'title': u' '}, {'comment': u'<pre>"the server cannot know whether the client is done sending."</pre>\n\nIn standard socket semantics, if the client closes the connection completely then the server knows that the client doesn\'t want to send (or receive) anything more.\n\n<pre>"What if the byte count is wrong"</pre>\n\nThen you implemented your protocol incorrectly, or the connection hung.\n\n<pre>"With a socket.close() the server cannot tell the client, \'\'Strange.\nYou are done sending data to me, but I didn\'t get all the data\'\',\nsince the client connection is not left open after the client is done\nsending."</pre>\n\nThat\'s why you leave the socket completely open until the server has told the client, "I got your request". If you also include checksums and timeouts in your protocol, then responses like "your request timed out" or "your request is malformed", can be sent to the client.<br><br>\n\nNote that in the case of the client using sock.shutdown(), there is actually data sent to the server, signaling that the connection has been shutdown in that particular way. If that data gets to the server, then so does any data that the client sent earlier, because of that whole "packets arrive in-order" thing. Now, here\'s the crucial bit; if the data didn\'t make it there, then neither does the shutdown notification. The server just notices that the socket is no longer readable. Without timeouts (on either the client or server end), the server will happily wait until TCP/IP times out the connection (which can be on the order of 5 minutes for some stacks, from http://www.netbook.cs.purdue.edu/othrpags/qanda219.htm ).\n\n<pre>"With a socket.shutdown(1) the client can still be told by the server\nthat something was wrong and take appropriate measures."</pre>\n\nWith no socket.shutdown(), the client can still be told by the server that everything was fine or something was wrong, and take appropriate measures to report success, resend the request, report failure to the user, etc.<br><br><br>\n\n\nWhat you seem to be missing is that there are more robust features of higher level protocols that handle "the client is done with requests", as well as the various error conditions that can arise; error conditions that can make socket.shutdown() ambiguous to the server.', 'title': u' '}], 'desc': u'I have implemented a "broken" client/server to show how socket.shutdown can be more useful than a simple socket.close operation. (I rewrote this to hopefully be more clear)\n\nThe close operation is not atomic. It implicitly tries to send any remaining data in _addition_ to closing a descriptor. Splitting this close operation up with the aid of the shutdown command can help avoid bugs. It gives the server one final way to say, "something went wrong". The server would also know that the client did not end correctly, since the socket should remain open when the client finished sending data. For example, if the function exits unexpectedly and python closes the socket for you, the server would not be able to send any data back.\n\nIn the server below, the client and server have different ideas about what the end marker should be. The rev_end function is written so as to look for an end marker. And, as long as they agree it should work. The socket.shutdown is for when something goes wrong.'}, {'comments': [], 'desc': u'My first recipe here, it uses __getattr__ to modify the error messages given when a wrong class method is called. It shows the first five ranked most similar method names, followed by the first line of their docstrings (this is useful to see their parameters, if you use this convention in your sources), and then it raises an AttributeError. Useful from the interactive shell too.'}, {'comments': [{'comment': u"And you've downloaded subprocess from effbot, then you should add this line somewhere:\nsubprocess.STARTF_USESHOWWINDOW = 1", 'title': u"If it doesn't work for you"}], 'desc': u'On the MS Windows platform, if you launch a subprocess from within a non-console process a console window appears. \n\nThis recipe shows how to avoid this by using the python 2.4 library module subprocess.py'}, {'comments': [{'comment': u'<pre>\nI tried to run this out of the box and was not able to get it to fire.\n\nHere\'s the trace I got.\n\nTraceback (most recent call last):\n File "zodbviewer.py", line 330, in ?\n frmZODB = ZODBFrame(None, -1, "")\n File "zodbviewer.py", line 102, in __init__\n self.__create_file_history()\n File "zodbviewer.py", line 112, in __create_file_history\n old_path = self.wxcfg.GetPath()\nAttributeError: \'ZODBFrame\' object has no attribute \'wxcfg\'\n\nBy commenting out line #105\n\n...\nself.__create_file_history()\n...\n\nI was able to run it okay. I did have to force it closed.\n</pre>', 'title': u'Great contribution! Slight startup error.'}, {'comment': u'I had the same issue. I added self.wxcfg = wx.Config() to __init__(), and was able to use it.\n<p></p>\nAlso, a few things to note: \n\nThis uses the latest persistent.Persistent from Zope3 instead of the old Persistence.Persistent. \n\nYou will need to import your Persistent subclasses (the ones you defined in which to store your data) in order for them to be "opened" in the tree by this script.', 'title': u'Similar issue, different solution'}, {'comment': u"I've hacked in ZEO support -- was pretty straight forward. Added a new menu item, did an import of ZEO.ClientStorage, added a few checks, etc. Very cool, very useful little tool -- thanks for sharing!", 'title': u'ZEO Support'}, {'comment': u'Hi Duncan,\n\nwould be nice to see your zeo-addon as a recontribution :)\n\nis this possible?\n\nthanks\nPeter', 'title': u'Would you share your ZEO addon?'}, {'comment': u'Sure... let me find it...\n\nOkay, you\'ll need this import:\n\n<pre>\nfrom ZEO import ClientStorage\n</pre>\n\nI then modified the open_zodb() function:\n<pre>\ndef open_zodb(Path, zeo=False):\n """Open ZODB.\n\n Returns a tuple consisting of:(root,connection,db,storage)\n The same tuple must be passed to close_zodb() in order to close the DB.\n """\n # Connect to DB\n if zeo:\n server = Path.split(\':\')\n server[1] = int(server[1])\n storage = ClientStorage.ClientStorage(tuple(server))\n else:\n storage = FileStorage.FileStorage(Path)\n db = DB(storage)\n connection = db.open()\n root = connection.root()\n return (root,connection,db,storage)\n</pre>\n\nTo ZODBFrame.__init__(), I added this:\n<pre>\n self.mnuFile.AppendItem(self.mnuOpen)\n + self.mnuOpenZEO = wx.MenuItem(self.mnuFile, wx.ID_OK, "&Open ZEO Instance...\\tCtrl-U",\n "", wx.ITEM_NORMAL)\n + self.mnuFile.AppendItem(self.mnuOpenZEO)\n</pre>\n\nI modified ZODBFrame.creatTree() to include this:\n\n<pre>\n def createTree(self, filename=\'\', server=\'\', zeo=False):\n """Create a new tree structure for when we open a file"""\n self.doClose()\n\n if zeo:\n self.db = open_zodb(server, zeo=True)\n self.root = self.db_layout_tree.AddRoot(server)\n else:\n self.db = open_zodb(filename)\n self.root = self.db_layout_tree.AddRoot(os.path.basename(filename))\n</pre>\n\nAnd, finally, I added this method:\n<pre>\n def doOpenUrl(self, *event):\n """Access a ZEO instance from a url"""\n dlg = wx.TextEntryDialog(self, message="Enter the server and port for the ZEO instance (hostname_or_ip:port)")\n if dlg.ShowModal() == wx.ID_OK:\n self.createTree(zeo=True, server=dlg.GetValue())\n dlg.Destroy()\n</pre>\n\nI may have midded something... and this was done against the first version of the recipe...', 'title': u'ZEO Hack'}, {'comment': u'It is a great program. I think, there should be a line in the _set_binding() method:\n<br>self.Bind(wx, EVT_MENU, self.doOpenUrl, id=wx.ID_OK', 'title': u'I think, there should be another line'}, {'comment': u'Please do me a favor. I am looking for a python script that can export wiki contents which is stored in ZODB to MYSQL.\n\nThanks', 'title': u'Exporting wiki contents from ZODB to MYSQL'}], 'desc': u'This is a very simple script to allow someone to examine a ZODB database. Start the script and you can see what is in your ZODB file as well as the overall structure.'}, {'comments': [], 'desc': u'You need to access socket, serial ports, or other asynchronous but blocking I/O sources while running a GUI with pygtk.\n\nThe cookbook already gives example suited for Tkinker and PyQt.\n\nHere is an attempt to do the same with pygtk based on the Tkinker and PyQt example.'}, {'comments': [], 'desc': u'Java programs use extensively "inner" (or nested) classes. There are actually four kinds of such classes (http://www.unix.org.ua/orelly/java-ent/jnut/ch03_08.htm), namely static and non-static member classes, local classes and anonymous inner classes. Python supports directly the last two through classes defined in nested scopes and lambdas. This recipe implements the first two kinds, static and non-static member classes.\n\nA non-static member class is associated with an instance of the outer class and has implicit access to its __dict__. Thus, if the normal attribute lookup fails for an instance of the inner class, it continues to the outer instance.\n\nSimilarly, a static member class is associated with the outer class, instead of a specific instance of the outer class.\n\nIn both cases, the outer object (instance or class) can be explicitly accessed though the \'__outer__\' attribute.'}, {'comments': [{'comment': u'Very useful, but ...\n<br>\n<br>\nThere is a similar module in development within the python cvs tree: \npython/nondist/sandbox/statistics/statistics.py\n<br>\n<br>\nThere is also a nice stats module at http://www.nmr.mgh.harvard.edu/Neural_Systems_Group/gary/python.html\n<br>\n<br>\nSciPy (http://www.scipy.org) also has some statistics-related functions:\nhttp://www.scipy.org/documentation/apidocs/scipy/scipy.stats.html', 'title': u'Preexisting solutions'}, {'comment': u"You use x both as loop variable and summation variable, so that the result is bogus. E.g. Statistics([-1, -1]) gives a negative variance (and thus an exception from sqrt).<br><br>\n\nAlso, computing the mode is more complicated than necessary: why not use\n<pre>\nmode = max(frequency.values())\n</pre>\n\n(Converting to a set does not save anything; one must touch all the elements of the list anyway, so it's O(n). And even if one wants to do list(set(lst)) first, max(lst) is faster than sorted(lst)[-1] or\nsorted(lst, reverse=True)[0].)\n", 'title': u'Bug in variance computation'}, {'comment': u'Thanks for pointing out the summation oversight and mode computation\nimprovement. Modifications have been merged.', 'title': u'Mode and variance'}], 'desc': u'A Python module implementing a class which can be used for computing\nnumerical statistics for a given data set.'}, {'comments': [], 'desc': u"[co-authored with Philip E. Nu\xf1ez]\n\nPython's stdlib does not have any included library for supporting ICMP packets; both reading them or creating them. But ICMP packets are common and useful; they are used for both the traceroute and ping utilities. And thus they can be useful to control to do network diagnostics.\n\nThe Packet class is what is used to create and read ICMP packets. To create a packet you instantiate the class, set the header and data fields, and then call the create() method which will the string representation that can be passed to a socket.\n\nTo read a packet, use the Packet.parse() classmethod, which will return an instance of Packet with the fields filled out.\n\nTo show its use you can also see the ping() method that is included. Just use the code as a script and pass in an address to ping. Response time is printed to stdout.\n\nOne word of warning, though, when using this module. Raw sockets tend to require root permissions on the process. Thus you might need to use sudo to execute the Python interpreter to make this all work. ping() does drop sudo permissions as soon as it can, though, for security reasons."}, {'comments': [{'comment': u'<pre>\n>>> from itertools import groupby\n>>> list(k for k,g in groupby([1,1,1,2,3,3]))\n[1, 2, 3]\n</pre>', 'title': u'Remove duplicates from sorted data with itertools.groupby'}, {'comment': u'in usage I would do\n[i for i,j in pairwise([1,1,1,2,3,3]) if i!=j or j==None]\n\ninstead of \n\n[i for i,j in pairwise([1,1,1,2,3,3]) if j==None or i!=j],\n\nputting the common case first. It is both faster due to shortcut eval, and slightly clearer - I usually THINK of the common case first. \nOf course groupby looks even more powerful, thatnks Raymond for pointing it out.', 'title': u'small nit'}, {'comment': u"If you just want to look ahead, consider one of the 'peek' recipes:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373<br>\nIf you really do want to view your items pairwise, I'd suggest a solution that works with any iterable instead of just sequences:\n<pre>\ndef pairwise(itr):\n first, second = itertools.tee(itr)\n second.next() # remove first element of second\n second = itertools.chain(second, [None]) # add final None\n return itertools.izip(first, second)\n</pre>", 'title': u' '}], 'desc': u'Iteration is a fundamental Python idiom. It is simple and effective.\n\nfor n in iterable:\n # do something with n\n\nBut there are also cases when you might want to look ahead one item during iteration. For example, with a sorted list, one can eliminate duplicated items by dropping those equals to the next item. This generator based recipe that enumerate an item and its next in a list. For example,\n\n>>> for i,j in pairwise([1,2,3]): print i,j\n...\n1 2\n2 3\n3 None'}, {'comments': [{'comment': u"I've also written one that handles lists:\n<br><br>\n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410469", 'title': u'Another alternative...'}, {'comment': u'pardon my remark but your code, confronted to newsml doesn\'t work well with repeated tags with properties.\nexample extracted from busineswire NewsML press release system :\n<pre><test>\n <Metadata>\n <MetadataType FormalName="BWKeywords"/>\n <Property FormalName="BWCountryKeywords" Value="United States"/>\n <Property FormalName="BWIndustryKeywords" Value="Technology"/>\n <Property FormalName="BWRegionKeywords" Value="North America"/>\n <Property FormalName="BWIndustryKeywords" Value="Hardware"/>\n <Property FormalName="BWIndustryKeywords" Value="Networks"/>\n <Property FormalName="BWIndustryKeywords" Value="Software"/>\n <Property FormalName="BWStateKeywords" Value="California"/>\n <Property FormalName="BWCategoryKeywords" Value="Personnel"/>\n </Metadata>\n</test></pre>\nAdding a few tests, here and there i succeeded to produce a more interesting ouput, but not yet what i expected and probably bad pythonic writing.\n\n<pre>from elementtree import ElementTree\n#import cElementTree as ElementTree\n\nclass XmlListConfig(list):\n def __init__(self, aList):\n for element in aList:\n childs = element.getchildren()\n if childs:\n # treat like dict\n tagslist=[]\n for c in childs :\n if not (c.tag in tagslist) :\n tagslist.append(c.tag)\n if len(childs) == 1 or len(childs)==len(tagslist):\n self.append(XmlDictConfig(element))\n # treat like list\n else:\n self.append(XmlListConfig(element))\n else:\n #ajout de la gestion des tags\n if element.items():\n self.append({element.tag:dict(element.items())})\n if element.text :\n self.append({element.tag:element.text})\n\n\nclass XmlDictConfig(dict):\n \'\'\'\n Example usage:\n\n >>> tree = ElementTree.parse(\'your_file.xml\')\n >>> root = tree.getroot()\n >>> xmldict = XmlDictConfig(root)\n\n Or, if you want to use an XML string:\n\n >>> root = ElementTree.XML(xml_string)\n >>> xmldict = XmlDictConfig(root)\n\n And then use xmldict for what it is... a dict.\n \'\'\'\n def __init__(self, parent_element):\n if parent_element.items():\n self.update(dict(parent_element.items()))\n for element in parent_element:\n childs = element.getchildren()\n if childs:\n # treat like dict - we assume that if the first two tags\n # in a series are different, then they are all different.\n tagslist=[]\n for c in childs :\n if not (c.tag in tagslist) :\n tagslist.append(c.tag)\n if len(childs) == 1 or len(childs)==len(tagslist):\n aDict = XmlDictConfig(element)\n # if the tag has attributes, add those to the dict\n if element.items():\n aDict.update(dict(element.items()))\n # treat like list - we assume that if the first two tags\n # in a series are the same, then the rest are the same.\n else:\n # here, we put the list in dictionary; the key is the\n # tag name the list elements all share in common, and\n # the value is the list itself \n aDict = XmlListConfig(element)\n # if the tag has attributes, add those to the list\n if element.items():\n aDict.append(element.items())\n self.update({element.tag: aDict})\n # this assumes that if you\'ve got an attribute in a tag,\n # you won\'t be having any text. This may or may not be a \n # good idea -- time will tell. It works for the way we are\n # currently doing XML configu', 'title': u'Interesting but incomplete'}, {'comment': u"i switched page with http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410469.\nI also tried you method but had problem with tags that don't have text like in the example above", 'title': u'sorry for my displaced comment'}], 'desc': u'Reads an xml file into a python dictionary of dictionaries (repeated elements are read in as lists).\nModified from xmlreader.py by Christoph Dietze - differs in not needing repeated elements to be tagged in the xml file.'}, {'comments': [], 'desc': u'The doctester extracts code from stdin and tests it using the doctest module in\nthe standard library. It can be invoked from the command line, but it is\nbest called from you editor of choice. I just give an example for Emacs.'}, {'comments': [{'comment': u"It's a nice recipe. Your algorithm for getting nice sounding words\nwith random characters is to alternate between consonants and vowels\n(all the if i%2 == 0 statements). With this, you cannot get your\nexample password 'nice137pass' but something like 'nice137pace'.\nYou can also add 'y' to your vowel list to get some more pronounceable\nphrases.\n\n--Hemanth P.S.", 'title': u'Nice sounding algorithm'}, {'comment': u'http://www.adel.nursat.kz/apg/', 'title': u'This is similar'}], 'desc': u"Password will be generated in the form 'word'+digits+'word' eg.,nice137pace \ninstead of a difficult-to-remember - K8Yn9muL"}, {'comments': [], 'desc': u'This simple program can be used to compute and display a 2D fractal tree. '}, {'comments': [], 'desc': u'A very-very simple dice game:\ntwo persons("You" and "CPU") are dropping dices.\nIf someone scores 17 during dropping dices, he wins.\nAny doubts are interpreted to a humans` side.\n(i`m too lasy to add draw here)\nAnd one more. Rules say- "if someone drops 3 same dices at the beginning, he wins."\nthis is not realized in game, too. (but the probability of this is just about 1.4%)\n'}, {'comments': [], 'desc': u"I use this for configuration. I hadn't intended to put it up anywhere, but there have been a couple discussions lately about converting XML to python dicts, so I feel obligated to share another approach, one that is based on Fredrik Lundh's ElementTree."}, {'comments': [], 'desc': u'This is a program in Jython to view a web images, basen in a anterior recipe '}, {'comments': [{'comment': u"Of course, this is just about the slowest possible way to do it for ascii/rtf/postscript because Mac OS X comes with pbcopy(1) and pbpaste(1), which don't have the overhead of starting a Python interpreter, etc.", 'title': u' '}, {'comment': u'Thanks for spoiling the fun. No, just kidding, thanks for pointing those out. Added some improvements/corrections anyway.', 'title': u'Indeed'}], 'desc': u'This is a clipboard manipulation module that demonstrates some simple use of Carbon API. It can double as a Unix-style command-line tool that prints the clipboard contents to stdout or, if specified, copies its stdin to the clipboard, although pbcopy(1) and pbpaste(1) are better suited for that.'}, {'comments': [], 'desc': u'This is a simple modal listbox class. It is intended to be invoked about like this: results = ListBoxChoice(root, list=listOfItems).returnValue().\n\nIt will return the list item selected. It will take any item in the list that can return a textual indicator.'}, {'comments': [{'comment': u"Try this with some large numbers (say 1000+ digits). For numbers of this magnitude, a probabilistic test such as Miller-Rabin is generally preferable. 30 rounds of Miller-Rabin can determine the primaility of any number with probability of error less than 1 in 10**18. I'd be willing to guess the probability of the computer having a random malfunction is higher.", 'title': u'Highly inefficient'}, {'comment': u'This recipe involves the construction of the list of primes This recipe involves the construction of the list of primes ', 'title': u'Further note on memory consumption'}, {'comment': u'This recipe involves the construction of the list of primes <= sqrt (aNumber). There are 50,847,534 prime numbers < 10 ** 9. Assuming 32 bits of storage for each, that would be nearly 194 megs of RAM simply to do a primality test on a 9 digit integer: clearly unacceptable.', 'title': u'Memory consumption redux -- with correct formatting!'}, {'comment': u"Hi Paul, thanks for your feedback.<br>\nYes the algorithm is slower than a direct trial-and-error, and substituting the prime list with calls to a sieve prime number generator, like the Recipe 117119, does not improve the situation: the result it's three time slower in my little experiments.\n<br>\nOnly a remark about memory consumption: len(primes(int(math.sqrt(10**9+1)))) gives me 3401, it didn't take so much memory to handle such a list ;-)", 'title': u'inefficient, but not so memory hungry'}, {'comment': u'Yeah, slight miscalculation. I forgot to take into account the sqrt operation. :P This recipe will take >194 megs to do a primality test on an 81 digit integer, not a 9 digit.', 'title': u'Oops.'}, {'comment': u'Make that 18 digit integer, not 81. :-) It seems I temporarily forgot the rules of exponentiation. (Not so good, since I am a grad student in math. ;)', 'title': u'Dyslexia? Nah. :P'}, {'comment': u'I got bored and posted a version of the Rabin-Miller test of primality that I wrote a few months back, it includes a "generate a prime number of b bits (with confidence parameter)" function.<br><br>\n\nEnjoy!<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410681', 'title': u'You want Rabin-Miller? You got it!'}], 'desc': u'Since the excellent <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/366178">fast prime number list generator</a> recipe, it\'s simple to implement a function to check if its input it\'s a prime number.'}, {'comments': [], 'desc': u'primepow(aNumber) finds the prime number P and power N of aNumber such that aNumber = P^N.\n\nThe implementation is heavily borrowed from Art Owen <a href="http://www.csit.fsu.edu/~burkardt/cpp_src/oa/oa.html">Orthogonal Arrays Library</a>. It requires the <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410662">isprime()</a> function. '}, {'comments': [{'comment': u"Honestly, I have no plan to use this recipe. But the trick is very educative to me. Sure I'll visit this recipe again in the future.\n\nBTW, I wonder if stack-related functions in the module inspect can make it even simpler. Just like how the zope.interface.implements works. Can we avoid all parameters to the function at all ? Wish someone give me an insight", 'title': u'Can stack inspection make it simpler ?'}, {'comment': u'What\'s wrong with this solution:\n\n<pre>\n class FooBar:\n def __init__(self, a,b,c,d,e,f,g,h, i=100, j=100):\n self.__dict__.update(locals())\n</pre>\n\nIt has the advantage of NOT requiring any strange playing about with func_code and co_varnames. It\'s a trivial one-liner. It doesn\'t require creating a "setargstoself" function that needs to be imported (or repeated in every module). The only disadvantage is that it sets "self" to, well, self. If this is too painful, you can use a second line to delete that (but why bother... Python\'s GC can handle reference loops quite easily these days).', 'title': u"What's wrong with the simple approach?"}, {'comment': u'...but does it cut against the "explicit is better than implicit" ethic of python?<br>\nMaybe it\'s a C++-ism, but I actually like to lay out all those crazy variables in the __init__, and document them...', 'title': u'Educational, yes...'}, {'comment': u'I think it a great recipe because it can be used to debug how a __init__ method is called.', 'title': u'Debugging'}, {'comment': u"<pre>\nclass Foo:\n def __init__(self, a, b, c, spamm=True, eggs=False):\n [setattr(self, a, v) for a,v in locals.items() if a != 'self']\n</pre>", 'title': u'Another variant'}, {'comment': u"Sorry, the code from the above comment had a typo and would have introduced also another variable into the namespace (from the unassigned return value of the list comprehension).<br>\n<br>\nSo, baby, one more time:<br>\n<pre>\nclass Foo:\n def __init__(self, a, b, c, spamm=True, eggs=False):\n for a,v in locals().items():\n if a != 'self':\n setattr(self, a, v)\n</pre>", 'title': u'arrrgh!'}], 'desc': u"I have found it tedious to, when passing many variables to a class's constructor, assigning them all to self. This is a method to assign them automatically. It works with default arguments as well."}, {'comments': [], 'desc': u'This decorator simply sets the function as the signal handler for the signal given as its argument.'}, {'comments': [{'comment': u'http://bob.pythonmac.org/archives/2005/04/17/twisted-and-foreign-event-loops/', 'title': u"Also check out Bob's solution"}, {'comment': u"Thanks for the link.\n\nI'm still using Twisted 1.3.0 at the moment so I'll need to continue to use the recipe as-is.\n\nWhen I migrate to Twisted 2.x I'll be sure to post a new recipe that uses the approach that Bob advocates.", 'title': u'great info'}], 'desc': u'Runs the Twisted reactor event loop in a thread alongside an IPython shell, for introspecting a running Twisted process.'}, {'comments': [{'comment': u'The problem with including vowels is that then your output can include natural-language words, and certain words can be offensive to certain people.<br>\n<br>\nMurphy\'s Law: when "fuk-u" shows up in one of your URLs, the wrong person is going to notice it.', 'title': u'You really want vowels in there?'}, {'comment': u'The thing I notice is that you\'re only converting in one direction.\nSomething like the code would be more useful if you ever want to use the base 70 number as a number. (for bases less than 37, int(n, base) is the simpler way to back-convert).\n\n<pre>\n\nINT_TO_DIGIT = [ x for x in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"\n "_abcdefghijklmnopqrstuvwxyz~!\'()*+"]\nDIGIT_TO_INT = dict([ (y, x) for x, y in enumerate(INT_TO_DIGIT) ]) \n\n\ndef convert(n, newbase=70, oldbase=10):\n nums = [ DIGIT_TO_INT[x] for x in str(n) ]\n nums.reverse()\n r = 1\n total = 0\n for x in nums:\n total += r * x\n r *= oldbase\n if total == 0:\n return \'0\'\n \n converted = []\n while total:\n total, remainder = divmod(total, newbase)\n converted.append(INT_TO_DIGIT[remainder])\n \n converted.reverse() \n return \'\'.join(converted)\n\n \nif __name__ == \'__main__\':\n \n numbers10 = (1, 256, 3, 34534, 20050427123456, 0, 453532)\n bases = (70, 16, 2, 7, 39)\n for n in numbers10:\n print "\\ndealing with %s" %n\n for base in bases:\n nbase = convert(n, base, 10)\n n10 = convert(nbase, 10, base)\n print "base %2s: %40s" % (base, nbase)\n assert (int(n10) == n)\n print "base 10: %40s" % n10\n\n</pre>', 'title': u'why not a two way process?'}, {'comment': u'I think you mean "raise TypeError, \'parameters must be numbers\'<br>"\nnot "raise TypeError, \'parameters bust be numbers\'"<br><br>\n\n-Anand', 'title': u'Spelling error'}, {'comment': u"You can accomplish something similar with the standard struct module and base64. Not quite as compact, and the numbers are padded, but it's fairly straight-forward. I have it at: http://svn.colorstudy.com/home/ianb/recipes/base64unpack.py ; but here's the raw code:\n\n<pre>\ndef pack_int(i):\n return struct.pack('i', i).encode('base64').replace('\\n', '').strip('=')\n\ndef unpack_int(s):\n s += '=' * (8 % len(s))\n return struct.unpack('i', s.decode('base64'))[0]\n</pre>", 'title': u'struct and base64'}, {'comment': u'I really like Ian\'s suggestion above. Very simple and elegant solution. We emailed briefly about this after I had done some testing. First, I made a minor change to his code above to allow for doubles (and thus much longer number sequences):\n\n<pre>\ndef pack_int(i):\n return struct.pack(\'d\', i).encode(\'base64\').replace(\'\\n\', \'\').strip(\'=\')\n</pre>\n\nBut after I made that change, I ran into some other issues. Given, these will most likely be edge cases, but interesting to note and be aware of nonetheless:\n\nPrecision is good here:\n<pre>\n>>> struct.pack(\'d\', 2**52).encode(\'base64\').strip().strip(\'=\')\n\'QzAAAAAAAAA\'\n>>> struct.pack(\'d\', 2**52+1).encode(\'base64\').strip().strip(\'=\')\n\'QzAAAAAAAAE\'\n</pre>\nBut increasing the power by one at this point results in a loss of precision:\n<pre>\n>>> struct.pack(\'d\', 2**53).encode(\'base64\').strip().strip(\'=\')\n\'Q0AAAAAAAAA\'\n>>> struct.pack(\'d\', 2**53+1).encode(\'base64\').strip().strip(\'=\')\n\'Q0AAAAAAAAA\'\n</pre>\n\nHere are a few examples of how this changes with numbers of increasing size (the numbers are test timestamps + "random" numbers):\n<pre>\n>>> struct.pack(\'d\', 20050817043010000).encode(\'base64\').strip().strip(\'=\')\n\'Q1HPByjThHQ\'\n>>> struct.pack(\'d\', 20050817043010001).encode(\'base64\').strip().strip(\'=\')\n\'Q1HPByjThHQ\'\n>>> struct.pack(\'d\', 20050817043010002).encode(\'base64\').strip().strip(\'=\')\n\'Q1HPByjThHQ\'\n>>> struct.pack(\'d\', 20050817043010003).encode(\'base64\').strip().strip(\'=\')\n\'Q1HPByjThHU\'\n</pre>\n\nI asked Ian about this, and he briefly touched on C and struct internals which I won\'t get into ;-) Something to keep in mind, though.', 'title': u'packing and base64'}, {'comment': u"I really like your convert logic. Much cleaner. I'll update the recipe with it at some point. However, your two-way doesn't do a full two-way:\n<br>\nUsing the order of your INT_TO_DIGIT list, 100 base70 would be the string '1U'; you conversion doesn't let you go from '1U' and reobtain 100. When I get some time, I'll look into that, just for kicks (I've never needed that functionality).\n<br><br>\nSome notes about INT_TO_DIGIT: 1) strings are already indexed iterables, so you don't need a list comprehension for it; and 2) it might be a good idea to list the strings in the notation in python sorting order, that way if someone sorted out a bunch of base70 strings, they would actually list in numerical order. Here they are in python sort order:\n<pre>\n!'()*-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~\n</pre>", 'title': u'Only part-way two-way...'}, {'comment': u"I'm hitting recursion limits. I suggest replacing:\n\n quotient, remainder = divmod(n, b)\n converted.append(remainder)\n if quotient != 0:\n converted.extend(self._convert(quotient, b))\n return converted\n\nwith:\n\n while True:\n quotient, remainder = divmod(n, b)\n converted.append(remainder) \n if quotient == 0:\n return converted\n n = quotient", 'title': u'Recursion is limiting'}], 'desc': u"For those times when '20050415115959' just takes up too much space. Useful for making your numbers shorter (like timestamps in URLs)."}, {'comments': [], 'desc': u'This recipe allows you to iterate over the children of an item in a wxTreeCtrl without having to fool around with GetFirstChild/GetNextChild/cookie boilerplate.'}, {'comments': [{'comment': u'Note that Miller-Rabin is actually a compositeness test more than a primality test. That is, it can only produce a certificate of compositeness for a given integer rather than a certificate of primality. The guarantee on Miller-Rabin is actually that if n is the input to the algorithm, at most 1/4 of the possible witnesses to the compositeness of n will be "liars." \n\nOf course, it\'s a mistake to say that n is "probably prime," since it\'s either prime or composite, but letting down our guard a bit on rigor, we can say that if n passes k trials of Miller-Rabin, it is prime with "probability" 1 - 1/4**k, rather than 1-1/2 ** k.', 'title': u'1-1/2**k ?'}, {'comment': u"I've updated the various portions to be more accurate. Thank you.", 'title': u' '}, {'comment': u'These statements are actually incorrect; in practise RM is actually much better, especially for larger bit sizes. See 4.4 on page 146 in the Handbook of Applied Cryptography, online at http://www.cacr.math.uwaterloo.ca/hac/', 'title': u'Probability of success'}, {'comment': u"I am a newby in Python but an expert on RM, and from the source I couldn't understand how the algorithm actually works. Or maybe it is a variation that I don't know. The algo I know writes N-1 as 2^u*v\nwith v odd, calculates w^v (modN) and squares this value u times to see if a -1 appears; if not w is a witness of compositeness.\nAccording to my Pythonbook pow(x,y,z) = pow(x,y)%z; I think that in combination with this algorithm it would be faster.", 'title': u'Implementation'}, {'comment': u'Successfully tested on this problem: http://spoj.sphere.pl/problems/PON/\n\n<pre>\n\nimport random\n\ndef powmod(x,a,m):\n r=1\n while a>0:\n if a%2==1: r=(r*x)%m\n a=a>>1; x=(x*x)%m\n return r\n\ndef isprime(p):\n q=p-1\n while q%2==0: q=q>>1\n for i in xrange(1,7): ## probability adjusted here\n a=2+long(random.random()*(p-2))\n if powmod(a,p-1,p)Successfully tested on this problem: http://spoj.sphere.pl/problems/PON/\n\n<pre>\n\nimport random\n\ndef powmod(x,a,m):\n r=1\n while a>0:\n if a%2==1: r=(r*x)%m\n a=a>>1; x=(x*x)%m\n return r\n\ndef isprime(p):\n q=p-1\n while q%2==0: q=q>>1\n for i in xrange(1,7): ## probability adjusted here\n a=2+long(random.random()*(p-2))\n if powmod(a,p-1,p)</pre></pre>', 'title': u'My own implementation of RM'}, {'comment': u"My prev. comment got doubled and cut.\nDue to... hmm... imo, due to a free nature of the site.\nThat's it... the free (incl. linux) just sucks.\nAnd those people derise at M$ software. Silly.\n\nPlz delete both these my comments.\n", 'title': u'Sorry...'}, {'comment': u'Comments cannot be deleted, and crapping on free software randomly, on a site that gives away free software, is pretty foolish.', 'title': u'...'}, {'comment': u'I implemented a variant of the Rabin Miller algorithm as provided in Algorithm Design by Goodrich and Tamassia, which is stated in the comment preceeding the content of the recipe.<br><br>\n\nAccording to tests I ran initially, repeated calls to pow(x,*,z) is slower than ipow(x,*,z) for certain large values of x, *, and z, because while ipow generates only those values necessary for the primality test, one ends up recalculating them with the pow solution, unless one uses pow instead of the multiplication/modulo that I use, but then you end up with function call overhead, which is slower than the standard mathematical operations.', 'title': u're: Implementation'}, {'comment': u"I went and read the page (and the few pages before and after), and from what I understand (which isn't a whole lot, given the minimal time at 2AM I spent reading), the probability of failure can be caluclated, and that the actual probability of failure tends to be far lower than (1/4)**t, (1/2)**(4.4*t) or lower when testing 100-binary digit possible primes with 10 tests.<br><br>\n\nOne thing to note is that I end up doing a HUGE number of tests (I had used 'k' as the number of tests, but that is generally used as # of bits) in comparison to what is generally suggested as being 'good enough'. At least 64 in fact. Take, for example, a 512 bit possible prime, and the minimum number of tests that I do, 64. Plugging that into 4.48 (iii) gets us approximately (1/2)**136, which is less than (1/4)**64. Using the default number of tests as bits*2, puts us generally into rule (iii), which gives failure probability that tends far lower than (1/4)**t, for most possible primes which would be interesting.<br><br>\n\nCertainly there are diminishing returns for each additional test one does (meaning that we could probably be happy with doing I went and read the page (and the few pages before and after), and from what I understand (which isn't a whole lot, given the minimal time at 2AM I spent reading), the probability of failure can be caluclated, and that the actual probability of failure tends to be far lower than (1/4)**t, (1/2)**(4.4*t) or lower when testing 100-binary digit possible primes with 10 tests.<br><br>\n\nOne thing to note is that I end up doing a HUGE number of tests (I had used 'k' as the number of tests, but that is generally used as # of bits) in comparison to what is generally suggested as being 'good enough'. At least 64 in fact. Take, for example, a 512 bit possible prime, and the minimum number of tests that I do, 64. Plugging that into 4.48 (iii) gets us approximately (1/2)**136, which is less than (1/4)**64. Using the default number of tests as bits*2, puts us generally into rule (iii), which gives failure probability that tends far lower than (1/4)**t, for most possible primes which would be interesting.<br><br>\n\nCertainly there are diminishing returns for each additional test one does (meaning that we could probably be happy with doing ", 'title': u' '}, {'comment': u'Darn it, I should have previewed that entry. Use of < without proper HTML escapes killed it.\n\nIn any case, to finish the post, I could probably get away with doing fewer than 20 tests, regardless of the size of the integer desired.', 'title': u' '}], 'desc': u'Included is a recipe for performing the Rabin-Miller probabilistic test for a composite witness. As provided by Paul Miller in the comments (not the Miller in Rabin-Miller), Rabin-Miller can only tell us if a value is definitely composite. In the case where a test value is not a witness for the compositeness of a potential prime, it can only lie with a probability of at most 1/4.\n\nWith this, we can attempt to catch a liar over some number of trials, and the probability of us not catching at least one liar after k trials (if the number is not actually prime) is at most 4**-k.\n\nIncluded is an algorithm for generating a number of b bits for which no composite witness was found after k trials. Removing mathematical rigor will suggest that the probability of the value being prime after k trials is at least 1-1/4**k.'}, {'comments': [{'comment': u'Interesting viewpoint. Instead of tricking around with\na generic solution, generate the specific one on thy\nfly. I wonder what implications this might have.', 'title': u'Interesting viewpoint'}], 'desc': u'Two approaches to generate all combination of elements from a number of sets. Compares "classic" statically coded algorithms to a pythonic on-the-fly generation of specific algorithm code.'}, {'comments': [{'comment': u'Nice and practical, easy to use recipe.', 'title': u'Nice and practical'}, {'comment': u"Why class Events and it's derivatives with all of this magic is needed? Only to steal event's name and pass it to _EventSlot constructor? I think _EventSlot (better renamed to 'event') is enough in most cases:\n<pre>\nclass MyModel(object):\n def __init__(self):\n self.OnChange = event('OnChange')\n ...\n def __set(self, value):\n ...\n self.OnChange()\n\nclass MyModelView(SomeWidget):\n def __init__(self, model):\n ...\n self.model = model\n model.OnChange += self.DisplayValue\n ...\n def DisplayValue(self):\n ...\n</pre>\n", 'title': u'It is may be simpler'}, {'comment': u'I think it\'s interesting to add support of "weak events" (weak references to handlers) so handlers may die when not needed anymore', 'title': u'weakevents'}, {'comment': u'The class Events is there mainly for 3 reasons:\n<br>\n1. Events (Slots) are added automatically, so there is no need to declare/create them separately. This is great for prototyping. (Note that __events__ is optional and should primarilly help detect misspelled event names.)\n<br>\n2. To provide (and encapsulate) some level of introspection.\n<br>\n3. And yes, to "steel the name" and hereby remove unneeded redundancy in a call like <pre>\nxxx.OnChange = event(\'OnChange\')</pre>', 'title': u'Simpler implementation here means complication for client code.'}, {'comment': u'I did implement weak events for fun, and they are not helpful at all.\n<br><br>\nIf you think further, adding weak event handlers would only prevent observers from beeing kept alive by their subject alone. But, since observers are usually GUI elements, their life is determined by user actions, not their reference count. When the user closes a window, for ex., the underlying widget/handle/whatever is destroyed, even if the wrapping python object continues to exist. Now, whether there are references to the python object or not - it becomes practically unusable.\n<br><br>\nSo what you actually need is to unsubscribe from the subject whenever the underlying widget goes away, but no weakrefs will help you here.', 'title': u'Not really'}], 'desc': u'IMPROVED. The concept of events is heavily used in GUI libraries and is the foundation for most implementations of the MVC (Model, View, Controller) design pattern (the latter being my prime motivation for this recipe). Another prominent use of events is in communication protocol stacks, where lower protocol layers need to inform upper layers of incoming data and the like. Here is a handy class that encapsulates the core to event subscription and event firing and feels like a "natural" part of the language.'}, {'comments': [], 'desc': u'Sometimes you get a list of lists and want to swap rows and columns, i.e. transpose the list. Yet, what if the rows have different lengths? Here is some advice you might find useful in such situations.'}, {'comments': [{'comment': u'This is what I\'d call an inspired solution. Of all switch-case substitutes, I probably like this one most.\n<br><br>\nJust one marginal note: the "raise StopIteration" at the end of "__iter__" is probably superfluous. StopIteration is raised as soon as a generatator returns normally.\n<br><br>\nPerhaps you\'d like to see my "Exception-based Switch-Case" recipe at\n<br><br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410695\n<br><br>\nand give me some comment on it?\n<br><br>\nBest Regards\n<br>\nZoran', 'title': u'A very inventive approach!!!'}, {'comment': u"Well-done and readable solution.\n\nI think we're getting close to being able to implement Duff's Device (http://en.wikipedia.org/wiki/Duff%27s_device) in Python. ;-)", 'title': u're: Readable switch construction...'}, {'comment': u"In python, I really haven't missed switch(), but I am really impressed with the simplicity and beauty of this implementation. Very nice.", 'title': u'Most Elegant'}, {'comment': u'Great solution. I liked it for its simplicity and elegance. The need for explicit "pass" is in line with all things Pythonic.', 'title': u'Nice solution'}, {'comment': u'I agree with the previous comments, it\'s nice, concise and elegant. Have you considered an extension to multiple cases ? I mean something like<pre>\nimport string\nc = \'A\'\nfor case in switch(c):\n if case(*string.lowercase):\n print "c is lower-case !"\n break\n if case(*string.uppercase):\n print "c is upper-case!"\n break\n if case(): # default\n print "I dunno what c was!"</pre>\n\nYou would just have to change a line in the match method to <pre> elif self.value in args:\n</pre>', 'title': u'Multiple cases ?'}, {'comment': u"Ooh, nice. I didn't consider it, as I was aiming to duplicate the actual functionality of 'switch', but this possibility definitely enhances it, in my opinion. I'm going to mention your suggestion in the recipe, if you don't mind.", 'title': u'Multiple cases ?'}, {'comment': u'... but I think I have to disagree with the consensus here: I think this is a poor idea.<br>\n<br>\nBrian explains:<br>\n> As far as I can tell, people generally use switch for its<br>\n> conciseness and readability, and not for its better lookup<br>\n> time, if that is indeed true.<br>\n<br>\nBut I disagree. Switch *IS* O(1) in number of branches, and that is an extremely important feature of it. Dictionary dispatch is the correct solution in Python when "a switch statement" is needed because it is O(1), and IMHO when people say "a switch statement" they are implying O(1).<br>\n<br>\nIf readability is the only criterion, then I personally believe that you can\'t beat this:\n\n<pre>\n if v == \'one\':\n print 1\n elif v == \'two\':\n print 2\n elif v == \'ten\':\n print 10\n else:\n print "something else!"\n</pre>\n\nSo, while I admire the cleverness that went into creating a syntax that closely mimics that of C and its offspring, I would advise AGAINST ever using this recipe. It\'s not that the recipe is poor, just that what it attempts to do (imitate C syntax) is not, IMHO, a wise idea in Python.', 'title': u'I hate to knock such a beautiful effort...'}, {'comment': u"You could extend this thing a long way and it will become more internally consistent/elegant, but I don't think it make things easier for a Python programmer. It is good for someone who needs to program a switch in some customized language running under Python.\nFor example, case could be smart enough to know when it tests true, so it raises an error when the programmer fails to choose a course of action in the code block and falls onto the next case test. That would be useful for some mini-language. Speaking as someone who often forgot the 'break' statement when first doing C<br><br>\n\nBut as a Python programmer, why would I write code that requires I\nremember to hardcode a 'break' or other action within each code block for any reason other than imitating C programming?<br><br>\n\nThis class could be expanded to be a smart tool for novice programmers, but\nas a Python programmer I would just leverage existing constructs, such as dictionaries.", 'title': u'It\'s not about Python, it\'s about a class of "switch"'}, {'comment': u"Hold on now... you recommend against using this just because it's O(n), but then recommend using if, elif, else?\n<pre>\nclass test(object):\n def __init__(self, value):\n self.value = value\n \n def __eq__(self, other):\n print 'calling __eq__'\n if hasattr(other, 'value'):\n return not cmp(self.value, other.value)\n else:\n return not cmp(self.value, other)\n\nt = test(10)\nif t == 0:\n print 'zero'\nelif t == 5:\n print 'five'\nelif t == 10:\n print 'ten'\nelif t == 15:\n print 'fifteen'\nelse:\n print 'twenty'\n</pre>\nThe output of the above is:\n<pre>\n calling __eq__\n calling __eq__\n calling __eq__\n ten\n</pre>\nSo how is this not O(n) for cases? Or does this only happen if __eq__ is overridden?", 'title': u'Re: I hate to knock such a beautiful effort...'}, {'comment': u"If you don't want to manually break, just change subsequent 'if' to 'elif'. It still saves you from typing a similar conditional over and over.", 'title': u'Re: It\'s not about Python, it\'s about a class of "switch"'}, {'comment': u'No, I recomend against using it because it is O(n) and if you want an O(n) solution, then you should use if-elif-else. In C (and its decendents) one uses switch() despite its ugliness because it is O(1), but this recipe lacks that advantage.', 'title': u'My Response'}, {'comment': u'I remember reading it somewhere that the switch..case in C is only a\nsyntactic sugar for if.. else if and not a O(1). What most of the\nmodern C compilers do when you profile the code and reuse the profile\ninformation is that they put the most likely condition to succeed at\nthe top of the if..else if.. structure so that on the average you get\nan O(1) performance.', 'title': u'switch is not O(1) in C'}, {'comment': u"Okay, after doing some reading in this direction, I've concluded that C's switch *can* be O(1), but it is not guaranteed.\n\n<pre>\nThe issue is discussed here -> http://c2.com/cgi-bin/wiki?SwitchStatement\nAlso, question #6 here -> http://c2.com/cgi-bin/wiki?SwitchStatement\n</pre>\nIn Python, it might be important to also consider the overhead in each approach, but I'm no expert in this area.", 'title': u'switch O(?)'}, {'comment': u'Oops, that second link should be:\n<pre>\nhttp://www.devx.com/amd/Article/21314\n</pre>', 'title': u' '}, {'comment': u'I don\'t think that the cookbook is reserved for speedy recipes only. For example, the recipe "Swapping Values Without Using a Temporary Variable" \n<pre>b, a = a, b</pre> involves packing and unpacking a tuple and probably runs slower then code that does use a temporary variable. Does this disqualify the recipe? No.\n<br><br>\nAs I understand the cookbook, it is about how things can be done with python. A good recipe will point out the pro\'s and con\'s for/against using it, and it\'s up to the cook what he/she will do about it. You want a speedy dish? Use dictionaries. You want a dish that looks like C but speed is less important to you? Use the recipe here.\n<br><br>\nAt the end, a cookbook conveys freedom of choice, and more recipes mean more freedom of choice.', 'title': u'Is there really a point in this?'}, {'comment': u'I think the idea is really interesting, interesting enough to propose another implementation. This one feels more natural to me (and is also much shorter).\n\nWhat do you think?\n\n<pre>\ndef switch(value):\n truth = [False]\n def case(*args):\n #~ if not args: return True\n if value in args:\n truth[0] = True\n return truth[0]\n return [case]\n</pre>\n\nIt has exactly the same behavior, but doesn\'t special case the call without args (just commented out here). The reasons: (1) It has been the only case that returns True, but does not start falling through further calls. (2) Anyway in C or Java there is no direct equivalent for it. Case must always have an argument. The default case has its own keywork ("default"). (3) You did already mention it: Its not necessary. Just omit the last conditional and write the default code near the end of the for loop. A conditional \'if True:\' near the end, or an \'else:\' clause for the for-loop have the same effect.\n', 'title': u'Another implementation'}, {'comment': u'I just timed both alternatives, and, despite your presumptions, it turns out that tuple unpacking is faster than using a temporary variable.', 'title': u' '}, {'comment': u'In what python version? On what platform? ...<br><br>\nUnpacking and re-packing used to be the slower variants in early versions of python, but even back then a, b = c, d was attractive for its conciseness, if not for the speed.\n<br><br>\nAnyway, timing *is not* the point here. Or would you change your code with every new version of python just because some constructs are now more optimized then the others used sofar?\n<br><br>\nI wonder how some people seem to be obsessed with speed at every bit, but then choose python as the implementation language. But I *do* admire the time and energy spent to measure even such negligible issues like the above.', 'title': u' '}, {'comment': u"Yet I couln't withstand the temptation and timed it myself. It turns out that a, b = b, a is about 7% slower on Python 2.2 and WinXP and about 11% slower on Python 2.4 and Win2000. My presumptions seem to still hold.", 'title': u' '}, {'comment': u'<pre>Brian Beck\'s - switch - class encasulates the underlying logic so that:\n \n (1) The logic can be applied without regard to the name of what is being \n assessed.\n (2) Hence the block of code in the switch instance becomes modular. \n It can be readily moved/copied from module to module. \n It can be found and copied or re-written by python. That\'s especially cool for dynamic modeling of changeable processes.\n \n</pre>\n[How pythonic is it?]....<br>\nEncapsulating is highly pythonic. It gives us the local namespaces of function, class, and module, as well as more subtle **kwargs and *args groupings of parameters. In terms of the instance at hand, here we see encapsulating both in the switch class\'s function suite, and in the *args addition Pierre Quentel suggested for groupings of workalike parameters. <br><br>\n\n[don cogsci hat]....<br>\nIn cognitive science terms, this encapsulating of a [supposedly unique-]choice function is akin to "chunking". Chunking is a well-proven psychological "trick": Chunking several items into one allows more stuff to be fitted into a limited-capacity memory or buffer (cf. fixed-length namespace). But here, instead of grouping *items* the abstraction is a grouping of tests. This structure of sequenced test criteria thus implements choice_function-chunking.\n<br><br>\n\n[switch back ;)] ...<br>\nIs this a case of \'Python fits the brain\'?', 'title': u'Seeing a switch: pythonic encapsulating and "brainy" chunking:'}, {'comment': u"Maybe I do it wrong, but on my FreeBSD 5.4 with Python 2.4.1 this code:\n<pre>\nimport timeit\na = 1\nb = 2\nt = timeit.Timer('a, b = b, a', 'from __main__ import a, b')\nprint t.timeit()\nt = timeit.Timer('c = a; a = b; b = c', 'from __main__ import a, b')\nprint t.timeit()\n\nGives me:\n0.129501104355\n0.168084859848\n</pre>", 'title': u'Different results'}], 'desc': u"Python's lack of a 'switch' statement has garnered much discussion and even a PEP. The most popular substitute uses dictionaries to map cases to functions, which requires lots of defs or lambdas. While the approach shown here may be O(n) for cases, it aims to duplicate C's original 'switch' functionality and structure with reasonable accuracy."}, {'comments': [{'comment': u'nice code, thanx.\n-------------------------------------------\nhttp://mortgage-calculator.teach-nology.com', 'title': u'worked fine'}], 'desc': u'When you want a class instance to act as if it was an instance of another class (at least from some aspect), but for some reason you can\'t use multiple inheritance, You have to deal with some kind of "delegation": You embed an object of the other instance as an attribute of your main instance, and then create as much attributes as you can that "point to" corresponding attribute of the embedded instance. To avoid all that coding stuff, here\'s a function, "immerse", that automatically sets as class properties all attributes that an instance of another class have, and that are not in the main class.\n\n'}, {'comments': [{'comment': u'Think this is worth bearing in mind: http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl\n\nIn particlar the remark;\n\n"Perhaps more important, it\'s not what compiler implementors expect. They expect exceptions to be set up often but thrown rarely, and they usually let the throw code be quite inefficient. Throwing exceptions is one of the most expensive operations in Java, surpassing even new."', 'title': u'Just being snarky...'}, {'comment': u'That comment may be relevent to Java or C++ but exceptions aren\'t "exceptionally" slow in Python. Consider the fact that Python uses an exception to mark the end of every for loop.', 'title': u'Not relevant to python'}, {'comment': u'Using exceptions for case switches brings some disadvantages, for example, you cannot use the asterisk for unpacking values "except case(*string.letters)" as you can do in Brian Beck\'s "for loop" case switch clause... Any way to overcome this disadvantage? ("reduce(case,[string.letters])" does not seem to work either.)', 'title': u'Some disadvantages...'}, {'comment': u'I\'ve benchmarked the exception-based variant with 10 cases against an if-elif variant. On Python 2.2.2, there is a factor of about 12.7 in favor of if-elif, so yes, exceptions are slower. Yet in python this is a reasonable overhead. On .NET for example, the factor is about 3500 (no typo, I repeat: 3500).\n<br><br>\nI wonder why "compiler implementors expect... exceptions to be set up often but thrown rarely, and they usually let the throw code be quite inefficient." \nThis is an illusionary expectation, because even the implementors of the standard platform libraries use exceptions for all kinds of assertions, which is only natural. There is no point in adding a (widely and readily accepted) feature to a language, but then let it be "quite inefficient".\n<br><br>\nThe Python developers obviously did understand this and made the throw code quite efficient, hence the preference of the idiom "Easier to Get Permission" to "Look Before You Leap".', 'title': u'About exceptions in Python and elsewhere'}, {'comment': u"Extending case(value) to case(*values) and checking if any of the values matches exobj.args[0] will enable code like\n<pre>except case(a, b, c):\n ...\nexcept case(*seq):\n ...\n</pre> I'll add this to the recipe.", 'title': u'Unpacking values'}, {'comment': u'... as extra function:<pre>except multicase(*values)</pre>is slower then case(), hence the decision to have an extra function.', 'title': u'Added ...'}, {'comment': u'The recipe runs slowly because all cases must be instantiated on every pass. Using string exceptions is much faster and does not require any wrapping logic:\n\n<pre>\nwhile 1:\n n = raw_input(\'Enter an integer: \')\n int(n) # verify that n is an integer\n try:\n raise n\n except (\'1\', \'2\', \'3\'):\n print "You entered a number between 1 and 3"\n except \'4\':\n print "You entered 4"\n except \'5\':\n print "You entered 5"\n except (\'6\', \'7\', \'8\', \'9\'):\n print "You entered a number between 6 and 9"\n except:\n print "You entered a number less than 1 or greater then 9"\n</pre>', 'title': u'Simplify and speed-up with string exceptions'}, {'comment': u'Due to a nuance of how string exceptions work, the above example should raise an interned version of the string:\n<pre>\n raise intern(n)\n</pre>', 'title': u'Correction'}, {'comment': u'That will not work for types other then strings, which is not in the "spirit" of a switch-case.\n\nHowever, since a switch-case is usually restricted to simple types in other languages, im many cases a variant of your suggestion may be utilized:\n<pre>try:\n raise intern(str(n))\nexcept (\'1\', \'2\', \'3\'):\n ...</pre>\nHowever, that might not work for objects that define their own __str__, while the code in this recipe works with any objects (to which the equalty operator may be reasonably applied).', 'title': u'Good hint, but not generally usable'}], 'desc': u'Here is yet another way to emulate a switch-case statement, perhaps one you might not have thought of.'}, {'comments': [{'comment': u'I think a metaclass is more useful and easier to read (in use, not necessarily in implementation) for this kind of thing. I\'ve posted an example of this in my repository: http://svn.colorstudy.com/home/ianb/recipes/class_property.py <p>\n\nI\'ll copy the actual code here:\n\n<pre>\nreal_property = property\n\nclass property_meta(type):\n\n def __new__(meta, class_name, bases, new_attrs):\n if bases == (object,):\n # The property class itself\n return type.__new__(meta, class_name, bases, new_attrs)\n fget = new_attrs.get(\'fget\')\n fset = new_attrs.get(\'fset\')\n fdel = new_attrs.get(\'fdel\')\n fdoc = new_attrs.get(\'__doc__\')\n return real_property(fget, fset, fdel, fdoc)\n\nclass property(object):\n\n __metaclass__ = property_meta\n\n def __new__(cls, fget=None, fset=None, fdel=None, fdoc=None):\n if fdoc is None and fget is not None:\n fdoc = fget.__doc__\n return real_property(fget, fset, fdel, fdoc)\n</pre>\n\nA brief discussion: this is backward compatible, because property.__new__ produces a normal property instance when you call it (__new__ keeps property() from returning an instance of itself, instead returning an instances of the real property class). The metaclass causes subclasses of this custom property to return property instances again, instead of real subclasses. (There\'s a special case that keeps the property class itself from returning an property instances -- bases == (object,)). Though the use of "class" is unfortunate, I think this is otherwise an ideal syntax for creating properties. I wrote this code, but I know I\'ve seen similar implementations elsewhere, so I can\'t claim it\'s my own novel idea. Ultimately you use it like:\n\n<pre>\nclass Angle(object):\n def __init__(self,rad):\n self._rad = rad\n\n class rad(property):\n \'\'\'The angle in radians\'\'\'\n def fget(self):\n return self._rad\n def fset(self,angle):\n if isinstance(angle,Angle): angle = angle.rad\n self._rad = angle\n</pre>', 'title': u'class/metaclass'}, {'comment': u'The two approaches (decorator vs metaclass) are pretty similar in usage, although completely different in implementation. The main difference in usage is the property "signature":<br>\n<pre>@Property\ndef rad():\n</pre> with decorator\nversus\n<pre>class rad(property):</pre> with metaclass. None is IMO as good as a special property syntax or code blocks would allow, e.g. something like \n<pre>rad = property:\n def fget(self): ...\n def fset(self): ...\n</pre>\nI find decorators are closer though by being more explicit; the class declaration would be misleading to anyone not familiar with the mutated property().\n\nAn advantage of the metaclass solution is the backwards compatibility with the builtin property(); with the decorator, a new name ("Property") has to be defined.\n', 'title': u' '}, {'comment': u'The two approaches (decorator vs metaclass) are pretty similar in usage, although completely different in implementation. The main difference in usage is the property "signature":<br>\n<pre>@Property\ndef rad():\n</pre> with decorator\nversus\n<pre>class rad(property):</pre> with metaclass. None is IMO as good as a special property syntax or code blocks would allow, e.g. something like \n<pre>rad = property:\n def fget(self): ...\n def fset(self): ...\n</pre>\nI find decorators are closer though by being more explicit; the class declaration would be misleading to anyone not familiar with the mutated property().\n\nAn advantage of the metaclass solution is the backwards compatibility with the builtin property(); with the decorator, a new name ("Property") has to be defined.\n', 'title': u' '}, {'comment': u'Here\'s a way that doesn\'t require any new decorators:\n\n<pre>\nclass Example(object):\n\n @apply\n def myattr():\n doc = """This is the doc string."""\n\n def fget(self):\n return self._value\n\n def fset(self, value):\n self._value = value\n\n def fdel(self):\n del self._value\n\n return property(**locals())\n</pre>', 'title': u'Alternate without a new decorator'}, {'comment': u"Your improvement on my recipe is great. Thanks.<br> \n<br>\nI just wanted to suggest that it's possible to change the original property<br>to take on this decorating behaviour in a backwards compatible way: <br>\n<pre>\nimport sys\n\n# changed name to use published cookbook idiom and to aid clarity\ndef nested_property(function):\n keys = 'fget', 'fset', 'fdel'\n func_locals = {'doc':function.__doc__}\n def probe_function(frame, event, arg):\n if event == 'return':\n locals = frame.f_locals\n func_locals.update(dict((k,locals.get(k)) for k in keys))\n sys.settrace(None)\n return probe_function\n sys.settrace(probe_function)\n function()\n return property(**func_locals)\n\nold_property = property\ndef property(fget=None, fset=None, fdel=None, doc=None, nested=False):\n if nested:\n return nested_property\n else:\n return old_property(fget, fset, fdel, doc)\n\n...\n\n\nclass Angle(object):\n def __init__(self,rad):\n self._rad = rad\n\n @property(nested=True)\n def rad():\n '''The angle in radians'''\n def fget(self):\n return self._rad\n def fset(self,angle):\n if isinstance(angle,Angle): angle = angle.rad\n self._rad = float(angle)\n\n ...\n\n</pre>", 'title': u'backward compatible change to property'}, {'comment': u'The apply function is deprecated. This is an abuse of sys.settrace, which should only be used for debuggers, profilers, and code coverage tools. (Also sys.settrace is implementation dependent.)\n<br>\nAbandoning both, you can accomplish something easier than the apply technique:\n<pre>\ndef newProp( fcn ):\n return property( **fcn() )\n\nclass Example(object):\n\n @newProp\n def myattr():\n doc = """This is the doc string."""\n\n def fget(self):\n return self._value\n\n def fset(self, value):\n self._value = value\n\n def fdel(self):\n del self._value\n\n return locals()\n</pre>', 'title': u'Apply is deprecated, and sys.settrace should not be abused this way'}], 'desc': u'This recipe refines an older recipe on creating class properties (\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183). The refinement consists of:\n- Using a decorator (introduced in python 2.4) to "declare" a function in class scope as property.\n- Using a trace function to capture the locals() of the decorated function, instead of requiring the latter to return locals(), as in the older recipe.'}, {'comments': [{'comment': u'This recipe would benefit from using twisted.internet.defer.gatherResults or perhaps some other helper function in that module, rather than inventing its own. It would make this recipe much simpler.', 'title': u'Should use utilty functions in twisted.internet.defer'}, {'comment': u"I don't think so.\nrunDeferredWorkers return a list of deferred.\nYou can do whatever you want with it.", 'title': u' '}], 'desc': u"This recipe presents a simple function for running several works concurrently with Twisted.\nA 'work' is an abstraction for an object that satisfies the IWorker interface presented in the code.\nAn example of work is downloading a web page."}, {'comments': [{'comment': u'Neat :) This would be a useful feature to the logging module.', 'title': u'Pretty cool'}, {'comment': u"I tried\n<pre>\n>>> handler = logging.StreamHandler(AutoIndent(sys.stderr))\n</pre>\nand the result was buggy. A function would get one indentation level the first time, and then a deeper level for every subsequent call. (Write me if you want the code.)\n\nFor example,\n<pre>\ndef f3():\n Unix.warning('I am f3')\ndef f2():\n Unix.warning('I am f2')\n f3()\ndef f1():\n Unix.warning('I am f1')\n f2()\ndef go():\n Unix.warning('I am go.')\n f1()\n f2()\n f3()\nf1()\ngo()\n</pre>\nProduced\n<pre>\n [.UnixWARNING]I am f1\n [.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n[.UnixWARNING]I am go.\n [.UnixWARNING]I am f1\n [.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n[.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n[.UnixWARNING]I am f3\n</pre>\nI fixed this by using\n<pre>\n def indent_level(self):\n import inspect\n return len(inspect.stack())-9\n</pre>\nwhich produced\n<pre>\n [.UnixWARNING]I am f1\n [.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n [.UnixWARNING]I am go.\n [.UnixWARNING]I am f1\n [.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n [.UnixWARNING]I am f2\n [.UnixWARNING]I am f3\n [.UnixWARNING]I am f3\n</pre>\nUnfortunately, using your class directly with my change, the output is completely unindented, while your version works perfectly.\n\nI don't know what's going on, but getting this to work with logging is not trivial.", 'title': u'Problems using this in a logging handler'}, {'comment': u'I had subtracted too much. Normally, the stack is not 9 deep! This works really well in general:\n<pre>\n def indent_level(self):\n import inspect\n return len(inspect.stack())-3\n</pre>\n\nYour version is definitely buggy when used inside a logging.Handler(), and that is a pretty big problem.', 'title': u'My version works consistently'}, {'comment': u"Another (better?) way is:\n<pre>\nfrom logging import Formatter\nclass IndentFormatter(Formatter):\n def __init__( self, fmt=None, datefmt=None ):\n Formatter.__init__(self, fmt, datefmt)\n def format( self, rec ):\n import inspect\n rec.indent = ' '*(len(inspect.stack())-8)\n out = Formatter.format(self, rec)\n del rec.indent\n return out\n</pre>\nWith %(indent)s in the format string, this produces\n<pre>\n[.UnixWARNING] I am Unix\n[.UnixWARNING] I am f1\n[.UnixWARNING] I am f2\n[.UnixWARNING] I am f3\n[.UnixWARNING] I am go.\n[.UnixWARNING] I am f1\n[.UnixWARNING] I am f2\n[.UnixWARNING] I am f3\n[.UnixWARNING] I am f2\n[.UnixWARNING] I am f3\n[.UnixWARNING] I am f3\n</pre>\nBut then a regular formatter would raise an exception if given %(indent)s in the format string. So I'm not sure of the best way.", 'title': u'Better way to indent logging output'}, {'comment': u'There has to be a way to find the baseline indentation level, rather than hard-coding it. For example, in ipython the stack is 8 deep in the shell alone!\n<br>\nAside from that, this solution is pretty good. I am going to try to get the function name from the call stack too, and stick that into a generally useful logging.Formatter, which might be a good cookbook entry by itself.', 'title': u'How do we discover the baseline stack depth?'}, {'comment': u"I hadn't tried it in conjunction with the logging module... It may be that adding one to the argument to sys._getframe will solve the problem, but I'm not sure. I will look into it.\n\nAs for the base stack depth-- the way I tried to avoid that was by only counting frames which write() had been called from, instead of counting all frames. Otherwise the indentation gets insane. ", 'title': u'base frame depth'}], 'desc': u'Output stream wrapper; possibly useful for debugging code with print statements.\n\nWhen write() is called, it makes a note of the calling frame. The indentation level is equal to the number of frames in the call stack which have been previously noted. See example.'}, {'comments': [], 'desc': u'Achieves exactness by manipulating values stored as a long integer mantissa with an integer exponent (base two).'}, {'comments': [], 'desc': u'This is an implementation of the singleton without using the __new__ class but by implementing the __call__ method in the metaclass.'}, {'comments': [], 'desc': u"This amazingly powerful module is a mystery to novices. Once you figure it out, you'll use it everywhere.\n\nIn addition to examples, here are a couple of useful filters."}, {'comments': [], 'desc': u'Some people like to sprinkle stack trace information in their code, and it is always helpful to get a visual clue to the call stack depth. inspect.stack() contains the entire call stack.\n\nTo make this information available conditionally, on a per-subsystem basis, the logging module is helpful. Here is one way to combine the two ideas.'}, {'comments': [{'comment': u'This recipe generates errors due to missing the original base class. Something like this will suffice:\n<br>\n<pre>\nclass Test( object ):\n def test(self): return self.__class__.__name__\n</pre>', 'title': u'Missing Demo Code'}], 'desc': u'Two implementations for extending an exsisting class using metaclasses'}, {'comments': [], 'desc': u'Some file processing tasks are quite time consuming, especially when COM is involved. Unnecessary repetitions are then unbearable. Here is a module that helps avoid them.'}, {'comments': [{'comment': u'it is interesting to find way to refresh desktop for another user (e.g. change currently logged user desktop from background admin task), or, more interesting, to force desktop refresh from network', 'title': u' '}], 'desc': u'Script that rewrites a to-do list on the Windows Active Desktop and then refreshes the display.'}, {'comments': [], 'desc': u'This recipe comes from an idea to "improve" Tim Delaney\'s "autosuper" recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195) by using a similar approach but with no need to inherit a class from \'autosuper\'. It is now a free function to be used inside a method body whithout the need to pass it the \'self\' object:\nclass C(object):\n def foo(self,*a,**k):\n # do something\n autosuper(*a,**k)\n # do something\n'}, {'comments': [], 'desc': u'The Python Imaging Library (PIL) makes many tasks easy in digital photography. This recipe shows how to make a "contact sheet" of images, a single image with thumbnails of many different pictures. It\'s limited in that it will only work with pictures of the same shape, but you can make some really fun images.'}, {'comments': [{'comment': u'Why not use .digest() instead of getting the .hexdigest() and converting it with a2b_hex?', 'title': u'Just use .digest()!'}, {'comment': u"Thanks. I've updated the recipe.", 'title': u'Indeed'}], 'desc': u'This recipe allows messages to be encoded in "Bubble Babble" format. It also includes an additional function to encode message digests (sha, md5) in this same format.'}, {'comments': [{'comment': u'Before jumping to pyrex, you could move some unvarying calculations out of the loop, like so:\n\n<pre>\nsx = s1 * sd\nsy = s2 * sd\nrx = rho / s2\nry = rho / s1\n\nfor i in range(1,n):\n x[i] = normal(m1 + rx * (y[i-1] - m2), sx)\n y[i] = normal(m2 + ry * (x[i-1] - m1), sy)\n\n</pre>\n\nIn any case, most of the work probably happens in normal(), whatever\nthat is, and nothing in this script can change that. ', 'title': u'speed'}, {'comment': u"Yes,\n\nMoving calculations out of the loop is basic. But answering to your question, Normal is a function from the Numeric module that draws a sample from a Normal distribution. It's probably C or Fortran code. So, apart from the function call overhead it must be pretty optimized already. <br><br>\n\nIn this first version of the recipe, I kept the calculations inside the loop to keep the specifications of the mean and standard deviations in one place (breaking up formulas makes it harder to figure out whats going on). But I'll run some tests to see what the speed improvement of moving these calculations out of the loop is and post back the results.", 'title': u'Thanks for the suggestion'}, {'comment': u'Ok,\n I did the timings:\nOriginal code:<br>\n<pre>\nIPython CPU timings (estimated):\nTotal runs performed: 1000\n Times : Total Per run\n User : 292.444541 s, 0.292444541 s.\n System: 0.0 s, 0.0 s.\n</pre>\nUnchanging calculations moved out of the loop:\n<pre>\nIPython CPU timings (estimated):\nTotal runs performed: 1000\n Times : Total Per run\n User : 268.004257 s, 0.268004257 s.\n System: 0.0 s, 0.0 s.\n</pre>\n<br>\nBy doing this we get an improvement of almost 10% at the expense of a few more lines.', 'title': u'Timings'}], 'desc': u'The gibbs sampler is an iterative conditional sampler from multidimensional probability density functions (PDFs). The resulting sample is plotted as a scatter plot with the Matplotlib module.'}, {'comments': [{'comment': u"This recipe will call the function at most the number of times per second. You don't want to reset the start time to NOW after the call but to increment it by the period. If the time between calls should be 5 seconds and the function call takes 1 second you want to wait 4 seconds before calling it again, not 5.", 'title': u'timing error'}, {'comment': u"Ah yes, agreed. The callback functions I'm using are so small, I did not detect any timing errors. Updating recipe...", 'title': u' '}, {'comment': u'In the context of game updates, the recipe\'s strategy bogs down when there are many recurring events. The caller is burdened by having to make frequent, unnecessary calls to event.next() in order to check whether each recurring event is ready to run. Not knowing which event is to occur next, the caller has to try calling each until one fires off -- essentially, this is a linear search. All of these calls consume CPU time even when events are scheduled for infrequent update intervals.<pre></pre>\nInstead of a linear search, the order of execution can be kept in a priority queue so that only the next scheduled event is called. Another improvement is use time.sleep() between events so as to not eat-up CPU time that could be used by other threads. The API can be improved by creating a task manager responsible for making the calls (instead of burdening the caller with the responsibility for tracking each event separately). Since these three improvements are already encapsulated in the sched module, an implementation is straight-forward:<pre>\nimport sched, time\n\nscheduler = sched.scheduler(time.time, time.sleep)\n\ndef new_timed_call(calls_per_second, callback, *args, **kw):\n period = 1.0 / calls_per_second \n def reload():\n callback(*args, **kw)\n scheduler.enter(period, 0, reload, ())\n scheduler.enter(period, 0, reload, ()) \n\n#### example code ####\n\ndef p(c):\n "print the specified character"\n print c,\nnew_timed_call(3, p, \'3\') # print \'3\' three times per second\nnew_timed_call(6, p, \'6\') # print \'6\' six times per second\nnew_timed_call(9, p, \'9\') # print \'9\' nine times per second\nscheduler.run()\n</pre>\nNote, the order of arguments was changed from the original. For better readability, the callback function needs to be listed adjacent to its arguments.\n\nAlso note, Windows users should substitute time.clock for time.time.\n', 'title': u'Alternate Strategy'}], 'desc': u'This simple generator function is used to call a function X times per second.'}, {'comments': [{'comment': u'Python may not have C\'s ternary operator (i.e. x ? a : b meaning a if x is true else b), but you can achieve the same effect with x and a or b:\n\n<pre>\n>>> a="a"\n>>> b="b"\n>>> x=True\n>>> x and a or b\n\'a\'\n>>> x=False\n>>> x and a or b\n\'b\'\n</pre>\n\nThe one limitation is that a must be a True value; otherwise you will always get b. You can work around this by inverting the condition:\n\n<pre>\n>>> a=0\n>>> x=True\n>>> x and a or b\n\'b\'\n>>> not x and b or a\n0\n>>> x=False\n>>> not x and b or a\n\'b\'\n</pre>', 'title': u'Ternary operator in Python'}, {'comment': u'This might work great for english only, but is horrid for other languages (where there might be one form for a single object, another for two and a third for everything up).\nFor that you would probably want to use the ngettext function in the gettext module, (or atleast write up a small function like it)', 'title': u'Bigger problems'}, {'comment': u"<pre>\ndef handlePlurals(number, singularTerm, pluralTerm, zeroQualifier='No'):\n if number == 1:\n return str(number) + ' ' + singularTerm\n elif number:\n return str(number) + ' ' + pluralTerm\n else:\n return zeroQualifier + ' ' + pluralTerm\n</pre>\n\nMaybe trivial, but at least hard to screw up. :)", 'title': u'A Lazy Way of Handling Plurals'}, {'comment': u"I had just noticed the previous comment, so a version that operates identically for simple singulars and plurals, but lets you specify different terms for specific counts of items:\n<pre>\ndef handlePlurals(number, countTerms, generalPluralTerm, zeroQualifier='No'):\n if type(countTerms) == type({}):\n specifics = countTerms\n else:\n specifics = {1:countTerms}\n if number in specifics:\n return str(number) + ' ' + specifics[number]\n elif number:\n return str(number) + ' ' + generalPluralTerm\n else:\n return zeroQualifier + ' ' + generalPluralTerm\n</pre>", 'title': u'Slightly less trivial'}, {'comment': u'The if/elif chain in _positive_spoken_number() could be reversed so that the more common cases are listed first.\n<pre></pre>\nGiven transformations of numbers and pluralization of nouns, consider providing accompanying transformations for subject/verb agreement: "there is one goose" vs "there are six geese".', 'title': u'Nits'}, {'comment': u'Reversed elifs, done and tested.\n<br>\nVerb and noun cases would be sweet! But I use this only for reporting statistics at the end of a program.\n<br>\nOf course, this recipe has very limited value, but the coolness factor is considerable if you use it in a program that someone else sees. Regular people say, "Wow. Cool."', 'title': u'Good point'}], 'desc': u'Have you seen error reports that say\n "1 errors detected"\nor\n "2 error found"\nand thought there must be a better way?\n\nThere is!'}, {'comments': [{'comment': u'On the left side of the page is \n\nSubmit Recipe\nMy Recipe\n\nAll Recipes\nAll Cookbooks\n\n...\n\nClink on "My Recipes" to get rid of this duplicate.', 'title': u'Go to "My Recipes"'}, {'comment': u'I know where to find "My Recipes" (but thanks anyway). What I don\'t know is how to delete a recipe when I\'m there. I only see "Edit | View", no "Delete" or the like. Am I constantly overlooking something?', 'title': u'... and then?'}], 'desc': u':( Somehow this recipe arived twice. Please go to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413268 :o Dear editors, please remove this one'}, {'comments': [{'comment': u"Your implementation is really cool, especially the validator of a feature. \n\nHowever, to me, the FeatureBroker is a kind of ServiceLocator. So it isn't really the Inversion of control that I expected. ", 'title': u'Maybe I misunderstood the article by Martin Flower. I think what you implemented is ServiceLocator pattern'}, {'comment': u'The essence of ServiceLocator is that components make explicit calls to the locator to request a particular feature, so every component "sees" the locator.\n<br><br>\nDependencyInjection is characterized by dependencies being somehow "declared" by components, while the resolution mechanism is completely hidden.\n<br><br>\nIn this recipe, components only need to declare what they need. They do not need to see the FeatureBroker, since that is an "implementation detail" of the dependency declaration/resolution mechanism. (The implementation can be changed anytime to search classes for RequiredFeature slots and actually inject values, as you probably expected, without affecting existing components.) From this design-level point of view, the recipe conforms to DependencyInjection.\n<br><br>\nOn the other hand, the implementation itself uses the FeatureBroker as a sort of ServiceLocator, so from an implementation-level point of view, the recipe is a ServiceLocator.\n<br><br>\nIn the end, it all depends on whose lawyer you are. If you are an implementation lawyer, you will think of the recipe as being a ServiceLocator. If you are a design lawyer, you will think of it as DependencyInjection. And if you are management lawyer, you will think of it in terms like "Does it get the job done, and how much does it cost?"', 'title': u'Kind of Point of View'}, {'comment': u'Also, statically typed languages do not support concepts like attribute descriptors, decorators etc. The strict separation of the two patterns is partly, if not mainly, enforced by the static nature of those languages.<br>\n<br>\nIn Python, thank to its dynamic features, it is possible to "adjust" how an attribute is retrieved and encapsulate that "adjustment" away from clients. It then becommes apparent that the two patterns are merely two manifestations of the same abstraction.', 'title': u' '}, {'comment': u'The line \n "return callable(attr)"\nshould be replaced with\n "if not callable(attr): return False"', 'title': u'There is a bug in the method HasMethods'}, {'comment': u'I have applied your fix to the recipe', 'title': u'A silly error indeed - thanks'}], 'desc': u'Sample Pythonic Inversion-of-Control Pseudo-Container.'}, {'comments': [{'comment': u'Wrote one of these myself last week! See http://www.codepoetics.com/code/tripoli/synchronization.py.', 'title': u'Heh'}, {'comment': u'Like it says at the end there...\n\nIncidentally, I will be looking at ways of writing unit tests for multi-threading components some time next week (I have a couple of tricks in mind, using the threadable function and AsyncResult class from http://www.codepoetics.com/code/tripoli/concurrency.py); MrowLockable will be the first candidate for testing.', 'title': u'Oh yeah,'}, {'comment': u"Your work definitely inspired this recipe; I thank you for that :)\n\nConsider adding reentrancy to locks acquired in the same thread; for instance, calling outer() in an instance of the class below will deadlock:\n\n<pre>\nclass Foo(MrowLockable):\n\n @MrowLockable.writes\n def outer(self):\n print 'outer'\n self.inner()\n\n @MrowLockable.writes\n def inner(self):\n print 'inner'\n</pre>", 'title': u'reentrancy'}, {'comment': u"I've updated the recipe to avoid some potential deadlock scenarios:\n<br><br>\n- Threads that have acquired a write lock can subsequently acquire read locks, as writers are implicitly readers as well.\n<br><br>\n- Threads that have acquired a read lock can subsequently acquire a write lock. The operation will block until existing read locks are released, then the read lock will morph into a write lock for the remainder of the lock acquisition's life span.\n<br><br>\nCaveat: The latter, while preventing a deadlock, might cause already-read data to become stale if a read lock morphs into a write lock after another write lock has been requested. I'll probably write a test case to illustrate this at some point.", 'title': u'deadlock corner cases'}, {'comment': u"A lot of inspiration can be taken from Doug Lea's work. First of all, there is the Java util.concurrent package (which has been integrated into Java 5) :<br>\n<br>\nhttp://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html<br>\n<br>\nThis package is explained in detail in a very good book, Concurrent Programming in Java :<br>\n<br>\nhttp://www.amazon.com/exec/obidos/ASIN/0201310090/<br>\n", 'title': u"Check out Doug Lea's books and web site"}, {'comment': u"Just read an interesting article in C++ Journal recently, about lock-free structures, which are perfect for read-many-write-rarely and hence for MROW (as one writer cannot stumble onto itself - see code below, it's hopefully clear...).<br>\n<br>\n(From memory) The basic idea is to use a pointer to a structure. Readers can read as much as they like, by reading the pointer, then going to the structure, without any locking. Writers make a copy of the structure, modify it, and then must atomically test-and-set the pointer to the structure.<br>\n<br>\nThis test-and-set operation was proved to be the most robust and efficient way to achieve lock-free resource access, and is implemented as one assembly instruction in many existing processors. In pure python, it would have to lock and would look something like this:<br>\n<pre>def test_and_set(pointer, expected_value, new_value):\n swapped = False\n lock() # Could lock globally or just on this pointer\n if pointer.pointee == expected_value:\n pointer.pointee = new_value\n swapped = True\n unlock()\n return swapped\n</pre>\n<br>\nAnd used like this (assuming 'pointer.pointee' is a structure):<br>\n<pre>\n# to read:\nsomething = pointer.pointee.something # Look, no lock!\n\n# to write:\nwhile True:\n data_pointer = pointer.pointee # Record the current 'pointer'\n new_data = copy(data_pointer) # Copy the data\n new_data.something = 'bla' # ... Work on new_data\n if test_and_set(pointer, data_pointer, new_data):\n break # Successfully set.\n # Otherwise, try again\n</pre>\n<br>\nNo time now to implement, please give it a go and tell me ;-)<br>\n<br>\nThe advantage in Python is that the discarded object will be garbage-collected. In non-GC C++, there's a lot of work to do!<br>\n<br>\nIt would be good to have this test_and_set as a native atomic operation!", 'title': u'Lock-free structures'}, {'comment': u'I took a slightly different approach to re-entrancy in the end, adding a re-entrant wrapper to the non-reentrant lock class. This keeps the implementation of the basic lock class simple, and provides a fairly clean separation of concerns.<br>\n<br>\nOne other modification I made was to force any read request from a new thread to block if there were any write requests pending, so that readers could not starve writers of access.<br>\n<br>\nThe new code, together with some unit tests, is part of the "syncopated" module in Tripoli, which is maintained as a separate module and licensed under the Lesser GPL. See http://www.sourceforge.net/projects/tripoli for downloads.', 'title': u'Adding re-entrancy'}], 'desc': u'In multithreaded apps, there is at times the need to control access to a resource to ensure data consistency and integrity. Multiple-reader, one-writer locking allows efficient read access by multiple threads, while ensuring that a write does not overlap any reads nor another write.'}, {'comments': [{'comment': u'Even simpler when using mod_python and Vampire, as you don\'t need to add any special error handling code which determines whether it was an XML-RPC request or not.\n\n<pre>\nfrom reportlab.pdfgen import canvas\nimport xmlrpclib\nimport vampire\n\nclass _Service:\n def getPdf(self,aMsg):\n c = canvas.Canvas(None)\n c.drawString(100,100,aMsg)\n c.showPage()\n c.save()\n return xmlrpclib.Binary(c.getpdfdata())\n\nhandler = vampire.Service(_Service())\n</pre>\n\nSetting the "handler" to be an actual service object, automatically ensures that all the appropriate XML-RPC specific work is done. The object being wrapped as a service can be an existing object which knows nothing about mod_python, whereas in the original example the XML-RPC code is intertwined with the CherryPy code.\n\nMod_python is available from "http://www.modpython.org" and Vampire from "http://www.dscpl.com.au/projects/vampire".', 'title': u'Even simpler using mod_python and Vampire.'}], 'desc': u"It's only a matter to put together Reportlab to generate a pdf file on the fly and Cherrypy xmlrpc filter to serve it as an XML/RPC binary object (base64-encoded)."}, {'comments': [{'comment': u'<pre>\nCPU: 1 Intel(R) Xeon(TM) CPU 3.06GHz (hyperthreading on)\nGPU: Nvidia Quadro4 980 XGL\nO/S: RH9\n\nVisual-2003-10-05\nframe rate: 38.7453874539\n</pre>', 'title': u'Frame rate'}, {'comment': u'<pre>\nCPU: 1 Athlon XP 2600+ \nGPU: ATI Radeon 9600pro\nO/S: Windows XP SP2\n\nframe rate: 21.6 (with psyco full)\n 22.0 (without psycho)\n 22.5 (python -O)\n</pre>', 'title': u'Frame Rate'}, {'comment': u"CPU: 1 Pentium(R) 4 CPU 3.40GHz (hyperthreading on)<br>\nGPU: RADEON X300<br>\nO/S: WinXP 'pro'<br>\n<br>\nframe rate: 50.2659866666", 'title': u'Frame rate'}], 'desc': u'OpenGL Stripchart plotter for a user defined number of channels.'}, {'comments': [{'comment': u"Nice solution, the best so far. My only issue is the interaction between enumerations when you mistakenly compare them:\n\n<pre>\n C1 = Enum('No', 'Yes')\n C2 = Enum('Yes', 'No')\n \n # Both asserts pass without an issue...\n assert C1.No != C2.No ## Kind of okay I guess\n assert C1.No == C2.Yes ## Yikes!\n</pre>\n\nChanging the __cmp__ method on EnumValue to do a == instead of cmp changes the results in a more comfortable way (No == No and No != Yes) but is still uncomfortable\n\nI believe two constants from two different enums should not be comparable at all, there is no sense in mixing apples and oranges. A solution is replacing the cmp with the following:\n\n<pre>\n def __cmp__(self, other):\n return cmp(self.EnumType, other.EnumType) or cmp(self.__value, other.__value)\n</pre>\n\nIn that case you end up comparing only similar things.", 'title': u'Small nit'}, {'comment': u"... different enums should not be comparable at all.\n<br><br>\nThe question is: Is it better to assert that, or always treat values from different enums as different, as you propose.\n<br><br>\nA flaw of the latter is that cmp cannot really tell if an EnumType is less or greater then another, so that for ex. sorting a list of different enums would result in random ordering, which might not be a lucky result.\n<br><br>\nSo, probably it's better to assert then to guess, I guess. Adding the assertion to the recipe ...", 'title': u"You're perfectly right ..."}, {'comment': u"... as C *does* allow you to compare apples and oranges, but I'm the last to complain about it.", 'title': u'... though this breaks C tradition'}, {'comment': u"Here's a small potential improvement: If you add:\n<pre>\nif len(names) == 1:\n names = tuple(names[0].split(' '))\n</pre>\nright after the commented-out assertion, then you can just use a space-separated string for the enum values:\n<pre>\nDays = Enum('Mo Tu We Th Fr Sa Su')\n</pre>\nThe user could of course do this manually, but it would be nice for the Enum to automatically do it.", 'title': u' '}, {'comment': u'I generally don\'t favor "omnipotent" code - meaning code that claims to deal with "everything". This kind of approach always turned against me. Instead, I favor clear separation of concerns and responsibilities, according to the maxim "do one thing, and do it well".<br>\n<br>\nAnyway, I doubt whether a "simplification" of (the already very simple) <pre>Days = Enum(*\'Mo Tu We Th Fr Sa Su\'.split())</pre> is worth the price of introducing a special case. What if someone liked <pre>Days = Enum(\'Mo,Tu.We,Th,Fr,Sa,Su\')?</pre> I think this is best left up to the user.', 'title': u' '}, {'comment': u"You're probably right. Nothing's stopping the user from making a wrapper function to do that kind of thing.", 'title': u' '}, {'comment': u"I'm using this recipe, and would like to have enumerations built of existing lists of strings.<br>\nHowever, when I have anything other than explicit function arguments in the call to Enum, python 2.4.1 chokes on <br>\n __slots__ = names<br>\nThis seems a little counter to what<br> http://docs.python.org/ref/slots.html says, so, if you have any insights, I'd like to hear it.<br>\nAlso, <br>\n constants = tuple(constants)<br>\nthree lines from the end, is a mysterious line. How does tuple-ifying the contants list affect the return value?<br>\nGreat code!<br>", 'title': u'Enums from lists'}, {'comment': u"I'm glad you liked this recipe.<br>\n<br>\nAbout __slots__ = names choking: Unfortunatly, from your description I couln't tell what went wrong, but maybe this would help on using string lists with Enum:\n<pre>\n# create a list of strings ...\n# either explicitly ...\ndayNames = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']\n# or by calculation ...\ndayNames = *'Mo Tu We Th Fr Sa Su'.split()\n# and use it to create the enum ...\nDays = Enum(*dayNames) # note the asterisk in front of 'dayNames'\n# Take care that all enum names are valid python identifiers,\n# otherwise __slots__ = names will fail\nDays = Enum('X', '~Y') # '~Y' is not a valid python identifier\n</pre>\nNote that assignments to __slots__ are checked by the python interpreter - a fact that is not documented at http://docs.python.org/ref/slots.html. Perhaps this explains the problem.\n<br>\n<br>\nAnd now for the mysterious line <pre>constants = tuple(constants)</pre>\n\nI know it does not seem to add any functionality, so it might seem a bit strange at first sight. At a second sight, it does add a value by revealing a certain intention: By making 'constants' imutable, it expresses that the content of 'constants' will not change from that point on, i.e. it really is what it says - a constant. (However, it is said that intention revealing code, while easy to read, is very hard to write, and that line of code is yet another proof. Have a look at what Martin Fowler says about the subject at http://www.martinfowler.com/articles/designDead.html )", 'title': u'Thanks, Christopher'}, {'comment': u"Days = Enum(*dayNames) # note the asterisk in front of 'dayNames'<br>\n^^^^^^^^^^^^^<br>\n...as the cluestick impacts the source of ignorance. :)", 'title': u'Note the dull thud'}, {'comment': u"I can't pickle an instance of the Enum type; pickle complains that __getstate__ must be defined if __slots__ is defined.", 'title': u"Can't be picked"}], 'desc': u'True immutable symbolic enumeration with qualified value access.'}, {'comments': [{'comment': u'In python to say "it is fast" you must measure. In my experiments this function:<br>\n<pre>\nreident = re.compile(r\'^[a-zA-Z_]\\w*$\')\ndef AreStringsIdentifiers2(*strings):\n matcher = reident.match\n for s in strings:\n if matcher(s) is None: return False\n return True\n</pre>\nis *five* times faster.', 'title': u"It isn't very fast"}, {'comment': u"I can't see this function being a bottleneck in any reasonable program. ", 'title': u'Does it need to be fast?'}, {'comment': u"Speed is not of such great importance here, as my pre-submitter noticed. I'll better remove the misleading part from the recipe.", 'title': u"Speed's not crusial here"}, {'comment': u'"Don\'t take it for granted, do your own measurements" someone said. So I did:\n<br><br>\n- When the very first string is not an identifier, the re-based code above is about 3.3 (not 5) times faster, and this factor does not seem to vary with the string length.\n<br><br>\n- When the very *last* string is not an identifier, the re-based code is about 3.3 times SLOWER for 8-char-strings, getting even worse for shorter strings.\n<br><br>\nUsually, measurements are expected to increase the accuracy and credibility of a statement. But then, it depends on what and how you measure ...', 'title': u'About credibility of measurements'}], 'desc': u"Sometimes you need strings to be true identifiers, for ex. to represent symbolic names. Smalltalk offers the type 'Symbol' for this purpose. In python, you need to test this explicitly. Here is a quick way."}, {'comments': [], 'desc': u'This is another way to deal with questions related to the "autosuper" topic. I have used a metaclass "auto" that keep track of every execution context for \nthe methods in the classes it generates, allowing the user to write "upcall(*args,**kwargs)" from inside a method - say "mymethod" - to mean \n"super(C,self).mymethod(*args,**kwargs)", where C is the class the current method is defined in. It\'s even possible to write just "delegate()" instead of \n"super(C,self).mymethod(*args,**kwargs)", when you want the method in the base class to be passed the same parameters the current methods are passed to.'}, {'comments': [], 'desc': u'this is an extension to Shai Berger\'s Pythologic to include support for PyLog. \nSee http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303057\nYou\'ll also need http://christophe.delord.free.fr/en/pylog/\n\nThis program also adds the "&" syntatic sugar. See the example class Test.'}, {'comments': [{'comment': u"I really like this recipe. However, I wonder what happens if 1000 users\ncall the same page: is the rendering being executed 1000 times or is\nthere some caching mechanism built in the Resource class? If not, \nI guess I would need to change the render method in something \nlike this: \n\n<pre>\n def render(self, request):\n try:\n return self.html\n except AttributeError:\n self.html = publish_string(self.rst, writer_name = 'html')\n return self.html\n</pre>\n\nAlso, what happens for long pages such that the rendering takes\na long time? Should I execute the rendering in a separate thread?\nI really don't know what Resource does under the hood.\n\n Michele Simionato", 'title': u'is there any caching here?'}, {'comment': u'After some experiments, I see that twisted does not cache the resources\nby default. Actually, each time I click on the link the a new resource object is created and the .rst file is re-read. Assuming the .rst file\ndoes not change often, this is a waste. A solution would be to memoize\nresource creation with a Memoize metaclass:\n\n<pre>\nclass Memoize(type):\n @memoize # a memoize decorator, there are many in the cookbook\n def __call__(cls, *args):\n return super(Memoize, cls).__call__(*args)\n\nclass ReStructured(Resource, object):\n __metaclass__ = Memoize\n def __init__(self, filename, *args):\n self.rst = open(filename).read()\n self.html = publish_string(self.rst, writer_name = \'html\') \n def render(self, request):\n return self.html\n</pre>\n\nNow one should add an "update" method to reinitialize the \nresource object when the .rst source file changes on the filesystem,\nbut that is easy.', 'title': u'thinking a bit more ...'}, {'comment': u"So if a .rst file is large enough, it'll block all other activity in that Twisted server.\n\nThe simplest way to fix that would be:\n\n<pre>\nfrom twisted.internet.threads import deferToThread\nfrom twisted.python import log\nfrom twisted.web.server import NOT_DONE_YET\n...\n\n def render(self, request):\n d = deferToThread(publish_string, self.rst, writer_name='html')\n d.addCallback(request.write)\n d.addCallback(lambda _: request.finish())\n d.addErrback(log.err)\n return NOT_DONE_YET\n</pre>", 'title': u"Twisted's Resource doesn't thread"}, {'comment': u"This is a version of this recipe for the Snakelets web application server.<br>\n<br>\n* Download and extract Snakelets from http://snakelets.sourceforge.net/<br>\n* Create a new directory in the 'webapps' folder named 'rest'<br>\n* Create a file named '__init__.py' containing the code below in the 'rest' folder<br>\n* Run Snakelets 'serv.py' script<br>\n* Point your browser at http://localhost:9080/rest/<br>\n\n<pre>\nfrom snakeserver.snakelet import Snakelet\nfrom docutils.core import publish_string\n\nclass ReStructured(Snakelet):\n def serve(self, request, response):\n filepath = self.getWebApp().getFileSystemPath() + '/..' + \\\n request.getRequestURL().replace('%20', ' ').rsplit('.', 1)[0] + '.txt'\n f = open(filepath, 'rt'); cont = f.read(); f.close()\n response.getOutput().write(publish_string(cont, writer_name = 'html'))\n\nname='Snakelets reStructuredText Webapp'\ndocroot='.'\nsnakelets= {\n '*.txt': ReStructured, # reStructuredText files have this extension\n '*.html': ReStructured # to be able to navigate in the generated page\n }\n\ndef dirListAllower(path):\n return True\n</pre>", 'title': u'Snakelets version'}], 'desc': u'a webserver which serves files from a specified directory and transforms files containing reStructuredText to HTML on the fly.'}, {'comments': [{'comment': u'Did you see the warning in the itertools documentation?\n\n"Note, this member of the toolkit may require significant auxiliary\nstorage (depending on how much temporary data needs to be stored). In\ngeneral, if one iterator is going to use most or all of the data\nbefore the other iterator, it is faster to use list() instead of\ntee(). New in version 2.4. "<br><br>\n\nWith your code, \'tee\' ends up building a rather large internal data structure which will never be used. With a 10000000-item iterator, Python needs about 170 megabytes to run an empty loop over the \'active\' iterator.<br><br>\n\nHere\'s a more robust solution:<br><br>\n\n<pre>\ntry:\n first = my_iter.next()\nexcept StopIteration:\n # empty\nelse:\n my_iter = itertools.chain([first], my_iter)\n ...\n</pre>', 'title': u'Needs lots of memory for large iterators'}, {'comment': u"I posted the last comment, but it looks like the comment system doesn't like me. Let's see if this works better.\n<br><br>\n</F>", 'title': u' '}, {'comment': u"What's wrong with:\n<pre>\ndef isEmpty (iterable):\n my_iter = itertools.islice (iterable, 0)\n try:\n my_iter.next()\n except StopIteration:\n return True\n return False\n</pre>\n?", 'title': u'islice to the rescue?'}, {'comment': u'Whoops. Change the islice call to islice (iterable,1)', 'title': u'Bugaboo'}, {'comment': u'The "corrected" code consumes the first element of the iterator, which is exactly what is not wanted. I withdraw my submission in favor of the effbot\'s superior python-fu.', 'title': u'Confucious say, never code after 3 AM'}, {'comment': u"You're right, of course. Thanks. I'll change the recipe.", 'title': u"Of course, you're right!"}, {'comment': u'Note that this problem has a lot in common with trying to "peek" into an iterator (that is, trying to see the first element without removing it). Take a look at:\n<pre>\n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373\n</pre>\nWith this code, you could write it something like:\n<pre>\ntry:\n _, my_iter = peek(my_iter)\nexcept StopIteration:\n # Code here for the case where the iterator is empty\nelse:\n # Code here for the case where the iterator is NOT empty\n</pre>\nor\n<pre>\nmy_iter = peekable(my_iter)\ntry:\n my_iter.peek()\nexcept StopIteration:\n # Code here for the case where the iterator is empty\nelse:\n # Code here for the case where the iterator is NOT empty\n</pre>', 'title': u'check the peek recipes'}, {'comment': u"Note, Fred's version does not use itertools.tee(). So, the first line of the recipe needs to be removed:<pre>\n my_iter, my_iter_copy = itertools.tee(my_iter)\n</pre>\n", 'title': u'Still incorrect'}, {'comment': u"Gee... with the help of the entire Python community, perhaps we'll eventually wind up with a correct and efficient snippet of code. I guess that's what the Cookbook is all about.", 'title': u'Okay, fixed that too.'}, {'comment': u'In my experience, code based on python iterators like this, is one of the less wise things to do. Python iterators are the wrong abstractions for almost anything other then element-by-element forward iteration. If you need random access (peeking the n-the value, which includes n=0), you obviously need another type of abstraction.', 'title': u'Why use iterators in the first place?'}, {'comment': u"If you believe that it is NEVER wise to use iterators, then I wonder where you are coming from... I find them a very useful tool for many situations. I tend to prefer them in nearly all cases where access will only be sequential (prefering lists when access will be random).\n<br> <br>\nSo if (to invent an example) the main task is to run through 1 million records in order and you've chosen to use an iterator because of that, you STILL have the problem of how to display the error message if there are NO records in the file. This recipe shows a simple idiom for solving THAT problem.", 'title': u'Why use iterators?'}, {'comment': u'It is getting quite TIGHT here, especially for YOUR kind of WORDING...', 'title': u'Pardon me?'}, {'comment': u'So what do you mean by "you wonder where I\'m coming from"? What does where I am coming from have to do with your recipe? Don\'t you think you are getting a bit too arrogant for someone who needed "the help of the entire Python community" to get 3+1/2 lines of moderate code working? Is DECENCY not a value where YOU come from, dude? How about COURTESY then?\n<br><br>\nAnyway, if you would have read my comment carefully before reacting, you wouldn\'t have missed the point this sadly. And the point was ABSTRACTION (not such a novel or rare concept in computer science, you know, some might EXPECT stuff like that in software). In most situations - be they invented or real - there is an early point when you can either choose the RIGHT abstraction, or blandly take a plain iterator. A wise choice however - even the very act of attempting it - requires understanding about the value of a good abstraction. Pity enough though, an abstraction presented still you have not.\n<br><br>\nTo conclude: After reading your explanation I am more then convinced that this recipe should better be declared bad code smell: Ever needing it is a clear sign of looming design flaw. (I\'ll give you a hint: There is a difference between an iterable, which is a good abstraction for sequential access, and an iterator, which is a bad one. I will leave it up to you to conclude why.)', 'title': u'Pardon me? (continued here due to lack of horizontal space in the actual thread above)'}], 'desc': u'With lists, it is common to test whether the list is empty and perform special code for the empty case. With iterators, this becomes awkward -- testing whether the iterator is empty will use up the first item! The solution is an idiom based on itertools.tee().'}, {'comments': [{'comment': u'... for ex.:\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107027\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52289', 'title': u'Nice closure application, but you should also mention similar / related recipes ...'}, {'comment': u"The second recipe, http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52289, is really cool - it seems to wrap each method when called, so it's unnecessary to predefine the interface. There are a lot of new instances created, on each call, but hey, no need to optimize prematurely :)\n<br>\nThe first recipe is conceptually different in that the proxy doesn't provide the same interface, so it can't be plugged in.", 'title': u"Thanks, I wasn't aware of them"}, {'comment': u'I didn\'t think of it the first time, but there are also parallels with my events recipe at \nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410686\n<br><br>\nIt fasciliates mapping compatible protocols (methods of same signature) onto each other, independent of their name, for ex.:<pre>\noutput_proxy = Events()\noutput_proxy.write += sys.stdout.write\noutput_proxy.write += sys.stderr.write\noutput_proxy.write += mylog.add_string # different name here\n...\noutput_proxy.write("Hi")</pre>', 'title': u'Another complement'}], 'desc': u'Create an proxy that forwards methods to a group of observers'}, {'comments': [{'comment': u"What's wrong with\n<pre>class Object...\n...\nObject = memoize(Object)\n...\no1 = Object(...)</pre>\nIt seems to me the metaclass is only there to attach a decorator to its __call__ method.", 'title': u'Why use a metaclass?'}, {'comment': u'I am using a very picky "memoize" implementation that takes functions\nand returns functions with the same signature, so it does not work\non classes. This is on purpose since I do not want\nto break introspection tools. You could define a "memoize" that takes\na class and returns a subclass of the original one with memoization\nproperties, or modifies both the __init__ and __new__ methods,\nor just returns a factory object which is not a class.\nThere is balance between not breaking introspection tools and easy\nof implementation. I am trying very hard not to break introspection\nfeatures and the metaclass is the most convenient way of reusing the\n"memoize" implementation in my decorator module.', 'title': u'depends on your memoize implementation'}, {'comment': u'I forgot to mention that the implementation based on overriding __call__\ndoes not work when calling the constructor with keyword arguments,\nunless __call__ is overridden with the right signature, but then\none should define a different metaclass for any different signature.\n\nA workaround is to memoize __new__ and __init__ separately, making\nsure they have a consistent signature, but then the implementation becomes too complex for a recipe, so let me skip it ;)\nEmail me if you interested.', 'title': u'Does not play well with keyword arguments'}], 'desc': u'This cookbook contains many recipes to memoize functions, however a recipe to\nmemoize classes was missing. Using this recipe you can cache object\ncreation, i.e. __new__ and __init__ methods are called only when needed.\nFor a good use case, see the discussion around http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413609'}, {'comments': [], 'desc': u'The recipe is an extremely simple demonstration of how two processes can talk to each other using mmap.'}, {'comments': [{'comment': u"Great recipe. Todd Proebsting mentions built-in local transaction support as a possible direction for future languages:\n<br>\nhttp://research.microsoft.com/~toddpro/papers/disruptive.ppt\n<br>\nI see you're using a descriptor class for the 'transactional' decorator. The following alternative:\n<pre>\ndef transactional(method):\n def wrappedMethod(self, *args, **kwargs):\n state = Memento(self)\n try:\n return self.method(*args, **kwargs)\n except:\n state()\n raise\n</pre>\n\nseems a little shorter and clearer. It seems to work, at least for the provided test case. Is there a design constraint I'm missing? Perhaps it needs to be read-only?\n<br>\nI also have some style suggestions for Memento:\n<pre>\ndef Memento(obj, deep=False):\n # state = (copy.copy, copy.deepcopy)[bool(deep)](obj.__dict__)\n state = (copy.copy if deep else copy.deepcopy)(obj.__dict__)\n def Restore():\n # obj.__dict__.clear()\n # obj.__dict__.update(state)\n obj.__dict__ = state\n return Restore\n</pre>\nThe first suggestion is simply an update to the new 2.5 syntax.\n\nThe second releases the orignal __dict__ for garbage collection and changes obj.__dict__ directly into a reference to state. state is part of the closure and will not have any other references.\n\nAgain, great recipe; it really came in handy.", 'title': u'Wrapping with a descriptor?'}], 'desc': u'The memento pattern is great for transaction-like processing. Having a handy implementation around might not be the worst thing.'}, {'comments': [], 'desc': u'This recipe illustrates how to extract a low resolution grid from a high resolution grid using the Numeric package. It presents an inefficient but straightforward solution and then a more efficient solution that employs the functionality in Numeric.'}, {'comments': [{'comment': u'* You don\'t need all those parentheses<br>\n* The "<>" operator is depricated in favor of "!="<br>\n* Better yet, use "is not"<br>\n* Save one dict lookup by *not* checking has_key<br>\n<pre>\ndef __setattr__(self, name, value):\n v = self.__dict__.get(name, value)\n if type(v) is not type(value):\n raise self._ConstError, "Can\'t rebind %s to %s" % (type(v), type(value))\n self.__dict__[name] = value\n</pre>\nI\'m not sure if sys.modules[__name__] = _consttype() is a good idea, since reload *does* require a module, even if import doesn\'t.', 'title': u'I like this one. Just a vew hints ...'}, {'comment': u'Thanks for the suggestions Zoran, they definitive improve the code. For the moment sys.modules[__name__] seems to work. Perhaps there is somebody to shed some light on this issue.', 'title': u' '}], 'desc': u'This is a variation on the existing recipe "Constants in Python" by Alex Martelli. It binds a variable to the type value at first usage. Further usage is then restricted to values of the same type. This avoids a variable of, say, type string to be re-used to contain an integer.'}, {'comments': [], 'desc': u'The Metropolis-Hastings Sampler is the most common Markov-Chain-Monte-Carlo (MCMC) algorithm used to sample from arbitrary probability density functions (PDF). Suppose you want to simulate samples from a random variable which can be described by an arbitrary PDF, i.e., any function which integrates to 1 over a given interval. This algorithm will do just that, as illustrated by the Plot done with Matplotlib. Notice how the samples follow the theoretical PDF.'}, {'comments': [{'comment': u"I forgot about keyword args:\n<pre>\n def __new__(cls, *args, **kw):\n new = dict.__new__(cls)\n dict.__init__(new, *args, **kw)\n return new\n\n def __init__(self, *args, **kw):\n pass\n\n>>> set([frozendict(a=1,b=2), frozendict(a=5), frozendict(b=2,a=1)])\nset([frozendict({'a': 1, 'b': 2}), frozendict({'a': 5})])\n</pre>", 'title': u'Ooops'}, {'comment': u"Is not the order consistent, as long as the dictionary is not modified in the meantime? This is what I get from the (version 2.3) Library Reference, section 2.3.7: Mappings, and it is consistent with my experience. If so, you really don't need to sort the items.", 'title': u'Dictionaries in arbitrary order'}, {'comment': u'If you iterate over the same dictionary object two times in a row without changing it in the middle the order will stay the same. Python makes no guarantees that two different dictionaries testing as equal will have the same item order. ', 'title': u'Dictionary order consistency'}, {'comment': u'The __init__ method can be removed, and maybe the __hash__ method can be faster (and use less memory) using a .sort() instead of sorted(), and using if "_cached_hash" in self.__dict__: instead of the the try-except.', 'title': u' '}, {'comment': u"Nope. __init__ is there for a reason.\n\ndict.__init__ is essentially equivalent to dict.update and could be used to modify the frozen dictionary. It's ignored rather than raising an exception because it will be called once on initialization.", 'title': u' '}, {'comment': u'<pre>\n>>> hash(frozendict({\'k\': [1,2,3]}))\n\nTraceback (most recent call last):\n File "", line 1, in \n hash(frozendict({\'k\': [1,2,3]}))\n File "C:/pydev\\frozendict.py", line 21, in __hash__\n h = self._cached_hash = hash(tuple(sorted(self.items())))\nTypeError: list objects are unhashable\n</pre>', 'title': u"Doesn't work when dict's values are mutable"}], 'desc': u'A frozendict is a dictionary that cannot be modified after being created - but it is hashable and may serve as a member of a set or a key in a dictionary.'}, {'comments': [{'comment': u'What your recipe does is basically\n<pre>\n[ line for line in fd.readlines() if cond(line) ]\n</pre>\nif handler is a sequence, or\n<pre>\n[ handler(line) for line in fd.readlines() if cond(line) ]\n</pre>\nif handler is callable. There is no need for more complications. Still, some general hints:\n<br><br>\n1) You don\'t need a class just to store fd. Using a class makes the impression that you could call process() many times, but you can\'t - the first call eats up all the lines. You get the same functionality with a function process(fd, handler, cond).\n<br><br>\n2) Replace "hasattr(handler, \'__call__\')" with "callable(handler)"\n<br><br>\n3) Avoid omnipotency (of parameters). The handler can be a list and a function today, tomorow it could also be another file to write to... That is generally not a good idea. Handler should be just a function, and that\'s it.', 'title': u'DoTheSimplestThingThatCouldPossiblyWork'}, {'comment': u'3a) Note that you can pass list.append as handler to get the same effect, buying elegance for speed.', 'title': u' '}, {'comment': u'Yes, I know that with list comprehensions it is quick and easy \nto do such things. However, the intention was to provide easy-to-use wrapping which newbies can remember. Then again, cookbook is often for \nhandy recipes and for teaching people to program in Python, and in that respect your list comprehensions are much better.\n\n(I have to admit I use listcomprehensions nowadays for the kind of stuff \n described, because of their clarity).', 'title': u'List comprehensions are powerful'}, {'comment': u'Python file objects iterate on lines, so you can use:<br>\n<pre>\n[handler(line) for line in fd]\n</pre>\nThis has the advantage of not reading the whole file into memory in advance.', 'title': u'readlines not necessary?'}], 'desc': u'Much simplified version exactly as suggested Zoran Isailovski - no class\nneeded either. Works as a very tutorial for list comprehensions :)'}, {'comments': [], 'desc': u'Sometimes it is convenient emit a log line only if the log message was different\ncompared to previous message. However, it is also good to log a line at least every n seconds so that user knows the system is working and has not hanged. These \nideas are combined in this very simple recipe.'}, {'comments': [{'comment': u'Why not do something like this for repeated messages:\n\n<pre>\n05-21-05 03:13 AM: Updating database.\n05-21-05 03:15 AM: Last entry repeated 20 times.\n</pre>\n?', 'title': u'An idea'}, {'comment': u'this can be done by remembering the last logged line until a new/different line is logged.', 'title': u'very nice...'}], 'desc': u'I needed to write a Python script for a "tail -f" that displays log entries from multiple files in a given directory. The display had to be in chronological order, the first column of each log file being timestamp of the log. It should work for any type of files.\n\nUsage: python tail_m.py directoryname'}, {'comments': [{'comment': u'Hi Denis,\n I find this code useful. I plan to use this in the tool am developing (summarydesk.tigris.org). Thank you for the same.\n\nRegards,\nMadan.', 'title': u'Using this recipe in summarydesk'}], 'desc': u"Python 2.3 module textwrap can justify text in three modes: left/right/center.\nSometimes 'align' mode become more useful."}, {'comments': [{'comment': u'you can add/update/delete a odbc data source just by \nadding/updating/delete the Value of the Key from\nHKEY_CURRENT_USER\\Software\\ODBC.\n\nbut this method may be rude.', 'title': u'u can also do it by _winreg'}, {'comment': u'Received the following Traceback Error information running under Active State Python V2.2 ...\n<br>\n<br>\nTraceback (most recent call last):<br>\n File "C:\\Python22\\Lib\\site-<br>packages\\Pythonwin\\pywin\\framework\\scriptutils.py", line 301, in RunScript<br><br>\n exec codeObject in __main__.__dict__<br><br>\n File "C:\\Storage\\Python\\source\\CrtODBCDsn.py", line 20, in ?\n import ctypes<br><br>\nImportError: No module named ctypes<br>\n<br>\nIs ctypes part of a supplemental Python package?\n<br>\n', 'title': u'ctypes Module Not Found Error running Pgm under ActiveState Python V2.2'}, {'comment': u"Located an older version of ctypes on Source Forge for Python V2.2.\n<br>\n<br>\nCode ran ok after installing this module.\n<br>\n<br>\nIs there a way to build a Python Win32 .EXE so that this functionality could be run by someone who doesn't have a Python installation?\n<br>\n<br>\nThanks,\n<br>\n<br>\npanfisher", 'title': u'ctypes missing module resolution; ctypes V0.6.3 installed; ok; Can .EXE Be Built?'}, {'comment': u'It is easy to create a wrapper script that processes an argument list from the commandline and use py2exe to create an executable.', 'title': u' '}, {'comment': u'i have installed python 2.4 and ctypes 0.9.6, and run this script, but it can not create ODBC for SQL server or DB2.\nos: windows xp + sp2\ndb: sql server 2000, db2 8.2\nwhat is the problem?', 'title': u' '}, {'comment': u'and what is the value of parameter "SERVER" for creating ODBC for DB2 database? system name or instance name? or other?\nthanks.', 'title': u' '}, {'comment': u'now odbc for sql server can be created. but for db2 still can not be created. i used following parameters:\n create_sys_dsn("IBM DB2 ODBC DRIVER",SERVER="DB2", DESCRIPTION="db2 DSN", DSN="brkDSN", Database="brk")\n ', 'title': u' '}], 'desc': u"When installing database applications that use ODBC, I wanted to create the required ODBC data sources from my python install script. With the help of the ctypes module, it's simple."}, {'comments': [{'comment': u'This recipe is already here, with a few other variants (including for recurring values):\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252143', 'title': u'Covered more thoroughly'}, {'comment': u'... just noticed the twist that this version is useful when values are lists! (Still, the link to the related recipe is useful.) Thanks.', 'title': u'Sorry ...'}], 'desc': u'Invert a dictionary that has lists as its values. For example, convert {A:[1,2,3], B:[4]} into {1:A, 2:A, 3:A, 4:B}'}, {'comments': [{'comment': u's/One this/One thing/', 'title': u'edit'}, {'comment': u'Dang it. My kingdom for a spell check!', 'title': u"D'oh"}], 'desc': u'A simple integration of a CherryPy web server, using Quixote template publishing, managed in its own thread. \n\nUsing CherryPy as a web server is a good move because it fixes problems on Windows shutting down a call to serve_forever. This example extends the CherryPy capability by running it in a seperate thread. Further extension comes from Quixote, for templating HTML. \n\nOne thing I like about this snippet of code is its simplicity. And the fact that it solves a large number of design problems, all in one shot.'}, {'comments': [{'comment': u"The requirement that the sequences are sorted, and the use of len() in two of the functions, means that the functions won't work on any iterable; they will only work on simple sequences. Try these more versatile functions that will work on any iterable, sorted or not:<br>\n<pre>\ndef min_gt(seq, val):\n return min([v for v in seq if v > val])\n\ndef min_ge(seq, val):\n return min([v for v in seq if v >= val])\n\ndef max_lt(seq, val):\n return max([v for v in seq if v < val])\n\ndef max_le(seq, val):\n return max([v for v in seq if v <= val])\n</pre>\n<br>\nIf you want all values greater than or less than a specific value in a sequence, a list comprehension is a clear and concise technique:\n<pre>\n [v for v in seq if v > val]\n</pre>\n\nOnce you have the resulting list, applying the min or max functions will extract the smallest or largest value.", 'title': u'simpler recipes'}, {'comment': u'Removing the [] can be positive on the last versions of Python, for example:<br>\n<pre>\ndef min_gt(seq, val):\n return min(v for v in seq if v > val)\n\ndef min_ge(seq, val):\n return min(v for v in seq if v >= val)</pre>', 'title': u'Alternative'}, {'comment': u'The standard module bisect does these stuff, and quickly too.\n<br>\nA useful module, You should get to know it.', 'title': u'bisect module'}, {'comment': u'The bisect module does the search with the binary search algorithm, which is O(log N). Instead of yours O(N) recipe.', 'title': u'Binary search'}, {'comment': u'Sadly, this recipe needs to go back to the kitchen.\n<br><br>\nmin_gt and min_ge will return the *first* value they find that is greater than (or possibly equal to) the value "val". min_gt([1, 3, 8, 7, 6], 6) returns 8, not 7. min_ge([2, 3, 4, 10, 8], 8) returns 10, not 8.\n<br><br>\nAlso, min_ge() has a parameter "sorted=false" which isn\'t referenced anywhere in the recipe\'s body... what\'s up with that?', 'title': u'Original recipe is broken'}, {'comment': u"bisect only works on lists, not any iterable, and it requires that the list be sorted. If you have a sorted list, or something that can be turned into a sorted list, bisect is a good way to quickly find elements in the list. If you have arbitrary iterables or can't sort your list, bisect won't be much help.", 'title': u'bisect suitable for some applications, not all'}, {'comment': u'..but forgot to mention in the docs. The remaining parameter sorted=False was in my first versions, where methods sorted input if it was needed. However, using \n\n<pre>max([for i in items where i < val])</pre>\n\nis far more clear and makes my recipe useless :)\n\nI think the bisect module will be even better, though the list comprehension should be the easiest to understand.', 'title': u'Input must be sorted in examples'}, {'comment': u'Rewrite the recipe using bisect module: <br>\n\n<pre>\nfrom bisect import bisect_left, bisect_right\n\ndef min_gt(seq, val):\n return seq[bisect_right(seq, val)]\n\ndef min_ge(seq, val):\n return seq[bisect_left(seq, val)]\n\ndef max_lt(seq, val):\n return seq[bisect_left(seq, val) - 1]\n\ndef max_le(seq, val):\n return seq[bisect_right(seq, val) - 1]\n</pre>', 'title': u'Just for completion...'}], 'desc': u"Sometimes it is useful to know what is the smallest value in a sequence\ngreater than (or equal to) some other value. Eg.\n\nmax_lt([2, 3, 5, 7, 11], 6) would be 5, because 5 is greatest value in the list\nwhich is also less than 6. Following the same lines method call\nmin_gt([3, 5, 6, 10, 12], 6) would return 10, because 10 is the smallest value in the list greater than 6. The following four simple methods implement min_gt, min_le, max_gt and max_ge, but the input must be sorted for them to work. \n\nHowever, Greg Jorgensen's suggestion is much more clever. No need for sorting, just use list comprehensions with min/max."}, {'comments': [{'comment': u'Broker and broadcaster for loose coupling:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81983<br>\n<br>\nC#-style events:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410686<br>\n<br>\nMulticasting:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52289<br>\n<br>\nA by-the-book observer pattern implementation:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/131499', 'title': u'Check out related recipes'}, {'comment': u"I am not able to understand why 'callbacks' list is needed in fireEvent\nfunction. Instead you can just have it like this:<br><br>\n\ncbs = Observer.listeners.get(event.name)<br>\n# in register you are guaranteeing a callback list for the event, so you<br> \n# either get None or a list on the above statement.<br>\nif cbs:<br>\n    for cb in cbs:<br>\n        cb(event)<br><br>\n\n--Hemanth", 'title': u'Why callbacks list in fireEvent function'}, {'comment': u'I\'d rather call this class an "event dispatcher", because it is independent of the objects that actually fire the events (probably because they changed their state). Objects subscribed to the dispatcher would then have to know for themselves, what the semantics of the event they received are, i.e what/who has actually changed.<br>\n<br>\n\nThe term observer/observable or publisher/subscriber is usually used for a pair of classes that define a similar but somewhat different interface, as the observable (publisher) class is usually used as a base class for objects, wanting to notify others about changes in their _own_ state. These objects would normally correspond to the "model" part of an MVC pattern.<br>\n<br>\nThe observer (subscriber) only needs to provide a method (usually called "update") that is called whenever the publisher fires an event. It then either has to ask the publisher about it\'s new state or the new state is already provided when update() is called ("pull" resp. "push").<br>\n<br>\nRecipe 131499 mentioned by the first comment implements the technique I described.', 'title': u'Misnomer'}, {'comment': u'If the callback invoked changes the list of registered objects, you will need a copy of the list. Otherwise some callbacks may not be invoked. This is the case when you register for an event, then unregister when the event occurs. ', 'title': u'Need the callbacks list due to possible looping'}, {'comment': u"Point taken. For my purposes, this was an simple implementation for a specific design need. The semantics and subtlies wheren't given much thought.", 'title': u'Gotcha'}], 'desc': u'This simple class implements the observer design pattern. Acting as a registration hub, it fires simple Events when requested. '}, {'comments': [{'comment': u'A usage example would make the recipe much easier to quickly comprehend.\nThanks :)', 'title': u'Why not add a usage example?'}, {'comment': u'I added a __main__ call to show how this is used in my situation.', 'title': u'Example Provided'}, {'comment': u"Here's a slightly shorter version that supports passing arbitrary positional arguments to the callback.\n\n<pre>\nfrom qt import QEvent, QObject, qApp\nfrom thread import get_ident\n\nclass CallbackEventHandler(QObject):\n\n MAIN_THREAD_ID = 0\n\n def __init__(self):\n QObject.__init__(self)\n self.installEventFilter(self)\n\n def eventFilter(self, obj, event):\n # FIXME: This is a workaround for an unexplained bug\n # The events were getting posted through postEVentWithCallback()\n # But the event() method wasn't getting called. But the eventFilter()\n # method is getting called. \n if event.type() == QEvent.User:\n callback = event.__dict__.get('callback')\n if callback:\n self._doEvent(event)\n return False\n return QObject.eventFilter(self, obj, event)\n\n def _doEvent(self, event):\n callback = event.__dict__.get('callback')\n args = event.__dict__.get('args')\n if callback is not None and args is not None:\n callback(*args)\n\n def event(self, event):\n if event.type() == QEvent.User:\n self._doEvent(event)\n return True\n return QObject.event(self, event)\n\n def postEventWithCallback(self, callback, *args):\n if get_ident() == CallbackEventHandler.MAIN_THREAD_ID:\n # if we're in main thread, just fire off callback\n callback(*args)\n else:\n # send callback to main thread \n event = QEvent(QEvent.User)\n event.callback = callback\n event.args = args\n qApp.postEvent(self, event)\n\n</pre>", 'title': u'Updated version'}, {'comment': u'Try using QCustomEvent (or a subclass) and a customEvent() handler. Using QEvent and event() together with a user-defined event ID may be confusing Qt3, requiring you to meddle with eventFilter().', 'title': u'How about customEvent()?'}], 'desc': u"This class forms a bridge between the main Qt event loop and python-based threads. This was a thorny problem to figure out, so I'm posting for others to benefit. Basically, you need to invoke all Qt GUI calls and (ActiveX calls on Windows) from the main Qt thread. But if you're using Python threads, you need to manage the interaction yourself. "}, {'comments': [{'comment': u"for something somewhat similar, check out the SQLObject project:\n<br>\n<br>\nhttp://www.sqlobject.org\n<br>\n<br>\nIt's different, because it does all the SQL calls in the background and returns the results as Python objects. Works well if you are using the one of the supported databases. The above is a less db-platform-specific solution.", 'title': u'SQLObject'}, {'comment': u'While simple, this module mostly serves my purposes. Bug report:\n<pre>\n# diff standardselect.py standardselect_orig.py\n233c233\n< def __str__(self): return (\' %s \' % self.infix).join([str(blanket_as_needed(e)) for e in self.elements if str(e).strip != ""])\n---\n> def __str__(self): return (\' %s \' % self.infix).join([str(blanket_as_needed(e)) for e in self.elements if e])\n877d876\n< >>> s.where.And(ima.ItemCount == 0)\n898,899c897\n< (ima.ItemCost < 200000) and\n< (ima.ItemCount = 0)\n---\n> (ima.ItemCost < 200000)\n</pre>', 'title': u'bug report'}], 'desc': u'construct sql query in python rather than performing tons of string manipulation.\nTake a look at docstring of StandardSelect and OracleSelect for a hint on how the module should be used.'}, {'comments': [{'comment': u"<p>\nSometimes an if/else can be replaced with an 'or' for prettyness.\n</p>\n<pre>\n...\nif not inCallback: self.inCallback=self.gotMessage \nelse: self.inCallback=inCallback\n...\n \nself.inCallback = inCallback or self.gotMessage\n</pre>", 'title': u"Optional Syntax In QueueMinder's Class Constructor"}], 'desc': u'This class will run a timer that checks a Queue.Queue object at a given interval. This is useful for monitoring messages between threads. You give it a callback, interval, and it does the rest: When its finds a message, your callback is fired up. '}, {'comments': [{'comment': u'<pre>\ncoding = zip(\n [1000,900,500,400,100,90,50,40,10,9,5,4,1],\n ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]\n)\n\ndef decToRoman(num):\n if num <= 0 or num >= 4000 or int(num) != num:\n raise ValueError(\'Input should be an integer between 1 and 3999\')\n result = []\n for d, r in coding:\n while num >= d:\n result.append(r)\n num -= d\n return \'\'.join(result)\n\n\nfor i in xrange(1,4000):\n print i, decToRoman(i)\n</pre>', 'title': u'For grins: A non-recursive version'}], 'desc': u'Convert decimals to Roman numerials.\nI use a recursive algorithm here since it reflects the thinking clearly in code.\nA non-recursive algothrithm can be done as well.'}, {'comments': [], 'desc': u"Sometimes I wish slice creation had a form that looked more like its invocation: [1:5], for example. This recipe allows slice arguments to be passed that look like {1:5}. NOTE: I don't recommend actually using this in practice. It will most likely just confuse any readers of your code. It is just a proof-of-concept. In an interview with Guido van Rossum, Guido was explaining the benefits of Python's built-in types. He gave an example of being able to pass slices as arguments instead of having individual start, stop and step arguments -- and this is very true. But I don't think a syntax to concisely create slices should be out of the question. (Step is not supported by this syntax, it wouldn't be possible and I rarely find myself using step anyway)."}, {'comments': [{'comment': u'Why not use the standard marshal module ?\n\nhttp://www.python.org/doc/2.4.1/lib/module-marshal.html', 'title': u'What about the marshall module ?'}, {'comment': u"From http://python.org/doc/2.4/lib/module-marshal.html:\n<br>\n<br>\nWarning: The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source.\n<br><br>\nThat's why! :-)", 'title': u'marshal has the same vulnerabilities as pickle.'}, {'comment': u'http://twistedmatrix.com/~moshez/unrepr.py\n<br><br>\nI wonder if using the same getattr trick could make this recipe much shorter...', 'title': u"Reminds me of Moshe Zadka's unrepr"}, {'comment': u"but for simple types... what's wrong w/ repr() and eval()? they're portable AND readable, right?", 'title': u'this might be really naive...'}, {'comment': u'Portable and Readable, yes. Secure, no. \n<br><br>\nFor example, what does eval("import os; os.rmdir(\'/\')") return?\n<br><br>\nThis recipe is designed to decode data coming from untrusted, possibly malicious network connections. It does this without running possibly dangerous eval statements.', 'title': u'repr and eval'}, {'comment': u"One builtin type missing from this recipe is bool. We're not in Python 2.2 any more!\n\nWith bool added, the data model described by this serialization format is nearly equivalent to that described by JSON (http://www.json.org). ", 'title': u'bool, JSON'}, {'comment': u'I created a module named rencode, which is based on bencode. This handles floats, dicts with any serializable keys, bools, None, and can safely decode from untrusted data sources. For complex, heterogeneous data structures with many small elements, the serialized strings are significantly smaller than those generated by bencode, gherkin, and this Recipe. It is also faster than this Recipe.<br><br>\n\nAvailable: http://barnesc.blogspot.com/2006/01/rencode-reduced-length-encodings.html', 'title': u'Alternative'}, {'comment': u'As of version 1.6, this recipe cannot encode and then decode -2**31.', 'title': u'Bug'}], 'desc': u"Unpickling from an untrusted source, such as a network connection, can allow maliciously formed pickles to run arbitrary code.\n\nThis recipe presents a simple solution for serializing and unserializing simple Python types. Only simple Python types can be serialized, which makes the use of this algorithm safer than using the pickle module.\n\nNB: I've changes this recipe drastically. It used to use a rather slow string slicing technique, which was a very bad example of how to use strings in Python! The cStringIO provided a faster, simpler replacement. This recipe now serializes faster than the Pickle module (not cPickle).\n\nNB: A Python 2.4 version of this recipe is available here:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/415791"}, {'comments': [], 'desc': u'Handles logic for detecting straights and groups of repeats in the presence of wildcards and hands with more than five cards.'}, {'comments': [{'comment': u'Early, I read about sorting sequences placed on tapes, on "Algorithms + Data Structures = Programs" by Niklaus Wirth; here we have speed -optimized one-step version with more disk and memory requirements.', 'title': u'Wirth is GOD ;)'}, {'comment': u"to be clear, I wanted to say, that I didn't find this algorythmus implemented in python :-)", 'title': u'ups ...'}, {'comment': u'You know, there is a category listing on the left side of this page which shows you how to spell "algorithm".', 'title': u' '}, {'comment': u"I have tested this algorithm with a 280 MB ASCII file. <br>\n<br>\nThe idea is compelling: for huge files do not sort them in one step, but break the file into chunks, sort each chunk separately and merge the files. <br>\n<br>\nThe result is correct, but the merge step uses a hugh amount of memory. Split and sort does not use a lot of memory, but merge does, around 700 MB. This is more than loading the whole file into memory and sort then.\n<br>\nAs an alternative I have used the following 3 liner\n<br>\n<pre>\n lines = inFile.readlines() \n lines.sort()\n map(outFile.write, lines)\n</pre>\n<br>\nwhich has used 'only' 400MB RAM to sort a 280 MB ASCII file.\n<br>\nI don't understand from the code why merge is using so much RAM. Otherwise the algorithm would be great. \n", 'title': u'Does work, but uses lots of memory'}, {'comment': u"<pre>\nHi, \nI found some improvements :-)\njust before I save the file (in _splitFile() method) I can also sort the lines:\n ...\n fileNames.append(tmpFile)\n data = self._sortRecords(lines) -- here\n open(tmpFile,'w').write(''.join(data))\n del lines[:]\n data = None\n size = 0\n\n if size > 0:\n tmpFile = fn + '.%03d' % (i+1)\n fileNames.append(tmpFile)\n data = self._sortRecords(lines) -- and here\n open(tmpFile,'w').write(''.join(data))\n data = None\n ....\n\nthe _sortRecords() method looks now like:\n\n def _sortRecords(self, records):\n get_key = self._getKey\n data = [(get_key(line), line) for line in records if line!='']\n data.sort()\n return [line[1] for line in data] \n\nin the sort() method I also commented out the code lines:\n\n ...\n #for fn in files:\n # self._sortFile(fn)\n ...\n\nAnd finally I change the code line\n\n ...\n buffSize = self._splitSize/(2*len(lines[0]))\n ...\n\nin _mergeFiles() method - don't remember why :-(\n\nIn my tests the memory stays on same level, with the file size I can optimize memory/speed. In your case when I tried 750 MB file I got memory problems.\n\nregards\nTomasz Bieruta\n</pre>\n\n", 'title': u' '}], 'desc': u' '}, {'comments': [{'comment': u'Hmmmm,\n I work mainly in Unix environments (Solaris and Linux), and I\n find a lot more characters mucking up file names :\n \n " \' , ` * and a few others.\n\n These of course are the characters that the shell uses to do\n special things, so putting them in file names makes command-line\n tasks rather difficult.', 'title': u'Is that all ?'}, {'comment': u"valid doesn't mean not 'mucking up'<br>\n\n/ and '\\0' are indeed the only invalid chars\n<br>\nof course it's unwise to use many others, including the\nones you mention.", 'title': u'invalid according to the standard'}, {'comment': u'Will 8.3 filesystems be supported? There is a different valid character set for 8.3 and long filename.\n\nShould this function accept Unicode strings and detect mapping failures to filesystems which use a local encoding?', 'title': u'Adding Windows and others'}, {'comment': u'Why?\n\nIsn\'t it easier to just try and create the file and catch any exception that occurs? Something like:\n\n<pre>\ntry:\n f = open ("some.file")\nexcept IoError:\n # do something\n</pre>\n\ncatches this (albeit in a rather nonspecific way -- you don\'t know if it was the filename that was invalid, the disk was full, etc) in a completely platform-neutral way.', 'title': u'Just one question'}, {'comment': u"Have you ever tried to rename a file with a '?' in it on windows?<br>\n<br>\nI did -- and failed. Can happen, if you access your ext2 file system from windows.<br>\n<br>\nWhat really came in handy would be a function, that strips a list of filenames of unsafe (that is, on all major filesystems) characters but maintains unambiguity.", 'title': u'Invalid chars one non-POSIX systems'}], 'desc': u'Oneliner to check for valid POSIX filenames'}, {'comments': [{'comment': u'FloatType is using the encoding type for C/C++ floats, while Python floats use C/C++ doubles. If you make the appropriate changes, you can end your main test block with: <pre>\n assert x == value\n</pre>', 'title': u"FloatType should be encoded as the eight-byte '!d', not '!f'"}, {'comment': u'Yes, thanks for the tip. I wondered what was happening to my floats, now I know! :D', 'title': u'Ahhh'}], 'desc': u'This recipe is a reimplemtation of this recipe,\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/415503\n\nusing Python 2.4 decorator syntax.\n\nIt also has added support for boolean and unicode types, and a keyword argument (compress=False) for the dumps function, which will compress the string.'}, {'comments': [], 'desc': u'Sometimes it is useful to be able to see fetch all keys in a dictionary which have a common value. The LookupDict class can do this.\n\nOther times, when a 1 to 1 mapping of keys and values, and values to keys is needed, the ReverseDict class could be used.'}, {'comments': [], 'desc': u'This recipe presents a way of serializing & de-serializing XML using\nthe marshal module. The XML is converted to an equivalent Python\ndictionary first, which is marshaled to serialize it. De-serialization\nfirst unmarshals the dictionary from the file, and constructs the\noriginal XML.'}, {'comments': [{'comment': u"Note that if you modify the PATH value, you may also need to substitute variables such as %SystemRoot% with their actual value. If you look at the registry value for PATH, it may contain things such as:<br>\n\n<pre>%SystemRoot%;%SystemRoot%\\system32;etc.</pre>\n<br>\nIn this case, if you modify the PATH registry value by appending a directory and then you broadcast the change, you'll notice that subsequent command prompts will not have C:\\WINNT and C:\\WINNT\\system32 in their PATH, but instead they'll still have %SystemRoot%;%SystemRoot%\\system32. In consequence, they won't find the usual Windows binaries such as ping, ipconfig, etc. I'm not sure why this is happening, since you would think that the command prompt would substitute %SystemRoot% with its actual value automatically.\n<br><br>\nWhat I had to do was something like:\n<br>\n<pre>\n dirs = path.split(';')\n try:\n systemroot = os.environ['SYSTEMROOT']\n except KeyError:\n pass\n else:\n dirs = [re.sub('%SystemRoot%', systemroot, dir) for dir in dirs]\n path = ';'.join(dirs)\n</pre>", 'title': u' '}, {'comment': u"You mustn't make the path a REG_SZ entry - it should be a REG_EXPAND_SZ entry.", 'title': u'The problem is REG_SZ'}, {'comment': u'Great! Thanks for the clarification, it worked just fine when I changed REG_SZ to REG_EXPAND_SZ.', 'title': u' '}, {'comment': u' ', 'title': u'Wow thanks! Exactly what I needed.'}, {'comment': u'I admit that I don\'t understand environment variables in NT/XP very well, however I did find that...\n<br><br>\n1. The old "SET" command doesn\'t work as you expect it to.\n<br><br>\n2. The "SETX" command does work as you expect it to. Almost! It doesn\'t apply the change in the current session, but it applies it in any new sessions.\n<br><br>\nThus, one can simply do an os call to set an environment variable\n<br><br>\n>>> os.system("setx foo hello")\n<br><br>\nThen the environment variable "foo" will be set to "hello" IN SUBSEQUENT DOS sessions.\n<br><br>\nSo after doing the above call start a new DOS session, restart python, and enter...\n<br><br>\n>>> os.system("set foo")<br>\nfoo=hello\n<br><br>\n(note. we use "setx" to set the variable, but "set" to display it)\n\n\n\n\n', 'title': u'There is a simpler way...'}], 'desc': u'This script allows adding/modifying/removing environment variables persistently on Windows. It also allows adding entries to the PATH environment variable.'}, {'comments': [], 'desc': u'Make the standard-lib SimpleXMLRPCServer multi-threaded by using a simple mix-in construction.'}, {'comments': [{'comment': u'One issue with this recipe is that you wind up with a list at the end that could be much shorter than what you have. Consider this alternative:\n<pre>\ndef split_seq(seq, size):\n\tnewseq = []\n\tsplitsize = 1.0/size*len(seq)\n\tfor i in range(size):\n\t\tnewseq.append(seq[int(round(i*splitsize)):int(round((i+1)*splitsize))])\n\treturn newseq\n</pre>\n\nThis produces the following results, which may be preferred for some applications:\n<pre>\n>>> split_seq([1,2,3,4,5,6,7,8,9,10], 3)\n[[1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]\n</pre>', 'title': u' '}, {'comment': u"Thanx Nick, that's a cool one as well. Do you want me to add your version to the recipe or are you going to add this as a recipe as well?\n\nCheers,\nGuyon Mor\xe9e\nhttp://gumuz.looze.net/", 'title': u'very useful as well'}, {'comment': u"I just submitted it as a separate recipe, though I'm not sure I like it so much. I wonder if it could be done using only integer math.", 'title': u' '}, {'comment': u"There's variations on this:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303279\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347689\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303060", 'title': u' '}], 'desc': u'Split up a sequence in same-size(if possible) parts.'}, {'comments': [{'comment': u"1) does not properly handle negative numbers or floats<br><br>\n\n2) Leaves a leading '0' on the string it returns<br><br>\n\nTo fix these, you could do:<br><br>\n\n<pre>def D(n):\n '''undefined on negative numbers, non-integers'''\n if n <= 0: return ''\n return D(n>>1) + str(n%2)</pre>", 'title': u'problems'}, {'comment': u"The modified version can not handle 0 correctly.<br>\n\n<pre>\n>>> D(0)\n''\n</pre>\n\nNot '0' as expected. Is there a better solution?", 'title': u'still has problem'}, {'comment': u"<pre>def E(n):\n '''undefined on negative numbers, non-integers'''\n s = ''\n if n < 0: return ''\n if n == 0: return '0'\n while n > 0:\n s = str(n%2) + s\n n = n >> 1\n return s</pre>", 'title': u'sure'}, {'comment': u'<pre>\ndef Decimal2Binary(dec_num):\n """ Return the binary representation of dec_num """\n if dec_num == 0: return \'0\'\n head, tail = divmod(dec_num, 2)\n return Decimal2Binary(head) + str(tail)\n</pre>', 'title': u'Opportunity to use divmod()'}, {'comment': u'<pre>\ndef Decimal2BinaryBits(dec_num, bits):\n res = Decimal2Binary(dec_num)[:bits].zfill(bits)\n return res\n\n\nprint Decimal2BinaryBits(0x1234, 16)\n>0001001000110100\nprint Decimal2Binary(0x1234)\n>01001000110100\n</pre>', 'title': u'control leading zeros'}, {'comment': u"binary operators should be fastest when it comes to dealing\nwith binary values\n\n<pre>\n\ndef bit_is_set(n, num): return (1 << n) & num != 0\n\ndef int_to_bin(num):\n out, n = '', 0\n while (1 << n) <= num:\n out += ((1 << n) & num != 0) and '1' or '0' # bit_is_set()\n n += 1\n return out and out[-1::-1] or '0'\n\n</pre>", 'title': u'a bit faster'}], 'desc': u'Converting binary numbers to decimal and vice-versa in the most straightforward way.'}, {'comments': [], 'desc': u"If each class's __init__ is used to set default values, it requires that one use super() or explicit parentclass.__init__() calls . Such ugly boilerplate can be avoided with this recipe. "}, {'comments': [{'comment': u'It took me a while to find this solution for a stoppable server. So I am very happy with it. However...\n\nThe server ends with an exception because get_request returns nothing with a timeout and handle_request tries to handle that nothing.\n\nresult:\n<pre>\nException in thread Thread-1:\nTraceback (most recent call last):\n File "C:\\Python24\\lib\\threading.py", line 442, in __bootstrap\n self.run()\n File "C:\\Python24\\lib\\threading.py", line 422, in run\n self.__target(*self.__args, **self.__kwargs)\n File "../../lib/src\\webservice.py", line 79, in serve\n self.handle_request()\n File "C:\\Python24\\lib\\SocketServer.py", line 217, in handle_request\n request, client_address = self.get_request()\nTypeError: unpack non-sequence\n</pre>', 'title': u'Exception after stopping the server'}, {'comment': u'The problem above might be caused by the fact that my implementation is a bit different (it is a SimpleXMLRpcServer i.s.o. a HTTPServer).<br>\nThe/a solution to my problem is to return (None,None) in get_request and handle a None request in also override close_request and process_request to handle the special case where the request is None. Heres the result.<br>\n<br>\nQuestions remain: Has anyone found a better solution for this (it seems cumbersome)? Is there something like an empty request - making it possible to remove some ifs?\n\n<pre>\nclass XMLRPCWebService(SimpleXMLRPCServer.SimpleXMLRPCServer):\n allow_reuse_address = True\n def __init__( self, host, port):\n SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self,(host,port))\n\n def server_bind(self):\n SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)\n self.socket.settimeout(1)\n self.stop_request = False\n \n def get_request(self):\n while not self.stop_request:\n try:\n sock, addr = self.socket.accept()\n sock.settimeout(None)\n return (sock, addr)\n except socket.timeout:\n pass\n return (None,None)\n \n def close_request(self, request):\n if (request is None): return\n SimpleXMLRPCServer.SimpleXMLRPCServer.close_request(request)\n \n def process_request(self, request, client_address):\n if (request is None): return\n SimpleXMLRPCServer.SimpleXMLRPCServer.process_request(request, client_address)\n \n def start(self):\n threading.Thread(target=self.serve).start()\n \n def stop(self):\n self.stop_request = True\n\n def serve(self):\n while not self.stop_request:\n self.handle_request()\n</pre>', 'title': u'Solution'}], 'desc': u'The usual Python HTTP server never stops. Since there is the timout option in the socket module, there is an easy way to do a clean shutdown of a running server.'}, {'comments': [{'comment': u'The special cases for length zero, one, and two can be eliminated. All the logic you need is in the final block:\n\n<pre>\ndef allstrings(alphabet, length):\n """Find the list of all strings of \'alphabet\' of length \'length\'"""\n\n c = [[]]\n for i in range(length):\n c = [[x]+y for x in alphabet for y in c]\n return c\n</pre>', 'title': u'Simplified'}, {'comment': u'Thanks for the modification; but I think the function should output [] for length=1. Here is another modification to do that:<br>\n\n<pre>\ndef allstrings2(alphabet, length):\n\t"""Find the list of all strings of \'alphabet\' of length \'length\'"""\n\n\tc = []\n\tfor i in range(length):\n\t\tc = [[x]+y for x in alphabet for y in c or [[]]]\n\t\t\n\treturn c\n</pre>', 'title': u' '}, {'comment': u'It should be, "but I think the function should output [] for length=0."', 'title': u'Sorry'}], 'desc': u'This recipe shows a way to generate a list of all strings (in this case, string=list of symbols) of a given alphabet having a specified length; by using list comprehensions.\n\nUPDATE: The case for alphabet length = 1 is fixed.'}, {'comments': [{'comment': u'You can save a lot of trouble by simply installing Optik for older versions of Python. Optik was renamed optparse when it was included in Python. Then simply do:\n\n<pre>\ntry:\n import optparse\nexcept ImportError:\n try:\n import optik as optparse\n except ImportError:\n print "Optik is required: download from http://optik.sf.net"\n raise\n</pre>', 'title': u'Optik'}, {'comment': u'I agree, but optik is not available in the standard library.\nIf you are constrained to use only the standard library, then\nthis recipe is helpful.\n\n-Anand', 'title': u'Agree, but'}, {'comment': u'That makes no sense. If you can use this recipe, you can just as easily use optik. Neither are in the standard library.', 'title': u' '}, {'comment': u"... because if you used Optik you would have to distribute it with your software for it to be able to run right out-of-the-box. This might not always be feasible, for example if you're just writing a one-file script or if the BSD licence of Optik is not compatible with the one your software uses.", 'title': u'I does make sense'}, {'comment': u'BSD license not compatible with the license your software uses? Not possible unless the license your software uses is braindead.', 'title': u' '}], 'desc': u'When writing applications that take command-line arguments in Python, one has to make a choice between the two command-line parsing modules, getopt and optparse. Optparse though more powerful than getopt is available only since Python 2.3. Hence if you are writing a program targeted at Python 2.2 +, you are mostly constrained with using getopt and writing command line parsing code on top of it.\n\nThis recipe provides a solution to this problem. It masks the actual module used for option parsing from the application. If optparse is available it is used, otherwise the parser class defaults to getopt. The application only requires to pass a dictionary of \noption keys and their settings, in a format inspired by optparse, but using tuples.'}, {'comments': [{'comment': u'The second parameter, "size", would be better named "numPieces", since split_seq([]..., x) always returns a list with x pieces.\n<br>\n>>> split_seq(range(10), 1)\n<br>\n[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]\n<br>\n>>> split_seq(range(10), 2)\n<br>\n[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] ', 'title': u'Naming suggestion'}, {'comment': u'Here is an all integer method that builds a list of ranges first, then splices the sequence.\n\n<pre>\ndef split_seq(seq, numpieces):\n seqlen = len(seq)\n d, m = divmod(seqlen, numpieces)\n rlist = range(0, ((d + 1) * (m + 1)), (d + 1))\n if d != 0: rlist += range(rlist[-1] + d, seqlen, d) + [seqlen]\n\n newseq = []\n for i in range(len(rlist) - 1):\n newseq.append(seq[rlist[i]:rlist[i + 1]])\n\n newseq += [[]] * max(0, (numpieces - seqlen))\n return newseq\n</pre>', 'title': u'All integer approach'}, {'comment': u'This version uses integer math and distributes the remaindered items evenly over the first few splits.\n\n<pre>\ndef split_seq(seq, p):\n newseq = []\n n = len(seq) / p # min items per subsequence\n r = len(seq) % p # remaindered items\n b,e = 0, n + min(1, r) # first split\n for i in range(p):\n newseq.append(seq[b:e])\n r = max(0, r-1) # use up remainders\n b,e = e, e + n + min(1, r) # min(1,r) is always 0 or 1\n\n return newseq\n\n\n>>> split_seq(range(10), 3)\n[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]\n>>> split_seq(range(11), 3)\n[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]\n>>> split_seq(range(10), 4)\n[[0, 1, 2], [3, 4, 5], [6, 7], [8, 9]]\n</pre>', 'title': u'alternate implementation using integers'}, {'comment': u'def splitCeil(seq, m):<br>\n """Distribute the seq elements in lists in m groups<br>\n according to quasi equitative distribution (decreasing order):<br>\n splitCeil(range(13), 4) --> seq = range(13), m=4 <br>\n result : [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]<br>\n """<br>\n n,b,newseq=len(seq),0,[]<br>\n for k in range(m):<br>\n q,r=divmod(n-k,m)<br>\n a, b = b, b + q + (r!=0)<br>\n newseq.append(seq[a:b])<br>\n return newseq<br>\n<br>\n<br>\ndef splitFloor(seq, m):<br>\n """Distribute the seq elements in lists in m groups<br>\n according to quasi equitative distribution (increasing order):<br>\n seq = range(13), m=4<br>\n result : [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11, 12]]<br>\n """<br>\n n,b,newseq=len(seq),0,[]<br>\n for k in range(m):<br>\n a, b = b, b + (n+k)//m<br>\n newseq.append(seq[a:b])<br>\n return newseq<br>', 'title': u'again, an integer approach'}], 'desc': u'Break a list into roughly equal sized pieces.'}, {'comments': [{'comment': u'This is great, a real brain-twister :) And very Pythonic at that.\n\nI wonder how to reset the thing at runtime, so that the function can be re-run in case background data changes - is it possible?', 'title': u'Great, but - how to reset?'}, {'comment': u'1. I liked your idea, so I reimplemented the recipe<br>\n2. I found and fixed a bug when using @once with a method, now there are two implementations<br>\n3. The new implementations are about 2 times faster than the old one<br>\n<br>\nI think the speedup comes from replacing that extra function call with a cheaper getattr-in-a-try-block. I stopped using the local list to hold the result, even though it is slightly faster, because the code is less readable.', 'title': u'Hmm...'}], 'desc': u'This decorator runs a function or method once and caches the result.\n\nIt offers minimal memory use and high speed (only one extra function call). It is _not_ a memoization implementation, the result is cached for all future arguments as well.\n\nThis code is used in the TestOOB testing framework (http://testoob.sourceforge.net).'}, {'comments': [{'comment': u'- Thanks for this, good example of raw tag-pulling using mechanize. I wonder why you chose mechanize rather than, say, Beautiful soup, when even pullparser\'s author has recommended the latter\n<br>\n- a couple of tag contents "100 projects" "57 projects" aren\'t labelled as to where they\'re hard-coded from, but i\'m pretty sure it\'s from the ADA project\n<br>\n- hard tabs?!', 'title': u'useful example'}], 'desc': u'This recipe uses the mechanize module to grab the "number of projects per progamming language" information from two large opensource software release sites. The information is interesting when comparing popularity of programming languages.'}, {'comments': [{'comment': u'<pre>\nfrom calendar import monthrange\n\t\ndef dow_date_finder(which_weekday_in_month=FIRST,day=MONDAY,month=JANUARY,year=2000):\n bom, days = monthrange(year, month)\n firstmatch = (day - bom) % 7 + 1\n return xrange(firstmatch, days+1, 7)[which_weekday_in_month]\n</pre>', 'title': u'Alternate version using the calendar module'}, {'comment': u"You might want to embed that last line in a try/except to catch the case when the requested day does not exist, e.g. there's not a 5th Thursday of Nov 1977 but there is in 1978:\n<br><br><pre>\n try:\n return xrange(firstmatch, days+1, 7)[which_weekday_in_month]\n except:\n return None</pre>", 'title': u' '}], 'desc': u'What is the 2nd last Friday in May 2005 ? What is the\nfirst Monday in August 2006 ?\n\ncutoff_date = dow_date_finder(SECONDLAST,FRI,OCT,2005) '}, {'comments': [], 'desc': u"A generator which provides a quick way to 'walk' a zip file archive.\nThe generator can process multiple zip archives, i.e zip files which\ncontain zip files. Inspired by the os.walk function."}, {'comments': [{'comment': u'<pre>>>> import base64\n>>> base64.encodestring("Test")\n\'VGVzdA==\\n\'\n>>></pre>', 'title': u'Have you tried the base64 module?'}, {'comment': u"Who needs a module?\n\n<pre>\n>>> 'Test'.encode('base64')\n'VGVzdA==\\n'\n</pre>", 'title': u' '}], 'desc': u'I am new to python so I need lots of help on this code\nbasically what it does is takes a decimal number(155) converts it into binary(10011011) takes the first six numbers in that(100110) converts that into a decimal number(38) and from there makes it a letter("m") according to the base64 code (http://email.about.com/cs/standards/a/base64_encoding.htm)'}, {'comments': [], 'desc': u'Here is a simple example showing how to correctly use the UDP multicast functionality of twisted.'}, {'comments': [{'comment': u'This need is pretty much met by StringIO and cStringIO. The difference in performance between cStringIO and "".join(iterable) is pretty much dependent entirely on the actual data - there\'s generally no performance reason to prefer one over the other.', 'title': u'(c)StringIO'}, {'comment': u'This recipe effectively maintains two positions, one for writing and one for reading. This way you can keep adding data for read() using write(), which is useful for socket communication.<br>\nHere\'s an implementation that leverages StringIO:\n\n<pre>\ndef independent_position(func):\n attrname = "_%s_pos" % id(func)\n def wrapper(self, *args, **kwargs):\n self.seek(getattr(self, attrname, 0))\n try: return func(self, *args, **kwargs)\n finally: setattr(self, attrname, self.tell())\n return wrapper\n\nfrom StringIO import StringIO\nclass StringQueue(StringIO):\n write = independent_position(StringIO.write)\n read = independent_position(StringIO.read)\n</pre>\n ', 'title': u"Right, but it's still nice"}, {'comment': u'Neat hack! The independent read and write position is not met by StringIO, hence the above recipe.\n\nI think I like yours more than the original. :-)', 'title': u"Agreed, StringIO doesn't fit the requirement exactly."}, {'comment': u"... but kept putting it off. I liked your recipe, and then Tim's comment made me think. :-)<br>\nIs there a simple way to use cStringIO instead of StringIO? Can't subclass it...", 'title': u'I was needing such a thing for a while...'}, {'comment': u'cStringIO lacks write(), AFSIK.\n<br><br>\nAnyway, the StringIO approach would be more memory hugry: the whole written and read data would be kept in memory for as long as the queue is in use. The recipe, on the other hand, just holds unread data - for most network apps just be enough.', 'title': u'cStringIO lacks write'}, {'comment': u'There\'s a bug in this, which is hard to get rid of. "" (the empty string) signals EOF; however, if there is no queued data, this does not actually imply there\'s no additional data.<br><br>\n\nSadly there\'s not a very good way around this. You could change the file protocol and say "" is a reasonable return, and you should catch EOFError to signal the end (assuming you also add a .close() method -- though would it mean you close the reader or the writer interface?).\n<br><br>\nThe other way is to block when no data is waiting, on the hope that some other thread will add data. And you have to set up the proper events to do that properly. Which is a bit painful as well, and of course only makes sense in a threaded environment, since without threads there\'s no way data could appear while you are blocking on a read.', 'title': u'EOF Bug'}, {'comment': u"I'm not sure I follow.\n\nI can't see where I would need an EOFError, except to mimic the File object more closely. In all instances where I've used this class, I've not found a need to implement this.", 'title': u'EOF Bug?'}, {'comment': u"An example might go like this:\n\n<pre>\ndef poll_file(filename, squeue):\n last_size = 0\n while 1:\n size = os.stat(filename).st_size\n if size <= last_size:\n time.sleep(1)\n f = open(filename, 'rb')\n f.seek(last_size)\n content = f.read()\n f.close()\n last_size += len(content)\n squeue.write(content)\n\nmy_squeue = StringQueue()\nthreading.Thread(target=poll_file, args=('f1.txt' my_squeue)).start()\n\ndef consumer():\n while 1:\n content = my_squeue.read(1000)\n if not content:\n break\n print 'New content:', repr(content)\n</pre>\n\nIt's a little contrived, but anyway... the point is, if my_squeue was a normal file, then it would return strings in response to .read(), until it returned the empty string, at which point EOF would have been reached and the loop should terminate. But with StringQueue, it will return an empty string if there's no input waiting, but it *doesn't* mean EOF was reached, just that there's no waiting input.<br><br>\n\nOf course, this is only an issue if you are really treating the queue just like you would a file. But if you weren't, then a list or Queue.Queue object would work just as well.", 'title': u'example'}, {'comment': u'"But if you weren\'t, then a list or Queue.Queue object would work just as well"\n<br><br>\nI use this class to read data from a network socket, where I generally know exactly how many bytes I need to read. As stated above: \'This class takes care of the list.append and "".join mess, which is needed for fast string concatenation.\' \n<br><br>\nIt is really just a simple wrapper around a list object, not a complete File-like class.', 'title': u'Queue.Queue and list'}, {'comment': u'<pre>\nimport cStringIO\nwritable = cStringIO.StringIO()\nwritable.write("You can write to me ...")\nunwritable = cStringIO.StringIO("... but not to me.")\n</pre>', 'title': u'Only if initialized with a string'}], 'desc': u'A queue data structure, for string data only, which looks like a File object. This class takes care of the list.append and "".join mess, which is needed for fast string concatenation.'}, {'comments': [{'comment': u'I need something that does EAN and UPC-A. Any way to do that in Python?', 'title': u'Would you consider doing one for UPC-A ?'}], 'desc': u'This class generate EAN bar code, it required PIL (python imaging library)\ninstalled.\n\nIf the code has not checksum (12 digits), it added automatically.\n\nCreate bar code sample :\n from EANBarCode import EanBarCode\n bar = EanBarCode()\n bar.getImage("9782212110708",50,"gif")'}, {'comments': [{'comment': u"You should reformat your code snippets in the discussion via <pre>, and verify it looks the way you want it to with the 'preview' button.", 'title': u'preview is your friend'}, {'comment': u'Yes, now it looks much better indeed.', 'title': u'Good point'}, {'comment': u'Added a few useful predicates:<br>\n<br>\n@takes(list_of(int))<br>\n- checks whether the parameter is a uniform list of ints<br>\n<br>\n@takes(tuple_of(int))<br>\n- checks whether the parameter is a uniform tuple of ints<br>\n<br>\n@takes(dict_of(str, str))<br>\n- checks whether the parameter is a dict mapping strs to strs<br>\n<br>\n@takes(by_regex("^[0-9]{1,8}$"))<br>\n- checks whether the parameter is a str or unicode conforming to a regex<br>', 'title': u'Added predicates'}, {'comment': u'Added another predicate useful for checking protocol conformance:<br>\n<br>\n@takes(with_attr("read", "write"))<br>\n- checks whether the parameter has particular attributes', 'title': u'Added predicate'}, {'comment': u'Added one_of checker and support for checking kwargs', 'title': u' '}], 'desc': u'This recipe adds parameter type checking to each method or function invocation. Not a replacement for static typing, but it makes a nice pair of shackles to me.'}, {'comments': [{'comment': u'def colsplit(l, cols):<br>\n....rows,r = divmod(len(l),cols)<br>\n....rows += (r!=0)<br>\n....m = []<br>\n....for i in range(rows):<br>\n........m.append(l[i::rows])<br>\n....return m<br>', 'title': u' a light modification'}, {'comment': u'This recepie is quite nice for dividing a sequence for the presentation needed. However, the last sequence could end up containing only one item. If minimizing skew between result sequences is important, see the recepies the author referenced in the discussion.', 'title': u'To skew or not to skew...'}], 'desc': u"Break a list into roughly equaly sized 'columns', e.g. for display in a table."}, {'comments': [{'comment': u"Worth noting that random.sample handles iterators:\n<pre>\npy> import random\npy> i = iter(range(10))\npy> random.sample(i, 2)\n[2, 0]\n</pre>\nI don't know if it makes any guarantees about efficiency though.", 'title': u'random.sample handles iterators'}, {'comment': u"Unlike random.sample, the OP's recipe samples with replacement -- whether that is a feature or bug is another question. Given an iterator input, the OP's function has the virtue of not pulling all the data into memory at once; in contrast, random.sample will sometimes (depending on the ratio of population size to sample size) pull all the data into memory. In terms of operating efficiency, the OP's recipe uses far too many calls to the underlying random number generator; in contrast, random.sample makes at many fewer calls. Here's an alternate recipe that gives the best of both worlds (memory efficiency and fewer calls to the generator):\n<pre>\nfrom random import random, shuffle\n\ndef random_items(iterable, k=1):\n result = [None] * k\n for i, item in enumerate(iterable):\n if i < k:\n result[i] = item\n else:\n j = int(random() * (i+1))\n if j < k:\n result[j] = item\n shuffle(result)\n return result\n</pre>\n", 'title': u'Comparison with random.sample'}, {'comment': u'Oooh, nice, Raymond.', 'title': u'Clever'}, {'comment': u"assuming that generally len(iterable) >> k, for efficiency's sake you'd be better off splitting the loop in two parts, to avoid the soon-to-be-useless comparison i assuming that generally len(iterable) >> k, for efficiency's sake you'd be better off splitting the loop in two parts, to avoid the soon-to-be-useless comparison i ", 'title': u'further split your loop'}, {'comment': u"Please correct me if I'm wrong, but it seems like the first items in the iterable will have a much greater chance of being picked than the higher ones.\n\nConsider <pre>random_items(iter(range(1000)), 5)</pre>\nIn this case, after the first 5 items are in result the algorithm will begin generating random numbers and replacing items in result with k/n probability, with k being the desired number of random items and n being the index of each item in the iterable. So the chance for 20 being in the result (at some point during the algorithm) is 5/20, and the chance for 950 would be 5/950. Also, the lower numbers get replaced so in this case, there is almost no chance that the numbers 0-45 will be in the final array.\n\nThis is a good algorithm for picking some numbers from an iterable, but it does not seem to pick uniformly random items.", 'title': u'Correctness'}, {'comment': u'When we actually try it, say running it 1000 times so each item can expect to be picked 5 times in total:\n\n<pre>\nlcTotalPicks = [0] * 1000\nfor i in range(1000):\n lcPicks = random_items(iter(range(1000)), 5)\n for j in lcPicks:\n lcTotalPicks[j] += 1\n</pre>\n\nwe find no significant difference between the first 20 and the last 20 items:\n\n<pre>\nprint lcTotalPicks[0:20]\nprint lcTotalPicks[980:1000]\n\n[4, 4, 7, 9, 4, 2, 4, 2, 7, 4, 8, 9, 4, 7, 6, 7, 8, 8, 5, 1]\n[4, 3, 1, 9, 9, 3, 4, 9, 8, 8, 3, 5, 6, 5, 4, 5, 5, 7, 4, 6]\n</pre>\n\nIndeed, lower numbers are more likely to be in the result, and also more likely to be replaced. The two effects cancel out, and every number has the same "almost no chance" (5/1000) to be included in the final result.', 'title': u'And yet ...'}], 'desc': u"Each item has an equal chance of being picked. The iterator is processed only once, and only the selected items are stored, making this function memory efficient.\n\nThis is based on idea from Richard Papworth's recipe that picks a random from a file - see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/59865 - but is more general."}, {'comments': [], 'desc': u'The story behind this one is that I was building a database conversion utility, converting both schema and data from one database engine to another. Thing was, the target database only allows 10 characters in its table and column names. I stripped down the longer entity names by removing whitespace and spacing characters, then non-leading vowels, and at the last resort, I truncated.\n\nThis worked on the whole, but I was getting the occasional duplicate, so I came up with this.'}, {'comments': [{'comment': u"Sorry - can't resist it. An easier way to read *and* write config files is using ConfigObj - <br> http://www.voidspace.org.uk/python/configobj.html<br>\n\nIt presents a dictionary interface (members rather than attributes) - which IMHO is more Pythonic (a config file is well represented by a mapping object) *and* less limited (you can't use some values as attributes (e.g. ``print``) - so you *have* to provide another way of accessing members, which violates - 'there should be only one obvious way to do it').<br>\n<br>\n<pre>\nconfig = ConfigObj(filename)\nvalue1 = config['member1'] \nvalue2 = config['member2']\n</pre>\n*or*<br>\n<pre>\nconfig = ConfigObj()\nconfig.filename = filename\nconfig['member1'] = value1\nconfig['member2'] = value2\nconfig.write()\n</pre>\n<br>\nNot only this - but ConfigObj 4 is *nearly* ready. It's all implemented except for preserving comments and the ``writein`` method. It has a powerful interface to a validation schema, but the main change is that it will read sections nested to any arbitrary depth using indentation. (But will still read and write simple INI files). This version has no external dependencies.\n<br>\nFetch it from : <br>\nhttps://svn.rest2web.python-hosting.com/branches/configobj4/", 'title': u'ConfigObj'}], 'desc': u'Python includes the ConfigParser module in its library, which is able to read .ini files.\nTo make the configuration code more readable, I wrote this Configuration class, which parses an .ini file and lets you access the configuration info through its members.\nPlease see the test code (after the #Test comment) for an example of use!'}, {'comments': [{'comment': u'This works perfectly except for 1 problem I have, which is, I think, with wxPython itself. The problem is that the column header remains obscured as if the graphic was still there after sorting on another column. I have tried numerous workarounds involving wx.NullBitmap, my own image lists with 1 pixel wide images, etc. No luck. Otherwise it works great and seems faster than using the list control alone.', 'title': u'One wx problem'}, {'comment': u'The data can be any sequence: all that is required is that the itemDataMap support the __get__ method with an integer argument, which obviously applies to any sequence. This simplifies the data input quite a bit.', 'title': u'dict not required'}, {'comment': u'This code has been very helpful! I appreciate that you shared it with all of us. =)<br><br>\n\n@David S<br>\nThe problem with the column header lies in wxPython. More specifically, it lies in the function that is used when clearing the "arrow" image from the previously sorted column.<br><br>\n\nBefore you click on a column to sort it, the columns are not obscured yet because they are not set to show an image -yet-. After you click it, it sets that column to allow an image and then loads the image you specified into it. When you sort another column afterwards, the function that is used to clear that image only sets the image to nothing. It does not tell the program you don\'t need space there for an image anymore; therefore, the program still thinks an image is being used there and leaves space open for it.<br><br>\n\nYou\'ll have to override this function in your listctrl class.<br>\nIt\'s called: ClearColumnImage(self, col)<br><br>\n\nI overrided it with nearly the same code it uses--except, without the code that tells it to save space for an image. The function is in the _controls.py file.', 'title': u'Thank you'}, {'comment': u"Here's a better SortItems() method -- the ColumnSorterMixin.__ColumnSorter() method already handles the ascending/descending, and it knows to sort on another column if the chosen columns have the same value.\n\n<pre>\n def SortItems(self,sorter=cmp):\n items = list(self.itemDataMap.keys())\n items.sort(sorter)\n self.itemIndexMap = items\n \n # redraw the list\n self.Refresh()\n</pre>", 'title': u'A better SortItems method'}, {'comment': u'Thanks Matt,\n\nI swapped my SortItem function for yours (nearly 6 months after you submitted it, sorry!). I really like what you did!\n\nCheers,\nEgor', 'title': u'Code update...'}], 'desc': u'This recipe shows a way of using ColumnSorterMixin with virtual lists (wx.ListCtrl defined with the wx.LC_VIRTUAL flag). The sample code pretty much follows the wx.listctrl demo (provided with wxPython). The interesting bit is the TestVirtualList class and the musicdata dictionary (altogether lines 42 to 257). Remainder is provided to run the TestVirtualList class (or others from the wxdemo) standalone.\n\nThe idea is to combine an itemDataMap dictionary with an index table which defines the order in which the dictionary items are displayed. The actual display is handled by the virtual list using only the OnGetItemText, OnGetItemImage and OnGetItemAttr methods.\n\nFirst of all, the 3 methods OnGetItemText OnGetItemImage and OnGetItemAttr must be declared. Following the ListCtrl demo and in addition to the self.itemDataMap dictionary, a self.itemIndexMap table defines the items order.\n\nColumnSorterMixin uses the SortItems, GetListrCtrl and GetSortImages methods which are redefined here.\nGetListCtrl now returns self (to keep the mixin happy). GetSortImages is pretty much the same as in the ListCtrl demo, only it uses the art provider (needs better looking arrows, maybe). SortItems handles the sorting. It gets the column clicked from the mixin _col variable and the sorting order (ascending or descending) from the _colSortFlag table.'}, {'comments': [{'comment': u'How is this different to or better than using XRCed resource editor and the xrc module that comes with wxPython?', 'title': u'Resource Editor'}, {'comment': u'The problem is that the xrc module is not well documented (well, there\'s an example in the demo and that\'s about it).<br>\n\nI found a wiki with a reasonably well explained example here: http://wiki.wxpython.org/index.cgi/UsingXmlResources<br>\n\nThe difference between the two XML structures is that XMLMenuLoader focusses on the menu structure only, rather than the whole application.<br>\n\nFrom the example again, this is how the menu xml looks like\n<pre>\n <object class="wxMenuBar" name="MenuBar"> \n <object class="wxMenu" name="OperationMeu"> \n <label>Operations</label> \n <object class="wxMenuItem" name="AddMenuItem"> \n <label>&Add</label> \n <accel>Ctrl-A</accel> \n <help>Add second arg to the first arg.</help> \n </object> \n <object class="wxMenuItem" name="SubstractMenuItem"> \n <label>&Substract</label> \n <accel>Ctrl-S</accel> \n <help>Substract second arg from the first arg.</help> \n </object> \n <object class="separator"/> \n <object class="wxMenuItem" name="MultiplyMenuItem"> \n <label>&Multiply</label> \n <accel>Ctrl-M</accel> \n <help>Multiply first arg by second arg</help> \n </object> \n <object class="wxMenuItem" name="DivideMenuItem"> \n <label>&Divide</label> \n <accel>Ctrl-D</accel> \n <help>Divide first arg by second arg.</help> \n </object> \n </object> \n </object>\n</pre>\n\nI think the structure in XMLMenuLoader is a bit lighter (easy enough to be edited by hand if needed):\n<pre>\n<menubar>\n <menu name=\'_File\'>\n <menuitem name=\'_New\' callback=\'OnChoice\'/>\n <menuitem name=\'_Open...\' callback=\'OnChoice\'/>\n <menu name=\'_Export to\'>\n <menuitem name=\'Jpeg...\' callback=\'OnChoice\'/>\n <menuitem name=\'Png...\' callback=\'OnChoice\'/>\n </menu>\n <separator/>\n <menuitem name=\'E_xit\' callback=\'OnCloseWindow\'/>\n </menu>\n</menubar>\n</pre>\n\nXMLMenuLoader also connects elements in the menu with function names and handles non-existing functions gracefully.', 'title': u'Re: Resource Editor'}, {'comment': u"Thank you for responding to my question Egor. I think you raise valid issues. I'll have to look a little more closely.", 'title': u'Resource Editor'}], 'desc': u'XMLMenuLoader uses XML definitions to create a wx.MenuBar. It is based on the code in this post:\n\nhttp://mail.python.org/pipermail/python-list/2001-June/046912.html\n\nand adds checkable menus and submenus.'}, {'comments': [{'comment': u'Also, you can do this with:\n<pre>\nzip(*[iter(s)]*bite)\n</pre>\nSo that your code works like:\n<pre>\npy> bite = 3\npy> a = "supercalifragalisticexpialidocious"\npy> b = [\'sup\', \'erc\', \'ali\', \'fra\', \'gal\', \'ist\', \'ice\', \'xpi\', \'ali\', \'doc\', \'iou\']\npy> zip(*[iter(a)]*bite)\n[(\'s\', \'u\', \'p\'), (\'e\', \'r\', \'c\'), (\'a\', \'l\', \'i\'), (\'f\', \'r\', \'a\'), (\'g\', \'a\', \'l\'), (\'i\', \'s\', \'t\'), (\'i\', \'c\', \'e\'), (\'x\', \'p\', \'i\'), (\'a\', \'l\', \'i\'), (\'d\', \'o\', \'c\'), (\'i\', \'o\', \'u\')]\npy> zip(*[iter(b)]*bite)\n[(\'sup\', \'erc\', \'ali\'), (\'fra\', \'gal\', \'ist\'), (\'ice\', \'xpi\', \'ali\')]\n</pre>\nHowever, Guido views this as an abuse of the argument parsing machinery.', 'title': u' '}, {'comment': u'[a[x:x+bite] for x in range(0,len(a),bite)]', 'title': u'This might work better'}, {'comment': u'If you need it, use<pre>\n[s[x:x+bite] for x in range(0,len(s),bite) if x+bite<=len(s)]</pre>', 'title': u'... but it does not cut off the tail if len % bite != 0'}], 'desc': u'A (mostly) one-liner that cuts an iterable into X sized chunks... '}, {'comments': [], 'desc': u'This decorator runs a function/method the first time called, and on any subsequent calls when some user-defined metric changes. The metric function provided to the decorator is called every time, but the function being decorated is only called on the first call and when the metric changes.'}, {'comments': [{'comment': u'Is there any chance you could post the source for checkhotfix.py too?', 'title': u'checkhotfix.py?'}, {'comment': u'There is a repository of Python scripts for Windows admin task on the Microsoft web site:<br>\n<pre>\nhttp://www.microsoft.com/technet/scriptcenter/scripts/python/default.mspx\n</pre>\n<br>\nIf you need to access the Windows registry in your Python script, have a look at this recipe:<br>\n<pre>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66011\n</pre>', 'title': u'Useful links'}], 'desc': u"The following is a guide for Windows administrators who would like to use Python for their login scripts. Once, you've found Python, you'll never go back to VbScript or the dreaded batch files. "}, {'comments': [], 'desc': u'This code converts variables which is made with upper-leters only, into\nconstants at compile time, if it is possible to be replaced. and generate\n.pyc file.\n\nThis recipe pay attensions to the compile time evaluation,\nthe feature of Constants. '}, {'comments': [], 'desc': u'This recipe allows for calling an unlimited chain of nonexistent attributes - every call is forwarded to a default method with attribute chain as argument.'}, {'comments': [{'comment': u'As of Python 2.3 the os.walk() function does much the same thing and allows for selectivly choosing which directories are examined. See http://python.org/doc/2.4.1/lib/os-file-dir.html#l2h-1636', 'title': u'os.walk() is currently preferred and non-recursive'}, {'comment': u"Oh... that's right.\nThanks for pointing that.", 'title': u' '}], 'desc': u'An equivalent of os.path.walk(), but without callback function.'}, {'comments': [], 'desc': u'In console-less environments, printing raises an exception.\nDisabling all print statements can be a pain.\nThis recipe allows you to leave all print statements in place.'}, {'comments': [{'comment': u'I can only get this to work with windows bitmap files', 'title': u'only BMPs on Windows XP'}, {'comment': u"To use anything besides BMP files, you'll need to use ActiveDesktop functions. I don't know if that can be done via Python -- is there any way to get a pointer to the IActiveDesktop interface (CLSID_ActiveDesktop, IID_IActiveDesktop)? In C++ you'd use the CoCreateInstance function.", 'title': u'use ActiveDesktop functions for non-BMP images'}], 'desc': u'Change the current wallpaper under Windows'}, {'comments': [], 'desc': u"There was recently a short discussion about some way to make certain initialization of instances easier (less typing). This was then followed by an expression of a desire for the automatic generation of the __slots__ attribute for classes (which is generally painful to do by hand for any nontrivial class). This recipe defines a metaclass and a function. The 'AutoSlots' metaclass automatically generates a __slots__ attribute during compilation, and the 'InitAttrs' function initializes instance variables during runtime.\n\nA variant which only requires the metaclass would be convenient and would be graciously accepted."}, {'comments': [{'comment': u"On the expense of one more line (and the re module plus the regular expression inserted into your namespace), you can get some speed (On my PC, for the contents of a random python script, it finishes in a third of the time) by pulling almost everything out of the function. Of course, this works best if you use this function quite often.\n<pre>import re\n_newlines_re = re.compile(r'(\\r\\n|\\r|\\r)')\ndef _normalize_newlines(string):\n return _newlines_re.sub('\\n', string)\n</pre>", 'title': u'Speed up by precompiling regular expression'}, {'comment': u'It\'s even better to do two replace calls:\n\n<pre>\n#!/usr/bin/env python\nimport profile, re, random\n\ns = "".join([random.choice(" \\n\\r") for i in range(10000)])\n\ndef use_re_sub():\n global r1\n for i in range(1000):\n r1 = re.sub(r\'(\\r\\n|\\r|\\n)\', \'\\n\', s)\n\n_newlines_re = re.compile(r\'(\\r\\n|\\r|\\n)\')\ndef use_re_compile():\n global r2\n for i in range(1000):\n r2 = _newlines_re.sub(\'\\n\', s)\n\ndef use_replace():\n global r3\n for i in range(1000):\n r3 = s.replace(\'\\r\\n\', \'\\n\').replace(\'\\r\', \'\\n\')\n\nprofile.run(\'use_re_sub()\')\nprofile.run(\'use_re_compile()\')\nprofile.run(\'use_replace()\')\nassert r1 == r2 == r3\n</pre>\n\nThe last version is several times faster (of course this also depends on the string you convert).', 'title': u"don't use regular expressions when not really needed."}, {'comment': u"When this function shows up in my profiler I'll probably do this.\n\nUntil it does, I prefer the greater readability -- in my eyes -- of not precompiling the expression.", 'title': u'Good point'}, {'comment': u"It's there for readability.\n\nReplacing (\\r\\n|\\r|\\n) with whatever (I arbitrarily chose '\\n') sits in my mind fairly well. And I understand that regex at a single glance.\n<br><br>\nI agree that using two replaces, noting that '\\n' need not be replaced with '\\n', is both efficient and clever.\n<br>\nI'll probably stay with the regex, though, because I find it easier to understand, and it isn't a performance hit in my application yet.", 'title': u"The regular expression isn't there for special features"}], 'desc': u'When comparing text generated on different platforms, the newlines are different. This recipe normalizes any string to use unix-style newlines.\n\nThis code is used in the TestOOB unit testing framework (http://testoob.sourceforge.net).'}, {'comments': [{'comment': u"Thanks for this neat code!\n\nI think I've found a small bug in it:\nin the dismissWorker() function, I think the max() call should be min()", 'title': u'A small bug'}, {'comment': u"Silly me! Of course you're right. I've fixed the recipe and the version on my website.<br>\n<br>\nI also made a slight change to the WorkerThread class and replaced the _dismissed flag with a threading.Event object.", 'title': u'Thanks!'}, {'comment': u'I have uploaded a new version (1.2) that has exception handling to my website (see above for link). Check it out!', 'title': u'New enhanced version on my website'}, {'comment': u'i believe the<br><br>\n\nif item == isinstance(item, tuple):<br><br>\n\n\nshould be<br><br>\n\nif isinstance(item, tuple):', 'title': u'version 1.2.1, line 236'}, {'comment': u'Fixed in version 1.2.2 on my website', 'title': u'Thanks!'}, {'comment': u"The assert is on an undefined variable 'req' Should be 'request'.\nThe self test works because 'req' is a global from the test.", 'title': u'A bug in version 1.2.2 putRequest, line # 195'}], 'desc': u"A thread pool is a class that maintains a pool of worker threads to perform\ntime consuming operations in parallel. It assigns jobs to the threads\nby putting them in a work request queue, where they are picked up by the\nnext available thread. This then performs the requested operation in the\nbackground and puts the results in a another queue.\n\nThe thread pool class can then collect the results from all threads from\nthis queue as soon as they become available or after all threads have\nfinished their work. It's also possible, to define callbacks to handle\neach result as it comes in.\n\nBasic usage:\n\n>>> main = TreadPool(poolsize)\n>>> requests = makeRequests(some_callable, list_of_args, callback)\n>>> [main.putRequests(req) for req in requests]\n>>> main.wait()\n\nSee the below for a longer, annotated usage example."}, {'comments': [{'comment': u'As I see, you have basically followed Alexander Semenov\'s remark to my recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410686 - see remark named "It is may be simpler", posted on 2005/05/07): Your Dispatcher class (which Alexander suggested naming Event) is basically my _EventSlot class spiced up with a bit of threading.\n\nOriginally, my Events class would be (and is) typically used like this:\n<pre>class Sprite:\n events = Events()\n...\n s = Sprite((2,4))\n def SpriteLocationChanged(oldLocation, newLocation):\n ...\n def SpriteImageChanged(oldImage, newImage):\n ...\n s.events.LocationChanged += SpriteLocationChanged\n s.events.ImageChanged += SpriteImageChanged\n</pre>\nNote - No extra event declarations needed. Particular events are added automatically as they are referred. This was exactly what I wanted.\n\nThe magic __events__ came in in order to gain *some* control over events that are subscribed to but never fired. With this aspect in mind, I certainly agree that Alexanders proposal and your implementation is the simpler and safer approach.', 'title': u'Dispatcher === _EventSlot'}, {'comment': u'Simplify:\n<pre>def __init__(self, targets=None, nonBlocking=True):\n self._targets = targets or []\n</pre>\n\nFix / make safer:\n<pre>def __iadd__(self, target):\n ##if target in self._targets: return #<- (*)\n self._targets.append(target)\n return self\ndef __isub__(self, target):\n # __iadd__ allows for multiple addition of the same target,\n # so we need to remove ALL occurences of target here\n # At the same time, we gracefully ignore targets that are not here\n # Alternatively, ensure a target is added only once ==> see (*)\n while target in self._targets:\n self._targets.remove(target)\n return self\n</pre>', 'title': u'Some hints'}, {'comment': u'Note that an event slot call in C# is definitely blocking, at least in WinForms applications on .NET 1.1.', 'title': u'Remark on "C#-style events ... are non-blocking by default"'}, {'comment': u'Just a few thoughts. I think the principle difference between this and the referenced recipe is that the former focuses on simplicity of design/implementation while the later focuses on ease of use within client code. I would certainly agree that it is easier to use the event dispatching mechanism provided by the referenced recipe, as only one declaration per "event set" is required, and events may be added without further declaration. One of the main design goals of the current recipe, however, is to implement the concept of dynamic dispatch without forcing the client code to group the objects being dispatched ("event", "message", whatever the necessary conceptualization may be) into one class whose sole purpose is to provide a (useful, to be sure) "bookkeeping" mechanism, which is the point I believe Alexander may have been making. I think this recipe is, as you said, simply a refinement of the _EventSlot class in the referenced recipe along the lines of Alexander\'s suggestions, with the added philosophy that the grouping of Dispatcher\'s within a separate class should merely be a design decision that is made within the client code, not within the implementation of the dispatching system. \n<br>\n<br>\nWith respect to introspection, I don\'t necessarily see the advantage of that the Events class provides. If a person would like to inspect the events that are currently available for a particular class, they would have to know something about the implementation of Events; namely, to look in the __name__ attribute of the contents of __event__. In the current recipe, however, one simply has to look for members of the class that are instances of Dispatcher, and not necessarily know anything about how Dispatcher is implemented.', 'title': u'Simplicity of implementation vs. simplicity of use'}, {'comment': u'In some situations I found it useful to loop over events<pre>\nfor event in obj.events:\n inspect(event)\n</pre>\nHowever, these situations were rare, and the same could be acomplished with<pre>\nfor name, event in vars(obj).items():\n if not isinstance(event, Dispatcher): continue\n inspect(event)\n</pre>\nThe more I think about it, the more I like the simplifications here. ;)', 'title': u'You are right'}, {'comment': u"Hmm... I was pretty sure of this. So I'll have to look into it pretty soon. In any case you can turn threading off, and you can change its default when you implement this in your own project.", 'title': u'Re: non-blocking'}, {'comment': u"I definitely still disagree here. I'm allowing that for each use of += with a handler, the programmer knows that he is adding it for the first time or not. Therefore, with the equivalent (and symmetric) -=, he knows he wants to remove one or more notifcations to a handler. I do not presume to know for every programmer how they want manage the possibility of multiple notifications, therefore, I leave it flexible.", 'title': u'Re:'}, {'comment': u'Accidental +=/-= asymmetry can lead to consecutive faults that are hard to track down to their real source. (For ex., a handler accidentally left in the dispatcher that accesses a destroyed widget might cause an exception saying that there\'s is no widget with id=xxx, which is a bit misleading about the real source of error.)<br>\n<br>\nSo, while your approach is straightforward, it is not flexible at all. On the contrary, my proposed "graceful release" is the really flexible approach: It is practically equivalent to yours in symmetric +=/-= situations, but handles asymmetric ones as well (instead of leaving the burden to the user of the code).<br>\n<br>\nIn my experience, it always paid off to go for a gracefull release.', 'title': u'straightforward != flexible'}, {'comment': u'Actually, in this case, yes it is. You seem to keep confusing the "conveniences" that you think *must* be enforced for all programmers as flexibility. Flexibility is defined as choices, and I\'m electing to leave choices of how to manage handlers there. It\'s completely stated what is done. Further, the straightforwardness of the recipe is such that the user can change the bit of code as they wish to do what you say, or manage it outside. Given that, I guess it might be nice to implement the "in" operator. Your "graceful release" may be a convenience, and you can argue all day about whether or not it is more healthy for all programmers aside from yourself, but the objective bottom line is that enforcing it and removing choice is not flexibility. Remember, this is a recipe, not a standard module for which I\'m going to attempt to make all choices and solve all problems for prospective useres. That\'s why it is flexible.', 'title': u'Re:'}, {'comment': u'Alrighty, it appears ALL events (not just within WinForms) are blocking on the .NET platform:\n\nhttp://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx\n\nSo I stand corrected on that. In any case it can be turned off or even easily excluded altogether in this recipe. But until I run into conflicts with any 3rd-party modules or frameworks I rather like the non-blocking option.', 'title': u'non-blocking'}, {'comment': u'Firstly, I don\'t think you are able to assert whether or not I am confusing something. The utmost that you can tell is that you don\'t see the connexion.\n<br><br>\nSecondly, and more important, if I am removing choice, as you say, then what kind of choice are YOU leaving open? The choice to modify that piece of code? Well, THAT is a choice that we already always had, with or without your effort. Sorry to disillusion you, but hey, thanks anyway.\n<br><br>\nAnd now for the better: Although it is refreshing to see people defending their recipes this passionately (including myself - sigh - what imperfect creatures we really are :), you should admit that this kind of discussion easily gets quite destructive. Let\'s try to change that:\n<br><br>\nIn one point I agree: This is a recipe, not a module. So your favor for straightforwardness over trickiness of design is comprehensible (however flexible and briliant that tricky design might be :p) But flexibility IS something else than a chance to change the code.\n<br><br>\nAnyway, I probably really *could* "argue all day", if you don\'t see the difference, then you don\'t see it. You\'ll know it once you experience it for yourself - just as with the blocking vs. non-blocking issue.\n<br><br>\nAnd now excuse me, I will make use of my freedom of choice to devote myself to more fruitful things... :D', 'title': u'Re yourself :p'}], 'desc': u'This is an dynamic dispatching approach inspired by C#-style events. The approach allows for the dispatch of an event to a series of chained methods through the use of a Dispatcher. The Dispatcher can be defined either as part of a class or merely as a variable in some code. When the Dispatcher is invoked the methods that are chained to it (i.e. handlers) are invoked. The dispatch can be either blocking or non-blocking, and is non-blocking by default.'}, {'comments': [{'comment': u'FWIW, deque() objects also work for your use case.', 'title': u'collections.deque()'}, {'comment': u"collection.dequeue surely worked, but I'm using greppy as a project to learn python. <br> It was funny to code RingList and if someone likes it... :)", 'title': u'Yep!'}], 'desc': u'The RingList is a class implementing a circular list.\nThe ring have a fixed size and when it is full and you append a new element, the first one will be deleted.\nThe class lets you access to the data like a python list or like a string.'}, {'comments': [{'comment': u'From the library reference:<br>\n<br>\n"If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single match object argument, and returns the replacement string."<br>\n<br>\nApplied to your problem (if I understood correctly what you meant):<br>\n<pre>\ndef repl_func(match):\n return "a%s-r" % match.group(1)\n\ntest = [\'asomething-d\', \'aother-d\', \'athing-d\', \'a-d\']\n\nfor item in test:\n print re.sub(r\'a(.+)-d$\', repl_func, item)\n</pre>', 'title': u'replacement can be a function'}, {'comment': u"This is what I'd add to the code, I only realized later. Thank you!", 'title': u'Thanks Chris!'}], 'desc': u"I needed to write a sed/awk Python equivalent for walking into a directory tree and renaming certain subdirectories, while also looking into all xml files on the way and replacing/modifying certain strings in those files.\n\nIt would be nicer if someone could suggest an enhanced re.sub(regex, replacement, subject) where I could replace all strings of a certain pattern with other strings of a certain pattern i.e. the second argument in re.sub namely 'replacement' would then be a regular expression and would be a different string for each different string in 'subject' that matches with the pattern 'regex'. For example 'arthinternational-d' would be replaced by 'arthinternational-r', 'arthfmt-d' would be replaced by 'arthfmt-r' but 'a-d' would remain unmodified."}, {'comments': [{'comment': u"On Linux, gnome-panel is ignored by wx.ClientDisplayRect() and 0,0 coordinates along with the full resolution is returned regardless of its position.<br><br>\n\nThis is rather unfortunate as it's exactly what I've been looking for over the past few hours.<br><br>\n\nAlso on both Linux and Windows, the above code fails if wx.App() has not been instantiated.<br><br>\n\nwxPython 2.8.0.1<br>\nPython 2.4.3 (#2, Oct 6 2006, 07:52:30)<br>\n[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2", 'title': u'Unfortunately this works for Windows only.'}, {'comment': u"The closet I've come so far is calling frame.Maximize() and frame.GetRect() which gives the desired output, but this requires the frame being shown in its maximized state which obviously isn't desirable.", 'title': u' '}], 'desc': u'In Windows explorer the user can choose to have the taskbar field on any of the for sides of the screen (i.e top, bottom, left or right). This means that code that needs to display windows relative to this selection has to know where the taskbar is placed.\n\nThis little procedure finds the position of the taskbar field and returns "top",\n"bottom", "left" or "right" depending on the choice of the user.'}, {'comments': [{'comment': u'Thanks for the code, but there\'s a little typo in it. \n"dataclass" is the concatenation of data and a new class. So insert a few newlines and it\'s fixed.', 'title': u'typo'}, {'comment': u'I edited the recipe. Thank you! ', 'title': u"Yes, I missed a few lines during cut'n'paste"}, {'comment': u'When trying to run the file standalone, i was prompted to give code for "read_and_parse" as it could not be found... <br>So i guess the code is broken?', 'title': u'read_and_parse?'}, {'comment': u'Noted you entered the read_and_parse code as well. :) Thank you!', 'title': u'thanks'}, {'comment': u'There where a bug (a missing row = [] in end_element()). Now it is \ncorrected. I hope it helps... ', 'title': u'2005-11-28 Bug correction'}], 'desc': u'This is a quick-and-dirty snippet that read a OpenOffice 1.1 spreadsheet (.sxc files) as a list of lists, every list representing a oocalc row. The row contents are unicode object with the "string" content of the cell. This snippet used as a program will convert .sxc files into comma-separated-values (csv) on the command line. Style is not perfect and could be greatly enhanced, but it works for me as is...'}, {'comments': [{'comment': u'Thank you for this example. However, I believe that you also need to free the memory used by the argument list once you\'ve finished calling CommandLineToArgvW(), e.g.:\n\n<pre>\nif array_memory_address != win32con.NULL:\n retval = ctypes.windll.kernel32.LocalFree( array_memory_address )\n if retval != win32con.NULL:\n raise Exception( "LocalFree() failed." )\nelse:\n raise Exception( "CommandLineToArgvW() failed." )\n</pre>\n\nI may be mistaken since I\'m fairly new to ctypes, however.', 'title': u'Possible Memory Leak'}], 'desc': u'This is a way to parse command line from user provided string or try to get the original Argv from Windows OS Platform.'}, {'comments': [{'comment': u'<pre>ftpfind.py --expr=\'pattern( "foo*x86_64.tar.gz", file.name ) and</pre>\n<pre> file.age < week and file.size < 2*megabyte\' ftp.bar.edu</pre>\n\n<pre>\n"expr" can be any arbitrary python expression that\'s assumed to be the body\nof a lambda of the form: lambda file: "expr". The file parameter is of type\nFileInfo and has the following fields pre-computed to make life easy:\n\npath current path (string)\nname current filename (string)\nlongname file\'s path and name intelligently concatenated (string)\nmodeStr the permisions part of the ls listing, e.g. \'-rwxrwxrwx\' (string)\nisdir is the current file a directory (boolean)\nislink is the current file a link (boolean)\nmode the mode of the file as an octal number (int)\nn.b. octal literals in python start with a 0, e.g. 0777\nlinks number of links to a file\nowner file\'s owner (string)\ngroup file\'s group (string)\nsize file\'s size (int)\ndateStr file\'s modification date, e.g. \'Jul 6 2:04\'\ndate file\'s modification date expressed in secs since ... (int)\nage file\'s age in secs (int)\nline the original ls line obtained from ftp (string)\n\n</pre>', 'title': u'previous doc prematurely truncated'}, {'comment': u'<pre>\nAll times are in seconds, all sizes are in bytes.\nTo make the age queries easier to write the following constants are\navailable: minute, hour, day, week, year. To make size queries easier,\nthe following constants are available: kilobyte(2**10), megabyte(2**20),\ngigabyte(2**30), terabyte(2**40). To make unix style globbing simpler,\nthe function, pattern, is defined:\n\ndef pattern( pattern, candidate ): return fnmatch.fnmatch( candidate, pattern )\n\nOf course you can define your own predicates and import then in the body\nof the lambda.\n\nOther useful features: file downloads are automatically resumed if previously\ninterrupted, files are intelligiently renamed (from foo to .foo.) to\navoid clobbering.\n\nFull command-line options:\n\n-e --expr EXPR filters files using \'lambda file: EXPR\'. default: --expr=True\n-p --password PASSWD use PASSWD to authenticate on ftp server. default: ftpfind@sf.net\n--print EXPR print callback. default: --print=\'"%s" % file.line\'\n-s --daystart compute file ages from midnight this morning\n-t --test print filenames but do not perform gets\n-u --user=USER use USER to authenticate on ftp server. default: anonymous\n-x --exclude=DIR add the DIR pattern to the list of excluded directories\n\nSyntax:\n\nftpfind.py [option ...] server [dir ...]\n\nI\'ll be putting this up on SourceForge when I get some time so others\ncan improve it.\n</pre>', 'title': u'doc part 3'}, {'comment': u'Missing parameter, line, in the call to the FileInfo constructor- it should have read...\n<pre>\ndef extract_info( cwd, line ):\n fullmode, links, owner, group, size, rest = line.split( None, 5 )\n isdir, islink, mode = str2perm( fullmode )\n dateStr, name = rest[:12], rest[13:]\n date = parseDate( dateStr )\n return FileInfo( cwd, name, fullmode, isdir, islink, mode, int( links ), owner, group, int( size ), dateStr, date, line)\n</pre>', 'title': u'typo in extract_info'}], 'desc': u'On several occasions I wanted to peruse an FTP site for a specific rpm within\na certain age range and with a particular pattern to its filename and none of\nthe tools available gave me that functionality. This recipe gives a find-like\ntool to the world of FTP. Great for cron jobs that download new RPMs that fit\nsome tricky condition (e.g. less than 1 meg, less than a week old, ends in\nx86_64.tar.gz etc).'}, {'comments': [{'comment': u'The rfc822 module: http://python.org/doc/current/lib/module-rfc822.html provides something like this. You might use that module like:\n\n<pre>\n>>> from cStringIO import StringIO\n>>> import rfc822\n>>> f = StringIO("a:1\\nb:2\\n\\na:10\\nb:20")\n>>> records = []\n>>> while 1:\n... msg = rfc822.Message(f)\n... if not msg: #EOF reached\n... break\n... records.append(dict(msg))\n>>> records\n[{\'a\': \'1\', \'b\': \'2\'}, {\'a\': \'10\', \'b\': \'20\'}]\n</pre>\n\nBlank lines separate records. Records can be extended to multiple lines by using leading whitespace on secondary lines.', 'title': u'RFC822'}], 'desc': u'A method to parse a file like object containing data in the record jar format as described by ESR in "The Art of Unix Programming" (see http://www.faqs.org/docs/artu/ch05s02.html#id2906931).'}, {'comments': [], 'desc': u'doing a tail -f on a system log and handling log rotation (File::Tail for python)'}, {'comments': [{'comment': u"Why all the nested list comprehensions so that you need [0][-1][0] at the end? Why don't you just use multiple fors in the same list comprehension? Then you only need the final [-1]:\n<pre>\n# sum\nnl = [2, 3, 6, 18]\n[j for j in [0] for i in nl for j in [j + i]][-1]\n\n# product\nnl = [2, 3, 6, 18]\n[j for j in [1] for i in nl for j in [j * i]][-1]\n\n# factorial\nfac = 6\n[j for j in [1] for i in xrange(2, fac+1) for j in [j*i]][-1]\n</pre>", 'title': u' '}, {'comment': u"I am astounded. I so wanted what you so elegantly achieved. To make them<br>work you had to swap the left and right `for' clauses to remove the<br>nesting. I very incorrectly assumed that would not work. Your functions<br>are so nice and easy they might even find use. You could be the DeMorgan of<br>Python list comprehensions.<br><br>(Sorry for the typo: the first 'comprehension' should have ended in 's') ", 'title': u'Thanks'}, {'comment': u'And, the pattern works just as effectly with prefix functions\n\n<pre>>>> T=[set(s) for s in [(1,2,3,4,5),(2,3,4,5,6),(3,4,5,6,7),(4,5,6,7,8)]]\n\n>>> f=set.intersection\n>>> [ s for s in [f(*T[:2])] for i in range(2,len(T)) for s in [f(s,T[i])] ][-1]\nset([4, 5]) ## issues the null set if no intersection between all given sets\n\n>>> f=set.union\n>>> [ s for s in [f(*T[:2])] for i in range(2,len(T)) for s in [f(s,T[i])] ][-1]\nset([1, 2, 3, 4, 5, 6, 7, 8])\n\n>>> # join\n>>> T=[(1,2,3,4,5,6,7),(3,4,5,6,7),(5,6,7),(7,8,9,2,1,5)]\n\n>>> [ s for s in [T[0]] for i in range(1,len(T)) for s in [s + T[i]] ][-1]\n(1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 5, 6, 7, 7, 8, 9, 2, 1, 5)\n\n>>> T=["abcd","efgh","ijkl","mnop","qrst"]\n\n>>> [ s for s in [T[0]] for i in range(1,len(T)) for s in [s + T[i]] ][-1]\n\'abcdefghijklmnopqrst\'</pre>', 'title': u'The pattern with prefix functions'}, {'comment': u'<pre>>>> l=[20,30,40,50,60,70,80,90,1,2,3,4,5]\n\n>>> # all function\n>>> [ p for p in [l[0]>42] for i in range(1,len(l)) for p in [p and l[i]>42] ][-1]\nFalse\n\n>>> # any function\n>>> [ p for p in [l[0]>42] for i in range(1,len(l)) for p in [p or l[i]>42] ][-1]\nTrue\n\nThis pattern is very general and regular, my favorite type.</pre>', 'title': u'And with predicates'}], 'desc': u'List comprehensions, like functions, return values. They can even initialize and accumulate variables.\n\nInitialization in these comprehension takes the form "j for j in (n,)" where `n\' is any value and is equivalent to the "j = n" statement. Initialization happens only once at the top level of these comprehensions. Accumulation has the form of "[j for j in (j*i,)]" which is equivalent to j *= i where `*\' can be any associative operator and `i\' any value.'}, {'comments': [], 'desc': u'This is a simple Object Oriented way use regular expressions to with a simple include/exclude metaphore to select files on the filesystem.'}, {'comments': [], 'desc': u'You are processing unicode strings. You want to print the string but run into UnicodeEncodeError all the time. This recipe show you some simple steps to visualize unicode strings.'}, {'comments': [{'comment': u'I like your recipe!', 'title': u'Nice!'}], 'desc': u'Implements class invariants, pre/postconditions in a way similar to PyDBC, but significantly better.'}, {'comments': [{'comment': u"I believe the proper way is to add a site path using site.py and friends but just to add a module from a subdir within a portable project this works a charm, thanks to above.\n<br><br>\n#replace --indent-- with spaces or tabs\n<br><br>\nimport os<br>\nimport sys<br>\ndir='./uspp' #your dir here<br>\nif os.path.isdir(dir):<br>\n--indent--sys.path.append(dir)<br>\nimport uspp<br>", 'title': u'Import module from directory'}], 'desc': u'For something I am working on, I needed the ability to scan a supplied directory, adding the directory to the sys.path within Python, and then blanket import the modules within that directory. Following that, I had to filter any builtin or special methods within those modules and return a list of the methods for the module I had imported.\n\nThe script is very simplistic in what it does.'}, {'comments': [{'comment': u"Here's the aforementioned url: http://code.box.sk/", 'title': u' '}, {'comment': u"Hi!\n<br>\nHere's a slightly shorter version ;)\n<pre>\nn = 1\nwhile True:\n factors = [1]\n [factors.append(i) for i in range(2,n+1) if n%i == 0]\n if sum(factors) == 2*n: print n\n n += 1\n</pre>\n\nRegards, Markus ", 'title': u' '}, {'comment': u'Even shorter :)\n<pre>\nn = 1\nwhile True:\n if sum([i for i in range(1,n+1) if n%i == 0]) == 2*n: print n\n n += 1\n</pre>', 'title': u' '}, {'comment': u"I'm new to python (and programming), and your solutions have taught me a lot about economy and style in writing code. Any further suggestions would be equally welcome. :) \nRegards,\nAditya", 'title': u'Thanks Markus!'}, {'comment': u"I'm new to Python (and programming) and your solutions have taught me a lot about economy and style in writing code. Any further suggestions about style will be equally welcome. :)\nRegards,\nAditya", 'title': u'Thanks Markus!'}, {'comment': u'<pre>\nfor c in xrange(1, 100000):\n if sum(x for x in xrange(1,c) if not c%x) == c:\n print c\n</pre>', 'title': u'For-loops simplify the code'}, {'comment': u'The following runs a lot faster, at the cost of some typing. (Finding perfect numbers with python is going to be slow no matter what, so I suppose it is a silly problem to optimize).\n\nMainly--you only need to search factors up to the square root of n.\n\n<pre>\nfrom math import sqrt\nimport sys\n\ntry:\n max_n=int(sys.argv[-1])\nexcept ValueError:\n max_n=50000\n\ndef factor(n):\n sr=int(sqrt(n)+1)\n factors=[i for i in xrange(2,sr) if n%i==0]\n factors.extend([n/i for i in factors][::-1])\n return factors\n\ndef perfect():\n print [n for n in xrange(1,max_n) if sum(factor(n))==n-1]\n</pre>', 'title': u'Optimization'}, {'comment': u'As with just about anything dealing with primes, the fastest way to generate values is to start with precomputed values. In this case the perfect numbers can be generated from Mersenne primes, and there are only 42 or so of those which are known. Testing Mersenne candidates is faster than the general prime factor generation algorithms shown here so if you don\'t want to stop with a ValueError you might want to implement one of them instead, or use a service which connects to the Great Mersenne Prime Search server.\n\n<pre>\nmersenne_prime_powers = [2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521,\n 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,\n 21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,\n 1257787, 1398269, 2976221, 3021377, 6972593, 13466917, 20996011,\n 24036583, 25964951]\n\ndef perfect_numbers():\n for p in mersenne_prime_powers:\n yield (2**p-1)*(2**(p-1))\n yield ValueError, "that\'s a large number"\n\nfor p in perfect_numbers():\n print p\n</pre>\n\nMore details at http://mathworld.wolfram.com/PerfectNumber.html .', 'title': u'precomputed values'}, {'comment': u'Err, change that "yield ValueError," into a "raise ValueError,". As you might guess, I didn\'t make it that far in my testing. :)', 'title': u'yield -> raise'}], 'desc': u'A perfect number is a number whose factors, including the number\nitself, sum up to twice the number. For example,6 is a perfect number\nsince its factors (1, 2, 3, 6) sum up to 12.'}, {'comments': [{'comment': u"Haven't tried the recipe yet, but compacting the 3-function idiom sounds useful.", 'title': u'Nice idea!'}, {'comment': u'Try this:\n\n<pre>\nclass decoratorargs(object):\n\tdef __new__(typ, *attr_args, **attr_kwargs):\n\t\tdef decorator(orig_func):\n\t\t\tself = object.__new__(typ)\n\t\t\tself.__init__(orig_func, *attr_args, **attr_kwargs)\n\t\t\treturn self\n\t\t\n\t\treturn decorator\n\nclass decorator(decoratorargs):\n\tdef __init__(self, arg1, arg2, ...):\n\t\t...\n\n\tdef __call__(self, ...):\n\t\t...\n</pre>', 'title': u'This is overly complex'}], 'desc': u'This is meant to be a method for writing decorators very easily.'}, {'comments': [{'comment': u'Looks like you want this:\n<pre>\n push = lambda self, x: heapq.heappush(self, x)\n\n popmin = lambda self: heapq.heappop(self)\n\n replace = lambda self, x: heapq.heapreplace(self, x)\n\n heapify = lambda self: heapq.heapify(self)\n</pre>', 'title': u'borrowed methods should be lambdas'}], 'desc': u'For people who prefer object-oriented style, this wrapper class\nprovides a cleaner interface to the functions in the heapq module. It\nalso provides some additional capabilities, including reduce, which is\nuseful in some graph algorithms.'}, {'comments': [{'comment': u'Very practical script! Here is an alternative to using the import(..); construct\nin the python code: use getopt to get an option (\'-m\' here) with a list of\nmodules to import.\n\nImport the getopt module, then replace code between 8 and 16 with this code:\n\n<pre>\nopts, args = getopt.getopt(sys.argv[1:], \'m:\')\n\nopts = dict(opts)\nif \'-m\' in opts:\n for imp in opts[\'-m\'].split(\',\'):\n locals()[imp] = __import__(imp.strip())\n\ncmd = \' \'.join(args)\nif not cmd.strip():\n cmd = \'line\' # no-op\n</pre>\n\nThe import list is comma separated with no spaces. Example:\n\n<pre>cat \'foo\' | pyline -m sys,os "</pre>', 'title': u'getopt alternative'}, {'comment': u"Oh, that's much better. Great idea, Jacob; I've updated the code with your recommendation.", 'title': u"That's a great idea."}, {'comment': u"<pre>line = line[:-1]</pre>\n\nbetter way:\n\n<pre>line = string.split(line, '\\n')[0]</pre>", 'title': u'incorrect EOL handling'}, {'comment': u'what about string.split() ?', 'title': u' '}, {'comment': u'what about line.strip()', 'title': u'ooops, shout think before typing:'}, {'comment': u'<pre>\n if isinstance(result, list):\n result = " ".join(map(str, result))\n result = str(result)\n</pre>\nallows things like \n<pre>\n pyline \'words[-1::-1]\'\n</pre>\nto do the obvious thing. (You can get back the original less desirable behaviour by simply wrapping the arg in repr() so there\'s no loss in generality.)', 'title': u'auto-handle lists'}, {'comment': u"I didn't want to use line.strip() in case the whitespace in the output was significant. \n\nI'm not sure that line.split('\\n')[0] is more correct than line[:-1], though perhaps there are some Python implementations where this is an important?", 'title': u'line.strip() and side-effects'}, {'comment': u'I see your point, and can imagine cases where a string-joined list representation would be favourable. I\'m a bit hesitant, though; sometimes the list-formatted output is easier to read. Sometimes, I\'ve used \'pyline "words"\', just to get better visual delimiting between words in the output. \n<br><br>\nMaybe this is a behaviour that could be turned on via a command-line flag? \n<br><pre>\n-j or --join: join list-like result via \' \'.join(map(str, result))\n</pre>\nThoughts?', 'title': u'+0'}, {'comment': u"Mark, after frequent use of the script, I've seen the error of my ways. List (and tuple) results are now joined via ' '.join(map(str, result)). Thanks.", 'title': u're: auto-handle lists'}, {'comment': u'"""Windows users: it works under Windows, but name it "pyline.py" \ninstead of "pyline", and call it via a batch file so that the \npiping works properly."""\n\nBetter yet. Add .PY to your PATHEXT environment variable. \n\nThen all python scripts can be called without extension.', 'title': u'using on windows'}, {'comment': u'I am having trouble using this on windows - I already had .py as part of my pathext environment variables, but when I run something like: \n<br><br>\nls | pyline -m os "os.path.isfile(line) and os.stat(line).st_size > 1024 and line"\n<br><br>\nI end up with:\n<br><br>\nTraceback (most recent call last):<br>\n File "C:\\windows\\usr\\utilities\\pyline.py", line 24, in ?<br>\n for numz, line in enumerate(sys.stdin):<br>\nIOError: [Errno 9] Bad file descriptor<br>\n<br><br>\nWhat I am wondering is if even though I have .py in PATHEXT, there is still something to the statement "and call it via a batch file so that the piping works properly." \n<br><br>\nAnybody have an idea as to why this is happening?', 'title': u'Using on Windows???'}, {'comment': u'"What I am wondering is if even though I have .py in PATHEXT, there is still something to the statement \'and call it via a batch file so that the piping works properly.\'"\n<br><br>\nYes, it\'s got to be a batch file. I don\'t know the deep reasons for it, but a Web search for "python pipe windows bad file descriptor" might turn it up for you.<br><br>\nHere\'s a sample pyline.bat file. It assumes that pyline.py (the recipe) is in c:\\python24; adjust as necessary.\n<pre>@echo off\npython c:\\python24\\pyline.py %1 %2 %3 %4 %5 %6 %7 %8 %9\n</pre>', 'title': u"Yes, it's got to be a batch file."}, {'comment': u'Pretty nice, I was inspired: I wrote an additional xxdiff transformation script that uses this transformation method, similar to xxdiff-rename/xxdiff-filter, etc.\n\nThis allows you to review the changes with a side-by-side graphical diff before they are applied, and you get backup files automatically as well. You can also cherry-pick the desired changes and save them over the original files.\n\nThe new script is called xxdiff-pyline:\nhttp://furius.ca/xxdiff/doc/xxdiff-scripts.html#xxdiff-pyline\n\n(Note: all the scripts described in the documentation will be released with xxdiff 3.2 (soon)).', 'title': u'With xxdiff scripts...'}, {'comment': u'Snapshots here until I release it:\nhttp://furius.ca/downloads/xxdiff/snapshots/', 'title': u'snapshots'}, {'comment': u'Nice application of the idea, Martin. Thanks. :-)', 'title': u'Nice'}, {'comment': u'I\'ve implemented something based on a similar idea, named osh. However, instead of using the shell\'s pipe to connect commands, I have everything running in one Python process. For example:\n\n<pre>\n osh f \'path(".").files()\' ^ expand ^ select \'file: file.size > 100000\' ^ f \'file: (str(file), file.size)\' $\n\n- osh: invokes osh.\n\n- f \'path(".").files()\': Run the function f, producing a list of files in the current directory.\n\n- ^: The osh symbol for piping objects.\n\n- expand: Turn the list into a stream of objects in the streams (files).\n\n- select \'file: file.size > 100000\': If a file received as input has size > 100000 then pass it to on as output, otherwise discard it.\n\n- f \'file: (str(file), file.size)\': Apply a function taking a file as input and generating a tuple of (file name, file size) as output. \n\n- $: Render input objects as strings and print to stdout.\n</pre>\n\nFor more info: http://geophile.com/osh', 'title': u'Object-oriented shell'}, {'comment': u"Instead of passing in -m and the list of modules, something like this might make it even simpler to use (let the script figure out what modules are needed):\n\n<pre>\nimport re\npossibleModules = re.findall(r'(\\w+)\\.', cmd)\nfor m in possibleModules:\n try:\n locals()[m] = __import__(m)\n except:\n pass\n</pre>\n\nNot tested much, but it works with the os and md5 examples given above.", 'title': u'Non getopt alternative'}], 'desc': u'This utility was born from the fact that I keep forgetting how to use\n"sed", and I suck at Perl. It brings ad-hoc command-line piping\nsensibilities to the Python interpeter. (Version 1.2 does better \noutputting of list-like results, thanks to Mark Eichin.)'}, {'comments': [{'comment': u'Get ipython from http://ipython.scipy.org/ . It a mature tool which does all that and much more.', 'title': u'Just get ipython'}, {'comment': u'I don\'t think ipython is really a replacement for something like this. ipython is interactive, but a recipe like this is very usable in a "script" environment (and maybe in any environment). I\'d feel weird creating a script specifically intended to be piped to ipython.\n<br><br>\nIf it were to be a fuller module, it would be good to use the stdlib subprocess module, and it would be better if it returned a real object. And perhaps if shell.attr was equivalent to shell(\'attr\'), if you want to give a full path to an executable.', 'title': u'subprocess'}, {'comment': u"I assumed (shame on me) that I could make this call:\n<br><pre>\n >>> shell.cat('/etc/fstab /etc/crontab') \n</pre>\nas I would on the command-line and get a stdout with both files. Instead I need:\n<pre>\n >>> shell.cat('/etc/fstab', '/etc/crontab')\n</pre>\nThis makes sense once I look at the code, especially in the context of this example. However, it was a bit less obvious when attempting:\n<pre>\n >>>shell.prefix = '/usr/bin'\n >>>shell.svnlook('changed -r%s %s') % (rev, repos)\n</pre>\n\nBut thanks for the introduction to __getattr__ I'm continually impressed with Python's flexibility.", 'title': u'calling with multiple parameters ...'}], 'desc': u'One common aspect of programming is calling executables and processing results. It is not as easy or elegant to do this in Python as it is in a shell scripting language, such as bash. This script implements a shell-like module in Python which allows you to easily call executables and work with the results.'}, {'comments': [{'comment': u'If you think there is missing stuff in the standard library documentation\nthen send your examples to the documetnation maintainers - who are\nalways looking for more material.', 'title': u'Pretty Good'}, {'comment': u'Nice reminder of these handy little functions. One improvement (for me anyway) is to remove the empty application window that pops up behind the file dialogs. If your program only needs the file dialogs and no other application window, that empty window is a distraction. The solution is to use the window manager\'s withdraw() method. E.g.\n<pre>\n>>> import Tkinter, tkFileDialog\n>>> root = Tkinter.Tk()\n>>> root.withdraw()\n\'\'\n>>> dirname = tkFileDialog.askdirectory(parent=root,initialdir="/",title=\'Pick a directory\')\n</pre>\nThen you\'ll get just the file dialog and nothing else.<br>\n<br>\nThe docstring for the withdraw method is:\n<pre>\n>>> print Tkinter.Tk.withdraw.__doc__\nWithdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.\n</pre>', 'title': u'Same again, but without the main app window in the background'}, {'comment': u"As I've used this for every example today, good job! And I know Tkinter pretty well. Its good to have boilerplate like this come up easily via google.", 'title': u'Good Recipe'}], 'desc': u"Basic Tkinter dialogs for directory selection, file selection and so on.\nThat's dirt simple (although the official documentation is not very explicit about these features)."}, {'comments': [], 'desc': u'This recipe is a simple pair of classes that implement something like what is proposed for <a href="http://www.python.org/peps/pep-0342.html">PEP 342</a>, but with a few differences. For one, you can send any signature, not just one object. You are able to pass any number of positional and keyword arguments through the send method. Also, this does not address a close method, but one could be easily added.'}, {'comments': [{'comment': u"You don't benefit from using a class here.\n\ndef inc(x=0):\n while 1:\n yield x\n x += 1\n\nis certainly simpler.", 'title': u'Easier...'}, {'comment': u'<pre>\n>>> import itertools\n>>> inc = itertools.count(0).next\n>>> inc()\n0\n>>> inc()\n1\n>>> inc()\n2\n</pre>', 'title': u'Batteries Included'}, {'comment': u'I obviously should look more closely at itertools.', 'title': u'This is what I should have used'}], 'desc': u'This will automaticly return then next integer forever it starts with 0. This is an example of how to make a generator and how to make a callable object.'}, {'comments': [{'comment': u"I just ran your results with set(), and saw the conditions under which a type error occurs, which leads me to believe set uses the same underlying hashing the python dict type uses, since I ran into the same error when I did it the old way:\n<br>\n<br>\n<pre>\ndef unique(seq):\n return dict.fromkeys(seq).keys()\n</pre>\n<br>\n<br>\nThe performance is so similar to set() that there must be a lot of shared code on the C side (2.13 seconds versus 1.57 or so in a test I ran). I'm sure the new set() stuff is a bit simpler and the python side is definitely cleaner.\n\nInteresting stuff--thanks.", 'title': u'Old Way'}], 'desc': u'Python needs a unique function, this is my best try so far. It uses the faster algorithm (among five) for each situation.'}, {'comments': [], 'desc': u'Add a user defined Sign function to SQLite using PySQLite (http://initd.org/projects/pysqlite). The utility of this is explained in this very nice tutorial:\nhttp://souptonuts.sourceforge.net/readme_sqlite_tutorial.html'}, {'comments': [], 'desc': u'Generate a catenateFiles function parameterized for\ncommon variations.'}, {'comments': [], 'desc': u'Find out how often and by who a particular file is being requested. Prints the requesting addresses, hostnames, access times, and hit counts.'}, {'comments': [{'comment': u'Typically "None" in the place of a predicate means the identity function. For instance:\n<pre>\nfilter(None, lst)\n</pre>\n\nMeans to filter out all the items in the list that aren\'t true. So if the predicate is None it should be replaced with \n\n<pre>\nlambda v: v\n</pre>\n\nOr something like that.', 'title': u'Use of None'}, {'comment': u"True, I was debating whether or not to post the default as the identity function. Would it not be the same as the default being 'bool'?\n<br><br>\nMy reasoning was that first(seq) should return the first item in the sequence no matter what, since that's what it 'says.'", 'title': u' '}], 'desc': u'A common practice when dealing with sequences is to find the first or last item in the list that satisfies a predicate. This simple recipe increases the readability and writability for these tasks and nothing more.'}, {'comments': [{'comment': u'Get ipython at http://ipython.scipy.org .', 'title': u'Use ipython'}, {'comment': u"Works fine, even with gvim.exe. However, for editing multiple lines like:<pre>\n\n print 1\n def f( x ):\n return x + 2\n</pre>\na small extension is required before 'return line'.\nOnly the last line entered via the editor is returned by raw_input(). The other lines are handed over to InteractiveConsole.push(), e.g. <pre>\n\n def raw_input(self, *args):\n line = InteractiveConsole.raw_input(self, *args)\n if line == EDIT_CMD:\n ... \n lines = line.split( '\\n' )\n for i in range(len(lines) - 1): self.push( lines[i] )\n line = lines[-1]\n return line\n</pre>", 'title': u'Editing multiple lines'}, {'comment': u"Awesome tip! This brings the standard Python shell to 90% of IPython's functionality (for me).\n\nIf you change the following line, the temporary file will have a .py file extension which might be helpful::\n<pre>\n fd, tmpfl = mkstemp('.py')\n</pre>", 'title': u'Python file extension'}], 'desc': u'I hacked up this useful wrapper around the python command line shell to allow editing of the last typed in lines of code in an external editor.'}, {'comments': [], 'desc': u"By default ReportLab PDF library <http://www.reportlab.com> doesn't allow\neasy using Cyrillic fonts for generating PDF documents. The following example\nexplains how to use any font in the Adobe AFM ('Adobe Font Metrics') and PFB\n('Printer Font Binary') format (aka Type 1) which supports Unicode Cyrillic\ncharacters (glyphs). It assumes that you have font files named 'a010013l.afm'\nand 'a010013l.pfb' in the same directory with this example.\nThe font files can be found in /usr/share/fonts/default/Type1 directory in\nmany Linux distributions."}, {'comments': [], 'desc': u'This example uses ReportLab PDF library <http://www.reportlab.com> and made\nfrom reportlab/demos/stdfonts/stdfonts.py demo. It generates tables showing\nall Type 1 fonts in Cyrillic cp1251 encoding in /usr/share/fonts/default/Type1\nLinux directory. It may be helpful for choosing most suitable fonts for your\ndocuments.'}, {'comments': [{'comment': u"You can remove the eval() call and replace it with just <pre>setattr(args[0], '_' + func.func_code.co_varnames[i + 1], arg)</pre>.", 'title': u'eval() is not necessary'}, {'comment': u"The following will also handle defaults and keyword arguments.\nIt still does not handle possible errors and will fail badly \nif you miss the correct signature.\n<pre>\ndef vars_private(func):\n def wrapper(*args, **kwargs):\n A = {}\n self = args[0]\n args = args[1:]\n for i, arg in enumerate(func.func_code.co_varnames[1:func.func_code.co_argcount]):\n if i < len(args):\n A[arg] = args[i]\n elif kwargs.has_key(arg):\n A[arg] = kwargs[arg]\n else:\n the_default_arg = i - func.func_code.co_argcount + 1\n A[arg] = func.func_defaults[the_default_arg]\n for name, value in A.items():\n setattr(self, '_' + name, value)\n return func(self, **A)\n return wrapper\n</pre>", 'title': u'Defaults and keyword arguments'}, {'comment': u'<pre>def __init__(self, **entries): \n self.__dict__.update(entries)\n # rest of initialization..\n</pre>', 'title': u'Much simpler way'}, {'comment': u'Simple. Yes! But not quite the same.<br><br>\nThis requires that all instantiations use named arguments which could get tiedious if there are several being done. And argument mismatch at instantiation passes by silently.', 'title': u'Yes! But ...'}], 'desc': u'Automate boring constructors that simply create lots of private member variables.'}, {'comments': [{'comment': u'<pre>Traceback (most recent call last):\n File "verbs.py", line 71, in ?\n pprint.pprint(result)\n File "/usr/lib/python2.4/pprint.py", line 55, in pprint\n printer.pprint(object)\n File "/usr/lib/python2.4/pprint.py", line 106, in pprint\n self._stream.write(self.pformat(object) + "\\n")\n File "/usr/lib/python2.4/pprint.py", line 110, in pformat\n self._format(object, sio, 0, 0, {}, 0)\n File "/usr/lib/python2.4/pprint.py", line 144, in _format\n items.sort()\nAttributeError: \'generator\' object has no attribute \'sort\'\n<br><br>\nAny solution?</pre>', 'title': u'not compatible with pprint'}, {'comment': u'There are some problems with this implementation.\n<br>\n\nvalues() and items() must return a list. <br>\nsince iterkeys() and __iter__() methods are not implemented, for k in d: returns keys in the any order. ', 'title': u'Problems'}], 'desc': u'Yet another ordered dict.'}, {'comments': [{'comment': u'* Converted to a generator<br>\n* Use string methods instead of string module<br>\n* trailing_newline set with a single test<br>\n* Nested if-statements collapsed to if/elif/else<br>\n* Replace var!=0 comparison with simple boolean test<br>\n* Import of os module was unused\n\n<pre>\ndef BackwardsReader(file, BLKSIZE = 4096):\n """Read a file line by line, backwards"""\n\n buf = ""\n file.seek(-1, 2)\n lastchar = file.read(1)\n trailing_newline = (lastchar == "\\n")\n \n while 1:\n newline_pos = buf.rfind("\\n")\n pos = file.tell()\n if newline_pos != -1:\n # Found a newline\n line = buf[newline_pos+1:]\n buf = buf[:newline_pos]\n if pos or newline_pos or trailing_newline:\n line += "\\n"\n yield line\n elif pos:\n # Need to fill buffer\n toread = min(BLKSIZE, pos)\n file.seek(-toread, 1)\n buf = file.read(toread) + buf\n file.seek(-toread, 1)\n if pos == toread:\n buf = "\\n" + buf\n else:\n # Start-of-file\n return\n\n\n# Example usage\nfor line in BackwardsReader(open(\'brent.txt\')):\n print repr(line)\n</pre>', 'title': u'Simplifying code transformations'}], 'desc': u'Yet another way to read a file line by line, starting at the end. '}, {'comments': [], 'desc': u'Uses the SIOCGIFCONF ioctl to obtain a list of interfaces and extracts those names, returning them in a list of strings.'}, {'comments': [{'comment': u"Here is similar code to get the hardware address. Same platform caveat's apply:\n\n<pre>\ndef get_hw_address(ifname):\n s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))\n hwaddr = []\n for char in info[18:24]:\n hdigit = hex(ord(char))[2:]\n if len(hdigit) Here is similar code to get the hardware address. Same platform caveat's apply:\n\n<pre>\ndef get_hw_address(ifname):\n s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))\n hwaddr = []\n for char in info[18:24]:\n hdigit = hex(ord(char))[2:]\n if len(hdigit) </pre></pre>", 'title': u'MAC Address'}, {'comment': u"I just thought I'd mention my new netifaces package, which you can download from the Cheese Shop with<br>\n\n<pre>\neasy_install netifaces\n</pre>\n\nIt should be able to find IP addresses and MAC addresses on machines that implement getaddrinfo() or the SIOCGIFxxx ioctl()s. It definitely works on Mac OS X, and I think it should work (possibly with a small amount of tweaking) on other UNIX-like systems too.<br><br>\n\nPresently it doesn't work on Windows, but if someone wanted to write the code and contribute it, I'm happy to merge it in. When I have time, I might have a go myself, but Windows isn't my primary development platform at the moment, and I'm pretty busy.", 'title': u'netifaces'}, {'comment': u"OK, I've added some code to make my netifaces package work on Windows. It checks out on Win2K, and should work back to Windows 98 and forward to Windows Vista (in theory\xe2_\u258c)", 'title': u'netifaces now works on Windows too'}, {'comment': u'A common way of the determining the "IP address of the computer" is just to use:\n<pre>\n socket.gethostbyname(socket.gethostname())\n</pre>\nThis works well on Windows, and on unix hosts configured in the traditional way with their main ip address set in /etc/hosts. It won\'t return useful results on unix systems that have their hostnames mapped to the loopback address in /etc/hosts, which is pretty common, but it\'s a good platform independent fallback to use when no specific interface or address information has been provided.', 'title': u'Platform independent fallback'}], 'desc': u'Uses the Linux SIOCGIFADDR ioctl to find the IP address associated with a network interface, given the name of that interface, e.g. "eth0". The address is returned as a string containing a dotted quad.'}, {'comments': [{'comment': u'<pre>\nimport itertools\n\ndef group2(iterator, count):\n return itertools.imap(None, *([ iter(iterator) ] * count))\n</pre>\n\nor just map(), if you want a partial last tuple to be filled out with None...', 'title': u'using itertools.imap()'}], 'desc': u'Creates an iterator which returns N-tuples built from the incoming items from another iterator. Useful, for example, when you need items two at a time.'}, {'comments': [{'comment': u' ', 'title': u'Nice!'}, {'comment': u'With the ctypes module (at least 0.9.1), you can also do this with a simple call to PyCell_Get. Watch out though, the function needs to be told about its type signature before it works (at least that was my experience, maybe future ctypes releases will fix this)\n\n<pre>\n>>> import ctypes\n>>> cellget = ctypes.pythonapi.PyCell_Get\n>>> cellget.restype = ctypes.py_object\n>>> cellget.argtypes = (ctypes.py_object,)\n>>> def f(x): return lambda: x\n...\n>>> l = f(10)\n>>> cellget(l.func_closure[0])\n10\n</pre>', 'title': u'You can also do this with ctypes'}], 'desc': u'Python closures hold closed-over values in a special datatype called a "cell"; a sort of indirect pointer. It\'s not simple, though, to see what values are stored there. Here\'s the key.'}, {'comments': [], 'desc': u'Printing sequences or maps containing non-ASCII strings results in escape sequences. This function uses the not-so-commonly-known "string_escape" codec to facilitate printing such sequences for quick-viewing.'}, {'comments': [], 'desc': u'A simple beta-tool that fills the DATA field of an address packet with strings, then send the packet(s) to an host specified. \nYou can observe the strings received by putting an ICMP sniffer on the remote machines.'}, {'comments': [], 'desc': u'This recipe solves the problem of shuffle-merging files -- interlacing (shuffle-merging) many small text files into one large text file, while preserving the order of the lines from within the small files.'}, {'comments': [], 'desc': u'This example shows how to stop yourself from running multiple copies of a program (in this case, pine).'}, {'comments': [{'comment': u"What's the advantage of this over PyDispatcher?", 'title': u'Advantages...?'}, {'comment': u'Connecting a Borg method to a Signal does not work if no Borg instance is kept (which is the aim of the Borg).\n<br><br>\nThe solution is to use a \'staticmethod\'. No Borg instance will be given to the method, but as it is a Borg, it\'s not a problem.\n<br>\nHere is an example:\n\n<pre>\nclass BorgListener(object):\n __state = {}\n __init = True\n\n def __new__(cls, *args, **kwds):\n self = object.__new__(cls, *args, **kwds)\n self.__dict__ = cls.__state\n return self\n\n def __init__(self):\n if BorgListener.__init:\n self.val = 1\n BorgListener.__init = False\n\n # a sample method that will be connected to the signal\n def onClick():\n print "onClick: val = %d" % BorgListener().val\n onClick = staticmethod(onClick)\n\nb = Button()\nb.sigClick.connect(BorgListener().onClick)\nBorgListener().val = 2\nb.sigClick()\nb.sigClick.disconnect(BorgListener().onClick)\nb.sigClick()\n</pre>\n\nResult:\n<br><br>\nonClick: val = 2', 'title': u'Signal and Borg'}, {'comment': u"What's a borg method?", 'title': u' '}, {'comment': u'See this recipe about Borg/Singleton:\n\n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531', 'title': u'Borg method'}], 'desc': u'This is a signals implementation for python. It is similar to the pydispatch module. This implementation enables you to create Signals as members of classes, as globals, or as locals. You may connect any number of functions or class methods to any signal. Connections manage themselves with the weakref module. Signals may also have arguments as long as all connected functions are callable with the same arguments.'}, {'comments': [{'comment': u"Note that the locale module does most of what you want here:\n\n<pre>\npy> import locale\npy> locale.setlocale(locale.LC_ALL, '')\n'English_United States.1252'\npy> locale.format('%i', 42, True)\n'42'\npy> locale.format('%i', 4242, True)\n'4,242'\npy> locale.format('%i', 424242, True)\n'424,242'\npy> locale.format('%i', 42424242, True)\n'42,424,242'\n</pre>", 'title': u' '}, {'comment': u"Nevertheless Mr. Bethard, it is an interesting definition.\nHowever, I found that it faults when supplied a decimal or a float.\n\n<pre>\n>>> group(44.44)\n'44,.44'\n</pre>", 'title': u'Error...'}], 'desc': u'What the title says. No more, no less. (Version 2, now supports negative numbers.)'}, {'comments': [{'comment': u"Valentino Volonghi points out to me that there is already a function\nin Twisted doing the same job as my 'callInThread', and doing it\nbetter: twisted.internet.threads.deferToThread.\n\nSo just import it and define the decorator as 'deferred=deferToThread.__get__'\n\nValentino also points out that threads are not scalable, but I\nbet you already knew that ;)", 'title': u'deferToThread'}, {'comment': u'Callbacks you add to the Deferred will run in the thread, but only *sometimes*. This makes thread safety really hard, possibly impossible and means lots of obscure hard to track down bugs.\n\nInstead, use twisted.internet.threads.deferToThread, where callbacks added to result will run in the Twisted main thread.', 'title': u"You don't want to use this code"}], 'desc': u'Twisted FAQs clearly state that "deferreds do not magically convert blocking\ncode into non-blocking code". So, how do you magically convert blocking\ncode into non-blocking code? \n\nThis recipe is the solution!'}, {'comments': [], 'desc': u'This recipe can be good to avoid some limitations of multiple inheritance, when in need to expand functionalities of superclasses in the hierarchy or controlling the classes cooperation.'}, {'comments': [], 'desc': u'The List monad in Haskell has many uses, including parsing and nondeterministic algorithms. This code implements the Monad combinators "bind", "return" and "fail", and the MonadPlus combinators "plus" and "zero". It works with all iterables, and returns a generator rather than a list in order to preserve a lazy semantics.'}, {'comments': [], 'desc': u'Starts a timer that can be stopped or acts upon time-out.'}, {'comments': [{'comment': u"Err... you do know about the standard 'logging' module, don't you...?", 'title': u"There's already a standard module..."}, {'comment': u'What does it do for you? ', 'title': u' '}], 'desc': u'This module is called with a string message and it is written to a file with a date and timestamp. After a certain number of entries, it creates a backup of the file.'}, {'comments': [{'comment': u'I tried this module. It is neat. But, it will save a file (that contains strings for data), O.K. But when I try to reload the (saved) file\nI get an empty string back. If I look in the directory, such as c:\\Python24 (Windows) I can find the saved file and open it with Notepad, and it is a fresh file with a date/time group that is new. However, this code will not reload the file, when attempting a reload, it says the string (file) is empty ????', 'title': u'This "lister module" '}, {'comment': u'The load function does work!\nThe thing is the list isnt pased back to the rest of the program, so it disapears when the function returns. If the load function would end with something like:<br><br>\n\nreturn local_list_name<br><br>\n\nand be caled (in the event handling loop) with something as<br><br>\n\nglobal_list_name = Load()<br><br>\n\nthen the list will be pased back to the main program<br>\nalternatively inside the Load function you can explicitly assign to the global variable(something like global.listname = ... but Im not sure)<br><br>\n\nCheers\n\n', 'title': u'The Load function works!!'}, {'comment': u'due to first needing to subscribe, and the break in the train of thought that causes I have inadvertedly put this comment in the wrong thread.', 'title': u'sorry please remove'}], 'desc': u'This program let you edit,save and load a list.\nThis program also demonstrate how to use files, pickle (or cPickle), and built-in list method.'}, {'comments': [{'comment': u'How about this (not much tested, but you get the idea, I suppose.\nThis is using the unittest module with your own sample text.\n\n<pre>\nclass TagStrippingTest(unittest.TestCase):\n def test(self):\n "Test replacing HTML-like tags from text."\n inpText = "Keep this Text <remove><me /> KEEP </remove> 123"\n expText = "Keep this Text KEEP 123"\n t = re.sub("< */? *\\w+ */?\\ *>", "", inpText) ### here\'s the meat!\n self.assertEqual(t, expText)\n</pre>', 'title': u'Why so long?'}, {'comment': u"This could have serious problems with HTML comments. What I use to strip HTML tags is the follow pair of regular expressions (replace the square brackets in the regex with angle brackets... I had a bear of a time trying to get it to post correctly with angle brackets). This doesn't work on all web pages I've tried and definitely doesn't implement the correct SGML comment syntax (which is very subtle, see the acid2 test for details), but it gets me by in a pinch.\n\n<pre>\nimport re\nHTMLtag = re.compile('[.*?]') # Matches HTML tags\nHTMLcom = re.compile('[!--.*?--]') # Matches HTML comments\nresultstr = HTMLtag.sub('', HTMLcom.sub('', sourcestr))</pre>", 'title': u' '}, {'comment': u'<pre>\n>>> test_text = "Keep this Text KEEP 123"\n>>> import HTMLParser\n>>> class MLStripper(HTMLParser.HTMLParser):\n... def __init__(self):\n... self.reset()\n... self.fed = []\n... def handle_data(self, d):\n... self.fed.append(d)\n... def get_fed_data(self):\n... return \'\'.join(self.fed)\n...\n>>> x = MLStripper()\n>>> x.feed(test_text)\n>>> x.get_fed_data()\n\'Keep this Text KEEP 123\'\n>>>\n</pre>\n\nUsing HTMLParser rather than sgmllib is preferable because it doesn\'t die on unmatched tags, etc. Also, using this particular module rather than a custom re-based parser will allow you to build applications that do things other than strip HTML/XML/SGML/...', 'title': u'Why reinvent the wheel?'}, {'comment': u"Mybe to use HTMLParser s the best solution, but if you want to not use it, I think I know a better way to do this. Your code has a performance of O(n^2) (never acces members of a list by their position, use iterators!), following code has a performance of O(n) (and it shows you the beauty of python):\n\n<pre>\ndef stripTags(s):\n# this list is neccesarry because chk() would otherwise not know\n# that intag in stripTags() is ment, and not a new intag variable in chk().\n\tintag = [False]\n\t\n\tdef chk(c):\n\t\tif intag[0]:\n\t\t\tintag[0] = (c != '>')\n\t\t\treturn False\n\t\telif c == '<':\n\t\t\tintag[0] = True\n\t\t\treturn False\n\t\treturn True\n\t\n\treturn ''.join(c for c in s if chk(c))\n</pre>", 'title': u'nice but inefficient'}, {'comment': u'Here\'s that test with the proper portions of tags escaped.<br><br>\n\n<pre>>>> test_text = "Keep this Text <remove><me /> KEEP </remove> 123"\n>>> import HTMLParser\n>>> class MLStripper(HTMLParser.HTMLParser):\n... def __init__(self):\n... self.reset()\n... self.fed = []\n... def handle_data(self, d):\n... self.fed.append(d)\n... def get_fed_data(self):\n... return \'\'.join(self.fed)\n...\n>>> x = MLStripper()\n>>> x.feed(test_text)\n>>> x.get_fed_data()\n\'Keep this Text KEEP 123\'\n>>></pre>', 'title': u'Gah with html escapes'}], 'desc': u'Completely gets rid any tags from XML/HTML input. It gives you the same text minus the tags. The algorithm is rather simple.'}, {'comments': [{'comment': u"This is not really related to your recipe, but rather to your unique-function. FYI, the fastest (most efficient) approach I'm aware of to return a list of unique values is to use a dictionary:\n<pre>\ndef unique(sequence):\n d = {}\n for item in sequence:\n d[item] = None\n return d.keys()\n</pre>", 'title': u'Faster unique function'}, {'comment': u"I was tempted to use the dict version wich is like:<br>\nunique = lambda x: reduce(lambda y,z: y.setdefault(z, None) or y, x, {}).keys()<br>\nunique([3, 4, 5, 6, 5, 3, 7])<br>\n<br>\n\nI prefer no to do so because it doesn't keeps the sequence's order, but I agree it's faster (and notably faster on old python versions)\n", 'title': u'Faster unique function'}, {'comment': u"Shorter:\n\n<pre>\ndef unique(seq):\n return dict.fromkeys(seq).keys()\n</pre>\n\nOr even better:\n\n<pre>\ndef unique(seq):\n return sets.Set(seq)\n</pre>\n\nWell, that's a little trivial, maybe just:\n\n<pre>\nunique = sets.Set\n</pre>", 'title': u'even shorter...'}, {'comment': u"I'm not sure why that makes me want to smile, Ian; but it does. How succinct!\n<br><br>\nSince you still need a separate line to import 'sets', you could also use the one-liner:\n<pre>from sets import Set as unique</pre>", 'title': u'unique = sets.Set: +1'}, {'comment': u"last night I was doing some stuff at my toilet... whatever! I was\nconcerned about making code a little bit more maintable. so, given\nthat I readed this recipe some time ago, inspiration came to me and :\n<br>\n<pre>\nclass A:\n def method( self ):\n print 'foo'\n return 1\n \nclass B:\n def method(self):\n return len(B.__bases__) and B.__bases__[0].method(self) or self\n\n</pre>\n<br>\n\nthis is super dooper, since I could get B as base class in the future\nwithout crashing anything.\noh yeah! , thanks mr burroni for giving your knowledge to the people<br>\namen/", 'title': u"bollean operations, the kidss' friend"}, {'comment': u"sorry there is a typo at class B definition\n<pre>\n\nclass A:\n def method( self ):\n print 'foo'\n return 1\n \nclass B(A):\n def method(self):\n return len(B.__bases__) and B.__bases__[0].method(self) or self\n\n</pre>", 'title': u' '}, {'comment': u'you got the point ;)', 'title': u' '}], 'desc': u'Boolean operations offers more than its simple ability to test for truth'}, {'comments': [], 'desc': u"Autodesk's AutoCAD drafting software has for a number of versions included an increasingly complete COM interface. Using the Python win32com modules we have been able to automate some aspects the software; unfortunately because of the organization of the interface certain methods and properties were inaccessible from Python. In recent versions of the win32 modules a new function has been added though: win32com.client.CastTo(). By casting our objects as the correct type we now have access to much of the object model that used to be unreachable.\n\nIn this example we search the ModelSpace collection for text objects. Once found we then cast them and alter one of the text specific properties. To test this code open AutoCAD and in a blank file add at least one dtext object with 'Spam' as its value."}, {'comments': [], 'desc': u'This script asks for a base directory and then changes all xrefs in all drawings in all subdirectories so that they use relative paths. To use it just copy it somewhere in your target directory structure and run.'}, {'comments': [], 'desc': u'The following code is my solution to replace an irksome if-else block I was using. The use of a function decorator allows setting attributes (the comparision, which maybe a sequence for multiple matches) for particular methods in a class. The constructor of the switch class creates a dictionary that maps the comparision value to specific methods. Then match method can be used to retrieve the specific method. '}, {'comments': [{'comment': u'Why "import config"?', 'title': u'Import of non-existant module.'}, {'comment': u'This code was derived from\na much larger codebase which allows you to\nquery Python packages on a command line. It had\na module named config which I forgot to remove\nwhen I rewrote it in one single module.\n\n', 'title': u'Corrected it '}], 'desc': u'This recipe provides a quick way to search and retrieve information about installed Python packages and modules in your Python installation. It classifies\nthe retrieved module information into types (built-in, source files, c-extensions etc) and prints module information under each type as a sorted list. '}, {'comments': [{'comment': u"I recently had similar requirements and used someting like below:\n\n\n>>> dict = {'key': ['v1']}\n\n>>> dict['key'].append(1)\n\n>>> dict\n\n{'key': ['v1', 1]}", 'title': u'Simply Using this Dict with List'}], 'desc': u'I often find myself wanting to accumulate all the values for a given\nkey in a list. The mdict class provides a simple implementation of\nthis feature.'}, {'comments': [], 'desc': u'The collection class allows you to persistently monitor a collection of items. It reports on which items are new to the collection, which items have left the collection and the age in seconds of each item in the collection.'}, {'comments': [], 'desc': u'Using win32 API to change the background color of the menubar/menu items in a wxPython app without affecting system-wide settings.'}, {'comments': [{'comment': u"This could be much shorter, and really doesn't need to be a function:\n\n<pre>\nfrom sets import Set\nnew_list = list(Set(old_list))\n</pre>\n\nThis won't preserve the order of the original list, of course.", 'title': u' '}, {'comment': u'But is the list object callable?\n\nI get the following when I run the above:\n\n>>> new_list = list(Set(old_list))\nTraceback (most recent call last):\n File "", line 1, in ?\nTypeError: \'list\' object is not callable', 'title': u'Thanks Nick'}, {'comment': u'>>> from sets import Set<br>\n>>> old_list = [1,2,3,3,4,4,4,5]<br>\n>>> new_list = list(Set(old_list))<br>\n>>> list = []<br>\n>>> new_list = list(Set(old_list))<br>\nTraceback (most recent call last):<br>\n File "", line 1, in ?<br>\nTypeError: \'list\' object is not callable<br>', 'title': u"Don't redefine the list() built-in"}, {'comment': u'Even simpler, and faster, as of Python 2.4 with the C implementation of set data type in the core:\n\n->> L = [1,1,1,2,3,1,5,6,7]\n->> list(set(L))\n[1, 2, 3, 5, 6, 7]', 'title': u'And as of 2.4...'}, {'comment': u'Mike Watkins: oops, left result out.<br>\n->> L = [1,1,1,2,3,1,5,6,7]<br>\n->> list(set(L))<br>\n[1, 2, 3, 5, 6, 7]', 'title': u' '}, {'comment': u'a = [1, 2, 2, 3, 4, 4, 5]\nb = {}\nfor i in a: b[i] = 0\na = b.keys()', 'title': u'For versions later 2.3'}, {'comment': u'<pre>a = [1, 2, 2, 3, 4, 4, 5]</pre>\n<pre>b = {}</pre>\n<pre>for i in a: b[i] = 0</pre>\n<pre>a = b.keys()</pre>', 'title': u' '}], 'desc': u"I needed a list for a long bunch of elements but then I didn't want duplicates. I LOVE Sets, so I use a set to get the list I needed."}, {'comments': [{'comment': u'I think you should definitely go with the new proxy instance each time. No reason to lose thread safety when you don\'t have to.\n\n<pre>\nclass dictproperty(object):\n\n class _proxy(object):\n\n def __init__(self, obj, fget, fset, fdel):\n self._obj = obj\n self._fget = fget\n self._fset = fset\n self._fdel = fdel\n\n def __getitem__(self, key):\n if self._fget is None:\n raise TypeError, "can\'t read item"\n return self._fget(self._obj, key)\n\n def __setitem__(self, key, value):\n if self._fset is None:\n raise TypeError, "can\'t set item"\n self._fset(self._obj, key, value)\n\n def __delitem__(self, key):\n if self._fdel is None:\n raise TypeError, "can\'t delete item"\n self._fdel(self._obj, key)\n\n def __init__(self, fget=None, fset=None, fdel=None, doc=None):\n self._fget = fget\n self._fset = fset\n self._fdel = fdel\n self.__doc__ = doc\n\n def __get__(self, obj, objtype=None):\n if obj is None:\n return self\n return self._proxy(obj, self._fget, self._fset, self._fdel)\n</pre>', 'title': u'New proxy instance on each attribute access'}], 'desc': u'A Python property is accessed like a normal attribute, but is implemented using method calls. This is a recipe for dictproperty: an attribute that is accessed like an indexed (dictionary) attribute, but is implemented using method calls.'}, {'comments': [], 'desc': u'In most languages with closures, it is possible to change a closed-over value and have the change visible in other closures which share a reference to the same variable. Python\'s syntax makes this impossible.\n\nEven if you\'re content (I am) with the work-around-- putting your changeable values inside a mutable object like a list-- it may occasionally happen that you wish you could change the closed-over values, found in "cell" objects in a function\'s func_closure tuple. Another recipe I submitted shows how to get at the values in standard Python; this one will demonstrate a way to actually change that value, so that functions which also close over that value (share a reference to the same cell) will see the change.'}, {'comments': [{'comment': u'Since it is handling every line, I am wondering how is it different from any other approaches. Say, e.g., I could think of this alternative implementation for parse(cond) :\n<pre>\ndef parse(cond):\n for line in file(INPUT_FILE):\n for test_cond, value in cond:\n changed_line = line.replace(test_cond,value)\n if changed_line != line:\n yield changed_line #pattern was found\n break #skip to the next line\n if changed_line == line: # pattern was not found\n yield line # give back the original line\n</pre>\n--Hemanth', 'title': u'How is it efficient'}], 'desc': u"This script use an efficient way to tranform a file's\ntext to something else, with conditions for few lines."}, {'comments': [{'comment': u'and I read the mangled paragraph with ease too!', 'title': u'nice '}, {'comment': u'I doubt the algorithm\'s ability to fool a bayesian classifier armed with a reasonably large corpus. At best, the algorithm will render many words to be unrecognizable as spam words but it won\'t do anything to raise the count of non-spam words. At worst, a few of the misspellings for shorter words will unique to spam messages (for instance, "raed" is a typo that would only show up in a mangled message). Further, a high-percentage of unrecognizable words is its own cue that the message is spam (you can throw a blanket over the camel but can\'t hide its humps).', 'title': u'Naive bayes still pretty smart'}, {'comment': u'Some methods of cryptanalysis look for common letter combinations such as \'th\' and \'qu\'. This can be used to throw a little "speed bump" into that.', 'title': u'Other use...'}, {'comment': u'Well done. A nice class which performs the algorithm efficiently.', 'title': u'Well done.'}], 'desc': u'The misspell class takes a string and slightly mangles it by randomly transposing two adjacent characters while leaving the first and last characters intact. The resulting text is almost completely misspelled but still completely readable. Words less than four characters, numbers, email addresses and URLs are untouched. Each run will produce a message with a different signature (checksum).'}, {'comments': [], 'desc': u'To convert a given number into a string that contains the base 2 representation of the number, with its sign.'}, {'comments': [{'comment': u'I tried http://btbytes.com/techbytes/arff-to-sql-database-importer and got 404 error.', 'title': u'Link http://btbytes.com/techbytes/arff-to-sql-database-importer is broken'}], 'desc': u'Python script to import ARFF data files (http://www.cs.waikato.ac.nz/~ml/weka/arff.html)\ninto *any* database.'}, {'comments': [{'comment': u'<pre>\n File "sudoku-shaw.py", line 109, in solve\n all = digits()\nNameError: global name \'digits\' is not defined\n</pre>\nA few months ago I tried this too.<br>\nFind my shorter (and more procedural) versions here:<br>\n<br>\nhttp://www.maltemedia.de/sudoku/<br>\n<br>\nAll versions only try to insert valid numbers. <br>\n<br>\nThe first one uses a global square array without copying for the recursion, but reconstruction after the recursion.<br>\nThe second uses a linear array and copies the array before recursion.<br>\nThe third one uses a global linear array with reconstruction after the recursion.<br>\n<br>\nRegards<br>\nMalte<br>', 'title': u'Does not work for me / shorter versions'}, {'comment': u'def digits():\n return set(range(1, 10))', 'title': u'OOps'}], 'desc': u'This is a simple text based Sadoku puzzle solver.\n\nSee http://www.websudoku.com/ for more details.'}, {'comments': [], 'desc': u'Creates believable Chomsky style obfuscated prose.'}, {'comments': [], 'desc': u"Whoops... please delete it, it's a duplicate... There's an almost identical implementation in chapter 19.14 of the Python Cookbook. I'm not anymore sure if I wrote this from scratch a while ago.\n\nSuppose you have some sorted iterables, and you want to get them merged preserving ordering, without consuming iterables (and computing time) unnecessarily. This recipe may come in handy."}, {'comments': [{'comment': u"There exist already some 'expect'-like modules but they would all benefit from a 'non-pty' based approach.\n<br>\nThe author's subprocess module is a gem and I really hope that the functionality described in the above subclass would become part of the Python standard library.", 'title': u'Useful addition to the standard library'}, {'comment': u'I was successful using nonblocking io, for example.\n<pre>\nflags = fcntl.fcntl(subprocess.stdout, fcntl.F_GETFL)\nfcntl.fcntl(subprocess.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)\n</pre>\nOnce the process instance is created change its stdout to nonblocking reads. I am aware of one downside to this approach is the resource temporarily unavailable exceptions upon reading. These can be safely ignored. Another may be the need to poll the subprocess, so I suspect the select method with 0 for the timeout is more appropriate.', 'title': u'Possible alternative unix approach'}, {'comment': u'Instead of calling "get_conn_maxsize(which, maxsize)"<br>\nin the function _recv<br>\nI use "self.get_conn_maxsize(which, maxsize)"<br>\nOtherwise I get an error message', 'title': u'Error Message under winXP'}, {'comment': u'Sorry about that, I had forgotten the self. portion during a refactoring.', 'title': u' '}, {'comment': u"Well, select with 0 for a timeout only tells you if data is ready. If one attempts to read more than is available, it will block. I've included the fcntl trick to change the pipes to non-blocking. Thank you!", 'title': u' '}, {'comment': u"Sorry, maybe too much to ask for... But a couple examples would be very helpful. Maybe one executing a file and another executing an OS call such as 'dir' or 'echo'.\n\nThanks.\n\n --Alan", 'title': u'Maybe a Use Case Example?'}, {'comment': u"I've added a bit to the end of the recipe.", 'title': u' '}, {'comment': u"You don't need to set non-blocking mode. This is a common missconception.\n\nos.read and os.write only block in blocking mode if **nothing** could be read or written. Otherwise they will not block and will do a partial read/write. You are already checking with select() that at least something could be read/written, so they will not block, even without non-blocking mode.", 'title': u'non-blocking not required.'}, {'comment': u"I was able to avoid buffering problems with Windows Python by invoking Python with the '-u' option.", 'title': u'Python buffering in Windows'}, {'comment': u"I was able to avoid buffering problems with Windows Python by invoking the Python subprocess with the '-u' option.", 'title': u'Python buffering in Windows'}, {'comment': u"That doesn't always work.", 'title': u' '}, {'comment': u"Nice piece of code. I was dealing with the output from a long running process and found recv_some() would occasionally freeze. If the proc.recv() happened to take long enough, time.time() could be greater than x, which results in a negative argument for time.sleep(). It apparently tries to sleep forever in this case. I just added a check:\n\n<pre>\n delay=(x-time.time())/5\n if delay>0:\n time.sleep(delay)\n</pre>\n\nAlso, on Linux, I had to add 'import select'. Nice work, though, definitely saved me some time.", 'title': u'Long running processes'}, {'comment': u'After adding "import select", the code runs (SUSE 10). However, changing the line:\n<br>\nshell, commands, tail = (\'sh\', (\'ls\', \'echo HELLO WORLD\'), \'\\n\')\n<br>\nto\n<br>\nshell, commands, tail = (\'sh\', (\'./mttst.py\'), \'\\n\')\n<br>\nresults in an immediate error "Other end disconnected!"\n<br>\nmttst.py is executable and runs from the CL.\n<br><br>\n#! /usr/bin/python\n<br>\nimport time\n<br>\nprint "mttst.py started"\n<br>\nfor i in range(5):\n<br>#the next two lines should be indented. Don\'t know how.<br>\n print time.time()\n<br>\n time.sleep(1)\n<br>\nprint "mttst.py finished"\n<br>\n<br>\nSuggestions on what I\'m doing wrong much appreciated.', 'title': u"Can't capture child output"}, {'comment': u"The _setup method raises an exception if one of the stdin, stdout, stderr file descriptors is None.\n\nSetting non-blocking mode at sub-process startup (POSIX case) seems to break the unit tests (test_subproces.py) of the standard subprocess module.\nI set the non-blocking flag in _send and _recv methods and restore the original ones before they returns.\n<pre>\ndef _recv(self, which, maxsize):\n conn, maxsize = self.get_conn_maxsize(which, maxsize)\n if conn is None:\n return None\n\n flags = fcntl.fcntl(conn, fcntl.F_GETFL)\n fcntl.fcntl(conn, fcntl.F_SETFL, flags | os.O_NONBLOCK)\n\n try:\n if not select.select([conn], [], [], 0)[0]:\n return ''\n\n r = conn.read(maxsize)\n if not r:\n conn.close()\n setattr(self, which, None)\n return None\n\n if self.universal_newlines:\n r = self._translate_newlines(r)\n return r\n finally:\n fcntl.fcntl(conn, fcntl.F_SETFL, flags)\n</pre>\nThis fixes the problem.\nThe _setup method now is no more needed.", 'title': u'Standard subprocess unittest'}, {'comment': u'If you look at other pieces of the demo, it asumes each item run will execute almost instaneously. In this case, the program it is attempting to run takes around 5 seconds (plus the starting up of Python, which hopefully should be fast).\n\nEven if it did run successfully, it wouldn\'t necessarily print everything as output (especially considering Python\'s sometimes wonky stdout buffering semantics on certain platforms).\n\nI tried running it on Windows, and it printed out the "starting" message along with the first timestamp. Then it paused for 5 seconds waiting for the subprocess to close (while not recieving information), and quit without exception.', 'title': u' '}, {'comment': u'Thank you!', 'title': u' '}, {'comment': u"It looks like you used this code (I did a visual compare if this code was included that could have been more clear from your answer).\n<br>But actually 'self.' is missing in\nthe non mswindows version:\n<pre>\n def _recv(self, which, maxsize):\n conn, maxsize = self.get_conn_maxsize(which, maxsize)\n</pre>\nSo you cannot currently download the code and have it running on non-windows.", 'title': u"forgot 'self.'"}, {'comment': u'Fixed the code that you mention. Thank you.', 'title': u' '}, {'comment': u'When I run your example on Linux with Python 2.4.4 I get an exception. The stack dump is\n\n<pre>\nHELLO WORLD\nTraceback (most recent call last):\n File "./aspn_440554.py", line 167, in ?\n print recv_some(a, e=0)\n File "./aspn_440554.py", line 136, in recv_some\n r = pr()\n File "./aspn_440554.py", line 26, in recv\n return self._recv(\'stdout\', maxsize)\n File "./aspn_440554.py", line 123, in _recv\n fcntl.fcntl(conn, fcntl.F_SETFL, flags)\nValueError: I/O operation on closed file\n</pre>\n\nChanging the line 123 to \n<pre>\nif not conn.closed: fcntl.fcntl(conn, fcntl.F_SETFL, flags)\n</pre>\nfixes the problem for me.', 'title': u'Running your examples gives me a "ValueError: I/O operation on closed file"'}, {'comment': u'I modified a few more lines to fix it for all fcntl calls in the _recv method.', 'title': u' '}], 'desc': u"The 'subprocess' module in Python 2.4 has made creating and accessing subprocess streams in Python relatively convenient for all supported platforms, but what if you want to interact with the started subprocess? That is, what if you want to send a command, read the response, and send a new command based on that response?\n\nNow there is a solution. The included subprocess.Popen subclass adds three new commonly used methods: recv(maxsize=None), recv_err(maxsize=None), and send(input), along with a utility method: send_recv(input='', maxsize=None).\n\nrecv() and recv_err() both read at most maxsize bytes from the started subprocess.\nsend() sends strings to the started subprocess.\nsend_recv() will send the provided input, and read up to maxsize bytes from both stdout and stderr.\n\nIf any of the pipes are closed, the attributes for those pipes will be set to None, and the methods will return None.\n\nv. 1.3 fixed a few bugs relating to *nix support\nv. 1.4,5 fixed initialization on all platforms, a few bugs relating to Windows support, added two utility functions, and added an example of how to use this module.\nv. 1.6 fixed linux _recv() and test initialization thanks to Yuri Takhteyev at Stanford.\nv. 1.7 removed _setup() and __init__() and fixed subprocess unittests thanks to Antonio Valentino. Added 4th argument 'tr' to recv_some(), which is, approximately, the number of times it will attempt to recieve data. Added 5th argument 'stderr' to recv_some(), where when true, will recieve from stderr. Cleaned up some pipe closing.\nv. 1.8 Fixed missing self. parameter in non-windows _recv method thanks to comment.\nv. 1.9 Fixed fcntl calls for closed handles."}, {'comments': [{'comment': u'From this recipe:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/181905\n\nThanks!', 'title': u'Borrowed Some Code'}, {'comment': u'As of BitTorrent 4.1 or so BT natively supports Twisted, as such the above recipe no longer works without some hevy modification. Currently the best idea is to subclass LaunchMany, or to just add your own layer of MultiTorrent.<br><br>\n\nSee http://metamoof.net/2006/02/13/getting-bittorrent-working-under-twisted', 'title': u'This no longer works'}, {'comment': u'As of BitTorrent 4.1 or so BT natively supports Twisted, as such the above recipe no longer works without some hevy modification. Currently the best idea is to subclass LaunchMany, or to just add your own layer of MultiTorrent.<br><br>\n\nSee http://metamoof.net/2006/02/13/getting-bittorrent-working-under-twisted', 'title': u'This no longer works'}, {'comment': u"As per the comments on metamoof.\n\nThe design of BitTorrent predates twisted and twisted's rawserver looks eerily similar to twisted's reactor. Of course twisted has grown well beyond what rawserver ever tried to achieve.\n\nIn fact many bugs in twisted were debugged by Greg Hazel who was responsible for integrating twisted into BitTorrent.", 'title': u'History of BitTorrent vs. Twisted.'}], 'desc': u"Two modules that run a BitTorrent server, and uses Twisted as a client to coordinate control-message passing, and progress monitoring. The server can be run as a separate process, or as a thread within the client -- the same messages can be passed back and forth. \n\nControl messages can cancel individual downloads (or the whole process), as well as pause downloading. Progress queries can be invoked through the client, which will ping the server, and report back each downloads' progress. "}, {'comments': [{'comment': u"Nice recipe; Boost.Bind is actually a generalization of partial application so it's even more powerful. Two comments:<br>\n\n<br>- kw.copy() is not necessary; when a dict d is passed in as named arguments, a copy is created anyway.\n\n<br>- You can easily create automatically the first N placeholders; no need for eval():<pre>\n _g = globals()\n for i in xrange(100):\n _g['_%d' % (i+1)] = placeholder(i)\n</pre>\nAlthough for practical reasons this is more than enough, I still don't like the idea of predefining N. With a small change to the placeholder's syntax to enclose the position in brackets, placeholders are constructed and cached only when necessary:<pre>\n class _PlaceHolders(object):\n _cache = {}\n def __getitem__(self, i):\n assert isinstance(i,int) and i>0\n try: return self._cache[i]\n except KeyError:\n return self._cache.setdefault(i,placeholder(i-1))\n \n _ = _PlaceHolders()\n\n def foo(a, b, c, d = None, e = None): return (a, b, c, d, e)\n foo1 = bind(foo, _2, 2, _1, e = 'Nee!')\n foo2 = bind(foo, _[2], 2, _[1], e = 'Nee!')\n assert foo1(3,4) == foo2(3,4)\n</pre>", 'title': u' '}], 'desc': u"The Boost.Bind library \nhttp://www.boost.org/libs/bind/bind.html\n, which I use a lot in C++, has a very nice implementation of the Curry technique. The main innovation of the library is usage of 'placeholders', which allows 'currying' arbitrary parameters in the arg list (please see discussion section). I missed this library in Python, and reimplementing it in a dynamic language was a piece of cake (and I did not have to yell at my compiler to get it done ;). Enjoy!"}, {'comments': [{'comment': u'IPy is a package that fits a similar niche, with many more capabilities, not the least of which is IPv6 support. IPy is at http://c0re.23.nu/c0de/IPy/', 'title': u'IPy is an alternative'}, {'comment': u'...is IPv4_Utils at PyPI', 'title': u'...and another implementation...'}], 'desc': u'Two simple classes for IPv4 addresses and networks. Features include\nchecking if network contains another, returning ip/mask in normalized form,\nconversions from/to numeric/string, enumerating all contained ip addresses etc.'}, {'comments': [{'comment': u'I\'d like to use the HTML generated from this recipe with CSS classes. The problem is that you can\'t do T.tag(class="whatevercssclass") because "class" is a Python keyword and using it this way generates an error. Is there a clean way to get around this?', 'title': u'Attributes that are Python keywords'}, {'comment': u'add this chunk of code after line 46 of the code:\n\n<pre>\n\t__klass = kwargs.pop(\'klass\', None)\n\tif __klass:\n\t\tkwargs[\'class\'] = __klass\n</pre>\n\nthen just do this:\n<pre>\n T.option(klass="aclass")( ..some content..)...\n</pre>\n\nspelt with a \'k\' so Python does not catch it as a reserved word, and it \nwill output with the correct class="aclass" attribute', 'title': u"to add attribute 'class'"}, {'comment': u"I've added this modification to the code. Thank you.", 'title': u' '}], 'desc': u'The other day I was complaining about writing html, forms, etc., for Python cgi and/or web programming. I had pointed out a selection of three examples, the first of which ended up being very much like Nevow.stan . Thinking a bit about it, I realized that stan had issues in that you couldn\'t really re-use pre-defined tags with attributes via map, and keyword arguments were just too darn convenient to swap the calling and getitem syntax.\n\nInstead, I hacked together a mechanism that supports:\nT.tagname("content", T.tagname(...), ..., attr1=\'value\', ...)\nT.tagname(attr1=\'value\', ...)("content", T.tagname(...), ...)\nx = T.tagname(attr1=\'value\', ...)\ny = T.tagname(*map(x, [\'content\', ...]))\n... and many other options.\n\nEssentially, you can mix and match calls as much as you want, with three memory and sanity saving semantics:\n1. Creating a new tag object via T.tagname, or any call of such, will create a shallow copy of the object you are accessing.\n2. smallred = T.font(size=\'-1\', color=\'red\');bigred = smallred(size=\'+1\') Works exactly the way you expect it to. If it doesn\'t work the way you expect it to, then your expectations are confused.\n3. If you are adding content that sites within the tag, the content is replaced, not updated, like attributes.\n\nThis simple version handles auto-indentation of content as necessary (or desireable), auto-escaping of text elements, and includes an (I believe) nearly complete listing of entities which don\'t require closing tags.\n\nI don\'t know where this is going, whether it can or will expand into something more, or what, but I believe what I have managed to hack together is better than other similar packages available elsewhere (including this recipe over here http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/366000 , which I discovered after writing my own). Funny how these things work out. Astute observers will note that I borrow nevow.stan\'s meme of using T.tagname for generating tag objects.'}, {'comments': [{'comment': u'A few comments:<br>\n1. Shuffling the set of vaild characters before using random.sample() is unnecessary.<br>\n2. While hashing is generally useful for reasonably sized data sets, hashing a short string as initialization to MT would generally be quite ineffectual at actually seeding the random number generator.<br>\n3. Most people would use as an identifier either their login name or the domain of the url, etc. Sometimes sites change urls, sometimes users can\'t use the same login everyhwere, ...<br>\n4. Your module is stateless. That is, the only thing you need to carry around is the module itself; no database of passwords necessary. However, it does not solve the general problem of "I\'ve already got YY usernames and passwords that need to be stored, and it would be nice to know where I have logins". For that, there are many programs which also offer random password generation (see KeePass Password Safe for an example which does password generation right).', 'title': u' '}, {'comment': u'The problem with programs like Keepass, PINs, etc., is that strangely\nthey are always written for a single platform (either Windows or Linux) and not portable. For me the easiest way to store account information is in a plain text file with columns indicating Account Name, URL The problem with programs like Keepass, PINs, etc., is that strangely\nthey are always written for a single platform (either Windows or Linux) and not portable. For me the easiest way to store account information is in a plain text file with columns indicating Account Name, URL ', 'title': u'On the need to store the logins in a database'}, {'comment': u'Regardless of platform, your recipe still has the aforementioned problems. Find a decent encryption algorithm that is doable in Python, and write a simple interface to an encrypted password store. Then you can move around your (encrypted) list of sites with logins along with your simple Python interface, and solve all four problems.', 'title': u' '}, {'comment': u'Upgrading your version of Python in the future may cause you to loose all your passwords until you go back to the previous version.<br>\n<br>\nThis code assumes that you will get the same sample for any given seed. While this is true for any particular pseudo-random implementation, you are likely to get a different sequence if the implementation ever changes. The implementation of the random module has changed in the past. It may very well do so again. When this happens, the only way to recover your passwords is to go back to the previous version of the Python library.', 'title': u'Warning: depends on specific implementation of random module'}, {'comment': u'Thanks to Walker Hale for pointing out the dependence on Random. I have now written another routine to generate password by using the bits in the SHA-1 as index into the alphabet set.', 'title': u'Removed dependency on Random() implementation'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha254()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha256()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha256()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha256()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha256()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}, {'comment': u'From Python2.5 a new hashlib is added to the standard library. Versions are also available for Python 2.4 and 2.3. More hash algorithms are available in this now.\n<pre>\nimport hashlib\ns = hashlib.sha256()\ns.update("String to hash")\nprint s.hexdigest()\n</pre>', 'title': u'New hashlib from 2.5'}], 'desc': u"This recipe generates a password of any length using the standard library modules of Python. The password generated is a function of an identifier and a master password.\n\nI liked the idea behind the PasswordMaker browser plugin (http://passwordmaker.org/). But I wanted to have a portable command line version which I wanted to carry around without having the need to install an application or needing a web browser. Additionally I wanted to use only the pre-installed modules.\nI haven't looked into the PasswordMaker's algorithms but I have borrowed the main idea that you have a single master password. To that you add a site address or your account name and take a cryptographic hash (MD5, SHA-1, etc.) of this string. Your password will be a function of this generated hash.\nI have broken each of the above steps into separate functions so that one can replace the actual implementation with their own algorithms.\nNote on Security: I am not a security expert; so I am not qualified to comment on how secure this approach is. I welcome others' comments on the vulnerabilities.\n"}, {'comments': [{'comment': u'Wonderful recipe, but please add docstrings.', 'title': u'Needs docstrings'}, {'comment': u'Added docstrings.', 'title': u'Re: Needs docstrings'}], 'desc': u'Makes it easier to execute async calls or deal with external systems calls to which can block forever or occassionally take long time to complete.'}, {'comments': [{'comment': u'Here\'s a slight extension that will give you the min, max, and average time spent in a function. It might be useful for very simplistic profiling.\n\n<pre>\ndef timeit(f):\n """ Annotate a function with its elapsed execution time. """\n def timed_f(*args, **kwargs):\n t1 = time.time()\n\n try:\n f(*args, **kwargs)\n finally:\n t2 = time.time()\n\n dt = t2-t1\n timed_f.func_maxtime = max(dt, getattr(timed_f, \'func_maxtime\', 0))\n timed_f.func_mintime = min(dt, getattr(timed_f, \'func_mintime\',\n sys.maxint))\n timed_f.func_numcalls = getattr(timed_f, \'func_numcalls\',0)+1\n timed_f.func_avgtime = ((dt+((timed_f.func_numcalls-1) *\n getattr(timed_f, \'func_avgtime\',0))) /\n timed_f.func_numcalls)\n\n return timed_f\n\ndef print_functimes(f):\n print \'Avg running time: %f secs\' % f.func_avgtime\n print \'Max running time: %f secs\' % f.func_maxtime\n print \'Min running time: %f secs\' % f.func_mintime\n print \'Number of calls: %d\' % f.func_numcalls\n</pre>\n\n(BTW, to be a friendly decorator, it\'s probably a good idea to copy the __doc__, __name__, etc attributes from f to timed_f.)', 'title': u'Re: Use function annotation to track elapsed execution time'}, {'comment': u'How exactly is this function supposed to be called?', 'title': u' '}, {'comment': u"The timed_f function doesn't return any value.<br>\n\nAdding a:<br>\n\n<pre>res = f(...)</pre>\n\nand a<br>\n\n<pre>return res</pre>\n\nat the end solves the problem of timing a function that returns something.", 'title': u'Add a return value to timed_f'}], 'desc': u'This function annotates the a given function with its elapsed execution time in minutes, seconds, and milli seconds. The attricbute is a tuple named func_time. This function could also be used as a python 2.4 decorator.'}, {'comments': [{'comment': u"I recently had the need to debug what was going on in urllib2 as well. Upon investigating the urllib2 source, and the underlying httplib source I found that subclasses of urllib2.AbstractHTTPHandler incorporate an optional debuglevel parameter to their __init__ method. They then pass the debug parameter into the httplib.HTTPConnection object. This causes the information you're looking for to be displayed at runtime. Here's the solution I came up with:\n<pre>\ndef build_opener(debug=False):\n # Create a HTTP and HTTPS handler with the appropriate debug\n # level. We intentionally create a new one because the\n # OpenerDirector class in urllib2 is smart enough to replace\n # its internal versions with ours if we pass them into the\n # urllib2.build_opener method. This is much easier than trying\n # to introspect into the OpenerDirector to find the existing\n # handlers.\n http_handler = urllib2.HTTPHandler(debuglevel=debug)\n https_handler = urllib2.HTTPSHandler(debuglevel=debug)\n\n # We want to process cookies, but only in memory so just use\n # a basic memory-only cookie jar instance\n cookie_jar = cookielib.CookieJar()\n cookie_handler = urllib2.HTTPCookieProcessor(cookie_jar)\n\n handlers = [http_handler, https_handler, cookie_handler]\n opener = urllib2.build_opener(handlers)\n\n # Save the cookie jar with the opener just in case it's needed\n # later on\n opener.cookie_jar = cookie_jar\n\n return opener\n</pre>", 'title': u'Alternative way...'}, {'comment': u"I recently had the need to debug what was going on in urllib2 as well. Upon investigating the urllib2 source, and the underlying httplib source I found that subclasses of urllib2.AbstractHTTPHandler incorporate an optional debuglevel parameter to their __init__ method. They then pass the debug parameter into the httplib.HTTPConnection object. This causes the information you're looking for to be displayed at runtime. Here's the solution I came up with:\n<pre>\ndef build_opener(debug=False):\n # Create a HTTP and HTTPS handler with the appropriate debug\n # level. We intentionally create a new one because the\n # OpenerDirector class in urllib2 is smart enough to replace\n # its internal versions with ours if we pass them into the\n # urllib2.build_opener method. This is much easier than trying\n # to introspect into the OpenerDirector to find the existing\n # handlers.\n http_handler = urllib2.HTTPHandler(debuglevel=debug)\n https_handler = urllib2.HTTPSHandler(debuglevel=debug)\n\n # We want to process cookies, but only in memory so just use\n # a basic memory-only cookie jar instance\n cookie_jar = cookielib.CookieJar()\n cookie_handler = urllib2.HTTPCookieProcessor(cookie_jar)\n\n handlers = [http_handler, https_handler, cookie_handler]\n opener = urllib2.build_opener(handlers)\n\n # Save the cookie jar with the opener just in case it's needed\n # later on\n opener.cookie_jar = cookie_jar\n\n return opener\n</pre>", 'title': u'Alternative way...'}, {'comment': u"I recently had the need to debug what was going on in urllib2 as well. Upon investigating the urllib2 source, and the underlying httplib source I found that subclasses of urllib2.AbstractHTTPHandler incorporate an optional debuglevel parameter to their __init__ method. They then pass the debug parameter into the httplib.HTTPConnection object. This causes the information you're looking for to be displayed at runtime. Here's the solution I came up with:\n<pre>\ndef build_opener(debug=False):\n # Create a HTTP and HTTPS handler with the appropriate debug\n # level. We intentionally create a new one because the\n # OpenerDirector class in urllib2 is smart enough to replace\n # its internal versions with ours if we pass them into the\n # urllib2.build_opener method. This is much easier than trying\n # to introspect into the OpenerDirector to find the existing\n # handlers.\n http_handler = urllib2.HTTPHandler(debuglevel=debug)\n https_handler = urllib2.HTTPSHandler(debuglevel=debug)\n\n # We want to process cookies, but only in memory so just use\n # a basic memory-only cookie jar instance\n cookie_jar = cookielib.CookieJar()\n cookie_handler = urllib2.HTTPCookieProcessor(cookie_jar)\n\n handlers = [http_handler, https_handler, cookie_handler]\n opener = urllib2.build_opener(handlers)\n\n # Save the cookie jar with the opener just in case it's needed\n # later on\n opener.cookie_jar = cookie_jar\n\n return opener\n</pre>", 'title': u'Alternative way...'}, {'comment': u'My apologies for the repeat posts, the site was lagging a bit and I thought my post got lost in the ether.', 'title': u'Sorry for the repeats...'}, {'comment': u'Im a rank amateur with python and Im trying to access this URL to scrape score info:\n\nhttp://www.dreamteamfc.com/dtfc05i/servlet/PlayerProfile?playerid=18307&gameid=183\n\nHowever it uses a re-direct if you try and access it directly. If you try again (using a browser) it accesses a cookie and grants access.\n\nHow can I repeat this behaviour using urllib2?\n\nThanks.', 'title': u'Cookie Handling'}, {'comment': u'As I can see in urllib2.py, the build_opener function has this signature:\n\n<pre>def build_opener(*handlers):</pre>\n\nSo I think that we must change this line in your source code:\n\n<pre>opener = urllib2.build_opener(handlers)</pre>\n\nfor this one:\n\n<pre>opener = urllib2.build_opener(*handlers)</pre>', 'title': u'A correction'}, {'comment': u'I\'ve never used cookielib and urllib2 before. I wanted a simple "hello world" style program to show me how things worked. It is remarkable that your example is not in the official documentation!\n\nI spent an hour looking over the official docs for urllib2 and cookielib and got nowhere. I downloaded your example, changed the URL to the site I wanted to test against and VOILA, it worked!\n\nNow I am off and running! I\'m sure your example has saved countless people hours of wrestling with documentation!', 'title': u'bless you!'}], 'desc': u"Say you need to make sure the HTTP headers to and from the server are right? Or you just want to track them like using Firefox and LiveHTTPHeaders. Use this custom processor to watch them. Note that I used the ClientCookie package, but this should work with urllib2 without ClientCookie. It should also be adaptable to Python 2.4's cookielib."}, {'comments': [{'comment': u'can i use it in commercial project?\n<br>\nhttp://mortgage-calculator.teach-nology.com', 'title': u'can i use it in commercial project?'}, {'comment': u'that is quite useful. i\'ve modded it to just handle a simple function.\na lot if times, when developing/screen scraping, it\'s nice to have simple fuctions cache the results automatically. \n<pre>\nimport os\nimport cPickle as pickle\ndef autopickle(f):\n """ decorator to persistently cache a function """\n def new_f(*args, **kwds):\n filename = "pickled/%s.dat" % f.func_name\n if os.path.exists(picklename):\n return pickle.load(open(picklename))\n else:\n res = f(*args,**kwds)\n pf = pickle.dump(res,open(picklename,\'wb\'),1)\n return res\n return new_f\n</pre><br>\n\nUSEAGE:\n<pre>\n@autopickle\ndef get_station_list(rawurl):\n # this will only print 1x. \n print "getting from first time"\n soup = BeautifulSoup(U.urlopen(rawurl).read())\n atags = soup.findAll(\'a\',attrs={\'href\':re.compile(\'rawmain\',re.I)})\n return [a[\'href\'] for a in atags]\n\nif __name__ == "__main__":\n atags = get_station_list(rawurl)\n print "\\n".join(atags[:5])\n</pre>\n\n', 'title': u'simple function decorator. '}, {'comment': u"replace all ocurrences of 'picklename' with 'filename' so the previous works. ", 'title': u'error'}], 'desc': u'This recipe addresses the following two needs:\n- Object construction for some class is expensive.\n- Objects of this class need to be instantiated across multiple runs of the program.\nFor example, object instantiaton may involve reading one or more big files, connecting to a database or a network socket with considerable expected delay, etc.\n\nThe autopickle decorator deals with this problem by wrapping the __init__ of the class. The first time a specific instance is created, it is also pickled to a file. In all subsequent attempts to create the same instance, the pickled instance is loaded and returned instead. If unpickling the file is faster than creating the instance normally, all but the first instantiations are faster than the normal one.\n\nThe instance determines the path of the file to be pickled to by calling its getPickleFilename() method. This takes the same arguments given in __init__ and it has the responsibility to specify a valid and distinct path for the instance.'}, {'comments': [], 'desc': u'This recipe shows how to add a __getattr__ method to your class that allows you to use shortened forms for attribute names in interactive use.'}, {'comments': [{'comment': u"I am using it. It's quite handy.\n\nA bug is that it doesn't count the size of the taskbar. So the status bar of the explorers aren't visible. (I am using Win Xp)", 'title': u'Good stuff'}], 'desc': u'This recipie will run two copies of Windows Explorer, resize them to fit each of them to half the desktop size and place them side by side to facilitate file management between two directories or disk drives.'}, {'comments': [{'comment': u'Check out the PyCaptcha library too. I have found it to be simple and extensible:<br>\n<br>\nhttp://freshmeat.net/projects/pycaptcha/', 'title': u'An alternative python captcha library'}, {'comment': u'no pycaptcha projct on freshmeat; the ones I could find are all PHP.', 'title': u'dead'}, {'comment': u'http://sourceforge.net/projects/pycaptcha/', 'title': u'http://sourceforge.net/projects/pycaptcha/'}, {'comment': u'Instead of taking the word from dictionary it could be generated as follows:\n\n<pre>\ndef gen_random_word(wordLen=6):\n allowedChars = "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWZYZ0123456789"\n word = ""\n for i in range(0, wordLen):\n word = word + allowedChars[random.randint(0,0xffffff) % len(allowedChars)]\n return word\n\n</pre>\n\nThe main function would change to\n\n<pre>\n\nif __name__ == \'__main__\':\n\t"""Example: This grabs a random word from the dictionary \'words\' (one\n\tword per line) and generates a jpeg image named \'test.jpg\' using\n\tthe truetype font \'porkys.ttf\' with a font size of 25.\n\t"""\n word = gen_random_word()\n gen_captcha(word.strip(), \'porkys.ttf\', 25, "test.jpg")\n</pre>', 'title': u'An alternate method to generate the word'}], 'desc': u"The gen_captcha function generates an image containing text that's easy for a human to read, but difficult for a computer. This allows you create a test to tell humans and computers apart. (requires PIL)"}, {'comments': [{'comment': u'I added some tweaks for formatting, CDATA, and compactness:\n<pre>\ndef toXML(obj,objname,nodePrefix=\'\', isCdata=False):\n if obj == None:\n return ""\n if adapt.has_key(obj.__class__):\n return adapt[obj.__class__](objname,obj)\n else:\n objXML = None\n if hasattr(obj, \'toXML\'):\n objXML = obj.toXML(nodePrefix)\n if not objXML: return \'\'\n if not objXML: objXML = str(obj)\n if objXML and len(objXML)>0:\n if isCdata:\n return "%s<%s><![CDATA[%s]]></%s>\\n"%(nodePrefix,objname,objXML,objname)\n else:\n return "%s<%s>%s</%s>\\n"%(nodePrefix,objname,objXML,objname)\n else: return "%s<%s/>\\n"%(nodePrefix,objname)\n</pre>', 'title': u'Some Tweaks'}], 'desc': u'This function generates XML for any Python object through recursive functions. It is easy to add specific handlers for your own object types for more complex output options.'}, {'comments': [{'comment': u'So many similar if...elif... constructs are a sign that you need better data structures. In this case an array to hold the game, instead of 9 globals, would make the code a lot shorter. You have some recursion going on when xturn calls xtest, which then may call xturn again (same for oturn and otest). If the board was represented in a nine-element array your code would get a lot simpler. You should return a result from functions rather than making the functions call the calling function again.\n<br><br>\nHere\'s a tic-tac-toe game I developed for a programming class I organized for kids and teens. It shows typical Python data structures and functions. This program follows these rules to choose a square: (1) Win the game if possible; (2) Block opponent if necessary; (3) If playing offense, take a lever square if possible; If playing defense and opponent has an open lever square, make two-in-a-row to force opponent to block into a non-lever square; (4) Take the center; (5) Take a corner; (6)Take a side. A lever square is where two winning lines intersect. Given any two squares, draw lines through them to indicate all winning positions that include those squares. Eliminate lines that go through both squares. Eliminate lines that have an opponent\'s piece on them. If any intersections are left, those are levers. For any two squares you hold, if you can also occupy one of the levers for those squares you have made two two-in-a-row combinations, so you can win on the next turn.\n<br><br>\nThis code could condensed quite a bit, but it was developed during the course of the class and is verbose in places to illustrate programming concepts.\n<pre>\n# tic tac toe - revised version\n#\n# by Greg Jorgensen with help from Josh Singer\n\nfrom random import shuffle\n\n# wins contains all possible winning combinations,\n# excluding reflections and rotations\nallwins = [(1,2,3), (1,4,7), (1,5,9), (2,5,8), (3,5,7), (3,6,9), (4,5,6), (7,8,9)]\n\n# board values\nE = \'.\'\nX = \'X\'\nO = \'O\'\n\n# fresh board, note position 0 not used\nnewgame = [E, E,E,E, E,E,E, E,E,E]\n\n# opponent for each player\nopponent = {X:O, O:X}\n\n\n# helper functions\n\ndef display(game):\n \'\'\' print the game \'\'\'\n print "%s %s %s\\n%s %s %s\\n%s %s %s" % tuple(game[1:])\n\ndef askHuman(game):\n \'\'\' prompt human player to pick a square, return when they pick an empty square \'\'\'\n while 1:\n s = raw_input(\'\\nyour move (1-9)? \')\n try:\n p = int(s.strip())\n if p < 1 or p > 9:\n print \'between 1 and 9\'\n elif game[p] == E:\n return p\n else:\n print \'pick an empty square\'\n except:\n print \'numbers only\'\n\ndef possibleWins(wins, player, square):\n \'\'\' return all wins for player that don\'t include square \'\'\'\n w = []\n for a in wins[player]:\n if square not in a:\n w.append(a)\n\n return w\n\ndef winner(game, wins, player):\n \'\'\' return true if player won the game \'\'\'\n for p,q,r in wins[player]:\n line = (game[p], game[q], game[r])\n if line == (player, player, player):\n return 1\n\n return 0\n\ndef findWins(game, wins, player):\n \'\'\' find all winning squares for player, list of winning squares or [] if none \'\'\'\n squares = []\n for p,q,r in wins[player]:\n line = (game[p], game[q], game[r])\n if line == (player,player,E):\n squares.append(r)\n elif line == (player,E,player):\n squares.append(q)\n elif line == (E,player,player):\n squares.append(p)\n\n return squares\n\ndef findTwos(game, wins, player):\n \'\'\' find all two-in-a-row combinations with a possible win for player \'\'\'\n twos = []\n for p,q,r in wins[player]:\n line = (game[p], game[q], game[r])\n if line == (player,E,E):\n twos.append((q,r))\n elif line == (E, player, E):\n twos.append((p,r))\n elif line == (E, E, player):\n twos.append((p,q))\n\n return twos\n\ndef fi', 'title': u'Needs more sophisticated data structures'}], 'desc': u"This was my first file that was larger than 100 lines, and ended up being 500. I'm new at coding and would like some feedback as to how i can improve, and what you like. I also made the computer unbeatable, unless i messed up somewhere in my code and never noticed it."}, {'comments': [{'comment': u"Be aware that using fileinput.input() will concatenate all of the files on the command line into the output. I'm not sure if that's what the recipe intended. A slightly shorter version that works on a single file is:\n\n<pre>\nimport sys\n\nlines = open(sys.argv[1]).readlines()\nlines.sort()\nmap(sys.stdout.write, lines)\n</pre>\n\nThere might even be a shorter way to write this. Any takers?", 'title': u'Single file approach'}, {'comment': u'Hi!\n<br>\n\nWith sorted() you can make this a oneliner:\n<pre>map(sys.stdout.write, sorted(file(sys.argv[1]).readlines()))\n</pre>\n\nRegards, Markus', 'title': u' '}], 'desc': u'A simple (4 lines) recipe that will sort a file named on the command line and write the sorted lines to standard output.'}, {'comments': [], 'desc': u"Sometimes it's usefull to use MS-Excel as a gui front-end to your data(for viewing and processing),for example while debugging a program. \nThis script makes this task simple.\n\n"}, {'comments': [], 'desc': u"This recipe is based off of\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061\n\nI found and used the recipe above, however, I took issue with the results. See, I wanted to use it on a big Java file that had lots of long lines. With extra long package names, and extra long lines containing multiple semicolons without spaces after them, I found it necessary to modify this algorithm to suit my specific purposes.\n\nIf you have a line like this:\n\nimport com.jobsintheus.vaccinium.controller.ejb.stateful.VacciniumStatefulSessionRemoteHome;\n\nyou're going to have problems using the above algorithm, but the one herein does something useful with that - splitting the line on the periods too. It works for semicolons too.\n\nInserted line breaks will become the visible backslash charater plus the line break.\n\nOtherwise, line breaks that existed before stay as is (with no visible backslash character).\n\nThe point is to have the Java code be a readable addition as an input file to (la)tex verbatim."}, {'comments': [], 'desc': u'This is the first version of a game that I wrote. If you have ever played a card game called "WAR," then you already should be familiar with one version of this game. Well, this is my first interpretation of the game. One little note about winning the game -- control the "nines." That is how you will win. :)'}, {'comments': [], 'desc': u'And here is my second interpretation of the card game known as "WAR." If you are wondering how it works, you should look at "Version 1" of this program (it is another program that I submitted). There is no documentation whatsoever of this program (as you can see), but it follows just about the same logic of the first game. This game is just easier to win at IMHO.'}, {'comments': [{'comment': u"split's default seperator is whilespace.<br>\n\nSo little simplification can be done after try block (assuming this is easy to explain in an introduction).<br>\n\n<pre>\nnumbers = raw_input('What numbers should I average? ').split()\n</pre>", 'title': u' '}, {'comment': u'Are there tab requirements when I type this into the compiler?\n', 'title': u'Question'}, {'comment': u'The source must have the general tabbing as seen.\nTry downloading the source and executing it that way.', 'title': u'Answer'}, {'comment': u"<pre>\ndef main():\n while True:\n try:\n numbers = raw_input('What numbers do you want averaged? ').split()\n print 'The average is', average([int(number) for number in numbers])\n raw_input('Press enter to quit.')\n return\n except:\n print 'not here.'\n\ndef average(numbers):\n return sum(numbers) / len(numbers)\n\nif __name__ == '__main__':\n main()\n</pre>", 'title': u'Version 2'}, {'comment': u'Version 2 may seem to be somewhat more complicated but is also a good introduction to what can be done in Python. The recipe should probably be used only with more advanced programmers.', 'title': u'About'}], 'desc': u'Here is a simple program that can average a list of numbers. I wrote this to introduce someone to the language that we all use and love. :D The program may be simple, but it shows how easily a simple but useful program can turn out to be.'}, {'comments': [{'comment': u'Does anyone know of a standard format for printing directories, their files, their sub-directories, etc? That is the main this that this module is lacking. Is does not have any functions for displaying the contents of a "real" directory or a "packaged" directory. If there was a standard format, I would love to write the code for it or see the code that someone else might write for this purpose. It is annoying when you have a package and cannot (at a glance) see what its contents are. Example: someone doesn\'t want to paste a package for some specific reason that could easily be identified if they could only look at what the package contained.', 'title': u'Function(s) Requested'}, {'comment': u'How about\nhttp://www.jorendorff.com/articles/python/path/path.py', 'title': u'path.py'}, {'comment': u"I was looking for a function that would print out the list of files, sub-directories, etc. but could not find it. Do you know what the name of the of function is? All I'm looking for is some inspiration as to how someone would want to view a print-out of this information.", 'title': u'Where is the function?'}, {'comment': u'Depends on how you would like to format it.\nwalk() will do "depth-first":\n\n<pre>\nfrom path import path\nfor sub in path(\'.\').walk(): print sub\n</pre>', 'title': u'Walk?'}], 'desc': u'Here are a few basic fuctions that allow someone to copy a directory (along with its files and sub-directories) and paste it somewhere else. They ignore links and anything else that is not a directory or a file. The data returned from copy_dir() is in a format that paste_dir() can understand. A design note: what you get back from copy_dir() may be different whether or not you have a path separator at the end of the path; paste_dir() makes use of that feature (whether or not you want the first folder to be created). The fuctions can easily be modified to not include sub-directories in the returned package, and errors caused by accessing to files or directories can also be ignored with some simple editting. Also, note the asserts in the functions; these functions are designed to crash hard so that the calling code has to take care of the errors.'}, {'comments': [], 'desc': u'The main purpose of these functions are to allow encoding a string from base 256 to a special base 255. The function view the strings as numbers and simply change what base they are written in. This is not recommended for very long strings; otherwise, the encoding and deconding process can take a very long time to complete.'}, {'comments': [{'comment': u"It might be good to point out that the encryption method used here isn't very secure. For the record it's a single letter substitution cipher. It's simple to implement and likewise simple to break (which I'm sure the author is aware of).<br><br>\n\nIf let's say 6% of the letters in the data was an A before encryption and A get's translated to K, then 6% of the encrypted letters will be a K. Since these statistical properties are preserved it's possible to work the process backwards and recover the plain text without having the key.<br><br>\n\nAnother thing - calling seed with a string (as I assume name is) will seed the random number generator with the hash of the string. Since the hash is a python int this might reduce the information contained in the string in case a long key is used. There will be only 2^32 possible keys and the encryption is easily breakable with brute-force (trying every possible key). For encryption purposes it's not a good idea to pass a string to seed (or use the built-in seed at all).", 'title': u'Security'}, {'comment': u'That is why it is suggested that the "string_to_number()" function is recommended for use. Yes, this is not very secure; however, this would probably be an effective encryption system if, for example, it were used on an executeable. It might also be effective on a compressed file.', 'title': u' '}], 'desc': u'The main purpose of these functions are to encrypt and decrypt a string (or change the string from one "language" into another). I\'m guessing that Python already has something like this, but this is my implementation of the process. The code is simple, but it provides a simple solution to a well-known encryption scheme. As a recommendation, this may be better when used in conjunction with an encoding system (such as the base 256 to base 255 encoded that I submitted).'}, {'comments': [{'comment': u"The template syntax used in this recipe is quite similar to Quixote's PTL, which I had seen. It turns out that the implementation is also fairly similar, which I was not aware of (this is a clean-room implementation, I promise!). Both operate using the compiler module and modifying ASTs, although PTL is much more sophisticated in what it can do.<br>\n<br>\nPTL is somewhat different in that it returns any template strings found in a function, while this recipe evaluates the strings wherever they are found. As a result, the usage patterns are fairly different. Nonetheless, kudos to the team at mems-exchange.org for an original templating approach. ", 'title': u'Due credit'}], 'desc': u"A small, powerful templating language using template strings embedded in standard Python syntax. Templates are valid Python source, compiled directly to bytecode. Variable substitution is performed using 'string.Template'."}, {'comments': [{'comment': u"paste.util.classinit.build_properties provides something similar:\n\nhttp://svn.pythonpaste.org/Paste/trunk/paste/util/classinit.py\n\nIt uses a convention of __get, __set, __del suffixes to functions to build properties (automatically), and also to rewrite properties in a similar fashion when subclassing. Generally you'd run it in __classinit__ (using the metaclass also in that module).", 'title': u'another option...'}, {'comment': u'add_getters / add_setters / add_getters_and_setters in dulcinea.spec has a simpler job - look for "specifications in a class, in the format\n\n<pre>\nclass Foo:\n name_is = str\n age_is = either(int, long)\n\nadd_getters_and_setters(Foo)\n</pre>\n\nAnd you\'ll end up with a class that has set/get_name and set/get_age methods with appropriate checks for input in the set methods against the specification. The utility function intentionally does not override existing methods - often I need to write a custom "setter" that does more than just check for correct input. Also, "spec" is persistence method agnostic, although I now do most of my work against a Durus object database, I could see using this package with SQL Object or other approaches. <br><br>\n\nTasty:<br> http://www.mems-exchange.org/software/dulcinea/Dulcinea-0.10.tar.gz/Dulcinea-0.10/lib/spec.py\n\n<br><br>Part of a larger package:<br>http://www.mems-exchange.org/software/dulcinea/', 'title': u'similar but different'}], 'desc': u"Sometimes you define properties in base class and override the getter setter methods in derived classes. \nThen you find out the base class though has derived properties are still pointing to baseclasse's methods not the overriden ones."}, {'comments': [], 'desc': u"This program counts in a very strange way. Be sure to review it so that you can figure out how to shut it down. If you don't, you will get just as annoyed as I did. :P"}, {'comments': [{'comment': u'http://wswang.com/pytan/ajaxdemo<br><br>\nit display a random number in random background color, then fade in white.<br>\nIt used "Fade Anything Technique" from http://www.axentric.com', 'title': u'a little fancier example'}, {'comment': u'This is a nice example, but it would be cool if you\nincluded both input and output from the ajax handler.\nThis one just does output.', 'title': u'Need input and output'}], 'desc': u'This JSON parser works well with stringified Python list or dictionary. It is from json.org javacript json parser with small modification.'}, {'comments': [{'comment': u'Ah! A bug! :P -- That\'s just for me.\nIt is recommended that "raise SystemExit(0)" be removed from the html, plain, and self. Unfortunately, "try: code; except: code" can catch the exception and error handling code can be executed. Does anyone know of a better, harder way to kill a program while still returning an exit code of 0?', 'title': u'Error'}, {'comment': u'A solution was conjured up at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440642 in regards to the problem. The code can be modified so that it continues passing a SystemExit exception up the stack if needed.', 'title': u'Nevermind'}], 'desc': u'I found the CGI module to be nice in its power but wanted to create my own simpler version of the module. It lacks some of the power that the CGI module affords, but the code is small and has some helpful functions defined in it. The module listed below has been tested but really needs some test code written for it.'}, {'comments': [{'comment': u"Hadn't noticed a little error being displayed at the end of a file. Here is an improved show_file function.\n<pre>\ndef show_file():\n try:\n if cgi.dictionary['file'][-3:].lower() != '.py':\n raise Exception\n cgi.plain(file(cgi.dictionary['file']).read())\n except Exception, error:\n if str(error) != '0':\n show_form(cgi.dictionary['file'])\n</pre>", 'title': u'Found A Bug'}, {'comment': u"Here is the 2nd revision of the show_file() function. It is more precise in its purpose and now does exactly what it was supposed to do.\n<pre>\ndef show_file():\n try:\n if cgi.dictionary['file'][-3:].lower() != '.py':\n raise Exception\n cgi.plain(file(cgi.dictionary['file']).read())\n except Exception, error:\n if error.__class__ is not SystemExit:\n show_form(cgi.dictionary['file'])\n</pre>", 'title': u'Better Correction'}], 'desc': u'First of all, this code was written to take advantage of the custom CGI module that I wrote. The purpose for this script is to allow someone to view a CGI script through a server. I have the problem that when I click on a python (*.py) file while viewed through my browser, the script is run so that it cannot be viewed. Unless the script is using "cgi.execute(function, exception)", then there is no way of getting around the problem. Therefore, this CGI application was written so that python files (and only *.py files) can be viewed if the user knows either the filename of a file in the same directory as this script or the full path of a file somewhere on the host computer. WARNING: do not use this script if you do not want someone to view any and all python scripts on your computer!'}, {'comments': [{'comment': u'<pre>\n\n\n\n\nCGI Playground\n\n<!--\nBODY {\n\tFONT-SIZE: small; COLOR: #000000; FONT-FAMILY: "trebuchet ms", Verdana, Arial, Helvetica, sans-serif; BACKGROUND-COLOR: #FFFFFF\n}\n\nH1 {\n\tFONT-SIZE: large;\n}\n\nA:hover {\n\tCOLOR: #ff9900; TEXT-DECORATION: underline;\n}\n\n.footer {\n\tTEXT-ALIGN: center; FONT-SIZE: smaller;\n}\n\n.footer IMG {\n\tBORDER: 1px solid #888;\n}\n-->\n\n\n\nWelcome to Abyss Web Server\n<p>\nAbyss Web Server is running correctly on your system. You should now change this page with yours.\n\n<p>\nPlease include in your web pages (at least the first) the \'Powered by Abyss Web Server\' banner to promote the use of the software.\n\n\n\n<p class="footer">\nAbyss Web Server - \nCopyright © 2001-2005 Aprelium Technologies - All rights reserved\n\n<p class="footer">\n\n\n\t\n\t\n\t\tWhy is this the CGI Playground?\n\t\n\t\n\t\tThis place is all about testing Python CGI files.\n\t\n\t\n\t\tYou also have access to Volume C and Volume Z.\n\t\n\t\n\t\tIf you are wondering about the links below,<br>\n\t\tjust take a look at the source code.\n\t\n\t\n\t\n\t\tLinks:\n\t\n\n\t\n\t\n\t\tDoor Signs:\n\t\n\t\n\t\tJohnson 211\n\t\n\t\n\t\tJohnson 212\n\t\n\t\n\n\n</pre>', 'title': u'index.txt'}, {'comment': u'<pre>\nrmelc208.dorms.bju.edu Randy Melchert\nmtuck322.dorms.bju.edu Mark Tucker\npbeni427-web.dorms.bju.edu Peter Beninate\nzcoch215.dorms.bju.edu Zachary Cochran\nkcruc212.dorms.bju.edu Kevin Cruce\nnblac490.dorms.bju.edu Nathanael Black\nahamm894.dorms.bju.edu Aaron Hammons\njcris964.dorms.bju.edu Jonathan Crisan\nkstil371.dorms.bju.edu Kennie Still\nmangl442.dorms.bju.edu Melody Anglea\n</pre>', 'title': u'links.txt'}, {'comment': u'I was trying to show the contents of the index.txt file, but it is HTML source. Does anyone have a suggestion as to how I might be able to post the source here?', 'title': u'Sorry About That'}, {'comment': u"Let's think about pages linking to each other as directed graphs.\n<br>\nAnd let's say that link-pages made with a recipe such as this link to other link-pages of a similar kind.\n<br>\nIf the graph of linking has cycles: then pages linking (even indirectly) to pages in cycles would never show up.\n<br>\nInstead the various web hosts will start an endless parade of sending each other requests.\n<br><br>\nThis cool feature will probably be better if implemented in the browser instead of in websites.", 'title': u'The infinite recursion loop hole'}, {'comment': u'Notice that this program only makes a connection to another web server. It does not actaully make a request. Therefore, Python would not be invoked on each server that is checked.', 'title': u'Not a problem'}, {'comment': u'Notice that this program only makes<br>\na connection to another web server.<br>\nIt does not actaully make a request.<br>\nTherefore, Python would not be invoked<br>\non each server that is checked.<br>', 'title': u'Not A Problem'}], 'desc': u'The following allows someone to create "smart" links on their web site.\nThis is just a simple system and is not very advanced, but it works quite well (given its purpose). If a link is not active (because a server is down), the link is shown as such.'}, {'comments': [{'comment': u'I also have noted the similarity between comprehensions and SQL queries... and I plain dislike SQL syntax, and writing ugly SQL queries in a clean python program. :)\n<br>I\'ve wondered if there was some way of getting back to the data contained in a generator expression, such that something like\n\n<pre>query(r.name for r in plane_tbl if r.country == "France")</pre>\n\ncould be translated into the corresponding SQL query by the \'query\' constructor without performance penalty. Unfortunately, I couldn\'t find a way to inspect the objects generated by generator expressions... could anybody help in that?', 'title': u' '}, {'comment': u"I don't think you can inspect generators the way you have in mind, but check out SQLObject (http://sqlobject.org/SQLObject.html). It can express sql queries almost as clean as generators and with the same lazy evaluation property.", 'title': u' '}, {'comment': u'I don\'t think it\'s possible. Using the SQLObject approach would\nbe something like\n<pre>\nquery(r.name for r in TABLE.plane_tbl if r.country == "France")\n</pre>\n\nwhere TABLE implemented a getattr which tracked how the\nplane_tbl was used. Problem is, there\'s no way at the object\nlevel to distinguish the above vs.\n\n<pre>\nquery((r.country == "France", r.name) for r in TABLE.plane_tbl)\n</pre>\n\nnor, because of short circuiting, is it possible to get all of the\npossible routes through a complicated \'if\' test. Eg, consider\n\n<pre>\n if (r.population > 1E6 and r.latitude > 25) or\n (not r.population > 1E6 and r.latitude < -10)\n</pre>\n\nThe SQLObject approach seems to be the best. One alternative,\nbtw, is to allow introspection of a "well-formed" function.\n\n<pre>\ndef search(db):\n for r in db.plane_tbl:\n if r.country == "France":\n yield r.name\n</pre>\n\nYou can then inspect the byte code or parse tree to figure out what\nthe function is doing and construct a query with the same results.\nNot for the faint-hearted. :)', 'title': u"generators won't work"}, {'comment': u'It sounds like what you want is a language where you can reprogram how the compiler interprets the syntax. That\'s what you\'d be doing if you were reading the contents of a generator expression -- your input would be the generator expression\'s parse tree, and your output would be a new chunk of code. Essentially, a tree-transform... and that\'s what compilers do. :)\n\nAnd what\'s cool is that this is actually possible now. There\'s an interesting language called "boo" that\'s basically python-with-more-neat-stuff (and static typing). It\'s written for the CLI (Mono/.NET), but don\'t hold that against it -- it\'s still pretty spiffy\n\nhttp://boo.codehaus.org/\n\nNow if only someone would invent a language for writing new languages, so we can trade syntax modules instead of code modules.', 'title': u'This is a title!'}, {'comment': u'I have used this method in another recipe, #442447 : get the source code of the generator expression, then parse it with the compiler module, then build the SQL statement', 'title': u'Done in recipe 442447'}], 'desc': u'The usual way to make a request to a database is to write a string with the SQL syntax, then execute this request and get the result as a list with cursor.fetchall() or cursor.fetchone()\n\nPython has list comprehensions to select items in an iterable if a certain condition is true ; this is very similar to database requests\n\nThis recipe wraps a table of a DB-API compliant database in a class that implements the iteration protocol, so that you can use the for ... in ... if ... syntax'}, {'comments': [{'comment': u'__getitem__(slice) would be more intuitive if it returns a self.__class__ instance instead of a list. A safe way to do this is:\n<pre>\n ans = copy.copy(self)\n ans[:] = [self.get_element(i) for i in indices]\n return ans\n</pre>\nNote that it is not in general safe and correct to call self.__class__(), hence the extra cost of copying the instance.', 'title': u'__getitem__(slice)'}, {'comment': u'Right, that was a bug. I fixed it, but it required a change to the interface of ListMixin: instead of requiring __copy__, the ListMixin now requires constructor(self, iterable) => new instance initialized from given iterable. (The alternative was to require O(n) time for slicing out an empty slice, which is ridiculous).<br><br>\n\nNote that __repr__() intentionally uses self.__class__.__name__ in the created representation. Usually __repr__() is a developer feedback mechanism, so I think this is a reasonable compromise between theoretical safety and practical utility (i.e. practicality wins).', 'title': u'Bug'}, {'comment': u"That's better now. One more thing: I would prefer the required method names to start with underscore, i.e. s/get_element/_get_element, etc., since they are typically not intended to be exposed by the class inheriting the mixin.", 'title': u' '}, {'comment': u'Good idea...I changed the method names as suggested.', 'title': u' '}, {'comment': u"I ran the unittest test_list against listmixin.TestList. With a few patches, all the tests that should pass do. The patches and test results are below. Even so, if the goal is to match the behavior of built-in lists, there are problems with this implementation. Some of listmixin's methods assume the list is unaltered while the method is active. For instance:\n<pre>\n def __iter__(self):\n for i in xrange(len(self)):\n yield self._get_element(i)\n</pre>\n__iter__() does not accommodate changes in the list's length. If the list shrinks during the iteration, _get_elment(i) will assert; if the list gets longer, the extra elements will not be returned.\n\n<pre>\nPATCHES\n\n* Indices needed some type checking. I put in _fix_index:\n\n def _fix_index(self, i):\n if type(i) not in [types.IntType, types.LongType, types.BooleanType]:\n raise TypeError('list indices must be integers')\n .\n\n* Handle cases where lists are inserted into itself:\n\n def __setitem__(self, i, value):\n if value is self:\n value = self._constructor(value)\n .\n\n* Apparently Decimals are okay for pop and insert indices (but not elsewhere . go figure?)\n\nfrom decimal import Decimal as DecimalType\n .\n def pop(self, i=None):\n if i == None:\n i = len(self)-1\n elif type(i) == DecimalType:\n i = int(i)\n .\n def insert(self, i, x):\n if type(i) == DecimalType:\n i = int(i)\n .\n\n* Added __contains__():\n\n def __contains__(self, other):\n for item in self:\n if item == other:\n return True\n return False\n\nUNITTEST TEST_LIST\n\ntest_addmul (__main__.ListMixinTest) ... ok\ntest_append (__main__.ListMixinTest) ... ok\ntest_constructor_exception_handling (__main__.ListMixinTest) ... ok\ntest_constructors (__main__.ListMixinTest) ... ok\ntest_contains (__main__.ListMixinTest) ... ok\ntest_count (__main__.ListMixinTest) ... ok\ntest_delitem (__main__.ListMixinTest) ... ok\ntest_delslice (__main__.ListMixinTest) ... ok\ntest_extend (__main__.ListMixinTest) ... ok\ntest_extendedslicing (__main__.ListMixinTest) ... ok\ntest_getitem (__main__.ListMixinTest) ... ok\ntest_getitemoverwriteiter (__main__.ListMixinTest) ... ok\ntest_getslice (__main__.ListMixinTest) ... ERROR\ntest_iadd (__main__.ListMixinTest) ... ok\ntest_identity (__main__.ListMixinTest) ... ok\ntest_imul (__main__.ListMixinTest) ... ok\ntest_index (__main__.ListMixinTest) ... ok\ntest_init (__main__.ListMixinTest) ... ok\ntest_insert (__main__.ListMixinTest) ... ok\ntest_len (__main__.ListMixinTest) ... ok\ntest_minmax (__main__.ListMixinTest) ... ok\ntest_pop (__main__.ListMixinTest) ... ok\ntest_print (__main__.ListMixinTest) ... FAIL\ntest_remove (__main__.ListMixinTest) ... ok\ntest_repeat (__main__.ListMixinTest) ... ok\ntest_repr (__main__.ListMixinTest) ... FAIL\ntest_reverse (__main__.ListMixinTest) ... ok\ntest_reversed (__main__.ListMixinTest) ... ok\ntest_set_subscript (__main__.ListMixinTest) ... ok\ntest_setitem (__main__.ListMixinTest) ... ok\ntest_setslice (__main__.ListMixinTest) ... ERROR\ntest_slice (__main__.ListMixinTest) ... ok\ntest_sort (__main__.ListMixinTest) ... FAIL\ntest_subscript (__main__.ListMixinTest) ... ok\ntest_truth (__main__.ListMixinTest) ... ok\n</pre>\ntest_getslice/setslice/delslice failed because these functions are not implemented (and rightly so.) test_print and test_repr failed because TestList has a different repr from list. The test_sort failure is a bit esoteric: it an exception that doesn't occur with the listmixin implementation.\n", 'title': u'test_list results'}], 'desc': u'Use ListMixin to create custom list classes from a small subset of list methods.'}, {'comments': [{'comment': u'The code...\n<pre>\n start = clock()\n for i in range(count):\n f(*args, **kwargs)\n end = clock()\n</pre>\n<br>\n...is calculating the duration of 1) a for loop, 2) a list creation call (range), and 3) a function call. It is not calculating the time a function takes to run its code.', 'title': u'this function will report incorrect results'}, {'comment': u"Thanks for criticising the pytime() function. As part of the recipe's design, I intended pytime() to include the function call overhead. However, as you said, using range() in the timing loop is a bad idea (I modified the recipe to use xrange). Also, I reduced some more overhead by calling f() directly if no arguments are given, f(*args) if only positional arguments are given, and f(*args, **kwargs) at last resort.<br><br>\n\nNow back to your concerns. Often one may want to time Python statements directly, without the function call overhead. I added pytime_statement(), which does this. It works by pasting the statement multiple times into the inner timing loop, thus it has slightly less timing overhead than module timeit.", 'title': u'Addressing concerns'}], 'desc': u'Module timeit requires you to specify the number of iterations for the timing loop. This module does not.'}, {'comments': [], 'desc': u'A list of bits, compacted in memory so that 8 elements use 1 byte of storage.'}, {'comments': [{'comment': u'Thank you for sharing this excellent recipe!', 'title': u'Excellent'}, {'comment': u"It was very useful, thanks. I made the following adaption, though.\n\n<pre>\ndef paged(self, psize=128):\n recset = Dispatch('ADODB.Recordset')\n recset.Open(u'SELECT * FROM [%s]' % self.name, self.doc.conn, 0, 1)\n try:\n fields = [field.Name for field in recset.Fields]\n ok = True\n while ok:\n # transpose: rows become columns and columns become rows\n rows = zip(*recset.GetRows(psize))\n if recset.EOF:\n recset.Close()\n recset = None\n ok = False\n for row in rows:\n yield dict(zip(fields, row))\n except:\n if recset is not None:\n recset.Close()\n del recset\n raise\n</pre>", 'title': u'Small change'}, {'comment': u'Thanks for the transposing tip :)', 'title': u'Good idea !'}, {'comment': u'This code is extremely awesome, however when I tried using it inside a thread, this error pops up:<br>\n<br>\nException in thread Thread-1:Traceback (most recent call last):<br>\n File "D:\\Python23\\Lib\\threading.py", line 442, in __bootstrap<br>\n self.run()<br>\n File "D:\\mlim\\SPS-Python\\ITLWWMRToCGenerator\\Script1.py", line 18, in run<br>\n mainClass.getExcelList()<br>\n File "D:\\mlim\\SPS-Python\\ITLWWMRToCGenerator\\clsMain.py", line 93, in getExcelList<br>\n clsE = ExcelDocument(r"D:\\mlim\\SPS-Python\\ITLWWMRToCGenerator\\excel\\cin24-1.\nxls")<br>\n File "D:\\mlim\\SPS-Python\\ITLWWMRToCGenerator\\clsMain.py", line 104, in __init__<br>\n self.connection = win32com.client.Dispatch(\'ADODB.Connection\')<br>\n File "D:\\Python23\\lib\\site-packages\\win32com\\client\\__init__.py", line 95, in <br>\nDispatch dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,c\nlsctx)<br>\n File "D:\\Python23\\lib\\site-packages\\win32com\\client\\dynamic.py", line 84, in _\nGetGoodDispatchAndUserName<br>\n return (_GetGoodDispatch(IDispatch, clsctx), userName)<br>\n File "D:\\Python23\\lib\\site-packages\\win32com\\client\\dynamic.py", line 72, in _GetGoodDispatch<br>\n IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)<br>\ncom_error: (-2147221008, \'CoInitialize has not been called.\', None, None)<br>', 'title': u'Error when used in threads'}, {'comment': u'When using COM objects in a threaded context, you have to make sure to call pythoncom.CoInitialize(). See for example :<br>\n<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347209', 'title': u'This is normal'}, {'comment': u'I needed to access the fields by ordinal position, so not to bother my customer who does not send first row as headers in their excel files\n\nSo I changed this line: \n\n#fields = [self.encoding(field.Name) for field in recordset.Fields]\n\nto this:\nfields = [self.encoding(field) for field in range recordset.Fields.Count)]\n \n\nand now can access the fields I want like this:\n\nxls = ExcelAPI.ExcelDocument(mypath)\n sheetslist = xls.sheets() \n sheetnametoread = sheetslist[0] #want first sheet, could be named whatever\n rows = ExcelAPI.ExcelSheet(xls,sheetnametoread,0,0)\n for row in rows:\n print row[1],row[2],row[5],\n query= "Insert into CountyKeyedDeedInfo (DeedType,Book,CountyKeyedID) values(\'%s\',%s,%s)" %(row[1], row[2], row[5] )\n ret=cur.execute(query)\n ', 'title': u'Ordinal position choice instead'}], 'desc': u"Sometimes you get an Excel spreadsheet (say, from the marketing departement) and you want to read tabular data from it (i.e. a line with column headers and lines of data). There are many ways to do this (including ODBC + mxODBC), but the easiest way I've found is this one : provide a file name and a sheet name, and read the data !"}, {'comments': [{'comment': u'<pre>\ndef multiSplit(astring, *splits):\n """multiSplit(astring, *splits): given astring, and one or more split strings, it\n splits astring gerarchically. The first split key is the higher level one. Ex.:\n s = "a b\\nc d"\n split(s, "\\n", " ") => [[\'a\', \'b\'], [\'c\', \'d\']] """\n if len(splits) <= 1:\n return astring.split(*splits)\n else:\n sp = splits[1:]\n return [multiSplit(st, *sp) for st in astring.split(splits[0])]\n</pre>\n<br>\n\nNotice the splits[1:] instead of splits[-1:] -- in case you want to split on more than three parameters.\n\nNow you can correctly split::\n\n<br><br>\n<pre>\n tetris = """\\\n . . . .\n . # # .\n . # # .\n . . . .\n\n # # # #\n # # # #\n . . # #\n . . # #"""\n\n from textwrap import dedent\n tetris = dedent(tetris)\n print tetris\n print multiSplit(tetris, "\\n\\n", "\\n", " ")\n</pre>', 'title': u'split[1:] vs split[-1:]'}, {'comment': u'Took me a moment, but I think the term you mean in the description is "hierarchically", not "gerarchically". The latter isn\'t a word in the English language.<br><br>\nIt\'s not a coding issue, but fixing it might help people understand and find the recipe...', 'title': u'gerarchically?'}, {'comment': u'If you have a mandatory first separator argument, you can better emulate the behaviour of string.split. In addition you avoid the slicing of the separator argument.\n<pre>\ndef deepsplit(s, sep=None, *subsep):\n r"""deepsplit -- a nested string splitting function\n usage:\n >>> s = \'a b\\nc d\'\n >>> deepsplit(s) #split on whitepace, flat\n [\'a\', \'b\', \'c\', \'d\']\n >>> deepsplit(s, \' \') #split on space, flat\n [\'a\', \'b\\nc\', \'d\']\n >>> deepsplit(s, \'\\n\', \' \') #split on <cr>, then space\n [[\'a\', \'b\'], [\'c\', \'d\']]\n """ \n if not subsep:\n return s.split(sep)\n return [deepsplit(fragment, *subsep) for fragment in s.split(sep)]\n\nif __name__ == \'__main__\':\n import doctest\n doctest.testmod()\n</pre>', 'title': u'You could rearrange the argurment-list to have a mandatory first separator'}, {'comment': u'Slight mistake in the comment above. The first separator arg is not mandatory, but has a default value.', 'title': u'Mistake in comment above'}, {'comment': u"You solution is quite better than mine. I don't know if this deserves to become a standard string method. It's slick and elegant, and I use it now and then, but I don't know how often other people can use something like this.", 'title': u'Thank you'}], 'desc': u'To split a string more times, hierarchically.'}, {'comments': [{'comment': u"Twisted doesn't require asyncore.", 'title': u' '}, {'comment': u'I never claimed that Twisted required asyncore.', 'title': u'Huh?'}, {'comment': u"I found this server very usable, but there is one thing that should be noted. In StringIO module, method 'fileno' is not implemented and calling it will yield exception. This method is only called when user request directory listing.<br> \n<br>\nAbove description is for 2.4 version.\n<br><br>\nHere is little modification, where it will use 'fileno' if is implemented, and if not, it will calculate size without it.<br>\n<br>\nIn line 253, instead:<br>\n<pre>\nsize = os.fstat(f.fileno())[6]\n</pre>\n\nadd:\n\n<pre>\ntry:\n size = os.fstat(f.fileno())[6]\nexcept(AttributeError):\n size = f.len\n</pre>\n<br>\nPS.<br>\nWithoud this, directory listing will not be available because of exception. With this, listing will works fine.<br>\n<br>\nRegards.", 'title': u'Little mod...'}, {'comment': u'Thank you, fixed the bug.', 'title': u'Thanks!'}, {'comment': u"How come that if I add a __del__(self) to RequestHandler, it isn't called when the connection closes? Does this mean that the objects aren't garbage collected?", 'title': u'Garbage Collection?'}, {'comment': u'It seems that setting self.found_terminator = self.handle_request_line (as opposed to defining found_terminator()" hinders __del__ from being called. Why I don\'t know; please enlighten me.', 'title': u'Garbage Collection?'}, {'comment': u'The vagaries of Python garbage collection when a __del__ method is defined is somewhat of a mystery, though I have also run into issues when __del__ methods are defined on asyncore subclasses. My suggestion: override the handle_close() method to do what you would do in __del__.', 'title': u' '}, {'comment': u"I could be wrong, but I thought the asyncore and asynchat modules *are* Medusa. I thought that these were simply part of the renaming that was done once Medusa was added to the Python standard library since version 1.5.2. From what I understand about Twisted, it isn't based on Medusa/asyncore/asynchat.<br><br>\n\nRegardless, this is a really nice recipe! Runs fast, too. I've always been impressed by Twisted and plan to use it more, but I believe part of the point of this recipe was that is would only require modules in the standard library (asyncore and asynchat) instead of committing to a full Twisted install. Distribution is easier that way, API's will change less often, etc. For now, asyncore and asynchat are a little easier to understand for beginners like me, but of course you can't beat the stuff you get out-of-the-box with Twisted.<br><br>\n\nSorry for getting off-topic.", 'title': u'Confusion with the first two comments.'}, {'comment': u'Hi Josiah, how to add a link to "Up to higher level directory" in the sub folders?', 'title': u'how to add "Up to higher level directory"'}], 'desc': u'A recipe version of the SimpleAsyncHTTPServer with a few additional options not previously available for basic Python-only web servers.'}, {'comments': [], 'desc': u'This recipe uses NanoThreads. http://lgt.berlios.de/\n\nIt shows how simulated concurrency, (using generators as tasks), can be transparently combined with OS Level Python threads, as and when needed.'}, {'comments': [], 'desc': u"The Heap class is an improvement over a previous recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/437116) that also wraps the heapq module. There are two main differences from the other recipe:\n- All methods on this heap preserve the heap property invariant; therefore there is no need for is_heap().\n- When creating a new heap, an optional 'key' argument can be specified to determine the comparison key for the items to be pushed into the heap."}, {'comments': [], 'desc': u'Memoize, but clear cache when last function call returns. Suitable for dynamic programming.'}, {'comments': [{'comment': u'<pre>def test_4():\n first_name = "Foo" # imagine it is fetched from database\n last_name = "Bar"\n print call_template(locals())</pre>', 'title': u'Just use locals()'}, {'comment': u'<pre>def test_4():\n first_name = "Foo" # imagine it is fetched from database\n last_name = "Bar"\n print call_template(test_template, locals())</pre>', 'title': u'Of course, that should have been ...'}, {'comment': u'... but with locals() the caller has to do the trick. Frame inspection saves the caller from writing locals(). locals() may be more portable to other implementations than CPython, though.', 'title': u'Right you are...'}, {'comment': u"This would be much more typical (and in fact, looking for a solution to this problem is what led me here). If there's more than one layer, you'll need to search up the frame stack to find the controller rather than just assuming it called the view directly.", 'title': u'What if there are additional layers between the controller and the view?'}], 'desc': u"Using string templates to separate views from models and controllers is fine, but passing data from controllers to views is often tiresome. Using frame inspection can make things a lot more straightforward, saving you the hassle of explicitely passing each and every bit of data the template needs through boring lines of code like {'name':name}. Here is a sample with a fake templating system."}, {'comments': [{'comment': u"Nice tool, but shouldn't it escape lines starting with 'From ' at<br>least in the data section when using a mbox style file backend?<br>\nPseudo-diff:\n<pre>\n- self.mailboxFile.write( data )\n+ self.mailboxFile.write( data.replace('\\nFrom ', '\\n>From ' )\n</pre>\n\nPete", 'title': u'From escaping?'}, {'comment': u'wow, great, exactly what I was looking for.\n\nbtw. this could be integrated in some web frameworks. however I wonder what is the license of it. Could we use it in the BSD like licensed frameworks?', 'title': u'license for frameworks?'}], 'desc': u'This little class starts up an SMTP server which acts as an email sink, collecting all received emails destined for any address. All emails are routed to a Portable Unix Mailbox file. This is very handy for testing applications that send email. It runs in its own thread, so you can easily use it from a test fixture to collect your emails and verify them for correctness.'}, {'comments': [{'comment': u'Looks pretty finite to me. ;-)', 'title': u'Infinite?'}], 'desc': u'Generates an infinite character pasword'}, {'comments': [{'comment': u'Your article is really interesting and concise, which adds value.<br>\nBTW, is there any way to get the "desktop" dimensions in Linux/Unix?', 'title': u'Good stuff, one question'}, {'comment': u'I\'m not very good in Linux programming, but in the Bazaar VCS sources used such approach to get width of terminal:\n\n<pre>def terminal_width():\n """Return estimated terminal width."""\n width = 0\n try:\n import struct, fcntl, termios\n s = struct.pack(\'HHHH\', 0, 0, 0, 0)\n x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)\n width = struct.unpack(\'HHHH\', x)[1]\n except IOError:\n pass\n if width <= 0:\n try:\n width = int(os.environ[\'COLUMNS\'])\n except:\n pass\n if width <= 0:\n width = 80\n\n return width</pre>\n\nI hope this helps.', 'title': u' '}], 'desc': u"This recipe is Python implementation of few lines of C-code that get useful information about current working console on Windows. It may be useful for console application to proper formatting output. Recipe need ctypes package to be installed.\n\nThis is the second version of recipe. When use handle of stdout for determining size of console and connect output of program via pipe to another program (e.g. pager 'more') then you get default 80x25 size. In case of using handle of stderr for this purpose then pipe don't destroy actual size."}, {'comments': [], 'desc': u"This is my implementation of Rendering Arbitrary Objects with Nevow (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286260) using CherryPy 2.1. CherryPy doesn't care about adapters or stuff like that, but since it is written in Python it is easy to add that sort of functionality."}, {'comments': [{'comment': u"This won't work as advertised, for instance, with 'thisFunctionDoesSomething'. Since 'this' won't match the [A-Z][^A-Z] regexp, it won't show up in re.findall.\n<br>This function will add a space in each uppercase-lowercase boundary.\n\n<pre>\ndef split_uppercase(string):\n return re.sub(r'([a-z])([A-Z])', r'\\1 \\2', string)\n</pre>", 'title': u"Doesn't work as specified"}, {'comment': u'thisFunctionDoesSomething() is a perfectly-readable function name.', 'title': u'Completely Useless'}, {'comment': u"First off, I'd like the say that this recipe is a complete waste of time. Please don't ask me why I'm spending time fixing it.\n\nSecondly, there's an error in your regex.\n\n<pre>\n>>> split_uppercase('thisIsAFunctionName');\n'this Is AFunction Name'\n</pre>\n\nThat can be fixed with the following...\n\n<pre>\ndef split_uppercase(s):\n return re.sub(r'([a-z]*)([A-Z])',r'\\1 \\2',s)\n</pre>\n\n<pre>\n>>> split_uppercase('thisIsAFunctionName')\n'this Is A Function Name'\n</pre>", 'title': u'Regex Correction'}, {'comment': u"def split_uppercase(string):\n\tx=''\n\tfor i in string:\n\t\tif i.isupper():\n\t\t\tx+=' %s' %i\n\t\telse:\n\t\t\tx+=i\n\treturn x.strip()\n\n>>> split_uppercase('HolaQueTal')\n'Hola Que Tal'", 'title': u'Simple. No regex'}], 'desc': u'This function accepts a string and returns a string with whitespace(one space) inserted between words with leading capitalized letters.'}, {'comments': [], 'desc': u'This recipe explains how to check that a given function does not run slower than a given pystone rate. It first calculates the pystone ratio on your box.'}, {'comments': [], 'desc': u'This recipe applies the "once and only once" principle to function default values. Often two or more callables specify the same default values for one or more arguments. This is especially typical when overriding a method. Using the defaultsfrom(func) decorator, a method may \'inherit\' the default values from the super method. More generally, any function may inherit the default values from another one.'}, {'comments': [], 'desc': u"The Voicent Python Simple Interface class contains the following functions.\n\n callText\n callAudio\n callStatus\n callRemove\n callTillConfirm\n\nThese functions are used to invoke telephone calls from your Python program. For example, callText is used to call a specified number and automatically play your text message using text-to-speech engine.\n\nIn order for this class to work, you'll need to have Voicent Gateway installed somewhere in your network. This class simply sends HTTP request for telephone calls to the gateway. Voicent has a free edition for the gateway. You can download it from http://www.voicent.com\n\nMore information can be found at:\nhttp://www.voicent.com/devnet/docs/pyapi.htm\n"}, {'comments': [{'comment': u"Hi. I'd recommend that methods like setMenu() should be added to a specialization of Function class instead of the class itself. That should improve the reuse of Function class.", 'title': u'Factorization recommended'}], 'desc': u'A simple but useful class that emulates a function to gracefully permit latent assignment. In other words, I can use the emulating class as a valid function in assignments with the ability to later associate a function to perfrom the actual operations.\n'}, {'comments': [{'comment': u'are you the Peter Norvig from Google?', 'title': u'by the way'}], 'desc': u'Given a message encoded with a shift/rotation cipher, such as rot13, this recipe recovers the most probable plain text for the message. It does this by using statistics of bigram (2-character sequence) counts from a sample of text.'}, {'comments': [], 'desc': u'Packing images of different sizes into one image is often required in order to efficiently use hardware accelerated texture mapping functions of 3D video cards.'}, {'comments': [{'comment': u'Afaik, Apache Benchmark does all that and more.', 'title': u'Why not ab?'}, {'comment': u"I needed a simple tool which was able to measure times where I specified them. It wasn't meant to be a full-on benchmarking tool, so I am not surprised that apache bench supports additional options, though I am surprised to note that ab does not measure a superset of the times that I do, nor does it include median and standard deviation in its statistics. It does offer data transfer totals and rates, which I should probably add into my recipe, if not to be complete, but to save people from having to work out data transfer totals and rates by hand afterwards (I have).", 'title': u' '}, {'comment': u'It is late friday evening and i needed something to stress the tcp stack /http server of an embedded device over the weekend.\nFound your script ...\nIt perfectly matches my needs. This is a really good example for handy code snippets.', 'title': u'runs out of the box...'}, {'comment': u"I hacked this to return stats on the top 10 open socket connections\n(from 'netstat -n --inet'). When the stddev of the max goes over 3\nthen I send an alert. Apache Bench may do more, but this is hackable.\nTook me all of 20 minutes...", 'title': u'Thanks!'}, {'comment': u"This is a great script - thanks for sharing.\n\nI had a problem hitting an HTTP/1.1 server as it was expecting a Host: header, so I replaced the following line:\n\n<pre>\ns.sendall('GET /%s HTTP/1.1\\r\\n\\r\\n'%file)\n</pre>\n\nwith\n\n<pre>\ns.sendall('GET /%s HTTP/1.1\\r\\nHost: %s\\r\\n\\r\\n'% (file,host))\n</pre>", 'title': u'Update for http/1.1 hosts'}, {'comment': u'I have added support for passing the Host: header. Thank you for the suggestion.', 'title': u' '}], 'desc': u"Recently, there has been a discussion between myself and another individual as to the performance of particular web servers under certain situations. Being that web server testing frameworks have different ways of measuring how long a 'request' takes, I thought I would take the guesswork out of it and measure everything explicitly.\n\nThere are generally 5 portions to a web request:\n1. create the connection\n2. start sending the request\n3. finish sending the request\n4. start recieving the response\n5. finish reading the response\n\nThis recipe measures the amount of time to perform each portion of a request to a single file many times, and prints the results in a somewhat reasonable fashion."}, {'comments': [{'comment': u"If you are not looking for properties that are overrideable method by method, then this can be implemented in an even simpler way:\n\n<pre>\nProperty = None\n\nclass Property (object):\n class __metaclass__ (type):\n def __new__(cls, name, bases, dct):\n if Property in bases:\n get = dct.get('get')\n set = dct.get('set')\n delete = dct.get('delete')\n doc = dct.get('__doc__')\n return property(get, set, delete, doc)\n return type.__new__(cls, name, bases, dct)\n\n</pre>\nThis Property class can be used just like the earlier version. The advantages of this approach are: <br>\n1) Shorter code. <br>\n2) behaves identical to to the built-in property() method. The property objects created are the same as if done by calling property(), since it the implementation uses the property itself. <br><br>\n\nThe disadvantage is of course, you cannot override get, set, or delete separately.", 'title': u'A simpler implementation'}], 'desc': u"This recipe allows you to declare properties as inner classes. It's based combining a class-based idea proposed by Michael Urman on python-dev (http://mail.python.org/pipermail/python-dev/2005-October/057372.html) with late-binding properties (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408713)"}, {'comments': [{'comment': u'<pre>\nfinal_list = []\ntry:\n f_enter_0(*enter_0_args, **enter_0_kargs)\n final_list.append(((f_exit_0, exit_0_args, exit_0_kargs))\n ...\n f_enter_1(*enter_1_args, **enter_1_kargs)\n final_list.append(((f_exit_1, exit_1_args, exit_1_kargs))\n ...\n f_enter_2(*enter_2_args, **enter_2_kargs)\n final_list.append(((f_exit_2, exit_2_args, exit_2_kargs))\n ...\nfinally:\n while final_list:\n try:\n function = elements[0]\n if len(elements) > 2:\n args, kargs = elements[2:]\n function(*args, **kargs)\n elif len(elements) > 1:\n function(*elements[1])\n else:\n function()\n except Exception, e:\n handleFinallyException(e)\n</pre>', 'title': u"Wouldn't a structure like this work?"}, {'comment': u'Oops, missing line (pasting in parts):\n\nThe final loop should read:\n<pre>\n...\nfinally:\n while final_list:\n try:\n elements = final_list.pop()\n function = elements[0]\n if len(elements) > 2:\n...\n</pre>', 'title': u'oops -- add to top of final loop'}], 'desc': u'This is a convenient way to deeply nest try/finally statements.'}, {'comments': [{'comment': u'I always thought this was impossible, but then I had no idea that the innards of list comprehensions were generator expressions. Python metaprogramming strikes again!', 'title': u'This is really cool'}], 'desc': u'This recipe is a follow-up to #440653, which was easy to implement but very slow because the iteration required to read all the rows of a table\n\nAs suggested by Matteo Dell\'Amico in a comment, it would be much better if we could write something like\n\n\tquery(r.name for r in plane_tbl if r.country == "France")\n\nwhere the generator expression is first translated into an SQL select, so that the iteration on the instance of query only reads the rows selected by the SQL statement\n\nThe present recipe is an attempt to achieve this. The first problem is to get the source code of the generator expression. I use information from the stack frame to get the file name and the line number, then the tokenize module to read the elements of the generator expression in the source code\n\nThen, to build the SQL statement, the source code must be parsed : this is done using the compiler package and "visitors" that walk the AST tree returned by compiler.parse and do operations on the nodes, depending on their type\n\nFinally, once the SQL statement is built, the iteration on the query instance can start : for the first one, the SQL statement is executed ; then the iteration yields the selected rows one by one. \n\nThe items can be :\n- objects, with attribute names matching those in the generator expression, except that qualified names (table.name) are converted to table_name\n- dictionaries : the keys are the same as the attribute names above\n- lists\n\nFor instance :\n- iterating on query(name for r in plane_tbl) returns objects with an attribute name\n- iterating on query(r.name for r in plane_tbl) returns objects with an attribute r_name\n\nThis is because of iteration on tables which have the same field names\n\nquery((r.name,c.name) for r in plane_tbl for c in country_tbl if r.speed > 500 )\n\nThe type of the items is set by query.return_type = object, dict or list'}, {'comments': [{'comment': u'5 stars for the lovely title, sadly none left...', 'title': u'Title'}, {'comment': u'Very nice. I dropped it into a program I have and added a bunch of random places to throw exceptions - everything works beautifully.', 'title': u'Very Nice'}], 'desc': u"Even production applications have bugs, and it would be nice to have Python tracebacks emailed to you rather than dumped to the hapless user's screen. This recipe shows you how."}, {'comments': [{'comment': u'Here\'s my version, which I think is simpler.\n\n/cco\n<pre>\n\nimport re\nlastNum = re.compile(r\'(?:[^\\d]*(\\d+)[^\\d]*)+\')\n\ndef increment(s):\n """ look for the last sequence of number(s) in a string and increment """\n m = lastNum.search(s)\n if m:\n next = str(int(m.group(1))+1)\n start, end = m.span(1)\n s = s[:max(end-len(next), start)] + next + s[end:]\n return s\n\ndef T(_):\n print "from",_, "to", increment(_)\nif __name__==\'__main__\':\n T("10dsc_0010.jpg")\n T("10dsc_0099.jpg")\n T("dsc_9.jpg")\n T("0000001.exe")\n T("9999999.exe")\n T("ref-04851")\n</pre>', 'title': u'Simplification'}], 'desc': u'Suppose one reference number on your invoice is "XYZ-001", then let this algorithm figure out that the next one should be "XYZ-002" or that "dsc_010.jpg" should become "dsc_011.jpg"'}, {'comments': [], 'desc': u'Remove non-empty directories leaving specified directories.'}, {'comments': [{'comment': u"I've always thought setting up a SSL server was only for the experts in cryptography, so finding this short recipe, very well explained, is a very nice surprise. I've followed your explanations and everything worked, except I had to google around to find a Windows binary for OpenSSL for Python 2.4. I found it here : http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.4.exe.\n<br>Merci beaucoup !", 'title': u'Excellent !'}], 'desc': u"This recipe describes how to set up a simple HTTP server supporting SSL secure communications. It extends the SimpleHTTPServer standard module to support the SSL protocol. With this recipe, only the server is authenticated while the client remains unauthenticated (i.e. the server will not request a client certificate). Thus, the client (typically the browser) will be able to verify the server identity and secure its communications with the server.\n\nThis recipe requires you already know the basis of SSL and how to set up OpenSSL. If it is not the case you should consult [1].\n\nThis recipe is mostly derived from the examples provided with the pyOpenSSL [2] sources.\n\n\nIn order to apply this recipe, follow these few steps:\n\n1- Install the OpenSSL package [1] in order to generate key and certificate. Note: you probably already have this package installed if you are under Linux, or *BSD.\n\n2- Install the pyOpenSSL package [2], it wraps the OpenSSL library. You'll need to import this module for accessing OpenSSL's components.\n\n3- Generate a self-signed certificate compounded of a certificate and a private key for your server with the following command:\n\nopenssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes\n\nThis must have output them both in the same file named server.pem\n\n4- Assuming you saved this recipe in SimpleSecureHTTPServer.py, start the server (with the appropriate rights):\n\npython SimpleSecureHTTPServer.py\n\n5- Finally, open https://localhost with your browser, or https://localhost:port if your server listen a different port than 443.\n\n[1] http://www.openssl.org\n[2] http://pyopenssl.sourceforge.net"}, {'comments': [], 'desc': u'This function will return a list of tuples of process names and ids. It should provide a starting point for grabbing other process related information out of the pdh.'}, {'comments': [], 'desc': u'This is an easy way to construct a tree by given leaf nodes.'}, {'comments': [], 'desc': u'You want to create a simple browser-based desktop application with minimal fuss.'}, {'comments': [], 'desc': u'Converts Python source to a portable XHTML 1.0 strict document that includes a basic set of Dublin Core metadata. Based on the MoinMoin source colorizer.'}, {'comments': [], 'desc': u'This is basically the same as Version 2 except that now the cards are shown in ASCII art. The cards and imaging system are imported from some other modules that I wrote. Enjoy the game!'}, {'comments': [{'comment': u'You seem to be struggling very hard to replace the curses module.', 'title': u' '}, {'comment': u"And you, Paul Jimenez, seem to be forgetting that there is no 'curses' module on the Win32 platform.", 'title': u' '}, {'comment': u"Indeed I did - I avoid that platform whenever possible. For portability's sake perhaps this should be turned into 'win32curses' or somesuch and given an identical API - then it would 1) make existing curses-using programs easier to port and 2) let windows python programmers learn an API that will be useful to them on other platforms.", 'title': u'Indeed.'}, {'comment': u"With lists and/or mmap objects, you could make this faster for older Python versions (removing the += operation on strings). Just an idea.<br><br>\n\nIf I remember correctly, Python for cygwin has curses (if you want/need it), though I would understand not wanting to use it (I don't).", 'title': u'list/mmap'}], 'desc': u'There are probably other, better ways of printing ASCII graphics in Python; but since I do not know what they are, this is the product from that lack of knowledge. This is not meant to be the complete, final version -- there were other versions before this. Definitions and descriptions were finally written, and the code here tries to hold closely to concept that were put forth. Following the code are the specification for how the code should work.'}, {'comments': [{'comment': u"Oh, forgot to mention this implementation will only work on libc platforms having either ctypes or dl modules. I've tested it on FreeBSD and MacOSX (Darwin 10.4).", 'title': u'Platforms'}, {'comment': u"After a little debugging, I discovered that multiple users on the same machine could not connect to the same multicast channel. This may or may not be important to you, but it was for me. And challenging to track down. In order to achieve this, you must bind to the ANY address '::' (or ''), which made sense. But to complicate matters, a udp46 protocol on MacOSX does not seem to support it. I'm not sure if it is a bug or not, but to allow binding, simply switch to udp6 protocol by setting IPV6_V6ONLY.\n\n<pre>\nsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)\n</pre>", 'title': u'Multicast between different users on the same machine'}], 'desc': u'IPv6 can be tricky in many ways, and multicast makes it even more fun. This recipe is intended to give you a working implementation to start from. '}, {'comments': [{'comment': u'<pre>\nprint "Right order:"\nstufflist.sort(key=locale.strxfrm) # using locale\nprint "".join(stufflist)</pre>', 'title': u'Faster to use key=locale.strxfrm than cmp=locale.strcoll'}, {'comment': u"Beware:<br>\n<br>\n- The built-in function 'sorted()' is only available from Python 2.4.<br>\n<br>\n- Support for the keyword argument 'key' to the 'sort()' method of lists was only added in Python 2.4 as well.", 'title': u'Compability'}], 'desc': u'It takes me over half an hour to learn how it works. (I hope to save your time)\n\nYou have to remember to add compare function to your sort/sorted command.'}, {'comments': [], 'desc': u'I found my self want to express -string- in -list of regular expressions- and so I wrote this quick object to do the trick for me. It takes a list of strings containing regular expressions, compiles them into an internal list and then using the __contains__ operation ("in") looks to see if a given string contains any of the expressions. The first success returns True otherwise it returns False. '}, {'comments': [{'comment': u"Interesting concept! a good way to grab some simple user input when you don't want to write a whole widget. \n\nThe test app throws an exception for me (Python 2.4.1) on line 1042, after passing my mouse over the 2nd Right-side menu item:<br>\ndirs = [ re.sub( '.*%s' % os.path.sep, '', x ) for x in dirs ]", 'title': u'exception'}, {'comment': u'The regex for stripping file names (basename() would have done as well) gets messed up under Windows by putting a backslash at the end of the regex. An oversight caused by only working under Unix', 'title': u'Overlooked WIndows directory separator'}], 'desc': u'A variant of a Tkinter Menu which allos sub-menus to:\n automatically open/close when the controlling button is active/inactive\nsub-menus can be instances of any arbitrary widget, such as a Pmw.ComboBox'}, {'comments': [], 'desc': u'This recipe is meant to be used as a commmand line *.tar.gz file extractor. If it fails, then a usage note is given. It may be small, but it can be very useful for some people.'}, {'comments': [], 'desc': u'This program can help convert source code written in Unix into a format that can easily be read under Windows.'}, {'comments': [], 'desc': u'A caching decorator that garbage collects in a separate thread (for performance), allows each cached function to (optionally) set a custom maximum age for entries, and allows individual cache entries to be selectively invalidated.'}, {'comments': [], 'desc': u'You have files named with funky characters lying around in your\nfilesystem. Ugly files like "My Document #3 - (2005)[1].txt" are\ncommon when you\'re sharing directories with Windows users, but you\nwould like to have them renamed to something like\n"my_document_3_-_2005-1-.txt" so that your shell and other unix\nutilities won\'t have to deal with special characters.'}, {'comments': [{'comment': u'"There should be one-- and preferably only one --obvious way to do it."<br>\n Python Zen, by Tim Peters<br>\n<br>\nIn a moment of Python Zen, I found that Dan Gunter had already written\n\nthe same program and given it the same name:<br>\n\n<pre>\n2005-03-10 Dan Gunter [email removed]\n\n\t* python/tools: [...] Also added a little utility \'dribble.py\'\n\tto slowly copy data from stdin to stdout (for testing).\n\n</pre>\nhttp://www-didc.lbl.gov/NetLogger/ChangeLog<br>\n<br>\nFrom now on, I\'m not going to write code. I\'m just going to pick a name and Google it.', 'title': u'One Way To Do It'}], 'desc': u"This script echos the input with a time delay after each line. The input can be from standard input or a list of files on the command line, like the Unix 'cat' command. The delay between lines is adjustable, and defaults to 1 second."}, {'comments': [], 'desc': u'I needed a quick hack to extract some data from MS InfoPath files stored on a file server. Infopath data files are stored as XML so it was fairly straight forward to extract the required information. The outputed file is report.csv and a log file is called reportlog.txt. It reads settings from config.ini.'}, {'comments': [{'comment': u'Is this using smb or cifs as an underlying protocol for the transfer? I find both of these protocols to have painful latency and inherent slowness. I am looking for a module that has this functionality but which works fast. I guess with this module the windows user features for permissions is achieved.\n\nThanks,\nLuke', 'title': u'smb? cifs?'}], 'desc': u'This module enables users on the windows platform to transfer files to remote hosts. Requires pywin32 extensions by Mark Hammond'}, {'comments': [], 'desc': u"Have you ever tried to log an exception of unknown type ? What's in it ? How to fetch stack trace ? Will str(e) return plain ascii or international chars ? Is logger ready for it ? This recipe provides a formatting function."}, {'comments': [], 'desc': u'This hack allows you to add a cookie/header to a SOAPpy request. It uses a keyword args all-through to pass your own transports down to the SOAPpy core. It uses the ClientCookie module to store the cookies generated and/or to send the cookies. '}, {'comments': [], 'desc': u'Extension of the Restful Resource recipe from the cherrypy wiki (http://www.cherrypy.org/wiki/RestfulResource) to support nested resources and to dispatch based on HTTP verbs. '}, {'comments': [{'comment': u'Python 2.5 sets are implemented as a dictionary variant without values (not even references to None). See setobject.c, available here: http://svn.python.org/view/python/trunk/Objects/setobject.c?rev=41434&view=auto', 'title': u' '}], 'desc': u"This is inspired by Raymond Hettingers recipe for sets, using sorted lists.\nHowever here I'm not sorting the original list but just the indices and the sets share a common universe. This code is not for production use, I just show it in order to explain what I want to do."}, {'comments': [{'comment': u'<pre>If we want to convert a utf-16 encoded file to a \'unicode-escape\' encoded file replace the following two lines:<br>\nifile = open(sys.argv[1],"r")\nofile.write(data)\n\nwith these:\nifile = codecs.open(sys.argv[1], encoding=\'utf-16\', errors=\'strict\')\nofile.write(data.encode(\'unicode-escape\'))</pre>\n', 'title': u'To handle unicode I/O'}], 'desc': u'This program takes an input of a fixed width database output file with a header names, dashes, and data and converts it into CSV data. The code assumes that the dashes represent the fixed-column widths. For simplicity, all quotes are removed from data and all columns are wrapped with quotes.'}, {'comments': [{'comment': u"Before anyone jumps on me: in posting this, I am not implicitly advocating that explicit type checks are usually a good idea in Python. I know the potentially detrimental effect it can have on polymorphism, and duck typing in particular. In fact, I almost never use these kinds of up-front checks. The recipe is mostly intended as a demonstration of an implementation technique that can be used for more general contract-checking. And if you need to write boilerplate type-checking code for whatever reason (I don't judge!), the require decorator is a useful shortcut.", 'title': u'Type-checking considered harmful?'}, {'comment': u'There are previously existing recipes which do this.', 'title': u' '}, {'comment': u"nice recipe.\nmight be nice to enhance it so that all the type specs could be specified in a single @require call, like this:\n\n<br><pre>\n@require(x=(int,float), y=float)\ndef foo(x,y): pass\n</pre><br>\nseems like it shouldn't be too hard, something along the lines of:\n<br><pre>\ndef require(**typemap):\n for arg_name, allowed_types in typemap:\n if type(allowed_types) == types.TypeType:\n allowed_types = (allowed_types,)\n # ... proceed as before\n<pre></pre></pre>", 'title': u'more compact'}], 'desc': u'This is a handy little decorator that lets you annotate function definitions with argument type requirements. These type requirements are automatically checked by the system at function invocation time. The decorator frees you from writing type-checking boilerplate code by hand.'}, {'comments': [{'comment': u'The problem with your solution is that you must wrap all of the underlying methods to be effective. I personally prefer the standard answer of "use a list."<br>\n\n<pre>ref = [obj]</pre>', 'title': u' '}, {'comment': u'I clearly didn\'t provide sufficient examples. You use a Ref object just like you\'d use a list, except the syntax for setting/reading a value looks more like an extended lambda-calculus Cell than a list. Where you\'d write arg[0] in a method if you passed a list, you\'d write +arg to get the value, and arg[0] = value becomes arg += value.\n\nTo write the classic "inc" function, you\'d write:\n<pre>\ndef inc(x):\n x += +x\n</pre>', 'title': u'No other wrappers needed.'}], 'desc': u'This is a container class, suitable for use to answer the question "How do I pass a reference to a variable to a function", abusing some of the methods to get a syntax that\'s easier to use than more conventional containers.'}, {'comments': [{'comment': u"Of course, it would all be much simpler if Python syntax would allow this:\n<pre>\n if m = re.search(patternA, line):\n match = m.group('A')\n elif m = re.search(patternB, line):\n match = m.group('B')\n</pre>\nPerhaps there should be a special assignment operator for use in if-tests? ", 'title': u'Why not assignment in test?'}, {'comment': u"In Python it isn't allowed and probably will never be allowed to use assignment in expressions.\n<br><br>\nThere are some other fiddly ways you can do it, maybe like:\n\n<pre>\nclass Value(object):\n def __init__(self):\n self.__dict__['_v'] = None\n def set(self, value):\n self._v = value\n def __getattr__(self, attr):\n return getattr(self._v, attr)\n def __setattr__(self, attr, value):\n setattr(self._v, attr, value)\n\nv = Value()\nfor line in lines:\n if v.set(regex.search(line)):\n print v.group(1)\n # or if Value is less magic, and more explicit:\n print v._v.group(1)\n</pre>\n\nThese tricks are of dubious value, though; they introduce new idioms that are hard to justify in the long term.", 'title': u'No = in expressions'}], 'desc': u"A wrapper class for (a small part of) the 're' module, that enables you to do re.match() or re.search() in an 'if' test or 'elif' test and use the result of the match after the test."}, {'comments': [{'comment': u"<pre>\nThanks for the nice tool. However, https redirection is not handled,\nsince urllib2 doesn't let you do set_proxy on the redirection\nrequests. I modified the above opener accordingly:\n\nclass ConnectHTTPHandler(urllib2.HTTPHandler):\n \n def __init__(self, proxy=None, debuglevel=0):\n self.proxy = proxy\n urllib2.HTTPHandler.__init__(self, debuglevel)\n\n def do_open(self, http_class, req):\n if self.proxy is not None:\n req.set_proxy(self.proxy, 'http')\n return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)\n\nclass ConnectHTTPSHandler(urllib2.HTTPSHandler):\n\n def __init__(self, proxy=None, debuglevel=0):\n self.proxy = proxy\n urllib2.HTTPSHandler.__init__(self, debuglevel)\n\n def do_open(self, http_class, req):\n if self.proxy is not None:\n req.set_proxy(self.proxy, 'https')\n return urllib2.HTTPSHandler.do_open(self, ProxyHTTPSConnection, req)\n\nNote that you specify your proxy with urllib2.build_opener, e.g.,\n\n p = '127.0.0.1:5865' \n opener = urllib2.build_opener(\n ConnectHTTPHandler(proxy=p), ConnectHTTPSHandler(proxy=p))\n\nAlso, of course, you no longer need to do req.set_proxy in your own\ncode.</pre>", 'title': u'Modification to use with https redirection (required for libgmail)'}, {'comment': u'To work with "HTTP proxy with CONNECT support to tunnel HTTPS request", a ProxyHTTPSConnertion is needed inside ConnectHTTPHandler <br>\n\nThis is the code change <br>\n<pre>\nclass ConnectHTTPHandler(urllib2.HTTPHandler):\n def do_open(self, http_class, req):\n return urllib2.HTTPHandler.do_open(self, ProxyHTTPSConnection, req)\n</pre>', 'title': u'HTTP proxy with CONNECT support to tunnel HTTPS request'}], 'desc': u'This small module builds an urllib2 opener that can be used to make a connection through a proxy using the http CONNECT method (that can be used to proxy SSLconnections).\nThe current urrlib2 seems to not support this method.\n'}, {'comments': [{'comment': u"It's a neat trick but you haven't said anything about what the motivation is. If the nested class' methods receive the outer class instance as first argument, what purpose does the nested class serve? Why not just define its methods directly on the outer class?", 'title': u'Why?'}], 'desc': u"inspired by Steven Bethard's recipe at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418 \nthis class allows you to use an inner class as an extention of your class."}, {'comments': [{'comment': u"The fact that there's no from x import q seems to confirm it.", 'title': u"The q() function doesn't seem to be defined"}, {'comment': u'PP_URL = "https://www.sandbox.paypal.com" + q("/cgi-bin/webscr")<br>\n\nq was simply a sort routine to webify spaces etc<br>\n<br>\njust use this<br>\n<br>\nPP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"<br><br>\n\nor the test website equivalent<br>', 'title': u'q - get rid of it'}, {'comment': u'We switched to accepting Unicode characters and it still worked ', 'title': u'Handles Unicode'}, {'comment': u'You shouldn\'t insert parameters directly into your query, because you may run into problems with special characters, or worse, SQL injection attacks. Instead, do this:\n\n<pre>\n query = "INSERT INTO names VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"\n db = MySQLdb.connect(host="localhost", user="username", passwd="passwd",db="db")\n cursor = db.cursor()\n cursor.execute (query, (invoice, firstn, lastn, street, city, state, zipc,\n f[\'payer_email\'].value,payer_url, f[\'option_selection1\'].value, f[\'option_selection2\'].value))\n f1.write(cursor._executed)\n</pre>', 'title': u'Use query parameters'}], 'desc': u"This is a cgi script that allows you to log an ipn request from paypal. Basically if you configure your paypal account with an ipn url it will send a post to a script url. You need to respond with a post and then will receive a VERIFIED response.\n\nI've included a subroutine to log the data to a database, but you could simply use a text file if that is all you need."}, {'comments': [], 'desc': u'this is a hack to get the "foo" module that\'s outside a package whithin a file of the package, when it also contains a module named "foo" (ie relative imports)'}, {'comments': [{'comment': u"It seems that not all the code is present. For example, there's no definition of the called function 'register_fields_pickler()' and the function 'add_fields_pickling()', which is defined, is not called anywhere...", 'title': u'Incomplete?'}, {'comment': u"The example was old, plus there was a bug (__setstate__ would recurse into itself).\n<br><br>\nI uploaded a new version which also allows pickling 'field' instances with methods returning unpickleable instances - an exception will be raised remotely when running these methods.\n<br><br>\nI hope the number of embarrassing mistakes has decreased...", 'title': u"Oops, you're right"}], 'desc': u'A \'fields\' class is a class that acts like a struct full of fields, e.g.:\n\n<pre>\nclass Titles:\n def __init__(self, name): self.name = name\n def dr(self): return "Dr. " + self.name\n def mr(self): return "Mr. " + self.name\n</pre>\n\nOnce an instance is constructed, the return value of x.dr() or x.mr() doesn\'t change.\n\nI sometimes have \'fields\' classes that I need to pickle (e.g. they go over a wire) but they contain unpickleable members, like file objects or tracebacks.\n\nThis code adds picklers to such classes that automatically \'flattens\' the instances on pickling, saving the return values and making the unpickled instance return the saved values.'}, {'comments': [{'comment': u'where are the snippets :D ?\n\nAnyway you can use set() builtin type or Set class in 2.3 to filter out duplicate stuff', 'title': u' '}], 'desc': u"I'm trying to create two seperate functions. One that removes all duplicate values from an array, and a fuction that removes all dupicate values from a list. "}, {'comments': [{'comment': u"<pre>\nimport os, sys\n\ndef main():\n try:\n purge(' '.join(argv[1:])\n print 'Done.'\n except:\n print os.path.basename(sys.argv[0]), ''\n\ndef purge(path):\n for name in os.listdir(path):\n path_name = os.path.join(path, name)\n try:\n if os.path.isdir(path_name):\n purge(path_name)\n elif os.path.isfile(path_name):\n size = os.path.getsize(path_name)\n file(path_name, 'wb', 0).write(chr(0) * size)\n except:\n print 'ERROR:', path_name\n\nif __name__ == '__main__':\n main()\n</pre>", 'title': u'Version 2'}], 'desc': u'This command-line program will replace the content of your files with zeros.'}, {'comments': [], 'desc': u'This program will print out the number of times a character is found in a file.'}, {'comments': [], 'desc': u'This program has been documented. It is designed to encode and decode files (for encryption purposes). It uses a simple encryption method.'}, {'comments': [], 'desc': u'This program is meant to be used to extract *.BMP and *.JPG files from one file that has one or more of these image files stored inside of it. Corruption of the image file is verified manually after the file has been extracted.'}, {'comments': [{'comment': u"There is a little bug in the code.\n\nThe line:\n<pre>\nself.file = open('x.flv', 'rb')\n</pre>\n\nShould be:\n<pre>\nself.file = open(filename, 'rb')\n</pre>\n\nI guess you will see that quickly enough once you try to run the code..\n", 'title': u'Little bug in the code listed'}], 'desc': u'How to read metadata from flash video files (height, width, etc.)\n\nCode oringinally stolen / ported from http://inlet-media.de/flvtool2'}, {'comments': [], 'desc': u"Some people have a burning need for emacs-like multiple key sequence hotkeys. What do I mean? Ctrl+x Ctrl+s to save the currently open document and exit emacs.\n\nIncluded as code is a sample wxPython program which implements multi-group keypress combinations, and will print 'hello!' in the statusbar if the combination Ctrl+Y Alt+3 Shift+B is entered. As you are entering a valid sequence of hotkeys, it will print your current combination in the status bar. If you make a mistake, it will print out your failed keyboard combination.\n\nI use variants of the menu manupulation and keymap generation code in PyPE (http://pype.sf.net)."}, {'comments': [{'comment': u"I think I have found a bug when setting open ended intervals:\n\n<pre>\n>>> i = intervalmap()\n>>> i[0:2] = 1\n>>> i[2:8] = 2\n>>> i[4:] = 3\n>>> i\n{[0, 2] => 1, [2, 4] => 2, [4, None] => 3}\n</pre>\n\nThe representation is right but the internal state seems wrong:\n\n<pre>\n>>> i._items \n[None, 1, 2, 2]\n</pre>\n\nThe last element shouldn't be 2 but 3. When setting another interval the error also shows up in the representation:\n\n<pre>\n>>> i[5:6] = 4 \n>>> i\n{[0, 2] => 1, [2, 4] => 2, [4, 5] => 2, [5, 6] => 4, [6, None] => 3}\n</pre>\n\nThis is wrong. The interval [4, 5] should be mapped to 3 instead of 2. The following patch fixes this:\n<pre>\n--- old.py 2005-11-28 14:29:52.000000000 +0100\n+++ new.py 2005-11-28 14:30:45.000000000 +0100\n@@ -77,9 +77,9 @@ def __setitem__(self,_slice,_value):\n else:\n self._bounds[start_point:] = [_slice.start]\n if start_point < len(self._items):\n- self._items[start_point:end_point] = [self._items[start_point]]\n+ self._items[start_point:] = [self._items[start_point],_value]\n else:\n- self._items[start_point:end_point] = [self._upperitem]\n+ self._items[start_point:] = [self._upperitem]\n self._upperitem = _value\n else:\n if end_point>=0:\n\n</pre>\n\nAll the other tests still succeed.", 'title': u'bug + fix'}, {'comment': u"I've integrated your fix and added a unit test. Thanks a lot !", 'title': u'Thanks'}, {'comment': u'A neat little recipe, but I am concerned that the asymptotic time complexity of interval insertion. I believe that the current version is not O(lg n) due to the O(n) step to update the bounds and items lists. \n\nCan you comment, Nicolas?', 'title': u'Asymptotic analysis'}, {'comment': u"You're right, a seemingly innocuous statement like self._bounds[start_point:end_point] = [_slice.start,_slice.stop] is indeed O(n). So insertion time is not O(log n).<br>\n<br>\nHowever, and in my usage pattern it's the most important thing, the lookup remains O(log n). This is the kind of data structure that you will write to once in a while but lookup a lot.<br>\n<br>\nSolving the insertion time asymptotic limit would require using a tree structure with appropriate algorithm so that replacing a range of keys could be done in O(n log n). That is certainly feasable but a bit too much for this recipe.<br>\n<br>\nRegards,<br>\nNicolas<br>\n<br>\nP.S. I'm sorry for the delay in answering your question, but the cookbook doesn't notify the recipe authors about new posts. It's about time this cookbook gets updated with recent innovations in mind, like e-mailing or even crazy technologies like RSS.", 'title': u"You're right for insertion time, not lookup time"}, {'comment': u'Useful recipe, thanks a lot! I easily managed to retrieve the interval bounds for an arbitrary given point. Therefore now my question: Is there a simple way to glue neighbouring intervals with identical values?', 'title': u'Unifying intervals'}], 'desc': u"This structure is a kind of dictionary which allows you to map data intervals to values. You can then query the structure for a given point, and it returns the value associated to the interval which contains the point. Boundary values don't need to be an integer ; indeed in the unit test I use a datetime object."}, {'comments': [], 'desc': u'Accepts a function to be approximated, and a list of x coordinates that are endpoints of interpolation intervals. Generates cubic splines matching the values and slopes at the ends of the intervals. Can generate fairly fast C code, or can be used directly in Python.'}, {'comments': [], 'desc': u"This recipe shows you how you might generate SQL code to insert the key-value pairs in a dictionary. The parameter table corresponds to an existing SQL table and dictionary keys correspond to the table's SQL column names. The SQL generated can then be inserted into a database (in this case MySQL) in the manner shown in exampleOfUse()."}, {'comments': [{'comment': u'sre docs suck, thanks for this one :)', 'title': u'nice!'}], 'desc': u"My company wrote an application server that works as a long running service. We were confronted with a memory usage that we couldn't explain until we found out, that the re module is caching a lot of data in the background."}, {'comments': [{'comment': u"You might wish to mention somewhere that you didn't write that snippet yourself (it's copied from Python's test suite; see e.g.\nhttp://mail.python.org/pipermail/python-dev/2003-April/035075.html )\n<br><br>\nCheers /F (the original author)", 'title': u'Footnote'}, {'comment': u'Of course you\'re right. I will add the notice. Whith this recipe I just wanted to give a hint to this hidden functionality in "re". ', 'title': u'Copied from testsuite'}, {'comment': u'yet another example why python docs suck. espeically the sre module. ;(', 'title': u'thank both guys (one for writing) other for posting here'}, {'comment': u"Thanks!\nQuite a few times I'd need a parser like that and was surprised I couldn't find one in Python.\n\nNow we just need a special parser for each type (so we won't have to filter from a list), and have it in a standard Python library.", 'title': u'Very useful'}, {'comment': u'Using the sre scanner looks interesting, though I have the feeling that for real parsing activities, using a parser like DParser, Spark, SimpleParse, etc., would probably get one farther.', 'title': u' '}], 'desc': u'The developers of Python hide a very nice function in the re module for scanning text. The example is taken from the Python testsuite: http://mail.python.org/pipermail/python-dev/2003-April/035075.html'}, {'comments': [{'comment': u'On Python 2.4.1, the code should be modified a little:\n-- Add "weakref" to the exclude list, such as:\n<pre>\nimport gc\nimport inspect\n\nexclude = [\n "function",\n "type",\n "list",\n "dict",\n "tuple",\n "wrapper_descriptor",\n "module",\n "method_descriptor",\n "member_descriptor",\n "instancemethod",\n "builtin_function_or_method",\n "frame",\n "classmethod",\n "classmethod_descriptor",\n "_Environ",\n "MemoryError",\n "_Printer",\n "_Helper",\n "getset_descriptor",\n "weakref", "property", "cell", "staticmethod"\n ]\n\ndef dumpObjects():\n gc.collect()\n oo = gc.get_objects()\n for o in oo:\n if getattr(o, "__class__", None):\n name = o.__class__.__name__\n #print (name)\n if name not in exclude:\n filename = inspect.getabsfile(o.__class__)\n print "Object :", `o`, "..."\n print "Class :", name, "..."\n print "defined:", filename, "\\n"\n\nif __name__=="__main__":\n\n class TestClass:\n pass\n\n testObject1 = TestClass()\n testObject2 = TestClass()\n\n from wx import Colour\n color = Colour()\n\n dumpObjects()\n</pre>', 'title': u'Test on Python 2.4.1'}, {'comment': u"And the result:\n<pre>\nObject : <__main__.TestClass instance at 0x00954D00> ...\nClass : TestClass ...\ndefined: c:\\temp\\py\\test.py\n\nObject : <__main__.TestClass instance at 0x00954D28> ...\nClass : TestClass ...\ndefined: c:\\temp\\py\\test.py\n\nObject : <class 'string.Template'> ...\nClass : _TemplateMetaclass ...\ndefined: d:\\bin\\python\\lib\\string.py\n\nObject : wx.Point(-1, -1) ...\nClass : Point ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_core.py\n\nObject : wx.Size(-1, -1) ...\nClass : Size ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_core.py\n\nObject : wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.) ...\nClass : _wxPyUnbornObject ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_core.py\n\n...\n\nObject : <wx._core.__DocFilter instance at 0x00957E90> ...\nClass : __DocFilter ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_core.py\n\nObject : wx.Colour(0, 0, 0) ...\nClass : Colour ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_gdi.py\n\nObject : <wx._core.PyEventBinder object at 0x016CEED0> ...\nClass : PyEventBinder ...\ndefined: d:\\bin\\python\\lib\\site-packages\\wx-2.6-msw-unicode\\wx\\_core.py\n\n...\n</pre>", 'title': u' '}], 'desc': u'Since Python 2.2 there is a handy function in the Garbage Collection Module called get_objects(). It gives back a list of all objects that are under control of the Garbeage Collector. This way you can extract informations of your application in runtime. '}, {'comments': [], 'desc': u'If you are debugging a program you may want to know if some special objects exist and where they came from. '}, {'comments': [], 'desc': u'Sometimes you like to have a very global namespace where to put e.g. configuration data. This data should be accessible form all modules you use. SuperGlobal solves this need.'}, {'comments': [{'comment': u'Nice and simple example!', 'title': u'Nice'}], 'desc': u'Distribute already (or newly) implemented Python objects, allowing them to be remotely accessed without much hussle'}, {'comments': [], 'desc': u'How to transfer large files with Twisted Perspective Broker using twisted.spread.util.Pager and friends. Code copied and pasted from here:\nhttp://twistedmatrix.com/pipermail/twisted-python/2003-May/004019.html\n\nJust wanted to make it easier to find. Originally by: Glyph Lefkowitz'}, {'comments': [], 'desc': u'This recipe is the Python implementation of the SystemParametersInfoA() invocation required to retrieve the area that application windows can inhabit. On multi-monitor setups, the windows code returns the area on the primary monitor only. This recipe is the cleaned up version of this email post http://mail.python.org/pipermail/python-list/2003-May/162433.html .'}, {'comments': [{'comment': u"My dual monitor setup includes a primary monitor to the right of the secondary. This causes negative numbers for RECT.top and/or RECT.left, which the functions above casted as c_ulong. Using c_long's corrects this glitch.\n\n<pre>\nclass RECT(ctypes.Structure):\n _fields_ = [\n ('left', ctypes.c_long),\n ('top', ctypes.c_long),\n ('right', ctypes.c_long),\n ('bottom', ctypes.c_long)\n ]\n</pre>", 'title': u'Negative RECT values'}], 'desc': u'This recipe gets the sizes of all the monitors on a multi-monitor Windows PC. It gets both the actual resolution and the usable ("work") resolutions. The usable resolution excludes the taskbar and docked applications.'}, {'comments': [], 'desc': u'A methode to traverse a tree (or the rest of a tree starting from a node with unkown position) depth-first without recursion and without mandatorily keeping track of the position of the current node; requires each node to have reference acess to its parent, first child and next sibling, therefore especially suitable for DOM trees.'}, {'comments': [], 'desc': u"This recipe creates a class to allow access to variables stored in pkg-config files ( or '.pc' files ). This is usefull in conjunction with distutils to get correct information for compiling external C/C++ modules. Variable substitution is performed with string.Template. "}, {'comments': [], 'desc': u'This recipe implements a base class, which allows derived classes to track instances in self.__instances__. It uses a WeakValueDictionary to store instance references.'}, {'comments': [{'comment': u'I wrote a fully functional example, yours does not even run :(\n\nclass Ini(object):\n def __init__(self):\n self.ini = []\n \n def add_section(self, section):\n self.ini.append("[%s]" % section)\n \n def add_key(self, key, value):\n self.ini.append("%s=%s" % (key, value))\n \n def add_comment(self, comment):\n self.ini.append(";%s" % comment)\n \n def add_verb(self, verb):\n self.ini.append(verb)\n\n def show(self):\n return "\\n".join(self.ini)\n \nif __name__ == "__main__":\n from ConfigParser import ConfigParser\n from StringIO import StringIO\n\n w = Ini()\n w.add_comment("Hi Everybody")\n w.add_section("Adv Config Options")\n w.add_key("Number of rows", 25)\n print w.show()\n\n fd = StringIO(w.show())\n parser = ConfigParser()\n parser.readfp(fd)\n\n print\n print parser.sections(), parser.options(parser.sections()[0])\n\n\nrhymes@voodoo:~/downloads $ python iniforger.py\n;Hi Everybody\n[Adv Config Options]\nNumber of rows=25\n\n[\'Adv Config Options\'] [\'number of rows\']', 'title': u'Better and fully functional example'}, {'comment': u'Ehm I forgot pre tags.\n\n<pre>\nclass Ini(object):\n def __init__(self):\n self.ini = []\n \n def add_section(self, section):\n self.ini.append("[%s]" % section)\n \n def add_key(self, key, value):\n self.ini.append("%s=%s" % (key, value))\n \n def add_comment(self, comment):\n self.ini.append(";%s" % comment)\n \n def add_verb(self, verb):\n self.ini.append(verb)\n\n def show(self):\n return "\\n".join(self.ini)\n \nif __name__ == "__main__":\n from ConfigParser import ConfigParser\n from StringIO import StringIO\n\n w = Ini()\n w.add_comment("Hi Everybody")\n w.add_section("Adv Config Options")\n w.add_key("Number of rows", 25)\n print w.show()\n\n fd = StringIO(w.show())\n parser = ConfigParser()\n parser.readfp(fd)\n\n print\n print parser.sections(), parser.options(parser.sections()[0])\n\n \nrhymes@voodoo:~/downloads $ python -tt iniforger.py\n;Hi Everybody\n[Adv Config Options]\nNumber of rows=25\n\n[\'Adv Config Options\'] [\'number of rows\']\n</pre>', 'title': u'Better and fully functional example'}], 'desc': u'This class contains serval methods to create an INI file.'}, {'comments': [{'comment': u'Um... <pre>rm -rf path</pre>', 'title': u' '}, {'comment': u'Most of the code that I write is for Windows. :)', 'title': u'Windows'}], 'desc': u"This program is used to cleanup any folder that you specify but is used here primarily to cleanup a profile in Windows. The purpose of this program to to clean out a profile that may be located in a lab setting (such as at a university). The primary reason that this program was written was that it is impossible to log off of a computer if one's profile is too large."}, {'comments': [{'comment': u"<pre>\nimport os, sys\n\ndef main():\n try:\n engine(file(' '.join(sys.argv[1:]), 'rb', 0).read())\n except:\n print os.path.basename(sys.argv[0]), ''\n\ndef engine(string):\n if len(string) > 0:\n parts = divide(string, 16)\n rule = can_print()\n for index in range(len(parts)):\n print ' | '.join([hex(index)[2:].upper().zfill(8)[-8:] + '0', \\\n pad_right(convert_hex(parts[index]), 47), \\\n convert_print(parts[index], rule)])\n\ndef divide(string, length):\n return [string[index*length:index*length+length] \\\n for index in range(len(string[:-1]) / length + 1)]\n\ndef pad_right(string, length, padding=' '):\n return string + padding[0] * (length - len(string))\n\ndef convert_hex(string):\n return ' '.join([hex(ord(character))[2:].upper().zfill(2) \\\n for character in string])\n\ndef convert_print(string, rule):\n return ''.join([character in rule and character \\\n or '.' for character in string])\n\ndef can_print():\n return ''.join([chr(byte) for byte in range(256) \\\n if len(repr(chr(byte))) == 3 or byte == ord('\\\\')])\n \nif __name__ == '__main__':\n main()\n</pre>", 'title': u'Second Version'}, {'comment': u"<pre>print ' | '.join([hex(index)[2:].upper().zfill(7)[-7:] + '0', \\</pre>", 'title': u'Correction'}], 'desc': u'This program will dump a file to the screen "classic" style.'}, {'comments': [], 'desc': u'This program is slightly simpler that the first version.'}, {'comments': [{'comment': u'In function ModifiedMixin.__init() the self.bind_all(...) should be changed to self.bind(...). This becomes obvious when you have two or more Tkinter.Text widgets and this "mixin" only works for the last one created.', 'title': u'bind() not bind_all()'}], 'desc': u'A Tkinter.Text can notice when its contents are changed. This recipe shows how to make use of the virtual event this generates to call your own callback.'}, {'comments': [], 'desc': u'This is modified version of War Game (Version 3) and includes updated classes.'}, {'comments': [], 'desc': u'An extremely simple example of using httplib to write a file to a WebDAV server. This version does not use any authentication mechanism.'}, {'comments': [{'comment': u'Interesting looking recipe. Could you escape the html in your template example so that it shows up?', 'title': u'Code for the template'}, {'comment': u'Sorry about that. Here it is.\n\n<br><br>\n<html><br>\n  <head><br>\n    <title>###title</title><br>\n  </head><br>\n  <body><br>\n    These are my posts:<br>\n    <?for post in posts?><br>\n      Post title: ###post.title<br/><br>\n      Post content:<br/><br>\n      ###post.content<br>\n    <?end?><br>\n<br>\n    <?if post.has_timestamp ?><br>\n      Creation data: ###post.timestamp<br>\n    <?end?><br>\n  </body><br>\n</html><br>\n<br>', 'title': u'Escape'}], 'desc': u'Trivia is simple but powerful Python Template. It was designed for making nice and easy HTML templates.'}, {'comments': [], 'desc': u'The ResettableTimer class is a timer whose counting loop can be reset arbitrarily. Its duration is configurable. Commands can be specified for both expiration and update. Its update resolution can also be specified. Resettable timer keeps counting until the "run" method is explicitly killed with the "kill" method.'}, {'comments': [], 'desc': u"Synchronization has got to be one of the most popular uses for decorators, but there's no recipe here. So, this is a simple synchronization decorator."}, {'comments': [], 'desc': u'This shared lock implementation supports timeouts so that an attempt to acquire a lock occasionally times out. It also preserves FIFO ordering for threads waiting for exclusive lock and has other valuable features.'}, {'comments': [{'comment': u'check out http://monkey.org/~dugsong/dpkt/ for another implementation of the same idea, using a simple metaclass in dpkt.py.', 'title': u'dpkt metaclass'}, {'comment': u'After creating a ConcreteRecord this class can be used to attach boolean flag names to a byte.\n\n<pre>\nclass ByteFlags:\n \n def __init__(self, flags, data=None):\n self._flags = []\n bit = 1\n for f in flags:\n self._flags += [(f, bit)]\n bit = bit * 2\n if data == None: return\n for f in self._flags:\n name,bit = f\n val = bool(data & bit)\n self.__dict__[name] = val\n \n def __int__(self):\n val = 0\n for f in self._flags:\n name,bit = f\n if self.__dict__.get(name):\n val |= bit\n return val\n \n def __str__(self):\n return pack("B",self.__int__())\n\n#### EXAMPLE ####\n\nmyrf = RecordFactory("""\n B.flags\n 4B.ip\n >H.port\n >I.session_id\n""")\n\nr = myrf.build("\\x0f" + "\\x00\\x01\\x02\\x03" + "\\x00\\x04" + "\\xFE\\xDC\\xBA\\x98")\n\nr.flags= ByteFlags([\'bit0\',\'bit1\',\'bit2\',\'bit3\',\'bit4\',\'bit5\',\'bit6\',\'bit7\'], r.flags)\nr.flags.bit2=False\nstr(r.flags)\nstr(r)\n</pre>', 'title': u'Using a byte as flags'}], 'desc': u"Python's struct library is too low-level for direct usage. This recipe (only 40 lines) shows how it can be turned into more developer-friendly tool."}, {'comments': [], 'desc': u"Many Python programmers have trouble wrapping their mind around decorators that accept arguments. Here's a one-line decorator designed just for making decorators that accept arguments."}, {'comments': [{'comment': u"What's wrong with:\n\n<pre>\nd = {}\nfor x in iterable:\n d[x] = d.get(x, 0) + 1\nreturn d # or d.items() if you're desperately after a list of tuples\n</pre>", 'title': u'Erm... A dict?'}, {'comment': u'but this one is quite faster with very long strings.', 'title': u'Nothing is wrong with using a dict,'}, {'comment': u'<pre>import itertools\nimport random\n\ndef countElems(s):\n return [(i[0], len(tuple(i[1]))) for i in itertools.groupby(sorted(s))]\n\na = [random.randint(1, 100) for i in range(1000)]\n\nfor i, j in countElems(a):\n print i, j</pre>', 'title': u'itertools.groupby (Python 2.4+)'}], 'desc': u'Please refer to recipe 277600.'}, {'comments': [], 'desc': u"An enhanced version of yaptu, with the following changes\n- separated parsing from execution\n- added caching of parsed templates\n- added some error reporting\n- added a choice of template syntaxes\n- added comment syntax\n- added Cheetah-style variable substitution with optional caching of the equivalent Python expression\n- limited flow control to 'for' and 'if'\nReasonably small, no external dependencies, pretty fast."}, {'comments': [{'comment': u"<pre>\nimport TaskQueue\nimport Queue\nimport random, time, sys, threading, posixpath, traceback, os\nimport socket; socket.setdefaulttimeout(30)\nimport ftplib\nfrom pprint import pprint\n\nDEFMAXSIZE = 40*1024*1024\nDEFBLOCKSIZE = 64*1024\nDEFMERGESIZE = 16*1024\n\ndef get_error_traceback():\n errtype, errinst, tb = sys.exc_info()\n try:\n error = ''.join(traceback.format_exception_only(errtype, errinst))\n trace = ''.join(traceback.format_exception(errtype, errinst, tb))\n return error, trace\n finally: del tb\n\ndef calccount(totalsize, maxsize=DEFMAXSIZE):\n q, r = divmod(totalsize, maxsize)\n count = q+bool(r)\n return count\n\ndef calcsizes(totalsize, count):\n q, r = divmod(totalsize, count)\n sizes = [q]*count\n sizes[0] += r\n return sizes\n\ndef calcoffsets(sizes):\n offsets = []\n pos = 0\n for s in sizes:\n offsets.append(pos)\n pos += s\n\n return offsets\n\ndef _test1():\n totalsize = 364388352\n maxsize = DEFMAXSIZE\n count = calccount(totalsize, maxsize)\n assert (1.0*totalsize/count)<pre>\nimport TaskQueue\nimport Queue\nimport random, time, sys, threading, posixpath, traceback, os\nimport socket; socket.setdefaulttimeout(30)\nimport ftplib\nfrom pprint import pprint\n\nDEFMAXSIZE = 40*1024*1024\nDEFBLOCKSIZE = 64*1024\nDEFMERGESIZE = 16*1024\n\ndef get_error_traceback():\n errtype, errinst, tb = sys.exc_info()\n try:\n error = ''.join(traceback.format_exception_only(errtype, errinst))\n trace = ''.join(traceback.format_exception(errtype, errinst, tb))\n return error, trace\n finally: del tb\n\ndef calccount(totalsize, maxsize=DEFMAXSIZE):\n q, r = divmod(totalsize, maxsize)\n count = q+bool(r)\n return count\n\ndef calcsizes(totalsize, count):\n q, r = divmod(totalsize, count)\n sizes = [q]*count\n sizes[0] += r\n return sizes\n\ndef calcoffsets(sizes):\n offsets = []\n pos = 0\n for s in sizes:\n offsets.append(pos)\n pos += s\n\n return offsets\n\ndef _test1():\n totalsize = 364388352\n maxsize = DEFMAXSIZE\n count = calccount(totalsize, maxsize)\n assert (1.0*totalsize/count)</pre></pre>", 'title': u'used TaskQueue'}], 'desc': u'Updated to use TaskQueue from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475160'}, {'comments': [], 'desc': u'This is a rewrite of <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252508">Doug Tolton\'s</a> extract algorithm. It\'s portable and small, ideal for paste-and-use. NB: directory structure creation is slightly pendantic to ensure creation of implicit directories annotated by certain trixter zipfiles. cStringIO guards against errors writing large files over 128MB in size.'}, {'comments': [], 'desc': u'Linked dictionaries are dictionaries that can refer to other dictionaries (its bases), similar to class hierarchies, but built at runtime. A linked dictionary shows all the key/value pairs that are defined locally (in the very instance) and globally (in other linked bases). '}, {'comments': [], 'desc': u'Injecting _() in the __builtin__ module in order to inject global functions _() and N_() is common in applications which need i18n. This is a variation on the theme that does this in a multi-threaded environment, using threading.local from Python-2.4.'}, {'comments': [], 'desc': u"Parses the output of MS Access's documenter report and generates sql create table statements for the tables in the report. To use - run the documenter and save its output in a text file named documenter.txt. Then run this program. Output goes to documenter2.txt."}, {'comments': [], 'desc': u"Group a list of items according to the starting character(s) of items.\nThis is based on Raymond Hettinger's groupby class: \nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259173"}, {'comments': [{'comment': u"That's a good try at what would be very useful functionality. <br>Unfortunately, I don't think the numbers for CPU usage will be correct. If I read the code correctly, what you are recording is the amount of CPU used by the *process* while a function was being run in a *thread*. That CPU usage figure will include any CPU time used by other threads that received some CPU resource during the (real) time in which the function was running.\n<br><br>I'm not aware of any system call that would give CPU usage for a thread. The only way I can think of doing this accurately is somehow to catch context switches and record CPU usage against thread at that point. Again, I don't know how to do this (I'm sure it would have to be at the C level rather than in Python).\n<br>:-(", 'title': u'Double accounting?'}], 'desc': u'This recipe shows how to profile threads in Python by using custom profiler function.'}, {'comments': [], 'desc': u'While there are many alternate implementations of the Singleton pattern available, I decided to offer my own anyway.'}, {'comments': [], 'desc': u"This useless hack allows normal functions to be attached to a 'ThunkSpace' which causes the function to be lazily evaluated when the thunk is referenced. It is just a experiment using closures and descriptors to try and change python function call syntax."}, {'comments': [{'comment': u"This style of cooperative threading can be very useful. There is one small issue with the exception handling.<br><br> \nIf the user's code which is run by the line:\n<br><br>\ntasks[0].generator.next()\n<br><br>\nraises IndexError, the Exception will silently pass. ", 'title': u'Exception Handling'}, {'comment': u'Explicit testing "len(tasks) == 0" is about 15% slower (for tasks that yield often), but the idea of silent exception is also bad. The solution:\n<pre>\nexcept IndexError:\n if len(tasks) > 0: raise\n</pre>\nThanks for advice :-)\n', 'title': u'Exception Handling'}, {'comment': u'Or you can be a little more careful to put only what might raise an exception into the try/except block::\n\n<pre>\ntry:\n task = tasks[0]\nexcept IndexError:\n continue\ntry:\n task.generator.next()\nexcept StopIteration:\n del tasks[0]\nelse:\n tasks.rotate(-1)\n</pre>', 'title': u' '}, {'comment': u'<pre>Similar approach has been written about in \n\nCharming Python: Implementing "weightless threads" with Python generators\nDavid Mertz\nhttp://www-128.ibm.com/developerworks/linux/library/l-pythrd.html\n\nOne limitation is the yield must be called in main(). If main() calls\nanother method you cannot execute in that method or it will be \ntreated as generator.</pre>', 'title': u'See Charming Python series in IBM developer works'}, {'comment': u"Thanks for the link, it's a nice article.\n\nAbout yield in main():\nI have come up with the recipe how to yield from generator used in another generator. It should make generator based kernels even more powerfull. Please see recipe 466299 for details.\n\n<pre>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/466299\n</pre>", 'title': u' '}], 'desc': u"Cooperative multitasking offers an alternative to using threads. It can be harder to use in some cases (blocking IO) but in other it can be much easier (sharing data between tasks). This recipe shows how to use generators to achieve simple, cooperative multitasking, that allows thousends of 'simultaneously' running tasks."}, {'comments': [], 'desc': u"SAX is commonly used on large XML files because they don't fit nicely into core memory necessary for the friendlier DOM API.\n\nWhen dealing with -really- large XML files, multiple passes over the file becomes costly.\n\nThe SAX handler in this recipe allows you to handle an XML file multiple ways in a single pass by dispatching to the handlers you supply."}, {'comments': [{'comment': u"What do you gain by this? The list() call loads everything into memory, so pretending like it's still an iterator but calling iter() seems misleading to me....", 'title': u' '}, {'comment': u"I agree that there is no implementation benefit to the iter() call, but it conforms to the interface where iterator modifiers are expected.\n<br><br>\nThe scheme involved has a 'source' iterator, and chains together several iterator-modifying functions to receive a final iterator. A configuration controls which modifying functions are used at run-time.\n<br><br>\nI know this implementation is a problem. I'd love to hear suggestions for a better one...", 'title': u'Fitting in an existing iterator-centric scheme'}, {'comment': u"Well, this isn't as random as random.shuffle -- items near the beginning of the original iterable will likely be near the beginning of the resulting iterable -- but at least it maintains the memory behavior of iterators.\n\n<pre>\ndef irandomize(iterable):\n iterable = iter(iterable)\n items = []\n try:\n while True:\n for i in xrange(random.randint(1, 10)):\n items.append(iterable.next())\n random.shuffle(items)\n for i in xrange(random.randint(1, 10)):\n if items:\n yield items.pop()\n else:\n break\n except StopIteration:\n random.shuffle(items)\n for item in items:\n yield item\n raise StopIteration\n</pre>\n\nIn worst-case behavior, it could load all items from the iterable into memory at once, but on the average I believe it should only be storing about 10 at a time.", 'title': u'more iterator-like implementation'}, {'comment': u'If you want to guarantee that memory limits are never exceeded, you will have to specify an upper bound somewhere.\n<br>\nI think the best way to tackle this is to provide a buffer-length argument to irandomize():\n<pre>\ndef irandomize(..., bufsize=1000):\n</pre>\netc. Once the buffer is full, you choose a random element, replace it with the next element from the iterator, and yield the chosen element. "Shuffle" is never needed.', 'title': u'Length of unknown iterator has no upper bound.'}], 'desc': u'Extremely simple/straightforward implementation.\n\nPosted mainly to receive comments on alternative implementations.'}, {'comments': [{'comment': u'Added the guess_primary_number() function that uses a fixed priority.\nAdded example data for unit testing.', 'title': u'slight revision'}, {'comment': u'Just found out gmail.com started exporting utf-16 encoded contacts.\nHad to feed utf-8 encoded strings instead of unicode to csv.reader to make it happy.', 'title': u'support utf-16 encoded gmail.csv'}, {'comment': u' ', 'title': u'ignore empty input lines'}], 'desc': u'This script uses the csv module to convert gmail.com contacts data to the "raw" gnokii phonbook format,\nwhich is another CSV variant, while preserving cell/home/work/fax numbers, street address, URL and notes data entries.\n\ngnokii (www.gnokii.org) is an open source program for communicating with mobile phones \nthat runs under Windows and Linux/Unix.\nNote that gmail.com supports exporting contacts in both Outlook and Gmail CSV formats. \nThis script needs the Gmail format. \n\nRun this script with a command like:\ncat gmail.csv | gmail-csv-to-gnokii | gnokii --writephonebook --overwrite'}, {'comments': [{'comment': u'While pondering over the code now that I posted it, I guess that it\'s a somewhat strange design decision to store containership in a tuple. It\'s much better to use a dictionary for that, and the following adapted _iterranges() does exactly this:\n\n<pre>\n def _iterranges(self,r1,r2,minval=_MININF,maxval=_MAXINF):\n curval = minval\n curstates = {"r1":False,"r2":False}\n imax, jmax = 2*len(r1), 2*len(r2)\n i, j = 0, 0\n while i < imax or j < jmax:\n if i < imax and ( ( j < jmax and\n r1[i>>1][i&1] < r2[j>>1][j&1] ) or\n j == jmax ):\n cur_r1 = r1[i>>1][i&1]\n if curval < cur_r1:\n if cur_r1 > maxval:\n break\n yield curstates, (curval,cur_r1)\n curval = cur_r1\n curstates["r1"] = not (i&1)\n i += 1\n else:\n cur_r2 = r2[j>>1][j&1]\n if curval < cur_r2:\n if cur_r2 > maxval:\n break\n yield curstates, (curval,cur_r2)\n curval = cur_r2\n curstates["r2"] = not (j&1)\n j += 1\n if curval < maxval:\n yield curstates, (curval,maxval)\n</pre>\n\nWhen you adapt _iterranges with that code, you\'ll need to adapt the function definitions too:\n\n<pre>\n __and__ = _make_function("__and__","set",\n "Intersection of two sets as a new set.",\n lambda s: s["r1"] and s["r2"])\n __rand__ = _make_function("__rand__","set",\n "Intersection of two sets as a new set.",\n lambda s: s["r1"] and s["r2"])\n __contains__ = _make_function("__contains__","bool",\n "Returns true if self is superset of other.",\n lambda s: s["r1"] or not s["r2"])\n __or__ = _make_function("__or__","set",\n "Union of two sets as a new set.",\n lambda s: s["r1"] or s["r2"])\n __ror__ = _make_function("__ror__","set",\n "Union of two sets as a new set.",\n lambda s: s["r1"] or s["r2"])\n __sub__ = _make_function("__sub__","set",\n "Difference of two sets as a new set.",\n lambda s: s["r1"] and not s["r2"])\n __rsub__ = _make_function("__rsub__","set",\n "Difference of two sets as a new set.",\n lambda s: s["r2"] and not s["r1"])\n __xor__ = _make_function("__xor__","set",\n "Symmetric difference of two sets as a new set.",\n lambda s: s["r1"] ^ s["r2"])\n __rxor__ = _make_function("__rxor__","set",\n "Symmetric difference of two sets as a new set.",\n lambda s: s["r1"] ^ s["r2"])\n difference = _make_function("difference","set",\n "Difference of two sets as a new set.",\n lambda s: s["r1"] and not s["r2"])\n intersection = _make_function("intersection","set",\n "Intersection of two sets as a new set.",\n lambda s: s["r1"] and s["r2"])\n issubset = _make_function("issubset","bool",\n "Returns true if self is subset of other.",\n lambda s: s["r2"] or not s["r1"])\n issuperset = _make_function("issuperset","bool",\n "Returns true if self is superset of other.",\n lambda s: s["r1"] or not s["r2"])\n symmetric_difference = _make_function("symmetric_difference","set",\n "Symmetric differe', 'title': u'Slight changes to the algorithm to make it slightly easier to read...'}, {'comment': u"and which I have now implemented in the recipe itself. I didn't know you could edit recipe's here. ;-)", 'title': u'...'}], 'desc': u"While programming an IPv4-Range class I stumbled upon the need for an efficient integer set type, which doesn't store individual items like the builtin set type does, but which only stores longs and ints, and does this in a run length encoded way to save space.\n\nThe following class implements such a beast as an immutable type, amongst support for minus and plus infinity to allow you to create infinitely sized sets. The set supports almost all operations that the builtin set type supports (which means excluding rich comparisons __gt__, __ge__, etc., for which I could find no meaningful interpretation).\n\nThe recipe is somewhat longish, but I couldn't think of some more elegant way to express most operations than by using predicate logic together with a set iterator, which keeps runtime for all set operations in O(n), except normalization, which is O(n*logn) because of the sort() operation on the list of ranges. Normalization is only done once on construction of the set; when a set is combined by some operation with another set, the output is automatically normalized.\n\nThe _Infinity private type is required to facilitate comparisons. _Infinity(True) will be smaller than any number and equal to itself, _Infinity(False) bigger than any number and equal to itself. This makes sorting easier."}, {'comments': [{'comment': u"Sorry, didn't mention this in the original: the idea for this code began in a discussion on comp.python.devel, and in particular ideas from Martin v. L\xf6wis and James Y Knight.", 'title': u'Credits that belong above'}, {'comment': u"While embedding the 'or' in the except clause header is cute, its also a little subtle and obscure, and causes the check to be executed every time the test is run, rather than when the test is defined.<br>\n<br>\nThis can be fixed with a straightforward test in the decorator function (outside the nested helper):<pre>\n if not exceptions:\n exceptions = unittest.TestCase.failureException\n</pre>", 'title': u'Check for exception arguments at test definition time not run time'}, {'comment': u'I like the concept, thanks!', 'title': u'Cool!'}], 'desc': u'broken_test_XXX(reason) is a decorator for "inverting" the sense of the following unit test. Such tests will succeed where they would have failed (or failed because of a raised exception), and fail if the decorated test succeeds.'}, {'comments': [], 'desc': u"You have some string input with some specical characters escaped using syntax rules resemble Python's. For example the 2 characters '\\n' stands for the control character LF. You need to decode these control characters efficiently. Use Python's builtin codecs to decode them efficiently."}, {'comments': [], 'desc': u'Building on another recipe of mine (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/466286) this is a set type for storing IPv4 address(-ranges) efficiently. It parses several different formats for specifying IPv4 address ranges described in the docstrings, and allows you to output the contained addresses as ip/mask or ip-ip pairs, and also allows you to iterate over all ip addresses.'}, {'comments': [{'comment': u"This code shows more clearly what the continuator is doing:\n<pre>\nclass continuator:\n def __init__(self, gen):\n self.stack = [iter(gen)]\n def __iter__(self):\n\twhile self.stack:\n\t gen = self.stack.pop()\n\t for ret_val in gen:\n\t\tif hasattr(ret_val, 'gi_frame'):\n\t\t self.stack.extend([gen, iter(ret_val)])\n\t\telse:\n\t\t yield ret_val\n</pre>", 'title': u'Simplifying continuator code'}, {'comment': u'Using a class seems overkill for this and gi_frame is most likely an implementation detail of generators. Also, why not make use of the wonderful itertools package:\n\n<pre>\nfrom itertools import chain\nfrom types import GeneratorType\n\ndef continuator(gen):\n while True:\n i = gen.next()\n if isinstance(i, GeneratorType):\n gen = chain(i, gen)\n else:\n yield i\n</pre>', 'title': u'Simpler still'}], 'desc': u'Yielding from generator used inside another generator.'}, {'comments': [{'comment': u'You can do x.sort(key=None), so you don\'t have to test for "key is not None". Testing "if len(current_chunk)>0" is a long way of saying "if current_chunk". And the variable "position" in merge doesn\'t seem necessary -- the stability of the first .sort() should be sufficient.\n<br><br>\nIt would be interesting to benchmark this against GNU sort, which I hear is really good at sorting large files. Obviously GNU sort will win, but by how much? Well, I can figure that out for myself I suppose; with a file with a million random lines:\n\n<pre>\n$ time sort test_big.txt > tmp.txt\nreal 0m4.017s\nuser 0m2.584s\nsys 0m0.396s\n\n$ time python large_sort.py test_big.txt tmp.txt\nreal 0m8.436s\nuser 0m7.454s\nsys 0m0.322s\n</pre>\n\nThree times slower than GNU sort... which is actually a lot better than I expected. ', 'title': u'tweaks and times'}, {'comment': u"Yeah, and how much did Python's startup time contribute to the difference?", 'title': u' '}, {'comment': u"I've modified the recipe according to your remarks. You're right, adding a position field to the merged tuples is unneeded since the iterators used by the merging function are returning items in a stable way. The index field is needed, though, otherwise for equal key values we would risk that the iterators be used in a different order than the original one.<br>\n<br>\nI've tested this script against GNU sort (textutils) 2.1 running under Win32, and it was quite competitive, only two to three times slower.<br>\n<br>\nThe point is that you get much more flexibility in the way you can define keys ; I wouldn't know how to easily have a two-part key with different semantics (lexicographic and numeric) using GNU sort. The key definition in the command line is only a start, you can define much more complicated keys.", 'title': u'Thanks for the tips'}, {'comment': u'A very useful recipe! But there is one \'gotcha\' in v1.4. If the input file does not end with a newline, then the output file will combine the last input line with the next line in the sort sequence. This is because file.writelines() does not add line separators.\n<br><br>\nIn my case, I am working with text files that end with \'\\x1a\' instead of a newline. GNU sort will put the \'\\x1a\' character on it\'s own line at the very beginning of the file, but the python version combines the first and second lines. I hacked in a workaround by checking for end-of-file using input_file.tell(), but it added 20% to the processing time :(<br> I figure there must be a more elegant solution.\n<br><br>\nAnother problem I encountered is that chunk files are not cleaned up if the chunk creation process is interrupted. This could happen when:<br><br>\n - the \'key\' function throws an exception<br>\n - KeyboardInterrupt (the user cancels the program; I do this all the time)<br>\n - MemoryError (buffer_size is too large)<br>\n - IOError (the disk is full)<br>\n<br>\nI timed the (modified) function against our previous implementation, which uses os.system():\n\n<pre>\n $ timeit.py -s \'import batchsort\' \\\n \'batchsort.batch_sort("test.TXT", "sorted.txt", lambda line: (line[210:223]))\'\n 10 loops, best of 3: 2.74e+05 usec per loop\n \n $ timeit.py -s \'import os\' \\\n \'os.system("sort -k 1.210,1.223 test.TXT > sorted2.txt")\'\n 10 loops, best of 3: 3.95e+05 usec per loop\n</pre>\n\nNot bad, 30% faster on an athlon 800Mhz running Python 2.3, against a 2Mb file with 2200 rows. The difference is probably from the overhead of starting and monitoring the external process. Could someone verify this?\n<br><br>\nI would consider replacements for existing os.system() calls to be a more common case than command-line usage, but the time advantage may disappear since you will probably be calling \'sort\' once on a large file, not 10 times on some small files.\n<br><br>\nOne advantage this recipe has over GNU sort is that it is predictable. On Linux Fedora Core 3 GNU sort does some funny and annoying things because of the default locale settings. I prefer to use predictable pure python rather than checking and setting environment variables in sort\'s calling shell.', 'title': u'gotchas, cleanup, and common usage'}], 'desc': u'This recipe can be used to sort big files (much bigger than the available RAM) according to a key. The sort is guaranteed to be stable on Python 2.3.'}, {'comments': [{'comment': u"Do you think that you could make a second version of this code that does not require Qt? It's somewhat difficult to get Qt for Widnows, and I am sure that your program is nice ...", 'title': u'Qt'}, {'comment': u"Here's a slightly shorter version that supports passing arbitrary positional arguments to the callback.\n\n<pre>\nfrom qt import QEvent, QObject, qApp\nfrom thread import get_ident\n\nclass CallbackEventHandler(QObject):\n\n MAIN_THREAD_ID = 0\n\n def __init__(self):\n QObject.__init__(self)\n self.installEventFilter(self)\n\n def eventFilter(self, obj, event):\n # FIXME: This is a workaround for an unexplained bug\n # The events were getting posted through postEVentWithCallback()\n # But the event() method wasn't getting called. But the eventFilter()\n # method is getting called. \n if event.type() == QEvent.User:\n callback = event.__dict__.get('callback')\n if callback:\n self._doEvent(event)\n return False\n return QObject.eventFilter(self, obj, event)\n\n def _doEvent(self, event):\n callback = event.__dict__.get('callback')\n args = event.__dict__.get('args')\n if callback is not None and args is not None:\n callback(*args)\n\n def event(self, event):\n if event.type() == QEvent.User:\n self._doEvent(event)\n return True\n return QObject.event(self, event)\n\n def postEventWithCallback(self, callback, *args):\n if get_ident() == CallbackEventHandler.MAIN_THREAD_ID:\n # if we're in main thread, just fire off callback\n callback(*args)\n else:\n # send callback to main thread \n event = QEvent(QEvent.User)\n event.callback = callback\n event.args = args\n qApp.postEvent(self, event)\n\n</pre>", 'title': u'Updated version'}, {'comment': u'Sorry about that...posted to the wrong thread (too many tabs in Firefox :). This was meant to go on this thread: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/415311', 'title': u'Oops...'}], 'desc': u'Starting with the recipe "Network Ping Pong using Twisted Prespective Broker" (181905), this recipe integrates Qt using the threadedselectreactor. An alternative to qtreactor, this recipe allows dispatching messages over the perspective broker while running the Qt event loop. It basically shows how to use reactor.interleave(aFunction) within the context of Qt.'}, {'comments': [], 'desc': u'This class provides thunk-like behavior in standard Python.\n\nIt allows a function to be evaluated only when needed, and the return value cached, or memoized, until explicitly deleted.'}, {'comments': [{'comment': u"Apparently you don't need to sort kw items. The following code snippet:\n<pre>\nfrom random import shuffle\na=list('Mona Lisa')\nshuffle(a)\nprint a\nb=dict.fromkeys(a)\nshuffle(a)\nprint a\nc=dict.fromkeys(a)\n\nprint b.items()==c.items()\n</pre>\nprints 'True', but I must confess I'm not sure whether this is guaranteed. If you do want to sort, you don't need itemgetter, since sort does the 'right thing' on tuples anyway.\n<pre>\n# simplified version\n\nclass memoize(object):\n def __init__(self, func):\n self.func = func\n self._cache = {}\n def __call__(self, *args, **kwds):\n t = (args, kwds.items())\n try:\n key = hash(t)\n except TypeError:\n key = dumps(t)\n if not key in self._cache:\n self._cache[key] = self.func(*args, **kwds)\n return result\n</pre>", 'title': u'Very nice - can be simplified a bit'}, {'comment': u'Obviously, the last line in the previous comment must be\n<pre>\nreturn self.cache[key]\n</pre>', 'title': u'Correction to above comment'}, {'comment': u"I don't believe that hash is appropriate here, because it considers floats and ints of the same value to be equivalent. But the result of 1/2 is different from the result of 1/2.0", 'title': u"hash shouldn't be used"}, {'comment': u'I would add the following around the "dump" bit, so if pickling fails, at least it will perform the function.\n\n<pre>\ntry:\n ....\nexcept PicklingError:\n return self.func(*args, **kwds)\n</pre>', 'title': u'PicklingError'}, {'comment': u"The comment about PicklingError is valid. However, the one about hash is not. While it is true that hash does not distinguish between floats and ints, the same is true about dict keys. Try:\n<pre>\na={}\na[1]= 'Clinton'\na[1.0] = 'Bush'\nprint a[1]\n</pre>\n(prints 'Bush')\n<br><br>\nSo, you cannot have separate entries in a dict for floats and ints \nof the same value. <br>\nThe reason to use hash was not just brevity but also to avoid one problem with the original recipe: The \n<pre>\nexcept TypeError \n</pre>\nclause does not only catch errors that originate from key hashing but also unhandled TypeErrors that originate inside func.\nHowever, one real problem with the proposed use of hash is the increased likelihood of key collisions, since we actually hash twice (first explicitly with 'hash' and then implicity when using the result of hashing as the key). This is amended in the code below.\n<pre>\nclass memoize(object):\n def __init__(self, func):\n self.func = func\n self._cache = {}\n def __call__(self, *args, **kwds):\n t = (args, kwds.items())\n try:\n hash(t)\n key = t\n except TypeError:\n try:\n key = dumps(t)\n except cPickle.PicklingError:\n return func(*args, **kwds)\n if not key in self._cache:\n self._cache[key] = self.func(*args, **kwds)\n return self._cache[key]\n</pre>", 'title': u'hash _should_ be used'}, {'comment': u"Thinking of it, I'm not really sure whether hashing a hash really increases the likelihood of collisions. Anyway, the most recent version is equivalent in its use of keys to the original one, but still avoids catching exceptions from inside the memoized function (except for PicklingErrors, obviously).", 'title': u'hashing again'}, {'comment': u"class memoize(object):<br>\n\n    def __init__(self, function):<br>\n        self._function = function<br>\n        self._cacheName = '_cache__' + function.__name__<br>\n<br>\n    def __get__(self, instance, cls=None):<br>\n        self._instance = instance<br>\n        return self<br>\n    <br>\n    def __call__(self, *args):<br>\n        cache = self._instance.__dict__.setdefault(self._cacheName, {})<br>\n        <br>\n        if cache.has_key(args):<br>\n            return cache[args]<br>\n        else:<br>\n            object = cache[args] = self._function(self._instance, *args)<br>\n            return object<br>", 'title': u'Thanks! __get__ is untrivial. This example stores cache in object instance, not in static'}, {'comment': u'nice! \nchanging __init__ to this, and importing shelve and os, you can get a persistent cache. likely only useful if the function is quite slow. \n\n<pre> \ncachedir = "/tmp/shelved/"\nif not os.path.exists(cachedir): os.mkdir(cachedir)\n\n\nclass memoize(object)\n def __init__(self, func,mode=\'c\'):\n self.func = func\n file = os.path.join(cachedir,"%s.shelve" % func.func_name )\n self._cache = shelve.open(file,mode)\n self._file = file\n</pre>', 'title': u'persistent memoize'}], 'desc': u"This tries to be a safer and faster memoize decorator, it works with mutable types and with keyword args too. The code comes from many different versions found around. This code isn't much tested yet, so it must be used with care."}, {'comments': [], 'desc': u'Sort recursively nested lists'}, {'comments': [{'comment': u"... at http://starship.python.net/crew/aaron_watters/kjbuckets/ provides another graph implementation, and incorparates some nice ideas about combining sets, graphs, and dictionaries. You might want to check it out (in case you haven't already).", 'title': u'kjBuckets by Aaron Watters ...'}, {'comment': u'Cool, but this particular wheel\'s already been invented with the NetworkX package, "High Productivity Software for Complex Networks." See https://networkx.lanl.gov/. Perhaps you can look through your code to see if you could find some way to contribute parts of it to the NetworkX code base.', 'title': u'NetworkX'}, {'comment': u'Wheels keep being re-invented all the time, and sometimes they improve other wheels. Some wheels look like "wheels" but their API is different, or they work in a different way, or they have different functions. Or maybe they are just older. Designing a good API is difficult, often you have to do it more than one time before finding a good one. I can count 6 other graph libraries beside NetworkX and Graph.<br>\n<br>\n>Perhaps you can look through your code to see if you could find some way to contribute parts of it to the NetworkX code base.<br>\n<br>\nI think Graph already contains a small part of NetworkX, thank you for the offer. Looking at other people code is a strength of Open Source.<br>\nThe purpose of this Recipe is mostly to show an API that can be discussed.', 'title': u'Re: NetworkX'}], 'desc': u'A directed Graph container can be useful for the collections module. This is a bare bones implementation, to show its basic API, a complete implementation is available. Many different graph implementations are possible, but I think this is flexible, fast and simple enough.'}, {'comments': [], 'desc': u'To quickly select the n-th rank ordered element of a given sequence. (It modifies the ordering of the given sequence).'}, {'comments': [], 'desc': u'If you want to log exceptions, here is a simple way to do so without having to explicitly repetitiously call the logger in each try-except clause.'}, {'comments': [{'comment': u'With Python V.2.4 you can do your examples as:<br>\ndata.sort(key=len)<br>\nOr:<br>\nsorted(data, key=len)<br>\n<br>\nfrom operator import itemgetter, attrgetter<br>\nsorted(data, key=itemgetter(0))<br>\nsorted(data, key=itemgetter(1))<br>\n<br>\nprint sorted(data, key=attrgetter("name"))<br>\nprint sorted(data, key=attrgetter("age"))<br>\n<br>\nOr:<br>\nprint sorted(data, key=lambda r: r.name)<br>\nprint sorted(data, key=lambda r: r.age)', 'title': u'key, itemgetter, attrgetter'}, {'comment': u'... I did this for a py2.3 app. Nice to see that python is going where I need it ;-)', 'title': u'Right ...'}, {'comment': u"I'm missing something here. Where is there a closure in any of this code? Over what are you closing? When is some part of the environment being captured into a function?", 'title': u'what closures?'}, {'comment': u"Been over it again... Looks to me like you think 'ByAttribute' etc are closing over the objects they will access, but they aren't. They are just producing functions that will take those objcts as arguments, and 'sort' is passing the arguments to them on every call. These are just plain vanilla functions, taking args and returning values. No part of the environment is closed over at the time of function creation. In fact, if there were closures, sort wouldn't need to keep passing the objects in each time for comparison, because the closures would have captured the values of those objects at the time they were created. ", 'title': u'no closures'}, {'comment': u"ByAttribute(name) and ByColumn(key) are both returning functions that enclose the 'name' and the 'key' respectively -- hence closures. Same goes for the more generic By(accessor), Attribute(name) and Column(key) functions.", 'title': u'those are definitely closures'}, {'comment': u'If I say "cmp_fn = ByAttribute(\'age\')", then cmp_fn knows that it\'s job is to compare two dicts by their \'age\' as opposed to comparing by some other key. cmp_fn is closed around the string \'age\'.', 'title': u'for example'}, {'comment': u'As Eric Dobs points out, they ARE closures. (Thanks Eric)<br><br>\nSee\n<br><br>\n http://en.wikipedia.org/wiki/Closure_%28computer_science%29\n<br><br>\nfor a definition expressed better then I could ;) ', 'title': u'and they are...'}], 'desc': u'Whenever I feel the impulse to write a class, I pause for a moment and think whether I can get away with a closure. This time I will be using closures to readably and flexibly customize the sorting of sequences (for Pythons 2.1 through 2.3).'}, {'comments': [], 'desc': u"Python's built in function str() and unicode() return a string representation of the object in byte string and unicode string respectively. This enhanced version of str() and unicode() can be used as handy functions to convert between byte string and unicode. This is especially useful in debugging when mixup of the string types is suspected."}, {'comments': [{'comment': u'In the example, all threads that are created are Daemon threads. When the main thread finishes sleeping, errors are sometimes (but not always) printed to the screen. What can be done to prevent this? The program should just close without errors being printed. The solution should be simple and allow the use of the Daemon threads if possible.', 'title': u'Threads'}], 'desc': u'This recipe demonstrates a multithreaded application.\nThe code is short but should be an easy example of HOW-TO.'}, {'comments': [], 'desc': u'This program demonstrates code ported from C to Python.\n1. The port is not very pythonic (see the first version for that).\n2. The port is almost a straight line-by-line translation of code.\n3. The code came from OPERATING SYSTEMS: Third Edition (by GARY NUTT).\n4. The code involves LAB EXERCISE 2.2 (on pages 83 -- 88).'}, {'comments': [], 'desc': u"some while ago, i posted a recipe with linked dictionaries (see <a href='http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/465748'>#465748</a>) to this site. yesterday a use case came up where that kind of delegational name/value lookup would be a nice thing if it worked for instance attributes.\n\nbasically, using a customized dictionary as an instance <tt>__dict__</tt> means modifying the standard lookup-by-inheritance-only behavior; in other words, part of the state of an instance can be kept in another instance.\n\nthis way, an instance that holds, say user configuration data, <tt>userCfg</tt> can be linked, at runtime, to a <tt>defaultCfg</tt> instance, and all the <tt>userCfg.frobfactor</tt> stuff that has not been defined by the user but for the default configuration would automatically be available. \n\nunfortunately, the na\xefve approach (setting <tt>self.__dict__=MyDict()</tt> in <tt>__init__</tt>) fails to work. an inquiry to comp.lang.python was swiftly answered by bengt richter, who suggested to use a property for <tt>__dict__</tt>. i slightly improved on his suggestion by adding the capability to do item assignment as well.\n\nnote that since we are using <tt>__getattr__</tt> to redirect attribute lookup, delegation only happens <i>after</i> lookup in the method resolution order (mro) has failed (inheritance overrides delegation)."}, {'comments': [{'comment': u"<pre>\n>>> aa = AttrDict()\n>>> aa.x = [4,5,6]\n>>> aa.x\n[4, 5, 6]\n\n>>> bb=aa.copy()\n>>> bb.x\n[4, 5, 6]\n\n>>> bb.x[1]='X'\n>>> bb.x\n[4, 'X', 6]\n>>> aa.x\n[4, 'X', 6]\n</pre>", 'title': u'copy() failed'}, {'comment': u'That seems to be the default feature of the standard dict. Check out a recipe that I just posted for a better way of copying:<br><br>\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473790', 'title': u'a better copy'}, {'comment': u'Jimmy Retzlaff (other recipes)<br>\nLast Updated: 2005/01/03 <br><br>\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/361668\n<br><br>', 'title': u'similar and much simpler'}], 'desc': u'This supclass of dict allows access the the value using attribute access syntax.\n\n\td = AttrDict()\n\td.one = "one"\n\tprint d\n\tprint d.get\n\tprint d.one\n\tprint d["one"]\n\td["two"] = 2\n\tprint d.two\n\tprint d["two"]'}, {'comments': [], 'desc': u'I have a program, say a debugger, that runs another program which has options of its own. I want people to be able to give options to either program and don\'t want them to get confused. For example, perhaps both have "--help" options.\n \nSo to be a little more concrete, let\'s say I\'d like to run say program (pdb) and have it pass "--help" to a program I want it to run (specified as a command argument) called "debugged-script". I\'d like to issue the command like this:\n\npdb --trace debugged-script --help\n\nand have "--help" go to "debugged-script" and not "pdb".'}, {'comments': [], 'desc': u'<code>A dict extension that has the following features:\n\n 1. dual data storages: use \'bd.x\' or \'bd["x"]\' for one,\n and bd.getDict() for another.\n\n 2. All the followings are equivalent::\n \n bd[\'x\']= val\n bd.x = val\n bd.setItem(\'x\', val) # Return bd\n \n 3. bd.setDict(\'x\',val) will save \'x\' to bd.__dict__, \n but not bd.items\n\n 4. When copy, copy the internal object correctly. \n</code> '}, {'comments': [], 'desc': u" Eli Criffield <python@zendo.net>\n avalible at http://eli.criffield.net/sum/\n a better better command line calculator,\n\n put this in a file, run it, cut and past a bunch of numbers (don't\n worry about the $ signs and commas) hit enter and it adds them up\n use / * - + like normal\n\n added features over just using python as a command line calculator:\n\n * numbers can include ,s and $s or anything really and it still works\n this allows you to cut and paste things like $1,123.65 and it still works\n * add by default! (unless you run with -x)\n cut and paste a bunch of numbers hit enter and it'll add them all up\n * command line history and readline, up arrow recalls your history\n even between sessions\n * _ is the last answer, just like in python"}, {'comments': [{'comment': u'Microsoft has quite a lot of useful examples available via<br>\nhttp://www.microsoft.com/technet/scriptcenter/scripts/python/default.mspx\n<br><br>\nAn alternative way to look up (user/sytem/whatever) environment variables is given by<br>\nhttp://www.microsoft.com/technet/scriptcenter/scripts/python/desktop/explorer/dmexpy03.mspx\n<br>\nwhich uses an SQL-ish way.', 'title': u"See also Microsoft's examples"}], 'desc': u"As you can see in Windows Control Panel 'System' applet there are two groups of environment variables: USER and SYSTEM.\nHere presents function for retrieve SYSTEM variable value.\n"}, {'comments': [], 'desc': u'Run parameterized map, filter, reduce, and extract functions on a database structured as a list of tuples. Useful for applications where the filter, extract, and summarize operations are specified by the user at runtime.'}, {'comments': [], 'desc': u"This is a simple console application that you can use to schedule iTunes to begin playing a playlist at a certain time. \nThe volume ramps up to full level over about 1 minute so you aren't blasted awake.\n\nI haven't worked with Python much so any suggestions, comments are appreciated. \n\nThanks, \nJosh"}, {'comments': [{'comment': u'<pre>\nimport random\n\ndef randrange(start, stop):\n values = range(start, stop)\n\n while values:\n yield values.pop(random.randrange(len(values)))\n\n raise StopIteration\n\nfor x in randrange(0, 10):\n print x\n</pre>', 'title': u' '}, {'comment': u'it is quicker to use random.shuffle()\n\n<pre>\nimport random\n\ndef randrange(start, stop):\n values = range(start, stop)\n random.shuffle(values)\n\n while values:\n yield values.pop()\n\n raise StopIteration\n\nfor x in randrange(0, 10):\n print x\n</pre>', 'title': u' '}, {'comment': u'this is meant to handle cases where the results of range() will not fit in memory - e.g. a randomized walk over all values of the IP address space, or even sys.maxint, etc.', 'title': u'hrr, i should have given an example...'}], 'desc': u'iterate over all values of a range in random order.\n\nrelated to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/466177'}, {'comments': [{'comment': u'Nice and simple example to embed images in HTML mails.\n\nThanks for sharing', 'title': u' '}], 'desc': u"HTML is the method of choice for those wishing to send emails with rich text, layout and graphics. Often it is desirable to embed the graphics within the message so recipients can display the message directly, without further downloads.\n\nSome mail agents don't support HTML or their users prefer to receive plain text messages. Senders of HTML messages should include a plain text message as an alternate for these users.\n\nThis recipe sends a short HTML message with a single embedded image and an alternate plain text message."}, {'comments': [{'comment': u'<br>\nVery good tool. Thx for sharing.', 'title': u' '}, {'comment': u'I should probably add that a version with the scintilla editor embedded for colorizing the source is available at http://sourceforge.net/project/showfiles.php?group_id=125834 under "lightning".', 'title': u'Version with colorized source'}, {'comment': u'Thank you, I like it.<br>\n<br>\nMay I suggest:<br>\n1) # -*- encoding: latin-1 -*- <br>\nat the beginning (so no encode error appear).<br>\n\nFor even faster typing and operating:<br>\n\n2) even faster to start would be to assign a hotkey.<br>\nI think, F5 is commonly used to run something.<br>\nclass EditorSashWindow(wx.Panel):<br>\n def __init__(self, parent):<br>\n ...<br>\n ...<br>\n runid = wx.NewId()<br>\n b3 = wx.Button(self.controls, runid, "Run", (3, 100))<br>\n ...<br>\n ...<br>\n aTable = wx.AcceleratorTable([(wx.ACCEL_NORMAL, wx.WXK_F5, runid)])<br>\n self.SetAcceleratorTable(aTable)<br>\n<br>\n<br>\n3) I would add a LF at the end to be able to type immediatly:<br>\nself.python_editor.AddText("#Editor window\\n")<br>\n<br>\n4) SetFocus to the edit window immediatly:<br>\n class EditorSashWindow(wx.Panel):<br>\n def __init__(self, parent):<br>\n ...<br>\n ...<br>\n self.python_editor.SetFocus()<br>', 'title': u' '}, {'comment': u'Thanks for the suggestions. I implemented them, and made a few minor changes. New version on sourceforge', 'title': u'Suggestions implemented!'}, {'comment': u"Great, thank you (for your changes and mentioning me! ;))<br>\n<br>\nMay I suggest one small thing.<br>\n(No need to update the program again, only of my suggestion)<br>\n\nthe scrolling of the output window isn't working;<br>\nso if the output exceeds line 28 (on my pc) the next outputs<br>\nare not seen automatically.<br>\n<br>\nSo I added:<br>\nclass LogWindow(python_editor):<br>\n...<br>\n def write(self, text):<br>\n self.AddText(text)<br>\n=> self.EnsureCaretVisible()<br>", 'title': u' '}], 'desc': u'I find that I often want to test some small code samples, too long to type at the interpreter (and retype, with some small changes), but not worth saving. The following wxPython based mini-app implements the basic for a small Python editor with a side output window. It also handles input() and raw_input(). '}, {'comments': [{'comment': u'I normally use something like the following for cartesian products:\n\n<pre>\ndef nest(*iterables):\n def _nest(outer, inner):\n for outer_item in outer:\n if not isinstance(outer_item, tuple):\n outer_item = (outer_item,)\n for inner_item in inner:\n yield outer_item + (inner_item,)\n return reduce(_nest, iterables)\n\n >>> list(nest(range(2), range(2), range(2)))\n [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]\n\n</pre>\n ', 'title': u'Seems like overkill'}, {'comment': u'>>> [(i,j,k) for i in range(2) for j in range(2) for k in range(2)]<br>\n[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]', 'title': u'why bother? '}, {'comment': u'It seems to me that a task like :<br>\n<pre>\nfor x in range(width):\n\n for y in range(height):\n\n do_something(x,y)\n</pre>\n<br>\ncan be accomplished with simple list comprehension:<br>\n<pre>\n[ do_somthing(x,y) for x in range(width) for y in range(height) ]\n</pre>\nthat is, one-liner compared to this long recipe.<br>', 'title': u'Use list comprehension ?'}, {'comment': u"Beware that\n\n<pre>[ do_somthing(x,y) for x in range(width) for y in range(height) ]</pre>\n\ncreates a list of width*height None's, which consumes (perhaps a significant amout of) memory with no benefit at all.\n\nList comprehensions are meant to ease list construction, not to squeeze for loops.", 'title': u'presumably an improper use of list comprehensions'}, {'comment': u'<pre>\nThe list comprehension example that I posted was just to demonstrate\nthe intrinsic capability of python to loop thru nested ranges. In \nthe newer python this "for-x-for-y" thingy doesn\'t need to be in a\nlist. Instead, it can be in ( ) to represent a generator. \n\nUsing the examples shown in this recipes:\n\n >>> for x,y in nest(3,3):\n ... print x,y\n\ncould be:\n\n >>> for x,y in ( (x,y) for x in range(3) for y in range(3)):\n ... print x,y\n\nand\n\n >>> for x,y in nest( (1,4), (10, 40, 10) ):\n ... print x,y\n\ncould be:\n\n >>> for x,y in ( (x,y) for x in range(1,4) for y in range(10,40,10)):\n ... print x,y\n\n\nIn these cases this recipe(nest) does make it shorter but with a\ntrade-in of having an extra module to import and an extra function \napi to remember. This is probably upto personal tastes, i guess.\n\nIn situations when conditional operations are in need, like the \nfollowing case:\n\n >>> for x,calc,y in nest((3,5), lambda(x): float(x[0])/10, 3):\n ... print x, calc, y\n\nthe intrinsic "for-x-for-y" approach is actually, IMO, much more\nreadable:\n\n >>> for x,calc,y in ( (x,x/10.0,y) for x in range(3,5) for y in range(3) ):\n... \tprint x, calc, y\n</pre>', 'title': u"That's true"}, {'comment': u"This recipe bacically came from a requirement to allow nested loops of non-specific depth (ie to be determined at run-time), as well as slightly more trackable in-place modification of the lists beings iterated over.. (permutations based countdown number game solver)\n<br><br>\nI agree with pretty much everything everybody said so far though, it's a bit unwieldy for everyday use, and most of what it gives you, you already get from list comprehensions, generators, and simple for-loops\n<br><br>\nin fact, it would've been rather less unwieldy (hmm. more wieldy?) if I'd posted it in its original form (just the list-based iterator iirc).. I added all that other crap to show how wonderfully versatile it all was :/", 'title': u'Yep, kinda see what you all mean..'}], 'desc': u'Transforms nested loops like\n<pre>for x in range(width):\n for y in range(height):\n do_something(x,y)</pre>\ninto:\n<pre>for x,y in nest(width, height):\n do_something(x,y)</pre>'}, {'comments': [{'comment': u"I'm not sure how the above solution works. Here is a solution I wrote a while back:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473832", 'title': u'Using Generators'}], 'desc': u"An enigma for the chess fans is the problem of the Eight Queens, that demands the following one: it is possible to place eight queens in an empty chessboard in way that none is ' attacking ' some another one (that is, without that two queens are in the same line, the same column or the same diagonal line)?\n\nUm enigma para os fas de xadrez \xe9 o problema das Oito Rainhas, \nque exige o seguinte: \xe9 poss\xedvel colocar oito rainhas em um \ntabuleiro de xadrez vazio de modo que nenhuma esteja 'atacando' \nalguma outra (isto \xe9, sem que duas rainhas estejam na mesma linha, \nna mesma coluna ou na mesma diagonal)?\n\nPS.: Texto retirado do livro: Java Como Programar, Sexta Edi\xe7ao, \nCap\xedtulo: 15, Pagina: 580, Exercicio: 15.15, \nH. M. Deitel(Ditel & Associates, Inc.), P. J. Deitel(Deitel & Associates, Inc.)."}, {'comments': [], 'desc': u'Sometimes we want to have a module initialized in different ways. This function, getimporter(), while placed inside a module X, allow you to initialize module X according to the module (properties) that is importing X. '}, {'comments': [{'comment': u"There are many python scripts in Gentoo Linux that just require to press a key to answer a question like (Y/n); really great to answer a lot of questions like you may have in the step-by-step mode of regexplace.py !<br>\n\nThe solution is to use a getch() python function, for example the one provided by this script: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/134892 <br><br>\nJust save it getch.py, and add 'import getch' in regexplace.py. Then replace each question of type:<br><br>\n\nquestion = raw_input('write(Y), skip (n), quit (q) ? ')<br>\nquestion = string.lower(question)<br><br>\n\nby:<br><br>\n\nprint 'write(Y), skip (n), quit (q) ? '<br>\nquestion = string.lower(getch.getch())<br><br>\n\nThat's all !<br>\n\nThanks Stefano for this powerful script !", 'title': u'For a better user interaction'}], 'desc': u'This script search and replace files in a directory, recursively.\n\nfile name and search string can be a regular expression.\n\nExecution can be simulated, step by step, and are always shown changed files/lines.'}, {'comments': [{'comment': u'The used method is propably not correct, because only the "best" board is recognized. But it works.<br>\nbtw the preview function displays the posting twice\n<pre>\n#!/usr/bin/python\n\ncoords = [ (n%8,n/8) for n in range(8*8)] # creates initial allowed coord list (0,1), (0,2) .. (7,7)\n\ndef queen_line( x1, y1, x2, y2 ): # checks if coords are on a "queen line"\n if (x1==x2) or (y1==y2) or (abs(x1-x2) == abs(y1-y2)): \n return True\n else:\n return False\n\ndef get_threat_board(x1, y1): # returns a table with forbidden coords\n return [queen_line(x1, y1, x2, y2) for x2,y2 in coords]\n \ndef get_allowed_coords(current_coords, x, y): # does what it says ;)\n t_board = get_threat_board(x,y)\n return [ (x,y) for x,y in current_coords if not t_board[y*8+x] ]\n\ndef get_newqueen_best_coords(allowed_coords, queen_coords): # returns a new coord list \n l_pcoords = []\n best_coords = None\n c_max_ac=0\n for x,y in allowed_coords:\n ac = get_allowed_coords(allowed_coords, x,y)\n if (len(ac) > c_max_ac):\n best_coords = ac\n c_max_ac = len(ac) \n qx=x\n qy=y\n return best_coords, queen_coords+[(qx, qy)]\n\ndef print_board(queen_coords):\n for x in range(8):\n for y in range(8):\n print [\' \', \'Q\'][(x,y) in queen_coords],\n print\n\nif __name__=="__main__": \n allowed_coords=coords\n queen_coords=[]\n while len(queen_coords)The used method is propably not correct, because only the "best" board is recognized. But it works.<br>\nbtw the preview function displays the posting twice\n<pre>\n#!/usr/bin/python\n\ncoords = [ (n%8,n/8) for n in range(8*8)] # creates initial allowed coord list (0,1), (0,2) .. (7,7)\n\ndef queen_line( x1, y1, x2, y2 ): # checks if coords are on a "queen line"\n if (x1==x2) or (y1==y2) or (abs(x1-x2) == abs(y1-y2)): \n return True\n else:\n return False\n\ndef get_threat_board(x1, y1): # returns a table with forbidden coords\n return [queen_line(x1, y1, x2, y2) for x2,y2 in coords]\n \ndef get_allowed_coords(current_coords, x, y): # does what it says ;)\n t_board = get_threat_board(x,y)\n return [ (x,y) for x,y in current_coords if not t_board[y*8+x] ]\n\ndef get_newqueen_best_coords(allowed_coords, queen_coords): # returns a new coord list \n l_pcoords = []\n best_coords = None\n c_max_ac=0\n for x,y in allowed_coords:\n ac = get_allowed_coords(allowed_coords, x,y)\n if (len(ac) > c_max_ac):\n best_coords = ac\n c_max_ac = len(ac) \n qx=x\n qy=y\n return best_coords, queen_coords+[(qx, qy)]\n\ndef print_board(queen_coords):\n for x in range(8):\n for y in range(8):\n print [\' \', \'Q\'][(x,y) in queen_coords],\n print\n\nif __name__=="__main__": \n allowed_coords=coords\n queen_coords=[]\n while len(queen_coords)</pre></pre>', 'title': u'shorter version'}, {'comment': u'see code here: http://www.rafb.net/paste/results/lmHVzI64.html', 'title': u'broken comment function?'}, {'comment': u'This version prints out all solutions (uses Python 2.4 sets):\n\n<pre>\nN = 8\n\nall_positions = set([(i,j) for i in range(N) for j in range(N)])\n\ndef reachablePositions(x,y):\n s = set([(x,i) for i in range(N)]) # vertical\n s |= set([(i,y) for i in range(N)]) # horizontal\n s |= set([(x+i,y+i) for i in range(-N,N)]) # diagonal \\\n s |= set([(x+i,y-i) for i in range(-N,N)]) # diagonal /\n return s\n\ndef place_queens(current_solution = [], allowed_positions = all_positions):\n if len(current_solution) == N: # only N queens to place - done\n yield current_solution\n return\n y = len(current_solution) # place queens line by line\n for x in range(N):\n if (x,y) in allowed_positions:\n for s in place_queens(current_solution+[(x,y)], allowed_positions - reachablePositions(x,y)):\n yield s\n\ndef printBoard(b):\n print \'\\n\'.join([\' \'.join([(\'.\', \'Q\') [(x,y) in b] for x in range(N)]) for y in range(N)])\n\nfor i,b in enumerate(place_queens()):\n print "Solution", i, b\n printBoard(b)\n print\n</pre>', 'title': u'All solutions'}, {'comment': u'It would be interesting if someone could compare these various solutions w.r.t time and space complexity.', 'title': u'Comparison?'}, {'comment': u'Here are some modifications for speed.\n<pre>\n# Utility functions for drawing chess board\ndef display(board):\n "Draw an ascii board showing positions of queens"\n string = str()\n assert len(board)==MAX\n it = iter(board)\n for row in xrange(NUM_QUEENS):\n for col in xrange(NUM_QUEENS):\n string += it.next() + \' \'\n string += \'\\n\'\n return string\n\nfor i,p in enumerate(rl):\n print \'=\' * NUM_QUEENS * 2, "#%s\\n%s" % (i+1, display(make_board(p)))</pre>', 'title': u' '}, {'comment': u'Check http://en.wikipedia.org/wiki/8_queens_problem; it has a Python solution for the n-queen problem. I even adapted it for my "Python Learning Environment" (rur-ple) where one can visually place 8 "queens" (Robots!) with colored lines showing which squares are under attack by each queen.\nEven though the use of generator is "interesting", I don\'t think that solution to such well-known problems belong in this cookbook.', 'title': u'non-generator ... but well-known'}, {'comment': u'I\'m not sure if 8-queens belongs in the Python Cookbook, but I do think the Python solutions to the problem are instructive. For example, I can\'t think of an elegant way to solve this problem in C++, but in Python I would say that using permutations and generators gives an intuitive and elegant (albeit slow) solution:\n\n<pre>\ndef permutations(L):\n if len(L) <= 1:\n yield list(L)\n else:\n for i in range(len(L)):\n for p in permutations(L[:i]+L[i+1:]):\n yield [L[i]] + p\n\ndef queens(n):\n for L in permutations(range(n)):\n if (len(set(i+L[i] for i in range(n))) == n and\n len(set(i-L[i] for i in range(n))) == n):\n yield L\n\nif __name__ == \'__main__\':\n for sol in queens(8):\n for col in sol:\n print \'.\'*col + \'Q\' + \'.\'*(8-1-col)\n print\n</pre>\n\nThe code above can be shortened to 9 lines by using generator expressions in permutations() and queens(), and simply printing len(list(queens(8))). However, this reduces the clarity of the code.\n\nAnother idea is to modify permutations() to accept a "filter" function, so that if two queens share a diagonal, then we don\'t waste time recursing on this case.\n', 'title': u'Instructive'}], 'desc': u'A classic algorithmic problem - place 8 queens on a chess board so that none is attacked by another.'}, {'comments': [], 'desc': u'Provides a simple way to access your database tables/rows/attributes as \nPython Classes/Instances/attributes respectively.'}, {'comments': [{'comment': u"You really don't want to be using xmlrpclib here. Use twisted.web.xmlrpc.Proxy. xmlrpclib is blocking your entire Twisted process every time you authenticate, and Twisted has a nice alternative already available for you in twisted.web.xmlrpc.", 'title': u'Please, please, please'}, {'comment': u"Thanks -- I'll add that to the comments. That's what I've done in production (in addition to implementing a caching solution). I did want to keep the recipe simple, so I left that bit out. I'll make a note in the description for now, but when I clean up and pare down the prod code, I'll update the recipe.", 'title': u'twisted.web.xmlrpc'}, {'comment': u'Okay, I have posted a couple more recipes that should make this as clean as possible. However, since twitsed.web.xmlrpc itself doesn\'t actually support authentication, I will not modify the recipe, but will post how to work around this here. The code to have a Twisted XML-RPC Proxy which supports Authentication is here:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473865\n\nWith that said, here\'s what you would do to modify this recipe:\n<pre>\nfrom zope.interface import implements\n\nfrom twisted.internet import defer\nfrom twisted.cred import checkers\nfrom twisted.cred import credentials\n\nfrom where.you.saved.xmlrpcauth import AuthProxy\n\nclass ZopeChecker(object):\n\n implements(checkers.ICredentialsChecker)\n credentialInterfaces = (credentials.IUsernamePassword,)\n\n def __init__(self, host, port=8080,scheme="https", path="/"):\n self.scheme = scheme\n self.host = host\n self.port = port\n self.path = path\n\n def _ebAuthProblem(self, failure):\n # For a real app, use some logging here instead\n print "Doh! There was a problem logging into the Zope server."\n print failure.getErrorMessage())\n\n def _cbCheckAuth(self, data, username):\n if data.get(\'authenticated\'):\n return username\n return failure.Failure(error.UnauthorizedLogin())\n\n def requestAvatarId(self, c):\n url = \'%s://%s:%s@%s:%s%s\' % (self.scheme, c.username, c.password, \n self.host, self.port, self.path)\n server = AuthProxy(url)\n deferred = server.callRemote(\'getXMLRPCUserInfo\')\n deferred.addCallback(self._cbCheckAuth, c.username)\n deferred.addErrback(self._ebAuthProblem)\n return deferred\n</pre>', 'title': u'Using Deferreds'}], 'desc': u"I was writing a custom Twisted XML-RPC server for radio station DJs to use, but one station was managing all of its internal web app users and groups through Zope. Twisted has an amazingly pluggable authentication framework, so the requirement was satisfied with the following. \n\nNote that in this simple example, every time a user executes an XML-RPC method, they are authenticating against Zope. This involves an xmlrpclib.ServerProxy instantiation as well as the overhead of making a network connection to Zope. For this reason, as well as in the event of Zope being down, one might want to implement some form of caching (without passwords), so that application functionality is not impacted by Zope downtime and overhead from authentication is only incurred when necessary.\n\nradix makes a very good point in the comments: the use of xmlrpclib in this recipe is blocking. This means that if you have 10, 20, whatever number of people using the app, and someone new logs in, the twisted reactor can't do it's usual thing and cycle through requests until that user finishes logging in. I will post an update that makes use of the non-blocking t.w.xmlrpc code. The solution will be messier, though, as t.w.xmlrpc is broken in that it doesn't handle scheme://username:pass@host:port URLs. This is due to the fact that t.w.xmlrpc.QueryProtocol doesn't set an Authentication header... and there's no mechanism in t.w.xmlrpc.Proxy and QueryFactory for parsing and setting user and password into from the URL.\n\nUpdate: see the comments below for how to work around this limitation."}, {'comments': [], 'desc': u'This recipe can be used by anyone who wants a date object for a program. This is the first version and correctness has not been totally verified. The code was written as a help for someone trying to do the same thing in C++.'}, {'comments': [], 'desc': u'This program is a Sudoku solver that uses 3 simple algorithms.'}, {'comments': [{'comment': u'Function expandvars are easily replaced by win32api.ExpandEnvironmentStrings', 'title': u'win32api.ExpandEnvironmentStrings is our choice! 8-)'}, {'comment': u'Good to know! I am not very familiar with the win32 extensions.<br>\n<br>\nBut my module would work with just the Python standard library without win32api installed.', 'title': u'expandvars'}], 'desc': u'This modules provides a few handy functions to retrieve the path names of some windows system directories from the registry [1] and the environment. These path names can be different depending on OS version, installation language, current user and personal setup. Because of this, they should not be included statically in your program.'}, {'comments': [], 'desc': u'If you prefer to write reports based on sorted by fields records manually rather than using automatic report generators, then this recipe can help you by concentrating on the writing of record details, headers and footers. No output page control is included however in this simple example. The code is based on a finite state machine.'}, {'comments': [], 'desc': u'This recipe demonstrates how easy it is to compile a list of (log) files into one large file. The source files come from the current directory, and the output file is written to the current directory. Only files with a specific format are put into the compiled (log) file.'}, {'comments': [{'comment': u'very nice example indeed !<br>\n\none small problem, if you have an input field in your html code before any img tags, the p3 regular expression will try to re-encode an already captured image resulting in the above stated exception<br>\n<br>\nurllib2.URLError: <urlopen error unknown url type: cid><br>\n<br>\ndue to the fact that you try to urlopen "cid:dazoot-img" which of course can not be found.<br>\n<br>\nto solve this you have to adapt the regular expression match a little<br>\n<br>\n\n\t\tself.p3=re.compile("(<input[^>]+src=\\")(.*?)(\\".*?>)", re.IGNORECASE|re.DOTALL)<br>\n\nthis if of course the same for self.p1.<br>\nfor self.p2 I would rather write something like this\n<br>\nself.p2=re.compile("(very nice example indeed !<br>\n\none small problem, if you have an input field in your html code before any img tags, the p3 regular expression will try to re-encode an already captured image resulting in the above stated exception<br>\n<br>\nurllib2.URLError: <urlopen error unknown url type: cid><br>\n<br>\ndue to the fact that you try to urlopen "cid:dazoot-img" which of course can not be found.<br>\n<br>\nto solve this you have to adapt the regular expression match a little<br>\n<br>\n\n\t\tself.p3=re.compile("(<input[^>]+src=\\")(.*?)(\\".*?>)", re.IGNORECASE|re.DOTALL)<br>\n\nthis if of course the same for self.p1.<br>\nfor self.p2 I would rather write something like this\n<br>\nself.p2=re.compile("(', 'title': u'urllib2.URLError: <urlopen error unknown url type: cid>'}, {'comment': u'sorry for my messy comment, I am quite sure I did not post it like that, I hope the webmaster will clean it up (like remove all the duplicate lines!)<br>\n<br>\nthe p2 regular expression didn\'t quite came out the way is should so here it is again<br>\n<br>\nself.p2=re.compile("(<.*?background=\\")([^\\"]*)(\\".*?>)", re.IGNORECASE|re.DOTALL)<br>\n<br>\nmeaning, capture all the text after the sequence \'background="\' up to but not including the next quote<br>\n<br>\n\n(hope these lines will be here only once ;-)<br>\n<br>\ngreetz,<br>\n<br>\nPeter<br>', 'title': u'what a messy comment !'}], 'desc': u'The thing about this class is to "build" a mail msg object, automatic, from an URL or a local html file WITH all images included.\nThe class takes care of the image parsing / downloading / embedding + "cid: ID-here" replacements. The return is a valid MIMEMultipart("related") msg object which can be used to send valid HTML mail.'}, {'comments': [], 'desc': u'A short, readable password generator that can be launched from the command line. Just launch it from the shell and it will print out an 8-character password. You can also specify the length and whether the password should be typed with alternating hands on a qwerty keyboard.'}, {'comments': [], 'desc': u'This recipe demonstrates some keyboard input functions and screen output "magic" that some people may be interested (such as for an ASCII game). It is meant as a very simple demonstration only, and does not contain any error checking whatsoever. The style of the code is not the best, but it is meant to get a point across.<br>NOTE: This code was written to work in windows.'}, {'comments': [{'comment': u'copy_reg lets you specifier pickling behavior for arbitrary types. The following will allow you to pickle any threading.Event, not just instances of a subclass.\n\n\n<pre>\nimport copy_reg, threading\n\ndef unserialize_event(isset):\n e = threading.Event()\n if isset:\n e.set()\n return e\n\ndef serialize_event(e):\n return unserialize_event, (e.isSet(),)\n\ncopy_reg.pickle(threading._Event, serialize_event)\n</pre>', 'title': u'This is simpler with the copy_reg module'}, {'comment': u'This is both more, and less, flexible than the solution I submitted. As you point out, it lets you serialize the Event type more generally, but at the expense of depending on the _Event class, which is (I assume, by the leading underscore) private to the implementation and could change without warning in future versions.<br><br>\n\nI doubt the _Event object _would_ go away, mind you, but I would say the right solution depends on whether you more greatly require forward compatibility or a more general solution.', 'title': u'A good solution to a (slightly) different problem'}], 'desc': u"Objects that use the Event object from the threading core library can't be pickled because the Event's underlying implementation is an unpicklable Lock object. Conceptually, though, an Event is just a boolean, so providing reasonable serialization behavior is pretty straightforward."}, {'comments': [], 'desc': u'This is a set of classes I have used for dealing with URL parsing in an easy and convenient manner. It keeps the code clean, etc.'}, {'comments': [{'comment': u"Hi I am looking for this in Twisted 2.5 and can't seem to find it. Twisted is a large package so perhaps I am just not finding it. Can you advise the location of the code in twisted. Many thanks.", 'title': u'Twisted xmlrpc auth'}], 'desc': u'These classes subclass several of the culprits in twisted.web.xmlrpc that are responsible for not being able to make autenticated XML-RPC calls.\n\nNote that this recipe also makes use of the URI classes that were posted in a previous recipe here:\n http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473864\n\nI will submit a patch to twisted along these lines, but there will be no references to the custom Uri module or code.\n\nUpdate: XML-RPC Authentication is now supported in Twisted (version 2.4 included a patch based on this recipe). If you are using a recent version of Twisted or can update to a recent version, this recipe is no longer needed.'}, {'comments': [], 'desc': u"There aren't many one-liner programs that exist, and that is probably a good thing. This recipe is designed to remove all comments from Python code where the comment is the only thing that is on a line of your program. This can be useful when just trying to get a summary of the code, especially if the comments are heavily used for documentation. Please take note of the program that this recipe has (listed below)."}, {'comments': [{'comment': u'I just noticed that I initialize but never use a variable "commas". I forgot to take that out before submitting the recipe. (It\'s a relic of the function\'s evolution)', 'title': u'Relic'}, {'comment': u"I fixed it. I didn't know I could edit the code after I submitted. Wish I could find a way to remove this redundant comment!", 'title': u'Relic Relic'}, {'comment': u'It\'s all in the standard library:<br>\n<br>\n<pre>\nimport locale\n\ndef number_format(num, places=0):\n return locale.format("%.*f", (places, num), True)\n\nif __name__ == \'__main__\':\n locale.setlocale(locale.LC_NUMERIC, \'\')\n print number_format(12345.6789, 2)\n # will print \'12.345,68\' (rounded!) in German locale\n</pre>\n\nReferences:<br>\n<br>\nhttp://www.python.org/doc/current/lib/module-locale.html<br>\nhttp://www.python.org/doc/current/lib/typesseq-strings.html (see item 4 in 3rd paragraph)<br>\n<br>\nBTW: the "F" in RTFM should be read as "fine" or "fantastic" here!', 'title': u'RTFM'}, {'comment': u"I found this code after I submitted this recipe. Hopefully, when the editor's get a round tuit, they'll just delete it.", 'title': u'Thanks, Chris'}, {'comment': u"silly but since I knew PHP before Python I actually got this link from google and thus found out about the locale module (I knew there was something in std lib but didn't know which module). so ... maybe one should leave the recipe up for us scarred PHP veterans? :)", 'title': u'probably good to keep the recipe up'}], 'desc': u'This function takes a number (integer or float) and returns a string with the integer portion grouped by thousands and the decimal portion rounded or padded to given number of decimal places.'}, {'comments': [{'comment': u'Check out http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/483752', 'title': u'An improved version supporting exceptions and decorators'}], 'desc': u"Using signals to timeout a function such as in:\nhttp://www.pycs.net/users/0000231/weblog/2004/10/\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307871\nwon't work if the function you are calling overrides the alarm. Using threads gives you away around this."}, {'comments': [], 'desc': u'This recipe will split a file into several smaller files while at the same time hiding the original formatting of the file. The program has a primitive GUI design (my first one), put allows a small amount of interaction with the program. Testing has not been extensive, but all appears to be in order.'}, {'comments': [], 'desc': u'This is a simple example of web service usage (here: currency exchange rate service from xmethods) in python via a http proxy. Proxy information is taken from the environment.'}, {'comments': [], 'desc': u"This class automates connection to Microsoft's delightful* Visual Source Safe source control system. * -> :D \n\n"}, {'comments': [{'comment': u'I have tried it with MatPlotLib, but it gives some problems:<br>\n>>> import importer<br>\n>>> importer.install()<br>\n>>> from pylab import *', 'title': u'MatPlotLib'}, {'comment': u"it seems the lazy importer doesn't handle C modules that import other modules very well. I have posted a question on python-list about this to try to figure out how to detect this case so I can handle it.\n\nhttp://mail.python.org/pipermail/python-list/2006-February/326087.html", 'title': u'MatPlotLib'}, {'comment': u'See also Phillip Eby\'s Importing package [1] and my autoimp module [2]. The former serves a need similar to your recipe; the latter is intended to make the interactive Python prompt easier to use by pre-importing all modules (and doing this lazily, so modules are only loaded when they are used).<br><br>\n\n[1]. http://peak.telecommunity.com/DevCenter/Importing">Importing<br>\n[2]. http://barnesc.blogspot.com/2006/06/automatic-python-imports-with-autoimp.html', 'title': u'See also'}, {'comment': u'This code is working well for me thanks.\nThe module type can be obtained from the desc output from imp.find_module. However this is not enough to get matplotlib to load as it depends on all modules being loaded for some documentation trickery\n\nTo get around the matplotlib problem I added a list of modules to skip as follows:\n<pre>\nclass OnDemandImporter(object):\n """ The on-demand importer imports a module proxy that\n inserts the desired module into the calling scope only when\n an attribute from the module is actually used.\n """\n __skip = [\'gtk\', \'gdk\', \'gobject\', \'matplotlib\']\n def find_module(self, fullname, path=None):\n nameparts = fullname.split(\'.\')\n for m in nameparts:\n if m in self.__skip:\n return None # load normally\n</pre>\nI also found that the reload() command is broken because it expects a module and gets a ModuleProxy instance instead. I got around that by changing the install function:\n\n<pre>\nonDemandImporter = OnDemandImporter()\n_realReload = None\ndef lazyReload(module):\n if type(module) is types.ModuleType:\n _realReload(module)\n\ndef install():\n global _realReload\n _realReload = __builtins__[\'reload\']\n sys.meta_path.append(onDemandImporter)\n __builtins__[\'reload\'] = lazyReload\n \ndef uninstall():\n try:\n sys.meta_path.remove(onDemandImporter)\n except ValueError:\n pass\n else:\n if _realReload is not None:\n __builtins__[\'reload\'] = _realReload\n</pre>', 'title': u'matplotlib and reloading'}], 'desc': u'The following recipe allows you to delay import module statements until the module is actually needed. This can lead to a much faster startup time for large programs with lots of imports. Installing is easy, just call importer.install(). '}, {'comments': [], 'desc': u'Yet another solver. Uses knowns to eliminate possibilities, then tries assumptions from remaining possibilities (depth-first search with heuristic to first explore cells with the fewest unknowns).'}, {'comments': [{'comment': u'Very useful! But I would suggest using list comprehension instead of generating expressions to make in working with Python 2.3.', 'title': u'Thanks!'}], 'desc': u'this recipe contains a function, "rename_members", which takes an object, and two strings describing variable naming conventions (e.g. "allcamel", "underscores", etc). it translates attribute names on the given object from the first naming convention to the second (it doesn\'t delete the original attributes). the function also takes an optional acceptance function, which will be passed each attribute. the default acceptance function is "callable".'}, {'comments': [{'comment': u"Nice idea! \n\nUnfortunately this does not work on OSX by default. The default terminal does not understand the save/load cursor ANSI sequence. However it does understand the GOTO COL 0 sequence ( ESC[G ). A way to fix this for OSX would be to change the following line: \n<pre>\nsys.stdout.write(self.ESC + '[2K' )\n</pre>\nto\n<pre>\nsys.stdout.write(self.ESC + '[2K' + self.ESC+'[G')\n</pre>\nI think this sequence would work on ANY terminal, meaning that you could zero out the function reset_cursor() and all function calls referring to it. ", 'title': u'Does not work on OSX (as it is)'}, {'comment': u'To avoid ANSI, you can use character Backspace (0x08) to move cursor one position backward, so entire recipe becomes:\n\n<pre>\n"""\nHere is a silly example of its usage:\n\nimport progress\nimport time\nimport random\n\ntotal = 1000\np = progress.ProgressMeter(total=total)\n\nwhile total > 0:\n cnt = random.randint(1, 25)\n p.update(cnt)\n total -= cnt\n time.sleep(random.random())\n\n\nHere is an example of its output:\n\n[-------------------------> ] 41% 821.2/sec\n\n\n2006-02-20 Denis Barmenkov: ANSI codes replaced by Backspace (0x08) characters\n"""\nimport time, sys, math\n\nclass ProgressMeter(object):\n #ESC = chr(27)\n def __init__(self, **kw):\n # What time do we start tracking our progress from?\n self.timestamp = kw.get(\'timestamp\', time.time())\n # What kind of unit are we tracking?\n self.unit = str(kw.get(\'unit\', \'\'))\n # Number of units to process\n self.total = int(kw.get(\'total\', 100))\n # Number of units already processed\n self.count = int(kw.get(\'count\', 0))\n # Refresh rate in seconds\n self.rate_refresh = float(kw.get(\'rate_refresh\', .5))\n # Number of ticks in meter\n self.meter_ticks = int(kw.get(\'ticks\', 60))\n self.meter_division = float(self.total) / self.meter_ticks\n self.meter_value = int(self.count / self.meter_division)\n self.last_update = None\n self.rate_history_idx = 0\n self.rate_history_len = 10\n self.rate_history = [None] * self.rate_history_len\n self.rate_current = 0.0\n self.last_refresh = 0\n self.prev_meter_len = 0\n\n def update(self, count, **kw):\n now = time.time()\n # Caclulate rate of progress\n rate = 0.0\n # Add count to Total\n self.count += count\n self.count = min(self.count, self.total)\n if self.last_update:\n delta = now - float(self.last_update)\n if delta:\n rate = count / delta\n else:\n rate = count\n self.rate_history[self.rate_history_idx] = rate\n self.rate_history_idx += 1\n self.rate_history_idx %= self.rate_history_len\n cnt = 0\n total = 0.0\n # Average rate history\n for rate in self.rate_history:\n if rate == None:\n continue\n cnt += 1\n total += rate\n rate = total / cnt\n self.rate_current = rate\n self.last_update = now\n # Device Total by meter division\n value = int(self.count / self.meter_division)\n if value > self.meter_value:\n self.meter_value = value\n if self.last_refresh:\n if (now - self.last_refresh) > self.rate_refresh or \\\n (self.count >= self.total):\n self.refresh()\n else:\n self.refresh()\n\n def get_meter(self, **kw):\n bar = \'-\' * self.meter_value\n pad = \' \' * (self.meter_ticks - self.meter_value)\n perc = (float(self.count) / self.total) * 100\n return \'[%s>%s] %d%% %.1f/sec\' % (bar, pad, perc, self.rate_current)\n\n def refresh(self, **kw):\n # Clear line and return cursor to start-of-line\n sys.stdout.write(\' \' * self.prev_meter_len + \'\\x08\' * self.prev_meter_len)\n # Get meter text\n meter_text = self.get_meter(**kw)\n # Write meter and return cursor to start-of-line\n sys.stdout.write(meter_text + \'\\x08\'*len(meter_text))\n self.prev_meter_len = len(meter_text)\n\n # Are we finished?\n if self.count >= self.total:\n sys.stdout.write(\'\\n\')\n sys.stdout.flush()\n # Timestamp\n self.last_refresh = time.time()\n\n\n</pre>', 'title': u'Avoiding use of ANSI codes'}, {'comment': u'Cool. On a related note, I created a "spinner"\nto use when you don\'t know how long it will take.<br>\nhttp://www.pixelbeat.org/talks/python/spinner.py', 'title': u'spinner'}], 'desc': u'A simple but useful progress meter for python, rendered in text. '}, {'comments': [{'comment': u'<pre>\nimport os, readline, sys\ntry:\n histfile = os.path.join(os.environ["HOME"], ".python_history")\n if sys.argv[0] == \'-\':\n try:\n readline.read_history_file(histfile)\n except IOError:\n pass\n import atexit\n atexit.register(readline.write_history_file, histfile)\nexcept IndexError:\n pass\ndel os, histfile, readline, sys\n</pre>\n<br>\nThough, this doesn\'t have a size limit or anything. The only difference here is it saves history only when starting python with a \'-\'... (i.e. python -). Oh, and there\'s no tab complete, but that could easily be added. \n<br>\nAlso, in your version, there\'s no reason to keep those variables around, so maybe del\'s would be in order. ', 'title': u'a more compact version... '}, {'comment': u'Here\'s what I use (strikingly similar):\n<pre>\nimport os, readline, rlcompleter, atexit\n\nhistory_file = os.path.join(os.environ[\'HOME\'], \'.python_history\')\ntry:\n readline.read_history_file(history_file)\nexcept IOError:\n pass\nreadline.parse_and_bind("tab: complete")\nreadline.set_history_length(1000)\natexit.register(readline.write_history_file, history_file)\n\ndel os, readline, rlcompleter, atexit, history_file, __file__\n</pre>\n\nThe history file is created on exit if it didn\'t already exist, and readline.set_history_length(1000) limits the number of entries saved.', 'title': u'Another version'}, {'comment': u'Ipython (http://ipython.scipy.org) works on all platforms and does all of the above, and so much more. It is somewhat bigger, of course ;-)', 'title': u'Why not ipython?'}], 'desc': u'This script creates a history file to share between your interactive python sessions, controlling its size in either lines or bytes. You have to put it in your PYTHONSTARTUP environment variable. As it uses readline, it only works under Unix systems. It also binds the tab key to complete words in the shell'}, {'comments': [{'comment': u"Maybe I didn't get something: If I put this into a library and used the library in two completely different programs, wouldn't that permit them to run at the same time? Wouldn't it make sense to include something like sys.argv[0] in the mutex name?", 'title': u'Usage in a library'}, {'comment': u'What about releasing mutex after successful work of instance ?', 'title': u'Release Mutex'}, {'comment': u'You got it right. Mutex name given here is just example, but in real situation, it should be given according to specific needs of your application, program name (sys.argv[0]) or something else.\nWhen I first used it, I used combination of sys.argv[0] and sys.argv[1], because it was allowed to run same program at same time, but only if it is started with different arguments.', 'title': u'Re: Usage in a library'}, {'comment': u'CloseHandle releases the mutex, AFAIK. And, of course, process shutdown should do so anyway.', 'title': u'Releasing the mutex'}, {'comment': u"In destructor, CloseHandle is called on mutex handle and I am not sure is it necessary to call ReleaseMutex explicitly.\nOriginal solution from Microsoft also uses only CloseHandle.<br>\nI am using it like this for long time in C++ programs and now in Python and didn't experience any problems, but would appreciate further comments/suggestions about this issue.", 'title': u'Re: Release Mutex'}], 'desc': u'Sometimes it is necessary to ensure that only one instance of application is running. This quite simple solution uses mutex to achieve this, and will run only on Windows platform.'}, {'comments': [{'comment': u"I'd like to see the visualization you were using. Can you add back in the visual calls?", 'title': u'Where are the vPython calls?'}, {'comment': u'I tried to put some vpython script in a comment window but it was not displayed correctly. Sorry.', 'title': u'The vpython code is in a separate script'}, {'comment': u"<pre>\nfrom visual import * \n\nn = 3\nn2 = n*n\nB = range(n)\nR = range(n2)\n\ndef show_friends(pt):\n for p in full():\n if list(p).count(0) >= 2:\n ball = sphere(pos=p, radius=.2,color=color.white)\n for p in friends(pt):\n ball = sphere(pos=p, radius=.3,color=color.yellow)\n ball = sphere(pos=pt, radius=.4,color=color.red)\n\ndef friends(point):\n x,y,z = point\n res = set()\n for i in R: res.update([(i,y,z),(x,i,z),(x,y,i)])\n a,b = x//n*n,y//n*n\n res |= set((a+i,b+j,z) for i in B for j in B)\n res.discard((x,y,z))\n return res\n\ndef full(): \n return set((i,j,k) for i in R for j in R for k in R)\n\ndef test():\n scene.center = n+1,n+1,n+1\n scene.stereo = 'passive'\n scene.stereodepth = 0\n scene.range = n2+2\n scene.up = -1,0,0\n scene.ambient = .5\n scene.fullscreen = 1\n show_friends((2,3,4))\n \nif __name__=='__main__':\n test()\n</pre>", 'title': u'OK, I found the <pre> tag ...'}], 'desc': u'This script views a sudoku problem as a 3-dimensional binary cube. It solves the sudoku problem by wiping away x,y,z points from this cube until the solution appears.'}, {'comments': [{'comment': u'good one, understood.How to do in Windows ?? ', 'title': u'William B.'}, {'comment': u"Statement 'print sys.path[0]' does what you want, see http://docs.python.org/lib/module-sys.html", 'title': u'Why not use sys.path[0] ?'}, {'comment': u"Well, to get the path + script file do something like: 'print os.path.join(sys.path[0], sys.argv[0])'", 'title': u'addition: full path to running script '}, {'comment': u"As I said there can be many ways,\none of the way is using: sys.path[0] \nsys.path is List of paths..\nTry this in python interpreter\n import sys\n print sys.path # prints out a whole list of python module paths..\n print sys.path[0] # prints out ''\nNow try same as a python script and compare:\n import sys\n print sys.path # prints out a whole list of python module paths..\n print sys.path[0] # prints out cwd\n \n\n ", 'title': u' '}, {'comment': u'In order to understand what is going on with the following short section of code, put it in a file named pwd.py, then do the following:\n<pre>\nmkdir junk\ncd junk\npython ../pwd.py\n</pre>\nYou need to make sure that your current working directory (the cd command destination) is not the same as the directory containing the Python script. After that it is self explanatory except for the .EXE path. Try running the script through PY2EXE first, and this will make more sense.\n<pre>\nimport os,sys\nprint "CWD: ",os.getcwd()\nprint "Script: ",sys.argv[0]\nprint ".EXE: ",os.path.dirname(sys.executable)\nprint "Script dir: ", os.path.realpath(os.path.dirname(sys.argv[0]))\npathname, scriptname = os.path.split(sys.argv[0])\nprint "Relative script dir: ",pathname\nprint "Script dir: ", os.path.abspath(pathname)\n</pre>\n\n', 'title': u'The current directory can be interpreted more than one way'}], 'desc': u'# 1. sys.arg has the script name\n# 2. Although there can be many ways, e.g. os.cwd() but, there is another \n# trick to \n# obtain the Complete URI or Location of the current script. \n# You can argue, os.getcwd() \n# import can give you working directory of the current script\n# Third party Java code calling your script.... ;)\n#'}, {'comments': [], 'desc': u"There has been a receipe already, but not supporting zero terminated 'C' strings. Zerotermination is marked with 'z', number before 'z', say 2z is not supported. You can use 2 'z' positions, however. Set tu=True outputs to [] instead of record."}, {'comments': [{'comment': u'Cool idea :)\nIt should also be mentioned that for recursion level lower than 13000 you can simply use sys.setrecursionlimit(15000) which is faster (but consumes more memory).', 'title': u'sys.setrecursionlimit'}, {'comment': u'I\'m reminded of Steele\'s "Lambda the Ultimate Declarative", which is available here: http://library.readscheme.org/page1.html<br><br>\n\npage 39:<br><br>\n\n"Auslander and Strong discuss a technique for \'removing recursion\' from PL/I programs which LISP programmers will recognize as a source-to-source semi-compilation. The technique essentially consists of of [sic] introducing an auxiliary array to serve as a stack (though the cited paper manages in the example to use an already existing array be means of a non-trivial subterfuge), and transforming procedure calls into GOTO\'s plus appropriate stack manipulations to simulate return addresses. What is astrounding is that this simple trick shortened the size of the example code by 8% and shortened the run time by a whopping 40%! They make the reason clear: "the implmentation of the recursive stack costs PL/I 336 bytes per level of recursive call ..." The GOTO\'s, on the other hand, presumable compile into single branch instructions, and the stack manipulations are just a few arithmetic instructions.<br><br>\n\n"Even more astounding, particularly in the light of existing compiler technology for LISP and other languages, is that Auslander and Strong do not advocate fixing the PL/I compiler to compile procedure calls using their techniques (as LISP compilers have, to some extent, for years). Instead, they say: "These tehniques can be applied to a program without an understanding of its purpose. Howerver they are complex enough so that we are inclined to teach them as tools for programmers rather than try to mechanize them as an option in an optimizing compiler." The bulk of thier transformations are well within the capability of an optimizing compiler. The problem is that historically procedure calls have received little attention from those who design optimizing compilers; Auslander and Strong how suggest that, since this is the case, we should rewrite all procedure calls into other constructs that the compiler understands better! This seems to defeat the entire purpose of having a high-level language."<br><br>\n\nSo I recommend that this very smart fellow just start working in a language with tail-call optimization, or perhaps he should fix the Python implementation. He\'s clearly to smart to waste his life on such things.<br>', 'title': u'This guy needs to program in a real language, or fix his broken python implementation'}, {'comment': u"Maybe, but you're not too smart to try to attract Lisp converts by flaming them. (It's not working for the RIAA, either.)", 'title': u'catching flies with vinegar'}, {'comment': u"What's the flame? <br><br>\n\nThe stuff I quoted is from 30 years ago. Is there really any excuse for this sort of ass-backwards behavior, given that it was identified as such 30 years ago?<br><br>\n\nI'm not trying for converts. You either want to work with a decent language, or you don't. <br><br>", 'title': u'Which converts?'}, {'comment': u'does stackless python handle this?\n\nseriously, nice hack, but python makes me want to puke my guts up.\n\nwould this be any faster if instead of waiting for grandparency it just waited for stack overflow? something in between?', 'title': u'wow'}, {'comment': u'http://w3future.com/weblog/2006/02/#tailCallEliminationInJavascript', 'title': u'Same thing in Javascript'}, {'comment': u'http://lambda-the-ultimate.org/node/1331#comment-15165\n<br><br>\nIt also works with mutual recursion and handles mixed tail/non-tail calls okay.', 'title': u'A version that uses lazy evaluation instead of exceptions:'}, {'comment': u'Sorry Sjoerd, whoever you are! -- I used bugmenot.', 'title': u'p.s.'}, {'comment': u'The exception thrown needs to include the function to be called, so when an exception is handled, not only are the arguments updated, but the function to be called next as well.\n<br>\n<br>\nI wrote about it here (link to updated source included):<br>\nhttp://the-dubois-papers.blogspot.com/2006/03/python-tail-call-decorator.html', 'title': u'Fix to support mutual tail recursion'}], 'desc': u'This decorator implements tail call optimization through stack introspection.'}, {'comments': [{'comment': u'Trying to do this with Python 2.4 has the following traceback:\n\n<pre>\nimport logging\nimport xlog\n\nlogging.basicConfig(level=logging.DEBUG,\n format="%(name)s %(levelname)s %(message)s in %(funcname)s",\n filename=\'UtilTest\' + \'.log\',\n filemode=\'w\')\n\nTraceback (most recent call last):\n File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/logging/__init__.py", line 729, in emit\n msg = self.format(record)\n File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/logging/__init__.py", line 615, in format\n return fmt.format(record)\n File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/logging/__init__.py", line 406, in format\n s = self._fmt % record.__dict__\nKeyError: \'funcname\'\n\n</pre>', 'title': u'Python 2.4 Error'}, {'comment': u'Solution:<br>use a named logger instead of the root logger:\n<pre>\nlogging.getLogger("somename").error(...)\n</pre>\n\nExplanation:<br>\n\nThe extended logger class is only used for loggers that haven\'t been created yet. The root logger (what you get with getLogger() or getLogger(\'\')) is instantiated before the default logger class can be changed.\n<br><br>\nHope this helps...', 'title': u'That happens when you use the "root logger"'}], 'desc': u"Adding new format specifiers to the logging module.\nIn this example, it's for the user name and the name of the function that logged the message."}, {'comments': [], 'desc': u'When offering an MP3 file for downloading, usually two files are stored in the server: the .mp3 file itself, and a small playlist file (.m3u) which tell the mp3 player to stream the .mp3 file. \nThis script avoids the need of storing an .m3u file for each .mp3 file. It serves an .m3u playlist "file" to the client, created on the fly.\nYou can test this script in the site of community radio KGNU; go to http://kgnu.org/ht/listings.html and click on any "Listen" icon.'}, {'comments': [], 'desc': u'Very simple way to interact with python via http.'}, {'comments': [], 'desc': u'This recipe will open a certain URL approximately every 0.5 second using your default browser. It continues to do so until a timeout occurs which has been specified (like the URL) by the user in number of minutes. The timeout starts a reminder that ends once the program has received input. The program then pauses until a key is struck or exits if ESC is pressed.'}, {'comments': [{'comment': u"I'd prefere to get rid of that os.system call by doing\n\n<pre>\nimport time, sys\n\ndef main():\n status, key = 0, ['|', '/', '-', '\\\\']\n while True:\n print '.' * (status / 8) + key[status % 4] + '\\r',\n sys.stdout.flush()\n status += 1\n time.sleep(0.1)\n\nif __name__ == '__main__':\n main()\n</pre>", 'title': u'Improvement'}, {'comment': u'<pre>\nThe list of strings is a bit artificial. Plain string will do the job just as well.\nThe print command adds an extra space. sys.stdout.write does\nnot have this problem.\nFinally the recipy may be themable! Try the themes below.\n(No I will not test the code in WinDoze)\n\n#! /usr/local/bin/python\nimport time, sys\n\nrotor = "|/-\\\\|/-\\\\"\nbaloon = " .oO@@Oo. "\nsquare = " _uUOOUu_ "\ndash = "_-=##=-_ "\nrotor2 = "3WEM"\nw = sys.stdout.write; f = sys.stdout.flush\n\ndef main(them):\n status = 0; n = len(them); n2 = 3*n\n while True:\n w(them[status % n]); f()\n time.sleep(0.1)\n status += 1\n\tif not (status%n2): w(\'\\b.\')\n\telse: w(\'\\b\')\n\nif __name__ == \'__main__\':\n# main(rotor)\n main(baloon)\n# main(square)</pre>', 'title': u'Themes'}], 'desc': u'This recipe has a similar objective to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473899, but was not derived from it. This recipe was written before the aforementioned recipe was submitted to this Cookbook. The purpose of this demo is to illustrate showing the status of an operation to a user in an ASCII environment.'}, {'comments': [{'comment': u'How would I do to make the background an image rather than just a background colour?', 'title': u'Image as a background, not a colour'}], 'desc': u'This recipe demonstrates the use of the Python Imaging Library to apply a gaussian blur drop shadow to an image.'}, {'comments': [], 'desc': u'This recipe is a command line alarm. If not used correctly, usage information is printed. If an exception is thrown, details on the exception are printed out, though in a format most useful for a programmer. The program has no built-in way of being shutdown, so such actions must be executed externally.'}, {'comments': [], 'desc': u'Windows supports a clipboard format called "HTML Format". This format allows various fragments of html formatted text to be copy and pasted between applications. This code implements that protocol.'}, {'comments': [{'comment': u"I think it's worth noting that this also makes it easy to update the closure variables since they're attributes of the function:\n<pre>\n>>> cnt_a = get_counter_neat()\n>>> cnt_a()\n1\n>>> cnt_a()\n2\n>>> cnt_a.x = 10\n>>> cnt_a()\n11\n</pre>", 'title': u'Updating closure variables'}, {'comment': u'Probably this is what you want:<br>\n<br>\ncnt_a = get_counter_neat()<br>\ncnt_b = get_counter_traditional()', 'title': u'Possible fix'}], 'desc': u'Alternative notation for defining closures in python; It avoids packing closure variables into containers by assigning attributes to the inner function.'}, {'comments': [{'comment': u'<pre>\ndef perm(items, n=None):\n if n is None:\n n = len(items)\n for i in range(len(items)):\n v = items[i:i+1]\n if n == 1:\n yield v\n else:\n rest = items[:i] + items[i+1:]\n for p in perm(rest, n-1):\n yield v + p\n\ndef comb(items, n=None):\n if n is None:\n n = len(items) \n for i in range(len(items)):\n v = items[i:i+1]\n if n == 1:\n yield v\n else:\n rest = items[i+1:]\n for c in comb(rest, n-1):\n yield v + c\n</pre>', 'title': u'Much simpler and clearer version'}], 'desc': u'The usaual way to solve these problem is to inflate a huge list, thus it need a lot of memory. These two enumerator take a different approach. It use a linklist to imitate permutations, a binary tree to imitate combination. Thus the program can spit out the result one by one.'}, {'comments': [{'comment': u'You might be interested in comparing the two.\n\nhttp://twistedmatrix.com/projects/flow/documentation/howto/flow.html', 'title': u'This is quite similar to Twisted Flow'}], 'desc': u'Shows how you can yield out of nested function calls. The version here works with methods.'}, {'comments': [{'comment': u'These are two implementations of the Euclidean algorithm, which is probably the most efficient for finding the GCD of two integers a and b.\n\nA recursive version:\n<pre>\ndef gcd(a, b):\n if b == 0:\n return a\n else:\n return gcd(b, a % b)\n</pre>\n\nAnd a looped version.\n<pre>\ndef gcd1(a, b):\n while a != b:\n if a > b:\n a = a - b\n else:\n b = b - a\n return a\n</pre>', 'title': u'These might be a little more efficient.'}, {'comment': u'Perhaps, but the point of the _extended_ euclid GCD function is to find a multiplicative inverse.<br><br>\n\nSay a and b are coprime, and (d, i, j) = egcd(a,b). d will be 1, and (a*i)%b == 1 . This is a very useful calculation for the RSA cryptosystem.', 'title': u' '}, {'comment': u'The egcd() method that he provides is actually (i, j, d) and not (d, i, j).', 'title': u' '}, {'comment': u"I don't know if this is more efficient, but following the code in http://www.geocities.com/hjsmithh/Numbers/GCDe.html gives me:\n\n<pre>\ndef egcd(a, b):\n\tu, u1 = 1, 0\n\tv, v1 = 0, 1\n\tg, g1 = a, b\n\twhile g1:\n\t\tq = g // g1\n\t\tu, u1 = u1, u - q * u1\n\t\tv, v1 = v1, v - q * v1\n\t\tg, g1 = g1, g - q * g1\n\treturn u, v, g\n</pre>", 'title': u'alternate version'}, {'comment': u'How can i know wich code is faster? \nGenerally how to that in Python?', 'title': u'thanks but ...'}, {'comment': u'Use the timeit module:\n\n<pre>\n$ cat > egcd1.py\ndef egcd(a,b): # a > b > 0 \n """ Extended great common divisor, returns x , y\n and gcd(a,b) so ax + by = gcd(a,b) """\n \n if a%b==0: return (0,1,b)\n q=[]\n while a%b != 0:\n q.append(-1*(a//b))\n (a,b)=(b,a%b)\n (a,b,gcd)=(1,q.pop(),b)\n while q:(a,b)=(b,b*q.pop()+a)\n return (a,b,gcd)\n\n$ cat > egcd2.py\ndef egcd(a, b):\n u, u1 = 1, 0\n v, v1 = 0, 1\n g, g1 = a, b\n while g1:\n q = g // g1\n u, u1 = u1, u - q * u1\n v, v1 = v1, v - q * v1\n g, g1 = g1, g - q * g1\n return u, v, g\n$ python -m timeit -s "from egcd1 import egcd; nums = xrange(1, 100)" "[egcd(x, y) for x in nums for y in nums]"\n10 loops, best of 3: 89.5 msec per loop\n$ python -m timeit -s "from egcd2 import egcd; nums = xrange(1, 100)" "[egcd(x, y) for x in nums for y in nums]"\n10 loops, best of 3: 77 msec per loop\n</pre>\n\nIf I didn\'t screw that up, it looks like my version\'s slightly faster.', 'title': u'timeit'}, {'comment': u"thanks you, your version is a lot faster.\nwhy to use g ang g1?\n\nthis is better isn't it?\n\n<pre>\ndef egcdweb1(a,b):\n u, u1 = 1, 0\n v, v1 = 0, 1\n while b:\n q = a // b\n u, u1 = u1, u - q * u1\n v, v1 = v1, v - q * v1\n a, b = b, a - q * b\n return u, v, a\n\n</pre>", 'title': u'thanks'}, {'comment': u"That's fine too of course. I was just trying to be as faithful as possible to the link I referenced.", 'title': u' '}], 'desc': u'the function find out the gcd(a,b) as a linear conbination of a anb b,\nax+by=gcd(a,b). Please help me if you can.'}, {'comments': [], 'desc': u'A regular expression that matches Python string literals. Tripple-quoted, unicode, and raw strings are supported.'}, {'comments': [{'comment': u"<pre>\ndescription=HI+102&start=01%2F16%2F06&end=04%2F28%2F06&sunday=&monday=13%3A00+-+13%3A50&tuesday=10%3A00+-+10%3A50&wednesday=13%3A00+-+13%3A50&thursday=10%3A00+-+10%3A50&friday=13%3A00+-+13%3A50&saturday=\n</pre>\nThe previous query string works for me, and many query strings will work, but it has been demonstrated (by adding another year to the end date) that this recipe is incomplete. It seems that the following line has a problem with it.\n<pre>\nnow = time.strptime(str((month / 12) % 100).zfill(2) + ' ' + str(month % 12) + ' 01', '%y %m %d')\n</pre>\nThe problem has not yet been solved.", 'title': u'Oops'}, {'comment': u'The most current version of this program should now work correctly.', 'title': u'Corrected'}], 'desc': u'This CGI program is designed to create schedules once given valid information on a form.\nIt is not designed to look pretty but tests the ability to combine custom modules in different sized projects.\nIt has minimal functionality but gets its job done in a timely manner and in a format that can be understood.'}, {'comments': [], 'desc': u'Presented here are two modules, "html_help" & "Zam".\nBoth modules contain two classes.\n\n"html_help" contains "html_table" and "html_month".\nA html_table produces tables with a readable format.\nA html_month is just a logical extention of the html_table.\n\n"Zam" contains "array" and "matrix".\nAn array is 1D list with fixed sized and mutable internals.\nA matrix is the same except for the fact that it is 2D.'}, {'comments': [{'comment': u'Thanks!', 'title': u'cool!'}, {'comment': u'I just modified the recipe to support terminals like OS X that use setaf/setab instead of setf/setb.\n\n-Edward', 'title': u'Added support for OS X'}, {'comment': u'My terminfo states, that the capability name for HIDE_CURSOR should be "civis" and not "cinvis".', 'title': u'Typo in capability name'}], 'desc': u'The curses module defines several functions (based on terminfo) that can be used to perform lightweight cursor control & output formatting (color, bold, etc). These can be used without invoking curses mode (curses.initwin) or using any of the more heavy-weight curses functionality. This recipe defines a TerminalController class, which can make portable output formatting very simple. Formatting modes that are not supported by the terminal are simply omitted.'}, {'comments': [], 'desc': u'For simple tasks, locks and queues are a cumbersome way to prevent race conditions. Here is a simple technique for temporarily keeping control of the intrepreter to execute a few steps atomically.'}, {'comments': [], 'desc': u"effbot's ElementTree module (http://effbot.org/zone/element-index.htm) is an excellent way to work with XML. It has a lot of incarnations though so distributing code that uses it right now is little bit of a pain. Here is a snippet you might want to use to import one of all the available incarnations -- hopefully the users of your script will have one."}, {'comments': [{'comment': u'Some docstrings and comments would be nice.', 'title': u'Documentation?'}, {'comment': u'It will be nice to have debug/production flag:\n\ndebug: create decorators as specified\nproduction: no checks/empty decorators for speed optimisations', 'title': u'debug/production flag'}, {'comment': u'I added a \'strict\' flag(default = False) for the constructor, which means:\n<br>\nIf \'strict\' is set, there is no way to to suppress the evaluation\n- but if it is not set, the evaluation depends from the __debug__ state of the interpreter. When __debug__ is set, there will be an evaluation. Otherwise, the decorator is replaced by "lambda func: func" - should be fast enough.\n<br><br>\nBest Regards,\nTobi', 'title': u'strict flag'}], 'desc': u'Watchdog((Param_Type1, Param_Type2, ...), Result_Type) returns a function decorator which can easily be applied to functions in oder to check parameter / result integrity.'}, {'comments': [], 'desc': u"Here's a text-based object browser that is helpful when working with big complicated data structures."}, {'comments': [{'comment': u"I'm a newbie and I also made a script for this problem some time ago, but my was far too complicated, and slow :)<br>\nIn windows box 10 queens was calculating 43 hours!!! on Celeron 2,66 (and without preview - only displaying the sum of combinations at the end), so I stoped it without finding a solution...<br>\nSo I started to ask myself: IS PYTHON JUST TOO SLOW? :)<br>\nNow I can learn how to do such things better!!!<br>\nThanx!<br>\nRade", 'title': u'Thanx!'}, {'comment': u'I am very happy that this little program can help you a little. Python is really a very powerful and interesting programming language.', 'title': u'I am very happy on hering that.'}, {'comment': u"I removed all output of the solutions from the suggestion and got<br>\n solutions: 92<br>\n time: 0.502584934235<br>\n\nThen I hacked an other version with<br>\n solutions: 92<br>\n time: 0.0768530368805<br>\n\nI currently fail to list my script here in this html form, it gets mangled somehow. I uses in-situ permutation and skips permutations that don't resolve the left-most conflict.", 'title': u'far from optimal'}], 'desc': u"This is a general method to figuren out all solutions of eight queens. Certainly, it can also solve any number of queens. It's very fast."}, {'comments': [{'comment': u"Hi,<br>\n<br>\nIf you need a similar data structure with high-performance, have a look at pytst, which includes a close_match method which is similar to this feature. pytst uses a Ternary Search Tree index and is implemented in C++, with a SWIG Python wrapper.<br>\n<br>\npytst also include high-performance algorithms for wildcard matches, prefix matches, etc.<br>\n<br>\nUnfortunately, documentation is quite scarce. I'll work on it Real Soon Now.<br>\n<br>\nhttp://nicolas.lehuen.com/index.php/Pytst<br>", 'title': u'High performance alternative'}], 'desc': u'This is more an ease of use subclass of dict - rather then one that uses a lot of dict features. \n\nIf your requested item is in the dictionary (with a key that hashes the same) then it acts as a more or less normal dictionary.\n\nIf on the other hand you are looking for a string that is similar to a key in the dictionary, then the class iterates over all the keys and finds the one that is the closest match.'}, {'comments': [], 'desc': u'This recipe was designed for remotely receiving bug reports. It was written after participating in a programming contest where feedback was not helpful. The concept presented here is a step towards working with Python remotely. As sys.stderr is replaced in this recipe, so sys.stdin and sys.stdout can also be redirect to an alternate source (such as sockets connected to another computer).'}, {'comments': [{'comment': u'If you want to get the same results with less code try this.\n<pre>\nfrom time import clock\ntime = clock()\nwhile clock() - time If you want to get the same results with less code try this.\n<pre>\nfrom time import clock\ntime = clock()\nwhile clock() - time </pre></pre>', 'title': u'Bad Example?'}, {'comment': u"I'm intrigued by the sync concept and would enjoy seeing more convincing examples.\n<pre></pre>\nThe sync(3) part of the example doesn't add anything new or better. Using .join() is the preferred way to wait on multiple threads to terminate. So, if sync is to show its worth, it will have to be with threads that carry-on after synchronization (as in the sync(2) example).\n<pre></pre>\nThe sync(2) part of the example is broken. Potentially, the input thread could mutate the value again before the output thread has a chance to print. This is easily seen if you insert a time.sleep(60) before the print or if you assign a large value to sys.checkinterval(). The RightWay(tm) for this kind of synchronized data passing is to use the Queue module (with a blocking get() before output) or to use a condition variable (with the lock held until after the print).\n<pre></pre>\nThe error with the sync(2) example indicates that syncing is less broadly applicable than suggested. What value is there in syncing if two or more racing threads immediately resume their race after the synchronization step?\n<pre></pre>\nThe answer that springs to mind is where one or more threads create some values or conditions that can then be relied on by all threads as having been done. When the threads resume, the producer can go on to do something else but needs to take care not to alter or overwrite whatever was just produced (as it has no way of knowing when other threads are going to read the value).\n<pre></pre>\nGiven this limitation, Queues or condition variables would always be preferred for handling simple producer/consumer relationships. In contrast, syncing would be of value for more interdependent step-wise relationships where all threads can work in parallel to build on the results of a previous step. For example, in constructing a multi-floor building, threads for framing walls can proceed in parallel but cannot go on to build the next floor until the current level is complete.\n\n", 'title': u'Interesting idea. Example broken. Core concept limited to step-wise parallel ops.'}, {'comment': u"<pre>\nimport os, random, sync, time\n\nSLOTS = 10\n\ndef example():\n def writer(slots, select, stop):\n while True:\n if not random.randint(0, 10 ** 5):\n stop.sync()\n time.sleep(5)\n slots[select] = (slots[select] + 1) % 10\n def reader(slots):\n while True:\n if os.name == 'nt':\n os.system('cls')\n elif os.name == 'posix':\n os.system('clear')\n for slot in slots:\n print slot,\n slots = [0 for slot in range(SLOTS)]\n stop = sync.sync(len(slots))\n sync.thread.start_new_thread(reader, (slots,))\n for select in range(len(slots)):\n sync.thread.start_new_thread(writer, (slots, select, stop))\n sync.sync(2).sync()\n\nif __name__ == '__main__':\n example()\n</pre>\nWhat does it do? This simulates a slot machine with SLOTS number of<br>\nslots where slots stop independently of each other. The slot machine<br>\nautomatically starts up again five seconds after all slots have<br>\nstopped. The last line in the example function is only meant to block<br>\nindefinitely.<br>\n<br>\nWith regards to the original code:<br>\n1. If someone wanted the do_output thread to wait before printing,<br>\nthen they are programming with the possibility that everything from<br>\nget_input might not be printed. It is the programmer's responsibility<br>\nto ensure the correctness of the code written.<br>\n2. Notice that the threading module was NOT imported. By the design of<br>\nthe code, joining was not an option for the threads. That is why<br>\nsync(3) was introduced -- to show a method of synchronizing the<br>\ntermination of threads.", 'title': u'Second Example'}], 'desc': u'This recipe presents the sync class and an example usage. The primary ingredient\nin this recipe are the locks from the thread module. The idea that is followed\nis quite simple. You have a room with a front door and a back door. Threads walk\ninto the front door and out the back door. Your room only has a certain capacity\nfor threads (specified on construction of the room [sync object]) and the back\ndoor is closed. When the room is full, the front door is closed; and the back\ndoor is opened. When the room has been emptied, the front door is opened; and\nthe back door is closed. In this way, you know that all of your threads pile\ninto a room; and that when they all arrive, they will all exit concurrently with\neach other. The example function shows two different sync objects being used in\ndifferent roles.'}, {'comments': [], 'desc': u'This recipe generates a dynamic icon (2 vertical, 5 segment bar graphs) in the system tray.'}, {'comments': [], 'desc': u'Sometimes, especialy if you are working with database object mappers, you encounter deeply nested dictionaries. You want to access a particular leaf item and you have in your hand the long, decorated, name. reduce can be your friend!'}, {'comments': [{'comment': u"While I likely won't be using your recipe specifically, knowing how to open the raw disk on Windows is terribly convenient.", 'title': u' '}], 'desc': u'This recipe will display a hex dump of the disk specified on the command line. As the last two arguments, the program takes the first sector and last sector that should be displayed by this utility. The size of the sectors is stored in a variable created right after the imports executed by this script. The main feature of this recipe is its cross OS capabilities as demonstrated in get_data.'}, {'comments': [], 'desc': u"Many programs need a set of initial data. For ease of use and flexibility, design a mini-language for your input data. Use Python's superb text handling capability to parse and build the data structure from the input text."}, {'comments': [], 'desc': u'Queue subclass to simplify working with consumer threads. Keeps a count of tasks put into the queue and lets the consumer thread report when each task has been retrieved AND PROCESSED COMPLETELY. This reporting supports a join() method that blocks untils all submitted tasks have been fully processed.'}, {'comments': [], 'desc': u'AWK is a text processing language that makes it easy to "search files for lines [...] that contain certain patterns. When a line matches one of the patterns, awk performs specified actions on that line." (GNU Awk User\'s Guide)\nThis recipe provides a way to do the same thing in python.'}, {'comments': [{'comment': u"I didn't try your algorithm, I just browsed it quickly; since I have a similar algorithm (in my case, it was nighttime-downloading of update packages in rpm format and then splitting them to record on CD's --DVD's weren't that popular then), I believe that you could have more accurate results if you round up the file sizes in sector granularity (ie, size = (size+2047)//2048 )", 'title': u'Minor detail'}, {'comment': u"I try to run your script, and found these issues:\n<br>\n<br>\n1. the best match writes at top of list, so I must scroll console back (on Linux) or run script with some paging program (Windows) to see best match. My decision for this script: reversed(collections) on last loop (requires Python 2.4); \n<br>\n<br>\n\n2. user must specify each item on command line, unhelpful;\n<br>\n<br>\n\n3. grouped items printed as one big line, it kills my eyes ;) ;\n<br>\n<br>\n\nThank you for reminder, I'll publish my script for this job here later.\n", 'title': u'trying...'}, {'comment': u"At some point I was considering adding a block size option, but then I realized that there was the issue of what to do with directories and gave up, but then again you're right: it would be more accurate.", 'title': u'Granularity'}, {'comment': u"As you may have guessed, the program is fitted to my usage pattern, which is (in Linux) always something like:\n\n<pre>\n$ cd /dir/to/stuff/to/burn/in/dvds\n$ mixnmatch.py *\n4482695104 95.38% xxx yyy zzz \n4480609827 95.33% xxx aaa bbb\n4397360001 93.56% xxx ccc\n...\n$ growisofs -Z /dev/dvdrw xxx yyy zzz\n</pre>\n\nSo I always select the items from one of the top lines and paste it back on the command line. I admit a GUI would be nice, but providing one is a tad beyond my intents.\n<br>\nNevertheless, reverse sorting is a good idea. It's just a matter of taking away the minus sign in\n<pre>\ncollections.sort(lambda (xsize, xnames), (ysize, ynames): -cmp(xsize, ysize))\n</pre>\n\nI shall post later an updated version of the script with after gathering all the feedback.", 'title': u'Usability'}, {'comment': u'This program crashes badly if there is a symbolic link whose target does not exist. ', 'title': u'symlink problem'}], 'desc': u'Python script to figure out how to best fit a collection of data into a container (such as a DVD) while avoiding to waste free space.'}, {'comments': [{'comment': u'more natural syntax for pipes:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/276960', 'title': u' '}, {'comment': u"I've seen that code before. The only problem is very time you need a to include a new utility you need to write the function for it.", 'title': u' '}], 'desc': u'Allows arbitrary number of commands to be strung together with each one feeding into the next ones input. Syntax is simple: x=pipe("cmd1", "cmd2", "cmd3").read() is equivalent to bash command x=`cmd1 | cmd2 | cmd3`.\n\nWorks under python 2.4.2'}, {'comments': [{'comment': u"This was very useful for me. I'm modifying the gnatsparse script that comes with Bugzilla. GNATS users are listed in a firstname.lastname format, and the bug reporter can be any email address or alias. With this, I can look up all that information and make sure to pick a real user. Very cool!", 'title': u'Thanks!'}, {'comment': u"I need to extract all smtp addresses from AD, and this looks like it will do that, but I don't know anything about Python. Is this something I have to purchase to be able to use? Is there a runtime version or something? Thanks for any help.", 'title': u'Question about this script'}, {'comment': u'Hi, this can be a useful scrip, how do i use it?\n\nAlso, i would really appreciate if you could explain a little bit how the scripts works.\n\nThanks\n\nRezuma', 'title': u'cool, how do i use it?'}, {'comment': u'This scripts is really great..\n\nQuestion:\nhow can I change the query from CN=Users of Active Directory to MyBusiness/Users/SBSUsers ?\n\nWith this script I can capture all users from Container Users but I cannot capture the Users from domain.local/MyBusiness/Users/SBSUsers\nOrganizational unit..\n\nplease help\nyou can email me at bobby@seerx.com\n\nThanks', 'title': u'Small Business Users'}], 'desc': u'For Windows Exchange Server running on Windows Server 2000/2003, from Exchange and Active Directory, get all email addresses (and aliases) from all active users.\nUses ASDI scripting, LDAP paths to get user info from Active Directory.\nUses Pythonwin'}, {'comments': [{'comment': u'a couple of the Dev\'s on Gnokki didn\'t like their direction so they split and made "Gammu"\n\nThey then wrote python binds for it to make making the GUI very easy\n\nhttp://cihar.com/gammu/python/', 'title': u'A python bind already exists'}], 'desc': u'gnokii is a tool allowing Nokia cellphone users to browse its content, when connected to a computer through a cable, IR or bluetooth. This simple script brings lots of automatization of this process.'}, {'comments': [{'comment': u"<pre>\nfrom mapper import star_map\n\ndef main():\n # define and store the maps\n map_list = create_map_list()\n # create the lists for comparison by combination of twos\n master_list = map_list[:-1]\n secondary_list = list()\n for index in range(1, len(map_list)):\n secondary_list.append(map_list[index:])\n # execute the comparisons\n for index in range(len(master_list)):\n map_a = master_list[index]\n for map_b in secondary_list[index]:\n map_a.find_self_in(map_b, 5) # 5 means that only constellations\n # with 5 or more stars will be found\n\ndef create_map_list():\n map_list = list()\n # dfa_zero (1)\n dfa_zero = star_map('dfa_zero (1)', '-100,-535,2|-102,-267,1|-102,-303,2|\\\n-104,407,1|-105,-246,1|-105,-509,1|-109,-126,1|-118,-306,3|-125,335,1|\\\n-126,-548,1|-127,-383,1|-142,272,1|-143,-272,2|-153,-449,2|-153,-91,1|\\\n-154,-496,4|-169,-19,1|-178,-574,3|-183,-457,1|-191,204,2|-191,584,1|\\\n-194,-106,2|-20,-371,1|-200,-163,1|-203,429,3|-209,344,1|-215,-454,1|\\\n-217,293,1|-219,324,2|-220,147,1|-230,447,1|-233,-562,1|-238,-36,2|-238,284,1|\\\n-239,-438,2|-240,-54,1|-242,-172,2|-244,378,3|-245,-12,2|-251,583,1|-254,536,2|\\\n-257,-446,1|-257,72,3|-259,149,1|-260,15,1|-265,197,1|-266,-541,3|-267,-246,1|\\\n-268,-98,4|-27,-505,1|-274,65,1|-275,-573,2|-277,-522,3|-280,-373,2|\\\n-285,-486,3|-289,-542,2|-289,362,2|-292,-227,1|-296,-3,1|-297,511,3|-298,173,1|\\\n-299,590,3|-3,428,1|-305,-392,3|-307,544,4|-312,67,1|-316,337,1|-317,-137,2|\\\n-321,-342,1|-327,60,1|-331,219,1|-331,266,1|-331,402,2|-332,502,1|-334,-585,2|\\\n-338,355,2|-356,-333,1|-363,390,1|-368,-190,2|-375,-435,1|-375,38,1|-378,487,2|\\\n-396,-252,2|-397,410,1|-399,451,2|-404,11,5|-406,-501,2|-41,-580,2|-410,-564,1|\\\n-416,300,2|-418,-465,6|-418,554,1|-424,506,1|-428,-271,3|-431,-126,1|\\\n-431,400,4|-435,-302,1|-440,-372,3|-459,-304,1|-467,-410,1|-471,-360,1|\\\n-471,56,1|-479,192,2|-481,-89,2|-483,-151,1|-483,509,2|-486,377,1|-489,-451,1|\\\n-495,-528,1|-497,276,3|-497,319,2|-503,583,1|-505,24,1|-506,-414,1|-519,242,2|\\\n-52,22,1|-521,148,1|-529,299,2|-53,-13,1|-531,-1,2|-532,-549,1|-532,77,1|\\\n-537,-354,1|-539,563,4|-543,-16,3|-544,-382,1|-549,388,1|-564,-565,1|\\\n-57,-354,1|-570,-107,1|-573,316,1|-575,-353,2|-580,401,1|-583,-274,1|\\\n-590,-590,1|-590,590,1|-66,116,1|-68,487,1|-75,83,6|-79,65,3|-90,-133,2|\\\n-92,-201,3|-92,371,3|-98,-58,1|0,366,4|105,497,2|112,-44,6|112,261,1|113,136,1|\\\n114,-457,2|115,409,2|12,47,1|120,310,1|125,-351,1|126,483,6|135,520,3|\\\n14,-341,1|153,359,1|161,37,1|162,-305,6|162,-408,4|166,155,2|17,533,4|\\\n170,-145,2|175,-65,2|178,50,1|18,314,1|185,150,1|186,350,4|190,-314,1|\\\n195,485,2|198,-32,3|222,-61,1|224,-557,1|224,491,3|232,-77,2|235,70,1|\\\n239,-212,1|240,436,1|247,-344,1|247,487,1|249,-494,1|25,-482,1|251,-539,1|\\\n257,221,1|262,-6,1|263,-573,1|264,23,1|265,174,2|288,-306,6|290,408,2|3,562,3|\\\n30,177,1|302,298,1|303,-315,2|307,-127,1|307,-279,5|310,501,3|32,481,1|\\\n332,100,2|346,-386,3|346,340,2|352,515,1|359,-190,1|36,-157,3|361,183,1|\\\n368,276,2|372,82,1|376,-118,2|377,119,2|378,-234,1|382,-507,5|383,-553,2|\\\n386,-476,2|390,-460,2|40,311,1|401,570,1|402,96,1|405,491,1|407,-109,1|\\\n407,-405,2|408,148,1|410,-280,2|420,564,1|424,-56,2|426,119,1|434,421,3|\\\n435,488,3|439,-510,4|456,397,5|458,-186,2|465,538,1|466,-59,1|468,293,1|\\\n469,-415,2|471,-147,2|472,-289,4|472,-77,3|474,-363,1|475,140,2|477,323,6|\\\n481,-255,1|484,-3,1|487,-287,6|494,-341,2|5,-197,1|509,120,6|512,40,1|\\\n515,-479,3|518,-119,2|518,25,2|519,244,3|520,-579,1|521,426,1|530,474,3|\\\n535,527,1|542,12,1|542,489,2|543,-56,1|548,-194,1|554,-150,3|561,-361,2|\\\n569,95,1|570,0,1|576,-105,4|579,-201,6|581,202,1|581,28,1|584,449,2|590,-590,1|\\\n590,590,1|6,498,6|62,-560,1|69,151,1|70,578,2|74,373,2|75,86,1|78,-349,1|\\\n79,-73,1|87,-148,1|93,194,1|99,587,1:')\n map_list.append(dfa_zero)\n</pre>", 'title': u'Example Usage'}, {'comment': u"<pre>\n\n # dfa_zero (2)\n dfa_zero = star_map('dfa_zero (2)', '-103,-352,1|-104,-393,3|-105,312,1|\\\n-106,391,6|-107,-10,2|-107,356,4|-112,-62,1|-112,542,2|-126,-368,3|-126,558,2|\\\n-133,443,2|-136,-130,1|-137,-295,1|-14,243,2|-143,-392,1|-146,77,3|-147,-4,3|\\\n-154,462,6|-157,-354,3|-158,-21,2|-161,277,4|-163,-39,1|-173,191,2|-18,178,2|\\\n-187,-364,2|-187,504,2|-188,-516,2|-19,-508,3|-192,79,1|-199,460,2|-200,272,1|\\\n-206,-207,4|-208,-556,1|-209,518,1|-211,-502,2|-214,585,3|-218,386,1|\\\n-22,-246,1|-221,-456,4|-225,287,1|-228,-212,1|-228,80,3|-233,357,1|-234,548,1|\\\n-239,392,5|-245,202,1|-249,-71,1|-250,286,4|-254,-347,3|-258,357,3|-259,-527,1|\\\n-263,251,2|-277,468,2|-277,519,3|-278,-125,5|-280,-218,1|-282,195,4|-285,75,1|\\\n-290,440,1|-292,-310,2|-292,-573,2|-292,398,1|-296,-414,2|-297,574,1|-3,-441,3|\\\n-300,223,1|-308,22,2|-31,209,1|-311,-351,2|-317,526,2|-32,-389,3|-320,477,1|\\\n-320,550,3|-323,-225,1|-334,224,1|-338,563,4|-342,364,1|-348,-270,1|\\\n-353,-300,1|-353,-533,1|-361,-567,1|-365,416,2|-371,-244,1|-377,-181,3|\\\n-377,-463,2|-379,545,2|-38,54,2|-380,463,1|-381,210,1|-381,306,1|-384,-135,1|\\\n-384,389,1|-385,38,1|-388,287,2|-397,151,1|-40,568,1|-409,-256,6|-415,406,1|\\\n-418,-585,1|-420,-231,3|-425,65,2|-427,-563,2|-431,370,1|-433,118,1|\\\n-434,-425,1|-440,91,4|-443,240,2|-445,214,2|-446,52,2|-458,-349,1|-459,-585,2|\\\n-47,225,3|-472,589,1|-48,74,2|-485,464,1|-494,313,1|-495,-371,3|-504,504,2|\\\n-506,-62,1|-512,193,1|-512,457,2|-529,458,1|-536,-106,1|-537,94,1|-539,-205,2|\\\n-543,-367,1|-549,-493,6|-553,390,6|-558,80,1|-561,-272,1|-572,-461,1|\\\n-575,143,1|-584,23,1|-584,429,2|-587,-534,2|-588,477,3|-590,-590,1|-590,590,1|\\\n-62,-326,1|-71,226,1|-72,-550,1|-73,-476,1|-78,332,1|-81,79,2|-86,468,1|\\\n-9,381,1|-97,-374,2|-97,46,2|-99,83,1|0,425,2|10,-575,2|101,225,1|105,210,1|\\\n108,-494,1|109,-301,2|109,552,1|11,-524,1|112,-463,2|116,-404,1|118,-52,2|\\\n128,30,3|130,534,2|132,415,1|147,-463,5|153,345,1|156,412,2|157,146,3|159,-6,3|\\\n16,-442,6|16,429,4|18,214,2|18,297,3|181,-577,6|183,-109,3|183,418,2|19,121,2|\\\n192,-197,4|196,459,2|198,60,1|200,-329,5|202,-398,2|205,-70,2|205,128,1|\\\n213,231,3|219,-337,2|220,9,2|227,-176,2|228,531,2|234,-254,1|236,-69,1|\\\n241,568,1|247,117,1|248,386,5|26,-556,1|267,359,1|271,-543,3|272,-178,1|\\\n274,-466,3|275,-321,2|283,-276,2|285,-577,2|287,145,4|292,555,1|294,429,1|\\\n3,-170,3|3,-343,2|300,-442,4|307,83,1|308,-355,1|310,-105,1|313,-586,4|\\\n320,-340,3|326,107,2|327,-563,1|332,561,2|340,454,1|35,428,3|353,-194,4|\\\n359,-70,1|370,-469,3|375,-278,1|377,448,3|380,-3,1|382,-572,5|382,324,2|\\\n397,63,1|398,241,6|399,-297,2|402,125,2|403,-189,1|404,433,1|406,-485,2|\\\n406,400,1|409,-556,1|419,305,1|423,155,4|426,-264,1|431,1,2|431,343,1|\\\n441,244,2|442,364,2|443,448,4|446,-316,1|45,-423,1|451,260,1|454,-29,2|\\\n465,-534,6|467,511,6|468,-128,2|473,571,1|474,-324,6|474,-49,1|480,37,2|\\\n49,292,1|492,-393,5|493,421,2|497,-53,3|503,191,2|504,-507,2|508,-17,1|\\\n512,-403,1|521,-472,1|522,-259,1|525,422,1|528,-126,2|531,-229,2|540,-348,1|\\\n546,439,3|547,-29,4|549,587,1|551,255,1|556,231,1|560,341,1|562,-512,2|\\\n573,196,2|576,481,4|579,-480,6|583,77,1|585,-424,1|59,311,1|590,-590,1|\\\n590,590,1|61,191,1|63,576,4|69,-7,5|8,88,2|82,-151,1|82,-207,1|9,490,1|\\\n97,-237,1:')\n map_list.append(dfa_zero)\n # dfa_zero (3)\n dfa_zero = star_map('dfa_zero (3)', '-10,-23,2|-104,-408,1|-106,241,1|\\\n-110,-450,4|-115,-428,1|-12,-313,1|-124,-161,1|-130,-480,1|-130,37,1|\\\n-131,-186,1|-133,294,1|-134,486,1|-15,549,1|-153,456,1|-154,208,1|-166,-60,1|\\\n-166,245,1|-168,533,1|-170,-360,5|-171,-216,3|-171,550,1|-172,451,1|-179,46,1|\\\n-18,59,1|-186,97,1|-208,-487,1|-210,-315,1|-211,-216,3|-213,-133,1|-218,-87,1|\\\n-225,-465,1|-228,-205,1|-232,-112,1|-238,14,1|-240,-500,2|-241,-268,1|\\\n-242,346,1|-246,32,1|-250,-420,1|-251,-186,1|-254,131,1|-26,391,3|-267,477,1|\\\n-273,-205,1|-275,-105,1|-275,63,1|-284,253,1|-284,460,1|-285,-236,1|\\\n-291,-156,1|-295,286,1|-30,540,2|-305,-471,1|-308,439,1|-31,-286,1|-320,294,1|\\\n-320,454,1|-326,-48,2|-326,112,1|-328,-448,1|-342,-59,1|-344,311,1|-3", 'title': u'Example Usage Code Continued'}, {'comment': u"<pre>\n # Jemaime77 (1)\n Jemaime77 = star_map('Jemaime77 (1)', '-103,-515,2|-110,150,1|-117,128,1|\\\n-119,-322,1|-119,66,3|-12,338,1|-120,552,1|-128,-162,1|-128,396,1|-136,62,1|\\\n-137,-199,5|-14,-305,2|-140,581,1|-141,-79,1|-145,-236,2|-149,-394,1|\\\n-150,244,1|-151,436,1|-153,535,1|-156,554,1|-16,-555,4|-163,-308,1|-166,-519,1|\\\n-169,-279,4|-186,-325,1|-186,-49,4|-187,126,2|-188,-146,1|-189,263,4|\\\n-190,481,2|-20,-140,1|-200,406,6|-226,-340,1|-228,197,2|-229,-476,1|\\\n-230,-320,1|-230,546,1|-236,82,1|-241,299,3|-241,516,2|-249,-270,4|-250,-308,2|\\\n-252,214,1|-256,-165,1|-26,-34,1|-268,-542,3|-274,-577,5|-282,558,2|\\\n-289,-493,1|-292,329,3|-294,500,1|-299,-454,1|-314,-149,3|-314,-439,2|\\\n-314,349,1|-315,-552,4|-316,-4,2|-318,109,2|-318,284,6|-321,176,4|-325,-470,2|\\\n-330,22,1|-333,-582,1|-336,-438,2|-338,563,1|-342,-531,6|-351,-191,2|\\\n-352,-421,1|-359,-260,1|-360,-578,2|-361,-544,1|-364,198,2|-367,155,2|\\\n-369,-111,2|-37,180,2|-370,-143,2|-371,-347,1|-382,567,6|-386,535,1|-395,3,2|\\\n-397,-42,2|-403,-371,1|-421,155,2|-423,-53,1|-427,-75,1|-428,-331,1|-430,49,2|\\\n-430,492,1|-432,128,2|-447,293,1|-453,-440,1|-459,388,1|-461,-390,1|-462,18,3|\\\n-470,432,1|-477,41,1|-48,-219,1|-480,-176,2|-491,-4,6|-5,461,2|-50,539,3|\\\n-500,228,1|-501,-163,1|-505,-285,1|-513,-14,4|-515,439,2|-531,-521,1|\\\n-532,-579,1|-533,97,3|-535,-237,1|-535,-308,2|-539,14,1|-540,-195,1|-548,197,1|\\\n-549,-46,6|-55,92,2|-562,86,3|-566,468,2|-567,189,1|-568,-179,1|-583,-22,4|\\\n-583,-248,4|-585,33,2|-590,-590,1|-590,590,1|-61,-412,2|-69,-233,1|-70,-51,3|\\\n-77,118,1|-78,-3,1|-85,-104,2|-86,-276,1|-90,-463,3|-92,444,1|-95,202,1|\\\n101,182,4|101,522,1|106,-167,1|106,291,1|106,448,1|109,-136,1|111,-535,1|\\\n111,-70,1|125,-339,2|128,278,2|128,555,1|131,156,1|131,332,1|133,-122,4|\\\n14,41,4|140,186,1|143,234,2|145,217,3|15,366,1|150,10,2|151,33,1|154,-428,1|\\\n180,-240,6|184,278,1|189,-172,1|190,-542,1|190,384,1|194,-42,2|20,-156,4|\\\n200,342,3|208,-230,2|21,246,1|212,382,2|22,-529,1|223,-579,1|223,130,1|\\\n225,169,1|228,-352,1|236,-516,1|240,-458,1|240,138,1|246,-485,5|248,-389,5|\\\n25,496,1|250,454,1|258,-309,2|258,122,4|263,-152,2|27,-345,3|27,-583,2|\\\n273,-82,1|278,-235,1|278,289,4|278,96,1|279,16,3|28,110,1|282,370,2|285,225,1|\\\n287,-544,6|289,527,3|297,-118,1|298,-5,1|299,259,1|304,-306,2|313,-336,1|\\\n313,-456,3|313,212,4|318,-85,1|321,-407,1|324,-31,3|325,-301,1|326,6,1|\\\n328,-554,6|329,330,6|333,189,1|335,452,1|338,244,3|34,-552,2|343,-316,2|\\\n343,-430,5|344,-492,2|345,16,2|361,-475,1|37,-147,2|371,234,1|373,-219,2|\\\n373,410,2|381,537,1|383,475,2|384,-487,1|391,353,1|392,-359,1|392,522,2|\\\n393,-12,2|397,-402,6|397,550,1|422,-373,2|427,572,4|429,-254,3|442,124,1|\\\n450,147,1|452,305,1|453,574,2|456,11,1|457,279,2|459,-270,1|468,247,1|\\\n469,-182,2|48,-12,1|488,-326,2|491,100,5|499,-113,2|499,-94,1|501,344,3|\\\n510,216,1|517,477,1|52,-274,1|523,-329,1|529,-356,1|532,-543,1|537,49,4|\\\n54,94,6|545,461,1|547,529,2|551,-582,1|552,58,6|553,291,2|56,-539,1|563,172,1|\\\n564,-423,2|570,-155,4|583,545,2|590,-590,1|590,590,1|6,-217,1|61,-498,1|\\\n73,-179,1|73,-278,1|75,431,3|77,7,1|78,230,2|85,-307,4|85,-383,1|86,518,1|\\\n98,-499,1:')\n map_list.append(Jemaime77)\n # Jemaime77 (2)\n Jemaime77 = star_map('Jemaime77 (2)', '-1,-246,2|-107,-200,1|-13,31,1|\\\n-13,361,2|-137,-36,1|-14,428,1|-140,-181,1|-143,321,3|-145,550,1|-148,-92,1|\\\n-156,-62,2|-158,-511,1|-159,79,1|-165,-306,1|-166,-586,3|-167,54,1|-172,448,1|\\\n-175,387,1|-182,-368,1|-188,238,1|-193,-487,1|-195,-129,1|-196,-338,1|\\\n-197,214,1|-198,-239,1|-206,431,1|-212,-509,1|-213,-375,1|-216,-532,1|\\\n-216,-82,2|-219,274,1|-220,256,1|-225,352,1|-226,-490,1|-227,458,1|-227,588,1|\\\n-23,321,1|-232,-448,2|-236,-212,1|-237,419,1|-241,-387,1|-248,513,1|\\\n-249,-358,1|-250,-161,1|-252,-408,1|-260,-456,1|-272,-438,6|-276,-92,1|\\\n-277,560,1|-280,305,2|-281,421,1|-283,102,1|-285,-394,1|-286,439,1|-288,-65,1|\\\n-296,24,1|-3,-19,1|-300,245,3|-308,364,1|-312,-318,2|-313,195,1|-321,-585,1|\\\n-323,-430,1|-329,387,1|-33,-149,1|-33,231,1|-344,-237,1|-346,-122,3|-347,21,1|\\\n-347,555,1|-349,5", 'title': u'Example Usage Code Continued'}, {'comment': u"<pre>\n # elvenscythe\n elvenscythe = star_map('elvenscythe', '-100,305,2|-108,79,2|-11,459,4|\\\n-118,-80,2|-123,516,1|-127,476,2|-128,-486,1|-13,-101,1|-130,395,3|-133,111,1|\\\n-14,90,1|-141,-84,1|-143,138,1|-146,-186,2|-147,436,3|-148,575,1|-149,-68,3|\\\n-156,-116,4|-158,-9,2|-170,477,3|-177,-491,2|-177,498,2|-181,289,1|-181,82,1|\\\n-182,386,1|-185,29,1|-189,-297,3|-20,-144,1|-204,-61,3|-209,-523,1|-21,-183,3|\\\n-215,-431,1|-217,-569,1|-22,-65,3|-229,347,2|-231,260,2|-234,-558,1|\\\n-251,-285,1|-253,-357,5|-257,-419,1|-263,-236,2|-266,-53,3|-27,473,6|\\\n-274,230,4|-277,-451,1|-292,365,1|-297,194,3|-299,150,1|-30,256,4|-303,132,1|\\\n-304,-303,2|-304,212,1|-308,537,1|-311,-145,1|-311,455,1|-313,6,3|-317,373,1|\\\n-320,-420,1|-327,58,1|-330,-206,1|-334,-323,3|-334,322,1|-336,109,1|\\\n-342,-161,1|-346,-291,1|-35,-264,1|-358,267,1|-364,-149,1|-364,463,2|\\\n-369,317,2|-371,182,2|-38,430,1|-385,-220,2|-385,562,1|-389,351,2|-391,184,1|\\\n-392,-237,1|-396,108,1|-404,448,1|-406,151,2|-407,-105,1|-413,-311,2|\\\n-422,-555,6|-426,-434,1|-43,-66,2|-432,-112,1|-433,237,3|-434,-145,2|\\\n-441,442,1|-454,-455,1|-455,24,1|-471,41,2|-473,-352,1|-474,-8,2|-483,-335,2|\\\n-491,-387,3|-495,-167,3|-501,-126,2|-502,-3,1|-508,534,1|-509,-357,2|-51,141,1|\\\n-513,418,2|-52,177,1|-522,-329,6|-528,-290,2|-533,-123,1|-533,230,1|-544,389,2|\\\n-547,-85,1|-548,290,3|-549,-323,6|-549,329,2|-554,-475,3|-554,548,1|-558,-18,1|\\\n-562,-364,3|-577,-252,1|-577,-9,2|-579,339,3|-59,-125,1|-590,-405,1|\\\n-590,-590,1|-590,590,1|-60,-531,2|-62,459,1|-64,-93,3|-67,-364,2|-75,249,1|\\\n-76,528,3|-81,-49,3|-85,504,1|-86,177,1|-9,-466,1|-99,-329,1|12,-195,1|\\\n121,-15,1|123,268,4|126,163,3|133,30,1|134,-403,2|14,-322,6|141,-541,2|\\\n143,393,3|146,429,1|152,491,1|162,-319,1|162,313,3|167,342,2|172,-216,3|\\\n174,-507,1|181,-471,1|183,131,1|184,192,2|185,108,4|191,265,1|193,572,2|\\\n195,-438,1|196,150,1|199,-300,1|2,1,1|202,-90,4|203,208,1|208,-372,1|208,581,6|\\\n215,-539,1|216,-334,1|217,-306,1|217,306,1|219,-187,2|228,-434,1|235,385,1|\\\n235,499,1|24,-453,2|244,123,3|247,428,1|248,-2,1|250,-458,1|250,245,2|\\\n253,523,3|254,-58,4|256,197,1|257,-200,3|261,109,2|263,289,1|263,449,1|\\\n27,-178,1|277,-524,1|280,-70,1|281,-85,2|285,-383,2|285,267,4|291,473,1|\\\n294,-426,2|295,114,3|296,-78,1|30,-259,1|302,224,2|304,-389,1|308,327,1|\\\n309,-360,1|31,-480,1|311,200,2|316,-529,2|316,286,1|319,-230,2|326,-383,2|\\\n329,259,1|346,186,3|357,-412,3|357,287,6|361,199,1|362,494,2|366,-361,1|\\\n39,359,1|392,227,2|4,504,2|405,548,1|410,440,1|413,150,1|414,423,2|414,94,2|\\\n419,-542,1|421,-208,3|421,-525,4|431,100,2|433,281,6|436,-377,1|437,488,2|\\\n444,82,1|445,-162,1|451,-459,1|452,553,1|455,-388,1|457,-480,1|458,-429,1|\\\n464,325,1|471,-498,1|472,-95,1|473,-45,3|477,-8,1|477,60,1|478,146,1|\\\n484,-381,1|486,282,1|487,227,1|49,215,1|497,-442,2|499,-472,6|500,-134,1|\\\n508,-271,3|509,-366,1|513,332,2|519,-445,1|52,583,1|522,44,2|524,292,1|\\\n525,14,2|527,511,1|529,-260,1|536,352,1|538,121,1|54,-137,4|550,586,1|\\\n552,-428,5|558,-17,4|56,-35,2|569,-490,1|577,263,1|581,-344,1|583,343,2|\\\n585,-258,1|587,417,3|59,157,3|590,-590,1|590,590,1|65,-258,3|69,-81,1|73,253,1|\\\n73,297,4|83,-127,1|88,194,1|92,-1,2|92,-187,2:')\n map_list.append(elvenscythe)\n # Raven193\n Raven193 = star_map('Raven193', '-104,253,1|-114,-290,1|-114,-462,2|\\\n-115,-78,6|-118,34,1|-119,-148,2|-119,226,4|-126,-398,1|-132,-226,2|\\\n-138,-365,1|-14,570,1|-140,-182,1|-147,295,1|-149,-234,1|-151,-405,3|\\\n-164,-329,2|-17,258,1|-172,509,3|-180,-582,1|-184,-76,2|-188,-439,1|-189,150,1|\\\n-19,-154,2|-191,-16,1|-192,46,1|-196,-155,2|-200,216,1|-202,111,2|-213,-186,4|\\\n-216,407,1|-217,-219,1|-217,355,1|-217,476,1|-217,64,3|-218,-86,1|-227,250,1|\\\n-232,-159,3|-232,168,3|-234,77,1|-240,-267,1|-247,421,2|-250,230,4|-250,4,3|\\\n-253,23,6|-256,-317,1|-257,-567,1|-265,-545,1|-269,467,1|-27,-336,4|\\\n-271,-308,4|-281,-349,3|-281,-364,1|-282,34,3|-309,-467,4|-309,268,1|\\\n-310,375,4|-320,7,1|-334,79,1|-337,-575,2|-342,-416,1|-342,389,2|-344,-97,1|\\\n-347,-366,1|-348,489,4|-350,-300,2|-360,54,5|-374,-458,1|-376,428,5|-388,", 'title': u'Example Usage Code Continued'}, {'comment': u"<pre>\n # zaught (1)\n zaught = star_map('zaught (1)', '-102,-5,1|-106,275,3|-108,-579,1|-110,325,2|\\\n-110,80,3|-112,-376,1|-114,-241,2|-117,-275,1|-12,177,2|-120,167,2|-121,408,2|\\\n-123,-310,1|-125,-33,1|-132,-387,5|-134,503,2|-135,-559,3|-135,35,1|-138,364,1|\\\n-139,163,1|-145,409,1|-154,-219,1|-157,29,3|-158,-396,1|-159,-77,3|-166,-160,1|\\\n-180,284,3|-185,389,1|-189,235,2|-192,-497,1|-194,-255,4|-194,366,1|-199,-72,1|\\\n-203,-313,1|-203,422,6|-206,-515,1|-209,10,1|-210,465,1|-227,-328,3|-229,80,2|\\\n-233,473,1|-239,-352,2|-240,282,1|-243,53,4|-254,466,1|-255,-552,2|-260,250,2|\\\n-261,-384,3|-263,405,1|-274,-324,1|-278,-218,5|-281,-361,1|-286,-101,1|\\\n-287,248,2|-290,-345,2|-292,-316,1|-293,-127,2|-296,-378,1|-297,382,1|\\\n-30,466,1|-301,-225,2|-305,521,4|-307,2,3|-323,-437,3|-325,-508,2|-333,-36,2|\\\n-334,-458,1|-334,100,4|-344,-315,2|-35,164,3|-350,166,1|-356,-562,1|-356,133,2|\\\n-356,236,2|-359,-467,2|-367,205,4|-371,-273,4|-373,-115,4|-379,-443,1|\\\n-379,498,1|-381,-293,6|-384,-481,1|-386,18,2|-388,205,3|-39,214,1|-393,346,2|\\\n-394,-112,1|-398,371,2|-400,493,1|-408,-165,1|-408,-523,5|-417,412,3|\\\n-433,118,1|-435,138,2|-437,-491,5|-438,87,1|-442,-72,1|-444,-198,2|-450,-155,1|\\\n-453,113,1|-462,-300,3|-465,323,2|-466,529,2|-469,-542,1|-475,-249,5|\\\n-477,-104,3|-481,-559,3|-486,-422,1|-489,470,1|-49,-36,4|-492,302,1|\\\n-496,-440,3|-499,88,1|-500,-50,1|-503,-285,1|-506,-380,1|-507,269,1|\\\n-518,-488,1|-519,-22,3|-528,341,5|-538,-168,2|-538,145,4|-541,-532,1|\\\n-545,-131,2|-55,241,3|-555,-314,1|-555,544,1|-56,-542,4|-560,127,4|-562,94,2|\\\n-563,-540,2|-566,278,1|-568,-348,2|-574,-239,4|-59,532,1|-590,-590,1|\\\n-590,590,1|-63,505,3|-68,479,1|-79,139,1|-8,-249,1|-8,380,5|-83,170,2|\\\n-89,-359,6|-91,-440,2|-93,-480,2|-97,411,2|10,248,3|103,86,3|104,-13,2|\\\n107,272,1|12,514,1|121,164,1|121,241,1|128,279,1|128,331,2|132,-230,2|\\\n134,-30,1|138,399,1|142,-518,1|145,49,3|147,500,1|154,-358,1|156,112,1|\\\n160,441,1|163,358,5|168,28,2|174,-488,4|176,-445,1|180,-277,1|184,73,5|\\\n186,-37,3|187,10,4|191,460,1|196,259,1|199,587,2|205,-543,2|213,-88,2|\\\n214,350,3|215,445,1|216,321,1|220,61,2|243,-279,2|246,-587,2|25,-529,3|\\\n259,-336,1|26,-454,1|263,-400,2|264,373,1|266,-198,1|278,260,1|281,-494,1|\\\n283,589,1|287,188,1|296,293,2|299,517,6|3,30,3|306,-262,3|307,-440,3|308,216,3|\\\n308,24,2|315,461,1|317,577,1|319,376,2|320,-27,1|329,-67,1|329,183,3|33,500,3|\\\n336,405,2|339,-384,2|344,-290,4|346,-356,1|354,-376,1|358,297,1|363,-289,1|\\\n366,122,2|366,96,2|371,-39,3|375,-258,4|377,69,2|383,-482,1|39,548,1|393,170,2|\\\n398,-344,2|399,396,1|4,-452,3|40,-349,4|401,-189,1|401,370,1|404,426,2|\\\n408,194,2|408,73,5|409,271,4|410,89,1|42,-208,3|42,6,3|425,190,1|43,-536,1|\\\n43,231,1|431,473,1|433,259,1|436,-304,2|441,-113,1|441,-570,2|443,-128,1|\\\n457,72,4|460,-350,1|461,-84,2|465,-428,2|467,42,1|469,382,1|472,91,1|\\\n479,-210,1|480,162,1|481,267,1|488,473,1|489,432,1|493,301,2|512,455,3|\\\n528,109,1|528,163,1|531,360,2|533,-313,1|535,3,4|536,180,1|541,505,3|546,217,1|\\\n546,287,1|549,363,2|552,266,1|556,-468,1|556,-501,1|560,-317,2|562,-93,1|\\\n571,-74,3|572,-531,2|576,584,3|590,-590,1|590,590,1|72,-90,4|73,420,3|82,513,1|\\\n88,234,2|99,311,1:')\n map_list.append(zaught)\n # zaught (2)\n zaught = star_map('zaught (2)', '-1,562,1|-106,-399,1|-106,-539,1|\\\n-106,403,1|-111,-256,1|-127,171,1|-133,534,1|-134,496,1|-134,577,1|-140,-457,1|\\\n-145,249,1|-147,356,1|-151,-226,1|-152,-564,1|-154,306,1|-155,-380,1|\\\n-155,209,1|-163,-321,1|-165,119,3|-169,-269,1|-175,382,1|-180,-449,1|\\\n-187,212,1|-19,455,3|-191,-503,1|-192,232,1|-193,-465,1|-195,422,2|-2,-520,1|\\\n-2,9,1|-204,-577,1|-204,259,1|-215,189,1|-218,90,1|-232,-158,1|-233,-419,1|\\\n-238,398,1|-240,-40,1|-244,-219,1|-245,-584,1|-246,196,1|-251,2,1|-251,297,1|\\\n-255,512,1|-263,452,1|-266,285,1|-274,-524,1|-274,77,1|-275,209,1|-283,-380,1|\\\n-295,-90,1|-303,-440,2|-303,525,1|-304,157,1|-31,-286,2|-310,13,1|-312,90,1|\\\n-315,-150,1|-319,-18,1|-322,404,1|-323,215,1|-323,547,1|-325,372,1|-335,452,1|\\\n-336,48,1|-345,-574,1|-346,217,1|-35,513,1|-352,-438,1|-363,-300,1|-", 'title': u'Example Usage Code Continued'}, {'comment': u"<pre>\n # Summernight\n Summernight = star_map('Summernight', '-10,-577,1|-100,-103,4|-105,-41,1|\\\n-106,118,3|-107,-461,2|-108,41,3|-110,433,1|-111,-125,1|-114,231,1|-114,253,1|\\\n-115,-510,4|-119,284,2|-137,-312,3|-137,-411,1|-138,-485,1|-138,276,2|\\\n-14,-217,3|-14,34,2|-142,-569,1|-148,-33,6|-149,-427,6|-15,392,6|-159,12,2|\\\n-161,109,4|-162,266,3|-165,446,1|-167,-188,1|-170,215,1|-187,370,3|-208,-426,3|\\\n-209,-180,2|-222,-326,3|-226,442,1|-227,46,1|-229,572,1|-23,-410,2|-23,293,1|\\\n-244,-257,6|-244,143,3|-244,367,4|-246,-563,1|-246,329,2|-250,161,2|\\\n-257,-301,1|-257,-439,1|-259,208,2|-261,-534,1|-264,-382,1|-264,402,1|\\\n-266,322,1|-270,-341,6|-270,-581,1|-276,-125,3|-277,-37,2|-28,532,2|\\\n-280,-432,1|-287,197,1|-290,140,3|-292,58,2|-293,-214,1|-298,75,1|-30,-233,1|\\\n-303,341,3|-306,-438,1|-308,413,1|-313,442,2|-327,-288,1|-329,-84,1|-33,448,1|\\\n-330,198,1|-344,-346,1|-348,341,1|-353,363,2|-358,209,1|-36,-468,3|-362,-582,1|\\\n-369,476,2|-372,-42,2|-374,161,3|-380,367,2|-385,-65,1|-386,-566,1|-388,-343,1|\\\n-394,-361,1|-401,258,1|-403,-85,3|-407,-429,2|-408,65,3|-409,-327,3|-41,327,1|\\\n-412,393,6|-414,-444,3|-414,555,2|-417,-128,1|-417,130,1|-42,238,2|-421,474,6|\\\n-425,268,3|-43,388,5|-435,-23,4|-439,-5,3|-439,365,1|-443,-382,1|-447,194,1|\\\n-448,-548,2|-449,-275,3|-457,-165,3|-459,433,2|-459,551,1|-469,-278,2|\\\n-470,-307,1|-472,390,1|-473,454,2|-478,-485,2|-483,210,1|-485,-370,1|\\\n-490,107,2|-505,39,2|-506,-121,2|-511,456,3|-512,-482,1|-514,132,2|-516,-440,1|\\\n-520,-275,5|-53,-277,2|-53,284,1|-535,-375,6|-536,-540,3|-539,-229,5|\\\n-539,-430,1|-541,-261,2|-545,564,1|-546,73,2|-554,94,1|-557,-25,1|-559,-159,1|\\\n-559,528,1|-566,321,1|-570,-553,2|-572,-311,1|-577,505,1|-579,-379,3|\\\n-590,-590,1|-590,590,1|-62,249,1|-7,237,2|-7,586,1|-75,588,3|-76,-373,4|\\\n-79,-181,1|-80,147,2|-81,-106,4|-81,-347,2|-81,44,4|-86,269,2|-88,-427,2|\\\n-98,168,4|11,69,6|111,498,1|112,-211,1|13,-109,3|130,-319,1|142,417,1|\\\n143,175,6|146,466,2|147,350,4|150,22,2|151,-395,4|16,383,2|167,112,6|17,-154,2|\\\n17,-419,1|172,-126,4|200,534,2|202,-106,2|202,271,4|216,-85,2|216,85,2|\\\n223,235,3|229,217,2|236,-400,1|236,78,1|24,-91,5|244,218,2|247,-230,1|\\\n254,-257,4|254,468,3|257,-471,3|257,394,1|260,344,2|263,-285,5|266,-365,1|\\\n276,-300,1|277,-469,3|277,118,4|291,-422,6|292,-36,1|297,-314,1|303,266,1|\\\n306,-109,3|317,281,4|321,85,2|323,-261,2|323,465,5|330,330,1|335,-374,1|\\\n336,144,1|341,-111,1|341,427,1|341,452,1|342,-294,1|344,576,1|346,-571,1|\\\n362,-576,1|368,249,4|368,541,1|374,414,1|378,229,4|383,73,3|406,-227,2|\\\n410,177,1|412,-575,1|422,346,2|426,75,2|444,-312,1|446,128,1|45,-364,1|\\\n451,219,2|454,326,1|459,363,1|463,192,1|468,-380,2|471,461,1|475,-118,4|\\\n475,103,1|480,366,1|490,209,1|496,279,1|498,-99,1|503,105,1|505,-534,4|\\\n505,-589,2|505,86,2|507,-421,1|51,472,5|529,510,3|53,-223,1|532,-440,2|\\\n532,23,2|533,-372,1|535,-95,3|536,-317,2|54,-184,1|541,563,2|545,258,2|\\\n547,-583,4|551,243,1|553,303,1|557,-299,1|562,-386,1|568,89,2|576,410,1|\\\n579,133,2|581,-85,2|586,-543,1|587,266,3|590,-590,1|590,590,1|60,-326,2|\\\n60,-38,2|62,-292,3|66,107,2|67,414,2|7,151,2|72,-407,1|78,80,5|85,-170,2|\\\n85,53,2|92,-6,1|94,-110,1|94,-88,2|96,-344,1:')\n map_list.append(Summernight)\n # snwangel1981\n snwangel1981 = star_map('snwangel1981', '-10,505,2|-106,-378,1|-113,500,1|\\\n-114,-338,2|-116,-543,2|-116,214,1|-121,-528,1|-122,229,1|-123,148,6|\\\n-123,454,1|-132,342,1|-137,-138,2|-137,-320,6|-137,-469,1|-14,337,1|-144,378,2|\\\n-153,-448,1|-156,-547,1|-164,-527,6|-169,-46,1|-177,-273,1|-179,-142,1|\\\n-180,210,1|-182,-413,1|-182,14,5|-183,-91,2|-185,-7,1|-186,-547,1|-189,268,2|\\\n-19,5,3|-192,359,1|-195,149,1|-195,284,1|-204,-298,2|-205,-458,1|-207,124,2|\\\n-212,-76,2|-22,574,1|-221,9,2|-228,-8,1|-230,501,2|-231,-469,3|-232,303,4|\\\n-235,-317,6|-247,-93,4|-25,-71,2|-260,-433,1|-260,248,5|-272,-540,1|-279,-43,1|\\\n-279,74,2|-282,-187,2|-288,-374,2|-288,271,3|-289,-203,5|-296,-121,2|\\\n-298,428,2|-30,-296,1|-300,251,1|-305,-176,3|-310,-51,1|-312,204,1|-314,527,6|\\\n-329,356,1|-33,273,1|-337,-307,1|-34,479,2|-345,-81", 'title': u'Example Usage Code Continued'}, {'comment': u"<pre>\n # Ravyn\n Ravyn = star_map('Ravyn', '-105,555,2|-108,-217,2|-110,235,5|-110,587,1|\\\n-114,-531,1|-114,269,1|-118,-234,2|-118,-394,2|-124,-415,1|-13,352,3|\\\n-136,-105,4|-138,522,2|-144,353,1|-147,257,1|-150,-144,3|-150,-532,1|\\\n-151,-585,2|-159,348,1|-160,-493,1|-17,-234,6|-173,147,1|-176,-40,2|-179,103,1|\\\n-185,74,5|-188,-361,1|-19,394,1|-191,-170,2|-194,369,2|-199,129,3|-2,507,2|\\\n-203,-14,2|-228,-414,1|-230,-531,1|-256,-220,5|-257,-364,2|-258,432,1|\\\n-271,-580,2|-273,372,1|-274,-41,1|-277,412,2|-287,200,3|-29,-536,4|-29,440,1|\\\n-291,-557,1|-296,-267,2|-30,291,2|-301,360,2|-311,-453,4|-312,-412,2|\\\n-313,-313,1|-313,503,2|-314,-194,1|-314,-88,2|-320,-215,1|-320,-564,2|\\\n-323,-173,4|-328,-233,1|-33,498,3|-331,580,1|-332,42,1|-339,87,1|-340,-545,2|\\\n-343,485,1|-344,-247,1|-344,-401,2|-350,-228,1|-355,-576,1|-362,571,2|\\\n-365,-355,4|-372,-380,6|-385,368,2|-399,587,1|-403,-556,3|-405,310,1|-41,555,1|\\\n-412,-429,6|-412,343,3|-43,-471,2|-435,-55,4|-436,468,1|-438,288,2|-439,71,4|\\\n-467,536,1|-469,209,3|-478,-554,2|-479,555,2|-483,-275,3|-483,-436,2|\\\n-484,-369,1|-486,-290,6|-486,-39,1|-488,-493,5|-490,437,1|-495,-117,1|\\\n-5,-446,6|-501,-80,1|-510,-590,2|-519,-5,2|-52,66,2|-522,-129,1|-527,-496,1|\\\n-529,244,1|-537,337,3|-537,447,1|-538,-175,2|-539,403,1|-542,-227,2|-546,374,4|\\\n-561,126,1|-562,560,2|-564,-44,1|-564,74,1|-568,32,2|-573,210,1|-576,-183,1|\\\n-58,111,2|-583,-431,1|-590,-590,1|-590,590,1|-590,7,2|-64,-535,1|-75,354,1|\\\n-77,477,1|-81,-523,3|-86,176,1|-88,538,2|-91,-236,6|104,-429,2|105,352,1|\\\n11,-513,1|116,495,2|120,-417,1|120,344,1|123,-515,1|125,327,1|127,-470,2|\\\n129,-121,1|13,-410,1|132,-145,1|141,260,1|160,-294,3|160,-434,1|160,179,1|\\\n162,-64,1|162,564,1|169,-504,1|183,423,2|184,-341,2|185,190,1|19,45,3|\\\n190,288,1|191,139,1|194,-460,4|195,-438,1|207,78,3|211,501,3|216,178,4|\\\n219,-295,1|220,-255,1|220,530,1|224,426,4|235,83,1|236,-477,3|239,210,1|\\\n24,-460,2|24,526,2|243,-126,3|246,-162,1|247,-64,5|249,367,1|255,-302,4|\\\n26,209,3|261,-361,1|27,427,1|276,183,2|276,83,1|278,-66,3|278,99,1|28,-542,1|\\\n280,17,2|280,465,3|292,320,2|298,-308,1|300,-436,1|301,275,1|303,-358,2|\\\n310,-560,3|316,3,1|324,-342,1|325,-399,3|327,-155,2|328,-500,1|33,-170,2|\\\n330,-263,2|332,585,1|334,8,2|335,305,2|336,392,1|34,-487,5|34,120,1|341,52,1|\\\n346,-454,3|349,-510,1|350,-264,2|353,11,1|364,550,1|372,570,2|378,479,1|\\\n382,-71,1|386,-416,3|39,514,2|390,48,1|401,-370,4|406,22,1|409,-20,1|41,-426,1|\\\n410,460,1|415,-48,1|416,-581,3|419,348,1|420,533,2|425,-304,3|429,-399,1|\\\n430,201,3|437,-65,2|441,106,2|445,35,2|447,-88,3|448,-195,1|448,569,1|\\\n465,-435,1|47,282,5|471,-350,6|473,-148,1|476,-571,2|478,396,3|478,548,1|\\\n480,100,1|485,472,2|49,-315,1|495,392,1|496,260,2|5,246,1|500,581,1|505,-77,1|\\\n525,70,1|535,227,1|537,-84,1|545,-439,2|547,-43,4|549,147,3|55,489,4|551,539,1|\\\n553,-510,6|559,-101,1|57,-473,4|570,432,3|572,-238,1|574,-350,1|577,475,1|\\\n586,-292,1|589,-365,2|590,-590,1|590,590,1|6,-241,4|61,1,1|65,-540,2|73,342,2|\\\n79,-316,1|8,416,1|80,508,1|81,395,2|83,-13,2|90,179,1:')\n map_list.append(Ravyn)\n # netclubmember\n netclubmember = star_map('netclubmember', '-10,-581,1|-108,-581,1|\\\n-109,224,1|-112,-10,1|-113,308,1|-121,394,1|-123,-515,1|-126,-69,1|-127,-560,1|\\\n-131,-317,1|-134,266,2|-139,-109,1|-14,157,2|-142,556,1|-146,-129,1|\\\n-147,-165,1|-156,415,1|-158,58,1|-161,-241,1|-168,-501,1|-177,-522,1|\\\n-178,-421,2|-185,384,1|-194,246,4|-196,30,1|-196,441,1|-2,581,1|-20,482,3|\\\n-202,586,1|-214,116,4|-219,-266,1|-232,335,1|-232,489,1|-233,87,1|-234,190,1|\\\n-237,-219,1|-238,441,1|-247,-417,1|-247,-99,1|-247,415,1|-25,326,1|-250,-488,1|\\\n-251,-234,1|-253,68,1|-259,560,1|-262,416,3|-264,186,3|-274,-346,1|-275,-278,1|\\\n-28,-425,1|-281,350,1|-285,-398,1|-288,-490,2|-289,-186,1|-295,246,1|-3,-481,1|\\\n-304,-223,1|-305,-180,1|-308,-450,2|-31,142,1|-310,-576,1|-312,445,1|\\\n-315,297,1|-319,-24,1|-319,88,1|-320,-429,1|-324,206,1|-328,-480,1|-329,-209,1|\\\n-330,-329,1|-330,-572,1|-331,19,1|-334,-60,1|-337,480,1|-34,-519,1|-34,383,1|\\\n-351,-46,1|-362,369,1|-364,-243,1|-", 'title': u'Example Usage Code Continued'}, {'comment': u'The above code must be copied and pasted together.<br>\nThe example above provides 13 different maps and several<br>\nconstellations matches (as can be seen from the output<br>\nlisted below this comment.', 'title': u'Example Usage Code Explained'}, {'comment': u'<pre>\nNo constellations with at least 5 stars could be found in dfa_zero (1) and dfa_zero (2).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and dfa_zero (3).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and Jemaime77 (1).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and Jemaime77 (2).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and elvenscythe.\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and Raven193.\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and zaught (1).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and zaught (2).\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and Summernight.\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and snwangel1981.\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and Ravyn.\n\nNo constellations with at least 5 stars could be found in dfa_zero (1) and netclubmember.\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and dfa_zero (3).\n</pre>', 'title': u'Example Code Output (Part 1)'}, {'comment': u'<pre>\nEngine sorted out 4 duplicate solutions from dfa_zero (2) and Jemaime77 (1).\n5 STARS:\n In dfa_zero (2):\n (-338, 563), (590, 590), (590, -590), (-590, 590), (-590, -590)\n In Jemaime77 (1):\n (-338, 563), (590, 590), (590, -590), (-590, 590), (-590, -590)\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and Jemaime77 (2).\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and elvenscythe.\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and Raven193.\n\nEngine sorted out 4 duplicate solutions from dfa_zero (2) and zaught (1).\n5 STARS:\n In dfa_zero (2):\n (590, -590), (-590, -590), (-433, 118), (-590, 590), (590, 590)\n In zaught (1):\n (590, -590), (-590, -590), (-433, 118), (-590, 590), (590, 590)\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and zaught (2).\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and Summernight.\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and snwangel1981.\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and Ravyn.\n\nNo constellations with at least 5 stars could be found in dfa_zero (2) and netclubmember.\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and Jemaime77 (1).\n</pre>', 'title': u'Example Code Output (Part 2)'}, {'comment': u'<pre>\nEngine sorted out 33 duplicate solutions from dfa_zero (3) and Jemaime77 (2).\n5 STARS:\n In dfa_zero (3):\n (-246, 32), (-326, 112), (-386, 92), (-406, 32), (-326, -48)\n In Jemaime77 (2):\n (-280, 305), (-360, 385), (-420, 365), (-440, 305), (-360, 225)\n5 STARS:\n In dfa_zero (3):\n (-10, -23), (-130, 37), (70, 37), (30, 7), (-50, -23)\n In Jemaime77 (2):\n (79, -276), (-41, -216), (159, -216), (119, -246), (39, -276)\n6 STARS:\n In dfa_zero (3):\n (-171, -216), (-91, -156), (-131, -186), (-211, -216), (-291, -156), (-251, -186)\n In Jemaime77 (2):\n (79, -276), (159, -216), (119, -246), (39, -276), (-41, -216), (-1, -246)\n6 STARS:\n In dfa_zero (3):\n (178, 265), (108, 205), (48, 225), (238, 285), (158, 135), (168, 225)\n In Jemaime77 (2):\n (-13, 361), (-83, 301), (-143, 321), (47, 381), (-33, 231), (-23, 321)\n6 STARS:\n In dfa_zero (3):\n (-170, -360), (-110, -450), (-250, -420), (-240, -500), (-90, -490), (-130, -480)\n In Jemaime77 (2):\n (-312, -318), (-252, -408), (-392, -378), (-382, -458), (-232, -448), (-272, -438)\n6 STARS:\n In dfa_zero (3):\n (87, -187), (207, -307), (147, -327), (147, -167), (227, -247), (67, -247)\n In Jemaime77 (2):\n (-420, 365), (-300, 245), (-360, 225), (-360, 385), (-280, 305), (-440, 305)\n6 STARS:\n In dfa_zero (3):\n (529, -281), (529, -421), (409, -281), (469, -251), (409, -421), (469, -451)\n In Jemaime77 (2):\n (488, 65), (488, -75), (368, 65), (428, 95), (368, -75), (428, -105)\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and elvenscythe.\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and Raven193.\n</pre>', 'title': u'Example Code Output (Part 3)'}, {'comment': u'<pre>\nEngine sorted out 4 duplicate solutions from dfa_zero (3) and zaught (1).\n5 STARS:\n In dfa_zero (3):\n (590, -590), (10, 248), (-590, -590), (-590, 590), (590, 590)\n In zaught (1):\n (590, -590), (10, 248), (-590, -590), (-590, 590), (590, 590)\n\nEngine sorted out 75 duplicate solutions from dfa_zero (3) and zaught (2).\n5 STARS:\n In dfa_zero (3):\n (469, -251), (409, -281), (529, -281), (409, -421), (529, -421)\n In zaught (2):\n (-46, -369), (-106, -399), (14, -399), (-106, -539), (14, -539)\n5 STARS:\n In dfa_zero (3):\n (-10, -23), (-50, -23), (30, 7), (-130, 37), (70, 37)\n In zaught (2):\n (-31, -286), (-71, -286), (9, -256), (-151, -226), (49, -226)\n5 STARS:\n In dfa_zero (3):\n (-110, -450), (-90, -490), (-170, -360), (-240, -500), (-250, -420)\n In zaught (2):\n (-195, 422), (-175, 382), (-255, 512), (-325, 372), (-335, 452)\n5 STARS:\n In dfa_zero (3):\n (-90, -490), (-130, -480), (-240, -500), (-170, -360), (-250, -420)\n In zaught (2):\n (78, -121), (38, -111), (-72, -131), (-2, 9), (-82, -51)\n5 STARS:\n In dfa_zero (3):\n (227, -247), (67, -247), (207, -307), (147, -327), (147, -167)\n In zaught (2):\n (-283, -380), (-443, -380), (-303, -440), (-363, -460), (-363, -300)\n5 STARS:\n In dfa_zero (3):\n (-326, -48), (-386, 92), (-246, 32), (-406, 32), (-326, 112)\n In zaught (2):\n (-375, -170), (-435, -30), (-295, -90), (-455, -90), (-375, -10)\n5 STARS:\n In dfa_zero (3):\n (160, 450), (170, 540), (110, 530), (140, 580), (-30, 540)\n In zaught (2):\n (-396, 100), (-386, 190), (-446, 180), (-416, 230), (-586, 190)\n5 STARS:\n In dfa_zero (3):\n (542, -505), (572, -545), (372, -545), (512, -555), (422, -475)\n In zaught (2):\n (-416, 230), (-386, 190), (-586, 190), (-446, 180), (-536, 260)\n5 STARS:\n In dfa_zero (3):\n (-91, -156), (-291, -156), (-171, -216), (-131, -186), (-211, -216)\n In zaught (2):\n (264, 256), (64, 256), (184, 196), (224, 226), (144, 196)\n5 STARS:\n In dfa_zero (3):\n (529, -281), (409, -421), (529, -421), (469, -251), (469, -451)\n In zaught (2):\n (497, -406), (377, -546), (497, -546), (437, -376), (437, -576)\n6 STARS:\n In dfa_zero (3):\n (-171, -216), (-131, -186), (-251, -186), (-91, -156), (-291, -156), (-211, -216)\n In zaught (2):\n (-31, -286), (9, -256), (-111, -256), (49, -226), (-151, -226), (-71, -286)\n6 STARS:\n In dfa_zero (3):\n (158, 135), (48, 225), (168, 225), (178, 265), (108, 205), (238, 285)\n In zaught (2):\n (-165, 119), (-275, 209), (-155, 209), (-145, 249), (-215, 189), (-85, 269)\n6 STARS:\n In dfa_zero (3):\n (-90, -490), (-130, -480), (-240, -500), (-250, -420), (-170, -360), (-110, -450)\n In zaught (2):\n (141, 385), (101, 395), (-9, 375), (-19, 455), (61, 515), (121, 425)\n6 STARS:\n In dfa_zero (3):\n (207, -307), (147, -167), (147, -327), (227, -247), (87, -187), (67, -247)\n In zaught (2):\n (-315, -150), (-375, -10), (-375, -170), (-295, -90), (-435, -30), (-455, -90)\n6 STARS:\n In dfa_zero (3):\n (-130, 37), (-50, -23), (70, 37), (-10, -23), (179, 284), (30, 7)\n In zaught (2):\n (64, 256), (144, 196), (264, 256), (184, 196), (373, 503), (224, 226)\n6 STARS:\n In dfa_zero (3):\n (529, -421), (529, -281), (409, -421), (469, -251), (469, -451), (409, -281)\n In zaught (2):\n (509, 209), (509, 349), (389, 209), (449, 379), (449, 179), (389, 349)\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and Summernight.\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and snwangel1981.\n\nNo constellations with at least 5 stars could be found in dfa_zero (3) and Ravyn.\n\nEngine sorted out 61 duplicate solutions from dfa_zero (3) and netclubmember.\n5 STARS:\n In dfa_zero (3):\n (-326, 112), (-386, 92), (-246, 32), (-406, 32), (-326, -48)\n In netclubmember:\n (-66, -49), (-126, -69), (14, -129), (-146, -129), (-66, -209)\n5 STARS:\n In dfa_zero (3):\n (108, 205), (48, 225), (238, 285), (158, 135), (178, 265)\n In netclubmember:\n (-264, 186), (-32', 'title': u'Example Code Output (Part 4)'}, {'comment': u'<pre>\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and Jemaime77 (2).\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and elvenscythe.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and Raven193.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and zaught (1).\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and zaught (2).\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and Summernight.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and snwangel1981.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and Ravyn.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (1) and netclubmember.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and elvenscythe.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and Raven193.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and zaught (1).\n\nEngine sorted out 49 duplicate solutions from Jemaime77 (2) and zaught (2).\n5 STARS:\n In Jemaime77 (2):\n (428, 95), (368, 65), (488, 65), (368, -75), (488, -75)\n In zaught (2):\n (-46, -369), (-106, -399), (14, -399), (-106, -539), (14, -539)\n5 STARS:\n In Jemaime77 (2):\n (-252, -408), (-232, -448), (-312, -318), (-382, -458), (-392, -378)\n In zaught (2):\n (-195, 422), (-175, 382), (-255, 512), (-325, 372), (-335, 452)\n5 STARS:\n In Jemaime77 (2):\n (-232, -448), (-272, -438), (-382, -458), (-312, -318), (-392, -378)\n In zaught (2):\n (78, -121), (38, -111), (-72, -131), (-2, 9), (-82, -51)\n5 STARS:\n In Jemaime77 (2):\n (-280, 305), (-440, 305), (-300, 245), (-360, 225), (-360, 385)\n In zaught (2):\n (-283, -380), (-443, -380), (-303, -440), (-363, -460), (-363, -300)\n5 STARS:\n In Jemaime77 (2):\n (159, -216), (-41, -216), (79, -276), (119, -246), (39, -276)\n In zaught (2):\n (264, 256), (64, 256), (184, 196), (224, 226), (144, 196)\n5 STARS:\n In Jemaime77 (2):\n (488, 65), (368, -75), (488, -75), (428, 95), (428, -105)\n In zaught (2):\n (497, -406), (377, -546), (497, -546), (437, -376), (437, -576)\n6 STARS:\n In Jemaime77 (2):\n (79, -276), (119, -246), (-1, -246), (159, -216), (-41, -216), (39, -276)\n In zaught (2):\n (-31, -286), (9, -256), (-111, -256), (49, -226), (-151, -226), (-71, -286)\n6 STARS:\n In Jemaime77 (2):\n (-33, 231), (-143, 321), (-23, 321), (-13, 361), (-83, 301), (47, 381)\n In zaught (2):\n (-165, 119), (-275, 209), (-155, 209), (-145, 249), (-215, 189), (-85, 269)\n6 STARS:\n In Jemaime77 (2):\n (-232, -448), (-272, -438), (-382, -458), (-392, -378), (-312, -318), (-252, -408)\n In zaught (2):\n (141, 385), (101, 395), (-9, 375), (-19, 455), (61, 515), (121, 425)\n6 STARS:\n In Jemaime77 (2):\n (-300, 245), (-360, 385), (-360, 225), (-280, 305), (-420, 365), (-440, 305)\n In zaught (2):\n (-315, -150), (-375, -10), (-375, -170), (-295, -90), (-435, -30), (-455, -90)\n6 STARS:\n In Jemaime77 (2):\n (488, -75), (488, 65), (368, -75), (428, 95), (428, -105), (368, 65)\n In zaught (2):\n (509, 209), (509, 349), (389, 209), (449, 379), (449, 179), (389, 349)\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and Summernight.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and snwangel1981.\n\nNo constellations with at least 5 stars could be found in Jemaime77 (2) and Ravyn.\n\nEngine sorted out 49 duplicate solutions from Jemaime77 (2) and netclubmember.\n5 STARS:\n In Jemaime77 (2):\n (-83, 301), (-143, 321), (47, 381), (-33, 231), (-13, 361)\n In netclubmember:\n (-264, 186), (-324, 206), (-134, 266), (-214, 116), (-194, 246)\n5 STARS:\n In Jemaime77 (2):\n (-392, -378), (-312, -318), (-382, -458), (-272, -438), (-252, -408)\n In netclubmember:\n (-178, -421), (-98, -361), (-168, -501), (-58, -481), (-38, -451)\n5 STARS:\n In Jemaime77 (2):\n ', 'title': u'Example Code Output (Part 5)'}], 'desc': u'The following recipe demonstrates the use of SETs in Python.\nThe scenario that this was written for is as follows:\n\nA star map is given according to the format X,Y,Z|...|X,Y,Z:\nX represents the X coordinate of the star (which may be any real integer).\nY represents the Y coordinate on the star (which may be any real integer).\nZ represents the color of the star (which may be any real integer larger than 0).\n| separates the stars (strings represented by X,Y,Z).\n, separates the numbers describing the stars (X,Y,Z).\n: represents the end of the star map string.\n... is an arbitrary number of X,Y,Z strings with appropriate pipes.\n\nThe problem involves finding all constellations that are shared across two\ndifferent star maps. A constellation is defined as a group of stars. When trying\nto find out if a constellation is shared by two star maps, color and position do\nnot matter. However, all constellations would be oriented in the same direction.'}, {'comments': [], 'desc': u'Great for deciding automatically whether to use colors.\n\nBased on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116'}, {'comments': [{'comment': u'This algorithm doesn\'t work for various quantifiers such as kleene closure (*).\n<br>\nFor example, it returns the wrong point of failure for\n<br> \n<br> \npattern = r"a+[bc]+z*e+f"\n<br>\ntext = "aaaaabbbbe"', 'title': u'Code is broken'}, {'comment': u'To avoid this bug one can pop out characters from the end of the \npattern\n<pre>\nimport re\n\ndef sub_re(pattern):\n for offset in range(len(pattern)+1,0,-1):\n try:\n re_obj = re.compile(pattern[:offset])\n except re.error: # syntax error in re part\n continue\n yield offset, re_obj\n\ndef partial_pattern_match(pattern, text):\n good_pattern_offset = 0\n good_text_offset = 0\n for re_offset, re_obj in sub_re(pattern):\n match = re_obj.match(text)\n if match:\n good_pattern_offset = re_offset\n good_text_offset = match.end()\n return good_pattern_offset, good_text_offset\n return good_pattern_offset, good_text_offset\n\nif __name__ == "__main__":\n pattern = r"a+[bc]+d+e+"\n text = "aaaaabbbbe"\n pattern_offset, text_offset = partial_pattern_match(pattern, text)\n print "pattern, pattern_offset", pattern, repr(pattern_offset)\n print "good pattern", pattern[:pattern_offset]\n print "text:"\n print text\n print \' \' * text_offset + \'^\'\n\n pattern = r"a+[bc]+z*e+f"\n text = "aaaaabbbbef"\n pattern_offset, text_offset = partial_pattern_match(pattern, text)\n print "pattern, pattern_offset", pattern, repr(pattern_offset)\n print "good pattern", pattern[:pattern_offset]\n print "text:"\n print text\n print \' \' * text_offset + \'^\'\n</pre>', 'title': u'bug fix'}, {'comment': u"In my tests (actually, parsing Postfix log files :) I had no failures with the function as given --thank you again, and thank you too, Mario. I used Mario's version as suggested.", 'title': u'Thank you for pointing this out'}], 'desc': u'Debug non-matching regular expressions by finding out the maximum parts of the pattern and the text that do match.'}, {'comments': [{'comment': u'The following is quite a bit faster. And should be directly translatable to Numeric code.\n\n<pre>\nimport numpy as np\ndef peaks(data, step):\n data = data.ravel()\n length = len(data)\n if length % step == 0:\n data.shape = (length/step, step)\n else:\n data.resize((length/step, step))\n max_data = np.maximum.reduce(data,1)\n min_data = np.minimum.reduce(data,1)\n return np.concatenate((max_data[:,np.NewAxis], min_data[:,np.NewAxis]), 1)\n</pre>\n\nProfiling this function on my machine gives 0.015 seconds per call:\n<pre>\n>>> x = np.sin(np.arrayrange(0, 3.14, 1e-5))\n>>> profiler.run("run_n_times(\'peaks(x,1000)\', 1000)").print_stats()\n ncalls tottime percall cumtime percall filename:lineno(function)\n 999 0.190 0.000 14.880 0.015 :1(peaks)\n</pre>\n\nCompare with 0.104 seconds per call:\n\n<pre>\n>>> x = sin(arrayrange(0, 3.14, 1e-5))\n>>> profiler.run("run_n_times(\'peaksN(x,1000)\', 1000)").print_stats()\n ncalls tottime percall cumtime percall filename:lineno(function)\n 999 2.160 0.002 104.190 0.104 :1(peaksN)\n</pre>\n\nI don\'t think it is possilbe to combine the two operations (min and max) with functions that numpy provides, but you could probably write an algorithm in C and use weave to inline the code. ', 'title': u'This is quite a bit faster.'}, {'comment': u"so what i missed was ufunc's own .reduce() method<br>\nthanks a lot for pointing out!", 'title': u' '}], 'desc': u'Given a large one-dimensional array, break it into blocks of contstant length and compute min and max for each block, the so-called "peaks data". '}, {'comments': [{'comment': u'Hi,\nwhat about using the struct module?\nIt can also deal with the datatype size.', 'title': u'how about struct?'}, {'comment': u"You could implement something like this with the struct module and an array of characters. It's much more complicated. ctypes supports assignment of a tuple\ndirectly to a structure location. That would need to be rewritten at the Python level.\nIn reading the documentation I would start with the 3rd party xstruct module. In\nany case, I want to call C function through ctypes and in Python 2.5 ctypes will be\npart of the standard library, so there's no reason to roll an alternative approach.", 'title': u'struct module'}], 'desc': u'a resizeable list-like object using ctypes arrays for the primary data storage'}, {'comments': [], 'desc': u'This recipe demonstrates DS of RRS\n(Discreet Simulation of Round Robin Scheduling).\nThe purpose of this exercise is twofold.\n1. It demonstrates discreet simulation in a practical way.\n2. It demonstrates how different factors affect round robin scheduling.'}, {'comments': [], 'desc': u'The following recipe shows an example of the bounded buffer problem\nand its solution. Fortunately in Python, this is very easily solved\nwith the Queue class from the Queue module. Even creating a buffer\nwith a maximum size limit becomes rather easy with the automatic\nblocking feature (when trying to put when the Queue is full or when\ntrying to get when the Queue is empty). Overall, this is just a\nsimple example and approach to a classic problem.'}, {'comments': [], 'desc': u'This is the second example solution to the bounded\nbuffer problem. By looking at the code, you may\nnotice that it has several features that exapand\non what is demonstrated in the first example.\nFirst of all, it accepts several new command line\narguments that allow customization of the operation\nof this recipe (including an optional seed argument).\nFurthermore, this recipe features a fourth thread\nthat takes care of printing for the producer and\nconsumer threads. Of all the improvements in this\nexample, one of the nicest involves improved\nfunctions for the threads being executed.'}, {'comments': [{'comment': u'No need for all the strftime work, since date and datetime objects have attributes representing their days, months, years, etc.\n\n<br><br>For comparison, here\'s another way to write first_day and last_day functions. It\'s a bit opaque and undocumented, but is likely faster.\n\n<pre>from datetime import date, timedelta\n\ndef get_first_day(dt, d_years=0, d_months=0):\n # d_years, d_months are "deltas" to apply to dt\n y, m = dt.year + d_years, dt.month + d_months\n a, m = divmod(m-1, 12)\n return date(y+a, m+1, 1)\n\ndef get_last_day(dt):\n return get_first_day(dt, 0, 1) + timedelta(-1)\n\n>>> d = date.today()\n>>> d\ndatetime.date(2006, 3, 30)\n>>> get_first_day(d)\ndatetime.date(2006, 3, 1)\n>>> get_last_day(d)\ndatetime.date(2006, 3, 31)\n</pre>\n\nThe get_first_day function is a bit more convoluted than is stricly necessary. But allowing for those delta_month and delta_year optional arguments allows for a simpler get_last_month function, as well as letting you, e.g., get the last day of this month in the previous year.', 'title': u'strftime?'}, {'comment': u'There\'s an easier way to do this:\n\n<pre>thisMonth = \'%02d\' % (i+1)</pre>\n\nThe \'02\' qualifier means, "make it two characters wide, and pad it with zeroes on the left if necessary".\n\n<br><br>You might also use "range(1, 13)" instead of "range(12)", then you wouldn\'t have to add the one every time.', 'title': u'thisMonth = ("0%i"%(i+1,))[-2:]'}, {'comment': u"This library offers a relativedelta type.\nAdding relativedelta(day=31) to a date allways gives you the last day of the month that date is in.\n\n<pre>\n>>> from datetime import *\n>>> from dateutil.relativedelta import *\n>>> datetime(2008,2,3) + relativedelta(day=31)\ndatetime.datetime(2008, 2, 29, 0, 0)\n</pre>\n\nYou can do way more with this library, if you work a lot with dates it's worth a look.", 'title': u'Alternative: use dateutil from labix.org'}, {'comment': u'>>> [calendar.monthrange(year,month)[1] for year in [2006] for month in range(1,13)]\n<br>Results in:<br>\n[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n', 'title': u'Number of days in months for year 2006 --- calendar module'}, {'comment': u'How about today is 2007-12-30? It will give next month as 2007-01-01.', 'title': u"it doesn't work"}], 'desc': u'I often do reporting that requires the first and last day of the month as bounds. I ended up writing repetitive code until I wrote these utility functions. You might find them useful too.'}, {'comments': [], 'desc': u'One problem with ending all of your python scripts in .py is that you have to type the full name of the command. On Unix you can symlink to it with the shortened name, or wrap it in a bourne-shell script, or a shell alias. None of these solutions is particularly clean.\n\nOn MS Windows, file extensions have much more meaning. In fact, there is an environment variable to control what extensions should be considered executables, to permit them to be run from name, without the extension. This is the PATHEXT environment variable. Add .PY to this, and all of your python scripts can be executed transparently. '}, {'comments': [{'comment': u"The return values from __cmp__ are negative (less than), 0 (equals) or positive (greater than).\n\nYou therefore can't just compare with -1, 0 and 1 - you need to check < 0, 0 and > 0.", 'title': u'__cmp__ can return other values'}, {'comment': u"Sorry, why would you want this? If you define __cmp__, you can already use your object with <, >, !=, etc. so you shouldn't need any of the rich comparisons defined.\n\nA more useful mixin would be one that defines all the rich comparisons if you just define __eq__ and __lt__. (Python doesn't fill in the missing comparison operators because for some types you can't assume that ``not <`` implies ``>=``.)", 'title': u' '}], 'desc': u'The following mixin implements the full suite of rich comparison operators if __cmp__ is defined. See http://docs.python.org/ref/customization.html'}, {'comments': [{'comment': u'One way that I\'ve recently found to use reduce is for the chained replacement of characters in a string.\n\nSo instead of:\n<pre>\ndef replace(text, replacements):\n for (old, new) in replacements:\n text = text.replace(old, new)\n \n return text\n</pre>\n\nI use:\n<pre>\ndef replace(text, replacements):\n return reduce(lambda s, (old, new): s.replace(old, new), replacements, text)\n</pre>\n\nAnd an example:\n<pre>\nreplace("This is a normal string", [(c, c.upper()) for c in "aeiou"])\n\'ThIs Is A nOrmAl strIng\'\n</pre>\n\nIronically enough, on my machine the the reduce version is about 37% slower than the looped version on the example I gave above.', 'title': u'Chained replacements in a string'}, {'comment': u'Python is a wonderfully expressive programming language. Some expressions such as those involving reduce,<br>are more elegant and simple than others. I enjoy and value the functional facilities and functions as first<br>class objects in Python. I have, however, seen evidence that some of these are in jeopardy<br>(google for "The fate of reduce() in Python".)<br><br>\nHere are in-line list comprehension versions of your functions<br>and a bit more. The general form is: set initial value,<br>set iteration values and successively apply an infix or prefix function cumulatively and finally take the last value<br>of the generated list.<pre>\n\n>>> T=[set(s) for s in [(1,2,3,4,5),(2,3,4,5,6),(3,4,5,6,7),(4,5,6,7,8)]]\n\n>>> f=set.intersection\n>>> [ s for s in [f(*T[:2])] for i in range(2,len(T)) for s in [f(s,T[i])] ][-1]\nset([4, 5]) ## issues the null set if no intersection between all given sets\n\n>>> f=set.union\n>>> [ s for s in [f(*T[:2])] for i in range(2,len(T)) for s in [f(s,T[i])] ][-1]\nset([1, 2, 3, 4, 5, 6, 7, 8])\n\n>>> # join\n>>> T=[(1,2,3,4,5,6,7),(3,4,5,6,7),(5,6,7),(7,8,9,2,1,5)]\n\n>>> [ s for s in [T[0]] for i in range(1,len(T)) for s in [s + T[i]] ][-1]\n(1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 5, 6, 7, 7, 8, 9, 2, 1, 5)\n\n>>> t=["abcd","efgh","ijkl","mnop","qrst"]\n\n>>> [ s for s in [T[0]] for i in range(1,len(T)) for s in [s + T[i]] ][-1]\n\'abcdefghijklmnopqrst\'\n\n>>> # factorial\n>>> fac = 6\n>>> [j for j in [1] for i in range(2, fac+1) for j in [j*i]][-1]\n720\n\n>>> nl = [2, 3, 6, 18]\n\n>>> # sum\n>>> [j for j in [0] for i in nl for j in [j + i]][-1]\n29\n>>> # product\n>>> [j for j in [1] for i in nl for j in [j * i]][-1]\n648\n>>>\n\nMuch thanks to Steven Bethard for the cleaner form of this pattern.</pre>', 'title': u'Anonymous in-line list comprehension functions'}, {'comment': u'<pre>>>> l=(20,30,40,50,60,70,80,90,1,2,3,4,5)\n\n>>> # all function\n>>> [ p for p in [l[0]>42] for i in range(1,len(l)) for p in [p and l[i]>42] ][-1]\nFalse\n\n>>> # any function\n>>> [ p for p in [l[0]>42] for i in range(1,len(l)) for p in [p or l[i]>42] ][-1]\nTrue\n\nThe pattern *is* very general and regular</pre>', 'title': u'And for predicates'}, {'comment': u'I used reduce to build up a tuple of the parts of an elapsed time, starting with a floating point number of seconds. Posted at recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/511486\n\n-- Paul', 'title': u'Use reduce to call divmod with succesive divisors'}], 'desc': u"reduce is a pretty nice built-in, but its usage in everyday code is seemingly rare. If you've been looking for excuses to use reduce, here are a few useful recipes to get you started."}, {'comments': [], 'desc': u'The 3 Python array packages are not able to create multidimensional arrays from iterators. This recipe allows you to do that.'}, {'comments': [], 'desc': u"Say you want to generate a default image with my app without having to include an image file with my app. You'll want to encode the binary image data as text, using base64. This image can later be displayed in my app, or a binary image file can be written by decoding the encoded text string using the base64 module. To make this task a little easier for you, I created a small GUI app using Wax. Simply run the app, select the image file you want converted, then copy the encoded text string and paste it into your app (which could be a Wax, wxPython, Qt or even Tkinter app). The last part of the recipe shows you how to decode that text string back to binary data."}, {'comments': [], 'desc': u'Thunderbird mail client can export its addressbook to LDIF format, but exported file is not suitable for importing into OpenLDAP server. This recipe can fix that.'}, {'comments': [], 'desc': u'Sometimes one needs a quick and dirty solution for parsing and generating xml. This recipe uses only the python parser itself for the parsing of xml. xml code is translated to valid python code and then evaluated. The generated objects can then be manipluated within python itself and treated as regular python objects.'}, {'comments': [], 'desc': u'This recipe provides "Registry", a Windows registry wrapper class that makes it easy to work with the Windows registry. The class works with an inner class named "RegistryKey", which wraps up a Windows registry key and provides methods to access and manipulate the key information. The class provides easy to remember substitutes for long method names of _winreg.'}, {'comments': [], 'desc': u'The title of this recipe contains\nthe two words that gave the inspiration\nfor the writing of what appears below.\nPort forwarding -- think about it.'}, {'comments': [{'comment': u'We create solutions for which we hope there is a problem. :)', 'title': u'Nice!'}, {'comment': u'I guess 99.99% of the time a port forwarder is used with very few connections, so the threaded version does not have any problems. I\'ve put this asynchronous version as a tribute to the asyncore module, since I\'ve wrote this little port forwarder as I needed one and thought "what the heck, let\'s do it asynchronously" :)', 'title': u'Indeed :)'}, {'comment': u'There is a bug. The receiver connection is closed by the sender.handle_close() so if the receiver is slow (asynchronous connection) the receiver connection is closed before it has a chance to send the data. So check in sender.handle_close() if to_remote_buffer is empty first then close otherwise let receiver close it using its own receiver.handle_close(). This was after much checking of buffers and realising the ovezealous sender had closed the receiver connection in haste!!\n\nchange:\nclass sender(asyncore.dispatcher):\n def handle_close(self):\n self.close()\n if len(self.receiver.to_remote_buffer) == 0:\n self.receiver.close()', 'title': u'closed connection for receiver'}], 'desc': u'This forward the TCP traffic from your machine to another host, and back in the the other way. It uses asynchronous socket thanks to ye olde asyncore module, which was used by Zope up until recently (they integrated the Twisted reactor). As a consequence, it should be able to handle a great number of connections without crumbling under the weight of many threads.'}, {'comments': [{'comment': u"What follows is an example driver program for the code shown above.\n<pre>\nfrom mapper_v2 import stars, key\n\ndef main():\n maps = map_list()\n for star_map in maps[1:]:\n star_map.unlock(maps[0])\n\ndef map_list():\n map_list = list()\n # dfa_zero\n dfa_zero = key('dfa_zero', '-102,-24,1|-105,-243,1|-105,-309,1|-110,-206,1|\\\n-12,396,1|-121,299,1|-122,-589,1|-124,323,1|-128,-801,1|-13,-342,1|-131,-166,1|\\\n-131,-186,2|-131,-260,1|-134,-516,1|-14,-596,1|-146,439,1|-148,640,1|\\\n-154,181,1|-158,161,1|-159,-523,1|-162,276,1|-170,-47,1|-171,-216,1|\\\n-176,-679,1|-183,-771,1|-190,648,1|-198,678,1|-203,103,1|-206,357,1|-209,390,1|\\\n-210,-649,1|-211,-216,2|-217,72,1|-22,-260,1|-22,-61,1|-221,492,1|-226,397,1|\\\n-230,-471,1|-235,680,1|-239,-770,1|-246,367,1|-247,536,1|-249,248,1|-250,203,1|\\\n-251,-186,2|-251,221,1|-251,797,1|-252,-32,1|-252,-584,1|-257,-774,1|\\\n-258,342,1|-262,704,1|-263,-313,1|-271,-397,1|-272,742,1|-276,-158,1|\\\n-276,164,1|-276,591,1|-286,487,4|-291,-156,1|-296,155,1|-302,-325,1|-303,686,1|\\\n-306,-369,1|-306,232,1|-307,-622,1|-311,-517,1|-317,-811,1|-32,608,1|\\\n-326,-447,1|-33,681,1|-337,415,1|-341,-367,1|-341,-537,3|-346,-432,1|\\\n-346,-672,1|-349,-579,1|-356,347,1|-358,-788,1|-360,661,1|-363,67,1|-366,427,2|\\\n-367,-65,1|-371,-517,1|-372,-212,1|-372,615,1|-379,121,1|-38,-388,1|-38,147,3|\\\n-380,678,1|-384,20,1|-388,199,1|-389,-243,1|-389,712,1|-39,261,1|-392,-12,1|\\\n-4,-215,1|-411,-397,4|-413,295,1|-416,-74,1|-416,46,1|-426,-600,1|-43,-138,1|\\\n-436,-34,2|-436,-65,1|-437,-103,1|-437,270,1|-441,-353,1|-443,399,1|-45,655,1|\\\n-454,432,1|-456,6,3|-466,22,1|-467,-699,1|-472,719,1|-475,52,1|-482,-337,1|\\\n-483,213,1|-485,-281,1|-485,532,1|-489,794,1|-490,-732,1|-492,-757,1|\\\n-498,-670,1|-5,-321,1|-5,551,1|-506,-4,1|-506,-709,1|-507,277,1|-510,-774,1|\\\n-513,-234,1|-515,-742,1|-516,126,1|-52,55,1|-52,83,1|-525,580,1|-531,-774,1|\\\n-533,-220,1|-539,281,1|-54,-829,1|-540,-468,1|-544,165,1|-549,672,1|\\\n-556,-154,1|-559,-735,1|-56,-93,1|-56,314,1|-563,-220,1|-566,271,1|-567,628,1|\\\n-57,204,1|-575,-167,1|-576,154,1|-579,76,1|-590,-102,1|-592,-250,1|-599,-430,1|\\\n-603,-317,1|-604,-511,1|-606,-370,1|-606,499,1|-607,805,1|-61,-486,1|\\\n-617,-458,1|-634,766,1|-635,-417,1|-640,-662,1|-646,-827,1|-65,637,1|\\\n-651,308,1|-657,517,1|-66,570,1|-660,-160,1|-662,-384,1|-668,-413,1|-669,164,1|\\\n-67,-651,1|-670,-594,1|-675,-349,1|-677,-769,1|-679,60,1|-682,-745,1|\\\n-684,431,1|-688,316,1|-69,818,1|-693,-270,1|-698,375,1|-700,275,1|-701,-596,1|\\\n-71,-417,1|-71,-439,1|-71,435,1|-711,-276,1|-72,65,1|-721,-356,2|-721,660,1|\\\n-726,538,1|-729,-29,1|-73,-19,1|-730,798,1|-736,-501,1|-743,352,1|-758,-352,1|\\\n-759,-436,1|-761,205,1|-771,747,1|-778,-3,1|-790,138,1|-791,-256,2|-80,-773,1|\\\n-801,-226,1|-801,509,1|-802,589,1|-804,-751,1|-805,783,1|-81,789,1|-810,105,1|\\\n-813,312,1|-815,-23,1|-818,-622,1|-821,-386,1|-830,-830,1|-830,830,1|-85,110,1|\\\n-91,-156,2|-92,-711,1|-93,94,1|-97,474,1|-98,167,3|-98,730,1|0,749,1|\\\n100,-701,1|100,273,1|103,-216,1|108,-12,1|111,-819,1|112,-581,1|112,98,1|\\\n12,33,1|12,77,3|122,631,1|122,793,1|125,-631,1|127,609,1|13,-715,1|130,-186,4|\\\n131,-704,1|133,327,1|134,-121,1|134,-817,1|135,-785,1|150,-126,1|150,-591,1|\\\n151,541,1|154,679,1|157,-655,1|160,-355,1|162,-71,1|162,796,1|177,-600,2|\\\n177,-740,2|18,362,1|180,-701,1|188,-814,1|190,32,1|191,-480,1|195,716,1|\\\n196,-644,1|203,535,1|203,612,1|206,684,1|210,-106,2|210,-266,1|212,-371,1|\\\n22,167,1|225,-220,1|228,-790,1|233,-163,1|237,-62,1|239,176,1|239,542,1|\\\n244,-375,1|245,243,1|252,659,1|257,-87,1|259,-161,1|26,-157,1|26,-488,1|\\\n260,7,1|267,-660,1|270,-246,1|272,-555,1|274,454,1|277,-610,1|277,421,1|\\\n28,109,1|280,-439,1|283,-629,1|283,397,1|287,-321,1|288,556,1|289,-135,1|\\\n290,-186,2|294,-162,1|296,13,1|299,360,1|299,719,1|3,-584,1|303,683,1|\\\n304,-649,1|307,-698,1|31,507,1|32,-630,1|32,207,2|323,-140,1|324,390,1|\\\n327,347,1|334,-811,1|336,-542,1|338,172,1|338,85,1|340,-765,1|347,283,1|\\\n349,132,1|35,705,1|356,311,1|358,-471,1|358,676,1|370,596,1|372,-259,1|\\\n372,141,1|382,340,1|382,480,4|389,-9,1|394,", 'title': u'Example (Part 1)'}, {'comment': u"<pre>\n # Jemaime77\n Jemaime77 = stars('Jemaime77', '-1,-246,2|-107,-200,1|-13,31,1|\\\n-13,361,2|-137,-36,1|-14,428,1|-140,-181,1|-143,321,3|-145,550,1|-148,-92,1|\\\n-156,-62,2|-158,-511,1|-159,79,1|-165,-306,1|-166,-586,3|-167,54,1|-172,448,1|\\\n-175,387,1|-182,-368,1|-188,238,1|-193,-487,1|-195,-129,1|-196,-338,1|\\\n-197,214,1|-198,-239,1|-206,431,1|-212,-509,1|-213,-375,1|-216,-532,1|\\\n-216,-82,2|-219,274,1|-220,256,1|-225,352,1|-226,-490,1|-227,458,1|-227,588,1|\\\n-23,321,1|-232,-448,2|-236,-212,1|-237,419,1|-241,-387,1|-248,513,1|\\\n-249,-358,1|-250,-161,1|-252,-408,1|-260,-456,1|-272,-438,6|-276,-92,1|\\\n-277,560,1|-280,305,2|-281,421,1|-283,102,1|-285,-394,1|-286,439,1|-288,-65,1|\\\n-296,24,1|-3,-19,1|-300,245,3|-308,364,1|-312,-318,2|-313,195,1|-321,-585,1|\\\n-323,-430,1|-329,387,1|-33,-149,1|-33,231,1|-344,-237,1|-346,-122,3|-347,21,1|\\\n-347,555,1|-349,59,1|-35,336,1|-353,410,1|-354,270,1|-360,225,3|-360,385,1|\\\n-366,-586,5|-369,99,4|-374,464,1|-377,575,1|-382,-397,1|-382,-458,3|\\\n-383,-508,1|-383,260,1|-383,521,1|-385,-428,1|-388,-2,1|-392,-378,6|-41,-216,1|\\\n-41,-341,1|-420,365,1|-428,329,1|-430,-491,1|-430,568,1|-432,-531,1|-440,305,5|\\\n-443,-136,1|-445,-567,1|-452,-201,1|-464,-373,1|-474,186,1|-474,99,1|\\\n-478,575,1|-479,-387,1|-485,479,1|-490,-35,1|-491,293,1|-495,403,1|-499,24,1|\\\n-499,49,2|-500,-111,1|-502,-466,3|-513,-512,1|-524,-51,1|-527,-177,2|\\\n-529,-350,1|-535,269,1|-538,545,1|-542,-586,2|-545,498,2|-546,-77,1|\\\n-547,-138,1|-549,-560,1|-554,-19,1|-563,-379,1|-567,-297,1|-568,430,1|\\\n-57,307,1|-572,-436,3|-576,144,1|-577,117,1|-58,-336,1|-585,378,3|-590,-590,1|\\\n-590,590,1|-6,-410,1|-60,-544,1|-60,33,1|-67,-520,1|-73,183,1|-73,378,1|\\\n-83,301,1|-85,107,1|-89,151,1|-91,-302,1|-92,574,1|-98,443,1|102,375,1|\\\n110,-385,1|113,-356,1|119,-246,1|125,-538,1|126,398,1|129,-368,1|139,37,1|\\\n140,-221,1|142,-249,1|143,70,1|145,-504,1|150,-69,1|151,453,1|155,-589,1|\\\n159,-216,1|161,426,1|162,-281,1|165,198,1|168,-173,1|176,369,1|177,-19,2|\\\n18,-551,1|181,197,1|182,-340,1|183,70,1|183,95,1|187,31,1|189,-398,1|\\\n198,-556,1|201,-302,1|202,-354,1|207,286,1|209,-64,1|21,197,1|218,-475,1|\\\n218,-94,1|220,-346,1|222,553,1|228,347,1|23,100,1|243,572,1|248,98,1|\\\n250,-567,1|253,-241,1|254,525,1|263,130,5|275,-563,1|277,412,1|287,168,1|\\\n294,-464,1|304,-157,1|311,-302,3|316,-44,1|319,-521,1|320,-324,1|328,202,1|\\\n329,-7,1|33,-340,1|330,55,1|331,-242,2|331,254,1|332,-89,1|337,377,3|341,88,1|\\\n342,492,1|347,-106,1|347,-463,1|347,204,1|359,-276,1|360,465,1|368,-75,6|\\\n368,65,1|371,378,1|376,-20,1|386,-439,1|39,-276,2|391,-382,3|397,-557,1|\\\n397,237,2|397,397,3|414,-217,1|42,-480,1|426,270,1|427,-265,1|428,-105,1|\\\n428,95,4|429,-285,1|440,56,1|443,-90,1|443,290,1|445,-433,1|448,112,1|\\\n451,-362,1|457,451,1|46,-5,1|46,151,1|46,45,1|47,381,1|477,317,2|488,-75,3|\\\n488,65,1|490,451,1|506,450,1|51,167,1|516,-223,1|518,-193,1|525,289,1|\\\n526,519,1|531,-327,1|534,451,1|540,-544,1|540,270,1|549,453,1|56,409,1|\\\n564,58,1|565,455,1|572,123,1|575,33,1|577,-331,1|585,416,1|589,272,1|\\\n590,-590,1|590,590,1|61,5,1|62,94,1|63,130,1|64,540,1|69,-398,1|69,-538,1|\\\n79,-214,1|79,-276,6|79,86,1|8,-484,1|87,580,1|90,-397,1|94,303,1:')\n map_list.append(Jemaime77)\n # elvenscythe\n elvenscythe = stars('elvenscythe', '-100,305,2|-108,79,2|-11,459,4|\\\n-118,-80,2|-123,516,1|-127,476,2|-128,-486,1|-13,-101,1|-130,395,3|-133,111,1|\\\n-14,90,1|-141,-84,1|-143,138,1|-146,-186,2|-147,436,3|-148,575,1|-149,-68,3|\\\n-156,-116,4|-158,-9,2|-170,477,3|-177,-491,2|-177,498,2|-181,289,1|-181,82,1|\\\n-182,386,1|-185,29,1|-189,-297,3|-20,-144,1|-204,-61,3|-209,-523,1|-21,-183,3|\\\n-215,-431,1|-217,-569,1|-22,-65,3|-229,347,2|-231,260,2|-234,-558,1|\\\n-251,-285,1|-253,-357,5|-257,-419,1|-263,-236,2|-266,-53,3|-27,473,6|\\\n-274,230,4|-277,-451,1|-292,365,1|-297,194,3|-299,150,1|-30,256,4|-303,132,1|\\\n-304,-303,2|-304,212,1|-308,537,1|-311,-145,1|-311,455,1|-313,6,3|-317,373,1|\\\n-320,-420,1|-327,58,1|-330,-206,1|-334,-323,3|-334,322,1|-336,109,1|\\\n-342,-161,1|-346,-291,1|-35,-264,1|-358,267,1|-364,-149,1|-364,463,2|\\\r", 'title': u'Example (Part 2)'}, {'comment': u"<pre> # zaught\n zaught = stars('zaught', '-1,562,1|-106,-399,1|-106,-539,1|\\\n-106,403,1|-111,-256,1|-127,171,1|-133,534,1|-134,496,1|-134,577,1|-140,-457,1|\\\n-145,249,1|-147,356,1|-151,-226,1|-152,-564,1|-154,306,1|-155,-380,1|\\\n-155,209,1|-163,-321,1|-165,119,3|-169,-269,1|-175,382,1|-180,-449,1|\\\n-187,212,1|-19,455,3|-191,-503,1|-192,232,1|-193,-465,1|-195,422,2|-2,-520,1|\\\n-2,9,1|-204,-577,1|-204,259,1|-215,189,1|-218,90,1|-232,-158,1|-233,-419,1|\\\n-238,398,1|-240,-40,1|-244,-219,1|-245,-584,1|-246,196,1|-251,2,1|-251,297,1|\\\n-255,512,1|-263,452,1|-266,285,1|-274,-524,1|-274,77,1|-275,209,1|-283,-380,1|\\\n-295,-90,1|-303,-440,2|-303,525,1|-304,157,1|-31,-286,2|-310,13,1|-312,90,1|\\\n-315,-150,1|-319,-18,1|-322,404,1|-323,215,1|-323,547,1|-325,372,1|-335,452,1|\\\n-336,48,1|-345,-574,1|-346,217,1|-35,513,1|-352,-438,1|-363,-300,1|-363,-460,1|\\\n-37,428,1|-372,-427,1|-375,-10,1|-375,-170,1|-380,-559,1|-381,550,1|\\\n-384,-347,1|-386,190,1|-396,100,1|-396,40,1|-404,333,1|-405,-340,1|-405,546,1|\\\n-409,11,1|-416,230,2|-419,-116,1|-433,75,1|-435,-12,1|-435,-30,1|-440,-505,1|\\\n-443,-380,1|-445,-584,4|-446,180,1|-452,-127,1|-455,-90,1|-457,102,1|\\\n-46,-369,2|-46,452,1|-473,531,1|-48,579,1|-49,-61,1|-499,-559,1|-509,-362,1|\\\n-515,499,1|-521,483,1|-528,-71,1|-536,260,1|-538,-5,1|-545,479,1|-547,-52,1|\\\n-550,282,1|-554,-449,1|-556,-81,1|-558,-351,1|-560,-172,1|-560,224,1|\\\n-572,-283,1|-572,581,1|-575,499,1|-579,-154,1|-579,43,1|-583,-183,1|\\\n-585,-102,1|-586,190,1|-590,-590,1|-590,590,1|-6,-312,1|-70,-395,1|-71,-286,2|\\\n-72,-131,1|-79,-98,1|-82,-51,4|-85,269,1|-86,64,1|-89,-455,1|-9,-455,1|\\\n-9,375,2|-92,504,1|-94,241,1|0,288,1|0,60,1|101,395,1|103,192,1|106,-283,1|\\\n107,-326,1|116,153,1|12,542,1|121,425,3|123,482,1|125,169,1|127,508,1|\\\n14,-399,3|14,-539,2|141,-579,2|141,385,4|144,196,5|145,431,1|147,-370,1|\\\n147,576,1|154,-340,1|154,281,1|177,-496,1|178,-188,1|184,196,2|189,-407,1|\\\n202,77,1|206,-51,3|207,478,1|218,-343,1|218,49,1|224,226,2|232,-32,1|238,464,1|\\\n241,572,1|246,6,1|256,507,1|263,-311,2|264,256,3|265,-355,1|266,-158,1|\\\n269,130,1|284,316,1|286,-131,2|286,29,1|294,9,1|297,-116,1|298,-470,1|\\\n299,-340,1|302,344,1|312,-67,1|313,-381,1|313,573,1|322,143,1|323,-291,1|\\\n332,347,1|333,-251,1|335,412,1|340,-489,1|341,-354,1|343,-175,1|346,-111,1|\\\n360,546,1|373,503,1|374,581,1|377,-546,2|38,-111,1|389,209,3|389,349,1|\\\n393,-23,1|393,402,1|396,-246,1|399,-350,1|401,-273,1|402,-6,1|411,176,1|\\\n417,-88,1|422,364,1|437,-376,1|437,-576,1|448,-159,1|449,179,3|449,379,2|\\\n449,518,1|450,-392,1|450,541,1|459,-354,1|460,559,1|470,406,1|472,175,1|\\\n48,-247,1|486,-135,1|488,-370,1|489,146,1|49,-226,1|491,68,1|492,-244,1|\\\n496,89,1|497,-406,2|497,-546,1|509,209,6|509,349,1|512,-177,1|525,75,1|\\\n531,-80,1|534,47,4|536,-201,1|536,336,1|544,295,1|546,-420,1|56,-565,1|\\\n563,-1,1|566,80,1|570,-225,1|573,433,1|590,-590,1|590,590,1|61,515,1|63,-396,1|\\\n64,256,2|74,192,1|78,-121,1|82,-217,1|83,247,1|88,161,1|9,-256,4|98,562,1:')\n map_list.append(zaught)\n # Summernight\n Summernight = stars('Summernight', '-10,-577,1|-100,-103,4|-105,-41,1|\\\n-106,118,3|-107,-461,2|-108,41,3|-110,433,1|-111,-125,1|-114,231,1|-114,253,1|\\\n-115,-510,4|-119,284,2|-137,-312,3|-137,-411,1|-138,-485,1|-138,276,2|\\\n-14,-217,3|-14,34,2|-142,-569,1|-148,-33,6|-149,-427,6|-15,392,6|-159,12,2|\\\n-161,109,4|-162,266,3|-165,446,1|-167,-188,1|-170,215,1|-187,370,3|-208,-426,3|\\\n-209,-180,2|-222,-326,3|-226,442,1|-227,46,1|-229,572,1|-23,-410,2|-23,293,1|\\\n-244,-257,6|-244,143,3|-244,367,4|-246,-563,1|-246,329,2|-250,161,2|\\\n-257,-301,1|-257,-439,1|-259,208,2|-261,-534,1|-264,-382,1|-264,402,1|\\\n-266,322,1|-270,-341,6|-270,-581,1|-276,-125,3|-277,-37,2|-28,532,2|\\\n-280,-432,1|-287,197,1|-290,140,3|-292,58,2|-293,-214,1|-298,75,1|-30,-233,1|\\\n-303,341,3|-306,-438,1|-308,413,1|-313,442,2|-327,-288,1|-329,-84,1|-33,448,1|\\\n-330,198,1|-344,-346,1|-348,341,1|-353,363,2|-358,209,1|-36,-468,3|-362,-582,1|\\\n-369,476,2|-372,-42,2|-374,161,3|-380,367,2|-385,-65,1|-386,-566,1|-388,-343,1|\\\n-394,-361,1|-401,258,1|-403,-85,3|-4", 'title': u'Example (Part 3)'}, {'comment': u"<pre>\n # Ravyn\n Ravyn = stars('Ravyn', '-105,555,2|-108,-217,2|-110,235,5|-110,587,1|\\\n-114,-531,1|-114,269,1|-118,-234,2|-118,-394,2|-124,-415,1|-13,352,3|\\\n-136,-105,4|-138,522,2|-144,353,1|-147,257,1|-150,-144,3|-150,-532,1|\\\n-151,-585,2|-159,348,1|-160,-493,1|-17,-234,6|-173,147,1|-176,-40,2|-179,103,1|\\\n-185,74,5|-188,-361,1|-19,394,1|-191,-170,2|-194,369,2|-199,129,3|-2,507,2|\\\n-203,-14,2|-228,-414,1|-230,-531,1|-256,-220,5|-257,-364,2|-258,432,1|\\\n-271,-580,2|-273,372,1|-274,-41,1|-277,412,2|-287,200,3|-29,-536,4|-29,440,1|\\\n-291,-557,1|-296,-267,2|-30,291,2|-301,360,2|-311,-453,4|-312,-412,2|\\\n-313,-313,1|-313,503,2|-314,-194,1|-314,-88,2|-320,-215,1|-320,-564,2|\\\n-323,-173,4|-328,-233,1|-33,498,3|-331,580,1|-332,42,1|-339,87,1|-340,-545,2|\\\n-343,485,1|-344,-247,1|-344,-401,2|-350,-228,1|-355,-576,1|-362,571,2|\\\n-365,-355,4|-372,-380,6|-385,368,2|-399,587,1|-403,-556,3|-405,310,1|-41,555,1|\\\n-412,-429,6|-412,343,3|-43,-471,2|-435,-55,4|-436,468,1|-438,288,2|-439,71,4|\\\n-467,536,1|-469,209,3|-478,-554,2|-479,555,2|-483,-275,3|-483,-436,2|\\\n-484,-369,1|-486,-290,6|-486,-39,1|-488,-493,5|-490,437,1|-495,-117,1|\\\n-5,-446,6|-501,-80,1|-510,-590,2|-519,-5,2|-52,66,2|-522,-129,1|-527,-496,1|\\\n-529,244,1|-537,337,3|-537,447,1|-538,-175,2|-539,403,1|-542,-227,2|-546,374,4|\\\n-561,126,1|-562,560,2|-564,-44,1|-564,74,1|-568,32,2|-573,210,1|-576,-183,1|\\\n-58,111,2|-583,-431,1|-590,-590,1|-590,590,1|-590,7,2|-64,-535,1|-75,354,1|\\\n-77,477,1|-81,-523,3|-86,176,1|-88,538,2|-91,-236,6|104,-429,2|105,352,1|\\\n11,-513,1|116,495,2|120,-417,1|120,344,1|123,-515,1|125,327,1|127,-470,2|\\\n129,-121,1|13,-410,1|132,-145,1|141,260,1|160,-294,3|160,-434,1|160,179,1|\\\n162,-64,1|162,564,1|169,-504,1|183,423,2|184,-341,2|185,190,1|19,45,3|\\\n190,288,1|191,139,1|194,-460,4|195,-438,1|207,78,3|211,501,3|216,178,4|\\\n219,-295,1|220,-255,1|220,530,1|224,426,4|235,83,1|236,-477,3|239,210,1|\\\n24,-460,2|24,526,2|243,-126,3|246,-162,1|247,-64,5|249,367,1|255,-302,4|\\\n26,209,3|261,-361,1|27,427,1|276,183,2|276,83,1|278,-66,3|278,99,1|28,-542,1|\\\n280,17,2|280,465,3|292,320,2|298,-308,1|300,-436,1|301,275,1|303,-358,2|\\\n310,-560,3|316,3,1|324,-342,1|325,-399,3|327,-155,2|328,-500,1|33,-170,2|\\\n330,-263,2|332,585,1|334,8,2|335,305,2|336,392,1|34,-487,5|34,120,1|341,52,1|\\\n346,-454,3|349,-510,1|350,-264,2|353,11,1|364,550,1|372,570,2|378,479,1|\\\n382,-71,1|386,-416,3|39,514,2|390,48,1|401,-370,4|406,22,1|409,-20,1|41,-426,1|\\\n410,460,1|415,-48,1|416,-581,3|419,348,1|420,533,2|425,-304,3|429,-399,1|\\\n430,201,3|437,-65,2|441,106,2|445,35,2|447,-88,3|448,-195,1|448,569,1|\\\n465,-435,1|47,282,5|471,-350,6|473,-148,1|476,-571,2|478,396,3|478,548,1|\\\n480,100,1|485,472,2|49,-315,1|495,392,1|496,260,2|5,246,1|500,581,1|505,-77,1|\\\n525,70,1|535,227,1|537,-84,1|545,-439,2|547,-43,4|549,147,3|55,489,4|551,539,1|\\\n553,-510,6|559,-101,1|57,-473,4|570,432,3|572,-238,1|574,-350,1|577,475,1|\\\n586,-292,1|589,-365,2|590,-590,1|590,590,1|6,-241,4|61,1,1|65,-540,2|73,342,2|\\\n79,-316,1|8,416,1|80,508,1|81,395,2|83,-13,2|90,179,1:')\n map_list.append(Ravyn)\n # netclubmember\n netclubmember = stars('netclubmember', '-10,-581,1|-108,-581,1|\\\n-109,224,1|-112,-10,1|-113,308,1|-121,394,1|-123,-515,1|-126,-69,1|-127,-560,1|\\\n-131,-317,1|-134,266,2|-139,-109,1|-14,157,2|-142,556,1|-146,-129,1|\\\n-147,-165,1|-156,415,1|-158,58,1|-161,-241,1|-168,-501,1|-177,-522,1|\\\n-178,-421,2|-185,384,1|-194,246,4|-196,30,1|-196,441,1|-2,581,1|-20,482,3|\\\n-202,586,1|-214,116,4|-219,-266,1|-232,335,1|-232,489,1|-233,87,1|-234,190,1|\\\n-237,-219,1|-238,441,1|-247,-417,1|-247,-99,1|-247,415,1|-25,326,1|-250,-488,1|\\\n-251,-234,1|-253,68,1|-259,560,1|-262,416,3|-264,186,3|-274,-346,1|-275,-278,1|\\\n-28,-425,1|-281,350,1|-285,-398,1|-288,-490,2|-289,-186,1|-295,246,1|-3,-481,1|\\\n-304,-223,1|-305,-180,1|-308,-450,2|-31,142,1|-310,-576,1|-312,445,1|\\\n-315,297,1|-319,-24,1|-319,88,1|-320,-429,1|-324,206,1|-328,-480,1|-329,-209,1|\\\n-330,-329,1|-330,-572,1|-331,19,1|-334,-60,1|-337,480,1|-34,-519,1|-34,383,1|\\\n-351,-46,1|-362,369,1|-364,-243,1|-364,-8", 'title': u'Example (Part 4)'}, {'comment': u'The code of this recipe should probably be<br>\nwritten with a constellation class and star<br>\nclass.', 'title': u'As A Side Note'}], 'desc': u'The following recipe demonstrates the use of SETs in Python.\nThe scenario that this was written for is as follows:\n\nA star map is given according to the format X,Y,Z|...|X,Y,Z:\nX represents the X coordinate of the star (which may be any real integer).\nY represents the Y coordinate on the star (which may be any real integer).\nZ represents the color of the star (which may be any real integer larger than 0).\n| separates the stars (strings represented by X,Y,Z).\n, separates the numbers describing the stars (X,Y,Z).\n: represents the end of the star map.\n... is an arbitrary number of X,Y,Z strings with appropriate pipes.\n\nAs an extention to the original problem that this code was written for,\nconstellation definitions can follow the colon. The constellation string\nthat might follow is described by the following:\n\n:C!D#...#D|...|C!D#...#D\n: represents the beginning of the constellation definitions.\nC!D#...#D represents one constellation definition.\n| is the constellation definition separator.\nC is a number that identifies what constellation is being defined.\nD can be repesented as X,Y;X,Y or X,Y.\nX would be the X coordinate of a star defined in the star map.\nY would be the Y coordinate of a star defined in the star map.\n, would be the coordinate separator.\n; would be the star separator.\n... would be an arbitrary number of D string with appropriate # signs.\n... would be an arbitrary number of constellation definitions.\n\nThe explanation for D is that if two stars are listed, they are joined\ntogether with a line segment; but if there is one star, it is only highlighted.\n\nIn this updated version of the code, there is a key object that has\nconstellations already identified and a stars object that contains\nthe stars in the sky. Keys are used to unlocks the stars and the\nresults are printed out for the user of the program.'}, {'comments': [{'comment': u'Hallo Brian,\n\nI\'m new on Python but have to work on a Python-Project.There are a task to handling "Excel-Sheets". \nAnd your snippet of code works verry well for my job without reading Modul-Interfaces.\nIt saved me a lot of time.\nNever the less - in future I\'ll reading the Modul-Interface of xlrd soon ;-)\n\nThanks for your work\nRegards\nTimothy', 'title': u'Nice Code'}], 'desc': u'Easily extract data from microsoft excel files using this wrapper class for xlrd (http://www.lexicon.net/sjmachin/xlrd.htm). The class allows you to create a generator which returns excel data one row at a time as either a list or dictionary. I found this very handy for easily pulling in a variety of excel files without having to deal with COM calls or even needing to have windows.'}, {'comments': [{'comment': u'As the subject says, this method is no more secure than plain md5. If there are collisions in md5, then your method will also produce collisions. Even worse; if there were collisions in sha1 of input strings of 16 bytes (combinatorically this is far more likely than not), then your method will have worse security than md5.', 'title': u'This method is no more secure than plain md5.'}, {'comment': u'I suppose I should add that MD5 is effectively broken (one can generate collisions in seconds on a modern machine), so this "secure" scheme is actually quite insecure.', 'title': u' '}], 'desc': u'Generate hashes and compare them, with a very secure hash generation function.'}, {'comments': [{'comment': u'Oops, there should be an import sys at the top.', 'title': u"Don't forget to import sys"}, {'comment': u"Problem 1: this doesn't actually stop the function after the timeout. It leaves it running (in a seperate thread), still consuming resources.<br>\n<br>\nProblem 2: this isn't reliable. It can't interrupt functions that don't release the GIL. In fact, it can't interrupt functions that never return to the ceval loop. Here's an example:\n\n<pre>\n@timelimit(3)\ndef unstoppable():\n import itertools\n print list(itertools.ifilter(None, itertools.repeat(0)))\n\nunstoppable()\n</pre>", 'title': u'Two obvious problems'}], 'desc': u'Have a function that you want to put a time limit on? Just use this decorator like so:\n\n@timelimit(10)\ndef myfunction(...): ...\n\nwill limit myfunction to 10 seconds, raising TimeoutError if it takes longer.'}, {'comments': [{'comment': u"Function txt2img has 'imgformat' as argument but it never used it.", 'title': u'Unused function argument'}], 'desc': u'In the Web domain, sometimes it is necessary to dynamically create images containg just text. This recipe uses PIL to do just that, and it can be integrated to Zope/Plone through External Methods.'}, {'comments': [], 'desc': u"If you're administering a number of machines and each account on these machines has a number of cronjobs this recipe can be used to generate an HTML report listing all crontabs on all your machines. You can use this script in a cronjob to regenerate this report periodically."}, {'comments': [{'comment': u'I did test this under Ubuntu Linux. The recipe runs, but does create an exception on exiting, probably due to the way you close the app:\n\n<pre>\n$ python pbardemo.py\nTrue\nTraceback (most recent call last):\n File "pbardemo.py", line 51, in pbrm\n self.close(None)\n File "pbardemo.py", line 57, in close\n self.dlg.Destroy()\n File "/usr/lib/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/_core.py", line 13208, in __getattr__\n raise PyDeadObjectError(self.attrStr % self._name)\nwx._core.PyDeadObjectError: The C++ part of the ProgressDialog object has been deleted, attribute access no longer allowed.\n*** glibc detected *** corrupted double-linked list: 0x08171a60 ***\nAborted\n</pre>', 'title': u'problems on Linux'}], 'desc': u'I come across some cases, where I need to hook a progress bar from WX to my current running python project/script to indicate the current process progress.\nSome how if you use MainLoop() in child thread will cause the WX session hang and EVT handle will failed.\nAfter some study, found that WXAPP class instance and MainLoop have to same namespace.\nI manage to redesign it and make it work now.\nJust mail/vote me, if you feel this is useful for your project.\nE-Mail : cheengshuchin@gmail.com'}, {'comments': [], 'desc': u'This code implements a cache (CacheHandler) and a throttling mechanism (ThrottlingProcessor) for urllib2. By using them, you can ensure that subsequent GET requests for the same URL returns a cached copy instead of causing a roundtrip to the remote server, and/or that subsequent requests to a server are paused for a couple of seconds to avoid overloading it. The test code at the end explains all there is to it.'}, {'comments': [{'comment': u'At http://dnspentest.sourceforge.net there is a good fakeDNS server written in java.\nI have tested it and i can say that it is very stable.\nProbably, as the project says, it will be a part of DNS pentest suite.\nBye', 'title': u'There is anoter good fakeDNS sever written in java'}], 'desc': u'Minimal python dns server, it only replies with a selected ip in an A record'}, {'comments': [], 'desc': u'Recipe/Tools for easy and stable recursion of current function when only selected arguments have to be changed. No more mixup of argument positions/names. No more forgetting. Useful as well for realizing delayed/repeated/serialized function calls.'}, {'comments': [{'comment': u'<pre>>>> x = [3, 1, 0, None, 2, 4, None]\n>>> ix = range(len(x))\n>>> def key(i, x=x):\n... elem = x[i]\n... return elem is None, elem\n...\n>>> ix.sort(key=key)\n>>> [x[i] for i in ix]\n[0, 1, 2, 3, 4, None, None]\n\n\n\n</pre>', 'title': u'You can use a key function to move None to the end'}, {'comment': u'Thanks for the tip. It can also be used in processing missing values which may not be coded as None. Have revised the code.', 'title': u' '}], 'desc': u'The routines rank() and order() outputs the ranks and ordering of the elements of a list. Missing values are indicated by None and ranking have first, min, max, random alternatives just like in R.'}, {'comments': [], 'desc': u'Recipe/tool for turning exception handling into functional alternation.\n\ntry..except clauses make Python source code often clumsy and impact the readablity. This recipe presents a simple functional approach to work with exceptions and finalizations - applicable in a majority of cases.'}, {'comments': [{'comment': u'When you know the position of the argument in the function\'s argument list, you can use the standard function attribute "func_defaults".<br>\n<br>\n<pre>\ndef func(foo, bar="baz", spamm="eggs"):\n pass\n\n# index not counting non-default args\nprint func.func_defaults[1]\n\n... will print "eggs"\n\nSee http://www.python.org/doc/2.4.3/ref/types.html#l2h-76</pre>', 'title': u'Easier when you know the position of the argument'}], 'desc': u"Simple recipe for finding out a function argument's default value.\n\nCan be used as a poor-man's function attribute, see the examples."}, {'comments': [], 'desc': u'Code coverage testing is very useful especially for dynamic languages, it can easily give a view of the unused parts of your code. Not that this method is able to prove that statements are dead code, but instead help to prevent from syntax errors and to force yourself to think about your code, to find the right test cases reaching the unused statements.\n\nIn that sense, the module coverage.py [1] made by Ned Batchelder [2] is very useful and efficient.\n\nThe analysis returned by this module is very accurate, but as unreached lines numbers are not very readable by itself, this recipe simply generate an html output highlighting unreached lines. This recipe is directely based upon a source code colorizer [3] derived from this recipe [4].\n\n[1] http://www.nedbatchelder.com/code/modules/coverage.py\n[2] http://www.nedbatchelder.com\n[3] http://chrisarndt.de/en/software/python/colorize.html (Chris Arndt)\n[4] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298 (J. Hermann)'}, {'comments': [{'comment': u'http://www.jacobian.org/2006/mar/02/django-at-pycon/', 'title': u'See also'}], 'desc': u"This code uses the constraint package (http://labix.org/python-constraint) to solve sudoku puzzles. It's designed to be flexible, though i've only tested it with 9x9 puzzles with 1-9 as possible values. In theory it should be able to solve puzzles of different sizes comprised of letters or symbols instead of numbers."}, {'comments': [], 'desc': u"This was written as an underhanded solution to an problem in an online programming challenge (http://www.spoj.pl) that required converting simple arithmetic expressions from infix to postfix form. I thought the solution was pretty neat, and I suspect the general technique may be useful for other problems so i'm including it here."}, {'comments': [], 'desc': u'Kexec is a mechanism to use linux itself to load a new kernel without going \nthrough the BIOS thus minimizing down time. \nThis script kexecs the newest kernel on the system managed by rpm (assumes a Redhat like system).'}, {'comments': [], 'desc': u'Easy-to-use framework which makes threading almost as simple as normal function calling.\n\nBackgroundCall is a high-level (threading.Thread replacement) concept for non-blocking execution of time consuming functions - yet it focuses naturally on result-returning/conscious termination in a functional style (without imposing an extra Java-style alter ego class layout). It also handles exception (transfer) issues.\n\nSee also the twin brother recipe "CallQueue".'}, {'comments': [], 'desc': u'A framework for easy (2-way) inter-thread communication resembling normal function calling. \n\nEspecially useful for non-blocking UI techniques and for load distribution on jerky resources. Can replace stiff Queue.Queue techniques in most cases - making threading code more readable and functional.\n\nCallQueue lets you express function directly in local context, but execute things in a target thread. It focuses naturally on 2-way communication (with return value responses) and includes a fluid concept for inter-thread exception (transfer) issues. Supports also multi-producer, multi-consumer communication. \n\nA target thread just has to do callqueue.receive() periodically without worrying about any data passing. Thus CallQueue also supports naturally a high-level bulk threading concept with anonymous "default consumer threads": Allocated "thread resources" can be thrown efficently on bunches of jobs.'}, {'comments': [{'comment': u"This has the flaw that it assumes we aren't really merging iterables but sequences, or at least absolutely-lengthed, probably sorted already iterables. A really efficient imerge would not pull everything into a heapq before even the first iteration. what a hit if you just need the first!<br>\n<br>\nThat is why the original recipes, tho more complicated than need be, tried to look at the next values for each iterable, find which should be next, and yield it immediately. That is a large value in the use of iterators and the whole concept.<br>\n<br>\nAnyway, if you do need to just sort sequences or non-infinite iterators, this is a lot cleaner and falls back on trusting the built-in sorted to be faster than anything else:<br>\n<br>\n<pre>\ndef merge(*iters):\n iters = list(iter(i) for i in iters)\n while iters:\n for i in iters:\n try:\n yield i.next()\n except StopIteration, e:\n iters.remove(i)\n\nprint sorted(merge([1,2,3,5], [4,5]))\n</pre>", 'title': u'Iterable Merge or Sequence Merge?'}, {'comment': u'forget i said anything. dang ASPN, where is the comment delete button?!', 'title': u'OOPS'}, {'comment': u'def merge(*iters):\n myIters = (iter(i) for i in iters)\n for i in myIters:\n while True:\n try:\n yield i.next()\n except StopIteration, e:\n break\nprint sorted(merge([1,2,3,5], [4,5]))', 'title': u'improve for the privious version'}, {'comment': u"it seems that rather than doing this:\n<pre>\n while h:\n v, next = heappop(h)\n yield v\n try:\n v = next()\n except StopIteration:\n continue\n heappush(h, (v, next))\n</pre>\n\ndoing this might be slightly more efficient (i.e. you don't push iterators for iterables that have no more items back on the stack):\n\n<pre>\n while h:\n v, next = heappop(h)\n yield v\n try:\n v = next()\n heappush(h, (v, next))\n except StopIteration:\n continue\n</pre>\nnot too familiar with the heapq module though ;-)", 'title': u"why push v when we know there's no more there?"}, {'comment': u"The push step doesn't get reached when the preceding step raises StopIteration.", 'title': u'v stops getting pushed when emtpy'}], 'desc': u'Memory efficient multi-way iterator merge.'}, {'comments': [{'comment': u'The example is corrupted. What is in sphere.h?', 'title': u'Example broken'}, {'comment': u"Fixed the recipe's example discussion.", 'title': u' '}], 'desc': u'A simple python function to automate using the swig process for creating C modules for use inside Python.'}, {'comments': [], 'desc': u'Associates or launches an action to be performed by the os based on\nfilename extension. For example, assoc.py -e test.c will launch emacs.'}, {'comments': [], 'desc': u"The following recipe provides a simple\nsimulation of secondary memory and is\nprimarily designed to provide a driver\ninterface to a virtual hard drive. The\ninterface is simple and allows the\nsimulation of IO errors. Also provided\nare methods that allow efficient storage\nare retrieval of a disk object on the\ncomputer's file system."}, {'comments': [], 'desc': u'The class presented bellow (Disk Abstraction\nLayer 1) is designed to provide a very easy\ninterface to work with secondary memory\nwhere IO errors may occur and data is\nworked with in blocks. DAL1 allows access\nto a hard drive (via its driver) so that\nit can be accessed in a file-like way.\nIO errors are also taken care of at this\nlevel (which can cause problems at extremely\nhigh probabilities of failure.'}, {'comments': [], 'desc': u'The class DAL2 provides a way to label\nblocks on a hard drive while storing\nsuch information on the hard drive\nitself. The information is kept in the\nBIT (Block Information Table) and is\nwritten out to disk when appropriate.\nOtherwise, the BIT is kept in memory\nfor efficiency. The hard disk is again\npresented as a collection of blocks but\ncompletely hides disk IO as a result of\nDisk Abstraction Layer 1.'}, {'comments': [], 'desc': u'Disk Abstraction Layer 3 provides a more\nuseful framework for secondary memory and\nprovides an abstract interface for\nimplementing a generic file system. It\nrenumbers the blocks on the hard drive to\nstart at block 1 so that block 0 can be\nconsidered a NULL reference. At a lower\nlevel, block 0 would be seen to be where\nthe OS can keep a seed for its random\nnumber generator (interface provided).'}, {'comments': [], 'desc': u'While DAL3 created and enforced a distinction\namong directory blocks, file blocks, and\ndata blocks (along with providing an easy\ninterface to directory blocks and files blocks),\nDAL4 introduces the concept of linking all of\nthese blocks together and giving names to\ndirectories and files. While still primitive,\nthe file system is now unified and allows more\nadvanced abstractions to be built on top of it.'}, {'comments': [], 'desc': u"DAL5 continues to refine the file system's\ninterface and provides methods that should\nlook similar to what most programmers are\nused to working with. Files have still not\nbeen completely abstracted away and all\npath names must be given as relative to\nthe root. The path separator is defined\nin this module along with a list of\ncharacters for valid file and directory names."}, {'comments': [], 'desc': u'DAL6 provides the cap of the Disk Abstraction\nLayers and a way to create Context objects.\nThese Context objects provide relative paths\nand keep track of the Currect Working\nDirectory. A method for renaming was\naccidentally left out of the API. This\nrecipe also provides a full abstraction for\nfiles involving full buffering and including\nmost of methods that should be expected.'}, {'comments': [], 'desc': u'This is the final stage to the file system\nprovided in previous recipes. A test of\nthe seven other modules is shown here that\ndemonstrates the abilities of this abstract\ndesign. Working disks is provided via a\nsimple introductory menu, disk failure rate\nis fully customizable. A shell is provided\nwith several commands that built in along\nwith two programs that allow the creation\nand viewing of files.'}, {'comments': [], 'desc': u'Implements the three standard relational join algorithms: nested loops join, hash join, and merge join, using the iterator algebra support in Python 2.4. This recipe presents code that can be used for inner join, left outer join, full outer join, and semijoins. The nested loops join supports a theta join.'}, {'comments': [], 'desc': u'Python allows a very high level and clean solution to control break reporting problems. This time we use a dictionary and a list to create summary reports.'}, {'comments': [], 'desc': u'protect_utf8 is a function decorator that can prevent naive\nfunctions from breaking UTF-8.'}, {'comments': [], 'desc': u'A persistent, lazy, caching, dictionary, using the anydbm module for persistence. Keys must be basic strings (this is an anydbm limitation) and values must be pickle-able objects.'}, {'comments': [], 'desc': u'Progress bars are popular when trying to\nshow how much of a job has been completed.\nIn my case, it was encrypting and decrypting\nfiles. A GUI interface was written, but\nsomething was lacking. How was the user of\nthe program supposed to know if the program\nwas doing its job? A progress bar seemed like\na good answer, so a simple GUI progress bar\nwas written using Tkinter.'}, {'comments': [], 'desc': u'The Timer class was originally written to\nbe used in conjuction with a Progress Bar\nand a custom driver function. Three example\nfunctions are given in discussion to help\nbetter illustrate how this can be used.'}, {'comments': [{'comment': u"'chomp' removes the newline only. An equivalent call would be:\n\n<pre>strvar = strvar.rstrip('\\n')</pre>\n\nA bare 'rstrip' removes all whitespace from the end.", 'title': u'Not quite the same as chomp'}], 'desc': u'This is almost too trivial, but perhaps it will be useful to perl fugitives searching for a pythonic way to remove line endings from strings.\n\nThe answer: use rstrip()'}, {'comments': [], 'desc': u'Creates inclusive regular sequences or fully closed ranges which differs from the half-open ranges of Python. Also accepts floating point arguments.'}, {'comments': [], 'desc': u'Enriches (return) values transparently with extra data.'}, {'comments': [{'comment': u'try weeding out duplicate values first:\n\ntmplst = list(set(tmplst))\ntmplst.sort()\nstart = tmplst[0]\n...', 'title': u"only works if list doesn't contain duplicate values"}, {'comment': u'See http://www.python.org/doc/current/lib/itertools-example.html\n\n<pre>\n>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]\n>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):\n print map(operator.itemgetter(1), g)\n \n[1]\n[4, 5, 6]\n[10]\n[15, 16, 17, 18]\n[22]\n[25, 26, 27, 28]\n</pre>', 'title': u'Contrast with the example in the itertools docs'}, {'comment': u'Thank you for your comment! \nI forgot duplicate values.', 'title': u'duplicate values'}], 'desc': u"This code makes ranges of contiguous numbers from a list of integers.\nEach range is 2-integers-tuple which is same as for builtin range() function's argument."}, {'comments': [{'comment': u'I was fetching Bloomberg data using COM and the trade times came back as PyTime objects. This handled the conversion perfectly.', 'title': u'Worked great for me'}], 'desc': u'This recipe show how to convert OLE datetime values (as used by PyTime from the pywin32 extensions) into Python datetime objects.'}, {'comments': [{'comment': u"See: http://www.python.org/doc/current/lib/deque-recipes.html\n<pre>\n>>> print list(roundrobin([1,2,3], ['a','b'], [4], [-1,-2,-3,-4]))\n[1, 'a', 4, -1, 2, 'b', -2, 3, -3, -4]\n</pre>", 'title': u'Compare with the roundrobin() recipe in the docs for collections module'}], 'desc': u'This recipe splices any number of nonempty lists as one list. Each input list may be of different length. Elements of shorter lists may be recycled when the keyword argument recycle is set to True. Any error result in an empty output list.'}, {'comments': [{'comment': u'urllib.urlretrieve will do this. One problem with the code as given is that the entire file will be read into memory, and then written out to the file; briefly, but for a moment your program could get very memory hungry. urlretrieve will write the file out in chunks. shutil.copyfileobj will also copy between file objects in a chunked manner.', 'title': u'urllib'}, {'comment': u'Thank you a lot Ian. I will bare this in mind.', 'title': u'Tip appreciated.'}, {'comment': u'Would it be better to take a optional local file name ? You current code might clobber an important local file.<br>\nIt really depends on what the use context is.', 'title': u"What's its use ?"}, {'comment': u"http://www.gnu.org/software/wget/<br>\n\nI use this extensively for downloading images, using something similar to this:<br>\n\nos.system('wget %s -a log.log' % fullurl)", 'title': u'wget is available for Windows'}], 'desc': u'This script reads the contents of a web file and copies them into a local file, named the same as the web file.'}, {'comments': [{'comment': u'You need to add some error handling to the code. If a call to the decorated function ever raises an exception then all subsequent calls to the function will return garbage. e.g.\n\n<pre>\n>>> factorial(3)\n6\n>>> factorial(\'a\')\n\nTraceback (most recent call last):\n File "<pyshell#5>", line 1, in -toplevel-\n factorial(\'a\')\n File "<pyshell#1>", line 12, in result\n tc = g(*args,**kwd)\n File "<pyshell#3>", line 6, in factorial\n res = factorial(n-1, n*acc)\nTypeError: unsupported operand type(s) for -: \'str\' and \'int\'\n>>> factorial(3)\n(\'continue\', (3,), {})\n</pre>', 'title': u'This decorator is a bit fragile'}, {'comment': u'<pre>\nclass tail_recursive(object):\n CONTINUE = object() # sentinel\n \n def __init__(self, func):\n self.func = func\n self.firstcall = True\n\n def __call__(self, *args, **kwd):\n try:\n if self.firstcall: # start looping\n self.firstcall = False\n while True: \n result = self.func(*args, **kwd)\n if result is self.CONTINUE: # update arguments\n args, kwd = self.argskwd\n else: # last call\n break\n else: # return the arguments of the tail call\n self.argskwd = args, kwd\n return self.CONTINUE\n except: # reset and re-raise\n self.firstcall = True\n raise\n else: # reset and exit\n self.firstcall = True \n return result\n</pre>', 'title': u'This version is more robust against exceptions'}], 'desc': u'A new tail recursion decorator that eliminates tail calls for recursive functions is introduced. '}, {'comments': [], 'desc': u'This simple import hook can resolve Windows shortcuts refering to directories. This allows Windows users to simulate UNIX directory structures which contain symlinks.'}, {'comments': [{'comment': u"I've tried this function and did some benchmarks with a 5GB file. The win32file.CopyFile function was consistently 40-50% faster than this function and over 300% faster than shutil.copyfile.\n\nIn which situations is your function faster than win32file.CopyFile?", 'title': u"Not quite sure what's better than win32file.CopyFile"}], 'desc': u'This recipe uses pywin32 in order to copy files making use of the win32file.FILE_FLAG_SEQUENTIAL_SCAN, which makes much more efficient use of the system cache (only a few megabytes are consumed instead of caching the whole file).'}, {'comments': [], 'desc': u'A generic attribute container, with pretty printing and recursion protection'}, {'comments': [{'comment': u'I love it.', 'title': u'cool!'}, {'comment': u'http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496697', 'title': u'the Container recipe (link)'}, {'comment': u'Interesting, but this is in the wrong category. "Extending" refers to loading symbols into the Python interpretter, via either a dynamic library or recompiling the interpretter itself.\n<br><br>\nExtending the Exception class would go under "Object Oriented", maybe.', 'title': u'Wrong category'}], 'desc': u'an Exception base-class that supports keyword arguments and pretty printing'}, {'comments': [], 'desc': u"This recipe adds logging support to SimpleXMLRPCServer using Python's logging module. The server will log the client IP, the client's XML request and the server's XML response."}, {'comments': [{'comment': u'I\'ve found in the following lines a missing \'[\' and \']\' in string comprehension\n<br>\n1. padding = min([len(l) - len(l.lstrip()) for l in lines if l.strip()])\n<br>\t\t\t\t\n2. unpadded = "\\n".join([l[padding:] for l in lines])\n<br>\nThanks for the code. Nice indeed\n<br>\nOscar', 'title': u'There are a couple of errors in published code'}, {'comment': u'And totally cool.', 'title': u'Shrewd!'}, {'comment': u'python 2.4 has generator expressions, i.e.<br>\n<br>\n>>> (x for x in range(10))<br>\n<generator object at 0x009ED0F8><br>\n<br>\n\n-tomer', 'title': u'these are generator expressions'}, {'comment': u"Having to escape only '${' outside code and only '}$' inside code can be a bit confusing, and IMO should be more noticeably and clearly noted in the documentation (or changed). I admit that the choice of delimiters is such that not much escaping will probably be needed in day-to-day use; still, someone getting the escaping wrong could have a time understanding why.\n<br><br>\nPersonally I would prefer to have to escape both '${' and '}$' everywhere, for better uniformity. Of course, this is a personal preference.", 'title': u'Escaping delimiters'}, {'comment': u"Very nice. That's just the right amount of markup for embedding Python into html documents.", 'title': u' '}, {'comment': u'According to Python doc "eval(value, namespace)" should only be used\nfor value compiled as "eval" and for "exec" you should use instead\n"exec value in namespace". Which worked.', 'title': u'exec instead of eval'}], 'desc': u'A light-weight, fully functional, general purpose templating engine, in just 40 lines of code'}, {'comments': [{'comment': u"<pre>\nnewer version, can now import from list\n\nNote: the first param is a list..\nimport_once( ['os', 'sys'] )\n\nThanks :D\n</pre>", 'title': u'newer version...'}, {'comment': u"The import statement already has run-once semantics, so I'm not sure I see the purpose of this.", 'title': u'Motivation?'}, {'comment': u'I made this because I was using mutiple classes from multiple scripts and those scripts usually have similar "import os", "import sys". I have then notice that it is slow when it reimports the module...\nAfter I used import_once(\'os\'), the difference on speed is really noticeable on my SLOW computer.\nbtw, I was using it on a CGI server. \n<br>\nThanks for the comment', 'title': u' '}], 'desc': u'I just like to share this...\nplease feel free to comment/suggest on it'}, {'comments': [], 'desc': u'This recipe creates a metaclass, that can be used in any dict-like object to map specially named attributes to keys of that dictionary.\n\nBy default, such attributes are those whose name begin with one (and only one) underscore, and they are mapped to the dictionary key of the same name, without the underscore; but the method to determine that behavior is overridable.\n\nFor instance, accessing:\n d._somekey\nwould return:\n d.["somekey"]\n\nCreation, update and deletion of such attributes works as expected.'}, {'comments': [], 'desc': u"A class that makes generating Table easier (based from Gmail' sidebars) ...\nscreenshots on...\nhttp://fedmich.googlepages.com/FMLPython.gif\n\n\nFeatures:\nCollapsable mode\nColor Edge (Blue/Green)\nHighlight / Select rows\n\nNote: some images are used (triangle, edges)... download it from \nhttp://fedmich.googlepages.com/FMLimages.zip\n\nExtract the files on this format...\n\\bin\\<b>test.py</b>\n\\bin\\<b>FML.py</b>\n\\images\\triangle*.gif\n\\images\\edges*\n\nSave the two files using it's filename and run Test.py on your python CGI \nwebserver."}, {'comments': [], 'desc': u'While I have seen many permutation recipes on this site, there seems to be no recipe yet which shows how to generate the permutations of a "bag". A bag is like a set but can contain elements more than once.'}, {'comments': [], 'desc': u'This is an extension of recipe 304162. It adds a function that can be used to specify multiple keys to group on.'}, {'comments': [{'comment': u"I often wish objects would work with string formats. I normally add __getitem__ to my own classes, but it is a nuisance overriding other people's classes just to make them work with string formats. Your class solves the problem nicely.", 'title': u'Great solution to something I often want to do'}], 'desc': u'QuackTemplate.Wrapper is a template helper class: it takes arbitrary Python objects and uses__gettitem__ so that the wrapped object can be passed into the standard Python string substitution mechanism. It can follow method calls, dict keys and list members (to some extent).'}, {'comments': [{'comment': u'The script seems to work just fine on MacOS X. Here is an example\n<pre>\n[~] % python ./Thread.py with\n1\n1\n2\n2\n3\n3\n^CKeyBoardInterrupt\n[~] % \n</pre>\n\n/Jean Brouwers\n<br><br>\nPS) This is the ActiveState Python 2.4.3 build 11 for MacOS X PPC running on MacOS X 10.3.9.', 'title': u' '}], 'desc': u'Multithreaded Python programs often ignore the SIGINT generated by a\nKeyboard Interrupt, especially if the thread that gets the signal is\nwaiting or sleeping. This module provides a workaround by forking a\nchild process that executes the rest of the program while the parent\nprocess waits for signals and kills the child process.'}, {'comments': [{'comment': u'when i started this code, i got:\n\nFile "xtea.py", line 33, in __main__\nFailed example:\n z.encode(\'hex\')\nExpected:\n \'fe196d0a40d6c222b9eff3\'\nGot:\n \'dbb956b5e4c7be33f6cb5d\'\n**********************************************************************\n1 items had failures:\n 1 of 5 in __main__\n***Test Failed*** 1 failures.\n>Exit code: 0', 'title': u'error'}, {'comment': u'Sorry for the problem - I made some changes to the doctest to the master version and tried to edit the version here to match however got this wrong. This should now work correctly.\n\nThanks for pointing this out.\n\nPaul ', 'title': u'Doctests Fixed'}, {'comment': u'With the extended Euclid GCD algorithm and large (likely) prime generation recipes here in the cookbook, it would be fairly trivial to write an RSA cryptosystem implementation in Python, which is usable for more than just obfuscation.', 'title': u' '}], 'desc': u'This is a simple python implementation of the XTEA block encryption algorithm (http://www.cix.co.uk/~klockstone/xtea.pdf). For details please see docstrings in the code.'}, {'comments': [{'comment': u'(1) in function "_create_class_proxy":\nreplace line\n "if hasattr(theclass, name):"\nwith\n "if hasattr(theclass, name) and not hasattr(cls, name):".\n\n(2) in function "__new__":\nremove line\n "theclass.__init__(ins, obj, *args, **kwargs)" \nbecause it will be done by python itself becouse isinstance(ins, cls)', 'title': u'2 bugs'}], 'desc': u'transparent object proxying for (almost) all objects. '}, {'comments': [], 'desc': u'Uses object proxying to expose a more intuitive interface to shelves. Requires the Proxy recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496741).'}, {'comments': [], 'desc': u'HTML-element tree declaration that emits nice HTML'}, {'comments': [{'comment': u"I personally dislike the magic in _strategies's indexes, and Python altruistically casting booleans to 0/1... :)", 'title': u'Cool idea!'}, {'comment': u'<pre>\ntmp = TempFile("some",100)\ntmp.write("stuff")\nfileno = tmp.fileno()\ntmp.write("other stuff")\n</pre>\n\nWhat is the contents of tmp now? I suspect you may have lost the "somestuff" part of the buffer when you asked for a fileno?', 'title': u'What happens when...'}, {'comment': u'> tmp = TempFile("some",100) <br>\n> tmp.write("stuff") <br>\n> fileno = tmp.fileno() <br>\n> tmp.write("other stuff") <br>\n<br>\n> What is the contents of tmp now? I suspect you may have lost the <br>\n> "somestuff" part of the buffer when you asked for a fileno? <br>\n<br>\nYou\'re right. I\'ve edited the recipe so that it writes the content of\nthe buffer to the file before calling fileno. It should work correctly now.', 'title': u' '}], 'desc': u'From PEP 42...\n\nI wonder if it would be a good idea to have a new kind of\ntemporary file that stored data in memory unless:\n\n - The data exceeds some size, or\n\n - Somebody asks for a fileno.\n\nThen the cgi module (and other apps) could use this thing in a\nuniform way.'}, {'comments': [], 'desc': u'A metaclass that allows the runtime creation of parent references, without needing to pass them on the command line. For example:\n\na.b -> (points to) b\nb.creator -> (points to) a'}, {'comments': [{'comment': u'I can\'t comment on the safety mechanism, but your exec_timed might be more responsive for short evaluations if you use thread.join(timeout) instead of a sleep-loop with a one-second interval. One second can be a looong wait sometimes. :-) You would still need to check "signal_finished" or something like it, since the timeout will not throw an exception (you can\'t differentiate between a normal thread-death and a timeout).', 'title': u'thread.join?'}, {'comment': u'The timeout mechanism has no effect if eval finishes within the timelimit and I think the 1 second granularity for the timout is pretty reasonable. By checking the "signal_finished" flag every second I make sure that the "alarm" thread doesn\'t stick around long efter were done with "eval".', 'title': u' '}, {'comment': u"Sorry, I read your code backwards; now I see what you're doing here.", 'title': u'right'}, {'comment': u'If you try to import this as a module (using 2.4) an assertion error is raised:\n\n File "safeeval.py", line 121, in ?\n assert(is_valid_builtin(name))\nAssertionError\n\nIt works fine when run alone with the unit tests. Why this happens is beyond me, even after a few minutes looking at the code.', 'title': u'Assert error'}, {'comment': u'The current recipe use __builtins__, whose value is different when the module is imported. This is an old warth in Python. To get consistent behaviour, the recipe should use "__builtin__" instead, with an "import __builtin__" at the beginning.', 'title': u'Assert error'}, {'comment': u'There is still some possible DOS even with this versione of safe_eval. For instance, try:\n\n<pre>\nsafe_eval(82173821737213782173821739921**881230980921832173821732132323798321)\n</pre>\n\nYou will still need a manual CTRL+C to break. I think this is related\nto the fact that the Python interpreter does not release the GIL during\nlarge multiplications, so the alarm thread does not get its chance to break in. Not sure about possible solutions...', 'title': u'Possible DOS: large multiplication'}, {'comment': u"It's not clear to me why you ban raise statements.\n\nAlso, I assume you restrict try/except and try/finally to prevent the code from catching the KeyboardInterrupt raised by the monitor thread. \nIf I don't care about the timeout functionality is there any danger in allowing try/except/finally blocks? For example, looks like you block access to traceback attributes -- are there other dangerous things you can access through the exception object? ", 'title': u'why restrict raise?, etc.'}, {'comment': u"Would a solution be to also filter out large numbers? I guess you only need to worry about multiplication, exponentiation, and maybe division.\n\nYou could at least remove obvious large arguments to these operators. I'm not sure how you would protect against 2*2*2*2*2*2*2*2....", 'title': u' '}, {'comment': u'> I guess you only need to worry about multiplication, <br>\n> exponentiation, and maybe division. <br>\n\nNo - what about the Ackermann function?', 'title': u' '}, {'comment': u'Any ideas on how to safely allow at least some imports such as random, and re?', 'title': u'imports?'}], 'desc': u'Provides a retricted enviroment for dynamically executing a subset of the Python language suitable for configuration scripts, end-user oriented scripting and storing data in a user-friendly way.'}, {'comments': [{'comment': u'\xe2_\xf8 You don\'t need a \'global\' declaration just to read a global variable.<br>\n\xe2_\xf8 wlist.remove("") in iwordlist(v) will fail when v both starts and ends with a word. When v both starts and ends with non-word chars an empty string will remain in the worldlist.<br>\n\xe2_\xf8 The .strip() method in collapse() has no effect.<br><br>\n\nIn general, when you are dealing with non-ascii characters you should use Python\'s unicode strings. They often do the right thing out of the box:\n<pre>\n>>> print u"I\u0192I1I3I\xbcI\xb1".upper() # sigma in greek letters\nI\xa3ITI"IoI` # SIGMA in greek letters\n</pre>', 'title': u'Random remarks'}, {'comment': u'From Aaron Bentley\'s comment in "the Unicode Hammer" recipe at<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/251871 \n\n<pre>\n>>> s=u"\\N{LATIN CAPITAL LETTER A WITH ACUTE}"\n>>> s\nu\'\\xc1\'\n>>> import unicodedata\n>>> unicodedata.normalize(\'NFKD\', s).encode(\'ASCII\', \'ignore\')\n\'A\'\n>>> s=u"G\\N{LATIN SMALL LETTER O WITH DIAERESIS}teborg - Espa\\N{LATIN SMALL LETTER N WITH TILDE}a"\n>>> unicodedata.normalize(\'NFKD\', s).encode(\'ASCII\', \'ignore\')\n\'Goteborg - Espana\'\n>>> \n</pre>', 'title': u'stripping diacritics'}], 'desc': u'While processing text I felt some functions are missing, espacially for international texts. Here are some helpers.'}, {'comments': [{'comment': u'Adding the following to odict should allow its constructor to act like the dict() factory function, will preserve element order when converting from ordered sequences, and should repr() in order.\n\n<pre> def __init__(self, data=None, **kwdata):\n self._keys = []\n self._data = {}\n if data is not None:\n if hasattr(data, \'items\'):\n items = data.items()\n else:\n items = list(data)\n for i in xrange(len(items)):\n length = len(items[i])\n if length != 2:\n raise ValueError(\'dictionary update sequence element \'\n \'#%d has length %d; 2 is required\' % (i, length))\n self._keys.append(items[i][0])\n self._data[items[i][0]] = items[i][1]\n if kwdata:\n self._merge_keys(kwdata.iterkeys())\n self.update(kwdata)\n\n\n def __repr__(self):\n result = []\n for key in self._keys:\n result.append(\'%s: %s\' % (repr(key), repr(self._data[key])))\n return \'\'.join([\'{\', \', \'.join(result), \'}\'])\n\n\n def _merge_keys(self, keys):\n self._keys.extend(keys)\n newkeys = {}\n self._keys = [newkeys.setdefault(x, x) for x in self._keys\n if x not in newkeys]\n\n\n def update(self, data):\n if data is not None: \n if hasattr(data, \'iterkeys\'):\n self._merge_keys(data.iterkeys())\n else:\n self._merge_keys(data.keys())\n self._data.update(data)</pre>\n\nAnd some tests:\n\n<pre>>>> odict({\'one\': 2, \'two\': 3})\n{\'two\': 3, \'one\': 2}\n>>> odict({\'one\': 2, \'two\': 3}.items())\n{\'two\': 3, \'one\': 2}\n>>> odict({\'one\': 2, \'two\': 3}.iteritems())\n{\'two\': 3, \'one\': 2}\n>>> odict(zip((\'one\', \'two\'), (2, 3)))\n{\'one\': 2, \'two\': 3}\n>>> odict([[\'two\', 3], [\'one\', 2]])\n{\'two\': 3, \'one\': 2}\n>>> odict(one=2, two=3)\n{\'two\': 3, \'one\': 2}\n>>> odict([([\'one\', \'two\'][i-2], i) for i in (2, 3)])\n{\'one\': 2, \'two\': 3}\n>>> odict({\'one\': 1}, one=2)\n{\'one\': 2}\n>>> dict({\'one\': 1}, one=2)\n{\'one\': 2}</pre>\n\nAnd I suppose you could add this so you aren\'t copying self._keys when calling __iter__:\n\n<pre> def __iter__(self): \n for key in self._keys:\n yield key</pre>\n\nAlso, you probably should have named this "OrderedDict", to go along with the Python naming conventions.', 'title': u'Some Suggestions'}, {'comment': u"Whoops, messed up __repr__ there. It should probably be something like this:\n\n<pre> def __repr__(self):\n result = []\n for key in self._keys:\n result.append('(%s, %s)' % (repr(key), repr(self._data[key])))\n return ''.join(['OrderedDict', '([', ', '.join(result), '])'])</pre>", 'title': u'__repr__ Fix'}, {'comment': u'Also, if you wanted to add slicing support, this should work:\n\n<pre> def __getitem__(self, key):\n if isinstance(key, slice):\n result = [(k, self._data[k]) for k in self._keys[key]]\n return OrderedDict(result)\n return self._data[key]</pre>', 'title': u'Slicing'}, {'comment': u'odict is a not really a dictionary. it can not be used as replacement of a dictionary.\n\nfor example the following code fails.\n\n<pre>\n>>> from odict import odict\n>>> def f(a, b): return a+b\n... \n>>> d = odict()\n>>> d[\'a\'] = 1\n>>> d[\'b\'] = 2\n>>> \n>>> d\n{\'a\': 1, \'b\': 2}\n>>> \n>>> f(**d)\nTraceback (most recent call last):\n File "", line 1, in ?\nTypeError: f() argument after ** must be a dictionary\n</pre>', 'title': u'odict not a dictionary'}], 'desc': u'An Ordered Dict records the order in which items are added. This implementation uses much less code than the others by extending not well-known class DictMixin.'}, {'comments': [{'comment': u'The UI would greatly benefit from using cmd module. Check it out.', 'title': u' '}], 'desc': u'This little program is used to be record all your daily expenses.\nIt stores all data in SQLite.'}, {'comments': [], 'desc': u"Nothing fancy, just a script for encrypting/decrypting small files. The -c option is handy for those password files you'd rather leave obfuscated.\n\nAny suggestions on making it pipeable, more secure, or suitable for large files are welcome."}, {'comments': [], 'desc': u"This function allows you to set process priority under windows. It defaults to setting the priority of the current python process but can set anything for which you have a process ID. I find it handy to set a long-running job with lower than normal priority so the computer doesn't feel sluggish while it runs."}, {'comments': [{'comment': u"I can't imagine having access to the lastlog file, but not the lastlog program. As you say, the file format is system dependent and the lastlog program has been compiled with the system header files that define what that is. So something like os.popen('lastlog') is probably a better way to get this information from within Python.\n<br><br>\nAnyway, to get your program to work on my x86_64 machine, I had to add an initial = to the struct format. That is, I added the line\n<pre> \n lastlogformat = '=L32s256s'\n</pre>\nand then replaced both occurrences of your format string with lastlogformat.", 'title': u'Small change for x86_64'}, {'comment': u"I overlooked the byteorder, that is a very good suggestion. \n\nThis most likely will never be of use to you, but I have clusters where I need to aggregate several lastlog files. I also have 40000 users and would like to avoid the extra over head of pipes, file opens for every query, and nonsquential access if I step through all of the uid's.", 'title': u' '}, {'comment': u"On further examination '=' prefix works for x86 and x86_64, but not for ia64. I am not sure what the best way to make this work on all arches.", 'title': u' '}], 'desc': u'It took me a while to figure out the file format for /var/log/lastlog on *NIX type machines. Some of the sysadmins out there may find it usefull to be able to determine the last time of login for an account without using any other apps.'}, {'comments': [{'comment': u"Great script, small and fast.\nBut I was wondering if it was possible to add a field to the records after\nthe dbase was created ?\nPerhaps you could explain to me the best way to adapt your strakell script.\nI don't have the need nor the knowledge to use a sqlite solution and\nI hope I could use your nice strakell script.\n\nThanks,\nStas", 'title': u'Adding record field to an existing dbase'}, {'comment': u'Good idea, I have added two methods to modify the database structure, add_field() and drop_field()', 'title': u'Methods added'}, {'comment': u"If using a field called 'name' and trying to create an index the\nscript crashes as the 'name' attribute of Base is changed.\nI renamed Base.name into Bass._name to prevent this.\n ", 'title': u"name clash when using a field called 'name'"}, {'comment': u'Right, thanks for the report. To avoid other name conflicts it\'s probably better to prepend an underscore to the Base instance attribute : db._age for the index on "age"', 'title': u'Name conflicts'}, {'comment': u'Version 1.9 fixes a serious bug with indices and adds some new features. I also changed the module name for the more explicit PyDbLite', 'title': u'New version'}, {'comment': u'This version fixes a bug and adds a key __version__ to all records to manage concurrency control : it is set to 0 for new records and incremented each time the record is updated', 'title': u'Version 2.0'}], 'desc': u'A small, fast, in-memory database management program\n\nThe database object supports the iterator protocol, so that requests can be expressed with list comprehensions or generator expressions instead of SQL. The equivalent of : \n\n<font face="courier" size="2">    cursor.execute("SELECT name FROM table WHERE age=30")\n    rows = cursor.fetchall()</font>\n\nis :\n\n<font face="courier" size="2">    rows = [ row["name"] for row in table if row["age"] == 30 ]</font>\n\nThe module stores data in a cPickled file. Records are indexed by a unique record identifier, that can be used for direct access. Since operations are processed in memory they are extremely fast, nearly as fast as SQLite in the few tests I made. An index can be created on a field to speed up selections\n\nComplete documentation <a href="http://quentel.pierre.free.fr/PyDbLite/index.html">here</a>'}, {'comments': [{'comment': u'I think "instance" in __delete__ should be "obj"', 'title': u'error in __delete__?'}, {'comment': u'fixed that. thanks :)', 'title': u'oops'}, {'comment': u'Object addresses are reused. On OSX, the following program prints "uhh..." a few times.\n\n<pre>\n class Thing(object): pass\n class Foo(object):\n weak = weakattr()\n t = Thing()\n for i in range(10):\n f = Foo()\n try:\n f.weak\n except AttributeError:\n print "good."\n else:\n print "uhh..."\n f.weak = t\n</pre>', 'title': u'careful with id(obj)!'}], 'desc': u'Weak attributes - cyclic references made easy'}, {'comments': [{'comment': u'To convert binary to decimal you may also try this one:\n\n>>> int("101",2)\n5\n\nit also converts from other radixes like 16 (hexadecimal):\n\n>>> int("f", 16)\n15', 'title': u'Build in'}], 'desc': u'This is a python program that can convert bianry number( binary is a language that computers use to comunicate with other) to a normal digital number and the other way around.'}, {'comments': [], 'desc': u'This recipe was writen for my beautiful girl...however signification of this code is universal'}, {'comments': [], 'desc': u'Instant regular expressions.\nOn each keystroke, all matches of the given text are highlighted, and the corresponding replacements are performed. Parts of the regular expression can be selected to make their scope appear in the original text.'}, {'comments': [{'comment': u'I think this might be better, and works for any sequences that support slicing and len() (thus including lists):\n\n<pre>\n def split_len(seq, length):\n return [seq[i:i+length] for i in range(0, len(seq), length)]\n</pre>', 'title': u'For sequences...'}], 'desc': u"The code below takes a string and returns a list containing the n-sized pieces of the string. For example:\nsplitCount('aabbccdd', 2) => ['aa', 'bb', 'cc', 'dd']"}, {'comments': [], 'desc': u'Simple program that demonstrates how to write an XMLRCP server that uses https for transporting XML data.'}, {'comments': [{'comment': u'I think with BeautifulSoup this is a matter of 3 lines of code.\nhttp://www.crummy.com/software/BeautifulSoup/', 'title': u'use BeautifulSoup'}], 'desc': u"A simple html parser subclassing HTMLParser that will collect a dictionary of 'id':'text' elements, where 'text' is the text contained within an element with an id attribute, and 'id' is the name of the element. A nice demonstration of using the HTMLParser class. "}, {'comments': [{'comment': u'check out BeautifulSoup\nhttp://www.crummy.com/software/BeautifulSoup/\nNo dependencies, cross-platform, handles bad HTML', 'title': u'Beautifulsoup??'}, {'comment': u'Look for this: \nhttp://www.python.org/dev/peps/pep-0008', 'title': u'code style'}, {'comment': u'Yes, I know about BeautifulSoup. I never work on anything other than Windows though, for one thing. Beyond that, it _appeared to me_ that the parse tree for BeautifulSoup might not be self-similar in the way that the one that IE produces is. Can someone set me straight?', 'title': u'Thanks'}, {'comment': u'I usually take the extra blanks out in recipes. Forgot this time. My eyesight is poor.', 'title': u'Thanks.'}], 'desc': u'Used in conjunction with Mozilla\'s "DOM Inspector" and Mozilla\'s "View | Page Source" and (say) PythonWin, the parser component of IE can make scraping fairly easy in large part because the parse tree that it produces is rigorously self-similar from root to leaf. Here\'s an example that parallels the one offered for ScrapeNFeed.'}, {'comments': [{'comment': u'When I attempt to run the module, it stops at the line:\n to_depart_time = ts[0]\nand says the index is out of range. What am I doing wrong?', 'title': u'problem'}, {'comment': u'Does anyone have saved HTML source from the Southwest site for these pages? Obviously, without having a valid flight to check in to or sample source, it is impossible to test the script. Would need sample pages for:\n# 1) Southwest Airlines - Retrieve Itinerary.htm\n# 2) Southwest Airlines - Schedule.htm\n# 3) Southwest Airlines - Check In and Print Boarding Pass.htm\n# 4) Southwest Airlines - Print Boarding Pass.htm\n# 5) Southwest Airlines - Retrieve-Print Boarding Pass.htm\n\nThanks.', 'title': u'Southwest HTML Samples'}, {'comment': u'There is a free web front end to a southwest checkin script at http://www.southwestgroupa.com\n\n', 'title': u'Free html interface to a checkin script available'}, {'comment': u'I saved html samples from an actual flight and used them to debug this script. They are available on my home page at www.kenw.us\n', 'title': u'Samples available'}, {'comment': u"Your time format is probably set so that the reg expression fails so it doesn't return any times in the expected format. This is a bug that I will fix. In the mean time you can probably tweak the script to read your time format for your region and browser setting. If you do this I'd appreciate seeing what your settings are. This section is also not critical for the operation of the script so you can just comment this out and set the time variables to something bogus, but if you do that of course the script won't tell you what time you are departing, etc.", 'title': u'Time format'}, {'comment': u'This link is now gone.', 'title': u'dead link'}, {'comment': u'It is now located at www.checkinsooner.com', 'title': u'Web site front end checkin for Southwest'}, {'comment': u'I think I may have found a little bug. My flight is scheduled to leave in 06 and return in 07, but the script seems to think its all 06... This is what is returns:<br><br>\n\nDeparture date/time: Dec 29 7:30PM 2006 Arriving: 10:10PM 2006\nReturn date/time: Jan 3 10:15AM 2006 Arriving: 11:50AM 2006\nCurrent time: Dec 20 12:36PM 2006\nYou have 8 days, 6 hours, and 56 minutes remaining to check in.\nPlease wait for the scheduler to check in the departing flight...\n', 'title': u'Between Years'}, {'comment': u'Is this still working with SWAs current web schema? I can get the script to run and it retrieves the correct flight times, but I get the following when trying to check in:\n<br>\n<br>\nConfirmation number: XXXXXX<br>\nPassenger name: XXX XXXXXXX<br>\nDeparture date/time: Feb 20 X:XXAM 2007 Arriving: X:XXAM 2007<br>\nReturn date/time: Feb 22 X:XXPM 2007 Arriving: XX:XXPM 2007<br>\n<br>\nCurrent time: Feb 19 10:23AM 2007<br>\nYou were ready to check in 0 days, X hours, and XX minutes ago.<br>\nObtaining departing flight boarding pass right now...<br>\nError: Cannot read data from<br> www.southwest.com/travel_center/retrieveCheckinDoc.html<br>\nResponse: 302 Moved Temporarily<br>\n', 'title': u' '}], 'desc': u'This script automatically checks you into a Southwest airlines flight exactly 24 hours before the flight. It finds the time of your flight and handles the timing and the web posting automatically with plenty of error checking. All you have to do is provide a confirmation number, first name, and last name. The script will email the results to you if an email address and valid smtp server are provided. The departing or returning flight will be scheduled, whichever is closest to the current time.'}, {'comments': [], 'desc': u'Whilst testing that a C extension was causing a problem with reference counts I created some code to check that the reference counts of a set of variables were not being changed by a call to a specific C method. That code itself was buggy as the output of a particular reference count eg 12 could actually modify one or more of the reference counts being checked. The solution was to store the refcount info as a string.'}, {'comments': [{'comment': u"why don't you support storing changed properties? In the store() method always the _origProps are stored. In this case it does not behave like java Properties. ", 'title': u' '}, {'comment': u'Thanks, the code was helpful. I noticed it did not allow you to reference previous properties like java does, e.g.:\n<pre>\nprop1=hello\nprop2={prop1} world!\n</pre>\nI added code to handle this, if you want to add it:\n[in processPair, where value gets set]\n<pre>\n\t\tvalue = self.unescape(value)\n\n\t\tcurlies = re.compile("{.+?}")\n\t\tfound = curlies.findall(value)\n\t\t\n\t\tfor f in found:\n\t\t\tsrcKey = f[1:-1]\n\t\t\tif self._props.has_key(srcKey):\n\t\t\t\tvalue = value.replace(f, self._props[srcKey], 1)\n</pre>', 'title': u'Referencing previous properties'}, {'comment': u"Hi,\nthis was really helpful, but how do I get a unicode value from a properties file? I have a Java properties file that has been transformed into escaped unicode in Latin-1 (foo=b\\u0061r). When I read that property into Python, my value string is 'b\\\\u0061r'.\n\nHas anyone tried this before?", 'title': u'Unicode properties?'}], 'desc': u'This recipe provides a quick and easy way to process Java properties files using pure Python. Of course, Jython can always be used, but in situations where Jython cannot be used, this recipe provides a sure-fire drop-in replacement. The Properties class is modelled to duplicate the behaviour of the original as closely as possible.'}, {'comments': [], 'desc': u'This recipe lets databaseconnections live in their own thread and queues are used to communicate with them. '}, {'comments': [], 'desc': u'An accurate, simple event scheduler using blocking and event notification features available in the threading module.'}, {'comments': [], 'desc': u'This function can extract a inner function from a class or a function.\nIt may be useful when writing a unit test code.'}, {'comments': [{'comment': u'The lines within the outer loop could be replaced with a list comprehenstion like:\n<pre>\n r = [ i + [y] for y in x for i in r ]\n</pre>', 'title': u'Improve by using list comprehension'}], 'desc': u'With list comprehension, you can easily loop through all combinations of 2 or 3 lists. But what about more, like 4,6, 20? \nThis recipe show a way to do this, without use of recursion.'}, {'comments': [], 'desc': u'Taking a PDF file as input, include only the specified pages and optionally arrange several pages on a sheet of paper on output.\nSimilar to the "psnup" program for Postscript.\n\nRun it like:\n$./pdf-pages --pages=2-13,17-19 --nup=1 report.pdf\nThe output file will be "report-pdf-pages.pdf".\n\nRequires the "pdflatex" program.'}, {'comments': [{'comment': u'please delete this thread if possible. thx! :)', 'title': u'seems I accident send twice?'}], 'desc': u'Warning: this post is an old one please see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812\nand someone delete this recipe if possible.\n\nA very simple module to extend the original rlcompleter module in standard library.\nAfter invoke python interpreter and import irlcompleter, \nyou can indent and also complete valid python identifiers and keywords using a single "tab" key!\n\nNote: rlcompleter module only avail in unix platform.'}, {'comments': [{'comment': u"<pre>This is Nice! Except that it beeps, because you are really telling rlcompleter there is no more completions.\n\nWhat about changing:\nreadline.insert_text('\\t')\nreturn None\n\nto:\nreturn [' ',None][state]\n\nUsing spaces preferrably (or tabs) if you wish.\n\n-- Nilton</pre>", 'title': u'suggestion'}, {'comment': u"I had extened your recipe.\nMy recipe's url is http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496822 .", 'title': u'Completer and history viewer support indent and file_match'}, {'comment': u"I've edited my original recipe. :)", 'title': u'Thanks the suggestions.'}], 'desc': u'A very simple module to extend the original rlcompleter module in standard library.\nAfter invoke python interpreter and import irlcompleter, \nyou can indent and also complete valid python identifiers and keywords using a single "tab" key!\n\nNote1: original python rlcompleter module only avail in unix-like environment\nNote2: if you seek a completer with history viewer support and more features you could try Sunjoong LEE\'s recipe at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496822'}, {'comments': [{'comment': u'You can use the win32pdh module like this:\n\n<pre>import win32pdh\n\npath = win32pdh.MakeCounterPath( ( None, \'System\', None, None, 0, \'System Up Time\') )\n\nquery = win32pdh.OpenQuery()\n\nhandle = win32pdh.AddCounter( query, path )\n\nwin32pdh.CollectQueryData( query )\n\nseconds = win32pdh.GetFormattedCounterValue( handle, win32pdh.PDH_FMT_LONG | win32pdh.PDH_FMT_NOSCALE )[ 1 ] \n\nprint "uptime: %d seconds" %( seconds )</pre>', 'title': u'Use win32pdh'}, {'comment': u'for a simple way just use uptime.exe from M$ <br>\nprint os.popen(uptime.exe).readline()', 'title': u' '}], 'desc': u'This recipe will help getting windows uptime using the "net statistics server" info.'}, {'comments': [], 'desc': u'When you parse XML using minidom, you can get a map of attributes for any element. The problem is that using the "in" operator on this map will raise an exception. These three lines of code will fix that.'}, {'comments': [{'comment': u'One can make a somewhat shorter version via a generator function. This has the added advantage of being somewhat more memory efficient in situations where it is not required to contain all the permutations in memory simultaneously.\n\n<pre>def permu(xs):\n if len(xs) <= 1:\n yield xs\n else:\n for i in range(len(xs)):\n for p in permu(xs[:i] + xs[i + 1:]):\n yield [xs[i]] + p\n\nprint list(permu([4,5,6,6]))</pre>', 'title': u' '}, {'comment': u"def permu(xs):<br>\n  if xs: return [ [xs[i]]+p for i in range(len(xs)) for p in permu(xs[:i]+xs[i+1:])]<br>\n  else: return [[]]<br>\n<br>\nBut this, just like your and many others I found on the net, return repeated items, like two [4,5,6,6].<br>\nPermutation should not have repeated item, that's the main reason I wrote this recipe.", 'title': u"even shorter, but doesn't work"}, {'comment': u'Why not just wrap it in set()?', 'title': u' '}, {'comment': u'try set([[]]) or set([{}]).', 'title': u"because set doesn't work if item is list or dict"}, {'comment': u'Interesting, but it is possible to hit the recursion limit (usually 1000).\n<br>\n>>> permu2(range(1001)).next()\n<br>\nHere is a way to produce successive permutations. It *does* handle duplicates, and it could easily be made into a generator. (Swap lt with gt in value comparisons to compute prev.)\n\n<pre>\ndef permute_next(values):\n """\n Alter the list of values in-place to produce to the next permutation\n in lexicographical order.\n \n \'values\' must support slicing and ::reverse().\n """\n last = len(values) - 1\n a = last\n while a > 0:\n b = a\n a -= 1\n if values[a] Interesting, but it is possible to hit the recursion limit (usually 1000).\n<br>\n>>> permu2(range(1001)).next()\n<br>\nHere is a way to produce successive permutations. It *does* handle duplicates, and it could easily be made into a generator. (Swap lt with gt in value comparisons to compute prev.)\n\n<pre>\ndef permute_next(values):\n """\n Alter the list of values in-place to produce to the next permutation\n in lexicographical order.\n \n \'values\' must support slicing and ::reverse().\n """\n last = len(values) - 1\n a = last\n while a > 0:\n b = a\n a -= 1\n if values[a] </pre></pre>', 'title': u'Recursion limit'}, {'comment': u"The less-than and greater-than chars in my solution seem to cause HTML problems, despite using pre tags. Very annoying. I'll post a separate recipe.", 'title': u'HTML problems'}], 'desc': u'I saw a lot of implementations that doesn\'t work on list with repeated items.\nFor example: [3,3,"hello","hello"]\nThis recipe show such function that works on any list.\n(update 6/29/06) added generator version permu2(xs).'}, {'comments': [{'comment': u'See also my Recipe 52317 (whose comments section seems mangled now).\n<br>\nIn the following we have a straight-forward recursive generator\nnamed "Farey_r" and an equivalent, but more efficient, generator\nnamed "farey". "Farey_r" is provided simply to make it \'clear\' \n(and more provable) what the generator is computing.\n\n<pre>\ndef Farey_r(limit, start=(0, 1), stop=(1, 1)):\n \'\'\'recursive definition of a Farey sequence generator\'\'\'\n n, d = start\n N, D = stop\n mediant_d = d + D\n if mediant_d <= limit:\n mediant = (n + N), mediant_d\n for pair in Farey_r(limit, start, mediant): yield pair\n for pair in Farey_r(limit, mediant, stop): yield pair\n else:\n yield start\n\n\ndef farey(limit):\n \'\'\'Fast computation of Farey sequence as a generator\'\'\'\n # n, d is the start fraction n/d (0,1) initially\n # N, D is the stop fraction N/D (1,1) initially\n pend = []\n n = 0\n d = N = D = 1\n while True:\n mediant_d = d + D\n if mediant_d <= limit:\n mediant_n = n + N\n pend.append((mediant_n, mediant_d, N, D))\n N = mediant_n\n D = mediant_d\n else:\n yield n, d\n if pend:\n n, d, N, D = pend.pop()\n else:\n break\n</pre>', 'title': u'Some simpler ways based on the Farey properties'}, {'comment': u"Sorry about not referencing your recipe, I thought I did a search, but I must have missed it. <br><br> For those who didn't see it, take a look, the mediant calculation approach is certainly more effective.", 'title': u'Yep'}], 'desc': u'Function provides farey sequence, F(n), for any integer n.'}, {'comments': [{'comment': u'>>> history', 'title': u'history view'}, {'comment': u'>>> history()', 'title': u'history view with number'}, {'comment': u">>> history.save('saved.py')", 'title': u'save history to another file'}, {'comment': u">>> history.save('saved.py', 1, 3)", 'title': u"save history number from 1 to 3 into 'saved.py'"}, {'comment': u'>>> history.clear()', 'title': u'clear history buffer'}, {'comment': u'>>> history.recall()', 'title': u'recall history'}, {'comment': u">>> history.recall('saved.py')", 'title': u'recall history from another file'}, {'comment': u'<pre>\n>>> a = 1\n>>> b = a + 1\n>>> c = b + 1\n>>> print a, b, c\n1 2 3\n>>> history()\n1 a = 1\n2 b = a + 1\n3 c = b + 1\n4 print a, b, c\n>>> a = 2\n>>> history.run(2, 4)\n2 3 4\n</pre>', 'title': u'execute history'}, {'comment': u'I has changed the run mathod name to execute.', 'title': u'change history.run to history.execute'}], 'desc': u'This module let "tab" key can indent and completing valid python identifiers, keywords, and filenames.\nThis module support history view also.\n\nNote1: original python rlcompleter module only avail in unix-like environment\nNote2: if you seek a more simple completer you could try Jian Ding Chen\'s recipe at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812'}, {'comments': [], 'desc': u'Computes the strategy oddments for two-player zero-sum games of perfect information. Uses a robust, iterative approximation that can handle dominance, non-square payoff matrices, and games without a saddle-point.'}, {'comments': [], 'desc': u'A simple way to count the pages of a PDF the pure Python way.'}, {'comments': [{'comment': u'...like your office :)\n\nUse a shared folder (eg nfs, windows, samba) and try from several workstations.\n\nRecover your files 100% or your money back!', 'title': u'Best used in places with lots of reader devices'}], 'desc': u'Files existing on damaged media (eg old CD-ROMs) are not completely lost. Often, readers will read sectors unreadable in other readers. The "trick" is to merge the successful reads from several devices.'}, {'comments': [], 'desc': u"Good demonstration of inheriting python default object types. Define a maximum size (items, not bytes) to limit to and use as a normal dictionary (be careful to have KeyError exception handling, or use the dictionary's get method with a default value)."}, {'comments': [], 'desc': u'Here is a convenient way to create, parse, alter, and write .pc files. Just pass PkgConfig() a file-like object, or None to start fresh. Print the object to create a new .pc file.\n\nSome people might want even more functionality, but I chose not to hinder the flexibility of the class.'}, {'comments': [], 'desc': u'Grab the screen shot on Windows.'}, {'comments': [], 'desc': u'z_cgi.py provides a simple interface for CGI applications.\nIt does not currently support reading information from standard in.\nFuture versions will probably be delivered in a packaged format.'}, {'comments': [], 'desc': u'The module show a way to simple data encryption.\nCharacters are mapped to a key via replacement.'}, {'comments': [], 'desc': u'The module show a way to simple data encryption.\nCharacters are mapped to a key via replacement.'}, {'comments': [{'comment': u"What's wrong with closures, or partial function application? (The function 'partial' doesn't exist in 2.4, but it's not hard to write.)", 'title': u' '}], 'desc': u'This was written to emulate a flexible version of delegates from the C# language. Default arguments can be set and changed, and default arguments can be totally be replaced by new arguments on-the-fly. The delegate class was primarily written for working with Tkinter.'}, {'comments': [], 'desc': u'This recipe is a memory-based directory copier and paster. Pickled Directory objects will contain all data from a directory at path and can be saved in other locations. Once a Directory object has been created, pasting it to another location is extremely simple.'}, {'comments': [], 'desc': u'This recipe requires the z_matrix module.\nTwo classes are provided, HTML_Table and HTML_Month.\nHTML_Table can manage the generation of a table in HTML format.\nHTML_Month builds on top of HTML_Table and expands on its capabilities.\nIt allows for dynamically created tables that have the look of the selected month.'}, {'comments': [], 'desc': u'This module provides two classes that emulate one and two\ndimentional lists with fixed sizes but mutable internals.\nTheir primary purpose is to be used as a building tool for\nclasses that need storage structures that cannot change in\nsize.'}, {'comments': [], 'desc': u'This recipe emulates time from the fictional planet of Aens.\nThe code is meant to be a novelty and not for real programming.'}, {'comments': [], 'desc': u'This recipe gives access to the Sync class.\nObjects created by the Sync class are meant to\nbe used when trying to syncronize the execution\nof two or more threads. See z_service.py for more\na simple example of how Sync objects can be used.'}, {'comments': [], 'desc': u'This module allows creating and running a custom dialog box with a single function call. The custom dialog box must first be defined in an external XRC file. Editors like XRCed and wxGlade allow easily designing custom dialog boxes. You can then invoke the dialog box even if your application has no other GUI.'}, {'comments': [], 'desc': u'This handles duplicate values in the list. It could easily be made a generator, and it does not require recursion.'}, {'comments': [], 'desc': u'When you release your program to client, its a good idea to disable all the debug messages.\nIt is possible via custom configuring debug levels at all modules, but may be implemented using simple wrapper around logging.getLogger() function.'}, {'comments': [], 'desc': u'This module provides several functions that can\nencode and decode a string. It also has a\nfunction called partition for designing faster\nalgorithms. For sample usage of this module,\nz_service.py provides example code.'}, {'comments': [], 'desc': u'This recipe allows the creation of servers that\nprovide services to connecting programs. This is\nbasically a remote procedure call (RPC) server\nthat allows various clients to connect and\ncommunicate through registered functions.'}, {'comments': [], 'desc': u'The following four programs provide an example of how the z_service module can be used. This recipe demonstrates a chatting program built off of the easy to use framework provided by the Client, Server, and Sync_Server classes. These abstractions are meant to make networked function calls intuitive and easy to set up.'}, {'comments': [], 'desc': u'Yet another memoize decorator, except with a cache size limit with an LRU policy.'}, {'comments': [], 'desc': u"This is a groupby function for arrays. Given a list of arrays and a `key` function, it will group each array based on the value of `key(args[0])`. The returned arrays will be two dimensional. The size of the first dimension is equal to the number of groups, and the size of the second dimension is equal to the size of the largest group. All of the smaller groups are padded with the value of the keyword argument `fill_value`.\n\nThere's also a short recipe in here for functional composition."}, {'comments': [], 'desc': u'Invert different types of dictionaries with mixed data types as values.'}, {'comments': [], 'desc': u'A regex-based kludge for JavaScript code compression. Safely handles string constants and missing semicolons.'}, {'comments': [], 'desc': u'This is a simple maze generator & solver written in Python. It is written as a game, consisting of classes which can read mazes from STDIN or a file. It provides a a random maze generator game, which can generate mazes of any dimension and solve it. Use it for fun and learning.'}, {'comments': [], 'desc': u'A lightweight and powerful way to evaluate expressions embedded in strings during interpolation.'}, {'comments': [{'comment': u'Unless I am misunderstanding you should be able to use the __file__ attribute of a module for that.\n\n print os.path.dirname(__file__)', 'title': u'use "__file__"'}, {'comment': u"I think that what you are describing was basically the way that Peter B. was doing it in the link above, which was in turn based on something done in Zope, except for it to work, you have to pass __file__ to the function in some way (unless I am the one who is misunderstanding...). I wanted to be able to just have the function correctly guess the caller's package, which is why I ended up using the introspection code. It was all for the sake of making the calling code simpler.\n\nLet me know if I've missed your point.", 'title': u' '}, {'comment': u'This is a great solution however when I imported a module that references the function by importing another module, sys._getframe(1) does not return a frame object and instead returns an object with a _frame attribute that contains the frame object. I don\'t understand the inner workings of Python enough to explain this however this patch fixes the function:\n<pre>\nimport os, sys, inspect\ndef execution_path(filename):\n frame = sys._getframe(1)\n if hasattr(frame, "_frame"):\n frame = frame._frame\n return os.path.join(os.path.dirname(inspect.getfile(frame)), filename)\n</pre>', 'title': u'Patch'}, {'comment': u"I've since come across scenarios where inspect.getfile() still fails. A code object however seems to always be available and its file property can be used without needing the insepct module at all:\n\n<pre>\nimport os, sys\ndef execution_path(filename):\n return os.path.join(os.path.dirname(sys._getframe(1).f_code.co_filename), filename)\n</pre>", 'title': u'Patched again'}, {'comment': u'Thank you for improving this approach!', 'title': u'Thank you'}], 'desc': u'I ran into a dilemma when writing a PyUnit test case that read in sample data from a text file in the same package as the test. How I could successfully reference the relative location of the file changed depending on how I executed the code. So for example, when I ran the unit test in isolation, it passed, but when I ran the test as part of a suite, it failed, because the code was being executed from a different location. I needed to find a way to determine the relative location of the file at run-time no matter how it was executed.'}, {'comments': [{'comment': u'<pre>__doc__ = """\n This is module-level documentation\n"""\n</pre>\n\nYou will notice that triple-quotes and newlines don\'t mix well in your code.\nAlso, from stat import ST_MODE is unnecessary for a long time now. os.stat(filename).st_mode is more practical.', 'title': u'Well, tabify this :)'}], 'desc': u'A little script for those of us who prefer tabs over spaces.'}, {'comments': [], 'desc': u'Synchronize/sequentialize sensitive parts of an asynchronous event solution with EventQueue.\nFor example, sequentialize changes to a document buffer which may come from multiple threads.'}, {'comments': [], 'desc': u'One function to rule them all....'}, {'comments': [], 'desc': u"This recipe is a simple (very simple) batch process dispatcher. It allows you to utilize a simple file with a list of commands to run to make your command-line life a little easier. I use it for mencoder so I don't have to type/paste in a bunch of commands for backing up my DVDs. I can just write a batch file. And if there is an error somewhere along the way, or I need to stop for some reason, I can just start where I left off when I am ready."}, {'comments': [{'comment': u'For platforms with ANSI color, one can use ANSI escapes.', 'title': u' '}], 'desc': u'A simple function to change the background/foreground color of characters written to a Windows console (command line). Requires ctypes, which is included with Python version 2.5 or later.'}, {'comments': [], 'desc': u'There\'re quite a few python ORM\'s. However, most are not easy to use. In Ruby on Rails\'s ActiveRecord ORM, you don\'t have to define schema, just specify the relationship like "belongs_to" and "has_many", and ORM do rest of the work, it\'s very easy to learn and easy to use.\nThis recipe provide a python ORM that behave like ActiveRecord.'}, {'comments': [], 'desc': u'Framework for experimenting with guessing strategies in Master-mind style games.'}, {'comments': [{'comment': u'In general using __slots__ is not advisable unless there is a significant performance gain. __slots__ will cripple your classes and will cause strange side-effects later on, especially for somebody else who would use your code.', 'title': u'Why use __slots__?'}, {'comment': u"When applying this recipe to large databases, the use of __slots__ pays-off in two ways. First, it cuts memory use -- there is one Unit instance for every unique field value in the database -- each of those Units would need its own dictionary without __slots__. Second, the expense of propagation of activation and inhibition is markedly reduced when using psyco on code with __slots__ defined. If you don't like the __slots__ line, it is trivial for you to take it out.", 'title': u'Reasons for using __slots__'}], 'desc': u'Apply the IAC (interactive-competition-and-activation) model to analyzing a database. '}, {'comments': [{'comment': u'<pre> lines = open(filename, \'r\').readlines()\n\ttotal = ""\n\tfor line in lines:\n\t\ttotal += line\n</pre>\nIs a rather long way to spell:\n<pre> total=open(filename,\'r\').read()</pre>', 'title': u'Oh my'}, {'comment': u'very true.. fortunately, it would only eat up a humanly unidentifiable amount of processor time unless the file was a ridiculous length. I made the change though', 'title': u' '}, {'comment': u'Sorry - I\'m new to Python.<br>\n<br>\nI get:-<br>\n<pre>\n envin[\'dimensions\'] = dimensions\nNameError: global name \'dimensions\' is not defined\n</pre>\n\nAnd if i change the line so the function name "dimensions" is qualified by the class "World", then I get problems when trying to exec the text read from the file.txt:-<br>\n<pre>\n exec lines in envin\n File "", line 2, in ?\nTypeError: unbound method dimensions() must be called with World instance as first argument (got int instance instead)\n</pre>\n\nBTW I\'m using Python 2.4<br>', 'title': u"Can't get this example working"}, {'comment': u"again, a typo on my end. It should have been self.dimensions instead of dimensions\n\nthe dimensions method is indeed a method of the class World, but Python doesn't have static methods like java. Plus, this method needs an instance of world in order to edit instance data like width and height.\n\nthe self keyword in Python is equivalent to the this keyword in Java, and just refers to the instance of the class that the method was called in.", 'title': u' '}, {'comment': u'that did the trick\ncheers', 'title': u'Thanks'}], 'desc': u'This is useful for making easy and human to write definition files for whatever use. For example, lets say you are writing a simulator and you need an easy, human way to define parts about a given world like light sources, obstacles, and dimensions. see the discussion for this example fleshed out in code.'}, {'comments': [], 'desc': u'This recipe presents a way to introduce proper attribute access protection levels using a generic proxy object. By default all attributes are "protected" in the C++ sense and can be declared as public using either a function decorator or a class attribute.'}, {'comments': [], 'desc': u'If you want to serialize Python objects to XML then PyXML is a good choice. Except in the case when unicode strings come into play. In this case generic.Marshaller().dump() throws an ugly AttributeError: Marshaller instance has no attribute \'m_unicode\'\nThis recipe extends both PyXML Marshaller and Unmarshaller to support the de-/serialization of unicode strings. Put the following code in a separate module and test it with the given example.\nThe output will look like\n<marshal>\n  <list id="i2">\n    <string>text</string>\n    <unicode>german umlaut: A\xbc A\x14 <>&</unicode>\n  </list>\n</marshal>'}, {'comments': [{'comment': u"You can supply keyword arguments to dict() since Python 2.3. If 'dict' is too long then you can alias it with<br>\n<pre> nd = dict</pre>", 'title': u'dict(a=3) works since Python 2.3'}, {'comment': u'<pre>\n>>> d = dict(a=3)\n>>> d.update(b=4)\n>>> d\n{\'a\': 3, \'b\': 4}\n>>> john = dict(age=10, height=180, weight=150, eyeColor="black")\n>>> john.update(favBook="none", favMovie="none")\n>>> john\n{\'eyeColor\': \'black\', \'favMovie\': \'none\', \'weight\': 150, \'favBook\': \'none\', \'age\': 10, \'height\': 180}\n>>> \n</pre>', 'title': u'dict update also takes kwargs'}, {'comment': u"runsun pan don't be mad, sometimes I also reinvent a unknow wheel :)", 'title': u' '}], 'desc': u'This recipe provides an alternative way of generating and updating dictionaries. It savs couple of keystrokes, making routine dict operations easier. '}, {'comments': [], 'desc': u'I wrote this foldable panel to keep the look of my applications consistant with Windows. The code is extremely simple and is nowhere as flexible as the foldable panel already available in wxPython. Demo available in the code.'}, {'comments': [{'comment': u"There are some warnings you should probably include with this recipe. First off it will break some of the things you might expect to do if you thought you had just created a SteppedCounter object e.g. none of 'isinstance', 'dir' or 'help' will work as you might have expected.\n<br>\nYou would also have to be very careful if the class ever passes 'self' out to another function as the 'self' it passes out will be the original unprotected object.<br>\n\nAlso, and I think quite importantly, people need to be aware that this recipe is simply performing a more advance way to hide attributes against accidental intrusion, it doesn't add any kind of security and the attributes are still easily accessible if you want to get at them.\n\ne.g.\n<pre>\n>>> import new\n>>> def getcell(cell):\n closure = (cell,)\n a = 0\n def f():\n return a\n getter = new.function(f.func_code, f.func_globals, 'getter', None, closure)\n return getter()\n\n>>> sc = SteppedCounter()\n>>> realsc = getcell(sc.__getattr__.im_func.func_closure[0])\n>>> sc.inc()\n1\n>>> realsc._n\n1\n</pre>", 'title': u'You should include a few caveats'}, {'comment': u"These are very severe criticisms. Thanks, Duncan. I will investigate whether the cell inspection hack can be avoided. But I don't see any way of preventing leaking abstraction in case of returning a Counter instance without additional coding/wrapping. This is very bad.", 'title': u'Ah, I see'}], 'desc': u'This recipe enables proper protection of attributes that are mangled with Pythons privacy indicator: the single underscore _. '}, {'comments': [{'comment': u'I mean, there will be one more line after last [v=v.replace(".","_")]:\n<pre>\nimport re\n...\n v=v.replace(".","_") # old code\n v = re.sub(\'_{2,}\', \'_\', v) # fix!\n\n v_list.append(v) # old code\n</pre>', 'title': u'readability of identifiers'}, {'comment': u'I\'ll rework my string manipulation code but I think my program should come with a fair warning: "if possible, clean the filenames as much as you can before running the program".\n\nThe main reason for the code is to process the openoffice icons (see http://www.novell.com/coolsolutions/feature/1637.html for a zip/tarball).\n\nTheir (stock) filenames come as something like "stock_data-save.png" which need to be cleaned-up a bit before they can be used as variable names.\n\nIf I get a sec, I\'ll turn the filename->variable name conversion bit of code into a cookbook recipe (which won\'t span over 300 lines for a change!)\n\nCheers,\nEgor', 'title': u'Yes, that is useful. Converts multiple underscores into single ones.'}], 'desc': u'I use this utility to generate an "images.py" module which I use to provide images to my applications via wx.ImageFromStream . You can see an output in my other recipe "A foldable panel with a Windows XP look and feel". The utility is called "convert.py" and can be put in a folder together with the png images. When run, it\'ll generate the "images.py" file which can be moved to wherever it\'ll be used. The only thing I\'m checking for is that "convert.py" won\'t overwrite an existing "images.py" file in the same directory.'}, {'comments': [], 'desc': u'This recipe provides a very simple time profiling module which helps you to \nmeasure actual execution time for blocks of Python code without peppering your\ncode with many time.time() statements.'}, {'comments': [], 'desc': u"This a very simple implementation for how to do a readlines in reverse. It is not optimized for performance (which often doesn't matter). I have a 2nd version that is faster by loading blocks of data into memory instead of character by character. Of course, the code then almost doubles in size. And finally a third version that is the fastest, using split."}, {'comments': [], 'desc': u'This cleanses user input of potentially dangerous HTML or scripting code that can be used to launch "cross-site scripting" ("XSS") attacks, or run other harmful or annoying code. You want to run this on any user-entered text that will be saved and retransmitted to other users of your web site. This uses only standard Python libraries.'}, {'comments': [{'comment': u'This is a useful function that probably many of us have implemented in a number of different ways. But I like the conciseness of the "standard" version of the recipe:\n\n<pre>\nfrom itertools import chain, repeat, izip\ndef grouper(n, iterable, padvalue=None):\n "grouper(3, \'abcdefg\', \'x\') --> (\'a\',\'b\',\'c\'), (\'d\',\'e\',\'f\'), (\'g\',\'x\',\'x\')"\n return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)\n</pre>', 'title': u'Also see itertools recipes (5.16.3 in Python 2.4.3 documentation)'}], 'desc': u'Groups the elements returned by an iterator into n-tuples. The final tuple may be padded with Nones.'}, {'comments': [{'comment': u"The second call to PyThreadState_SetAsyncEx must use 'None' as second parameter, otherwise it will not work correctly on 64-bit plaforms:\n\n<pre>ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)</pre>\n\n'None' will be passed as pointer parameter, '0' would be passed as integer.", 'title': u'Small bug in the recipe'}, {'comment': u'see the link i gave for the full (updated) recipe', 'title': u'this code is not up-to-date'}], 'desc': u"A little module that extends the threading's module functionality -- allows one thread to raise exceptions in the context of another thread. By raising SystemExit, you can finally kill python threads :)"}, {'comments': [{'comment': u'I changed the coordinates to my home, but I keep getting blank images. Can you supply a little bit of documentation regarding how to change the mosaic sourced, and other parameters from the NASA server.', 'title': u'Blank inages'}, {'comment': u"First value in first tuple passing to the function is longitude, second is latitude, in decimal degrees. If that's correct and you still getting blank images, you can play with their server's parameters (layers, for example) using the web interface at http://onearth.jpl.nasa.gov/landsat.cgi and then change the value of request1.", 'title': u' '}], 'desc': u"This script downloads satellite image of desired position (in degrees) from the NASA's OnEarth site (http://onearth.jpl.nasa.gov/)."}, {'comments': [{'comment': u'Though your snippet is nice, you should really have a look at least comprehensions.\nWith a few built-in methods you can reduce your 8 lines of code (which is pretty slow because of the "extra work" I guess) to one:\n\n<pre>toHex = lambda x:"".join([hex(ord(c))[2:].zfill(2) for c in x])</pre>\n\nThe builtin string-method "join" joins every element of the list to the string by re-using the string. ";;".join([\'a\', \'b\', \'c\']) would result in \'a;;b;;c\'.\nNote that you can enhance the speed of the above snippet by replacing the [] with () what will change it from a list comprehension to a generator. Same enhancements can be done with your second function.\n\nRegards, Stargaming', 'title': u'list comprehensions'}, {'comment': u'this functionality already exists with the encodings library (which is built-in):\n<pre>\n>>> "hello".encode("hex")\n\'68656c6c6f\'\n>>> "68656c6c6f".decode("hex")\n\'hello\'\n>>>\n</pre>', 'title': u'encode and decode'}, {'comment': u"The hex() and int() builtins should do everything you need...\n<pre>\n>>> int('0x10AFCC', 16)\n1093580\n>>> hex(1093580)\n'0x10afcc'\n</pre>", 'title': u'base 16 int conversion'}, {'comment': u"Nevermind, I should've read the original post more closely. As the other commenter said, str.encode() and str.decode() do the same thing as your code.", 'title': u' '}], 'desc': u'Qoute string converting each char to hex repr and back'}, {'comments': [{'comment': u"<pre>\nfrom itertools import cycle, izip\n\ndef process (ss, key):\n key = cycle(key)\n return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(ss, key))\n\n--\n:-)\n</pre>", 'title': u'Short is better'}], 'desc': u'Simple xor for strings'}, {'comments': [], 'desc': u'This quick-and-dirty recipe fetches the version number from a Win32 PE file without the need for the win32 API. It is therefore suitable for execution on non-Windows platform.'}, {'comments': [{'comment': u'You may also be interested in Twisted: http://twistedmatrix.com\n<br>\nTwisted\'s "Deferred" allows you to do that, and more.', 'title': u'Nice approach!'}, {'comment': u"thanks! i'll look into it", 'title': u' '}], 'desc': u'combines queues and threads for efficient data processing.'}, {'comments': [], 'desc': u'This script runs a render farm on a bunch of networked machines, each with SSHD running, and POV-Ray and ImageMagick installed. The host machine uses mpeg2encode and ffmpeg to produce a MP4 video file, which I transfer to the Mac to burn a DVD. To keep life simple, I clone the same .ssh directory on all the machines.'}, {'comments': [{'comment': u"none of the open source tag libs I've found are able to correctly parse the genre tag in my aac files. iTunes is able to read it, as are other tools, so it is in there somehow, but the gen tag in this script (and every other I've tried) always comes up empty. I've finally got access to every tag i need, except for genre, so this is important.", 'title': u"anyone know what's up with Genre tag?"}], 'desc': u'This recipe yields the atoms contained in an MP4 file. Mostly used for extracting the tags contained in it (artist, title etc) using a convenience class (M4ATags). Implemented as an generator.'}, {'comments': [], 'desc': u'This software gets the date from a naval time server and updates the system clock for posix OS supporting the "date" command. It also requires an internet connection.\n\nWARNING: It will not work if your system clock is already off by more than 1 month.\n\nTIP: Use kcron to schedule this script on a periodic basis.'}, {'comments': [], 'desc': u'Separate pattern implementation from your code so that you can reuse the implementation elsewhere.\n\nThe following code is an example that shows a reusable implementation of the Observer pattern of the GoF book.'}, {'comments': [{'comment': u"What about accessing 'self'?", 'title': u'Cool'}, {'comment': u' ', 'title': u'Okay, saw it in the wiki page'}, {'comment': u'Maybe the mixin function can do the include too, so this:<br>\nimport testmixin<br>\nclass Bar(mixin(testmixin)):<br>\n<br>\nCan be replaced with this:<br>\nclass Bar(mixin("testmixin")):', 'title': u' '}], 'desc': u"Module mixins allow you to inherit from *modules*. This is how ruby achieves multiple inheritance, and I just wanted to show it's possible in python as well."}, {'comments': [{'comment': u"Replace:\n<pre>\nsys.path.insert(0, sys.argv[1])\ndel sys.argv[0:1]\nimport MY_SCRIPT\nMY_SCRIPT.main()\n</pre>\nwith:\n<pre>\nimport zipimport #after checking python version\nz = zipimport.zipimporter(sys.argv[1])\ndel sys.argv[0:1]\nexec z.get_code('MY_SCRIPT')\n</pre>\nAfter this change a script with the __name__ == '__main__' trick works, no need to specify a main() function.", 'title': u"make if __name__ == '__main__' work"}, {'comment': u"Anything added beyond the script does not get printed to the screen why?\n\nLike is added\necho 'Hello'\n\nWhich does get printed to the screen", 'title': u'Anything added beyond'}], 'desc': u'This is a handy way to package a group of python modules into a single compressed self-extracting python executable script. This works on UNIX and Cygwin with Python 2.3 Final or later.'}, {'comments': [{'comment': u"Raymond Hettinger as ususal provided a beautiful solution to this problem:\n\n<pre>\ndef izip_exact(*args):\n sentinel = object()\n iters = [chain(it, repeat(sentinel)) for it in args]\n for result in izip(*iters):\n if sentinel in result:\n if all(value==sentinel for value in result):\n return\n raise ValueError('sequences of different lengths')\n yield result\n</pre>\n\nI believe the plan is to add something like this to the itertools recipes section in the not-so-distant future.", 'title': u"Raymond Hettinger's solution"}, {'comment': u'zip_exc() doesn\'t do expensive tests for every tuple. So I\'m claiming "conceptual beauty", a term which I\'ve just made up :-)<br><br>\n\n$ python2.5 -m timeit -s\'from zips import zip_exc as zip; data = [range(1000)]*3\' \'for item in zip(*data): pass\'<br>\n1000 loops, best of 3: 255 usec per loop<br>\n$ python2.5 -m timeit -s\'from zips import izip_exact as zip; data = [range(1000)]*3\' \'for item in zip(*data): pass\'<br>\n1000 loops, best of 3: 1.08e+03 usec per loop<br><br>\n\nOn the other hand the setup for izip_exact() is a bit more lightweight.\nWith three sequences, the break-even is at 20 items (i. e. for less than 20 3-tuples izip_exact() wins):<br><br>\n$ python2.5 -m timeit -s\'from zips import izip_exact as zip; data = [range(20)]*3\' \'for item in zip(*data): pass\'<br>\n10000 loops, best of 3: 33.9 usec per loop<br>\n$ python2.5 -m timeit -s\'from zips import zip_exc as zip; data = [range(20)]*3\' \'for item in zip(*data): pass\'<br>\n10000 loops, best of 3: 33.5 usec per loop<br><br>\n\nI used the release candidate of 2.5 for the measurements because it provides all() as a built-in. <br><br>\n\nPS: If you want to use Raymond\'s approach in 2.4 you can define\n<pre>\ndef all(items):\n return True in (True for item in items if item)\n</pre>', 'title': u'Mine is faster for "long" sequences'}, {'comment': u"If speed is the main concern, the O(n) sentinel search step can be replaced with a generator that tracks the number of calls to next():\n\n<pre>\ndef izip_exact(*args):\n count = []\n def counter():\n while 1:\n count.append(None)\n yield None\n sentinel = counter()\n iters = [chain(it, sentinel) for it in args]\n for result in izip(*iters):\n if count: \n if len(count) == len(args):\n return\n raise ValueError('sequences of different lengths')\n yield result\n</pre>", 'title': u'Alternate version without the O(n) sentinel search'}, {'comment': u' ', 'title': u"FYI, Peter's version is still the fastest"}, {'comment': u'<pre>\ndef all(seq):\n for elem in ifilterfalse(None, seq):\n return False\n return True\n</pre>\n\nAlso, when using all() in the above recipe, use an "is" test instead of "==":\n\n<pre>\n if all(value is sentinel for value in result):\n return\n</pre>', 'title': u'Faster Py2.4 version of all()'}], 'desc': u"Using zip(names, values) may inadvertently eat some of your data when there are, e. g., fewer values than names. This is easy to fix with assert len(names) == len(values) if the arguments' length is known, but not if they are arbitrary iterables. With zip_exc() no such glitches go unnoticed as list(zip_exc(names, values)) throws a LengthMismatch exception if the number of names and values differ."}, {'comments': [{'comment': u'I\'d like to mention that "map(None, *iterables)" already does the job for most cases (padding Nones). So, if the result does not have to be an iterable (i.e. I am not dealing with huge data amounts), I\'d probably prefer using map.\n<br><br>\nI am adding this, since you mentioned you wanted an alternative for zip that pads values and is fast. "map(None, *iterables)" is both, and is readily available with python.\n<br><br>\nSee also\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410687', 'title': u'map is a simpler, though less general alternative'}, {'comment': u"FWIW, here is my version of a padding zipper:\n<pre>\ndef izip_longest(*args, **kwds):\n fillvalue = kwds.get('fillvalue')\n its = [chain(it, repeat(fillvalue)).next for it in args]\n term = [fillvalue] * len(args)\n while 1:\n result = [g() for g in its]\n if result == term: return\n yield tuple(result)\n\n\nprint list(izip_longest('x', 'abc', 'ABCDEF', '1', fillvalue=999))\n</pre>", 'title': u'izip_longest()'}, {'comment': u'as it relies on a non-unique sentinel:<br>\n<pre>\n>>> list(izip_longest(\'x-\', \'a-bc\', \'A-BCDEF\', \'1\', fillvalue="-"))\n[(\'x\', \'a\', \'A\', \'1\')]\n</pre>', 'title': u'This may fail...'}, {'comment': u"<pre>\ndef izip_longest(*args, **kwds):\n ''' Alternate version of izip() that fills-in missing values rather than truncating\n to the length of the shortest iterable. The fillvalue is specified as a keyword\n argument (defaulting to None if not specified).\n\n >>> list(izip_longest('a', 'def', 'ghi'))\n [('a', 'd', 'g'), (None, 'e', 'h'), (None, 'f', 'i')]\n >>> list(izip_longest('abc', 'def', 'ghi'))\n [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]\n >>> list(izip_longest('a', 'def', 'gh')) \n [('a', 'd', 'g'), (None, 'e', 'h'), (None, 'f', None)]\n '''\n fillvalue = kwds.get('fillvalue')\n def sentinel(counter=[fillvalue]*(len(args)-1)):\n yield counter.pop() # raises IndexError when count hits zero\n iters = [chain(it, sentinel(), repeat(fillvalue)) for it in args]\n try:\n for tup in izip(*iters):\n yield tup\n except IndexError:\n pass\n</pre>", 'title': u'A C-speed version using itertools'}], 'desc': u'On the rare occasion that you want to fill the sequences passed to zip() with a padding value, at least use something fast.\nYou can optionally specify a padding value other than None.'}, {'comments': [{'comment': u'__setattr__ will only work if it exists at the *class* level.\n\nhere\'s a snapshot:\n<pre>\n>>> class MyClass(object):\n... def __init__(self, foo, bar):\n... # set attributes normally here\n... self.foo = foo\n... self.bar = bar\n...\n... # override __setattr__\n... self.__setattr__ = self.__setattr_impl\n...\n... def __setattr_impl(self, name, value):\n... print "blah"\n...\n>>>\n>>> m=MyClass(1,2)\n>>> m.x=8\n>>>\n</pre>\n\n"blah" isn\'t printed...<br>\n<br>\n(sup dude? i\'m bored, i know... i\'m telling you, down with types and classes. we don\'t need them. go antitype! :)', 'title': u"doesn't work :("}, {'comment': u"There's a good chance this would work with old-style classes (haven't tested though). New-style classes are more picky about magic methods being in the class.", 'title': u'new-style'}, {'comment': u"This doesn't seem to work in new-style _or_ old-style classes. I don't know why I thought it did work.", 'title': u'My mistake'}], 'desc': u"Overriding __setattr__ in classes requires care when setting attributes yourself. Here's an idea for safely setting attributes in __init__.\n\nUpdate: this idea doesn't work. See Mike Foord's recipe for one that does:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389916"}, {'comments': [{'comment': u'Module textwrap implements this and more, http://docs.python.org/lib/module-textwrap.html\n<br>\n<pre>\nimport textwrap\ndef format(text, indent=2, width=70):\n return "\\n".join( textwrap.wrap(text, width=width, initial_indent=" "*indent, subsequent_indent=" "*indent) )\n</pre>', 'title': u"Nice, but module 'textwrap' may be a better choice"}, {'comment': u'testwrap.fill is equivalent to "\\n".join( textwrap.join ), so maybe\n<pre>\nimport textwrap\ndef format(text, indent=2, width=70):\n return textwrap.fill(text, width=width, initial_indent=" "*indent, subsequent_indent=" "*indent)\n</pre>', 'title': u'Silly me'}, {'comment': u'Isn\'t\n<pre>\nstack = text.split()\n</pre>\nequivalent to\n<pre>\nstack = [word for word in text.replace("\\n", " ").split(" ") if word]\n</pre>\n?', 'title': u"A 'split' comment"}, {'comment': u'Yes, it is. Maybe I should read the manual, hm?', 'title': u'Oops.'}, {'comment': u'...the line "if len(line) + len(" " + stack[0]) > width:" is a little wonky. By adding a " " to stack[0] you\'re allocating a whole new string and then throwing it away just to take the length. You should have said something like: "if len(line) + 1 + len(stack[0]) > width:" Or better yet, done something like this:\n\n<pre>\ndef format(text, indent=2, width=70):\n width = width - indent\n out = []\n\n # Make a generator to yield words and lengths.\n # Add 1 to the lengths to account for spaces.\n gen = ((len(word) + 1, word) for word in text.split())\n\n line = []\n line_len = -1 # adjust for space for 1st word.\n\n for wlength, word in gen:\n\n # Add word length (plus space length) to line length.\n line_len += wlength\n\n # Check if we\'ve filled a line.\n if line_len > width:\n\n # Build and append one line.\n out.append(" " * indent + " ".join(line))\n\n # Set line and length to word and length.\n line = [word]\n line_len = wlength - 1\n\n # If not, keep adding words to the line list.\n else:\n line.append(word)\n\n return "\\n".join(out)\n</pre>\n\nThis avoids all the expensive string operations you used to build your lines, and the repeated calls to len(line) in your inner while loop.\n\nOf course, you really should have just used the textwrap module, as Ori says.', 'title': u'Yes, and...'}], 'desc': u'This function formats a block of text. The text is broken into\ntokens. (Whitespace is NOT preserved.) The tokens are reassembled\nat the specified level of indentation and line width. A string is\nreturned.'}, {'comments': [], 'desc': u"Who's the most prolific committer in town? Use this script to find out!\n\nThis script uses pysvn, http://pysvn.tigris.org"}, {'comments': [], 'desc': u'You want to use nicely formatted timedeltas as an alternative to using absolute dates. Instead of writing "Last modified 2006-07-01" you want that to read "Modified two months ago" Or you are working for a credit card company and you want to send threatening letters; "Dear sir or madam, two weeks ago we contacted you about your overdue credit..."'}, {'comments': [], 'desc': u'Clear the screen on unix terminals, uses terminfo.\n\nterminfo inspiration courtesy of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116'}, {'comments': [{'comment': u"One can still use the __init__ method, which works just like an update.\n<pre>\n>>> t = tuct(a=20,c=40,b=30)\n>>> t\n{'a': 20, 'c': 40, 'b': 30}\n>>> t.__init__(a=0,z=1000)\n>>> t\n{'a': 0, 'c': 40, 'b': 30, 'z': 1000}\n>>>\n</pre>\n\n-- Nilton", 'title': u'Almost worked :)'}, {'comment': u'...and overload all changing methods to throw type-errors?<br>\n<br>\nGreets<br>\nMalte', 'title': u'Why not derive from dict...'}, {'comment': u'Because, if we had derived from dict, the class would be slower.', 'title': u'Speed'}, {'comment': u'So, do you recommend me something, in order to prevent this?', 'title': u'Recommendation'}, {'comment': u"<pre>class tuct(dict)\n def __setitem__(self, key, val):\n pass\n</pre>\n<br>\nIf I'm not wrong this does the same. But as Nilton mentioned, the via the __init__ you still can update it ;-).<br>\n<br>\nPS: I'm on Python 2.4<br>", 'title': u'Why not inherit from dict'}, {'comment': u"isn't hashability the primary reason for immutability?\n<pre>class tuct(dict):\n def __setitem__(self, key, value): pass\n def __hash__(self):\n items = self.items()\n res = hash(items[0])\n for item in items[1:]:\n res ^= hash(item)\n return res\n</pre>", 'title': u'__hash__'}, {'comment': u"something like this?\n\n<br><pre>\ndef __init__( self , dict = None , **kwds ) :\n if hasattr(self,'data'):\n raise AttributeError, '__init__'\n self.data = {}\n if dict is not None:\n self.data.update( dict )\n if len( kwds ) :\n self.data.update( kwds )\n\n del self.__init__\n</pre><br>\n\nbye,\nrm", 'title': u'__init__'}, {'comment': u'slower? it ought to be faster. you should really test that.', 'title': u'why?'}, {'comment': u'slower? it ought to be faster. you should really test that.', 'title': u'why?'}, {'comment': u"<pre>\n>>> class tuct(dict):\n... def __setitem__(self, key, value): pass\n... def __hash__(self):\n... items = self.items()\n... res = hash(items[0])\n... for item in items[1:]:\n... res ^= hash(item)\n... return res\n \n>>> d = tuct(test='test')\n>>> d\n{'test': 'test'}\n>>> d['test'] = 1\n>>> d\n>>> d.update(test=90)\n>>> d\n{'test': 90}\n>>> d.setdefault('moo', 1)\n>>> d\n{'test': 90, 'moo': 1}\n</pre>\nI think the envelope/letter idiom works well, especially when you need a immutable map for a class attribute or a default value.\n\n", 'title': u'RE: __hash__'}], 'desc': u'The implementation of a dictionary, whose items cannot be reset or deleted, nor new can be added.'}, {'comments': [], 'desc': u'The new Lego Mindstorms NXT brick has an on-board Bluetooth transceiver that can\nconnect to a serial port service on a PC. The NXT uses a simple format to pass\nraw bytes between connected Bluetooth devices. This interface allows the NXT \nbrick to be controlled from Python. Robot programming in Python anyone?'}, {'comments': [{'comment': u'Your first example should return 2, not 1.', 'title': u'mistake in docstring'}, {'comment': u"Yes, indeed! I've fixed it. Thanks.", 'title': u' '}], 'desc': u"Sometimes inside a decorator that creates a function with a generic (*args, **kwargs) signature, you want to access a value passed for a particular parameter name to a wrapped function, but don't know whether that value will be passed as a positional or keyword argument, or whether the wrapped function defines a default value for the parameter. The following utility function extracts this information for you."}, {'comments': [], 'desc': u'Konig\'s theorem tells us that every bipartite graph with maximum vertex-degree d can be edge-colored with just d colors.\nThis recipe relies on a previous recipe by D.Eppstein (123641) : "Hopcroft-Karp bipartite matching".'}, {'comments': [], 'desc': u'To split a textual table automatically. Improved from a comp.lang.python request.'}, {'comments': [], 'desc': u"A short and simple script to print your Web server's environment variables to the screen using mod_python and the Publisher handler."}, {'comments': [], 'desc': u'Script to enumerate the members of groups in the domain.'}, {'comments': [], 'desc': u'This is merely a sketch for a bare-bones XML 1.0 generator.I wrote it for working on little tasks for which other generators seem to be too much complex.\nPython version used to test this code was 2.4.3 on a Win32 platform.'}, {'comments': [], 'desc': u'ISBN, the International Standard Book Number, will migrate to 13-digits version from current 10-digits version on 2007-01-01. This recipe converts ISBN-10 to ISBN-13 by regenerating the check digit.'}, {'comments': [], 'desc': u'This recipe will insert multiplication symbols and convert all grouping symbols to equivalent parentheses. Uses the tokenize module for compact coding.'}, {'comments': [{'comment': u"The implementation above shares memos between different instances of the same object. If you want each instance to use a different memo, use something like this:\n\n<pre>\nclass memoized_method(memoized):\n def __init__(self, func, capacity, keyfunc=lambda *args, **kwargs: '%s: %s'\n % (id(args[0]), cPickle.dumps((args, kwargs)))):\n memoized.__init__(self, func, capacity, keyfunc)\n</pre>", 'title': u'Memos are shared between instances'}], 'desc': u"There are quite a few memoize decorators floating around, but none that met all my requirements. Here's my attempt. It draws from Bengt Richter's O(1) length-limited LRU cache (http://mail.python.org/pipermail/python-list/2002-October/125872.html) and a simplification of Daniel Brodie's Simple Decorators recipe (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/437086)."}, {'comments': [{'comment': u'You could instead replace the final line of the function with\n<pre>\n L.append(end - start)\n</pre>\n\nYou would then use the function as follows:\n<pre>\n t = []\n with accum_time(t):\n sum(range(1000000))\n with accum_time(t):\n sum(range(2000000))\n</pre>\nThis accumulates a list of times for each separate task, which you can then pass to the sum function for a final total:\n<pre>\n total = sum(t)\n</pre>', 'title': u'An improvement'}], 'desc': u'This recipe allows one to use the "with" statement to time sections of code.'}, {'comments': [], 'desc': u"This is a simple implementation of an octree data structure in python. Its use is primarily for fast collision or view frustrum culling in interactive 3d environments, but its possible uses are quite open-ended. It was originally written for use with the pyOgre 3d engine binding. The code makes use of recursive functions to insert and find nodes in the octree, and is heavily commented. It can store any type of object you create, so long as that object has a 'position' property in the form of a 3-vector tuple. It includes a test function which relies on the random module, but the octree itself has no required dependencies. It will try to use the psyco module to speed up its execution, but that is not essential."}, {'comments': [{'comment': u"I really don't like deepcopying values using the deepcopy() function. It slows your algorithm down and is kind of a last resort. Although the simplicity of the algorithm may be destroyed I would suggest more case analysis. For instance if L is a list of immutables it is appropriate to clone it using K = L[:]. One might even think about using a lazy datatype, that creates columns on demand ( depends on usage of course ).", 'title': u'Deepcopy'}], 'desc': u"Two functions useful when you don't use a numerical library. The first one creates a tensor, hopefully in the correct way, avoiding the mutability trap.\nThe second one transposes a 2D matrix keeping the type of the lists/tuples used."}, {'comments': [{'comment': u'remove "dict.pop(name)", or at least remove it with "dict.pop(name, None)".', 'title': u'1 bug'}], 'desc': u"This code here creates real mixed-in classes: it actually merges one class into another (c-python specific), taking care of name-mangling, some complications with __slots__, and everything else. As a side-effect, you can also use it to mix modules into classes. Similar to ruby's include statement."}, {'comments': [], 'desc': u'This recipe can be used to read in simple human readable intialization files.\nIt uses callback methods similar to some SAX implementations I have seen.'}, {'comments': [], 'desc': u'Retrieve a list of the available exhange rates from the NY Federal Reserve, and create a list of US Dollar to currency multipliers.'}, {'comments': [{'comment': u'Interested users may also want to check out geopy at http://exogen.case.edu/projects/geopy/, it also has support for this method.', 'title': u'geopy'}], 'desc': u'A simple script written as an experiment in geocoding addresses in a database. An address such as "100 Any Street, Anytown, CA, 10010" is passed to a Google Maps URL, and the latitude/longitude coordinates are extracted from the returned XML.\n\nXML methods are not used in this script, but simple string searches instead.'}, {'comments': [], 'desc': u'When loading text files into database tables (MSSQL in this example), the source columns often do not match the table definition. This script was written to find the maximum length of each column in a delimited text file, then modify the a table create DDL file to make each character column wide enough, so truncation errors do not occur.'}, {'comments': [{'comment': u'http://furius.ca/pubcode/pub/conf/common/bin/csv-db-import.html\n\nI think this program does something similar, and guesses the types automatically (you can also override with a header row).', 'title': u'csv-db-import'}], 'desc': u"Script generates CREATE TABLE statements based on the width of data present in comma delimited (csv) test files. Setting the correct datatypes (other than VARCHAR), is still a manual adventure.\n\n# TODOs: \n#\tEliminate '#N/A', '@NA' from data\n#\tRemove commas from numeric data\n#\tCheck for duplicate column names\n#\tCreate BCP format file or INSERT statements?"}, {'comments': [{'comment': u'What is the reason @catches exists (other than being a reminder) ? Shouldn\'t @catches and @throws be merged together or @catches be totally gotten rid of ?<br>\n<br>\nIf there is another reason for @catches, why would one want to declaratively specify the handler as in <br>\n<br>\n@catches(ZeroDivisionError, handler = lambda exc, msg, traceback: "zero-div") ?<br>\n<br>\nA bit ugly to me. Also, if a method fails to catch what it\'s supposed to catch, isn\'t it the same as if it was a method with @throws throwing an unexpected one ?<br>\n<br>\nAnyhow, this looks like a good companion to these related decorators:<br>\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/426123', 'title': u'Nice one'}, {'comment': u'If you want to get rid of @catches how do you check for the exception to be caught? \n<br>\n<br>\nThe argument signature of the handler callback might be "ugly" but it is the excact complement of Pythons raise statement:\n<br>\nhttp://docs.python.org/dev/ref/raise.html\n<br>\n<br>\nThe @catches decorator serves the single purpose of guaranteeing that the declared exception is actually handled. But it doesn\'t change\nthe behaviour of the program otherwise. That\'s why it doesn\'t do anything interesting by default but re-raises the caught exception\n( the act of catching the exception is a proof of it\'s treatment. I do don\'t see another way to check this without doing static analysis ).\nYou are right or course that it is not much more than an enforced reminder but these are checked exception declarations anyway. ', 'title': u'Handling what shall be handled'}, {'comment': u'I dislike checked exceptions, but this is so cool! (not going to use it though :)', 'title': u'Niiiice!'}], 'desc': u'Checked exceptions are one of the most debated features of the Java language. A checked exception is a contract between a function that declares and throws an exception and another function that calls those function and has to handle the exception in its body. This recipe presents a checked exception implementation for Python using a pair of decorators @throws(Exc) and @catches(Exc,...). Whenever a @throws decorated function is called it has to be inside of a function that is decorated by @catches. Otherwise an UncheckedExceptionError will be raised - unless the declared exception Exc is raised. '}, {'comments': [], 'desc': u'A set of template classes which allows to develop custom "mini-command"\nclasses which allow to execute any system command and customize the\nexecution using template strings. '}, {'comments': [], 'desc': u"I really like the Python 2.5 generator extensions. I have cases where I want a generator to pass a reference to itself to another generator, or to store it in a queue etc. Here's how a generator can get its own handle. "}, {'comments': [{'comment': u' ', 'title': u'Useful!!'}], 'desc': u'Weakly-bound methods: use this decorator to create methods that weakly-reference their instance (im_self). This means that the method itself will not keep the object alive. Useful for callbacks, caches, and avoiding cyclic references.'}, {'comments': [], 'desc': u'This module provides an advanced, easy-to-use API for\naccessing and mutating the Microsoft Windows Registry.\n\nExample code and instruction is given for discussion.'}, {'comments': [{'comment': u"Class MetaStruct is interresting. I didn't know that it's possible to get attributes in the order that they are defined. I have to play with metaclasses :-) You have to see pyConstruct project:\nhttp://pyconstruct.wikispaces.com\n\nI'm working on the same subject but with different syntax (different approach):\nhttp://hachoir.org/\n\nHachoir is a lazy-parser and fault tolerant. It allows to edit data and have tree organization with nice Python API.\n\nHaypo", 'title': u'Very interresting code :-)'}, {'comment': u"Would it be possible to allow the arrays to be dynamic? I know some binary formats that use that, like\n\n<pre>\nnumber_fields: integer\ndates: date[number_fields]\n</pre>\n\nI haven't found any struct-replacement that does that.", 'title': u'Dynamic arrays?'}, {'comment': u"I think this would be fairly hard to do. Currently I'm relying on knowing the sizes of various substructures etc. in advance, in order to know how to represent them in containing structures. I think it should be possible (given some restrictions like the count appearing before the array in the struct), but would probably require a different approach.", 'title': u'Dynamic arrays'}, {'comment': u'Getting the definition order requires a bit of a cheat. The idea is to create an object, and track the order they were created in, and then later sort based on this order. It does limit the syntax you can use to something that can create and return a new object though: "x=Foo.attr", "x=Foo()" and "x=Foo[1]" would all work given an appropriate Foo , but you can\'t use just "x = Foo".\n<br><br>\n\npyConstruct looks pretty neat. I\'ll check it out.', 'title': u'Definition order'}, {'comment': u'Both Hachoir and pyConstruct allow dynamic structure. pyConstruct uses Python eval() function to access to other fields:\n<pre>\n>>> # a TLV is a type-length-value entity. the length of the value is specified\n... # by the \'length\' field\n... tlv = Struct("tlv",\n... Byte("type"),\n... Byte("length"),\n... MetaBytes("value", "_.length"),\n... )\n</pre>\n\nHachoir approch is different: you directly access to the structure using [] operator (self["name"]):\n<pre>\nclass Chunk(FieldSet):\n def createFields(self):\n yield UInt32(self, "size")\n yield String(self, "tag", 4, charset="ASCII")\n yield RawBytes(self, "data", self["size"].value)\n</pre>\nWhere self["size"] is a Field object and has many attributes: value, address, absolute_address, parent, display (unicode string), etc. I don\'t have enough place here to explain all Hachoir internals :-)<br>\n<br>\nHaypo', 'title': u' '}, {'comment': u'In fact, pyConstruct, linked to in the post above by Victor Stinner looks like it would handle this. I think the equivalent of your example would be something like:<br>\n<pre>\nDate=LittleFloat64("timestamp")\n\nDynamicArray=Struct("dynamic_array",\n UInt32("number_fields"),\n MetaRepeater("_.number_fields", Date)\n)\n\ns= DynamicArray.build( Container(number_fields=2,\n timestamp=[time.time(), time.time()]))\n\nprint repr(s)\nprint DynamicArray.parse(s)\n</pre>', 'title': u'Just to follow up'}, {'comment': u"Cool, thanks for the tips, I'll look into them!\n", 'title': u' '}, {'comment': u"<br>This is a very nice recipe, worth the inclusion in the standard library!<br>\nI have a remark though. Is it possible to split the construction by keywords from the construction by decoding.<br>\nI mean:<br>\ns1=Shape(name='Triangle', numpoints=3, points=[\n\t\tPoint(x=0,y=0),\n\t\tPoint(x=5,y=5),\n\t\tPoint(x=10,y=0),\n\t\tPoint(x=0,y=0)])<br>\nand <br>\ns2=Shape.decode('Triangle\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x05\\x00\\x0A'\n\t'\\x00\\x00\\x00\\x00\\x00\\x00')<br>\nThis would be neater as you don't know in advance the contents of the string buffer and you might have a higher-level decode resting on<br> several lower-level decode<br>This is a very nice recipe, worth the inclusion in the standard library!<br>\nI have a remark though. Is it possible to split the construction by keywords from the construction by decoding.<br>\nI mean:<br>\ns1=Shape(name='Triangle', numpoints=3, points=[\n\t\tPoint(x=0,y=0),\n\t\tPoint(x=5,y=5),\n\t\tPoint(x=10,y=0),\n\t\tPoint(x=0,y=0)])<br>\nand <br>\ns2=Shape.decode('Triangle\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x05\\x00\\x0A'\n\t'\\x00\\x00\\x00\\x00\\x00\\x00')<br>\nThis would be neater as you don't know in advance the contents of the string buffer and you might have a higher-level decode resting on<br> several lower-level decode", 'title': u'Very nice recipe'}, {'comment': u'<pre>\nOnce you call Point3D, the parent class Point gets corrupted and it gets impossible to call it with only 2 arguments.\nAlain</pre>', 'title': u'inheritance bug'}, {'comment': u"Could you give some example code that fails. I've tried both<br>\n<pre>\np = Point(x=1, y=2)\np = Point('\\x01\\x00\\x02\\x00')\n</pre>\nafter the same code as above, and both seem to work. I did have a similar bug when developing it, but fixed it by taking a copy of _struct_data for the subclass (previously it was mutating the parent class's list). Is this still happening somewhere?", 'title': u"I'm not seeing it"}, {'comment': u'It should be pretty simple to do - just move the _data parameter and all but the "for k,v in kwargs.iteritems():" loop out of __init__ and into a new decode classmethod. I\'m not sure what you mean by your use case though - wouldn\'t that also be possible through __init__ too? <br><br>\n\nThe main reason I went with __init__ and __str__ overloads rather than pack / unpack methods was that I didn\'t want to add anything into the public namespace of the class, as it would prevent defining struct fields with the same name. If there\'s a good reason though, perhaps this isn\'t that important.', 'title': u'decode method'}, {'comment': u'Stupid me, I was experimenting with the code and i broke it myself !\nSorry !', 'title': u'Sorry'}, {'comment': u'Can you please explain me some strange behaviour.<br>\nI try to play with the Point class.<br>\nThe code is:<br>\nclass Point(Struct):<br>\n _format = Format.LittleEndian<br>\n x = Type.Short<br>\n a = Type.Char # the place is important <br>\n y = Type.Short<br>\n <br>\np = Point()<br>\np.x, p.y = 100,200<br>\nprint repr(p) # Prints "Point(\'d\\x00\\xc8\\x00\')<br>\n<br>\nI have error (of struct.unpack(...)) in __init__ of Struct.<br>\nIf I change the _format = Format.Native error is gone.<br>\nIf I put the a = Type.Char after the y = Type.Short\nthe error is gone too. ', 'title': u'Strange behaviour of class Point'}, {'comment': u'Can you please explain me some strange behaviour.<br>\nI try to play with the Point class.<br>\nThe code is:<br>\nclass Point(Struct):<br>\n _format = Format.LittleEndian<br>\n x = Type.Short<br>\n a = Type.Char # the place is important <br>\n y = Type.Short<br>\n <br>\np = Point()<br>\np.x, p.y = 100,200<br>\nprint repr(p) # Prints "Point(\'d\\x00\\xc8\\x00\')<br>\n<br>\nI have error (of struct.unpack(...)) in __init__ of Struct.<br>\nIf I change the _format = Format.Native error is gone.<br>\nIf I put the a = Type.Char after the y = Type.Short\nthe error is gone too. ', 'title': u'Strange behaviour of class Point'}, {'comment': u'Can you please explain me some strange behaviour.<br>\nI try to play with the Point class.<br>\nThe code is:<br>\nclass Point(Struct):<br>\n _format = Format.LittleEndian<br>\n x = Type.Short<br>\n a = Type.Char # the place is important <br>\n y = Type.Short<br>\n <br>\np = Point()<br>\np.x, p.y = 100,200<br>\nprint repr(p) # Prints "Point(\'d\\x00\\xc8\\x00\')<br>\n<br>\nI have error (of struct.unpack(...)) in __init__ of Struct.<br>\nIf I change the _format = Format.Native error is gone.<br>\nIf I put the a = Type.Char after the y = Type.Short\nthe error is gone too. ', 'title': u'Strange behaviour of class Point'}, {'comment': u'Can you please explain me some strange behaviour.<br>\nI try to play with the Point class.<br>\nThe code is:<br>\nclass Point(Struct):<br>\n _format = Format.LittleEndian<br>\n x = Type.Short<br>\n a = Type.Char # the place is important <br>\n y = Type.Short<br>\n <br>\np = Point()<br>\np.x, p.y = 100,200<br>\nprint repr(p) # Prints "Point(\'d\\x00\\xc8\\x00\')<br>\n<br>\nI have error (of struct.unpack(...)) in __init__ of Struct.<br>\nIf I change the _format = Format.Native error is gone.<br>\nIf I put the a = Type.Char after the y = Type.Short\nthe error is gone too. ', 'title': u'Strange behaviour of class Point'}, {'comment': u"The padding applied by the struct module is different depending on the format selected. With native format, an extra pad byte is inserted after the char to align it to an even boundary. With the other formats, no padding is done.<br><br>\n\nI was including the format information when building the string, but not when calculating the size of the structure, so this was always defaulting to native format, giving a _struct_size of 6 when the struct expected 5. This meant that the initialisation string was the wrong size, giving the error you saw.<br><br>\n\nI've now updated the recipe to fix this. The relevant change was changing the line:\n<pre>\tcls._struct_size = struct.calcsize(cls._struct_data)</pre>\nto\n<pre>\tcls._struct_size = struct.calcsize(cls._format + cls._struct_data)</pre>\n\nThanks.", 'title': u'Thats a bug'}, {'comment': u'Hello,\n I\'m a beginning Python programmer and am very interested using\nyour \'A higher level struct module\' code. My problem may be as\nsimple as version confusion on my part, but I\'m stuck. Here\'s a\ntranscript. I\'ve saved the text source into packclass.py minus the\nexamples at the end.<br>\n\nI can load that file and can successfully do the example with the\nPoint class. However, when I try the Shape example, a class that\nuses an array type, I get an error.<br>\n\nIs there a workaround?<br>\n Thank you,<br>\n Mark Shirley\n\n<pre>\nPython 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32\nType "help", "copyright", "credits" or "license" for more information.\n>>> from packclass import *\n>>> class Point(Struct):\n _format = Format.LittleEndian\n x = Type.Short\n y = Type.Short\n\n... ... ... ... >>> p = Point(\'\\x01\\x00\\x02\\x00\')\n>>> print p.x, p.y\n1 2\n>>> print repr(p)\nPoint(\'\\x01\\x00\\x02\\x00\')\n>>> class Shape(Struct):\n _format = Format.BigEndian\n name = Type.String[8]\n numpoints = Type.Int\n points = Type.Struct(Point)[4] # Array of 4 points.\n\n... ... ... ... ... Traceback (most recent call last):\n File "", line 1, in \n File "", line 3, in Shape\nTypeError: \'Element\' object is unindexable\n>>> \n</pre>\n', 'title': u"TypeError: 'Element' object is unindexable"}, {'comment': u'<pre>\n[Sorry to repeat this. I submitted it earlier and saw it in the\nlist of comments, but it\'s not there now.]\n\nHello,\n I\'m a beginning Python programmer and am very interested using\nyour \'A higher level struct module\' recipe. My problem may be as\nsimple as version confusion on my part, but I\'m stuck. Here\'s a\ntranscript. I\'ve saved the text source into packclass.py minus the\nexamples at the end.\n\nI can load that file and can successfully do the example with the\nPoint class. However, when I try the Shape example, a class that\nuses an array type, I get an error.\n\nIs there a workaround?\n Thank you,\n Mark Shirley\n\n\nPython 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32\nType "help", "copyright", "credits" or "license" for more information.\n>>> from packclass import *\n>>> class Point(Struct):\n _format = Format.LittleEndian\n x = Type.Short\n y = Type.Short\n\n... ... ... ... >>> p = Point(\'\\x01\\x00\\x02\\x00\')\n>>> print p.x, p.y\n1 2\n>>> print repr(p)\nPoint(\'\\x01\\x00\\x02\\x00\')\n>>> class Shape(Struct):\n _format = Format.BigEndian\n name = Type.String[8]\n numpoints = Type.Int\n points = Type.Struct(Point)[4] # Array of 4 points.\n\n... ... ... ... ... Traceback (most recent call last):\n File "", line 1, in \n File "", line 3, in Shape\nTypeError: \'Element\' object is unindexable\n>>> \n</pre>\n', 'title': u"TypeError: 'Element' object is unindexable"}, {'comment': u'I tried that code here, and I don\'t get an error. From the exception you\'re getting, it looks like its not finding __getitem__ on the Element object (I think it is the line "name = Type.String[8]" that is failing)\n\nCould you check that the line\n<pre> def __getitem__(self, num): return self(num)</pre>\nis correctly copied below class Element. If it is missing, or not indented with the rest of the Element members, it would cause the error you\'re seeing.', 'title': u"I'm not sure"}], 'desc': u'This recipe provides a higher level wrapper around the struct module. It provides a more convenient syntax for defining and using structs, and adds additional features such as:\n - Allows embedding structures within other structures\n - Allows defining arrays of items (or other structures)\n - Class based syntax, allowing access and updates by field name, not position\n - Extension of structures by inheritance '}, {'comments': [], 'desc': u"The code presented below is a short example of how\nto use winreg. This recipe prints out as much data\nas possible about the user's registry. Hives are\nspecified as such before their representations.\nErrors in opening keys are listed with the problem\nkey's name."}, {'comments': [], 'desc': u"This recipe is another example of how to use the winreg module.\nThe code had the first purpose of demonstrating the concept of\na graphical shell built in Python. The shell was easily modified\nto make use of the Window's registry but retains traces of its\noriginal method of operation (all of which has been commented out)."}, {'comments': [], 'desc': u'If you have long-running scripts on many remote machines and you want to be alarmed if one of them crashes, use the JabberHandler to log it to your account.'}, {'comments': [], 'desc': u'it includes two guessing flavors one that randomly guesses a number and one that guesses in the most efective way i could think of (my brother had the second idea)'}, {'comments': [{'comment': u'On UNIX systems mkdir is atomic which makes creating a lock very simple. I suspect that this also applies to Windows.\n', 'title': u' '}, {'comment': u'For a simple lock, creating/checking for the presence of a dir (or file for that matter) would work. But if you want to do something more complex like remote execution over ssh, then you need to also keep track of hostnames.', 'title': u'Good point'}, {'comment': u'I\'m sorry I fail to see how this achieves atomicity. You\'ve got a race condition in acquire() between the "if self.islocked()" check and the subsequent call to open().\n\nIn order to implement filesystem locks, you need to use some sort of atomic call that both creates a filesystem object or fails. open(..., \'w\') is not good enough, i.e. two concurrent processes could succesfully run through the check in acquire(), and both open the file in write mode. You\'re not going to get errors (i.e. no locking will have occurred), and the later file will remain. You can use mkdir() instead, but I don\'t know if that\'ll work under Windows.\n\nIn any case, I thought it would be important to point out the flaw in this code, for the benefit of those who would cut-n-paste without looking.\n\n\n', 'title': u'Race condition'}, {'comment': u'No doubt. This code isn\'t so robust as to catch the codition you mention, but for 99% of the use cases, it should "just work". Please do correct and improve.', 'title': u'True...'}], 'desc': u'This recipe implements a simple lockfile to ensure that only one instance of an app is alive at any given time.\n\n1.2 Added documentation and cleaned up a bit.'}, {'comments': [], 'desc': u"expand_tabs.py - Similar to Unix's expand(1) command, but can edit the files in-place."}, {'comments': [{'comment': u'#this solution uses the re module and a single function.\n\nimport re\ndef currency(amount):\n temp = "%.2f" % amount\n profile=re.compile(r"(\\d)(\\d\\d\\d[.,])")\n while 1:\n temp, count = re.subn(profile,r"\\1,\\2",temp)\n if not count: break\n return \'$\'+temp\n\nif __name__ == "__main__":\n print currency(3458905.54)\n print currency(-49786002.40)', 'title': u'Another solution'}], 'desc': u"Needed formatted numbers with thousands separator commas added on an end-user report. The usual way mentioned is to use 'module locale.format', but that didn't work cleanly on my Windows machine, and the cure seemed worse than the disease."}, {'comments': [{'comment': u'You need to import pdb in .pdbrc otherwise you get a pdb undefined error message.', 'title': u' '}, {'comment': u"hmm, even with that, I can't get tab completion to work. It's fine if I do readline.set_completer(rlcompleter.Completer(locals()).complete)\n manually, but the .pdbrc method fails. This is with python-2.4.3 on Gentoo.", 'title': u' '}, {'comment': u'Thanks for the feedback. Here\'s what I think is going on:\n\ntab completion works fine without the import provided you\'re stepping into your code with\n<pre>import pdb\npdb.set_trace()</pre>\n\nHowever if you step in with "python -m pdb myscript.py" then python\'s pdb module creates an instance of the Pdb class before we can override it\'s complete function. Bummer.', 'title': u'python -m grabs our Pdb class!'}, {'comment': u'Thanks for the comments. After a bit of testing I discovered that this wasn\'t working with \'python -m myscript.py\' because we are changing the complete function on the Pdb class object in our current code block. However, running pdb via "python -m" uses execfile to start your script, and that is executed in a new code block. The side effect of this is that from .pdbrc.py the Pdb class object is not the one that is being used to run this pdb session. To get a reference to the original class object one needs to jump out of the current frame back to the frame that spawned this script. sys._getframe().f_back does that and f_globals[\'Pdb\'] then grabs the origional Pdb class. <pre>Woot, it works!</pre>', 'title': u'This is fixed!'}], 'desc': u"I make frequent use of python's built-in debugger, but one obvious feature seems to be missing - the bash-like tab completion that you can add to the interpreter. Fortunately pdb's interactive prompt is an instance of Cmd, so we can write our own completion function.\n\nNote: this uses rlcompleter, which isn't available on windows\n\nEdit: updated to handle changes in local scope\nEdit: Fixed start via 'python -m pdb ...'. Check the comments for details.\n"}, {'comments': [], 'desc': u'Finds a windows hostname given the username'}, {'comments': [], 'desc': u'This python script monitors the IMAP mail server for the given\t\t\t account and moves the mails with attachments to "Downloadedmails"\nfolder in server after downloading the attachments to the individual\ndirectories on localmachine with the timestamp.'}, {'comments': [], 'desc': u'This class implements an interface similar to threading.Event using os.pipe() as the mechanism for signalling. This allows the class to be used to wake up select.select() and select.poll() loops without having to peridiodically resume execution to check the status of an event.'}, {'comments': [], 'desc': u'Yet another implementation of an Odict, a dictionary in which the *insertion* order of items is preserved.'}, {'comments': [{'comment': u"Isn't the quoting of subprocess.list2cmdline safe enough?", 'title': u' '}, {'comment': u"list2cmdline has two 'problems':\n<br>\n<br>(1) It is not mentioned in the Python documentation (a sure sign that the author prefers to keep the use of it private and does not want to take the burden of maintaining it)\n<br>\n<br>(2) From the code, it is clearly for use in a Microsoft only environment. QuoteForPOSIX is intended for UNIX environments.\n<br>\n<br>\nThe subprocess module is a goldmine for little nuggets like list2cmdline and I really hope the author would promote it.", 'title': u'Use of list2cmdline'}, {'comment': u'The original code does not run. \'p\' is used before the loop that declares it. I belive the following code does the same thing and does work.<br>\n\n<pre>\ndef quote_for_POSIX(string):\n\n output = "\'"\n output += string.replace( "\'", r"\\\'" )\n output += "\'"\n\n return output\n</pre>\n\nAs a side issue I have found that if using file names escaped this way as the command line in a call to os.popen() the quoting is not respected and a name with spaces is incorrectly interpreted as multiple arguments.', 'title': u'Code does not work'}, {'comment': u"The re module isn't actually used in the code, so the import of it can be omitted.", 'title': u'Unnecessary import'}, {'comment': u'Are split() and join() more efficient than something like:\n<br>\n<pre>\n return "\'%s\'" % string.replace( "\'", r"\'\\\'\'" )\n</pre>\nor\n<pre>\n return "\'" + string.replace( "\'", r"\'\\\'\'" ) + "\'"\n</pre>\n?', 'title': u'replace() vs. split() and join()?'}], 'desc': u'Often one has to quote a python string so that the result can be used as an argument to a command running in a POSIX shell.\n\nThe function QuoteForPOSIX can be used with sh, bash, csh, ksh\n'}, {'comments': [], 'desc': u'This code snippet shows how to kich off a performance data gathering shell script with telnetlib and download the data back to a local workstation with ftplib. \n'}, {'comments': [], 'desc': u'a small script which i use to get the DHCP ip of my laptop '}, {'comments': [], 'desc': u"I found django's auth module is too complex for my needs, instead I wrote a relative simple one, but I miss the login_required decorator in django auth module, so I decide to write a new one."}, {'comments': [], 'desc': u'DOM2ET is a simple python function which converts a DOM node object of type element to an ElementTree Element.\n<br>\nWriting it, was a good exercise to understand the workings of ElementTree \n'}, {'comments': [{'comment': u'<pre>\nfrom operator import itemgetter\nfrom itertools import groupby\n\ndict([(k,[h[1] for h in g]) for k,g in groupby(sorted((bool(n%2),n) for n in range(10)),key=itemgetter(0))])\n\ndict([(k,[h[1] for h in g]) for k,g in groupby(sorted((n%3,n) for n in range(10)),key=itemgetter(0))])\n\ndict([(k,[h[1] for h in g]) for k,g in groupby(sorted((article.author.lower(),article.summary) for article in articles),key=itemgetter(0))])\n</pre>\nThese do the same thing as the examples shown. The recipe is still usefull because clarity and efficency is better than one liners in many cases.', 'title': u'For the one-liner lovers out there'}], 'desc': u"This recipe enables the group_by functionality from Ruby on Rails, which is to be included in next version of Ruby. This code is from Ian Bicking's suggestion in discussing partition function in Ruby and Javascript by Ned Batchelder. \n\nOriginal Post: http://www.nedbatchelder.com/blog/200607.html#e20060730T221504\n\nHere is Ian Bicking's Response:\nhttp://www.nedbatchelder.com/reactor/comment.php?entryid=e20060730T221504"}, {'comments': [], 'desc': u'To choose among a list of objects using a specified frequency distribution.'}, {'comments': [], 'desc': u'Technocrati (http://www.technorati.com/) maintains a list of blogs tagged with user specified tags. People can submit their blogs for inclusion in Technocrati by using their RPC ping service at http://www.technorati.com/ping. This piece of code allows you ping Technocrati with blog details through a script.'}, {'comments': [{'comment': u'I generally find the<br>\nfrom numpy import *<br>\nto be bad style. In particular, it would be helpful\nin a recipe to show exactly where everything comes from.\nIf you want to be lazy later and import things with\nthe star notation, that is fine, but here it just\nobfuscates things.', 'title': u'Bad style'}], 'desc': u'Just a few lines of code if you are willing to use numpy. Uses fact that any prob. distr. can be sampled by computing the cumulative distribution, drawing a random number from 0 to 1, and finding the x-value where that number is attained on the cumulative distribution. The searchsorted(..) function performs this search.'}, {'comments': [], 'desc': u'Here are two examples showing how to script iTunes for Windows with Python.\nSee below under "Discussion" for additional comments and explainations.'}, {'comments': [], 'desc': u'The make statement from PEP 359 is implemented using decorators and function definitions.\n\nThe make statement:\n<pre>make <callable> <name> <tuple>:\n <block></pre>\nis implemented this way:\n<pre>@make(<callable>, <tuple>)\ndef <name>():\n <block></pre>\nThe code also has some examples, using the make decorator to create a namespace and a class.'}, {'comments': [], 'desc': u'Takes as input a graph and outputs Eulerian path (if such exists). The worst running time is O(E^2).'}, {'comments': [], 'desc': u'One-line decorator call adds caching to functions with hashable arguments and no keyword arguments. When the maximum size is reached, the least recently used entry is discarded -- appropriate for long-running processes which cannot allow caches to grow without bound. Includes built-in performance instrumentation.'}, {'comments': [], 'desc': u'Three ways to calculate a distance matrix out of a list of n-dimensional points using scipy.'}, {'comments': [], 'desc': u'The os.path.walk routine that ships with the python standard library is limited to traversing the file system tree. A generic traversal for arbitrary (directed) graphs with support for recursion limits and other accumulated partial results seems useful.'}, {'comments': [], 'desc': u'The recipe illustrates the composite design pattern by using hierarchical dictionaries. It can be used to process hierarchical, tree-based data structures using Python dictionaries.'}, {'comments': [], 'desc': u"This is a solution to the first problem in this tutorial:\nhttp://www.ai-junkie.com/ga/intro/gat1.html\n\nI wrote it in about an hour, and tried to keep everything as clear and simple as possible. Please excuse the sparse commenting.\n\nI deviated from the examples in the tutorial in several ways, the most important of which is the way the results are evaluated. In the tutorial it is stated that the equations are solved from left to right, but for expedience I let Python's operator precedence determine the order of evaluation. I'm not sure how close this example is to the example solution provided in the tutorial. I was to lazy to download unzip and decode the C source...\n"}, {'comments': [{'comment': u"The 'consumer' decorator is useful all by itself.", 'title': u'@consumer'}], 'desc': u"Implements the observer design pattern via generator coroutines, wrapped up to use the new 'with' statement of Python 2.5. Enables the loosely-coupled observation of any container implementing the dictionary protocol."}, {'comments': [{'comment': u"This example is very interesting, but it does not demonstrate why a co-routine is useful. In this case, a straight-forward, partially evaluated closure would have been simpler.\n<pre>\nfrom functools import partial\n\ndef record_if_BLACK(order, v, old_color, new_color):\n if new_color == BLACK:\n order.appendleft(v)\n\nwith observation(observe=coloring,\n notify=[partial(record_if_BLACK, \n ordering)]) as coloring:\n ....\n</pre>\n(Of course, 'observation' would have to be modified to call 'notify' directly, rather than notify.send().)\n<br><br>\nIn fact, we could turn the whole toposort into an iterator (in order of finishing time).\n<pre>\ndef yield_if_BLACK(v, old_color, new_color):\n if new_color == BLACK:\n yield v\n\nwith observation(observe=coloring,\n notify=[yield_if_BLACK]) as coloring: \n ....\n</pre>\nNow, we would get the results from toposort as they are found (but not in reverse order, naturally). However, only one 'consumer' can yield to the caller of toposort.\n<br><br>\nWhile the direct function call is much clearer, the co-routine is potentially quite powerful since it can maintain state, not only between calls, but before and after the entire algorithm. I do like the co-routine very much. Python looks more like Ruby all the time.", 'title': u'Interesting example.'}], 'desc': u"Implements the toposort and strongly_connected_components graph algorithms,\nas a demonstration of how to use the recipe, 'Implementing the observer pattern\nyet again: this time with coroutines and the with statement'.\n\nSee http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/498259\n"}, {'comments': [], 'desc': u'The str() in the standard library behaves in a slightly weird way when applied against lists: on each element of the list, the repr() is appended. In contrast, this module provides a deep_str() that deeply applies str() across lists.'}, {'comments': [], 'desc': u'In this recipe the builtin function reduce is generalized to a Python 2.5 style generator called greduce. The generator never stops and can be used to create an infinite stream of values by means of the generators send() method. '}, {'comments': [], 'desc': u'Purpose: Easing maintenance of JavaScript files and their inclusions in web pages by server-side dependency resolution. If at the top of a.js you include the comment\n\n// requireScript b.js\n\nand at the top of b.js you say\n\n// requireScript c.js\n\nthen JSResolver\'s method .asTags(\'a.js\') will give you e.g.\n\n<script language="javascript" src="c.js"></script>\n<script language="javascript" src="b.js"></script>\n<script language="javascript" src="a.js"></script>\n\nwhich you can then stick straight into your web page. \n\nCircular dependencies between JS files are forbidden and raise an exception.'}, {'comments': [{'comment': u'There already exists various LRU implementations in the cookbook.', 'title': u' '}, {'comment': u"... and searching for 'lru' turns up quite a few of them. Well, reinventing the wheel is at least educational if nothing else... this container though applies both a time limit and strives for thread safety, so there may yet be a little bit of merit in this recipe.", 'title': u'True...'}], 'desc': u'This container stores its items both in a dict (for direct access) and in a bi-directionally linked list, which enables it to update itself in essentially O(1) time. No iteration over the entire list is ever needed, no separate thread is required for cleaning either. Should be useful e.g. for session storage in web servers.'}, {'comments': [], 'desc': u'Python 2.5 improved the support for generators, making it easier to\nuse coroutines. If you want to use coroutines, however, you can not\ntransfer control out of nested functions. You can eliminate this\nrestriction by systematically converting regular functions into\ngenerator functions as demonstrated by this recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474127 The script below might\nserve as a starting point to do this transformation automatically,\nmaking the use of coroutines (tasklets, lightweight threads...) more\nnatural.'}, {'comments': [], 'desc': u'This is a simple recipe which uses generators to execute a chain of functions. These functions and their argurments are internally present in a list.Here use of generators and properties defined on the result set gives more control to users.'}, {'comments': [{'comment': u'This makes Python look more like Ruby.', 'title': u'Interesting.'}], 'desc': u'This recipe may be of interest to those who make heavy use of the itertools module. It provides a wrapper class that exposes most itertools functions as methods, plus a few more. Moreover, two frequently used itertools functions, chain and islice, are conveniently exposed as addition and slicing operators, respectively.'}, {'comments': [{'comment': u'__encoding__ = "utf-16"\n<br>\nshould read \n<br>\n# -*- coding: utf-16 -*-\n<br>\nand it should be on the top line.', 'title': u'Encoding syntax error'}, {'comment': u'The source is all-ASCII anyway.', 'title': u'UTF-16: Is it really needed?'}, {'comment': u"No. You're absolutly right. I had it in my head that without it python 2.5 raised a warning when importing it due to the non-ascii characters on line 28. It doesn't.", 'title': u'Is it really needed?'}], 'desc': u'A utility class to validate and parse (simply) International Securities Identification Numbers.'}, {'comments': [], 'desc': u'We alias the memory from a cairo surface so that we can manipulate the bits as a numpy array, or display/manipulate the image in pygame.'}, {'comments': [], 'desc': u'Solves the "tail-problem" for prose-oriented XML. Recursively pulls text out of elements and their sub-elements. Extracts text from DocBook, XMHTL, and other nested XML markup.'}, {'comments': [], 'desc': u'Developing with the interactive interpreter can be tricky. When your class changes, you need to reload the module and create new objects with the new code.\n\nThis recipe offers a simple wrapper which will make reloading a bit easier.'}, {'comments': [{'comment': u'There\'s a general purpose module in the \'QP\' package (see qp.lib.spec) which provides a useful "specification" capability which you might also find interesting:\n\n<pre>\n->> from qp.lib.spec import mapping, require\n\n# require that all keys of the dict be of type \'str\' and values be of type \'int\'\n->> myspec = mapping({str:int}, dict)\n->> require({\'foo\':123,\'bar\':456}, myspec)\n->> require({\'foo\':123,\'bar\':\'456\'}, myspec)\nTraceback (most recent call last):\n...\nTypeError: \n Expected: mapping({str: int}, anything)\n Got: {\'foo\': 123, \'bar\': \'456\'}\n\n\n# require that all keys of the dict be of type \'str\' and values be of type \'int\', and that key values be of specific values\n->> myspec2 = mapping({(\'foo\',\'bar\'):int}, dict)\n->> require({\'foo\':123,\'bar\':456}, myspec)\n->> require({\'foo\':123,\'bar\':456}, myspec2)\n->> require({\'foo\':123,\'bars\':456}, myspec2)\nTraceback (most recent call last):\n...\nTypeError: \n Expected: mapping({(\'foo\', \'bar\'): int}, dict)\n Got: {\'bars\': 456, \'foo\': 123}\n</pre>\n\nIts worth having a read through the "spec" module; its small enough to digest easily and can be used quite independently of the qp web framework. To see it in practical use, and discover how it can be used to replace tons of boilerplate initialization and value checking code, see also the "Dulcinea" package, also at the link below. Its a library of objects and user interfaces; the object definitions are generally very easy to understand and made simpler because of "spec". After discovering spec I went through a code refactoring exercise and was very pleased with the outcome.\n\nhttp://www.mems-exchange.org/software/', 'title': u'And to force consistency in types in keys or values...'}, {'comment': u' ', 'title': u'Why not raise KeyError instead of TypeError?'}], 'desc': u'The KeyedDict object keeps a list of approved key values. If you try to assigned an unapproved key to a value, an exception is thrown.\n\nWhen you create the object, you give it a sequence (tuple, list, etc.) of key objects and then, when you set an item with a key, it will make sure that the key is in the "approved" list. If you try to set an item with a key that isn\'t in your approved list, you get an TypeError exception.'}, {'comments': [], 'desc': u'Extracts the specific element matched by "item in container". Useful for interning or caching applications needing canonical or singleton values.'}, {'comments': [{'comment': u'You can put globals into a third module. I often call this module "Globals.py".\n<br><br>\nHowever, argument-passing seems unwise. If module A imports module B, there is no guarantee that module B will use the "arguments" passed to it from A. For example:\n<pre>\n[Globals.py]\nname = \'Perl\'\n\n[B.py]\nimport Globals\nprint "Using \'name\'", Globals.name\n\n[A.py]\nimport Globals\nGlobals.name = \'Python\'\nimport B\n\n[main.py]\nimport Globals\nGlobals.name = \'Ruby\'\nimport B\nimport A\n\nResult of main.py: Using \'name\' Ruby.\n</pre>\nThe problem is that B could be imported before A, so A does not really pass anything at all to B.', 'title': u'Are you sure?'}, {'comment': u'...for posting questions, but I\'ll try answering.<br>\n<br>\nIf by "when calling a module" you mean as one is imported, there\'s\nno direct way to do it that I know of. You could do so indirectly by\nfirst writing information out to a file, and then reading it in the\nmodule\'s body (which only executes the first time it\'s imported).<br>\n<br>\nA slightly more direct approach for passing some parameters would be\nto use the fact that Python stores entries to all modules imported\nin the "sys.modules" dictionary however it doesn\'t force the values\nassociated with the entries to be module objects -- leaving\nyou free to install instances your own objects there which do what\nyou want.<br>\n<br>\nHere\'s an illustration of what I\'m saying:\n<pre>\n#### file module.py\n\nclass _mymodule(object):\n def __init__(self):\n self.a = \'a\'\n self.b = \'b\'\n self.variables = None\n\n def pass_variables(self, *variables):\n self.variables = variables\n\nimport sys\nsys.modules[__name__] = _mymodule()\n\n#### end file module.py\n\n#### file sample.y\n\nimport module\nmodule.pass_variables(42,\'string\')\n\nprint "module.a:", module.a\nprint "module.b:", module.b\nprint "module.variables:", module.variables\n\n#### end file sample.y\n</pre>\n[Output from sample.py]\n<pre>\n module.a: a\n module.b: b\n module.variables: (42, \'string\')\n</pre>\n', 'title': u"This isn't a newgroup..."}, {'comment': u'Never mind. My sample code doesn\'t accomplish anything that couldn\'t be done in a normal module. The general idea can be useful for such things as controlling access to a module attributes via the __setattr__ and __getattr__ object methods -- which regular module objects don\'t possess -- as shown in recipe 6.2 in the 2nd edition of the "Python Cookbook". However it doesn\'t help here.<br>\n', 'title': u'Ahem...'}, {'comment': u'Never mind my previous comment. The sample code doesn\'t actually accomplish anything that couldn\'t be done with a regular module. The technique described can be useful, as shown in recipe 6.2 titled "Define Constants" in the 2nd edition of the "Python Cookbook". However, unlike the case there, the class defined in my example doesn\'t take advantage of any special object attributes or methods not possessed by regular module objects.<br>\n', 'title': u'Ahem...'}], 'desc': u'how to pass parameters when calling a module.\nI have one module.py and i need to pass variables as arguments for the same module, so that I can use that variable values for processing( like in unix shell scripting).\nIs ther any way to handle the same ?\npls advise\n'}, {'comments': [{'comment': u'Faster (on Py2.5) and uses less memory<br>\n<br>\nfrom itertools import izip<br>\n<br>\ndef hamming1(str1, str2):<br>\n____"""hamming1(str1, str2): Hamming distance. Count the number of differences<br>\n____between equal length strings str1 and str2."""<br>\n____# Do not use Psyco<br>\n____assert len(str1) == len(str2)<br>\n____return sum(c1 != c2 for c1, c2 in izip(str1, str2))<br>', 'title': u' '}, {'comment': u"I've not timed it but this feels like it should be yet faster\n\n<pre>\nimport itertools\n\ndef hamming1(str1, str2):\n return sum(itertools.imap(str.__ne__, str1, str2))\n</pre>\n\nLike bearophile's it does not build an intermediate list. This version uses one generator instead of two and cheats a bit by using the underlying string comparison directly rather than the Python expression.", 'title': u'alternative using imap'}, {'comment': u'With Python 2.5 it seems my version is a bit faster (and it works with unicode too).', 'title': u' '}, {'comment': u'The slow part was, surprisingly, the str.__ne__ call. Try this instead\n\n<pre>\ndef hamming2(str1, str2):\n assert len(str1) == len(str2)\n #ne = str.__ne__ ## this is surprisingly slow\n ne = operator.ne\n return sum(imap(ne, str1, str2))\n</pre>\n\nI found it was about 5% faster than using != in bearophile\'s example.\nHere\'s my test code.\n\n<pre>\nimport time\nfrom itertools import izip, imap\nimport operator\n\ndef hamdist(str1, str2):\n """Count the # of differences between equal length strings str1 and str2"""\n \n diffs = 0\n for ch1, ch2 in zip(str1, str2):\n if ch1 != ch2:\n diffs += 1\n return diffs\n\n\ndef bearophile(str1, str2):\n """hamming1(str1, str2): Hamming distance. Count the number of differences\n between equal length strings str1 and str2."""\n # Do not use Psyco\n assert len(str1) == len(str2)\n return sum(c1 != c2 for c1, c2 in izip(str1, str2))\n\ndef dalke(str1, str2):\n assert len(str1) == len(str2)\n #ne = str.__ne__ ## this is surprisingly slow\n ne = operator.ne\n return sum(imap(ne, str1, str2))\n\ndef go(i):\n str1 = "A" * i\n str2 = str1[:i//2] + "B" + str1[i//2+1:]\n\n print i,\n for func in (hamdist, bearophile, dalke):\n t1 = time.time()\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n func(str1, str2)\n t2 = time.time()\n print t2-t1,\n print\n\n\ngo(10)\ngo(100)\ngo(1000)\ngo(10000)\ngo(100000)\n</pre>\n\nand the output under a pre-release version of Python 2.5 (order is original, bearophile, dalke, and I\'ve cleaned up the output)\n\n<pre>\n 10 0.00025 0.00028 0.00044\n 100 0.0013 0.0016 0.0013\n 1000 0.024 0.018 0.013\n 10000 0.22 0.145 0.132\n100000 3.4 1.47 1.34\n</pre>', 'title': u'str.__ne__ is the slow part'}, {'comment': u'Very good, testing is the best way to find the truth in science too :-)\nNote that this has the same speed because imap takes the address of the operator.ne object anyway:<br>\nreturn sum(imap(operator.ne, str1, str2))', 'title': u' '}, {'comment': u'In some cases (eg, pure biological sequences with no need for unicode support) it may be better to use a numeric array rather than a Python string as the computer representation. I found that\n\n<pre>\ndef numeric_hamming4(num1, num2):\n assert len(num1) == len(num2)\n return numarray.sum(num1 != num2)\n</pre>\n\nusing a numarray array was faster than my previous example using stock Python.\n\n<pre>\nfrom itertools import imap\nimport operator\nimport numarray\n\ndef hamming3(str1, str2):\n assert len(str1) == len(str2)\n return sum(imap(operator.ne, str1, str2))\n\ndef numeric_hamming4(num1, num2):\n assert len(num1) == len(num2)\n return numarray.sum(num1 != num2)\n\n# See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/392115\ndef makeSigDigs(num, digits, debug=False):\n ... ## not included here; only used to make pretty output\n return sig_string \n\ndef go(i):\n str1 = "A" * i\n str2 = str1[:i//2] + "B" + str1[i//2+1:]\n\n print i,\n\n t1 = time.time()\n assert hamming3(str1, str2) == 1\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n hamming3(str1, str2)\n t2 = time.time()\n print makeSigDigs(t2-t1, 2),\n\n num1 = numarray.array(str1)\n num2 = numarray.array(str2)\n t1 = time.time()\n assert numeric_hamming4(num1, num2) == 1\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n numeric_hamming4(num1, num2)\n t2 = time.time()\n print makeSigDigs(t2-t1, 2)\n\ngo(10)\ngo(100)\ngo(1000)\ngo(10000)\ngo(100000)\ngo(1000000)\n</pre>\n\nThe result was timing numbers like\n\n<pre>\n 10 0.00025 0.0024\n 100 0.0013 0.0011\n 1000 0.038 0.0016\n 10000 0.17 0.0024\n 100000 1.8 0.039\n1000000 21. 0.28\n</pre>\n\nThat is, with Numeric most of the nontrivial overhead is in function call setup. but with strings over about 100 characters it\'s much faster.', 'title': u'another solution using numarray'}], 'desc': u'Was doing some work with strings and threw this together. This will calculate the Hamming distance (or number of differences) between two strings of the same length.'}, {'comments': [{'comment': u'How could the script be modified so that it locates all files in the current (or specified) root directory only - not its sub-directories?\nThanks.', 'title': u'a simple question'}, {'comment': u'import os<br>\nos.listdir()', 'title': u'os.listdir()'}, {'comment': u"<pre>\nimport os, fnmatch\n\ndef locate(pattern, root=os.curdir):\n '''Locate all files matching supplied filename pattern in and below\n supplied root directory.'''\n #for path, dirs, files in os.walk(os.path.abspath(root)):\n files = os.listdir(os.path.abspath(root))\n for filename in fnmatch.filter(files, pattern):\n yield filename\n\n</pre>\n", 'title': u'naturally i mean listdir as a keyword only'}, {'comment': u'Thanks for the help!<br>\nA solution to locate files matching a pattern inside the root dir only (so not its sub-dirs) could be:<br>\n<pre>def locate2(pattern, root=os.curdir):\n\tfilename = fnmatch.filter(os.listdir(os.path.abspath(root)), pattern)\n\tfor fn in filename:\n\t\tyield os.path.join(root, fn)</pre>', 'title': u'a simple solution (?)'}, {'comment': u'Thanks again for the help!', 'title': u'writing at the same time...'}, {'comment': u"The glob module in Python's standard library will find files matching a pattern in a single directory. Check out the docs.", 'title': u'Locating files in a single directory'}], 'desc': u"os.walk is a very nice replacement for os.path.walk, which I never did feel comfortable with. There's one very common pattern of usage, though, which still benefits from a simple helper-function; locating all files matching a given file-name pattern within a directory tree."}, {'comments': [{'comment': u'How about:\n\n<pre>\ndef allindices(string, sub, listindex=[], offset=0):\n i = string.find(sub, offset)\n while i >= 0:\n listindex.append(i)\n i = string.find(sub, i + 1)\n return listindex\n</pre>\n\nI prefer non-recursive functions. Also, there is no need to copy the string, because find() and index() can search from an offset themselves.', 'title': u'non-recursive'}, {'comment': u'How about :\n\ndef allindices(string, sub, offset=0, listindex=None):\n #call as l = allindices(string, sub)\n if listindex is None:\n listindex = []\n\tif (string.find(sub) == -1):\n\t\treturn listindex\n\telse:\n\t\toffset = string.index(sub)+offset\n\t\tlistindex.append(offset)\n\t\tstring = string[(string.index(sub)+1):]\n\t\treturn allindices(string, sub, listindex, offset+1)', 'title': u'No Need to Pass in Empty List or Offset'}, {'comment': u'You should look at the "re" module in the standard library. To find all of the the starting positions of S in T:\n\n<pre>import re\nstarts = [match.start() for match in re.finditer(re.escape(S), T)]\n</pre>\n\nPlus it supports substitutions, and lots of other goodness.', 'title': u"Don't reinvent the wheel"}, {'comment': u'The regular expression methods, including finditer(), find non-overlapping matches. To find overlapping matches you need a loop.', 'title': u"finditer() won't find overlapping strings"}], 'desc': u'I needed a version of the string.index(sub) function which returns a list of indices of ALL occurances of a substring in the string.\n\nIs there a better/shorter/more efficient way to do this? Please share.'}, {'comments': [], 'desc': u'Python has no inherent provision for a restrictive API that blocks accesses to methods and variables outside an allowed set. Inexperienced Python programmers may fail to adhere to an agreed-upon API, directly accessing the private internals of a class. Adherence to defined APIs is a good thing. This function allows a class to specify its API, and raise AttributeErrors for disallowed accesses.'}, {'comments': [{'comment': u'If you\'re really serious about command-line parsing, you should be using argparse (http://argparse.python-hosting.com/) or optparse (from the standard library). Your code could be as simple as:\n<pre>\ndef main(foo, bars):\n # do something with foo and bars\n\nif __name__ == \'__main__\':\n parser = argparse.ArgumentParser()\n parser.add_argument(\'--foo\')\n parser.add_argument(\'bars\', nargs=2)\n args = parser.parse_args()\n main(**vars(args))\n</pre>\nNow if the command line args are "--foo f b1 b2" then main will get called like\n<pre>main(foo=\'f\', bars=[\'b1\', \'b2\'])</pre>\nUsing argparse or optparse means that giving your program better command-line documentation is as simple as adding a help= keyword argument to your add_argument() calls.', 'title': u'a job for argparse or optparse'}], 'desc': u'I found an article by Guido a while ago describing a generic main method for most Python programs (http://www.artima.com/weblogs/viewpost.jsp?thread=4829). Since then I found myself copying the same code into most of my programs. This recipe shows how to do the same thing with a decorator that makes the code much cleaner.'}, {'comments': [], 'desc': u'A routine much like os.walk() that iterates over the directories and files of a remote FTP storage.'}, {'comments': [], 'desc': u'This function recursively walks the items and values of two dict like objects. At each level when a key exists in both, and each value is a dict, then the destination dict is updated from the source dict usiing the builtin dict.update method. After the operation all keys and values from the source, at any level, will be referenced in the destination.\n'}, {'comments': [], 'desc': u'This module provides a function to summarize a XHTML string - that is, shorten it so it is has no more than a given amount of words while keeping XHTML (or, hopefully, any XML) tags intact.\n\nNo third-party packages are required (as of Python 2.4, but should work in earlier versions.)'}, {'comments': [], 'desc': u"PyXPCOM gives Python access to Mozilla's XPCOM, cross-platform component object model.\n\nThis recipe demonstrates using PyXPCOM to access Mozilla's IDN service."}, {'comments': [], 'desc': u'This module is a tiny winamp implementation using ctypes, which presents mp3/wav/mid/ogg... playback in python by calling winamp plugins. Treating it as a little example for advanced ctypes usage. You can download the full demo (in_mp3.dll, out_wave.dll, sample.mp3 included) from: http://www.joynb.net/blog/up/1166948100.rar -- by skywind3000@hotmail.com\n\n'}, {'comments': [{'comment': u"This recipe won't work with Jython 2.1 - super() was not introduced until 2.2.", 'title': u'No super() in Jython 2.1'}, {'comment': u'In Python 2.5, you can use a context manager, which is an elegant way of solving the problem, can be used in other contexts as well, and has syntactic support via the "with" statement:\n\n<pre>\nfrom __future__ import with_statement\n\nwith open("some_file") as f:\n for line in f:\n print line.rstrip()\n</pre>', 'title': u'Problem solved in Python 2.5'}, {'comment': u'The "with" statement does indeed solve the problem of\nautomatically closing a file explicitly but the real\naim of this recipe is to\nmake it safe to use the "concise elegant file-reading idioms"\nthat Python offers. The "with" statement is yet another idiom\nbut it is not as concise because it is a statement,\nnot an expression, and so can\'t be used in all the\nplaces that iopen() can be used (e.g. list\ncomprehensions and generator expressions).', 'title': u'"with" doesn\'t solve the problem in the same way'}], 'desc': u'This recipe is a drop in replacement for open() that automatically explicitly closes the file when its input is exhausted.'}, {'comments': [], 'desc': u'This is a simple way of expressing non-linear scales (such as decibels) in python. In stead of:\ngain = 10 ** (12/10.)\n\nUse\ngain = 12 * dB'}, {'comments': [], 'desc': u"For many languages it is possible to use the locale module to format numbers. But there are at least three languages for which the locale.localeconv()['thousands_sep'] is empty: brazilian portuguese - 'pt_br', portuguese - 'pt' and spanish - 'es'.\n\nThe first function, format_positive_integer() will return the passed integer number as a string with the thousands group separator added.\n\nThe second function, format_number() much more generic, will accept any number, integer or float, positive or negative, and return a string with the thousands group separator and the desired precision."}, {'comments': [], 'desc': u'This script downloads RIDGE radar images from the RIDGE site (http://www.srh.noaa.gov/ridge/) to a local disk, then renames them with a timestamp. In the case below, the One-Hour Precipitation total image and associated world file for the Little Rock, AR station (LZK) are downloaded.'}, {'comments': [{'comment': u"The code\n<pre>\nfound = False\nfor c in classes:\n\tif relation(iter(c).next(), o):\n\t\tc.add(o)\n\t\tpartitions[o] = c\n\t\tfound = True\n\t\tbreak\nif not found:\n\tclasses.append(set([o]))\n\tpartitions[o] = classes[-1]\n</pre>\nis normally written using the for-loop's else clause:\n<pre>\nfor c in classes:\n\tif relation(iter(c).next(), o):\n\t\tc.add(o)\n\t\tpartitions[o] = c\n\t\tbreak\nelse:\n\tclasses.append(set([o]))\n\tpartitions[o] = classes[-1]\n</pre>", 'title': u"for-loop's else clause"}, {'comment': u"I had never seen that construct before, I'm still a bit new to python.", 'title': u'Thanks'}, {'comment': u'Compare to:\n<pre>\ndef partition(domain, relation):\n known = set()\n classes = {}\n for x in domain:\n for representative, values in classes.items():\n if relation(x, representative):\n values.add(x)\n break\n else:\n classes[x] = set([x])\n return classes.values()\n\nprint partition(xrange(-3, 5), lambda x,y: (x-y) % 4 == 0)\n</pre>', 'title': u'Seems like a lot of code to do very little'}, {'comment': u"If you look at the code you'll see most of the extra lines are extra functionality or comments.", 'title': u'More code to do more?'}], 'desc': u'Partitions a set of objects into classes according to some supplied equivalence relation. Useful when you know when objects are equivalent but cannot categorise them into groups easily.'}, {'comments': [], 'desc': u"Provides a context manager that allows the user to specify a method on the passed-in object to be called when the 'with' statement is exited. This is a generalization of contextlib.closing."}, {'comments': [], 'desc': u'A memory efficient implementation of a mapping type for mappings with fixed keys. '}, {'comments': [{'comment': u'Here is a similar example:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425210', 'title': u'Stoppable HTTP Server'}, {'comment': u"I did search, but your recipe didn't turn up (or it was somewhere way down on the list).<br><br>So all credits go to Dirk. He came up with it first.", 'title': u' '}, {'comment': u'Hi Rogier, thanks for the credits ;-) Your code is more compact than mine and I think it is a good variation for a solution over the same problem we both had with blocking servers. ', 'title': u'Credits'}], 'desc': u'BaseHTTPServer blocks while waiting for a connection. This means that a script will not respond to anything until it receives a network connection, which may never come. By adding a timeout to the listening socket, the script will regain control every so often.'}, {'comments': [], 'desc': u'This is a variation of itertools.groupby. The itertools.groupby iterator assumes that the input is not sorted but will fit in memory. This iterator has the same API, but assumes the opposite.'}, {'comments': [{'comment': u'IMO, instead of:\n<pre> >> Person = NamedTuple("Person x y") </pre>\nthis one seems more pythonic:\n<pre> >> Person = NamedTuple(x=0, y=0) </pre>\nBut of course, then the NamedTuple function should name the generated class automatically.<br><br>\n\nAlso, if we really require the generated class to have the name we want, the function can have a kwarg to set the class\'s name.\n<pre> >> Person = NamedTuple(x=0, y=0, name="Person") </pre>\n', 'title': u' '}, {'comment': u'I suggest the generated __new__ should take keyword arguments or an *iterable* in its only supported positional argument. This matches behaviour with tuple(), list() and other containers.', 'title': u'Constructor should take an iterable'}, {'comment': u'How about:<br>\n\n def NamedTuple(typename, s):', 'title': u'Syntax proposal'}, {'comment': u'>>> from cPickle import dumps<br>\n>>> dumps(p)<br>\nadded to the doctest fails.', 'title': u'Pickling error'}, {'comment': u'I like this, but :)<br>\n\n1) allow the fields to be defined directly rather than by split\n\nie\n\n<pre>\ndef NamedTuple(typename, field_names):\n\n.......\n if isinstance(field_names,str):\n field_names = field_names.split()\n\n.....\n</pre>\n\n2) allow a constructor __from_iterable__ and a property __field_names__\n\nie<br>\n<pre>\n def __from_iterable__(cls,arg):\n return cls.__new__(cls,*arg)\n\n......\n m.update(\n ........\n __field_names__ = tuple(field_names),\n __from_iterable__=classmethod(__from_iterable__),\n )\n\n</pre>', 'title': u'some minor mods'}, {'comment': u"I really wanted to be able to take a tuple or list like Giovanni's suggestion, so I built upon Robin's suggestions and came up with this: (I'm not sure if it breaks any semantics or protocols you were trying to preserve)\n<pre>\ndef NamedTuple(typename, field_names):\n if isinstance(field_names,str):\n field_names = field_names.split()\n nargs = len(field_names)\n\n def __new__(cls, *args, **kwds):\n if (len(args) == 1) and (getattr(args[0], '__iter__', False)) and (isinstance(args[0][0], str)):\n args = tuple(name for name in args[0])\n if kwds:\n try:\n args += tuple(kwds[name] for name in field_names[len(args):])\n except KeyError, name:\n raise TypeError('%s missing required argument: %s' % (typename, name))\n if len(args) != nargs:\n raise TypeError('%s takes exactly %d arguments (%d given)' % (typename, nargs, len(args)))\n return tuple.__new__(cls, args)\n\n repr_template = '%s(%s)' % (typename, ', '.join('%s=%%r' % name for name in field_names))\n\n m = dict(vars(tuple)) # pre-lookup superclass methods (for faster lookup)\n m.update(__doc__= '%s(%s)' % (typename, ', '.join(field_names)),\n __slots__ = (), # no per-instance dict (so instances are same size as tuples)\n __new__ = __new__,\n __repr__ = lambda self, _format=repr_template.__mod__: _format(self),\n __module__ = sys._getframe(1).f_globals['__name__'],\n __field_names__ = tuple(field_names),\n __from_iterable__=classmethod(__from_iterable__),\n )\n m.update((name, property(itemgetter(index))) for index, name in enumerate(field_names))\n\n return type(typename, (tuple,), m)\n</pre>", 'title': u'Possible Mod?'}, {'comment': u"Should have been just:\n<pre>if (len(args) == 1) and (getattr(args[0], '__iter__', False)):</pre>", 'title': u"D'oh!"}, {'comment': u"template +='\\n'.join('\\t%s = property(itemgetter(%d))' % (name, i) for i, name in enumerate(field_names))\n<br><br>\nThis may be worth considering if many Nuples and/or many fields are needed.\n<br>\nThe readability may suffer for it though ...", 'title': u'Little optimisation'}], 'desc': u'Fast, lightweight attribute-style access to tuples.'}, {'comments': [], 'desc': u'twvalidator is a simple markup validator gateway you can embed in your\nTwisted Web application for validating all your pages.'}, {'comments': [], 'desc': u"Often when a program adds some XML markup to a plain-text document, it doesn't retain the original whitespace formatting. This recipe determines the character offsets the XML elements should have had in the original document."}, {'comments': [], 'desc': u'This script helps me manage my digital photos by filing them in a directory\nbased on the EXIF date and applying keywords and by-line information to the IPTC\nmetadata.'}, {'comments': [], 'desc': u"This recipe yields each subset of size k from a super set of size n. I thought I had seen a recipe that did this before, but when I needed it I couldn't find it. There are two methods. The first operates on sets of integers of the form range(n). The seconds operates on arbitrary sets or lists."}, {'comments': [], 'desc': u"I am writing a log parse script that needs to run ever 10 minutes or so to update some stats in a database. This subclass if the 'file' object looks for a '.filename.pkl' file which contains the seek offset of the previous end of the file, then sets the seek offset to that number before returning the file. On closing the file or StopIteration, it writes the new max offset to this pickle file."}, {'comments': [], 'desc': u'This toy module shows a way to define symbols inside functions, using a decorator. Idea derived from recipe 303057 by Shai Berger.'}, {'comments': [{'comment': u'I built a very complete wrapper around Twisted deferreds that uses decorators in such a fashion to define handlers and such in the same structure as synchronous code, but mapping it to asynchronous handlers through Twisted deferreds.\n\nhttp://cheeseshop.python.org/pypi/DeferArgs', 'title': u"I've done something similar"}], 'desc': u'The logic of the code is a rewrite of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408937, however partial is used here and default Exception class is added when no input is given. I have also made some modifications in the way handlers and exception classes are passed to the decorator. (it was earlier posted in comments for the same receipe)'}, {'comments': [], 'desc': u'xmlrpc server client which do the following:\n* client sends a request with basic authentication \n* server on successful authentication sends response back and also sends cookies with authentication id\n* these cookies are saved by client and then used for authentication on any subsequent requests '}, {'comments': [], 'desc': u'This recipe is yet another combination generator, with an extra twist: the generated combinations can be yielded in blocks of a given size. This comes useful (or necessary) when processing arbitrarily long or infinite iterables in bounded-size blocks.'}, {'comments': [{'comment': u'Why not store the queue as consecutively numbered entries in a shelve, deleting low numbered entries as you extract them from the queue. Easy-peasy.', 'title': u'shelve approach'}, {'comment': u'Funny you should mention shelve, as one of the main motivations for making this class was trouble with an approach which used shelve :)\n<br><br>\nDuring periods of heavy load, a shutdown of the application which used the shelve approach caused the on-disk database to be corrupted, with the result of irrecoverable queue data. This was a couple of years ago, so the problems with bsddb (and gdbm for that matter) may have been fixed later.\n<br><br>\nStill, the PersistentQueue class does not depend on any 3rdparty libraries for storage, which I believe to be an advantage. Also, if there is a crash where the enqueue and dequeue caches are not properly synched to disk, you may still be able to recover other queue segments and not lose all data.', 'title': u'shelve'}, {'comment': u'It\'s possible to lose data under certain circumstances if your cache size is larger than the number of items you add in a given session, as demonstrated in the code at the end of this post. Or am I using PersistentQueue incorrectly?\n\nHere is the output from two runs of the test program:\n<pre>\nmaterial:~/dev art$ python queue-tester.py \nAt startup: Queue length: 0\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 5\nAt startup: Queue length: 5\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 10\nAt startup: Queue length: 5\n\n *** EXPECTED 10 but got 5\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 10\nmaterial:~/dev art$ python queue-tester.py \nAt startup: Queue length: 0\n\n *** EXPECTED 5 but got 0\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 5\nAt startup: Queue length: 5\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 10\nAt startup: Queue length: 5\n\n *** EXPECTED 10 but got 5\nEnqueueing 5 items, cache size = 15\nAt close: queue length: 10\nmaterial:~/dev art$ \n</pre>\n\n<pre>\nfrom PersistentQueue import PersistentQueue\n\ndef testLargeCacheImpl(expected_size_at_start, name, ELEMENTS, CACHE_SIZE):\n p = PersistentQueue(name, CACHE_SIZE)\n print \'At startup: Queue length:\', len(p)\n if len(p) != expected_size_at_start:\n print \'\\n\\t\\t\\t*** EXPECTED %d but got %d\' % (expected_size_at_start, len(p))\n print \'Enqueueing %d items, cache size = %d\' % (ELEMENTS,\n p.cache_size)\n for a in range(ELEMENTS):\n p.put(str(a))\n p.sync()\n size_at_close = len(p)\n print \'At close: queue length:\', size_at_close\n p.close()\n return size_at_close\n\ndef testLargeCache():\n name = \'cache_size_issue\'\n ELEMENTS = 5\n CACHE_SIZE = ELEMENTS * 3\n p = PersistentQueue(name, CACHE_SIZE)\n expected = len(p)\n p.sync()\n p.close()\n expected = testLargeCacheImpl(expected, name, ELEMENTS, CACHE_SIZE)\n expected = testLargeCacheImpl(expected, name, ELEMENTS, CACHE_SIZE)\n testLargeCacheImpl(expected, name, ELEMENTS, CACHE_SIZE)\n \nif __name__ == "__main__":\n testLargeCache()\n</pre>\n', 'title': u'Problem if cache size is larger than number of items added in a session'}, {'comment': u"There was a small bug in the index initialization which caused the problem revealed by your test program. I've updated the code with a fix .\n\nThanks for reporting!", 'title': u'New version'}], 'desc': u'A class for persistent queues.'}, {'comments': [{'comment': u'This seems like a rather complicated way of saying::\n<pre>\n>>> def multi_for(iterables):\n... \tif not iterables:\n... \t yield ()\n... \telse:\n... \t for item in iterables[0]:\n... \t for rest_tuple in multi_for(iterables[1:]):\n... \t yield (item,) + rest_tuple\n... \n>>> for i in multi_for(map(xrange, [2, 2, 1, 2])):\n... print i\n... \n(0, 0, 0, 0)\n(0, 0, 0, 1)\n(0, 1, 0, 0)\n(0, 1, 0, 1)\n(1, 0, 0, 0)\n(1, 0, 0, 1)\n(1, 1, 0, 0)\n(1, 1, 0, 1)\n</pre>\n\nNote that this version can handle any kind of iterables, not just ranges. If you want to iterate over ranges, simply pass in range or xrange objects (as shown above). If repeatedly slicing the iterables list and creating the intermediate tuples freaks you out, you could write this instead like:\n<pre>\n>>> def multi_for(iterables):\n... end = len(iterables)\n... def helper(index):\n... if index >= end:\n... yield []\n... else:\n... for item in iterables[index]:\n... for rest_list in helper(index + 1):\n... rest_list.append(item)\n... yield rest_list\n... for reversed_items in helper(0):\n... yield tuple(reversed(reversed_items))\n... \n>>> for i in multi_for(map(xrange, [2, 2, 1, 2])):\n... print i\n... \n(0, 0, 0, 0)\n(0, 0, 0, 1)\n(0, 1, 0, 0)\n(0, 1, 0, 1)\n(1, 0, 0, 0)\n(1, 0, 0, 1)\n(1, 1, 0, 0)\n(1, 1, 0, 1)\n</pre>', 'title': u' '}, {'comment': u"Nice recipe, Colin.\n\nFWIW, here's an optimized version:\n<pre>\ndef mrange(minvec, maxvec=None): \n if maxvec is None:\n maxvec = minvec\n minvec = [0] * len(maxvec)\n vec = list(minvec)\n unitpos = len(vec) - 1\n maxunit = maxvec[unitpos]\n _tuple = tuple\n while 1:\n if vec[unitpos] == maxunit:\n i = unitpos\n while vec[i] == maxvec[i]:\n vec[i] = minvec[i]\n i -= 1\n if i == -1:\n return \n vec[i] += 1\n yield _tuple(vec)\n vec[unitpos] += 1\n</pre>", 'title': u'Tweaked for Speed'}], 'desc': u"Python has a number of nice methods to handle 'for' loops. However, the situation often arises where you have a large number of nested loops. Using this solution reduces the number of loops to one."}, {'comments': [], 'desc': u'Saw recipe 502194 and wondered if I could do similar.\nI initially came up with function comb that enumerates all combinations. I wanted a generator however and so abandoned that approach for comb2 which is a little more complex.'}, {'comments': [], 'desc': u'This recipe introduces a novel way of compressing\ntext and is meant primarily as an exercise. The\nprocedures work best on standard 7-BIT ASCII and\nworst on binary encoded data. Please note that\nfunction "encode" returns a string and a key\nthat must be passed to function "decode" in\norder recover the original data.'}, {'comments': [], 'desc': u'This recipe introduces a novel way of compressing\ntext and is meant primarily as an exercise. The\nprocedures work best on standard 7-BIT ASCII and\nworst on binary encoded data. Please note that\nfunction "encode" returns a string and a key\nthat must be passed to function "decode" in\norder to recover the original data.'}, {'comments': [], 'desc': u'Just another hex dumper written in one of our favorite languages ...'}, {'comments': [], 'desc': u'Proxies can be useful at times but may not be\nsimple to create and run. This recipe provides\na single class that can build proxy objects\ncapable of being both started and stopped.'}, {'comments': [], 'desc': u'This is just a simple example usage example of the proxy module presented here:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502204'}, {'comments': [{'comment': u"This could be useful, but I think the name could be better. Deferred is a very common name, used from the popular Twisted project, so you immediately put an extra burden for anyone wanting to use this with a Twisted project. Maybe you could call it RuntimeDefault or something like that?\n\nAlso, what about callables instead of strings? I'm always opposed to strings of code.", 'title': u'Good but no cigar'}, {'comment': u"Indeed, selecting a meaningful yet short name is the toughest part. Deferred is a good compromise but you're right, it's already taken. As for callables vs strings, I also avoid the latter in general, but here they offer two advantages:<br>\n1. Brevity: Ideally re-evalutable defaults shouldn't be harder to spell than once-only defaults. Having to write something like f(x=RutimeDefault(lambda: [])) would render it practically unusable. If they are common enough, even a special syntax could be justified.<br>\n2. Makes accessible the previously defined arguments in the expression. AFAIK trying to modify directly the func_locals of a function has no effect (let alone callables that are not functions).", 'title': u' '}], 'desc': u'This recipe extends the standard python semantics with respect to default function arguments by allowing "deferred" expressions, expressions that are evaluated on every call instead of just once at function definition time.'}, {'comments': [], 'desc': u"useful for decorating functions/methods that you'd like to disable from the main loop or commandline via optparse. an example would be running certain verifications or checks that you deem unnecessary in certain scenarios"}, {'comments': [{'comment': u'The octal version should be int(x, 8) rather than int(x, 7). Octal "0123" is 83, not 66, AFAICT.', 'title': u'Radix error?'}], 'desc': u'This module provides an easy way to parse simple formatted strings. \nIt works similar to the version C programmers are used to.'}, {'comments': [{'comment': u'>>> timeit.Timer(\'a()\', \'a = lambda:"foobarbaz"\').timeit()\n0.75941300392150879\n>>> timeit.Timer(\'a()\', \'import itertools;a = itertools.repeat("foobarbaz").next\').timeit()\n0.50646805763244629\n>>> timeit.Timer(\'a()\', \'import itertools;a = (lambda s:itertools.repeat(s).next)("foobarbaz")\').timeit()\n0.40992307662963867\n\nSurprisingly, these are all consistent results, even the last two! I really can\'t explain why, but creating a function you can pass something to to do the work, rather than using itertools.repeat().next yourself is actually faster on the actual calls!', 'title': u'just wrap it up'}, {'comment': u'The timeit module can be tricky to use. Try specifying exactly how many repetitions you want and run the test multiple times in the a single script. Try to get your system as quiet as possible (switch-off other processes and net activity). Then, you with have a fighting chance of getting results that make sense:\n\n<pre>\nfrom timeit import Timer\n\nsetup = \'\'\'\nimport itertools\na = lambda: \'foobarbaz\'\nb = itertools.repeat(\'foobarbaz\').next\nc = (lambda s:itertools.repeat(s).next)("foobarbaz")\n\'\'\'\n\nfor i in (1,2,3,4,5):\n for stmt in \'a() b() c()\'.split():\n print stmt, min(Timer(stmt, setup).repeat(7, 1000000))\n print\n</pre>', 'title': u'Meaningful timing results'}], 'desc': u"Fast factory funtion for Py2.5's defaultdict making simple use of itertools. Equivalent to lambda:some_constant. "}, {'comments': [{'comment': u"That's fun. I added MyBoid that bounces around and keeps the others moving.\n\nThanks,\nJustin", 'title': u'Cool'}], 'desc': u'This recipe demonstrates a 2D boids simulation.\nThe code is configurable based on some constants defined near the top.\nThe idea for the code shown here came from the following URL:\nhttp://www.vergenet.net/~conrad/boids/pseudocode.html'}, {'comments': [], 'desc': u"This class wraps any object, and allows accessing and modifying that object's properties using the dict interface. This wrapper is meant to provide a clean interface to getattr/setattr/hasattr/delattr."}, {'comments': [], 'desc': u'This recipes describe how to simplify the process of extracting data from Microsoft chm file format. \nIt use pychm library http://gnochm.sourceforge.net/pychm.html. '}, {'comments': [], 'desc': u'Creating java class description files (like C/C++ headers) in html format, link together with data types.\n\n'}, {'comments': [{'comment': u'You don\'t need any of the dest= arguments or the action=\'store\' arguments -- you\'re just repeating the optparse defaults. Also, note that argparse (http://argparse.python-hosting.com/) understands required options (so you don\'t need to handle them yourself) and has a smarter \'store_true\' action that correctly defaults to False.\n\n<pre>\nparser = argparse.ArgumentParser()\nparser.add_argument(\'-H\', \'--host\', required=True,\n help=\'remote host or ip address\')\nparser.add_argument(\'-p\', \'--port\', default=69,\n help=\'remote port to use (default: %(default)s)\')\nparser.add_argument(\'-f\', \'--filename\', required=True,\n help=\'filename to fetch\')\nparser.add_argument(\'-b\', \'--blocksize\', default=512,\n help=\'udp packet size to use (default: %(default)s)\')\nparser.add_argument(\'-o\', \'--output\',\n help=\'output file (default: same as requested filename)\')\nparser.add_option(\'-d\', \'--debug\', action=\'store_true\',\n help=\'upgrade logging from info to debug\')\nparser.add_option(\'-q\', \'--quiet\', action=\'store_true\',\n help="downgrade logging from info to warning")\nargs = parser.parse_args()\n\nif args.debug and args.quiet:\n ...\n</pre>', 'title': u'optparse defaults'}], 'desc': u'The tftpy library provides simple classes for TFTP clients and servers alike. This is as simple as installing this library, instantiating a TftpClient object, and invoking its download() method. '}, {'comments': [], 'desc': u'This recipe provides a simple and efficient way of creating records (a.k.a. structs) where each argument to the constructor becomes an attribute of the object.'}, {'comments': [], 'desc': u"This recipe demonstrates a fictional time system\nfrom the world of Aens. It is mainly for showing\nhow, in a game, a new system of time could alter\na player's perspective of location in the game."}, {'comments': [], 'desc': u'This recipe demonstrates the use of the "Aens\nTime" module. It is imported here as "aens_time"\nand shown in a very simple role of updating a\nstring after one "mille" passes. The results for\nthis demonstration is a quickly updating clock.'}, {'comments': [], 'desc': u'The code presented below is an update to the original\nrecipe presented on this web site. Several more\nconfiguration options are presented at the top of\nthe file, and Rule 3 from the Boids algorithm is\ncorrectly used in the update_velocity method.'}, {'comments': [], 'desc': u'The physics system used in this simulation is\nboth incomplete and incorrect. This recipe evolved\nfrom the Boids Simulation and was an early attempt\nto simulate bouncing balls in an area contained\nwith a force field on the sides and a floor on the\nbottom. The spheres will respond to movement of\nthe window and will bounce if accelerated upward\nquickly. This is primarily a recipe that I later\nbuilt off of to create better software later on.'}, {'comments': [{'comment': u'The recipe here might be of interest: http://svn.colorstudy.com/home/ianb/recipes/propertyclass.py\n\nIt implements a property class that can be subclassed to create concrete properties.', 'title': u'with classes...'}], 'desc': u"This property shortcut doesn't restrict the property's attributes to get, set, del and doc.\nBesides these functions can have any name, not limited to fget, fset ...\nNote that the default doc is not the getter's one."}, {'comments': [], 'desc': u"Sometimes it's desirable to run a function not often than some time interval. The timeguard decorator below lets do exactly that. See the doctest for details."}, {'comments': [], 'desc': u'This program is an mutated version of Bouncing Balls\nDemonstration. Bombs fall to the floor, but if they\ntouch each other, they explode with velocity and are\nquickly repelled away from each other. All bombs are\nidentified with numbers and can be clicked to change\ncolors. If you wish to follow individual bombs, you\nmay wish to note their numbers. Otherwise, you may\nalso change their colors in an attempt to keep track\nof them.'}, {'comments': [], 'desc': u'Module for physics simulation.\n\nThis module provides two classes that allow the\napproximation of physics behind bouncing balls.'}, {'comments': [], 'desc': u'This recipe is designed to show sample usage of\nthe physics module. Once the program is running,\nthe window can be dragged around the screen; and\nthe balls will react accordingly. If an error is\ndisplayed on the screen, the window moved to show\nthe rest of the error message.'}, {'comments': [], 'desc': u'This recipe is designed to show sample usage of\nthe physics module. Once the program is running,\nthe window can be dragged around the screen; and\nthe balls will react accordingly. If an error is\ndisplayed on the screen, the window moved to show\nthe rest of the error message.'}, {'comments': [], 'desc': u'This recipe is designed to show sample usage of\nthe physics module. Once the program is running,\nthe window can be dragged around the screen; and\nthe balls will react accordingly. If an error is\ndisplayed on the screen, the window moved to show\nthe rest of the error message.'}, {'comments': [], 'desc': u'Interpolate variables and expressions in strings the ruby way. This is similar in functionality to recipe 496885, though implemented differently and with a different interpolation syntax.'}, {'comments': [], 'desc': u'This reciepe shows how to call a web service located on a remote machine to do stuff (convert centigrads to faranheit and farahneits to centigrads and retrieve the results as a python object.'}, {'comments': [], 'desc': u'Parseline breaks a line (actually a string) into python objects like strings, floats, ints, etc., based upon a short format string.'}, {'comments': [{'comment': u'So I made some changes:<br>\n<br>\ndef pkgconfig(*packages, **kw):<br>\n flag_map = {\'-I\': \'include_dirs\', \'-L\': \'library_dirs\', \'-l\': \'libraries\'}<br>\n for token in commands.getoutput("pkg-config --libs --cflags %s" % \' \'.join(packages)).split():<br>\n if flag_map.has_key(token[:2]):<br>\n kw.setdefault(flag_map.get(token[:2]), []).append(token[2:])<br>\n else: # throw others to extra_link_args<br>\n kw.setdefault(\'extra_link_args\', []).append(token)<br>\n\n for k, v in kw.iteritems(): # remove duplicated<br>\n kw[k] = list(set(v))<br>\n return kw<br>', 'title': u'Problems with additional arguments'}], 'desc': u'This is a short and sweet recipe for using pkg-config with your distutils extension modules.'}, {'comments': [{'comment': u"Paul Rubin posted a better version in the python mailing list:\n\n<pre>def unique(seq, keepstr=True):\n t = type(seq)\n if t==str:\n t = (list, ''.join)[bool(keepstr)]\n seen = []\n return t(c for c in seq if not (c in seen or seen.append(c)))</pre>\n\nNice!", 'title': u'Nicer version from Paul Rubin'}, {'comment': u"<pre>def unique(seq, keepstr=True):\n t = type(seq)\n if t in (str, unicode):\n t = (list, ''.join)[bool(keepstr)]\n seen = []\n return t(c for c in seq if not (c in seen or seen.append(c)))</pre>", 'title': u'Fixed to work with unicode string objects'}, {'comment': u'What about replacing the last two lines with:\n\n\nseen = set()\nreturn t(c for c in seq if not (c in seen or \nseen.add(c)))\n\n? This shuld be faster.\n', 'title': u'Using a set instead of a list ?'}, {'comment': u'Problem is that "list objects are unhashable". Paul Rubin posted a case-optimized version (using sets where possible) to the python group:\n\nhttp://tinyurl.com/24zchj', 'title': u'Using set() fails first assert'}, {'comment': u'Thank You for the link, I like that solution :-)\n', 'title': u' '}], 'desc': u"Tim Peter's recipe (52560) and bearophile's version (438599) seem a bit too complex. There are speed an sorting issues with each. Not to mention that neither keeps the data type of the input object. Here is my take on a python unique() function for enumerables (list, tuple, str)."}, {'comments': [], 'desc': u'Python has really nice logging framework, it has too a zipfile library in the default installation that makes you able to write compressed files.\n\nSeveral of the logging handlers "rotate" files, by size, date, etc. Here is an example of handler class for the logging framework that, when the file is rotated, it will make a .zip of the old file.'}, {'comments': [], 'desc': u'The recipe is a direct descendant of the program presented here:\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502251\nThis program was created at the suggestion of "Mark" (a friend\nof mine), and so the game was named in his honor. A high score\ntable is supported and is automatically saved to and loaded from\na file if possible. The object of the game is to click on each\nball until it is purple. The score is based on how many seconds\nare left on the clock in the bottom, left corner of the screen.\nHave fun, and try to beat the game in sixty seconds or less; it\nis possible!'}, {'comments': [], 'desc': u'_winreg module wrapper to provide easy access, walking and creation/modification of keys and values.\nTested with Win98 and XP (admin)'}, {'comments': [{'comment': u"I don't think it's a problem with closures in this case, but rather with how variables are defined in loops. In the first example a closure is created when asked, so value of i is used at this time. In the second one, however i is not created in the function scope, but rather referenced, so at the end of the loop value is 4, which would explain your result. In the third example again, new i is created for the scope of the closure and things are back to normal, here's an example:\n\n<pre>\ndef test2():\n all = []\n for i in range(5):\n def call(): return id(i)\n all.append(call)\n print id(i)\n return all\n\nprint test2.__name__, ':', [ f() for f in test2() ]\n</pre>\n\nid of i is the same everywhere. It's still the same in your example one, but what makes it work is the fact that it's a generator.", 'title': u' '}, {'comment': u'Changing "return i" to return "return id(i)" produced this output (of course the id\'s are not reproducible):\n\n<pre>\ntest1 : [3104596, 3104584, 3104572, 3104560, 3104548]\ntest2 : [3104548, 3104548, 3104548, 3104548, 3104548]\ntest3 : [3104596, 3104584, 3104572, 3104560, 3104548]\n</pre>\n\nAt the same time, printing id(i) gives me different id\'s in each loop cycle, in all cases.\n\nSo it is NOT the same for cases 1 and 3, the id is constant only in case 2.\n\n<br><br>\nI don\'t think that variables are defined in loops differently then outside of loops. For example,\n\n<pre>\ndef test2a():\n all = []\n i = 0\n def call(): return id(i)\n all.append(call)\n i += 1\n def call(): return id(i)\n all.append(call)\n # ... etc.\n return all\n</pre>\n\nbehaves equally strange.\n\n<br><br>\nAnyway, the fact that the id does not change in case 2 supports my theory that python tries to bind closures to surrounding scope at the latest possible moment.\n\n<br><br>\nIn the illustrated case (2), I think it\'s TOO LATE. I don\'t think that wrapping up some code in a function, like I did in case 3, should make so much difference. It is absolutely counter-intuitive (if not worse).', 'title': u'Really?'}, {'comment': u"The scoping rules in python are somewhat weird, I still think this is the cause of the problem, not how closures are made.\n\n<pre>\nfor i in range(10):\n print i\n# i is still defined over here\nprint i\n</pre>\n\nsame happens with list comprehensions. So with that in mind, it's more or less clear what happens in your examples, one and two don't define a scope where i is a separate instance. ...though I could be mistaken...", 'title': u' '}, {'comment': u"When i is evaluated in test2(), it's already at the end of the loop, and i=4. However, this one works as expected, as it capture i on each iteration:\n\n<pre>def test2():\n all = []\n for i in range(5):\n def call(j): return j\n all.append((call, i))\n return all\nprint test2.__name__, ':', [ f(a) for f,a in test2() ]</pre>", 'title': u'I think Petr is correct'}, {'comment': u"I'm pretty much out of horizontal space here... continuing as extra comment below...", 'title': u'Hmm...'}, {'comment': u'Jordan, please, look more carefully! When i is evaluated, it is NOT IN test2 AT ALL. It is OUTSIDE of test2, where i is not available at all! test2 simply returns the closures, but they are evaluated somewhere else. That\'s the benefit of closures.\n<br><br>\nBesides, in your code, \'call\' is not a closure at all. You are not adding closures to the sequence, but tuples of simple function adresses and argumens, and INTERPRET the tuples afterwards.\n<br><br>\nThe specific of a closure is that is is bound to values of it\'s surrounding environment - it is "closed" on those values (EVEN AFTER that environment gets out of scope, as is the case with local variables when the function exits). \n<br><br>\nThe question is: WHEN is it closed?\n<br><br>\nMy "anti-recipe" expresses the assumtion that closures in python are "closed" at the moment when the surrounding scope is left, not at the moment the closure is encontered (i.e. defined). It also expresses my (strong) belief that closures schould be closed when defined instead.\n<br><br>\nAfter all that\'s said, my assumption still holds. Whether or not my belief is correct... well, that\'s best left to history to judge ;) ', 'title': u'Hmm... (continued from response to "I think Petr is correct")'}, {'comment': u'is it really clear? A loop does not establish a separate scope in python, so it is only natural that i is visible after the loop. Same is true about list comprehensions. The interpreter encounters an assignement to i - it defines the variable. It sees the end of the loop - it just ends the loop. It does not imlicitly insert a "del i" at the end of the loop to undefine it. And fortunately so.\n<br><br>\nAll in all, I think scoping rules have definitely *not* something to do with the phenomenon I\'ve described in the "anti-recipe".', 'title': u'Petr,'}, {'comment': u'I realize that my example wasn\'t a "closure" (more of a functor pattern, though lispers might consider it a type of closure passing). I was only trying to illustrate Petr\'s comment that in that particular closure pattern in test2(), the context capture occurs after the loop, and so i=4. I probably just muddied the water rather than clarifying. Sorry about that.', 'title': u"You're right..."}, {'comment': u'Closures are over _local function variables_, never ever values. Even test1() "fails" if you wait for the function to end before calling the closures:\n\n def test1():\n for i in range(5):\n yield lambda: i\n\nIn [14]: [f() for f in test1()]\nOut[14]: [0, 1, 2, 3, 4]\nIn [15]: map(apply, [f for f in test1()])\nOut[15]: [4, 4, 4, 4, 4]\n\nThe functions all reference the same variable, the variable is just bound to different objects at when you are calling the closures.\n\nThe best way to create such functions is to use the default argument trick:\n\ndef test4():\n for i in range(5):\n yield lambda i=i: i\n\nIn [19]: [f() for f in test4()]\nOut[19]: [0, 1, 2, 3, 4]\nIn [20]: map(apply, [f for f in test4()])\nOut[20]: [0, 1, 2, 3, 4]', 'title': u'Misunderstanding'}], 'desc': u"Closures are powerful. Closures are beautiful. But: Closures are TRICKY! \n\nThis is an anti-recipe, a caveat about some obscure pitfalls with closures - or the way they are implemented in python.\n\nAnd now for the caveats: Two no-no's...\n\n1. Don't create more then one instance of the same closure per normal function!\n\n2. Don't create more then one instance of the same closure per generation cycle in a generator function!\n\nHere is why...\n"}, {'comments': [], 'desc': u"This recipe helps to manage a temporary file used in a test. It returns an open file so as to write the test data, and upon exiting the 'with' statement, makes sure that the created file is deleted."}, {'comments': [], 'desc': u'During a recent application server design, I came across the need for a thread locking class which supports read and write locks (in the filesystem lock kind of way).'}, {'comments': [], 'desc': u'timehook is a simple module that allows you to modify the time clock\nwithout having to modify the system clock.\n'}, {'comments': [], 'desc': u'A crude persistent dict class. Intended for saving GUI user preferences that can be hand edited, cf. shelve module. \nProbably not suitable for large amounts of data. '}, {'comments': [], 'desc': u"A small yet flexible threadpool implementation. I wasn't quite satisfied with other existing solutions, so I rolled one on my own, building on top of the threadpool module by Christopher Arndt. \n\nSee the example in the end and the docstrings (in Epydoc format) for the details."}, {'comments': [{'comment': u'When the client which is connected to your HexdumpServerProtocol disconnects, you probably want to disconnect your HexdumpClientProtocol guy. So, in connectionLost on your server, you may want to put something like this:<br>\n<br>\n <pre>self.dest.transport.loseConnection()</pre>\n<br>\nExcellent recipe! Thanks!\n', 'title': u'Need to handle client disconnects'}, {'comment': u"I'll add it in :)", 'title': u'Good idea'}], 'desc': u'A lightweight and portable way to hex-dump network traffic between network applications.'}, {'comments': [], 'desc': u'A Heap wrapper class around the standard heapq, it helps avoid some common bugs with a useful OOP, and it manages a key parameter too.'}, {'comments': [{'comment': u"At first, I thought you'd inverted the md5 hash. You would have gotten some money for that!", 'title': u'"Cracked"?'}, {'comment': u"Hah! Yeah, nice try. Well I don't know much about algorithm inversion. I haven't even taken Calculus yet. Still taking Pre-Calc now... I'll continue to work on these things if you guys think that they're any good. (Even if you hate them, I'll still continue Python, I enjoy it). The number one thing i need now from you all is feedback. Tell me how my program is, what more do you want it to be able to do. Be realistic, though =) .\n\n-N", 'title': u'Reply...'}, {'comment': u'Please see the rainbow tables page for practical password cracking: http://en.wikipedia.org/wiki/Rainbow_table', 'title': u' '}, {'comment': u'I thought seeing someone else\'s version of the program might be instructive; so, here\'s my go at it.\n\nNotes: optparse is really handy.\n strip() is preferable for removing whitespace\n readlines() is nice\n\n\nimport sys\nimport md5\nfrom optparse import OptionParser\n\ndef getOptionsAndArgs():\n parser = OptionParser("%prog [options] ")\n parser.add_option(\'-d\', \'--dict\',\n action="store",\n dest="pathToWordList",\n default="/usr/share/dict/words",\n help="Path to word list")\n parser.add_option(\'-v\', \'--verbose\',\n action="store_true",\n dest="verbose",\n default=False,\n help="Show words as they are searched")\n\n options, args = parser.parse_args()\n\n if not args:\n parser.print_help()\n sys.exit(1)\n\n return options, args\n\ndef searchForCollisions(targetHash, pathToWordList, verbose=False):\n for word in open(pathToWordList, "r").readlines():\n word = word.strip()\n hash2Test = md5.md5(word).hexdigest()\n if verbose:\n print "Searching...", word, hash2Test\n if hash2Test == targetHash:\n print "Collision Detected: The word is ", word\n return True\n return False\n\nif __name__ == "__main__":\n options, args = getOptionsAndArgs()\n\n if not searchForCollisions(targetHash=args[0],\n pathToWordList=options.pathToWordList,\n verbose=options.verbose):\n print "No Collision Detected"\n\n print "Done."\n', 'title': u'I might write it like this...'}, {'comment': u'optparse = cool\n\n<pre>\nimport sys\nimport md5\nfrom optparse import OptionParser\n\ndef getOptionsAndArgs():\n parser = OptionParser("%prog [options] ")\n parser.add_option(\'-d\', \'--dict\',\n action="store",\n dest="pathToWordList",\n default="/usr/share/dict/words",\n help="Path to word list")\n parser.add_option(\'-v\', \'--verbose\',\n action="store_true",\n dest="verbose",\n default=False,\n help="Show words as they are searched")\n\n options, args = parser.parse_args()\n\n if not args:\n parser.print_help()\n sys.exit(1)\n\n return options, args\n\ndef searchForCollisions(targetHash, pathToWordList, verbose=False):\n for word in open(pathToWordList, "r").readlines():\n word = word.strip()\n hash2Test = md5.md5(word).hexdigest()\n if verbose:\n print "Searching...", word, hash2Test\n if hash2Test == targetHash:\n print "Collision Detected: The word is ", word\n return True\n return False\n\nif __name__ == "__main__":\n options, args = getOptionsAndArgs()\n\n if not searchForCollisions(targetHash=args[0],\n pathToWordList=options.pathToWordList,\n verbose=options.verbose):\n print "No Collision Detected"\n\n print "Done."\n</pre>', 'title': u"Oops, need the <pre>s... anyway here's my go..."}], 'desc': u'This script allows you to crack an MD5 hash. The script asks you for both the file where the hash resides (a .txt file normally, although a .dat will work just as well), as well as the wordlist (also a .txt or .dat) to be used. The program functions by hashing each line from the wordlist, and then comparing it to the hash specified. Very quick runtime!'}, {'comments': [], 'desc': u"Needed the ability to 'pushback' values back onto an iterator, and also was able to add a 'nonzero' test to the iterator at the same time."}, {'comments': [], 'desc': u'This program can act an an alarm clock on a Windows machine.'}, {'comments': [], 'desc': u"This program raises or lowers the case of your file's extention."}, {'comments': [], 'desc': u'This program can rename lots of files that it recognizes for indexing purposes.'}, {'comments': [{'comment': u'A cross-platform (where Tkinter is available) program doing the same:\n\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/124894', 'title': u'Alternative'}], 'desc': u'This program can actually time anything you want,\nnot just eggs. Unfortunately, it only runs on Windows.'}, {'comments': [], 'desc': u'(T)iled (V)ideo player was written to show some images\nthat can be taken with Casio Exilim digital cameras.\nNow that big, 25 scene picture can actually make sense.'}, {'comments': [], 'desc': u'This module proves itself to be a useful _winreg\nwrapper. Examples following this recipe include\ninstall.py, uninstall.py, and opt.py [all part of the\n"Kaos Rain (MKv3)" hand-eye coordination testing program].'}, {'comments': [], 'desc': u'The following program shows sample usage of the _winreg Wrapper.'}, {'comments': [], 'desc': u'The following program shows sample usage of the _winreg Wrapper.'}, {'comments': [], 'desc': u'The following module shows sample usage of the _winreg Wrapper.'}, {'comments': [], 'desc': u'This module gives a simple implementation of the physics behind bouncing balls.'}, {'comments': [], 'desc': u'This program provides sample usage for the opt.py\nand physics.py modules shown in previous recipes.'}, {'comments': [{'comment': u'You can avoid the use of the strip call in the line:<br>\n<pre>\n return \'\'.join( [ "%02X " % ord( x ) for x in byteStr ] ).strip()<br>\n</pre>\nby joining with a space:<br>\n<pre>\n return \' \'.join( [ "%02X" % ord( x ) for x in byteStr ] )\n</pre>', 'title': u'remove strip'}, {'comment': u"If you remove the space separation then you don't need the .strip(), this is true But then test 4 kind of sucks.\n\nAlso, I like my hex byte output space separated. It makes it easier to read.", 'title': u'remove strip means remove space separation'}], 'desc': u"I write a lot of ad-hoc protocol analysers using Python. Generally, I'm dealing with a byte stream that I want to output as a string of hex. Sometimes, I want to convert it back again. Eventually, I got round to putting the functions in a module so I wouldn't keep cut and pasting them :)"}, {'comments': [], 'desc': u'This recipe lets you transparently forward attribute access to another object in your class. This way, you can expose functionality from some member of your class instance directly, e.g. foo.baz() instead of foo.bar.baz().'}, {'comments': [], 'desc': u'Many comparable or hashable classes calculate all comparison and hash results from the same simple calculation. The mixins in this recipe allow such classes to define a single __key__() method from which all the __eq__(), __lt__(), __hash__(), etc. methods are automatically defined.'}, {'comments': [{'comment': u'This is ugly:\n<pre>\nif num1 > num2 and num1 > num3:\n low = num1\nelif num2 > num1 and num2 > num3:\n low = num2\nelif num3 > num1 and num3 > num2:\n low = num3\n# find the highest number\nif num1 < num2 and num1 < num3:\n high=num1\nelif num2 < num1 and num2 < num3:\n high=num2\nelif num3 < num1 and num3 < num2:\n high=num3\n</pre>\nOuch! Try using min() and max():\n<pre>\nlow = min(num1, num2, num3)\nhigh = max(num1, num2, num3)\n</pre>\nOr maybe sorted():\n<pre>\nlow, mid, high = sorted([num1, num2, num3])\n</pre>', 'title': u'min(), max() or sorted()'}], 'desc': u'finds the least common multiple and the greatest common factor of three numbers. i wrote it a while ago for school.'}, {'comments': [], 'desc': u"reads bash.org/latest and saves it to a pre made .html file. on mac OSX i made a simple automater program that runs python BashReader.py in the terminal and set it to run when i login. evry time it runs it overwrites the old file so you don't have to worry about hundreds of bash.htmls mounting up on your computer"}, {'comments': [], 'desc': u"This relatively simple program solves by iteration the classic 8 queens chess problem. For those unfamiliar, the challenge is to find the number of ways it's possible arrange 8 queens on a chess board so that none can capture any other in one move. There's some wierd mathmatical proof of this, but this simple Python program demonstrates recursive iteration through many, (8^8), possible possibilities in the most efficient manor possible. The code itself was written for clarity and speed by someone relatively new to Python, so it should be pretty easy to understand."}, {'comments': [{'comment': u"This looks interesting, but I'm missing something::\n\n>>> import os\n>>> statinfo = os.stat('/tmp/test.file')\n>>> print type(statinfo.st_ctime)\n\n>>> cdt = FiletimeToDateTime(ctypes.c_long(creation))\n\nTypeError: int expected instead of float instance\n\nWhat am I doing wrong?\n\nThanks,\nKent", 'title': u'type problem'}], 'desc': u'Converting a FILTIME in a datetime is sometime verry useful if you use ctypes with win API.'}, {'comments': [], 'desc': u"This program is designed to automatically extract\n*.BMP and *.JPG files from a file has has this\ninformation packed in an easy-to-read format. The\noriginal purpose of this program was to help in\nthe recovery of a user's accidentally deleted files."}, {'comments': [], 'desc': u'This program was used to search for files with\ncertain extentions and then to delete them while\ncarefully reporting all errors. The recipe does\nnot accept command-line arguments but works well.'}, {'comments': [], 'desc': u'This program fixes a file for Firefox for use on\ncertain intranets and demonstrates automated\nfile searching and editing. It was written for\nuse at a university of several thousand computers.'}, {'comments': [{'comment': u'You should have a look at os.walk() ( http://docs.python.org/lib/os-file-dir.html#l2h-2707 ).', 'title': u'os.walk()'}], 'desc': u"This recipe demonstrates a simple text file searching program.\nThe code asks for a directory to search (with its subdirectories)\nand the text that needs to be found in the contained files. This\nis just a simple starting program demonstrating how to access\na computer's file system and accomplish useful work at the same time."}, {'comments': [], 'desc': u'This recipe introduces a new encoding scheme known\nas base255. It is useful in automatically making a\npython string into a "C string" so that no NULL\nbytes are left in the processed character array.'}, {'comments': [], 'desc': u'This program demonstrates some sample usage of the\nbase255 module and is the core of something called\nFDR (Full Duplex RPC). FDR has not been completed\nat this time, but the "spots" module takes most of\nthe work off of other modules in network chatter.'}, {'comments': [], 'desc': u'This program was adapted from the SAMPLES directory\nthat comes with Python. It allows two people to draw\non a program with someone else watching and, at the\nsame time watch what the other person is drawing also.'}, {'comments': [], 'desc': u'This recipe is the core of something called FDR\n(Full Duplex RPC). FDR has not been completed at\nthis time, but the "spots" module takes most of\nthe work off of other modules in network chatter.\nThis is the second version of "spots" and simplifies\nthe ZSP class while getting rid of the base255 module.'}, {'comments': [], 'desc': u'This program was adapted from the SAMPLES directory\nthat comes with Python. It allows two people to draw\non a program with someone else watching and, at the\nsame time watch what the other person is drawing also.'}, {'comments': [], 'desc': u'Looks at a directory hive, finds .JPGs with EXIF info, and sorts them in a new directory structure by camera model, year, month, and optionally, date. Imports EXIF.py and dirwalk.py in addition to standard Python modules.'}, {'comments': [{'comment': u"<pre>\nimport random\nimport textwrap\n\ndef iter_random_guesses(n, max):\n guessed = set()\n while True:\n guess = random.randrange(max)\n if guess in guessed:\n continue\n else:\n guessed.add(guess)\n yield guess\n\ndef iter_efficient_guesses(n, max):\n min = 0\n while True:\n guess = (min + max) / 2\n yield guess\n if guess < n:\n min = guess\n else:\n max = guess\n\n\nif __name__ == '__main__':\n\n guess_iter_map = {1: iter_random_guesses,\n 2: iter_efficient_guesses}\n\n print textwrap.dedent('''\\\n welcome to a number guessing program\n\n enter 1 for random\n or\n enter 2 for efficient\n ''')\n \n guess_type = int(raw_input('> '))\n n = int(raw_input('pick a number> '))\n max = int(raw_input('pick a range > '))\n get_guess_iter = guess_iter_map[guess_type]\n guess_iter = get_guess_iter(n, max + 1)\n for i, guess in enumerate(guess_iter):\n print guess\n if guess == n:\n break\n tup = n, i + 1, max\n print 'I got the number %i in %i guesses, out of a range of %i' % tup \n</pre>", 'title': u'A cleaner, more extensible version'}], 'desc': u'most number guessing programs make you guess the number but heres one where the computer guesses ether random or the most efficient way. '}, {'comments': [], 'desc': u"This recipe provides a couple of cross-platform utility functions, 'open' and 'mailto', for opening files and URLs in the registered default application and for sending e-mails using the user's preferred composer.\nThe python standard library already provides the os.startfie function that allows the user to open a generic file in the associated application but it only works on Windows.\nThe 'webbrowser' module is cross-platform but only handles a specific kind of application, the web browser, and it is useless if one wants to open e.g. a source code python file in the user's preferred text editor.\nThe 'open' function simply opens the file or URL passed as parameter in the system registered application.\nThe 'mailto' function starts the user's preferred e-mail composer and pre-fills the 'to', 'cc','bcc' and 'subject' headers if corresponding parameters are provided. It also handles parameters for the message body and for attachments.\n"}, {'comments': [{'comment': u"Is the URL in the script up to date? The script seems to work fine, but I'm not getting a hit on the URL.\nThanks,\n-t", 'title': u'Yahoo URL'}], 'desc': u'Courtesy of Yahoo finance, it is possible to bulk download historical prices data. This script, borrowed from pycurl retriever-multi.py example, fetch series for several tickers at a time. It uses urllib to fetch web data, so it should work with a plain vanilla python distro. '}, {'comments': [], 'desc': u'This code will add a previously created user to a previously created group in Active Directory. '}, {'comments': [{'comment': u'For those of us on Mac and Linux boxes, how might we access this Active Directory that all our coworkers keep talking about?', 'title': u'How about on other OSes?'}, {'comment': u'Hi,\n\nI have found that \n<pre> \n converted = datetime.fromtimestamp(int(time))\n</pre>\n\nworks well for converting from PyTime to Datetime.', 'title': u'PyTime conversion...'}, {'comment': u'I cannot report good results with int(pytime). With "real-world" data, there are just too many garbage dates inside of Active Directory. "int(pytime)" raised a ValueError, but doing it the "hard way" with "float(pytime)" does not raise an exception.\n<br><br>\nBut, granted, the dates that raise ValueError with "int(pytime)" are probably not worth trying to view as dates.', 'title': u'int(pytime) instead of float(pytime)'}], 'desc': u'From Active Directory (or any other LDAP server) dump ALL information about computers, users, and groups, in a nicely formatted report.'}, {'comments': [{'comment': u'Why are you reimplementing asyncore?', 'title': u' '}], 'desc': u'This recipe implements the concept of asynchronous socket programming in a\nmore straighforward way than in the modules asyncore and asynchat of the\nstandard distribution, which I find difficult to understand'}, {'comments': [], 'desc': u'This recipes implements the HTTP protocol with persistent connection and CGI support on top of the generic asynchronous server provided in recipe 511453'}, {'comments': [], 'desc': u'A directory tree walker that returns the files in breadth first order'}, {'comments': [{'comment': u"Very effective! but I don't understand the function millerTest, could u pls explain it for a while?", 'title': u' '}], 'desc': u'Very simple implementation of Miller-Rabin Primality Test with Tkinter'}, {'comments': [{'comment': u'The pdftotxt tool in Xpdf (http://www.foolabs.com/xpdf/download.html) can do a similar thing, though not in Python.', 'title': u' '}], 'desc': u'This example shows how to extract text informations from a PDF file without the need of system dependent tools or code. Just use the pyPdf library from http://pybrary.net/pyPdf/'}, {'comments': [], 'desc': u'There are a several ways to represent collections of key/value pairs in XML, which makes it more difficult than necessary to use that data in python. By taking advantage of common patterns in the XML it is easy to turn most formats into collections of lists and dicts.'}, {'comments': [], 'desc': u'Python type-string parser. The code evolved from a post in python-list on 11/22/05 by Fredrik Lundh on a dictionary parser. It parses a type-string to their type objects for all basic types. Raises SyntaxError and SemanticError on failures.\n \nSupported types:\n * containers: defaultdict, deque, dict, list, tuple, set\n * basic types: Decimal, bool, float, int, long, str\n * None type\n\nREQUIRES PYTHON >= 2.5'}, {'comments': [], 'desc': u'This is a simple function that runs another function in a different process by forking a new process which runs the function and waiting for the result in the parent. This can be useful for releasing resources used by the function such as memory.'}, {'comments': [], 'desc': u"Extends pyunit with method decorators, allowing the programmer to 'anotate' test methods and expected exceptions, rather than having to adhere to a naming convention."}, {'comments': [{'comment': u'That does the interpolation in the wrong direction (ie the higher the percent the closer to the lower value it went). Change to:\nd0 = key(N[int(f)]) * (c-k) and\nd1 = key(N[int(c)]) * (k-f)', 'title': u'Correction'}], 'desc': u'This function find the percentile of a list of values. Note that the list must be sorted already.'}, {'comments': [{'comment': u"The roundrobin recipe provides similar capabilities but works lazily and doesn't require indexing. See the collections.deque() docs at http://docs.python.org/lib/deque-recipes.html )", 'title': u'Similar to the roundrobin() recipe'}, {'comment': u'If your sequences are all the same length, a simple application of zip or izip gets you the same thing:\n<pre>\n>>> a = [1,3,5]\n>>> b = [2,4,6,8]\n>>> c = ["x","y","z"]\n>>> [item for items in itertools.izip(a, b, c) for item in items]\n[1, 2, \'x\', 3, 4, \'y\', 5, 6, \'z\']\n</pre>', 'title': u'zip/izip'}, {'comment': u'Re-inventing the wheel is fun sometimes. :) The deque roundrobin() recipe is exactly what I needed. Thanks.', 'title': u'ANN: Device for converting rotational motion into translational by means of a circular shaped mass about an axle'}, {'comment': u'a = [1,3,5]<br>\nb = [2,4,6,8]<br>\nc = ["x","y","z"]<br><br>\n\nprint [ y for x in map(None,a,b,c) for y in x if y]', 'title': u'a simpler way'}, {'comment': u'That\'s just freaky man!\n\nSo an expansion of that, without itertools would be:\n\n<pre>\na = [1,3,5]\nb = [2,4,6,8]\nc = ["x","y","z"]\n\nresult = []\nfor items in zip(a, b, c):\n for item in items:\n result.append(item)\n\nprint result == [item for items in zip(a,b,c) for item in items]\n</pre>', 'title': u'wow'}], 'desc': u'Interleaving can be thought of as two-dimensional iteration over a sequence of sequences, pulling the ith element from all n seqeuences before moving on to the ith + 1 element. Interleave does not truncate to the shortest list unlike flatten(zip(seqA, seqB)) [see flatten() recipe]. Here\'s an illustration:\n\n a = [1,3,5]\n b = [2,4,6,8]\n c = ["x","y","z"]\n\ninterleave(a,b,c) will return:\n\n [1, 2, "x", 3, 4, "y", 5, 6, "z", 8]'}, {'comments': [], 'desc': u'Here is a small footprint routine to convert a number of floating point seconds (such as an elapsed time, found by subtracting an earlier return value from time.time() from a later value) to "0:00:00.000" format, instead of "time.strftime("%H:%M:%S",time.gmtime(t2-t1))+(".%03d" % (((t2-t1)-int(t2-t1))*1000))" '}, {'comments': [], 'desc': u'An implementation of the token bucket algorithm in Python.'}, {'comments': [{'comment': u"The way you are calling GetDiskFreeSpaceEx is very wrong, since not only you don't check return error code, you are relying on the fact that SystemDrive environment variable only has ansi characters (otherwise unicode(...) won't work), which is true these days, but who can tell about future? Plus your code won't work on Win9x, since they don't have unicode versions of this function. The better (imho at least) way to wrap such native functions is like below:\n\n<pre>import os\nimport ctypes\n\ntry:\n GetDiskFreeSpaceEx = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_wchar_p, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64))\n GetDiskFreeSpaceEx = GetDiskFreeSpaceEx(('GetDiskFreeSpaceExW', ctypes.windll.kernel32), (\n (1, 'lpszPathName'),\n (2, 'lpFreeUserSpace'),\n (2, 'lpTotalSpace'),\n (2, 'lpFreeSpace'),))\nexcept AttributeError:\n GetDiskFreeSpaceEx = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64))\n GetDiskFreeSpaceEx = GetDiskFreeSpaceEx(('GetDiskFreeSpaceExA', ctypes.windll.kernel32), (\n (1, 'lpszPathName'),\n (2, 'lpFreeUserSpace'),\n (2, 'lpTotalSpace'),\n (2, 'lpFreeSpace'),))\n\ndef GetDiskFreeSpaceEx_errcheck(result, func, args):\n if not result:\n raise ctypes.WinError()\n return args[1].value, args[2].value, args[3].value\nGetDiskFreeSpaceEx.errcheck = GetDiskFreeSpaceEx_errcheck\n\nprint GetDiskFreeSpaceEx(os.getenv('SystemDrive'))</pre>", 'title': u'Calling ctypes like that is wrong'}], 'desc': u'This code uses pywin32 and the _winreg module to get some vital information about the system the script is running on, including OS version, installed browsers and free space on the main HD.\n\nEnjoy'}, {'comments': [{'comment': u"The code for the 'contains' method:\n\n<pre>\n def __contains__(self, key):\n s = frozenset([key])\n return not not (key AND self.master | key AND self.added)\n</pre>\n\nIs 'not not' a faster form of 'bool(X)'?\n\n<br><br>\n\nP.S. The comment formatting on the Python Cookbook is atrocious. I would personally be embarrassed, but I am probably not aware of the time/resource constraints the maintainer is under.", 'title': u'"not not"?'}, {'comment': u'Does wrapping the key in a "frozenset" mean that:\n\n<br>\n<br>\n1) the "hash" for the key is computed\n<br>\n2) as long as the frozenset is in the local scope, the hash for the key (already computed) is available as does not need to be computed again?\n<br><br>\nMy main question is, is the critical thing that the frozenset remains in the local scope?', 'title': u'wrapping the key in a "frozenset", purpose?'}, {'comment': u'Writing s=frozenset([k]) forces once call to k.__hash__(). Subsequent set operations on the frozenset will re-use the hash value and will avoid making more calls to the hash function (for example, computing master.intersection(s) will not call k.__hash__()). The ability of sets to remember hash values is intrinsic and has nothing to do with local scope.', 'title': u'Doing the hash only once'}, {'comment': u'<pre>\n > (building a new set triggers a hash call but set-to-set operations do not)\n</pre>\n<br>\nThank you for making this clear. I will try to keep this in mind in my own code.', 'title': u'set-to-set operations do not re-trigger a hash call'}], 'desc': u'Tracks the additions and deletions to a set during update operations. Useful for large sets with few modifications.'}, {'comments': [{'comment': u'cat rec_2.tmp would have worked as well', 'title': u'Seems more like "cat" to me'}], 'desc': u"based on user's profile/tag, and the target URL recommand "}, {'comments': [], 'desc': u'a very simple printer module for any *nix system that has lpr'}, {'comments': [], 'desc': u'A heap data structure that allows efficient merging of two heaps into one. See\nhttp://en.wikipedia.org/wiki/Binomial_heap'}, {'comments': [], 'desc': u'Merge sorted iterables with stability and built-in DSO'}, {'comments': [], 'desc': u"The `pickle' module provides a convenient way to serialize Python data structures to disk. With the introduction of `with' statement in Python 2.5, we can write code that reads/updates Python data in a more intuitive way."}, {'comments': [{'comment': u'Seems like coremethod.__get__ could just be:\n\n<pre>\ndef __get__(self, obj, objtype):\n if obj is None:\n return self.func\n else:\n return self.func.__get__(obj.__core__)\n</pre>', 'title': u'coremethod.__get__'}, {'comment': u"CoreAttrProxy also seems overly complex. The following still passes your doctests:\n<pre>\nclass CoreAttrProxy(object):\n __slots__ = ['name']\n def __init__(self, name):\n self.name = name\n def __get__(self, obj, objtype):\n return getattr(obj.__core__, self.name)\n def __set__(self, obj, value):\n setattr(obj.__core__, self.name, value)\n def __delete__(self, obj):\n delattr(obj.__core__, self.name)\n</pre>", 'title': u'CoreAttrProxy'}, {'comment': u"I like pushing the logic out of safedel and into the metaclass. Here's one way to do that:\n<pre>\nclass SafedelMetaclass(type):\n # list of weak references; when the objects they reference\n # disappear, their callbacks will remove them from this set\n _reflist = set()\n \n def __init__(cls, name, bases, class_dict):\n super(SafedelMetaclass, cls).__init__(name, bases, class_dict)\n\n # create the core class\n core_bases = []\n for base in bases:\n x = getattr(base, '__coreclass__', None)\n if x is not None:\n core_bases.append(x)\n core_class = type(name + '__Core', tuple(core_bases), {})\n core_class.__surfaceclass__ = cls\n\n # add core class __getattr__\n def core_getattr(core, name):\n return getattr(core.__surfaceclass__, name)\n core_class.__getattr__ = core_getattr\n\n # add core class methods (unwrapping coremethod objects)\n for attr_name, attr_value in class_dict.items():\n if isinstance(attr_value, coremethod):\n setattr(core_class, attr_name, attr_value.func)\n\n # add core class and attribute proxies to main class\n cls.__coreclass__ = core_class\n for attr_name in class_dict.get('__coreattrs__', []):\n setattr(cls, attr_name, CoreAttrProxy(attr_name))\n\n def __call__(cls, *args, **kwargs):\n # create a new instance, set __core__, then initialize\n obj = cls.__new__(cls, *args, **kwargs)\n obj.__core__ = obj.__coreclass__()\n obj.__init__(*args, **kwargs)\n\n # a closure for calling the class's __safedel__ method,\n # passing it the instance's core object\n def get_del_caller(core, cls):\n def del_caller(ref):\n SafedelMetaclass._reflist.remove(ref)\n cls.__safedel__(core)\n return del_caller\n\n # register a weak reference to call the __safedel__ \n del_caller = get_del_caller(obj.__core__, obj.__class__)\n SafedelMetaclass._reflist.add(weakref.ref(obj, del_caller))\n\n # return the newly created instance\n return obj\n</pre>\nWith this approach, you don't even really need the safedel class (though it's probably handy as a simple base class).", 'title': u'merging safedel.__init__ into SafedelMetaclass'}], 'desc': u'This is an ever-so-slightly over engineered solution to using weakrefs instead of __del__. It provides a "core" object for all the attributes your cleanup code needs, then allows your main object to continue as normal by using descriptors.'}, {'comments': [{'comment': u'Note that this recipe is working only for Python-2.5', 'title': u'python2.5 only'}, {'comment': u'Now that I have 2.5, everything I write has a generator expression or a ternary operator somewhere in it.\n\nI think if you replaced these, it should work on 2.4.', 'title': u'Generator expressions etc'}], 'desc': u"This function will display a nicely formatted textual table for you. Features include: auto-sizing of columns, auto-alignment based on column-type (which it sniffs from the first row), nicely formated centered headings, and most importantly wrapping of cells. Of course, you can manually override pretty much everything in case you don't like the defaults."}, {'comments': [{'comment': u"Generally, this seems like a nice approach, but it should be made a little more obvious that attributes are collected at the time of the enable_finalizer() call. A naive subclass might do something like:\n<pre>\n>>> class C(Finalizable):\n... def __init__(self):\n... self.items = [] # some resource\n... self.count = 0\n... self.enable_finalizer('items', 'count')\n... def add(self, item):\n... self.items.append(item)\n... self.count += 1\n... def __finalize__(self):\n... for i in range(self.count):\n... print 'releasing', self.items.pop()\n... print 'finalized'\n... \n>>> c = C()\n>>> c.add('foo')\n>>> c.add('bar')\n>>> del c\nfinalized\n</pre>\nAnd wonder why 'foo' and 'bar' weren't released. Perhaps the name should be changed from enable_finalizer() to store_finalizer_attributes() or something like that.", 'title': u' '}, {'comment': u"Thanks for the comment! I've changed the API from enable_finalizer/disable_finalizer to bind_finalizer/remove_finalizer.\nAlso, I've made clear in the doc that the attributes are bound when bind_finalizer() is called.\n\nAntoine.\n", 'title': u'corrected'}], 'desc': u'The well-known way to avoid __del__ (and its problems when the object to be deleted is involved in a reference cycle) is to use a finalization callback on a weakref.\n\nThis recipe simply makes it easier to write such "finalizable" objects by allowing to write the finalizer as a __finalize__ method (a bit similar to a __del__ method, but not exactly as we\'ll see).\n\nThe first step is to call the bind_finalizer(*attrs) method on your instance; you must give bind_finalizer a list of attribute names necessary for the finalizer to operate, and it will construct a "ghost object" holding those attributes (for example, if you have a "socket" attribute you want to close, you will include "socket" in the arguments to bind_finalizer, which in turn will bind a "socket" attribute on the ghost object). The ghost object has the same class as the original self, so you will be able to call instance methods and use class variables in the finalizer as well.\n\nPlease note: the ghost object is created and its attributes are bound *as soon as* bind_finalizer() is called, so their values must have been properly initialized. A practical idiom is probably to call bind_finalizer() at the end of your constructor. Creating the ghost ignores any __new__ or __init__ method you have defined, so you don\'t have to worry about constructor signature or unwanted side effects.\n\nYour __finalize__ method must be written as a normal method, except that it can only access those instance attributes whose names you gave to bind_finalizer. This is because __finalize__ gets a "ghost instance" instead of the original instance.\n\nFinally, there is a remove_finalizer() which does the obvious. Call it when the resources have been somehow freed manually and automatic finalization is not useful anymore.\n\nWith this recipe, you have an object-oriented finalization scheme which still works as required when your instance is part of a reference cycle to be broken by the Garbage Collector. Also, it doesn\'t use metaclasses which makes it easier to re-use if you have your own metaclasses.\n\nYou can find hereafter the code for the Finalizeable class, as well as an example TransactionBase class which helps writing objects with transaction-like behaviour and optional automatic rollback on object destruction.\n(but the interesting stuff is really in Finalizable)\n'}, {'comments': [], 'desc': u'Sometime I want extract part of disk-based log file, created by standard \nlogging module) into separated file on disk.\nThis recipe shows simple technique to acquire this.\n\nSample: processing tasks in loop, so on exit I have few logs: on log per task.'}, {'comments': [], 'desc': u"Since the year dot, file locking has been used as a very simple synchronizing primitive between processes. Here's my take on the approach. To try it, simply start two command windows/terminal windows and run the script in each.\n\nTested on WinXP and Ubuntu (Dapper and Feisty)."}, {'comments': [{'comment': u"http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/465850\nhttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412551\n\nThere are many more. Just search for 'singleton'.", 'title': u'other singleton (and related) recipes'}, {'comment': u"The solution is okay, but I've seen hundreds of these, and some exactly the same. This entry looks like noise in an attempt to ... ... maybe create presence ? Is the submitter planning a patent application. He won't be the first. ", 'title': u'Is this just noise?'}, {'comment': u' if OnlyOne.__instance == None:<br>\n obj = object.__new__(typ, *args, **kwargs)<br>\n OnlyOne.__instance = obj<br>\n<br>\nlooks like we need to make this three lines atomic...<br>', 'title': u' '}], 'desc': u"Here I have implemented the Singleton base class using __new__. \nI was reading thru Bruce Eckel's http://www.mindview.net/Books/TIPython\nand thought OnlyOne can be more simple....\n\nAre there any differences in between two approaches?"}, {'comments': [], 'desc': u'This recipe introduces a __finalize__ method along with a __finalattrs__ class attribute which can be used for simple finalization without all the complications that __del__ currently creates.\n\nSimply list any instance attributes that need to be available for finalization in the __finalattrs__ class attribute. When the instance is garbage collected, the __finalize__ method will be called with an object exposing just the __finalattrs__ attributes.'}, {'comments': [], 'desc': u"aebovl is a script that overlays images of the same scene taken at different exposures. This brightens under-exposed areas and darkens over-exposed areas of the image. This generates a kind of poor man's HDR image."}, {'comments': [], 'desc': u'Proxies are usually implemented as objects that forward method calls to a\n"target" object. This approach has a major problem: forwarding makes the target\nobject the receiver of the method call; this means that calls originating from\nthe body of a method in the target will not go through the proxy (and thus their\nbehavior cannot be modified by the proxy).\n\nFor example, suppose we want a proxy to an instance of Target (shown below)\nthat is "safe", i.e., does not do anything bad like firing missiles. We can\njust define a class that forwards calls to the safe methods, namely\nsend_flowers() and hang_out(). This class can have its own version of\nfire_missiles() that does nothing. Now consider what happens when we call\nthe proxy object\'s innocent-looking hang_out() method. The call is forwarded\nto the target object, which in turn calls the target object\'s (not the\nproxy\'s) fire_missiles() method, and BOOM! (The proxy\'s version of\nfire_missiles() is not called because forwarding has made the target object\nthe receiver of the new method call.)\n\nBy using delegation, one can implement proxies without the drawbacks of the\nmethod-forwarding approach. This recipe shows how Python\'s __getattr__\nmethod can be used to implement the kind of delegation present in\nprototype-based languages like Self and Javascript, and how delegation can\nbe used to implement better proxies.\n'}, {'comments': [], 'desc': u'The code based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195 but interface is PEP 367 like so you can write just super.base_method() inside a method. See doctests for examples.'}, {'comments': [], 'desc': u"SimpleXMLRPCServer is too simple. It's serve_forever function doesn't allow it to be incorporated into anything that needs to be gracefully stopped at some point. This code extends SimpleXMLRPCServer with the server_until_stopped and stop_serving functions."}, {'comments': [], 'desc': u'A class used for creating any object moving in 2D or a Vector Object\nit takes the initial position, speed, and direction, and lets you\naddspeed to the the object, steer the object and update it by time.\n'}, {'comments': [], 'desc': u' '}, {'comments': [{'comment': u'I and others use something like this:\n<pre>\nclass Counter(dict):\n def count(self, what):\n try:\n self[what] +=1\n except KeyError:\n self[what] =1\n return self\n</pre>\nFor sample I just <pre>sum(someCounter.values())</pre>\n\nAlso \nYour sort could be a lot simpler: See other recipes.', 'title': u'A simple counter'}, {'comment': u'There is a recipe for bags that solves the same problem, so you might want to check it.\n\nAlso, in python 2.5, defaultdict(int) does pretty much what you need.', 'title': u'Look at recipes for bag'}, {'comment': u"Thanks for the comments. \n\nThe recipe is a typical result of bein entrenched. I originally wrote it in the times of 1.5.2, when most of the fancier stuff in Python either wasn't there or was slow. As it worked for me, I never bothered to rethink the entire approach. \n\nLesson learned.", 'title': u'thx'}], 'desc': u'This class can be used to tally objects, for example when analyzing log files. It has two separate ways of calculating the "score board", one quicker for Python >=2.4 and one that works with older versions (though I doubt it works with anything <2.0).\n\nAs the class uses a dictionary, only hashables can be counted. Other than that, you can mix and match them however you want.'}, {'comments': [{'comment': u'One thing I don\'t get: what\'s the purpose of the read-only access to "listeners"?', 'title': u' '}, {'comment': u"The listeners attribute is a list. We let client's mutate the list by adding or removing listeners, but they have need to replace the list with a different object. And, knowing that the listeners list object is not changeable, it can be shared by clients across multiple threads.", 'title': u'Why listeners is read-only'}], 'desc': u'Monitor sets for changes using the Observer design pattern.'}, {'comments': [], 'desc': u'parse profile information from a myspace.com account.'}, {'comments': [], 'desc': u"Task: Administrative job to run in my case 2300 jobs in a scheduled manner\nRestriction: Don't start two jobs at same schedule on same server\n\nProblems to solve that for:\n* align list of projects into batch of jobs with distinct servers\n* templated job creation\n* create a crontab \n * to start all this jobs from a starting schedule every hour\n * respect some restrictions that on some days and some hours no jobs should be started\n\nThanks to builtin map() and standard-library time, datetime and timedelta to make that an ease at the end!"}, {'comments': [{'comment': u'Two comments:<br>\n1. Your source seems to have broken indentation.<br>\n2. Was already posted (originally almost 4 years ago now): http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252524', 'title': u' '}], 'desc': u'A class for maintaining a cache of limited size, with the most recently used versions being kept. This class is designed to operate in nearly constant time as the size of the cache varies.'}, {'comments': [], 'desc': u"Sometimes it is useful to make sure that arguments in a function are positional only, i.e. cannot be passed as keywords.\nThis recipe defines a decorator 'posonly' that does this: arguments cannot be passed as keywords. Note that **kwargs can still be used in the function definition to accept keywords."}, {'comments': [{'comment': u"FWIW, with a well crafted key= function, groupby() makes short work of data partitioning problems:\n\n<pre>\ndef blocks(s, start, end):\n def classify(c, ingroup=[0]):\n klass = c==start and 2 or c==end and 3 or ingroup[0]\n ingroup[0] = klass==1 or klass==2\n return klass\n return [tuple(g) for k, g in groupby(s, classify) if k == 1]\n\nprint blocks('the {quick} brown {fox} jumped', start='{', end='}')\n</pre>", 'title': u'Variant with itertools.groupby()'}, {'comment': u'Neat! It\'s also trivial to retain the delimiters by changing \n"return result" to "return result if skip_delim else result>=1". groupby is a real swiss knife!', 'title': u' '}], 'desc': u'A common task, especially in text processing, is to break some input sequence into chunks (lines, paragraphs, records, etc.) and process them one by one. The iterators of builtin strings and files can be considered such chunkers, breaking the object into characters and lines respectively. This recipe is a generic way to break any iterable into consecutive blocks, specified by a delimiter or a pair of (start,end) delimiters.'}, {'comments': [], 'desc': u'Since the version 5, Java includes an enum type in its language. It provides a way to perceive the enumerated types through an object-oriented approach.\n\nIn Java, each enumeration is a particular class and each item of this enumeration is an instance of this class. So, the value of an item can represent an integer, but also a point in a space, a operation, etc. Moreover it is possible to extend an enumeration by using the inheritance.\n\nThis recipe proposes a Python solution to implement the Java enum types, with the help of reflexion.'}, {'comments': [], 'desc': u"I got inspired to this class, after having read about the java SwingWorker.\nThe problem is that you sometimes have a tough task you want to do in a GUI program, but you don't want the UI to lock.\nThis recipe solves the problem by running the tough code in a background thread, while still letting you do useful interaction with it, like getting the progress or the latest results."}, {'comments': [], 'desc': u"First, a Dictionary class that 'journals' sets and dels. The changes in the journal can either be applied (like committing a transaction) or wiped (like rollback.) \n\nThe journalled dictionary is used to implement a JournalledMixin class that gives journalling/transaction behavor to any object. \n\nLinks and discussion below."}, {'comments': [], 'desc': u'This simple script shows how to play back a sound file using the mixer module from the pygame library. If you have pygame installed, this will work on all major platforms. The mixer module supports WAV and OGG files with many different sample rates, bits per sample and channels. The script will play back all supported files given on the command line sequentially.'}, {'comments': [{'comment': u'for i in xrange(1000000000000000000000, 1000000000000000000005, 2):\n print i,\n\nproduces 1000000000000000000000 1000000000000000000002\n\ninstead of the expected \n1000000000000000000000 1000000000000000000002 1000000000000000000004\n\nAND \n\nfor i in xrange(3, 4.1, 0.2):\n print i,\n\nproduces 3.0 3.2 3.4 3.6 3.8\ninstead of the expected 3.0 3.2 3.4 3.6 3.8 4.0\n\n\n', 'title': u'a bug, I thnk'}], 'desc': u"The built-in xrange is fast, but it does not support floats and longs as start,stop,step parameters.\nThis means you cannot iterate large number (that don't fit in an int) ranges via xrange as you would with small numbers."}, {'comments': [], 'desc': u'This module provide useful class for manipulating with version info in the form: major.minor.release.build\n\nMain operations is comparing between different versions. Also it could be useful for pretty formatting of version numbers, or to use as container for version info.\n\nLoaded with examples (they actually are doctests for this module).'}, {'comments': [{'comment': u'<pre>\nimport subprocess\nfrom elementtree import ElementTree # or use the stdlib one in py2.5+\n\nchangelog = ElementTree.parse(subprocess.Popen(\n ["darcs", "changes", "--xml-output"],\n stdout=subprocess.PIPE).stdout)\nfor patch in changelog.find("patch"):\n print patch.get(\'author\'), patch.find(\'name\').text\n</pre>', 'title': u'but if you do have darcs available to run, use xml'}], 'desc': u"Uses a multiline regular expression to retrieve patch details from a darcs (http://www.darcs.net) inventory file.\n\nThe regular expression is defined in verbose format for sanity's sake."}, {'comments': [{'comment': u'http://mail.python.org/pipermail/python-announce-list/2001-August/000954.html', 'title': u'An old requirement'}], 'desc': u"A dictionary in which the insertion order of items is preserved.\n\nBased on Doug Winter's recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/438823"}, {'comments': [], 'desc': u'#!/usr/bin/env python2.5\n#\n# html file:\n# <form action="test.cgi" method="POST" enctype="multipart/form-data">\n# <input name="file1" type="file"><input type="submit"></form>\n\n# test.cgi: ...\n\nimport SingleUpload\n\ndef upload():\n   fr = SingleUpload.open()\n   fw = open(\'/tmp/%s\' %fr.filename, \'wb\')\n\n   while True:\n      l = fr.read(65536)\n      if not l:\n         break\n\n      fw.write(l)\n      fw.flush()\n   fw.close()\n\nprint \'Content-Type: text/plain\\r\\n\\r\\n\'\ntry:\n   upload()\n   print \'OK\'\nexcept IOError:\n   __import__(\'traceback\').print_exc(\n      file=__import__(\'sys\').stdout )'}, {'comments': [], 'desc': u"This program provides the basic functions required to write a forum in MySQL and Python. The way the class is structured allows it to be imported and used in any application, whether it's web based, command line, Tcl/Tk or wxPython. It simply provides the helper functions to perform actions required to get, use and set different data in the database.\n\nHowever, I have not included the code to create the database yet. Here's the structure:\nTABLE: users\n INTEGER: id\n STRING: name\n STRING: signature\n STRING: password\nTABLE: messages\n INTEGER: id\n LONGSTRING: content\n DATE: created\n TIME: createdtime\n DATE: edited\n TIME: editedtime\n INTEGER: authorid\nTABLE: threads\n INTEGER: id\n STRING: title\n STRING: messages\n DATETIME: edited\n\nCreate that database, set up a user account, and change the arguments in ForumBase.__init__ to the user you want the program to log on as."}, {'comments': [], 'desc': u'Stale Pickles ... New Classes. Pickles are by far the easiest way to achieve persistent objects in Python. A problem arises however, when a class is modified between the time when an object is pickled and when it is un-pickled. When a stale pickle is extracted, the old data is coupled with the new class code. This is not a problem as long as no new data attributes are required. For instance, a new method that relies only on old data may be added and still work with the old pickle. \n\nOf course, if attributes are added, the old pickle files will no longer function correctly with the new class definition.\n\nThis recipe provides a framework for writing upgradable classes that support backward compatibility with stale pickles.\n'}, {'comments': [], 'desc': u"takes an ambiguous xml file and generates the ET code to generate that xml file. this is useful if you have an example xml file, or an ambiguous xml file that you'd like to use as a template to parameterize certain elements. upgrades coming."}, {'comments': [{'comment': u"You could use the alist[start::step] idiom, and if you don't care about the order, end with:\n\n<pre>\nfrom random import shuffle\n\ndef k_fold_cross_validation(items, k, randomize=False):\n \n if randomize:\n items = list(items)\n shuffle(items)\n\n slices = [items[i::k] for i in xrange(k)]\n\n for i in xrange(k):\n validation = slices[i]\n training = [item\n for s in slices if s is not validation\n for item in s]\n yield training, validation\n\nif __name__ == '__main__':\n items = range(97)\n for training, validation in k_fold_cross_validation(items, 7):\n for item in items:\n assert (item in training) ^ (item in validation)\n</pre>\n\nIf you do care about the order, you'd need to do some weaving though.", 'title': u' '}, {'comment': u'but is that better in some way than the version above? The version above does maintain the order unless randomise is true.', 'title': u'That was essentially the way I thought of at first'}, {'comment': u'The indirection through index_filter() is unnecessary, confusing and slower than simple list comprehensions:\n<pre>\ntraining = [x for i, x in enumerate(X) if i % K != k]\nvalidation = [x for i, x in enumerate(X) if i % K == k]\n</pre>\n', 'title': u'no need for index_filter()'}, {'comment': u'That docstring is a little confusing for me. I think I\'d instead write it as:\n<pre>\n"""Generates K (training, validation) pairs from the items in X.\n\nThe validation iterables are a partition of X, and each validation\niterable is of length len(X)/K. Each training iterable is the\ncomplement (within X) of the validation iterable, and so each training\niterable is of length (K-1)*len(X)/K.\n"""\n</pre>', 'title': u'docstring is a little confusing'}, {'comment': u' ', 'title': u'Thanks'}, {'comment': u'Not really. It is just maybe marginally faster though.', 'title': u' '}], 'desc': u'Takes a sequence and yields K partitions of it into training and validation test sets. Training sets are of size (k-1)*len(X)/K and partition sets are of size len(X)/K'}, {'comments': [], 'desc': u'Function becomes useful when we need hex value of crc32() result, even if it is negative.'}, {'comments': [{'comment': u"Using exceptions to implement a switch syntax seems to be a misuse of exceptions to me. I always thought dictionaries are the way to go:\n\n<pre>\nswitch = {1: 1,\n 6: 6,\n 5: 5}\nprint switch.get(55, 'default..')\n\nswitch = {1: 1,\n 'holaS': 'holaS',\n 'hola': 'hola'}\nprint switch.get('hola', 'default..')\n</pre>", 'title': u'Whats wrong with using dictionaries instead of Exceptions'}], 'desc': u"This doesn't not intent to be nor became a standard. \nInstead it's thought to be a proof of concept for a construction which mimics switch/case statements.\nI think it's funny, so, i'll hope you enjoy it as I do. "}, {'comments': [{'comment': u'The recipe below calculates the start date and end date of a given *week* of a year.', 'title': u'Description missing "week"'}, {'comment': u'from datetime import date, timedelta\n\ndef foo(year, week):\n d = date(year,1,1)\n dlt = timedelta(days = (week-1)*7)\n return d + dlt, d + dlt + timedelta(days=6)', 'title': u'Get the same with 5 lines of code'}, {'comment': u'<pre>\nfrom datetime import date, timedelta\n\ndef foo(year, week):\n d = date(year,1,1)\n dlt = timedelta(days = (week-1)*7)\n return d + dlt, d + dlt + timedelta(days=6)\n</pre>', 'title': u'Get the same with 5 lines of code'}, {'comment': u'First week of the given year does not necessarily start with January 1 a s its starting date.', 'title': u'First week of the given year'}, {'comment': u'However here is a fix.\n<pre>\ndef foo(year, week):\n d = date(year,1,1) \n d = d - timedelta(d.weekday())\n dlt = timedelta(days = (week-1)*7)\n return d + dlt, d + dlt + timedelta(days=6)\n</pre>', 'title': u'You are right!'}, {'comment': u'That simplifies my function a lot! I need to alter it though, I need the first week of the given year, if I pass 2004 1 to your function it returns "2003-12-29 , 2004-01-04" my expected result is "2004-01-05 , 2004-01-11". Thanks for the coding idea, it makes my codes a lot shorter! ', 'title': u'Cool function!'}], 'desc': u'The recipe below calculates the start date and end date of a given week of a year.\n\nParameters needed is the week number and year to use.'}, {'comments': [], 'desc': u'Using PIL and Tkinter you can easily display images in a window.'}, {'comments': [], 'desc': u'patches socket to tunnel through a tor server either by socks4a or socks5 (tor-resolve required for socks5), being careful not to leak dns requests\n\npyconstruct required, http://construct.wikispaces.com/'}, {'comments': [{'comment': u'Only looked at the upload method. `if(operator.contains(picext,ext))` is a rather obfuscated way to write `if ext in picext:`.<br>\nI\'d use a list of extensions instead of a long string. Anyway, using a block size of 1 has absolutely no sense IMHO.<br>\nIn case of exception, you print "Successful upload." ?????<br>\nYou should also strip off any path from the supplied filename.<br>\n<br>\nYou work hard to hide all errors from the final user, and guess a lot on what went wrong - but that\'s not good, at least you should print the original error message. For instance, a lot of things may fail when deleting a directory - but you always print an overlong message without having a clue whether that was the actual reason it failed.<br>\n<br>\nAlso, command handling should be greatly improved. Try to create a directory typing "makedir fooput ", or to retrieve a file using "get foo-get-1.0.tgz"', 'title': u'Needs more work'}], 'desc': u'This is a lightweight FTP client. I find it useful for my purposes. You may notice some weird code, but I assure you, it is legitimate. Python was being stubborn, so I had to circumvent some of the rules.'}, {'comments': [{'comment': u'Hi<br><br>\nBy storing the sides as a list, equal to range(1, sides + 1) when the die is initiated with an integer, you can eliminate the if statement in the roll method...\n<br><br>\n\nfrom random import randrange as _rand<br><br>\n\nclass die():<br><br>\n\n def __init__(self,sides=6):<br>\n if (type(sides)==int):<br>\n \tself.s = sides<br>\n \tself.sl = range(1, sides + 1)<br>\n else:<br>\n \tself.s = len(sides)<br>\n\t\tself.sl = sides<br><br>\n\t\t\n\t\t\n def roll(self):<br>\n \treturn self.sl[_rand(0, self.s)]<br>\n\n<br><br>\nCheers<br>\nTony<br>\n', 'title': u' '}, {'comment': u'BTW, is there a neater way to put code into comments? :-)', 'title': u' '}, {'comment': u'What\'s wrong with using the random.choice method? Seems like it was built for exactly this situation.\n\nAlso I tend to try to employ the "it\'s easier to ask forgiveness than permission" principle when possible to avoid things like type checking. So initially assume the sides parameter is an integer. If that assumption fails then assume it\'s something iterable. If that fails then bubble the exception back up to the user.\n\n<pre>\nfrom random import choice\n\nclass die:\n def __init__(self, sides=6):\n try: self.sides = range(sides)\n except TypeError: self.sides = list(sides)\n \n def roll(self):\n return choice(self.sides)\n</pre>', 'title': u'Use random.choice() instead?'}], 'desc': u'An object oriented approach to rolling a custom dice!\nthis technique allows a person to define a custom dice by list,\nby integer, or by nothing at all defaulting to 6 sides.\n'}, {'comments': [], 'desc': u'Download daily comics from comics.com and ucomics/gocomics.com e.g. peanuts, dilbert, calvin & hobbes etc.'}, {'comments': [], 'desc': u'This elisp code creates a key binding which inserts a new-style call to the base class method (using super) with the appropriate class and method name. For instance, if the point is inside method __init__ in class Widget, typing C-c C-f will insert the text "super(Widget,self).__init__()".\n\nRequires Emacs and python-mode.el.'}, {'comments': [], 'desc': u"I really like config files done in Python language itself, using a dictionary declaration. It's cool for programmers, but not so cool for system administrators not used to Python (it's so easy to forget a comma...). \nTo keep using dictionaries internally providing something more admin friendly, I've done some functions to convert a XML file to Python dictionary (and the reverse as well): "}, {'comments': [], 'desc': u'Text based command line blackjack. Hit and Stand are the only available options. Clean, commented code. Comment out any "clear()" statements you see if you want to run it in Idle.'}, {'comments': [], 'desc': u'You may have needed a priority queue with the ability to change the priorities of elements that were in the queue. This recipe solves this problem in an efficient way.'}]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/show_stats.py�����������������������������������������������������������0000664�0000000�0000000�00000001046�14107073154�0020450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" show_stats.py Display results from profiling with hotshot. Usage: In module M.py, replace a call to function f with this code: import hotshot profiler = hotshot.Profile("%s.prof" % (__file__)) profiler.runcall(f, *args) and run from the command-line as % python .../whatever.py args To get the results, run this file: % python .../show_stats.py .../whatever.py.prof """ import sys import hotshot, hotshot.stats stats = hotshot.stats.load(sys.argv[1]) stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(20) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/strip_cookbook_data.py��������������������������������������������������0000664�0000000�0000000�00000001066�14107073154�0022274�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ from os.path import * from pprint import pprint, pformat import datetime def doit(): recipes_path = expanduser("recipes.pprint") recipe_dicts = eval(open(recipes_path).read()) for r in recipe_dicts: for key in r.keys(): if key not in ('desc', 'comments'): del r[key] for c in r['comments']: for key in c.keys(): if key not in ('comment', 'title'): del c[key] f = open("stripped.pprint", 'w') f.write(pformat(recipe_dicts)) f.close() doit() ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/time_markdown_pl.pl�����������������������������������������������������0000775�0000000�0000000�00000000360�14107073154�0021571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ use Markdown; my @text_files = <$ARGV[0]/*.text>; my $file, $content; for $file (@text_files) { local(*INPUT, $/); open (INPUT, $file) || die "can't open $file: $!"; $content = <INPUT>; Markdown::Markdown($content); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/perf/util.py�����������������������������������������������������������������0000664�0000000�0000000�00000002554�14107073154�0017234�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!python # Copyright (c) 2004-2006 ActiveState Software Inc. """Perf utility functions""" import os from os.path import basename import sys import md5 import re import stat import textwrap import types from pprint import pprint, pformat # Global dict for holding specific hotshot profilers hotshotProfilers = {} # Decorators useful for timing and profiling specific functions. # # timeit usage: # Decorate the desired function and you'll get a print for how long # each call to the function took. # # hotspotit usage: # 1. decorate the desired function # 2. run your code # 3. run: # python show_stats.py <funcname>.prof # def timeit(func): clock = (sys.platform == "win32" and time.clock or time.time) def wrapper(*args, **kw): start_time = clock() try: return func(*args, **kw) finally: total_time = clock() - start_time print "%s took %.3fs" % (func.func_name, total_time) return wrapper def hotshotit(func): def wrapper(*args, **kw): import hotshot global hotshotProfilers prof_name = func.func_name+".prof" profiler = hotshotProfilers.get(prof_name) if profiler is None: profiler = hotshot.Profile(prof_name) hotshotProfilers[prof_name] = profiler return profiler.runcall(func, *args, **kw) return wrapper ����������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/sandbox/���������������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0016401�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/sandbox/mako/����������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0017330�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/sandbox/mako/README.txt������������������������������������������������������0000664�0000000�0000000�00000000462�14107073154�0021030�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mako is a templating language. I have some unfinished work here to attempt to get markdown2.py to treat Mako syntax just like raw HTML. I.e. allow writing mixed Markdown-Mako text. The key here is *unfinished*. I'm not sure if it is reasonable or feasible to support this with the current implementation. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/sandbox/mako/mako_templates.text���������������������������������������������0000664�0000000�0000000�00000000652�14107073154�0023246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- From front page of makotemplates.org with some Markdown additions. --> Here is *some* [Markdown](http://google.com/?q=Markdown). <%inherit file="base.html"/> <% rows = [[v for v in range(0,10)] for row in range(0,10)] %> <table> % for row in rows: ${makerow(row)} % endfor </table> <%def name="makerow(row)"> <tr> % for name in row: <td>${name}</td>\ % endfor </tr> </%def> ��������������������������������������������������������������������������������������python-markdown2-2.4.1/sandbox/mako/markdown2.patch�������������������������������������������������0000664�0000000�0000000�00000030710�14107073154�0022256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- markdown2.py.116 2008-09-06 10:05:56.000000000 -0700 +++ markdown2.py.makowork 2008-02-03 12:30:15.000000000 -0800 @@ -1,39 +1,38 @@ #!/usr/bin/env python # Copyright (c) 2007 ActiveState Corp. -"""A fast and complete Python implementation of Markdown. +r"""A fast and complete Python implementation of Markdown. [from http://daringfireball.net/projects/markdown/] > Markdown is a text-to-HTML filter; it translates an easy-to-read / > easy-to-write structured text format into HTML. Markdown's text > format is most similar to that of plain text email, and supports > features such as headers, *emphasis*, code blocks, blockquotes, and > links. > > Markdown's syntax is designed not as a generic markup language, but > specifically to serve as a front-end to (X)HTML. You can use span-level > HTML tags anywhere in a Markdown document, and you can use block level > HTML tags (like <div> and <table> as well). Module usage: >>> import markdown2 - >>> html = markdown2.markdown_path(path, ...) - >>> markdown2.markdown("*boo!*", ...) - <em>boo!</em> + >>> markdown2.markdown("*boo!*") # also markdown2.markdown_path(<path>) + u'<p><em>boo!</em></p>\n' - >>> markdowner = Markdown(...) + >>> markdowner = Markdown() >>> markdowner.convert("*boo!*") - <em>boo!</em> + u'<p><em>boo!</em></p>\n' >>> markdowner.convert("**boom!**") - <strong>boom!</strong> + u'<p><strong>boom!</strong></p>\n' This implementation of Markdown implements the full "core" syntax plus a number of extras (e.g., code syntax coloring, footnotes) as described on <http://code.google.com/p/python-markdown2/wiki/Extras>. """ cmdln_desc = """A fast and complete Python implementation of Markdown, a text-to-HTML conversion tool for web writers. """ @@ -118,21 +117,21 @@ safe_mode=safe_mode, extras=extras, link_patterns=link_patterns).convert(text) class Markdown(object): # The set of "extras" to enable in processing. This can be set # via (a) subclassing and (b) the constructor "extras" argument. extras = None urls = None titles = None - html_blocks = None + html_blocks = None # a HashTable instance html_spans = None html_removed_text = "[HTML_REMOVED]" # for compat with markdown.py # Used to track when we're inside an ordered or unordered list # (see _ProcessListItems() for details): list_level = 0 _ws_only_line_re = re.compile(r"^[ \t]+$", re.M) def __init__(self, html4tags=False, tab_width=4, safe_mode=None, @@ -157,21 +156,21 @@ self.extras = set(self.extras) if extras: self.extras.update(extras) self._instance_extra = self.extras.copy() self.link_patterns = link_patterns self._outdent_re = re.compile(r'^(\t|[ ]{1,%d})' % tab_width, re.M) def reset(self): self.urls = {} self.titles = {} - self.html_blocks = {} + self.html_blocks = HashTable() self.html_spans = {} self.list_level = 0 self.extras = self._instance_extra.copy() if "footnotes" in self.extras: self.footnotes = {} self.footnote_ids = [] def convert(self, text): """Convert the given text.""" # Main function. The order in which other subs are called here is @@ -206,20 +205,23 @@ # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ \t]*\n+/ . text = self._ws_only_line_re.sub("", text) if self.safe_mode: text = self._hash_html_spans(text) + if "mako" in self.extras: + text = self._hash_mako_blocks(text) + # Turn block-level HTML blocks into hash entries text = self._hash_html_blocks(text, raw=True) # Strip link definitions, store in hashes. if "footnotes" in self.extras: # Must do footnotes first because an unlucky footnote defn # looks like a link defn: # [^4]: this "looks like a link defn" text = self._strip_footnote_definitions(text) text = self._strip_link_definitions(text) @@ -404,23 +406,22 @@ [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) """ % _block_tags_b, re.X | re.M) def _hash_html_block_sub(self, match, raw=False): html = match.group(1) if raw and self.safe_mode: html = self._sanitize_html(html) - key = _hash_text(html) - self.html_blocks[key] = html - return "\n\n" + key + "\n\n" + hash = self.html_blocks.add(html) + return "\n\n" + hash + "\n\n" def _hash_html_blocks(self, text, raw=False): """Hashify HTML blocks We only want to do this for block-level HTML tags, such as headers, lists, and tables. That's because we still want to wrap <p>s around "paragraphs" that are wrapped in non-block-level tags, such as anchors, phrase emphasis, and spans. The list of tags we're looking for is hard-coded. @@ -455,20 +456,76 @@ _hr_tag_re = _hr_tag_re_from_tab_width(self.tab_width) text = _hr_tag_re.sub(hash_html_block_sub, text) # Special case for standalone HTML comments: if "<!--" in text: _html_comment_re = _html_comment_re_from_tab_width(self.tab_width) text = _html_comment_re.sub(hash_html_block_sub, text) return text + _mako_regexes = [ + # http://www.makotemplates.org/docs/syntax.html + # Ordering of these regexes is important. + + # Python Blocks + re.compile(r''' + <%!?\B.*?%> + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ''', re.M | re.S | re.X), + + # Tags + # - Block tags + re.compile(r''' + <%(def|call|doc|text)\b.*?> + .*? + </%\1> + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ''', re.M | re.S | re.X), + # - Single tag + re.compile(r''' + <%(page|include|namespace|inherit)\b.*?/> + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ''', re.M | re.S | re.X), + + # Control Structures + # Note: don't support "Newline Filters". + re.compile(r''' + ^[ \t]*%[ \t]*(for|if) + .*? + ^[ \t]*%[ \t]*end\1 + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ''', re.M | re.S | re.X), + + # Comments + # Note: don't support "Newline Filters". + re.compile(r'^[ \t]*##.*?$', re.M), + + # Expression Substitution + re.compile(r'\${.*?}'), + ] + + def _hash_mako_block_sub(self, match): + mako_block = match.group(0) + key = _hash_text(mako_block) + hash = self.html_blocks.add(mako_block) + return "\n\n" + hash + "\n\n" + + def _hash_mako_blocks(self, text): + for regex in self._mako_regexes: + text = regex.sub(self._hash_mako_block_sub, text) + return text + def _strip_link_definitions(self, text): # Strips link definitions from text, stores the URLs and titles in # hash references. less_than_tab = self.tab_width - 1 # Link defs are in the form: ^[id]: url "optional title" _link_def_re = re.compile(r""" ^[ ]{0,%d}\[(.+)\]: # id = \1 [ \t]* \n? # maybe *one* newline @@ -597,21 +654,21 @@ # Do hard breaks: text = re.sub(r" {2,}\n", " <br%s\n" % self.empty_element_suffix, text) return text # "Sorta" because auto-links are identified as "tag" tokens. _sorta_html_tokenize_re = re.compile(r""" ( # tag - </? + </? #TODO: append '%?' for Mako, how best to do this? (?:\w+) # tag name (?:\s+(?:[\w-]+:)?[\w-]+=(?:".*?"|'.*?'))* # attributes \s*/?> | # auto-link (e.g., <http://www.activestate.com/>) <\w+[^>]*> | <!--.*?--> # comment | <\?.*?\?> # processing instruction @@ -1227,21 +1284,21 @@ def _form_paragraphs(self, text): # Strip leading and trailing lines: text = text.strip('\n') # Wrap <p> tags. grafs = re.split(r"\n{2,}", text) for i, graf in enumerate(grafs): if graf in self.html_blocks: # Unhashify HTML blocks - grafs[i] = self.html_blocks[graf] + grafs[i] = self.html_blocks.unhash(graf) else: # Wrap <p> tags. graf = self._run_span_gamut(graf) grafs[i] = "<p>" + graf.lstrip(" \t") + "</p>" return "\n\n".join(grafs) def _add_footnotes(self, text): if self.footnotes: footer = [ @@ -1376,20 +1433,56 @@ - code-friendly: because it *disables* part of the syntax - link-patterns: because you need to specify some actual link-patterns anyway """ extras = ["footnotes", "code-color"] #---- internal support functions +class HashTable(dict): + """A table for mapping hashed versions of text. Basically + it is a {<hash>: <text>} dictionary with the .add() and .unhash() + convenience methods. + + >>> tbl = HashTable() + >>> hash = tbl.add("foo") + >>> hash + '!{hash}acbd18db4cc2f85cedef654fccc4a4d8!' + >>> hash in tbl + True + >>> tbl[hash] + 'foo' + >>> tbl.unhash("bar %s bar" % hash) + 'bar foo bar' + """ + def add(self, text): + hash = _hash_text(text) + self[hash] = text + return hash + + _hash_re = re.compile("!{hash}[0-9a-z]{32}!") + def _unhash_sub(self, match): + hash = match.group(0) + if hash in self: + return self.unhash(self[hash]) + else: + return hash + + def unhash(self, text): + if "!{hash}" not in text: + return text + return self._hash_re.sub(self._unhash_sub, text) + + + # From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 def _curry(*args, **kwargs): function, args = args[0], args[1:] def result(*rest, **kwrest): combined = kwargs.copy() combined.update(kwrest) return function(*args + rest, **combined) return result # Recipe: regex_from_encoded_pattern (1.0) @@ -1579,21 +1672,21 @@ # '@' *must* be encoded. I [John Gruber] insist. if r > 0.9 and ch != "@": return ch elif r < 0.45: # The [1:] is to drop leading '0': 0x63 -> x63 return '&#%s;' % hex(ord(ch))[1:] else: return '&#%s;' % ord(ch) def _hash_text(text): - return '!'+md5.md5(text.encode("utf-8")).hexdigest()+'!' + return '!{hash}'+md5.md5(text.encode("utf-8")).hexdigest()+'!' #---- mainline class _NoReflowFormatter(optparse.IndentedHelpFormatter): """An optparse formatter that does NOT reflow the description.""" def format_description(self, description): return description or "" def _test(): @@ -1668,18 +1761,17 @@ markdown_pl = join(dirname(__file__), "test", "Markdown.pl") for path in paths: if opts.compare: print "-- Markdown.pl" os.system('perl %s "%s"' % (markdown_pl, path)) print "-- markdown2.py" html = markdown_path(path, encoding=opts.encoding, html4tags=opts.html4tags, safe_mode=opts.safe_mode, extras=extras, link_patterns=link_patterns) - sys.stdout.write( - html.encode(sys.stdout.encoding, 'xmlcharrefreplace')) + sys.stdout.write(html.encode(sys.stdout.encoding, "xmlcharrefreplace")) if __name__ == "__main__": logging.basicConfig() sys.exit( main(sys.argv) ) ��������������������������������������������������������python-markdown2-2.4.1/sandbox/wiki.py��������������������������������������������������������������0000664�0000000�0000000�00000000726�14107073154�0017723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ import sys import re from os.path import * sys.path.insert(0, dirname(dirname(abspath(__file__)))) import markdown2 wiki_page = """ # This is my WikiPage! This is AnotherPage and YetAnotherPage. """ link_patterns = [ # Match a wiki page link LikeThis. (re.compile(r"(\b[A-Z][a-z]+[A-Z]\w+\b)"), r"/\1") ] processor = markdown2.Markdown(extras=["link-patterns"], link_patterns=link_patterns) print processor.convert(wiki_page) ������������������������������������������python-markdown2-2.4.1/setup.cfg��������������������������������������������������������������������0000664�0000000�0000000�00000000026�14107073154�0016562�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[wheel] universal = 1 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/setup.py���������������������������������������������������������������������0000775�0000000�0000000�00000003735�14107073154�0016470�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python import os import sys from setuptools import setup _top_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(_top_dir, "lib")) try: import markdown2 finally: del sys.path[0] classifiers = """\ Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: MIT License Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Operating System :: OS Independent Topic :: Software Development :: Libraries :: Python Modules Topic :: Software Development :: Documentation Topic :: Text Processing :: Filters Topic :: Text Processing :: Markup :: HTML """ script = (sys.platform == "win32" and "lib\\markdown2.py" or "bin/markdown2") setup( name="markdown2", version=markdown2.__version__, maintainer="Trent Mick", maintainer_email="trentm@gmail.com", author="Trent Mick", author_email="trentm@gmail.com", url="https://github.com/trentm/python-markdown2", license="MIT", platforms=["any"], py_modules=["markdown2"], package_dir={"": "lib"}, scripts=[script], description="A fast and complete Python implementation of Markdown", python_requires=">=3.5, <4", classifiers=classifiers.strip().split("\n"), long_description="""markdown2: A fast and complete Python implementation of Markdown. Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text format into HTML. Markdown's text format is most similar to that of plain text email, and supports features such as headers, *emphasis*, code blocks, blockquotes, and links. -- http://daringfireball.net/projects/markdown/ This is a fast and complete Python implementation of the Markdown spec. See http://github.com/trentm/python-markdown2 for more info. """, ) �����������������������������������python-markdown2-2.4.1/test/������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0015722�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/Markdown.pl�������������������������������������������������������������0000775�0000000�0000000�00000105446�14107073154�0020056�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl # # Markdown -- A text-to-HTML conversion tool for web writers # # Copyright (c) 2004 John Gruber # <http://daringfireball.net/projects/markdown/> # package Markdown; require 5.006_000; use strict; use warnings; use Digest::MD5 qw(md5_hex); use vars qw($VERSION); $VERSION = '1.0.1'; # Tue 14 Dec 2004 ## Disabled; causes problems under Perl 5.6.1: # use utf8; # binmode( STDOUT, ":utf8" ); # c.f.: http://acis.openlib.org/dev/perl-unicode-struggle.html # # Global default settings: # my $g_empty_element_suffix = " />"; # Change to ">" for HTML output my $g_tab_width = 4; # # Globals: # # Regex to match balanced [brackets]. See Friedl's # "Mastering Regular Expressions", 2nd Ed., pp. 328-331. my $g_nested_brackets; $g_nested_brackets = qr{ (?> # Atomic matching [^\[\]]+ # Anything other than brackets | \[ (??{ $g_nested_brackets }) # Recursive set of nested brackets \] )* }x; # Table of hash values for escaped characters: my %g_escape_table; foreach my $char (split //, '\\`*_{}[]()>#+-.!') { $g_escape_table{$char} = md5_hex($char); } # Global hashes, used by various utility routines my %g_urls; my %g_titles; my %g_html_blocks; # Used to track when we're inside an ordered or unordered list # (see _ProcessListItems() for details): my $g_list_level = 0; #### Blosxom plug-in interface ########################################## # Set $g_blosxom_use_meta to 1 to use Blosxom's meta plug-in to determine # which posts Markdown should process, using a "meta-markup: markdown" # header. If it's set to 0 (the default), Markdown will process all # entries. my $g_blosxom_use_meta = 0; sub start { 1; } sub story { my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_; if ( (! $g_blosxom_use_meta) or (defined($meta::markup) and ($meta::markup =~ /^\s*markdown\s*$/i)) ){ $$body_ref = Markdown($$body_ref); } 1; } #### Movable Type plug-in interface ##################################### eval {require MT}; # Test to see if we're running in MT. unless ($@) { require MT; import MT; require MT::Template::Context; import MT::Template::Context; eval {require MT::Plugin}; # Test to see if we're running >= MT 3.0. unless ($@) { require MT::Plugin; import MT::Plugin; my $plugin = new MT::Plugin({ name => "Markdown", description => "A plain-text-to-HTML formatting plugin. (Version: $VERSION)", doc_link => 'http://daringfireball.net/projects/markdown/' }); MT->add_plugin( $plugin ); } MT::Template::Context->add_container_tag(MarkdownOptions => sub { my $ctx = shift; my $args = shift; my $builder = $ctx->stash('builder'); my $tokens = $ctx->stash('tokens'); if (defined ($args->{'output'}) ) { $ctx->stash('markdown_output', lc $args->{'output'}); } defined (my $str = $builder->build($ctx, $tokens) ) or return $ctx->error($builder->errstr); $str; # return value }); MT->add_text_filter('markdown' => { label => 'Markdown', docs => 'http://daringfireball.net/projects/markdown/', on_format => sub { my $text = shift; my $ctx = shift; my $raw = 0; if (defined $ctx) { my $output = $ctx->stash('markdown_output'); if (defined $output && $output =~ m/^html/i) { $g_empty_element_suffix = ">"; $ctx->stash('markdown_output', ''); } elsif (defined $output && $output eq 'raw') { $raw = 1; $ctx->stash('markdown_output', ''); } else { $raw = 0; $g_empty_element_suffix = " />"; } } $text = $raw ? $text : Markdown($text); $text; }, }); # If SmartyPants is loaded, add a combo Markdown/SmartyPants text filter: my $smartypants; { no warnings "once"; $smartypants = $MT::Template::Context::Global_filters{'smarty_pants'}; } if ($smartypants) { MT->add_text_filter('markdown_with_smartypants' => { label => 'Markdown With SmartyPants', docs => 'http://daringfireball.net/projects/markdown/', on_format => sub { my $text = shift; my $ctx = shift; if (defined $ctx) { my $output = $ctx->stash('markdown_output'); if (defined $output && $output eq 'html') { $g_empty_element_suffix = ">"; } else { $g_empty_element_suffix = " />"; } } $text = Markdown($text); $text = $smartypants->($text, '1'); }, }); } } else { #### BBEdit/command-line text filter interface ########################## # Needs to be hidden from MT (and Blosxom when running in static mode). # We're only using $blosxom::version once; tell Perl not to warn us: no warnings 'once'; unless ( defined($blosxom::version) ) { use warnings; #### Check for command-line switches: ################# my %cli_opts; use Getopt::Long; Getopt::Long::Configure('pass_through'); GetOptions(\%cli_opts, 'version', 'shortversion', 'html4tags', ); if ($cli_opts{'version'}) { # Version info print "\nThis is Markdown, version $VERSION.\n"; print "Copyright 2004 John Gruber\n"; print "http://daringfireball.net/projects/markdown/\n\n"; exit 0; } if ($cli_opts{'shortversion'}) { # Just the version number string. print $VERSION; exit 0; } if ($cli_opts{'html4tags'}) { # Use HTML tag style instead of XHTML $g_empty_element_suffix = ">"; } #### Process incoming text: ########################### my $text; { local $/; # Slurp the whole file $text = <>; } print Markdown($text); } } sub Markdown { # # Main function. The order in which other subs are called here is # essential. Link and image substitutions need to happen before # _EscapeSpecialChars(), so that any *'s or _'s in the <a> # and <img> tags get encoded. # my $text = shift; # Clear the global hashes. If we don't clear these, you get conflicts # from other articles when generating a page which contains more than # one article (e.g. an index page that shows the N most recent # articles): %g_urls = (); %g_titles = (); %g_html_blocks = (); # Standardize line endings: $text =~ s{\r\n}{\n}g; # DOS to Unix $text =~ s{\r}{\n}g; # Mac to Unix # Make sure $text ends with a couple of newlines: $text .= "\n\n"; # Convert all tabs to spaces. $text = _Detab($text); # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ \t]*\n+/ . $text =~ s/^[ \t]+$//mg; # Turn block-level HTML blocks into hash entries $text = _HashHTMLBlocks($text); # Strip link definitions, store in hashes. $text = _StripLinkDefinitions($text); $text = _RunBlockGamut($text); $text = _UnescapeSpecialChars($text); return $text . "\n"; } sub _StripLinkDefinitions { # # Strips link definitions from text, stores the URLs and titles in # hash references. # my $text = shift; my $less_than_tab = $g_tab_width - 1; # Link defs are in the form: ^[id]: url "optional title" while ($text =~ s{ ^[ ]{0,$less_than_tab}\[(.+)\]: # id = $1 [ \t]* \n? # maybe *one* newline [ \t]* <?(\S+?)>? # url = $2 [ \t]* \n? # maybe one newline [ \t]* (?: (?<=\s) # lookbehind for whitespace ["(] (.+?) # title = $3 [")] [ \t]* )? # title is optional (?:\n+|\Z) } {}mx) { $g_urls{lc $1} = _EncodeAmpsAndAngles( $2 ); # Link IDs are case-insensitive if ($3) { $g_titles{lc $1} = $3; $g_titles{lc $1} =~ s/"/"/g; } } return $text; } sub _HashHTMLBlocks { my $text = shift; my $less_than_tab = $g_tab_width - 1; # Hashify HTML blocks: # We only want to do this for block-level HTML tags, such as headers, # lists, and tables. That's because we still want to wrap <p>s around # "paragraphs" that are wrapped in non-block-level tags, such as anchors, # phrase emphasis, and spans. The list of tags we're looking for is # hard-coded: my $block_tags_a = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del/; my $block_tags_b = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math/; # First, look for nested blocks, e.g.: # <div> # <div> # tags for inner block must be indented. # </div> # </div> # # The outermost tags must start at the left margin for this to match, and # the inner nested divs must be indented. # We need to do this before the next, more liberal match, because the next # match will start at the first `<div>` and stop at the first `</div>`. $text =~ s{ ( # save in $1 ^ # start of line (with /m) <($block_tags_a) # start tag = $2 \b # word break (.*\n)*? # any number of lines, minimally matching </\2> # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egmx; # # Now match more liberally, simply from `\n<tag>` to `</tag>\n` # $text =~ s{ ( # save in $1 ^ # start of line (with /m) <($block_tags_b) # start tag = $2 \b # word break (.*\n)*? # any number of lines, minimally matching .*</\2> # the matching end tag [ \t]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egmx; # Special case just for <hr />. It was easier to make a special case than # to make the other regex more complicated. $text =~ s{ (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 [ ]{0,$less_than_tab} <(hr) # start tag = $2 \b # word break ([^<>])*? # /?> # the matching end tag [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egx; # Special case for standalone HTML comments: $text =~ s{ (?: (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 [ ]{0,$less_than_tab} (?s: <! (--.*?--\s*)+ > ) [ \t]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) }{ my $key = md5_hex($1); $g_html_blocks{$key} = $1; "\n\n" . $key . "\n\n"; }egx; return $text; } sub _RunBlockGamut { # # These are all the transformations that form block-level # tags like paragraphs, headers, and list items. # my $text = shift; $text = _DoHeaders($text); # Do Horizontal Rules: $text =~ s{^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text =~ s{^[ ]{0,2}([ ]? -[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text =~ s{^[ ]{0,2}([ ]? _[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx; $text = _DoLists($text); $text = _DoCodeBlocks($text); $text = _DoBlockQuotes($text); # We already ran _HashHTMLBlocks() before, in Markdown(), but that # was to escape raw HTML in the original Markdown source. This time, # we're escaping the markup we've just created, so that we don't wrap # <p> tags around block-level tags. $text = _HashHTMLBlocks($text); $text = _FormParagraphs($text); return $text; } sub _RunSpanGamut { # # These are all the transformations that occur *within* block-level # tags like paragraphs, headers, and list items. # my $text = shift; $text = _DoCodeSpans($text); $text = _EscapeSpecialChars($text); # Process anchor and image tags. Images must come first, # because ![foo][f] looks like an anchor. $text = _DoImages($text); $text = _DoAnchors($text); # Make links out of things like `<http://example.com/>` # Must come after _DoAnchors(), because you can use < and > # delimiters in inline links like [this](<url>). $text = _DoAutoLinks($text); $text = _EncodeAmpsAndAngles($text); $text = _DoItalicsAndBold($text); # Do hard breaks: $text =~ s/ {2,}\n/ <br$g_empty_element_suffix\n/g; return $text; } sub _EscapeSpecialChars { my $text = shift; my $tokens ||= _TokenizeHTML($text); $text = ''; # rebuild $text from the tokens # my $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags. # my $tags_to_skip = qr!<(/?)(?:pre|code|kbd|script|math)[\s>]!; foreach my $cur_token (@$tokens) { if ($cur_token->[0] eq "tag") { # Within tags, encode * and _ so they don't conflict # with their use in Markdown for italics and strong. # We're replacing each such character with its # corresponding MD5 checksum value; this is likely # overkill, but it should prevent us from colliding # with the escape values by accident. $cur_token->[1] =~ s! \* !$g_escape_table{'*'}!gx; $cur_token->[1] =~ s! _ !$g_escape_table{'_'}!gx; $text .= $cur_token->[1]; } else { my $t = $cur_token->[1]; $t = _EncodeBackslashEscapes($t); $text .= $t; } } return $text; } sub _DoAnchors { # # Turn Markdown link shortcuts into XHTML <a> tags. # my $text = shift; # # First, handle reference-style links: [link text] [id] # $text =~ s{ ( # wrap whole match in $1 \[ ($g_nested_brackets) # link text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }{ my $result; my $whole_match = $1; my $link_text = $2; my $link_id = lc $3; if ($link_id eq "") { $link_id = lc $link_text; # for shortcut links like [this][]. } if (defined $g_urls{$link_id}) { my $url = $g_urls{$link_id}; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<a href=\"$url\""; if ( defined $g_titles{$link_id} ) { my $title = $g_titles{$link_id}; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= ">$link_text</a>"; } else { $result = $whole_match; } $result; }xsge; # # Next, inline-style links: [link text](url "optional title") # $text =~ s{ ( # wrap whole match in $1 \[ ($g_nested_brackets) # link text = $2 \] \( # literal paren [ \t]* <?(.*?)>? # href = $3 [ \t]* ( # $4 (['"]) # quote char = $5 (.*?) # Title = $6 \5 # matching quote )? # title is optional \) ) }{ my $result; my $whole_match = $1; my $link_text = $2; my $url = $3; my $title = $6; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<a href=\"$url\""; if (defined $title) { $title =~ s/"/"/g; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= ">$link_text</a>"; $result; }xsge; return $text; } sub _DoImages { # # Turn Markdown image shortcuts into <img> tags. # my $text = shift; # # First, handle reference-style labeled images: ![alt text][id] # $text =~ s{ ( # wrap whole match in $1 !\[ (.*?) # alt text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }{ my $result; my $whole_match = $1; my $alt_text = $2; my $link_id = lc $3; if ($link_id eq "") { $link_id = lc $alt_text; # for shortcut links like ![this][]. } $alt_text =~ s/"/"/g; if (defined $g_urls{$link_id}) { my $url = $g_urls{$link_id}; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<img src=\"$url\" alt=\"$alt_text\""; if (defined $g_titles{$link_id}) { my $title = $g_titles{$link_id}; $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= $g_empty_element_suffix; } else { # If there's no such link ID, leave intact: $result = $whole_match; } $result; }xsge; # # Next, handle inline images: ![alt text](url "optional title") # Don't forget: encode * and _ $text =~ s{ ( # wrap whole match in $1 !\[ (.*?) # alt text = $2 \] \( # literal paren [ \t]* <?(\S+?)>? # src url = $3 [ \t]* ( # $4 (['"]) # quote char = $5 (.*?) # title = $6 \5 # matching quote [ \t]* )? # title is optional \) ) }{ my $result; my $whole_match = $1; my $alt_text = $2; my $url = $3; my $title = ''; if (defined($6)) { $title = $6; } $alt_text =~ s/"/"/g; $title =~ s/"/"/g; $url =~ s! \* !$g_escape_table{'*'}!gx; # We've got to encode these to avoid $url =~ s! _ !$g_escape_table{'_'}!gx; # conflicting with italics/bold. $result = "<img src=\"$url\" alt=\"$alt_text\""; if (defined $title) { $title =~ s! \* !$g_escape_table{'*'}!gx; $title =~ s! _ !$g_escape_table{'_'}!gx; $result .= " title=\"$title\""; } $result .= $g_empty_element_suffix; $result; }xsge; return $text; } sub _DoHeaders { my $text = shift; # Setext-style headers: # Header 1 # ======== # # Header 2 # -------- # $text =~ s{ ^(.+)[ \t]*\n=+[ \t]*\n+ }{ "<h1>" . _RunSpanGamut($1) . "</h1>\n\n"; }egmx; $text =~ s{ ^(.+)[ \t]*\n-+[ \t]*\n+ }{ "<h2>" . _RunSpanGamut($1) . "</h2>\n\n"; }egmx; # atx-style headers: # # Header 1 # ## Header 2 # ## Header 2 with closing hashes ## # ... # ###### Header 6 # $text =~ s{ ^(\#{1,6}) # $1 = string of #'s [ \t]* (.+?) # $2 = Header text [ \t]* \#* # optional closing #'s (not counted) \n+ }{ my $h_level = length($1); "<h$h_level>" . _RunSpanGamut($2) . "</h$h_level>\n\n"; }egmx; return $text; } sub _DoLists { # # Form HTML ordered (numbered) and unordered (bulleted) lists. # my $text = shift; my $less_than_tab = $g_tab_width - 1; # Re-usable patterns to match list item bullets and number markers: my $marker_ul = qr/[*+-]/; my $marker_ol = qr/\d+[.]/; my $marker_any = qr/(?:$marker_ul|$marker_ol)/; # Re-usable pattern to match any entirel ul or ol list: my $whole_list = qr{ ( # $1 = whole list ( # $2 [ ]{0,$less_than_tab} (${marker_any}) # $3 = first list item marker [ \t]+ ) (?s:.+?) ( # $4 \z | \n{2,} (?=\S) (?! # Negative lookahead for another list item marker [ \t]* ${marker_any}[ \t]+ ) ) ) }mx; # We use a different prefix before nested lists than top-level lists. # See extended comment in _ProcessListItems(). # # Note: There's a bit of duplication here. My original implementation # created a scalar regex pattern as the conditional result of the test on # $g_list_level, and then only ran the $text =~ s{...}{...}egmx # substitution once, using the scalar as the pattern. This worked, # everywhere except when running under MT on my hosting account at Pair # Networks. There, this caused all rebuilds to be killed by the reaper (or # perhaps they crashed, but that seems incredibly unlikely given that the # same script on the same server ran fine *except* under MT. I've spent # more time trying to figure out why this is happening than I'd like to # admit. My only guess, backed up by the fact that this workaround works, # is that Perl optimizes the substition when it can figure out that the # pattern will never change, and when this optimization isn't on, we run # afoul of the reaper. Thus, the slightly redundant code to that uses two # static s/// patterns rather than one conditional pattern. if ($g_list_level) { $text =~ s{ ^ $whole_list }{ my $list = $1; my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: $list =~ s/\n{2,}/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "</$list_type>\n"; $result; }egmx; } else { $text =~ s{ (?:(?<=\n\n)|\A\n?) $whole_list }{ my $list = $1; my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: $list =~ s/\n{2,}/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "</$list_type>\n"; $result; }egmx; } return $text; } sub _ProcessListItems { # # Process the contents of a single ordered or unordered list, splitting it # into individual list items. # my $list_str = shift; my $marker_any = shift; # The $g_list_level global keeps track of when we're inside a list. # Each time we enter a list, we increment it; when we leave a list, # we decrement. If it's zero, we're not in a list anymore. # # We do this because when we're not inside a list, we want to treat # something like this: # # I recommend upgrading to version # 8. Oops, now this line is treated # as a sub-list. # # As a single paragraph, despite the fact that the second line starts # with a digit-period-space sequence. # # Whereas when we're inside a list (or sub-list), that line will be # treated as the start of a sub-list. What a kludge, huh? This is # an aspect of Markdown's syntax that's hard to parse perfectly # without resorting to mind-reading. Perhaps the solution is to # change the syntax rules such that sub-lists must start with a # starting cardinal number; e.g. "1." or "a.". $g_list_level++; # trim trailing blank lines: $list_str =~ s/\n{2,}\z/\n/; $list_str =~ s{ (\n)? # leading line = $1 (^[ \t]*) # leading whitespace = $2 ($marker_any) [ \t]+ # list marker = $3 ((?s:.+?) # list item text = $4 (\n{1,2})) (?= \n* (\z | \2 ($marker_any) [ \t]+)) }{ my $item = $4; my $leading_line = $1; my $leading_space = $2; if ($leading_line or ($item =~ m/\n{2,}/)) { $item = _RunBlockGamut(_Outdent($item)); } else { # Recursion for sub-lists: $item = _DoLists(_Outdent($item)); chomp $item; $item = _RunSpanGamut($item); } "<li>" . $item . "</li>\n"; }egmx; $g_list_level--; return $list_str; } sub _DoCodeBlocks { # # Process Markdown `<pre><code>` blocks. # my $text = shift; $text =~ s{ (?:\n\n|\A) ( # $1 = the code block -- one or more lines, starting with a space/tab (?: (?:[ ]{$g_tab_width} | \t) # Lines must start with a tab or a tab-width of spaces .*\n+ )+ ) ((?=^[ ]{0,$g_tab_width}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }{ my $codeblock = $1; my $result; # return value $codeblock = _EncodeCode(_Outdent($codeblock)); $codeblock = _Detab($codeblock); $codeblock =~ s/\A\n+//; # trim leading newlines $codeblock =~ s/\s+\z//; # trim trailing whitespace $result = "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n"; $result; }egmx; return $text; } sub _DoCodeSpans { # # * Backtick quotes are used for <code></code> spans. # # * You can use multiple backticks as the delimiters if you want to # include literal backticks in the code span. So, this input: # # Just type ``foo `bar` baz`` at the prompt. # # Will translate to: # # <p>Just type <code>foo `bar` baz</code> at the prompt.</p> # # There's no arbitrary limit to the number of backticks you # can use as delimters. If you need three consecutive backticks # in your code, use four for delimiters, etc. # # * You can use spaces to get literal backticks at the edges: # # ... type `` `bar` `` ... # # Turns to: # # ... type <code>`bar`</code> ... # my $text = shift; $text =~ s@ (`+) # $1 = Opening run of ` (.+?) # $2 = The code block (?<!`) \1 # Matching closer (?!`) @ my $c = "$2"; $c =~ s/^[ \t]*//g; # leading whitespace $c =~ s/[ \t]*$//g; # trailing whitespace $c = _EncodeCode($c); "<code>$c</code>"; @egsx; return $text; } sub _EncodeCode { # # Encode/escape certain characters inside Markdown code runs. # The point is that in code, these characters are literals, # and lose their special Markdown meanings. # local $_ = shift; # Encode all ampersands; HTML entities are not # entities within a Markdown code span. s/&/&/g; # Encode $'s, but only if we're running under Blosxom. # (Blosxom interpolates Perl variables in article bodies.) { no warnings 'once'; if (defined($blosxom::version)) { s/\$/$/g; } } # Do the angle bracket song and dance: s! < !<!gx; s! > !>!gx; # Now, escape characters that are magic in Markdown: s! \* !$g_escape_table{'*'}!gx; s! _ !$g_escape_table{'_'}!gx; s! { !$g_escape_table{'{'}!gx; s! } !$g_escape_table{'}'}!gx; s! \[ !$g_escape_table{'['}!gx; s! \] !$g_escape_table{']'}!gx; s! \\ !$g_escape_table{'\\'}!gx; return $_; } sub _DoItalicsAndBold { my $text = shift; # <strong> must go first: $text =~ s{ (\*\*|__) (?=\S) (.+?[*_]*) (?<=\S) \1 } {<strong>$2</strong>}gsx; $text =~ s{ (\*|_) (?=\S) (.+?) (?<=\S) \1 } {<em>$2</em>}gsx; return $text; } sub _DoBlockQuotes { my $text = shift; $text =~ s{ ( # Wrap whole match in $1 ( ^[ \t]*>[ \t]? # '>' at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines \n* # blanks )+ ) }{ my $bq = $1; $bq =~ s/^[ \t]*>[ \t]?//gm; # trim one level of quoting $bq =~ s/^[ \t]+$//mg; # trim whitespace-only lines $bq = _RunBlockGamut($bq); # recurse $bq =~ s/^/ /g; # These leading spaces screw with <pre> content, so we need to fix that: $bq =~ s{ (\s*<pre>.+?</pre>) }{ my $pre = $1; $pre =~ s/^ //mg; $pre; }egsx; "<blockquote>\n$bq\n</blockquote>\n\n"; }egmx; return $text; } sub _FormParagraphs { # # Params: # $text - string to process with html <p> tags # my $text = shift; # Strip leading and trailing lines: $text =~ s/\A\n+//; $text =~ s/\n+\z//; my @grafs = split(/\n{2,}/, $text); # # Wrap <p> tags. # foreach (@grafs) { unless (defined( $g_html_blocks{$_} )) { $_ = _RunSpanGamut($_); s/^([ \t]*)/<p>/; $_ .= "</p>"; } } # # Unhashify HTML blocks # foreach (@grafs) { if (defined( $g_html_blocks{$_} )) { $_ = $g_html_blocks{$_}; } } return join "\n\n", @grafs; } sub _EncodeAmpsAndAngles { # Smart processing for ampersands and angle brackets that need to be encoded. my $text = shift; # Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: # http://bumppo.net/projects/amputator/ $text =~ s/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/&/g; # Encode naked <'s $text =~ s{<(?![a-z/?\$!])}{<}gi; return $text; } sub _EncodeBackslashEscapes { # # Parameter: String. # Returns: The string, with after processing the following backslash # escape sequences. # local $_ = shift; s! \\\\ !$g_escape_table{'\\'}!gx; # Must process escaped backslashes first. s! \\` !$g_escape_table{'`'}!gx; s! \\\* !$g_escape_table{'*'}!gx; s! \\_ !$g_escape_table{'_'}!gx; s! \\\{ !$g_escape_table{'{'}!gx; s! \\\} !$g_escape_table{'}'}!gx; s! \\\[ !$g_escape_table{'['}!gx; s! \\\] !$g_escape_table{']'}!gx; s! \\\( !$g_escape_table{'('}!gx; s! \\\) !$g_escape_table{')'}!gx; s! \\> !$g_escape_table{'>'}!gx; s! \\\# !$g_escape_table{'#'}!gx; s! \\\+ !$g_escape_table{'+'}!gx; s! \\\- !$g_escape_table{'-'}!gx; s! \\\. !$g_escape_table{'.'}!gx; s{ \\! }{$g_escape_table{'!'}}gx; return $_; } sub _DoAutoLinks { my $text = shift; $text =~ s{<((https?|ftp):[^'">\s]+)>}{<a href="$1">$1</a>}gi; # Email addresses: <address@domain.foo> $text =~ s{ < (?:mailto:)? ( [-.\w]+ \@ [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ ) > }{ _EncodeEmailAddress( _UnescapeSpecialChars($1) ); }egix; return $text; } sub _EncodeEmailAddress { # # Input: an email address, e.g. "foo@example.com" # # Output: the email address as a mailto link, with each character # of the address encoded as either a decimal or hex entity, in # the hopes of foiling most address harvesting spam bots. E.g.: # # <a href="mailto:foo@e # xample.com">foo # @example.com</a> # # Based on a filter by Matthew Wickline, posted to the BBEdit-Talk # mailing list: <http://tinyurl.com/yu7ue> # my $addr = shift; srand; my @encode = ( sub { '&#' . ord(shift) . ';' }, sub { '&#x' . sprintf( "%X", ord(shift) ) . ';' }, sub { shift }, ); $addr = "mailto:" . $addr; $addr =~ s{(.)}{ my $char = $1; if ( $char eq '@' ) { # this *must* be encoded. I insist. $char = $encode[int rand 1]->($char); } elsif ( $char ne ':' ) { # leave ':' alone (to spot mailto: later) my $r = rand; # roughly 10% raw, 45% hex, 45% dec $char = ( $r > .9 ? $encode[2]->($char) : $r < .45 ? $encode[1]->($char) : $encode[0]->($char) ); } $char; }gex; $addr = qq{<a href="$addr">$addr</a>}; $addr =~ s{">.+?:}{">}; # strip the mailto: from the visible part return $addr; } sub _UnescapeSpecialChars { # # Swap back in all the special characters we've hidden. # my $text = shift; while( my($char, $hash) = each(%g_escape_table) ) { $text =~ s/$hash/$char/g; } return $text; } sub _TokenizeHTML { # # Parameter: String containing HTML markup. # Returns: Reference to an array of the tokens comprising the input # string. Each token is either a tag (possibly with nested, # tags contained therein, such as <a href="<MTFoo>">, or a # run of text between tags. Each element of the array is a # two-element array; the first is either 'tag' or 'text'; # the second is the actual value. # # # Derived from the _tokenize() subroutine from Brad Choate's MTRegex plugin. # <http://www.bradchoate.com/past/mtregex.php> # my $str = shift; my $pos = 0; my $len = length $str; my @tokens; my $depth = 6; my $nested_tags = join('|', ('(?:<[a-z/!$](?:[^<>]') x $depth) . (')*>)' x $depth); my $match = qr/(?s: <! ( -- .*? -- \s* )+ > ) | # comment (?s: <\? .*? \?> ) | # processing instruction $nested_tags/ix; # nested tags while ($str =~ m/($match)/g) { my $whole_tag = $1; my $sec_start = pos $str; my $tag_start = $sec_start - length $whole_tag; if ($pos < $tag_start) { push @tokens, ['text', substr($str, $pos, $tag_start - $pos)]; } push @tokens, ['tag', $whole_tag]; $pos = pos $str; } push @tokens, ['text', substr($str, $pos, $len - $pos)] if $pos < $len; \@tokens; } sub _Outdent { # # Remove one level of line-leading tabs or spaces # my $text = shift; $text =~ s/^(\t|[ ]{1,$g_tab_width})//gm; return $text; } sub _Detab { # # Cribbed from a post by Bart Lateur: # <http://www.nntp.perl.org/group/perl.macperl.anyperl/154> # my $text = shift; $text =~ s{(.*?)\t}{$1.(' ' x ($g_tab_width - length($1) % $g_tab_width))}ge; return $text; } 1; __END__ =pod =head1 NAME B<Markdown> =head1 SYNOPSIS B<Markdown.pl> [ B<--html4tags> ] [ B<--version> ] [ B<-shortversion> ] [ I<file> ... ] =head1 DESCRIPTION Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text format into HTML. Markdown's text format is most similar to that of plain text email, and supports features such as headers, *emphasis*, code blocks, blockquotes, and links. Markdown's syntax is designed not as a generic markup language, but specifically to serve as a front-end to (X)HTML. You can use span-level HTML tags anywhere in a Markdown document, and you can use block level HTML tags (like <div> and <table> as well). For more information about Markdown's syntax, see: http://daringfireball.net/projects/markdown/ =head1 OPTIONS Use "--" to end switch parsing. For example, to open a file named "-z", use: Markdown.pl -- -z =over 4 =item B<--html4tags> Use HTML 4 style for empty element tags, e.g.: <br> instead of Markdown's default XHTML style tags, e.g.: <br /> =item B<-v>, B<--version> Display Markdown's version number and copyright information. =item B<-s>, B<--shortversion> Display the short-form version number. =back =head1 BUGS To file bug reports or feature requests (other than topics listed in the Caveats section above) please send email to: support@daringfireball.net Please include with your report: (1) the example input; (2) the output you expected; (3) the output Markdown actually produced. =head1 VERSION HISTORY See the readme file for detailed release notes for this version. 1.0.1 - 14 Dec 2004 1.0 - 28 Aug 2004 =head1 AUTHOR John Gruber http://daringfireball.net PHP port and other contributions by Michel Fortin http://michelf.com =head1 COPYRIGHT AND LICENSE Copyright (c) 2003-2004 John Gruber <http://daringfireball.net/> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. =cut ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/README.md���������������������������������������������������������������0000664�0000000�0000000�00000007743�14107073154�0017214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This directory holds test suite. There are a number of test sets, each in its own directory: - **tm-cases**: Cases I wrote while writing markdown2.py. Many of these are very small bits of text testing a specific part of the Markdown syntax. - **markdowntest-cases**: The test cases from the [MarkdownTest_1.0.zip package announce on the markdown-discuss list](http://six.pairlist.net/pipermail/markdown-discuss/2004-December/000909.html). - **php-markdown-cases**: Test cases included in the MDTest package [announce on markdow-discuss in July 2007](http://six.pairlist.net/pipermail/markdown-discuss/2007-July/000674.html). - **php-markdown-extra-cases**: Test cases included in the MDTest package (same as above) testing extra Markdown syntax that only PHP Markdown implements. # markdown2.py test results To run the test suite: python test.py [TAGS...] The test driver used (testlib.py) allows one to filter the tests run via short strings that identify specific or groups of tests. Run `python test.py -l` to list all available tests and their names/tags. I use the "knownfailure" tag to mark those tests that I know fail (e.g. the `php-markdown-extra-cases` all fail because markdown2.py doesn't implement those additions to the Markdown syntax). To run the test suite **without** the known failures: $ python test.py -- -knownfailure markdown2/tm/auto_link ... ok markdown2/tm/blockquote ... ok markdown2/tm/blockquote_with_pre ... ok markdown2/tm/code_block_with_tabs [fromphpmarkdown] ... ok markdown2/tm/code_safe_emphasis [code_safe] ... ok markdown2/tm/codeblock ... ok markdown2/tm/codespans ... ok markdown2/tm/emphasis ... ok markdown2/tm/escapes ... ok markdown2/tm/header ... ok markdown2/tm/hr ... ok markdown2/tm/inline_links ... ok markdown2/tm/lists ... ok markdown2/tm/nested_list ... ok markdown2/tm/parens_in_url_4 [fromphpmarkdown] ... ok markdown2/tm/raw_html ... ok markdown2/tm/ref_links ... ok markdown2/tm/safe_mode ... ok markdown2/tm/sublist-para [questionable] ... ok markdown2/tm/tricky_anchors ... ok markdown2/tm/underline_in_autolink ... ok markdown2/markdowntest/amps_and_angle_encoding ... ok markdown2/markdowntest/auto_links ... ok markdown2/markdowntest/backslash_escapes ... ok markdown2/markdowntest/blockquotes_with_code_blocks ... ok markdown2/markdowntest/hard-wrapped_paragraphs_with_list-like_lines ... ok markdown2/markdowntest/horizontal_rules ... ok markdown2/markdowntest/inline_html_simple ... ok markdown2/markdowntest/inline_html_comments ... ok markdown2/markdowntest/links_inline_style ... ok markdown2/markdowntest/links_reference_style ... ok markdown2/markdowntest/literal_quotes_in_titles ... ok markdown2/markdowntest/markdown_documentation_basics ... ok markdown2/markdowntest/markdown_documentation_syntax ... ok markdown2/markdowntest/nested_blockquotes ... ok markdown2/markdowntest/ordered_and_unordered_lists ... ok markdown2/markdowntest/strong_and_em_together ... ok markdown2/markdowntest/tabs ... ok markdown2/phpmarkdown/backslash_escapes ... ok markdown2/phpmarkdown/code_spans ... ok markdown2/phpmarkdown/email_auto_links ... ok markdown2/phpmarkdown/headers ... ok markdown2/phpmarkdown/images_untitled ... ok markdown2/phpmarkdown/inline_html_comments ... ok markdown2/phpmarkdown/ins_&_del ... ok markdown2/phpmarkdown/links_inline_style ... ok markdown2/phpmarkdown/md5_hashes ... ok markdown2/phpmarkdown/php-specific_bugs ... ok markdown2/phpmarkdown/tight_blocks ... ok markdown2/direct/code_in_strong [code, strong] ... ok markdown2/direct/pre ... ok markdown2/direct/starter_pre [pre, recipes] ... ok ---------------------------------------------------------------------- Ran 52 tests in 0.799s OK TODO: Add details about which tests in the various test sets that markdown2.py fails... and why I'm not concerned about them. �����������������������������python-markdown2-2.4.1/test/api.doctests������������������������������������������������������������0000664�0000000�0000000�00000000543�14107073154�0020247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ >>> import markdown2 >>> hasattr(markdown2, "__version__") True >>> hasattr(markdown2, "__version_info__") True >>> str( markdown2.markdown("*boo*") ) '<p><em>boo</em></p>\n' >>> m = markdown2.Markdown() >>> str( m.convert("*boo*") ) '<p><em>boo</em></p>\n' >>> m = markdown2.MarkdownWithExtras() >>> str( m.convert("*boo*") ) '<p><em>boo</em></p>\n' �������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdown.php������������������������������������������������������������0000664�0000000�0000000�00000124433�14107073154�0020264�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php # # Markdown - A text-to-HTML conversion tool for web writers # # PHP Markdown # Copyright (c) 2004-2007 Michel Fortin # <http://www.michelf.com/projects/php-markdown/> # # Original Markdown # Copyright (c) 2004-2006 John Gruber # <http://daringfireball.net/projects/markdown/> # define( 'MARKDOWN_VERSION', "1.0.1j" ); # Tue 4 Sep 2007 # # Global default settings: # # Change to ">" for HTML output @define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />"); # Define the width of a tab for code blocks. @define( 'MARKDOWN_TAB_WIDTH', 4 ); # # WordPress settings: # # Change to false to remove Markdown from posts and/or comments. @define( 'MARKDOWN_WP_POSTS', true ); @define( 'MARKDOWN_WP_COMMENTS', true ); ### Standard Function Interface ### @define( 'MARKDOWN_PARSER_CLASS', 'Markdown_Parser' ); function Markdown($text) { # # Initialize the parser and return the result of its transform method. # # Setup static parser variable. static $parser; if (!isset($parser)) { $parser_class = MARKDOWN_PARSER_CLASS; $parser = new $parser_class; } # Transform text using parser. return $parser->transform($text); } ### WordPress Plugin Interface ### /* Plugin Name: Markdown Plugin URI: http://www.michelf.com/projects/php-markdown/ Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a> Version: 1.0.1j Author: Michel Fortin Author URI: http://www.michelf.com/ */ if (isset($wp_version)) { # More details about how it works here: # <http://www.michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/> # Post content and excerpts # - Remove WordPress paragraph generator. # - Run Markdown on excerpt, then remove all tags. # - Add paragraph tag around the excerpt, but remove it for the excerpt rss. if (MARKDOWN_WP_POSTS) { remove_filter('the_content', 'wpautop'); remove_filter('the_content_rss', 'wpautop'); remove_filter('the_excerpt', 'wpautop'); add_filter('the_content', 'Markdown', 6); add_filter('the_content_rss', 'Markdown', 6); add_filter('get_the_excerpt', 'Markdown', 6); add_filter('get_the_excerpt', 'trim', 7); add_filter('the_excerpt', 'mdwp_add_p'); add_filter('the_excerpt_rss', 'mdwp_strip_p'); remove_filter('content_save_pre', 'balanceTags', 50); remove_filter('excerpt_save_pre', 'balanceTags', 50); add_filter('the_content', 'balanceTags', 50); add_filter('get_the_excerpt', 'balanceTags', 9); } # Comments # - Remove WordPress paragraph generator. # - Remove WordPress auto-link generator. # - Scramble important tags before passing them to the kses filter. # - Run Markdown on excerpt then remove paragraph tags. if (MARKDOWN_WP_COMMENTS) { remove_filter('comment_text', 'wpautop', 30); remove_filter('comment_text', 'make_clickable'); add_filter('pre_comment_content', 'Markdown', 6); add_filter('pre_comment_content', 'mdwp_hide_tags', 8); add_filter('pre_comment_content', 'mdwp_show_tags', 12); add_filter('get_comment_text', 'Markdown', 6); add_filter('get_comment_excerpt', 'Markdown', 6); add_filter('get_comment_excerpt', 'mdwp_strip_p', 7); global $mdwp_hidden_tags, $mdwp_placeholders; $mdwp_hidden_tags = explode(' ', '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>'); $mdwp_placeholders = explode(' ', str_rot13( 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '. 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli')); } function mdwp_add_p($text) { if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) { $text = '<p>'.$text.'</p>'; $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text); } return $text; } function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); } function mdwp_hide_tags($text) { global $mdwp_hidden_tags, $mdwp_placeholders; return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text); } function mdwp_show_tags($text) { global $mdwp_hidden_tags, $mdwp_placeholders; return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text); } } ### bBlog Plugin Info ### function identify_modifier_markdown() { return array( 'name' => 'markdown', 'type' => 'modifier', 'nicename' => 'Markdown', 'description' => 'A text-to-HTML conversion tool for web writers', 'authors' => 'Michel Fortin and John Gruber', 'licence' => 'BSD-like', 'version' => MARKDOWN_VERSION, 'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a>' ); } ### Smarty Modifier Interface ### function smarty_modifier_markdown($text) { return Markdown($text); } ### Textile Compatibility Mode ### # Rename this file to "classTextile.php" and it can replace Textile everywhere. if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) { # Try to include PHP SmartyPants. Should be in the same directory. @include_once 'smartypants.php'; # Fake Textile class. It calls Markdown instead. class Textile { function TextileThis($text, $lite='', $encode='') { if ($lite == '' && $encode == '') $text = Markdown($text); if (function_exists('SmartyPants')) $text = SmartyPants($text); return $text; } # Fake restricted version: restrictions are not supported for now. function TextileRestricted($text, $lite='', $noimage='') { return $this->TextileThis($text, $lite); } # Workaround to ensure compatibility with TextPattern 4.0.3. function blockLite($text) { return $text; } } } # # Markdown Parser Class # class Markdown_Parser { # Regex to match balanced [brackets]. # Needed to insert a maximum bracked depth while converting to PHP. var $nested_brackets_depth = 6; var $nested_brackets; var $nested_url_parenthesis_depth = 4; var $nested_url_parenthesis; # Table of hash values for escaped characters: var $escape_chars = '\`*_{}[]()>#+-.!'; # Change to ">" for HTML output. var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX; var $tab_width = MARKDOWN_TAB_WIDTH; # Change to `true` to disallow markup or entities. var $no_markup = false; var $no_entities = false; function Markdown_Parser() { # # Constructor function. Initialize appropriate member variables. # $this->_initDetab(); $this->nested_brackets = str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). str_repeat('\])*', $this->nested_brackets_depth); $this->nested_url_parenthesis = str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); # Sort document, block, and span gamut in ascendent priority order. asort($this->document_gamut); asort($this->block_gamut); asort($this->span_gamut); } # Internal hashes used during transformation. var $urls = array(); var $titles = array(); var $html_hashes = array(); # Status flag to avoid invalid nesting. var $in_anchor = false; function transform($text) { # # Main function. The order in which other subs are called here is # essential. Link and image substitutions need to happen before # _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a> # and <img> tags get encoded. # # Clear the global hashes. If we don't clear these, you get conflicts # from other articles when generating a page which contains more than # one article (e.g. an index page that shows the N most recent # articles): $this->urls = array(); $this->titles = array(); $this->html_hashes = array(); # Standardize line endings: # DOS to Unix and Mac to Unix $text = preg_replace('{\r\n?}', "\n", $text); # Make sure $text ends with a couple of newlines: $text .= "\n\n"; # Convert all tabs to spaces. $text = $this->detab($text); # Turn block-level HTML blocks into hash entries $text = $this->hashHTMLBlocks($text); # Strip any lines consisting only of spaces and tabs. # This makes subsequent regexen easier to write, because we can # match consecutive blank lines with /\n+/ instead of something # contorted like /[ ]*\n+/ . $text = preg_replace('/^[ ]+$/m', '', $text); # Run document gamut methods. foreach ($this->document_gamut as $method => $priority) { $text = $this->$method($text); } return $text . "\n"; } var $document_gamut = array( # Strip link definitions, store in hashes. "stripLinkDefinitions" => 20, "runBasicBlockGamut" => 30, ); function stripLinkDefinitions($text) { # # Strips link definitions from text, stores the URLs and titles in # hash references. # $less_than_tab = $this->tab_width - 1; # Link defs are in the form: ^[id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 [ ]* \n? # maybe *one* newline [ ]* <?(\S+?)>? # url = $2 [ ]* \n? # maybe one newline [ ]* (?: (?<=\s) # lookbehind for whitespace ["(] (.*?) # title = $3 [")] [ ]* )? # title is optional (?:\n+|\Z) }xm', array(&$this, '_stripLinkDefinitions_callback'), $text); return $text; } function _stripLinkDefinitions_callback($matches) { $link_id = strtolower($matches[1]); $this->urls[$link_id] = $this->encodeAmpsAndAngles($matches[2]); if (isset($matches[3])) $this->titles[$link_id] = str_replace('"', '"', $matches[3]); return ''; # String that will replace the block } function hashHTMLBlocks($text) { if ($this->no_markup) return $text; $less_than_tab = $this->tab_width - 1; # Hashify HTML blocks: # We only want to do this for block-level HTML tags, such as headers, # lists, and tables. That's because we still want to wrap <p>s around # "paragraphs" that are wrapped in non-block-level tags, such as anchors, # phrase emphasis, and spans. The list of tags we're looking for is # hard-coded: # # * List "a" is made of tags which can be both inline or block-level. # These will be treated block-level when the start tag is alone on # its line, otherwise they're not matched here and will be taken as # inline later. # * List "b" is made of tags which are always block-level; # $block_tags_a = 'ins|del'; $block_tags_b = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. 'script|noscript|form|fieldset|iframe|math'; # Regular expression for the content of a block tag. $nested_tags_level = 4; $attr = ' (?> # optional tag attributes \s # starts with whitespace (?> [^>"/]+ # text outside quotes | /+(?!>) # slash not followed by ">" | "[^"]*" # text inside double quotes (tolerate ">") | \'[^\']*\' # text inside single quotes (tolerate ">") )* )? '; $content = str_repeat(' (?> [^<]+ # content without tag | <\2 # nested opening tag '.$attr.' # attributes (?> /> | >', $nested_tags_level). # end of opening tag '.*?'. # last level nested tag content str_repeat(' </\2\s*> # closing nested tag ) | <(?!/\2\s*> # other tags with a different name ) )*', $nested_tags_level); $content2 = str_replace('\2', '\3', $content); # First, look for nested blocks, e.g.: # <div> # <div> # tags for inner block must be indented. # </div> # </div> # # The outermost tags must start at the left margin for this to match, and # the inner nested divs must be indented. # We need to do this before the next, more liberal match, because the next # match will start at the first `<div>` and stop at the first `</div>`. $text = preg_replace_callback('{(?> (?> (?<=\n\n) # Starting after a blank line | # or \A\n? # the beginning of the doc ) ( # save in $1 # Match from `\n<tag>` to `</tag>\n`, handling nested tags # in between. [ ]{0,'.$less_than_tab.'} <('.$block_tags_b.')# start tag = $2 '.$attr.'> # attributes followed by > and \n '.$content.' # content, support nesting </\2> # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document | # Special version for tags of group a. [ ]{0,'.$less_than_tab.'} <('.$block_tags_a.')# start tag = $3 '.$attr.'>[ ]*\n # attributes followed by > '.$content2.' # content, support nesting </\3> # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document | # Special case just for <hr />. It was easier to make a special # case than to make the other regex more complicated. [ ]{0,'.$less_than_tab.'} <(hr) # start tag = $2 \b # word break ([^<>])*? # /?> # the matching end tag [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document | # Special case for standalone HTML comments: [ ]{0,'.$less_than_tab.'} (?s: <!-- .*? --> ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document | # PHP and ASP-style processor instructions (<? and <%) [ ]{0,'.$less_than_tab.'} (?s: <([?%]) # $2 .*? \2> ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document ) )}Sxmi', array(&$this, '_hashHTMLBlocks_callback'), $text); return $text; } function _hashHTMLBlocks_callback($matches) { $text = $matches[1]; $key = $this->hashBlock($text); return "\n\n$key\n\n"; } function hashPart($text, $boundary = 'X') { # # Called whenever a tag must be hashed when a function insert an atomic # element in the text stream. Passing $text to through this function gives # a unique text-token which will be reverted back when calling unhash. # # The $boundary argument specify what character should be used to surround # the token. By convension, "B" is used for block elements that needs not # to be wrapped into paragraph tags at the end, ":" is used for elements # that are word separators and "S" is used for general span-level elements. # # Swap back any tag hash found in $text so we do not have to `unhash` # multiple times at the end. $text = $this->unhash($text); # Then hash the block. static $i = 0; $key = "$boundary\x1A" . ++$i . $boundary; $this->html_hashes[$key] = $text; return $key; # String that will replace the tag. } function hashBlock($text) { # # Shortcut function for hashPart with block-level boundaries. # return $this->hashPart($text, 'B'); } var $block_gamut = array( # # These are all the transformations that form block-level # tags like paragraphs, headers, and list items. # "doHeaders" => 10, "doHorizontalRules" => 20, "doLists" => 40, "doCodeBlocks" => 50, "doBlockQuotes" => 60, ); function runBlockGamut($text) { # # Run block gamut tranformations. # # We need to escape raw HTML in Markdown source before doing anything # else. This need to be done for each block, and not only at the # begining in the Markdown function since hashed blocks can be part of # list items and could have been indented. Indented blocks would have # been seen as a code block in a previous pass of hashHTMLBlocks. $text = $this->hashHTMLBlocks($text); return $this->runBasicBlockGamut($text); } function runBasicBlockGamut($text) { # # Run block gamut tranformations, without hashing HTML blocks. This is # useful when HTML blocks are known to be already hashed, like in the first # whole-document pass. # foreach ($this->block_gamut as $method => $priority) { $text = $this->$method($text); } # Finally form paragraph and restore hashed blocks. $text = $this->formParagraphs($text); return $text; } function doHorizontalRules($text) { # Do Horizontal Rules: return preg_replace( '{ ^[ ]{0,3} # Leading space ([*-_]) # $1: First marker (?> # Repeated marker group [ ]{0,2} # Zero, one, or two spaces. \1 # Marker character ){2,} # Group repeated at least twice [ ]* # Tailing spaces $ # End of line. }mx', "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n", $text); } var $span_gamut = array( # # These are all the transformations that occur *within* block-level # tags like paragraphs, headers, and list items. # # Process character escapes, code spans, and inline HTML # in one shot. "parseSpan" => -30, # Process anchor and image tags. Images must come first, # because ![foo][f] looks like an anchor. "doImages" => 10, "doAnchors" => 20, # Make links out of things like `<http://example.com/>` # Must come after doAnchors, because you can use < and > # delimiters in inline links like [this](<url>). "doAutoLinks" => 30, "encodeAmpsAndAngles" => 40, "doItalicsAndBold" => 50, "doHardBreaks" => 60, ); function runSpanGamut($text) { # # Run span gamut tranformations. # foreach ($this->span_gamut as $method => $priority) { $text = $this->$method($text); } return $text; } function doHardBreaks($text) { # Do hard breaks: return preg_replace_callback('/ {2,}\n/', array(&$this, '_doHardBreaks_callback'), $text); } function _doHardBreaks_callback($matches) { return $this->hashPart("<br$this->empty_element_suffix\n"); } function doAnchors($text) { # # Turn Markdown link shortcuts into XHTML <a> tags. # if ($this->in_anchor) return $text; $this->in_anchor = true; # # First, handle reference-style links: [link text] [id] # $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ ('.$this->nested_brackets.') # link text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }xs', array(&$this, '_doAnchors_reference_callback'), $text); # # Next, inline-style links: [link text](url "optional title") # $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ ('.$this->nested_brackets.') # link text = $2 \] \( # literal paren [ ]* (?: <(\S*)> # href = $3 | ('.$this->nested_url_parenthesis.') # href = $4 ) [ ]* ( # $5 ([\'"]) # quote char = $6 (.*?) # Title = $7 \6 # matching quote [ ]* # ignore any spaces/tabs between closing quote and ) )? # title is optional \) ) }xs', array(&$this, '_DoAnchors_inline_callback'), $text); # # Last, handle reference-style shortcuts: [link text] # These must come last in case you've also got [link test][1] # or [link test](/foo) # // $text = preg_replace_callback('{ // ( # wrap whole match in $1 // \[ // ([^\[\]]+) # link text = $2; can\'t contain [ or ] // \] // ) // }xs', // array(&$this, '_doAnchors_reference_callback'), $text); $this->in_anchor = false; return $text; } function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $link_text = $matches[2]; $link_id =& $matches[3]; if ($link_id == "") { # for shortcut links like [this][] or [this]. $link_id = $link_text; } # lower-case and turn embedded newlines into spaces $link_id = strtolower($link_id); $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $url = $this->encodeAmpsAndAngles($url); $result = "<a href=\"$url\""; if ( isset( $this->titles[$link_id] ) ) { $title = $this->titles[$link_id]; $title = $this->encodeAmpsAndAngles($title); $result .= " title=\"$title\""; } $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text</a>"; $result = $this->hashPart($result); } else { $result = $whole_match; } return $result; } function _doAnchors_inline_callback($matches) { $whole_match = $matches[1]; $link_text = $this->runSpanGamut($matches[2]); $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $url = $this->encodeAmpsAndAngles($url); $result = "<a href=\"$url\""; if (isset($title)) { $title = str_replace('"', '"', $title); $title = $this->encodeAmpsAndAngles($title); $result .= " title=\"$title\""; } $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text</a>"; return $this->hashPart($result); } function doImages($text) { # # Turn Markdown image shortcuts into <img> tags. # # # First, handle reference-style labeled images: ![alt text][id] # $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ ('.$this->nested_brackets.') # alt text = $2 \] [ ]? # one optional space (?:\n[ ]*)? # one optional newline followed by spaces \[ (.*?) # id = $3 \] ) }xs', array(&$this, '_doImages_reference_callback'), $text); # # Next, handle inline images: ![alt text](url "optional title") # Don't forget: encode * and _ # $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ ('.$this->nested_brackets.') # alt text = $2 \] \s? # One optional whitespace character \( # literal paren [ ]* (?: <(\S*)> # src url = $3 | ('.$this->nested_url_parenthesis.') # src url = $4 ) [ ]* ( # $5 ([\'"]) # quote char = $6 (.*?) # title = $7 \6 # matching quote [ ]* )? # title is optional \) ) }xs', array(&$this, '_doImages_inline_callback'), $text); return $text; } function _doImages_reference_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $link_id = strtolower($matches[3]); if ($link_id == "") { $link_id = strtolower($alt_text); # for shortcut links like ![this][]. } $alt_text = str_replace('"', '"', $alt_text); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $result = "<img src=\"$url\" alt=\"$alt_text\""; if (isset($this->titles[$link_id])) { $title = $this->titles[$link_id]; $result .= " title=\"$title\""; } $result .= $this->empty_element_suffix; $result = $this->hashPart($result); } else { # If there's no such link ID, leave intact: $result = $whole_match; } return $result; } function _doImages_inline_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $alt_text = str_replace('"', '"', $alt_text); $result = "<img src=\"$url\" alt=\"$alt_text\""; if (isset($title)) { $title = str_replace('"', '"', $title); $result .= " title=\"$title\""; # $title already quoted } $result .= $this->empty_element_suffix; return $this->hashPart($result); } function doHeaders($text) { # Setext-style headers: # Header 1 # ======== # # Header 2 # -------- # $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', array(&$this, '_doHeaders_callback_setext'), $text); # atx-style headers: # # Header 1 # ## Header 2 # ## Header 2 with closing hashes ## # ... # ###### Header 6 # $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s [ ]* (.+?) # $2 = Header text [ ]* \#* # optional closing #\'s (not counted) \n+ }xm', array(&$this, '_doHeaders_callback_atx'), $text); return $text; } function _doHeaders_callback_setext($matches) { $level = $matches[2]{0} == '=' ? 1 : 2; $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>"; return "\n" . $this->hashBlock($block) . "\n\n"; } function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>"; return "\n" . $this->hashBlock($block) . "\n\n"; } function doLists($text) { # # Form HTML ordered (numbered) and unordered (bulleted) lists. # $less_than_tab = $this->tab_width - 1; # Re-usable patterns to match list item bullets and number markers: $marker_ul = '[*+-]'; $marker_ol = '\d+[.]'; $marker_any = "(?:$marker_ul|$marker_ol)"; $markers = array($marker_ul, $marker_ol); foreach ($markers as $marker) { # Re-usable pattern to match any entirel ul or ol list: $whole_list = ' ( # $1 = whole list ( # $2 [ ]{0,'.$less_than_tab.'} ('.$marker.') # $3 = first list item marker [ ]+ ) (?s:.+?) ( # $4 \z | \n{2,} (?=\S) (?! # Negative lookahead for another list item marker [ ]* '.$marker.'[ ]+ ) ) ) '; // mx # We use a different prefix before nested lists than top-level lists. # See extended comment in _ProcessListItems(). if ($this->list_level) { $text = preg_replace_callback('{ ^ '.$whole_list.' }mx', array(&$this, '_doLists_callback'), $text); } else { $text = preg_replace_callback('{ (?:(?<=\n)\n|\A\n?) # Must eat the newline '.$whole_list.' }mx', array(&$this, '_doLists_callback'), $text); } } return $text; } function _doLists_callback($matches) { # Re-usable patterns to match list item bullets and number markers: $marker_ul = '[*+-]'; $marker_ol = '\d+[.]'; $marker_any = "(?:$marker_ul|$marker_ol)"; $list = $matches[1]; $list_type = preg_match("/$marker_ul/", $matches[3]) ? "ul" : "ol"; $marker_any = ( $list_type == "ul" ? $marker_ul : $marker_ol ); $list .= "\n"; $result = $this->processListItems($list, $marker_any); $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>"); return "\n". $result ."\n\n"; } var $list_level = 0; function processListItems($list_str, $marker_any) { # # Process the contents of a single ordered or unordered list, splitting it # into individual list items. # # The $this->list_level global keeps track of when we're inside a list. # Each time we enter a list, we increment it; when we leave a list, # we decrement. If it's zero, we're not in a list anymore. # # We do this because when we're not inside a list, we want to treat # something like this: # # I recommend upgrading to version # 8. Oops, now this line is treated # as a sub-list. # # As a single paragraph, despite the fact that the second line starts # with a digit-period-space sequence. # # Whereas when we're inside a list (or sub-list), that line will be # treated as the start of a sub-list. What a kludge, huh? This is # an aspect of Markdown's syntax that's hard to parse perfectly # without resorting to mind-reading. Perhaps the solution is to # change the syntax rules such that sub-lists must start with a # starting cardinal number; e.g. "1." or "a.". $this->list_level++; # trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); $list_str = preg_replace_callback('{ (\n)? # leading line = $1 (^[ ]*) # leading whitespace = $2 ('.$marker_any.') [ ]+ # list marker = $3 ((?s:.+?)) # list item text = $4 (?:(\n+(?=\n))|\n) # tailing blank line = $5 (?= \n* (\z | \2 ('.$marker_any.') [ ]+)) }xm', array(&$this, '_processListItems_callback'), $list_str); $this->list_level--; return $list_str; } function _processListItems_callback($matches) { $item = $matches[4]; $leading_line =& $matches[1]; $leading_space =& $matches[2]; $tailing_blank_line =& $matches[5]; if ($leading_line || $tailing_blank_line || preg_match('/\n{2,}/', $item)) { $item = $this->runBlockGamut($this->outdent($item)."\n"); } else { # Recursion for sub-lists: $item = $this->doLists($this->outdent($item)); $item = preg_replace('/\n+$/', '', $item); $item = $this->runSpanGamut($item); } return "<li>" . $item . "</li>\n"; } function doCodeBlocks($text) { # # Process Markdown `<pre><code>` blocks. # $text = preg_replace_callback('{ (?:\n\n|\A) ( # $1 = the code block -- one or more lines, starting with a space/tab (?> [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces .*\n+ )+ ) ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }xm', array(&$this, '_doCodeBlocks_callback'), $text); return $text; } function _doCodeBlocks_callback($matches) { $codeblock = $matches[1]; $codeblock = $this->outdent($codeblock); $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); # trim leading newlines and trailing newlines $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock); $codeblock = "<pre><code>$codeblock\n</code></pre>"; return "\n\n".$this->hashBlock($codeblock)."\n\n"; } function makeCodeSpan($code) { # # Create a code span markup for $code. Called from handleSpanToken. # $code = htmlspecialchars(trim($code), ENT_NOQUOTES); return $this->hashPart("<code>$code</code>"); } function doItalicsAndBold($text) { # <strong> must go first: $text = preg_replace_callback('{ ( # $1: Marker (?<!\*\*) \* | # (not preceded by two chars of (?<!__) _ # the same marker) ) \1 (?=\S) # Not followed by whitespace (?!\1\1) # or two others marker chars. ( # $2: Content (?> [^*_]+? # Anthing not em markers. | # Balence any regular emphasis inside. \1 (?=\S) .+? (?<=\S) \1 | . # Allow unbalenced * and _. )+? ) (?<=\S) \1\1 # End mark not preceded by whitespace. }sx', array(&$this, '_doItalicAndBold_strong_callback'), $text); # Then <em>: $text = preg_replace_callback( '{ ( (?<!\*)\* | (?<!_)_ ) (?=\S) (?! \1) (.+?) (?<=\S)(?<!\s(?=\1).) \1 }sx', array(&$this, '_doItalicAndBold_em_callback'), $text); return $text; } function _doItalicAndBold_em_callback($matches) { $text = $matches[2]; $text = $this->runSpanGamut($text); return $this->hashPart("<em>$text</em>"); } function _doItalicAndBold_strong_callback($matches) { $text = $matches[2]; $text = $this->runSpanGamut($text); return $this->hashPart("<strong>$text</strong>"); } function doBlockQuotes($text) { $text = preg_replace_callback('/ ( # Wrap whole match in $1 (?> ^[ ]*>[ ]? # ">" at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines \n* # blanks )+ ) /xm', array(&$this, '_doBlockQuotes_callback'), $text); return $text; } function _doBlockQuotes_callback($matches) { $bq = $matches[1]; # trim one level of quoting - trim whitespace-only lines $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); $bq = $this->runBlockGamut($bq); # recurse $bq = preg_replace('/^/m', " ", $bq); # These leading spaces cause problem with <pre> content, # so we need to fix that: $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', array(&$this, '_DoBlockQuotes_callback2'), $bq); return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n"; } function _doBlockQuotes_callback2($matches) { $pre = $matches[1]; $pre = preg_replace('/^ /m', '', $pre); return $pre; } function formParagraphs($text) { # # Params: # $text - string to process with html <p> tags # # Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); # # Wrap <p> tags and unhashify HTML blocks # foreach ($grafs as $key => $value) { if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { # Is a paragraph. $value = $this->runSpanGamut($value); $value = preg_replace('/^([ ]*)/', "<p>", $value); $value .= "</p>"; $grafs[$key] = $this->unhash($value); } else { # Is a block. # Modify elements of @grafs in-place... $graf = $value; $block = $this->html_hashes[$graf]; $graf = $block; // if (preg_match('{ // \A // ( # $1 = <div> tag // <div \s+ // [^>]* // \b // markdown\s*=\s* ([\'"]) # $2 = attr quote char // 1 // \2 // [^>]* // > // ) // ( # $3 = contents // .* // ) // (</div>) # $4 = closing tag // \z // }xs', $block, $matches)) // { // list(, $div_open, , $div_content, $div_close) = $matches; // // # We can't call Markdown(), because that resets the hash; // # that initialization code should be pulled into its own sub, though. // $div_content = $this->hashHTMLBlocks($div_content); // // # Run document gamut methods on the content. // foreach ($this->document_gamut as $method => $priority) { // $div_content = $this->$method($div_content); // } // // $div_open = preg_replace( // '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); // // $graf = $div_open . "\n" . $div_content . "\n" . $div_close; // } $grafs[$key] = $graf; } } return implode("\n\n", $grafs); } function encodeAmpsAndAngles($text) { # Smart processing for ampersands and angle brackets that need to be encoded. if ($this->no_entities) { $text = str_replace('&', '&', $text); $text = str_replace('<', '<', $text); return $text; } # Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: # http://bumppo.net/projects/amputator/ $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', '&', $text);; # Encode naked <'s $text = preg_replace('{<(?![a-z/?\$!%])}i', '<', $text); return $text; } function doAutoLinks($text) { $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}', array(&$this, '_doAutoLinks_url_callback'), $text); # Email addresses: <address@domain.foo> $text = preg_replace_callback('{ < (?:mailto:)? ( [-.\w\x80-\xFF]+ \@ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ ) > }xi', array(&$this, '_doAutoLinks_email_callback'), $text); return $text; } function _doAutoLinks_url_callback($matches) { $url = $this->encodeAmpsAndAngles($matches[1]); $link = "<a href=\"$url\">$url</a>"; return $this->hashPart($link); } function _doAutoLinks_email_callback($matches) { $address = $matches[1]; $link = $this->encodeEmailAddress($address); return $this->hashPart($link); } function encodeEmailAddress($addr) { # # Input: an email address, e.g. "foo@example.com" # # Output: the email address as a mailto link, with each character # of the address encoded as either a decimal or hex entity, in # the hopes of foiling most address harvesting spam bots. E.g.: # # <p><a href="mailto:foo # @example.co # m">foo@exampl # e.com</a></p> # # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. # With some optimizations by Milian Wolff. # $addr = "mailto:" . $addr; $chars = preg_split('/(?<!^)(?!$)/', $addr); $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed. foreach ($chars as $key => $char) { $ord = ord($char); # Ignore non-ascii chars. if ($ord < 128) { $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. # roughly 10% raw, 45% hex, 45% dec # '@' *must* be encoded. I insist. if ($r > 90 && $char != '@') /* do nothing */; else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; else $chars[$key] = '&#'.$ord.';'; } } $addr = implode('', $chars); $text = implode('', array_slice($chars, 7)); # text without `mailto:` $addr = "<a href=\"$addr\">$text</a>"; return $addr; } function parseSpan($str) { # # Take the string $str and parse it into tokens, hashing embeded HTML, # escaped characters and handling code spans. # $output = ''; $regex = '{ ( \\\\['.preg_quote($this->escape_chars).'] | (?<![`\\\\]) `+ # code span marker '.( $this->no_markup ? '' : ' | <!-- .*? --> # comment | <\?.*?\?> | <%.*?%> # processing instruction | <[/!$]?[-a-zA-Z0-9:]+ # regular tags (?> \s (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* )? > ').' ) }xs'; while (1) { # # Each loop iteration seach for either the next tag, the next # openning code span marker, or the next escaped character. # Each token is then passed to handleSpanToken. # $parts = preg_split($regex, $str, 2, PREG_SPLIT_DELIM_CAPTURE); # Create token from text preceding tag. if ($parts[0] != "") { $output .= $parts[0]; } # Check if we reach the end. if (isset($parts[1])) { $output .= $this->handleSpanToken($parts[1], $parts[2]); $str = $parts[2]; } else { break; } } return $output; } function handleSpanToken($token, &$str) { # # Handle $token provided by parseSpan by determining its nature and # returning the corresponding value that should replace it. # switch ($token{0}) { case "\\": return $this->hashPart("&#". ord($token{1}). ";"); case "`": # Search for end marker in remaining text. if (preg_match('/^(.*?[^`])'.$token.'(?!`)(.*)$/sm', $str, $matches)) { $str = $matches[2]; $codespan = $this->makeCodeSpan($matches[1]); return $this->hashPart($codespan); } return $token; // return as text since no ending marker found. default: return $this->hashPart($token); } } function outdent($text) { # # Remove one level of line-leading tabs or spaces # return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); } # String length function for detab. `_initDetab` will create a function to # hanlde UTF-8 if the default function does not exist. var $utf8_strlen = 'mb_strlen'; function detab($text) { # # Replace tabs with the appropriate amount of space. # # For each line we separate the line in blocks delemited by # tab characters. Then we reconstruct every line by adding the # appropriate number of space between each blocks. $text = preg_replace_callback('/^.*\t.*$/m', array(&$this, '_detab_callback'), $text); return $text; } function _detab_callback($matches) { $line = $matches[0]; $strlen = $this->utf8_strlen; # strlen function for UTF-8. # Split in blocks. $blocks = explode("\t", $line); # Add each blocks to the line. $line = $blocks[0]; unset($blocks[0]); # Do not add first block twice. foreach ($blocks as $block) { # Calculate amount of space, insert spaces, insert block. $amount = $this->tab_width - $strlen($line, 'UTF-8') % $this->tab_width; $line .= str_repeat(" ", $amount) . $block; } return $line; } function _initDetab() { # # Check for the availability of the function in the `utf8_strlen` property # (initially `mb_strlen`). If the function is not available, create a # function that will loosely count the number of UTF-8 characters with a # regular expression. # if (function_exists($this->utf8_strlen)) return; $this->utf8_strlen = create_function('$text', 'return preg_match_all( "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", $text, $m);'); } function unhash($text) { # # Swap back in all the tags hashed by _HashHTMLBlocks. # return preg_replace_callback('/(.)\x1A[0-9]+\1/', array(&$this, '_unhash_callback'), $text); } function _unhash_callback($matches) { return $this->html_hashes[$matches[0]]; } } /* PHP Markdown ============ Description ----------- This is a PHP translation of the original Markdown formatter written in Perl by John Gruber. Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text format into HTML. Markdown's text format is most similar to that of plain text email, and supports features such as headers, *emphasis*, code blocks, blockquotes, and links. Markdown's syntax is designed not as a generic markup language, but specifically to serve as a front-end to (X)HTML. You can use span-level HTML tags anywhere in a Markdown document, and you can use block level HTML tags (like <div> and <table> as well). For more information about Markdown's syntax, see: <http://daringfireball.net/projects/markdown/> Bugs ---- To file bug reports please send email to: <michel.fortin@michelf.com> Please include with your report: (1) the example input; (2) the output you expected; (3) the output Markdown actually produced. Version History --------------- See the readme file for detailed release notes for this version. Copyright and License --------------------- PHP Markdown Copyright (c) 2004-2007 Michel Fortin <http://www.michelf.com/> All rights reserved. Based on Markdown Copyright (c) 2003-2006 John Gruber <http://daringfireball.net/> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. */ ?>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdown.py�������������������������������������������������������������0000664�0000000�0000000�00000160701�14107073154�0020123�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python version = "1.6b" version_info = (1,6,2,"rc-2") __revision__ = "$Rev$" """ Python-Markdown =============== Converts Markdown to HTML. Basic usage as a module: import markdown md = Markdown() html = markdown.convert(your_text_string) See http://www.freewisdom.org/projects/python-markdown/ for more information and instructions on how to extend the functionality of the script. (You might want to read that before you try modifying this file.) Started by [Manfred Stienstra](http://www.dwerg.net/). Continued and maintained by [Yuri Takhteyev](http://www.freewisdom.org). Contact: yuri [at] freewisdom.org License: GPL 2 (http://www.gnu.org/copyleft/gpl.html) or BSD """ import re, sys, os, random, codecs # Set debug level: 3 none, 2 critical, 1 informative, 0 all (VERBOSE, INFO, CRITICAL, NONE) = range(4) MESSAGE_THRESHOLD = CRITICAL def message(level, text) : if level >= MESSAGE_THRESHOLD : print text # --------------- CONSTANTS YOU MIGHT WANT TO MODIFY ----------------- TAB_LENGTH = 4 # expand tabs to this many spaces ENABLE_ATTRIBUTES = True # @id = xyz -> <... id="xyz"> SMART_EMPHASIS = 1 # this_or_that does not become this<i>or</i>that HTML_REMOVED_TEXT = "[HTML_REMOVED]" # text used instead of HTML in safe mode RTL_BIDI_RANGES = ( (u'\u0590', u'\u07FF'), # from Hebrew to Nko (includes Arabic, Syriac and Thaana) (u'\u2D30', u'\u2D7F'), # Tifinagh ) # Unicode Reference Table: # 0590-05FF - Hebrew # 0600-06FF - Arabic # 0700-074F - Syriac # 0750-077F - Arabic Supplement # 0780-07BF - Thaana # 07C0-07FF - Nko BOMS = { 'utf-8' : (unicode(codecs.BOM_UTF8, "utf-8"), ), 'utf-16' : (unicode(codecs.BOM_UTF16_LE, "utf-16"), unicode(codecs.BOM_UTF16_BE, "utf-16")), #'utf-32' : (unicode(codecs.BOM_UTF32_LE, "utf-32"), # unicode(codecs.BOM_UTF32_BE, "utf-32")), } def removeBOM(text, encoding): for bom in BOMS[encoding]: if text.startswith(bom): return text.lstrip(bom) return text # The following constant specifies the name used in the usage # statement displayed for python versions lower than 2.3. (With # python2.3 and higher the usage statement is generated by optparse # and uses the actual name of the executable called.) EXECUTABLE_NAME_FOR_USAGE = "python markdown.py" # --------------- CONSTANTS YOU _SHOULD NOT_ HAVE TO CHANGE ---------- # a template for html placeholders HTML_PLACEHOLDER_PREFIX = "qaodmasdkwaspemas" HTML_PLACEHOLDER = HTML_PLACEHOLDER_PREFIX + "%dajkqlsmdqpakldnzsdfls" BLOCK_LEVEL_ELEMENTS = ['p', 'div', 'blockquote', 'pre', 'table', 'dl', 'ol', 'ul', 'script', 'noscript', 'form', 'fieldset', 'iframe', 'math', 'ins', 'del', 'hr', 'hr/', 'style'] def is_block_level (tag) : return ( (tag in BLOCK_LEVEL_ELEMENTS) or (tag[0] == 'h' and tag[1] in "0123456789") ) """ ====================================================================== ========================== NANODOM =================================== ====================================================================== The three classes below implement some of the most basic DOM methods. I use this instead of minidom because I need a simpler functionality and do not want to require additional libraries. Importantly, NanoDom does not do normalization, which is what we want. It also adds extra white space when converting DOM to string """ ENTITY_NORMALIZATION_EXPRESSIONS = [ (re.compile("&"), "&"), (re.compile("<"), "<"), (re.compile(">"), ">"), (re.compile("\""), """)] ENTITY_NORMALIZATION_EXPRESSIONS_SOFT = [ (re.compile("&(?!\#)"), "&"), (re.compile("<"), "<"), (re.compile(">"), ">"), (re.compile("\""), """)] def getBidiType(text) : if not text : return None ch = text[0] if not isinstance(ch, unicode) or not ch.isalpha(): return None else : for min, max in RTL_BIDI_RANGES : if ( ch >= min and ch <= max ) : return "rtl" else : return "ltr" class Document : def __init__ (self) : self.bidi = "ltr" def appendChild(self, child) : self.documentElement = child child.isDocumentElement = True child.parent = self self.entities = {} def setBidi(self, bidi) : if bidi : self.bidi = bidi def createElement(self, tag, textNode=None) : el = Element(tag) el.doc = self if textNode : el.appendChild(self.createTextNode(textNode)) return el def createTextNode(self, text) : node = TextNode(text) node.doc = self return node def createEntityReference(self, entity): if entity not in self.entities: self.entities[entity] = EntityReference(entity) return self.entities[entity] def createCDATA(self, text) : node = CDATA(text) node.doc = self return node def toxml (self) : return self.documentElement.toxml() def normalizeEntities(self, text, avoidDoubleNormalizing=False) : if avoidDoubleNormalizing : regexps = ENTITY_NORMALIZATION_EXPRESSIONS_SOFT else : regexps = ENTITY_NORMALIZATION_EXPRESSIONS for regexp, substitution in regexps : text = regexp.sub(substitution, text) return text def find(self, test) : return self.documentElement.find(test) def unlink(self) : self.documentElement.unlink() self.documentElement = None class CDATA : type = "cdata" def __init__ (self, text) : self.text = text def handleAttributes(self) : pass def toxml (self) : return "<![CDATA[" + self.text + "]]>" class Element : type = "element" def __init__ (self, tag) : self.nodeName = tag self.attributes = [] self.attribute_values = {} self.childNodes = [] self.bidi = None self.isDocumentElement = False def setBidi(self, bidi) : if bidi : orig_bidi = self.bidi if not self.bidi or self.isDocumentElement: # Once the bidi is set don't change it (except for doc element) self.bidi = bidi self.parent.setBidi(bidi) def unlink(self) : for child in self.childNodes : if child.type == "element" : child.unlink() self.childNodes = None def setAttribute(self, attr, value) : if not attr in self.attributes : self.attributes.append(attr) self.attribute_values[attr] = value def insertChild(self, position, child) : self.childNodes.insert(position, child) child.parent = self def removeChild(self, child) : self.childNodes.remove(child) def replaceChild(self, oldChild, newChild) : position = self.childNodes.index(oldChild) self.removeChild(oldChild) self.insertChild(position, newChild) def appendChild(self, child) : self.childNodes.append(child) child.parent = self def handleAttributes(self) : pass def find(self, test, depth=0) : """ Returns a list of descendants that pass the test function """ matched_nodes = [] for child in self.childNodes : if test(child) : matched_nodes.append(child) if child.type == "element" : matched_nodes += child.find(test, depth+1) return matched_nodes def toxml(self): if ENABLE_ATTRIBUTES : for child in self.childNodes: child.handleAttributes() buffer = "" if self.nodeName in ['h1', 'h2', 'h3', 'h4'] : buffer += "\n" elif self.nodeName in ['li'] : buffer += "\n " # Process children FIRST, then do the attributes childBuffer = "" if self.childNodes or self.nodeName in ['blockquote']: childBuffer += ">" for child in self.childNodes : childBuffer += child.toxml() if self.nodeName == 'p' : childBuffer += "\n" elif self.nodeName == 'li' : childBuffer += "\n " childBuffer += "</%s>" % self.nodeName else : childBuffer += "/>" buffer += "<" + self.nodeName if self.nodeName in ['p', 'li', 'ul', 'ol', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'] : if not self.attribute_values.has_key("dir"): if self.bidi : bidi = self.bidi else : bidi = self.doc.bidi if bidi=="rtl" : self.setAttribute("dir", "rtl") for attr in self.attributes : value = self.attribute_values[attr] value = self.doc.normalizeEntities(value, avoidDoubleNormalizing=True) buffer += ' %s="%s"' % (attr, value) # Now let's actually append the children buffer += childBuffer if self.nodeName in ['p', 'li', 'ul', 'ol', 'h1', 'h2', 'h3', 'h4'] : buffer += "\n" return buffer class TextNode : type = "text" attrRegExp = re.compile(r'\{@([^\}]*)=([^\}]*)}') # {@id=123} def __init__ (self, text) : self.value = text def attributeCallback(self, match) : self.parent.setAttribute(match.group(1), match.group(2)) def handleAttributes(self) : self.value = self.attrRegExp.sub(self.attributeCallback, self.value) def toxml(self) : text = self.value self.parent.setBidi(getBidiType(text)) if not text.startswith(HTML_PLACEHOLDER_PREFIX): if self.parent.nodeName == "p" : text = text.replace("\n", "\n ") elif (self.parent.nodeName == "li" and self.parent.childNodes[0]==self): text = "\n " + text.replace("\n", "\n ") text = self.doc.normalizeEntities(text) return text class EntityReference: type = "entity_ref" def __init__(self, entity): self.entity = entity def handleAttributes(self): pass def toxml(self): return "&" + self.entity + ";" """ ====================================================================== ========================== PRE-PROCESSORS ============================ ====================================================================== Preprocessors munge source text before we start doing anything too complicated. Each preprocessor implements a "run" method that takes a pointer to a list of lines of the document, modifies it as necessary and returns either the same pointer or a pointer to a new list. Preprocessors must extend markdown.Preprocessor. """ class Preprocessor : pass class HeaderPreprocessor (Preprocessor): """ Replaces underlined headers with hashed headers to avoid the nead for lookahead later. """ def run (self, lines) : i = -1 while i+1 < len(lines) : i = i+1 if not lines[i].strip() : continue if lines[i].startswith("#") : lines.insert(i+1, "\n") if (i+1 <= len(lines) and lines[i+1] and lines[i+1][0] in ['-', '=']) : underline = lines[i+1].strip() if underline == "="*len(underline) : lines[i] = "# " + lines[i].strip() lines[i+1] = "" elif underline == "-"*len(underline) : lines[i] = "## " + lines[i].strip() lines[i+1] = "" return lines HEADER_PREPROCESSOR = HeaderPreprocessor() class LinePreprocessor (Preprocessor): """Deals with HR lines (needs to be done before processing lists)""" def run (self, lines) : for i in range(len(lines)) : if self._isLine(lines[i]) : lines[i] = "<hr />" return lines def _isLine(self, block) : """Determines if a block should be replaced with an <HR>""" if block.startswith(" ") : return 0 # a code block text = "".join([x for x in block if not x.isspace()]) if len(text) <= 2 : return 0 for pattern in ['isline1', 'isline2', 'isline3'] : m = RE.regExp[pattern].match(text) if (m and m.group(1)) : return 1 else: return 0 LINE_PREPROCESSOR = LinePreprocessor() class LineBreaksPreprocessor (Preprocessor): """Replaces double spaces at the end of the lines with <br/ >.""" def run (self, lines) : for i in range(len(lines)) : if (lines[i].endswith(" ") and not RE.regExp['tabbed'].match(lines[i]) ): lines[i] += "<br />" return lines LINE_BREAKS_PREPROCESSOR = LineBreaksPreprocessor() class HtmlBlockPreprocessor (Preprocessor): """Removes html blocks from self.lines""" def _get_left_tag(self, block): return block[1:].replace(">", " ", 1).split()[0].lower() def _get_right_tag(self, left_tag, block): return block.rstrip()[-len(left_tag)-2:-1].lower() def _equal_tags(self, left_tag, right_tag): if left_tag in ['?', '?php', 'div'] : # handle PHP, etc. return True if ("/" + left_tag) == right_tag: return True if (right_tag == "--" and left_tag == "--") : return True elif left_tag == right_tag[1:] \ and right_tag[0] != "<": return True else: return False def _is_oneliner(self, tag): return (tag in ['hr', 'hr/']) def run (self, lines) : new_blocks = [] text = "\n".join(lines) text = text.split("\n\n") items = [] left_tag = '' right_tag = '' in_tag = False # flag for block in text: if block.startswith("\n") : block = block[1:] if not in_tag: if block.startswith("<"): left_tag = self._get_left_tag(block) right_tag = self._get_right_tag(left_tag, block) if not (is_block_level(left_tag) \ or block[1] in ["!", "?", "@", "%"]): new_blocks.append(block) continue if self._is_oneliner(left_tag): new_blocks.append(block.strip()) continue if block[1] == "!": # is a comment block left_tag = "--" right_tag = self._get_right_tag(left_tag, block) # keep checking conditions below and maybe just append if block.rstrip().endswith(">") \ and self._equal_tags(left_tag, right_tag): new_blocks.append( self.stash.store(block.strip())) continue else: #if not block[1] == "!": # if is block level tag and is not complete items.append(block.strip()) in_tag = True continue new_blocks.append(block) else: items.append(block.strip()) right_tag = self._get_right_tag(left_tag, block) if self._equal_tags(left_tag, right_tag): # if find closing tag in_tag = False new_blocks.append( self.stash.store('\n\n'.join(items))) items = [] if items : new_blocks.append(self.stash.store('\n\n'.join(items))) new_blocks.append('\n') return "\n\n".join(new_blocks).split("\n") HTML_BLOCK_PREPROCESSOR = HtmlBlockPreprocessor() class ReferencePreprocessor (Preprocessor): def run (self, lines) : new_text = []; for line in lines: m = RE.regExp['reference-def'].match(line) if m: id = m.group(2).strip().lower() t = m.group(4).strip() # potential title if not t : self.references[id] = (m.group(3), t) elif (len(t) >= 2 and (t[0] == t[-1] == "\"" or t[0] == t[-1] == "\'" or (t[0] == "(" and t[-1] == ")") ) ) : self.references[id] = (m.group(3), t[1:-1]) else : new_text.append(line) else: new_text.append(line) return new_text #+ "\n" REFERENCE_PREPROCESSOR = ReferencePreprocessor() """ ====================================================================== ========================== INLINE PATTERNS =========================== ====================================================================== Inline patterns such as *emphasis* are handled by means of auxiliary objects, one per pattern. Pattern objects must be instances of classes that extend markdown.Pattern. Each pattern object uses a single regular expression and needs support the following methods: pattern.getCompiledRegExp() - returns a regular expression pattern.handleMatch(m, doc) - takes a match object and returns a NanoDom node (as a part of the provided doc) or None All of python markdown's built-in patterns subclass from Patter, but you can add additional patterns that don't. Also note that all the regular expressions used by inline must capture the whole block. For this reason, they all start with '^(.*)' and end with '(.*)!'. In case with built-in expression Pattern takes care of adding the "^(.*)" and "(.*)!". Finally, the order in which regular expressions are applied is very important - e.g. if we first replace http://.../ links with <a> tags and _then_ try to replace inline html, we would end up with a mess. So, we apply the expressions in the following order: * escape and backticks have to go before everything else, so that we can preempt any markdown patterns by escaping them. * then we handle auto-links (must be done before inline html) * then we handle inline HTML. At this point we will simply replace all inline HTML strings with a placeholder and add the actual HTML to a hash. * then inline images (must be done before links) * then bracketed links, first regular then reference-style * finally we apply strong and emphasis """ NOBRACKET = r'[^\]\[]*' BRK = ( r'\[(' + (NOBRACKET + r'(\['+NOBRACKET)*6 + (NOBRACKET+ r'\])*'+NOBRACKET)*6 + NOBRACKET + r')\]' ) BACKTICK_RE = r'\`([^\`]*)\`' # `e= m*c^2` DOUBLE_BACKTICK_RE = r'\`\`(.*)\`\`' # ``e=f("`")`` ESCAPE_RE = r'\\(.)' # \< EMPHASIS_RE = r'\*([^\*]*)\*' # *emphasis* STRONG_RE = r'\*\*(.*)\*\*' # **strong** STRONG_EM_RE = r'\*\*\*([^_]*)\*\*\*' # ***strong*** if SMART_EMPHASIS: EMPHASIS_2_RE = r'(?<!\S)_(\S[^_]*)_' # _emphasis_ else : EMPHASIS_2_RE = r'_([^_]*)_' # _emphasis_ STRONG_2_RE = r'__([^_]*)__' # __strong__ STRONG_EM_2_RE = r'___([^_]*)___' # ___strong___ LINK_RE = BRK + r'\s*\(([^\)]*)\)' # [text](url) LINK_ANGLED_RE = BRK + r'\s*\(<([^\)]*)>\)' # [text](<url>) IMAGE_LINK_RE = r'\!' + BRK + r'\s*\(([^\)]*)\)' # ![alttxt](http://x.com/) REFERENCE_RE = BRK+ r'\s*\[([^\]]*)\]' # [Google][3] IMAGE_REFERENCE_RE = r'\!' + BRK + '\s*\[([^\]]*)\]' # ![alt text][2] NOT_STRONG_RE = r'( \* )' # stand-alone * or _ AUTOLINK_RE = r'<(http://[^>]*)>' # <http://www.123.com> AUTOMAIL_RE = r'<([^> \!]*@[^> ]*)>' # <me@example.com> #HTML_RE = r'(\<[^\>]*\>)' # <...> HTML_RE = r'(\<[a-zA-Z/][^\>]*\>)' # <...> ENTITY_RE = r'(&[\#a-zA-Z0-9]*;)' # & class Pattern: def __init__ (self, pattern) : self.pattern = pattern self.compiled_re = re.compile("^(.*)%s(.*)$" % pattern, re.DOTALL) def getCompiledRegExp (self) : return self.compiled_re BasePattern = Pattern # for backward compatibility class SimpleTextPattern (Pattern) : def handleMatch(self, m, doc) : return doc.createTextNode(m.group(2)) class SimpleTagPattern (Pattern): def __init__ (self, pattern, tag) : Pattern.__init__(self, pattern) self.tag = tag def handleMatch(self, m, doc) : el = doc.createElement(self.tag) el.appendChild(doc.createTextNode(m.group(2))) return el class BacktickPattern (Pattern): def __init__ (self, pattern): Pattern.__init__(self, pattern) self.tag = "code" def handleMatch(self, m, doc) : el = doc.createElement(self.tag) text = m.group(2).strip() #text = text.replace("&", "&") el.appendChild(doc.createTextNode(text)) return el class DoubleTagPattern (SimpleTagPattern) : def handleMatch(self, m, doc) : tag1, tag2 = self.tag.split(",") el1 = doc.createElement(tag1) el2 = doc.createElement(tag2) el1.appendChild(el2) el2.appendChild(doc.createTextNode(m.group(2))) return el1 class HtmlPattern (Pattern): def handleMatch (self, m, doc) : place_holder = self.stash.store(m.group(2)) return doc.createTextNode(place_holder) class LinkPattern (Pattern): def handleMatch(self, m, doc) : el = doc.createElement('a') el.appendChild(doc.createTextNode(m.group(2))) parts = m.group(9).split('"') # We should now have [], [href], or [href, title] if parts : el.setAttribute('href', parts[0].strip()) else : el.setAttribute('href', "") if len(parts) > 1 : # we also got a title title = '"' + '"'.join(parts[1:]).strip() title = dequote(title) #.replace('"', """) el.setAttribute('title', title) return el class ImagePattern (Pattern): def handleMatch(self, m, doc): el = doc.createElement('img') src_parts = m.group(9).split() el.setAttribute('src', src_parts[0]) if len(src_parts) > 1 : el.setAttribute('title', dequote(" ".join(src_parts[1:]))) if ENABLE_ATTRIBUTES : text = doc.createTextNode(m.group(2)) el.appendChild(text) text.handleAttributes() truealt = text.value el.childNodes.remove(text) else: truealt = m.group(2) el.setAttribute('alt', truealt) return el class ReferencePattern (Pattern): def handleMatch(self, m, doc): if m.group(9) : id = m.group(9).lower() else : # if we got something like "[Google][]" # we'll use "google" as the id id = m.group(2).lower() if not self.references.has_key(id) : # ignore undefined refs return None href, title = self.references[id] text = m.group(2) return self.makeTag(href, title, text, doc) def makeTag(self, href, title, text, doc): el = doc.createElement('a') el.setAttribute('href', href) if title : el.setAttribute('title', title) el.appendChild(doc.createTextNode(text)) return el class ImageReferencePattern (ReferencePattern): def makeTag(self, href, title, text, doc): el = doc.createElement('img') el.setAttribute('src', href) if title : el.setAttribute('title', title) el.setAttribute('alt', text) return el class AutolinkPattern (Pattern): def handleMatch(self, m, doc): el = doc.createElement('a') el.setAttribute('href', m.group(2)) el.appendChild(doc.createTextNode(m.group(2))) return el class AutomailPattern (Pattern): def handleMatch(self, m, doc) : el = doc.createElement('a') email = m.group(2) if email.startswith("mailto:"): email = email[len("mailto:"):] for letter in email: entity = doc.createEntityReference("#%d" % ord(letter)) el.appendChild(entity) mailto = "mailto:" + email mailto = "".join(['&#%d;' % ord(letter) for letter in mailto]) el.setAttribute('href', mailto) return el ESCAPE_PATTERN = SimpleTextPattern(ESCAPE_RE) NOT_STRONG_PATTERN = SimpleTextPattern(NOT_STRONG_RE) BACKTICK_PATTERN = BacktickPattern(BACKTICK_RE) DOUBLE_BACKTICK_PATTERN = BacktickPattern(DOUBLE_BACKTICK_RE) STRONG_PATTERN = SimpleTagPattern(STRONG_RE, 'strong') STRONG_PATTERN_2 = SimpleTagPattern(STRONG_2_RE, 'strong') EMPHASIS_PATTERN = SimpleTagPattern(EMPHASIS_RE, 'em') EMPHASIS_PATTERN_2 = SimpleTagPattern(EMPHASIS_2_RE, 'em') STRONG_EM_PATTERN = DoubleTagPattern(STRONG_EM_RE, 'strong,em') STRONG_EM_PATTERN_2 = DoubleTagPattern(STRONG_EM_2_RE, 'strong,em') LINK_PATTERN = LinkPattern(LINK_RE) LINK_ANGLED_PATTERN = LinkPattern(LINK_ANGLED_RE) IMAGE_LINK_PATTERN = ImagePattern(IMAGE_LINK_RE) IMAGE_REFERENCE_PATTERN = ImageReferencePattern(IMAGE_REFERENCE_RE) REFERENCE_PATTERN = ReferencePattern(REFERENCE_RE) HTML_PATTERN = HtmlPattern(HTML_RE) ENTITY_PATTERN = HtmlPattern(ENTITY_RE) AUTOLINK_PATTERN = AutolinkPattern(AUTOLINK_RE) AUTOMAIL_PATTERN = AutomailPattern(AUTOMAIL_RE) """ ====================================================================== ========================== POST-PROCESSORS =========================== ====================================================================== Markdown also allows post-processors, which are similar to preprocessors in that they need to implement a "run" method. Unlike pre-processors, they take a NanoDom document as a parameter and work with that. Post-Processor should extend markdown.Postprocessor. There are currently no standard post-processors, but the footnote extension below uses one. """ class Postprocessor : pass """ ====================================================================== ========================== MISC AUXILIARY CLASSES ==================== ====================================================================== """ class HtmlStash : """This class is used for stashing HTML objects that we extract in the beginning and replace with place-holders.""" def __init__ (self) : self.html_counter = 0 # for counting inline html segments self.rawHtmlBlocks=[] def store(self, html) : """Saves an HTML segment for later reinsertion. Returns a placeholder string that needs to be inserted into the document. @param html: an html segment @returns : a placeholder string """ self.rawHtmlBlocks.append(html) placeholder = HTML_PLACEHOLDER % self.html_counter self.html_counter += 1 return placeholder class BlockGuru : def _findHead(self, lines, fn, allowBlank=0) : """Functional magic to help determine boundaries of indented blocks. @param lines: an array of strings @param fn: a function that returns a substring of a string if the string matches the necessary criteria @param allowBlank: specifies whether it's ok to have blank lines between matching functions @returns: a list of post processes items and the unused remainder of the original list""" items = [] item = -1 i = 0 # to keep track of where we are for line in lines : if not line.strip() and not allowBlank: return items, lines[i:] if not line.strip() and allowBlank: # If we see a blank line, this _might_ be the end i += 1 # Find the next non-blank line for j in range(i, len(lines)) : if lines[j].strip() : next = lines[j] break else : # There is no more text => this is the end break # Check if the next non-blank line is still a part of the list part = fn(next) if part : items.append("") continue else : break # found end of the list part = fn(line) if part : items.append(part) i += 1 continue else : return items, lines[i:] else : i += 1 return items, lines[i:] def detabbed_fn(self, line) : """ An auxiliary method to be passed to _findHead """ m = RE.regExp['tabbed'].match(line) if m: return m.group(4) else : return None def detectTabbed(self, lines) : return self._findHead(lines, self.detabbed_fn, allowBlank = 1) def print_error(string): """Print an error string to stderr""" sys.stderr.write(string +'\n') def dequote(string) : """ Removes quotes from around a string """ if ( ( string.startswith('"') and string.endswith('"')) or (string.startswith("'") and string.endswith("'")) ) : return string[1:-1] else : return string """ ====================================================================== ========================== CORE MARKDOWN ============================= ====================================================================== This stuff is ugly, so if you are thinking of extending the syntax, see first if you can do it via pre-processors, post-processors, inline patterns or a combination of the three. """ class CorePatterns : """This class is scheduled for removal as part of a refactoring effort.""" patterns = { 'header': r'(#*)([^#]*)(#*)', # # A title 'reference-def' : r'(\ ?\ ?\ ?)\[([^\]]*)\]:\s*([^ ]*)(.*)', # [Google]: http://www.google.com/ 'containsline': r'([-]*)$|^([=]*)', # -----, =====, etc. 'ol': r'[ ]{0,3}[\d]*\.\s+(.*)', # 1. text 'ul': r'[ ]{0,3}[*+-]\s+(.*)', # "* text" 'isline1': r'(\**)', # *** 'isline2': r'(\-*)', # --- 'isline3': r'(\_*)', # ___ 'tabbed': r'((\t)|( ))(.*)', # an indented line 'quoted' : r'> ?(.*)', # a quoted block ("> ...") } def __init__ (self) : self.regExp = {} for key in self.patterns.keys() : self.regExp[key] = re.compile("^%s$" % self.patterns[key], re.DOTALL) self.regExp['containsline'] = re.compile(r'^([-]*)$|^([=]*)$', re.M) RE = CorePatterns() class Markdown: """ Markdown formatter class for creating an html document from Markdown text """ def __init__(self, source=None, # deprecated extensions=[], extension_configs=None, encoding="utf-8", safe_mode = False): """Creates a new Markdown instance. @param source: The text in Markdown format. @param encoding: The character encoding of <text>. """ self.safeMode = safe_mode self.encoding = encoding self.source = source self.blockGuru = BlockGuru() self.registeredExtensions = [] self.stripTopLevelTags = 1 self.docType = "" self.preprocessors = [ HTML_BLOCK_PREPROCESSOR, HEADER_PREPROCESSOR, LINE_PREPROCESSOR, LINE_BREAKS_PREPROCESSOR, # A footnote preprocessor will # get inserted here REFERENCE_PREPROCESSOR ] self.postprocessors = [] # a footnote postprocessor will get # inserted later self.textPostprocessors = [] # a footnote postprocessor will get # inserted later self.prePatterns = [] self.inlinePatterns = [ DOUBLE_BACKTICK_PATTERN, BACKTICK_PATTERN, ESCAPE_PATTERN, IMAGE_LINK_PATTERN, IMAGE_REFERENCE_PATTERN, REFERENCE_PATTERN, LINK_ANGLED_PATTERN, LINK_PATTERN, AUTOLINK_PATTERN, AUTOMAIL_PATTERN, HTML_PATTERN, ENTITY_PATTERN, NOT_STRONG_PATTERN, STRONG_EM_PATTERN, STRONG_EM_PATTERN_2, STRONG_PATTERN, STRONG_PATTERN_2, EMPHASIS_PATTERN, EMPHASIS_PATTERN_2 # The order of the handlers matters!!! ] self.registerExtensions(extensions = extensions, configs = extension_configs) self.reset() def registerExtensions(self, extensions, configs) : if not configs : configs = {} for ext in extensions : extension_module_name = "mdx_" + ext try : module = __import__(extension_module_name) except : message(CRITICAL, "couldn't load extension %s (looking for %s module)" % (ext, extension_module_name) ) else : if configs.has_key(ext) : configs_for_ext = configs[ext] else : configs_for_ext = [] extension = module.makeExtension(configs_for_ext) extension.extendMarkdown(self, globals()) def registerExtension(self, extension) : """ This gets called by the extension """ self.registeredExtensions.append(extension) def reset(self) : """Resets all state variables so that we can start with a new text.""" self.references={} self.htmlStash = HtmlStash() HTML_BLOCK_PREPROCESSOR.stash = self.htmlStash REFERENCE_PREPROCESSOR.references = self.references HTML_PATTERN.stash = self.htmlStash ENTITY_PATTERN.stash = self.htmlStash REFERENCE_PATTERN.references = self.references IMAGE_REFERENCE_PATTERN.references = self.references for extension in self.registeredExtensions : extension.reset() def _transform(self): """Transforms the Markdown text into a XHTML body document @returns: A NanoDom Document """ # Setup the document self.doc = Document() self.top_element = self.doc.createElement("span") self.top_element.appendChild(self.doc.createTextNode('\n')) self.top_element.setAttribute('class', 'markdown') self.doc.appendChild(self.top_element) # Fixup the source text text = self.source.strip() text = text.replace("\r\n", "\n").replace("\r", "\n") text += "\n\n" text = text.expandtabs(TAB_LENGTH) # Split into lines and run the preprocessors that will work with # self.lines self.lines = text.split("\n") # Run the pre-processors on the lines for prep in self.preprocessors : self.lines = prep.run(self.lines) # Create a NanoDom tree from the lines and attach it to Document buffer = [] for line in self.lines : if line.startswith("#") : self._processSection(self.top_element, buffer) buffer = [line] else : buffer.append(line) self._processSection(self.top_element, buffer) #self._processSection(self.top_element, self.lines) # Not sure why I put this in but let's leave it for now. self.top_element.appendChild(self.doc.createTextNode('\n')) # Run the post-processors for postprocessor in self.postprocessors : postprocessor.run(self.doc) return self.doc def _processSection(self, parent_elem, lines, inList = 0, looseList = 0) : """Process a section of a source document, looking for high level structural elements like lists, block quotes, code segments, html blocks, etc. Some those then get stripped of their high level markup (e.g. get unindented) and the lower-level markup is processed recursively. @param parent_elem: A NanoDom element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None""" if not lines : return # Check if this section starts with a list, a blockquote or # a code block processFn = { 'ul' : self._processUList, 'ol' : self._processOList, 'quoted' : self._processQuote, 'tabbed' : self._processCodeBlock } for regexp in ['ul', 'ol', 'quoted', 'tabbed'] : m = RE.regExp[regexp].match(lines[0]) if m : processFn[regexp](parent_elem, lines, inList) return # We are NOT looking at one of the high-level structures like # lists or blockquotes. So, it's just a regular paragraph # (though perhaps nested inside a list or something else). If # we are NOT inside a list, we just need to look for a blank # line to find the end of the block. If we ARE inside a # list, however, we need to consider that a sublist does not # need to be separated by a blank line. Rather, the following # markup is legal: # # * The top level list item # # Another paragraph of the list. This is where we are now. # * Underneath we might have a sublist. # if inList : start, theRest = self._linesUntil(lines, (lambda line: RE.regExp['ul'].match(line) or RE.regExp['ol'].match(line) or not line.strip())) self._processSection(parent_elem, start, inList - 1, looseList = looseList) self._processSection(parent_elem, theRest, inList - 1, looseList = looseList) else : # Ok, so it's just a simple block paragraph, theRest = self._linesUntil(lines, lambda line: not line.strip()) if len(paragraph) and paragraph[0].startswith('#') : m = RE.regExp['header'].match(paragraph[0]) if m : level = len(m.group(1)) h = self.doc.createElement("h%d" % level) parent_elem.appendChild(h) for item in self._handleInlineWrapper(m.group(2).strip()) : h.appendChild(item) else : message(CRITICAL, "We've got a problem header!") elif paragraph : list = self._handleInlineWrapper("\n".join(paragraph)) if ( parent_elem.nodeName == 'li' and not (looseList or parent_elem.childNodes)): #and not parent_elem.childNodes) : # If this is the first paragraph inside "li", don't # put <p> around it - append the paragraph bits directly # onto parent_elem el = parent_elem else : # Otherwise make a "p" element el = self.doc.createElement("p") parent_elem.appendChild(el) for item in list : el.appendChild(item) if theRest : theRest = theRest[1:] # skip the first (blank) line self._processSection(parent_elem, theRest, inList) def _processUList(self, parent_elem, lines, inList) : self._processList(parent_elem, lines, inList, listexpr='ul', tag = 'ul') def _processOList(self, parent_elem, lines, inList) : self._processList(parent_elem, lines, inList, listexpr='ol', tag = 'ol') def _processList(self, parent_elem, lines, inList, listexpr, tag) : """Given a list of document lines starting with a list item, finds the end of the list, breaks it up, and recursively processes each list item and the remainder of the text file. @param parent_elem: A dom element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None""" ul = self.doc.createElement(tag) # ul might actually be '<ol>' parent_elem.appendChild(ul) looseList = 0 # Make a list of list items items = [] item = -1 i = 0 # a counter to keep track of where we are for line in lines : loose = 0 if not line.strip() : # If we see a blank line, this _might_ be the end of the list i += 1 loose = 1 # Find the next non-blank line for j in range(i, len(lines)) : if lines[j].strip() : next = lines[j] break else : # There is no more text => end of the list break # Check if the next non-blank line is still a part of the list if ( RE.regExp['ul'].match(next) or RE.regExp['ol'].match(next) or RE.regExp['tabbed'].match(next) ): # get rid of any white space in the line items[item].append(line.strip()) looseList = loose or looseList continue else : break # found end of the list # Now we need to detect list items (at the current level) # while also detabing child elements if necessary for expr in ['ul', 'ol', 'tabbed']: m = RE.regExp[expr].match(line) if m : if expr in ['ul', 'ol'] : # We are looking at a new item #if m.group(1) : # Removed the check to allow for a blank line # at the beginning of the list item items.append([m.group(1)]) item += 1 elif expr == 'tabbed' : # This line needs to be detabbed items[item].append(m.group(4)) #after the 'tab' i += 1 break else : items[item].append(line) # Just regular continuation i += 1 # added on 2006.02.25 else : i += 1 # Add the dom elements for item in items : li = self.doc.createElement("li") ul.appendChild(li) self._processSection(li, item, inList + 1, looseList = looseList) # Process the remaining part of the section self._processSection(parent_elem, lines[i:], inList) def _linesUntil(self, lines, condition) : """ A utility function to break a list of lines upon the first line that satisfied a condition. The condition argument should be a predicate function. """ i = -1 for line in lines : i += 1 if condition(line) : break else : i += 1 return lines[:i], lines[i:] def _processQuote(self, parent_elem, lines, inList) : """Given a list of document lines starting with a quote finds the end of the quote, unindents it and recursively processes the body of the quote and the remainder of the text file. @param parent_elem: DOM element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None """ dequoted = [] i = 0 for line in lines : m = RE.regExp['quoted'].match(line) if m : dequoted.append(m.group(1)) i += 1 else : break else : i += 1 blockquote = self.doc.createElement('blockquote') parent_elem.appendChild(blockquote) self._processSection(blockquote, dequoted, inList) self._processSection(parent_elem, lines[i:], inList) def _processCodeBlock(self, parent_elem, lines, inList) : """Given a list of document lines starting with a code block finds the end of the block, puts it into the dom verbatim wrapped in ("<pre><code>") and recursively processes the the remainder of the text file. @param parent_elem: DOM element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None""" detabbed, theRest = self.blockGuru.detectTabbed(lines) pre = self.doc.createElement('pre') code = self.doc.createElement('code') parent_elem.appendChild(pre) pre.appendChild(code) text = "\n".join(detabbed).rstrip()+"\n" #text = text.replace("&", "&") code.appendChild(self.doc.createTextNode(text)) self._processSection(parent_elem, theRest, inList) def _handleInlineWrapper (self, line) : parts = [line] for pattern in self.inlinePatterns : i = 0 while i < len(parts) : x = parts[i] if isinstance(x, (str, unicode)) : result = self._applyPattern(x, pattern) if result : i -= 1 parts.remove(x) for y in result : parts.insert(i+1,y) i += 1 for i in range(len(parts)) : x = parts[i] if isinstance(x, (str, unicode)) : parts[i] = self.doc.createTextNode(x) return parts def _handleInline(self, line): """Transform a Markdown line with inline elements to an XHTML fragment. This function uses auxiliary objects called inline patterns. See notes on inline patterns above. @param item: A block of Markdown text @return: A list of NanoDom nodes """ if not(line): return [self.doc.createTextNode(' ')] for pattern in self.inlinePatterns : list = self._applyPattern( line, pattern) if list: return list return [self.doc.createTextNode(line)] def _applyPattern(self, line, pattern) : """ Given a pattern name, this function checks if the line fits the pattern, creates the necessary elements, and returns back a list consisting of NanoDom elements and/or strings. @param line: the text to be processed @param pattern: the pattern to be checked @returns: the appropriate newly created NanoDom element if the pattern matches, None otherwise. """ # match the line to pattern's pre-compiled reg exp. # if no match, move on. m = pattern.getCompiledRegExp().match(line) if not m : return None # if we got a match let the pattern make us a NanoDom node # if it doesn't, move on node = pattern.handleMatch(m, self.doc) # check if any of this nodes have children that need processing if isinstance(node, Element): if not node.nodeName in ["code", "pre"] : for child in node.childNodes : if isinstance(child, TextNode): result = self._handleInlineWrapper(child.value) if result: if result == [child] : continue result.reverse() #to make insertion easier position = node.childNodes.index(child) node.removeChild(child) for item in result: if isinstance(item, (str, unicode)): if len(item) > 0: node.insertChild(position, self.doc.createTextNode(item)) else: node.insertChild(position, item) if node : # Those are in the reverse order! return ( m.groups()[-1], # the string to the left node, # the new node m.group(1)) # the string to the right of the match else : return None def convert (self, source = None): """Return the document in XHTML format. @returns: A serialized XHTML body.""" #try : if source is not None : self.source = source if not self.source : return "" self.source = removeBOM(self.source, self.encoding) doc = self._transform() xml = doc.toxml() #finally: # doc.unlink() # Let's stick in all the raw html pieces for i in range(self.htmlStash.html_counter) : html = self.htmlStash.rawHtmlBlocks[i] if self.safeMode : html = HTML_REMOVED_TEXT xml = xml.replace("<p>%s\n</p>" % (HTML_PLACEHOLDER % i), html + "\n") xml = xml.replace(HTML_PLACEHOLDER % i, html) # And return everything but the top level tag if self.stripTopLevelTags : xml = xml.strip()[23:-7] + "\n" for pp in self.textPostprocessors : xml = pp.run(xml) return self.docType + xml __str__ = convert # deprecated - will be changed in 1.7 to report # information about the MD instance toString = __str__ # toString() method is deprecated def __unicode__(self): """Return the document in XHTML format as a Unicode object. """ return str(self)#.decode(self.encoding) toUnicode = __unicode__ # deprecated - will be removed in 1.7 # ==================================================================== def markdownFromFile(input = None, output = None, extensions = [], encoding = None, message_threshold = CRITICAL, safe = False) : global MESSAGE_THRESHOLD MESSAGE_THRESHOLD = message_threshold message(VERBOSE, "input file: %s" % input) if not encoding : encoding = "utf-8" input_file = codecs.open(input, mode="r", encoding=encoding) text = input_file.read() input_file.close() new_text = markdown(text, extensions, encoding, safe_mode = safe) if output : output_file = codecs.open(output, "w", encoding=encoding) output_file.write(new_text) output_file.close() else : sys.stdout.write(new_text.encode(encoding)) def markdown(text, extensions = [], encoding = None, safe_mode = False) : message(VERBOSE, "in markdown.markdown(), received text:\n%s" % text) extension_names = [] extension_configs = {} for ext in extensions : pos = ext.find("(") if pos == -1 : extension_names.append(ext) else : name = ext[:pos] extension_names.append(name) pairs = [x.split("=") for x in ext[pos+1:-1].split(",")] configs = [(x.strip(), y.strip()) for (x, y) in pairs] extension_configs[name] = configs md = Markdown(extensions=extension_names, extension_configs=extension_configs, safe_mode = safe_mode) return md.convert(text) class Extension : def __init__(self, configs = {}) : self.config = configs def getConfig(self, key) : if self.config.has_key(key) : return self.config[key][0] else : return "" def getConfigInfo(self) : return [(key, self.config[key][1]) for key in self.config.keys()] def setConfig(self, key, value) : self.config[key][0] = value OPTPARSE_WARNING = """ Python 2.3 or higher required for advanced command line options. For lower versions of Python use: %s INPUT_FILE > OUTPUT_FILE """ % EXECUTABLE_NAME_FOR_USAGE def parse_options() : try : optparse = __import__("optparse") except : if len(sys.argv) == 2 : return {'input' : sys.argv[1], 'output' : None, 'message_threshold' : CRITICAL, 'safe' : False, 'extensions' : [], 'encoding' : None } else : print OPTPARSE_WARNING return None parser = optparse.OptionParser(usage="%prog INPUTFILE [options]") parser.add_option("-f", "--file", dest="filename", help="write output to OUTPUT_FILE", metavar="OUTPUT_FILE") parser.add_option("-e", "--encoding", dest="encoding", help="encoding for input and output files",) parser.add_option("-q", "--quiet", default = CRITICAL, action="store_const", const=NONE, dest="verbose", help="suppress all messages") parser.add_option("-v", "--verbose", action="store_const", const=INFO, dest="verbose", help="print info messages") parser.add_option("-s", "--safe", action="store_const", const=True, dest="safe", help="same mode (strip user's HTML tag)") parser.add_option("--noisy", action="store_const", const=VERBOSE, dest="verbose", help="print debug messages") parser.add_option("-x", "--extension", action="append", dest="extensions", help = "load extension EXTENSION", metavar="EXTENSION") (options, args) = parser.parse_args() if not len(args) == 1 : parser.print_help() return None else : input_file = args[0] if not options.extensions : options.extensions = [] return {'input' : input_file, 'output' : options.filename, 'message_threshold' : options.verbose, 'safe' : options.safe, 'extensions' : options.extensions, 'encoding' : options.encoding } if __name__ == '__main__': """ Run Markdown from the command line. """ options = parse_options() #if os.access(inFile, os.R_OK): if not options : sys.exit(0) markdownFromFile(**options) ���������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/�����������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0021540�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Amps and angle encoding.html�������������������������0000664�0000000�0000000�00000000771�14107073154�0026674�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>AT&T has an ampersand in their name.</p> <p>AT&T is another way to write it.</p> <p>This & that.</p> <p>4 < 5.</p> <p>6 > 5.</p> <p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p> <p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p> <p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p> <p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p> �������python-markdown2-2.4.1/test/markdowntest-cases/Amps and angle encoding.tags�������������������������0000664�0000000�0000000�00000000134�14107073154�0026657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This fails only because python-markdown2 now escapes the naked '>'. knownfailure issue21 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Amps and angle encoding.text�������������������������0000664�0000000�0000000�00000000575�14107073154�0026716�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������AT&T has an ampersand in their name. AT&T is another way to write it. This & that. 4 < 5. 6 > 5. Here's a [link] [1] with an ampersand in the URL. Here's a link with an amersand in the link text: [AT&T] [2]. Here's an inline [link](/script?foo=1&bar=2). Here's an inline [link](</script?foo=1&bar=2>). [1]: http://example.com/?foo=1&bar=2 [2]: http://att.com/ "AT&T"�����������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Auto links.html��������������������������������������0000664�0000000�0000000�00000001042�14107073154�0024434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Link: <a href="http://example.com/">http://example.com/</a>.</p> <p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p> <ul> <li>In a list?</li> <li><a href="http://example.com/">http://example.com/</a></li> <li>It should.</li> </ul> <blockquote> <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p> </blockquote> <p>Auto-links should not occur here: <code><http://example.com/></code></p> <pre><code>or here: <http://example.com/> </code></pre> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Auto links.text��������������������������������������0000664�0000000�0000000�00000000407�14107073154�0024460�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Link: <http://example.com/>. With an ampersand: <http://example.com/?foo=1&bar=2> * In a list? * <http://example.com/> * It should. > Blockquoted: <http://example.com/> Auto-links should not occur here: `<http://example.com/>` or here: <http://example.com/>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Backslash escapes.html�������������������������������0000664�0000000�0000000�00000002426�14107073154�0025731�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>These should all get escaped:</p> <p>Backslash: \</p> <p>Backtick: `</p> <p>Asterisk: *</p> <p>Underscore: _</p> <p>Left brace: {</p> <p>Right brace: }</p> <p>Left bracket: [</p> <p>Right bracket: ]</p> <p>Left paren: (</p> <p>Right paren: )</p> <p>Greater-than: ></p> <p>Hash: #</p> <p>Period: .</p> <p>Bang: !</p> <p>Plus: +</p> <p>Minus: -</p> <p>These should not, because they occur within a code block:</p> <pre><code>Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- </code></pre> <p>Nor should these, which occur in code spans:</p> <p>Backslash: <code>\\</code></p> <p>Backtick: <code>\`</code></p> <p>Asterisk: <code>\*</code></p> <p>Underscore: <code>\_</code></p> <p>Left brace: <code>\{</code></p> <p>Right brace: <code>\}</code></p> <p>Left bracket: <code>\[</code></p> <p>Right bracket: <code>\]</code></p> <p>Left paren: <code>\(</code></p> <p>Right paren: <code>\)</code></p> <p>Greater-than: <code>\></code></p> <p>Hash: <code>\#</code></p> <p>Period: <code>\.</code></p> <p>Bang: <code>\!</code></p> <p>Plus: <code>\+</code></p> <p>Minus: <code>\-</code></p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Backslash escapes.text�������������������������������0000664�0000000�0000000�00000001571�14107073154�0025751�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������These should all get escaped: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- These should not, because they occur within a code block: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- Nor should these, which occur in code spans: Backslash: `\\` Backtick: `` \` `` Asterisk: `\*` Underscore: `\_` Left brace: `\{` Right brace: `\}` Left bracket: `\[` Right bracket: `\]` Left paren: `\(` Right paren: `\)` Greater-than: `\>` Hash: `\#` Period: `\.` Bang: `\!` Plus: `\+` Minus: `\-` ���������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Blockquotes with code blocks.html��������������������0000664�0000000�0000000�00000000272�14107073154�0030007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>Example:</p> <pre><code>sub status { print "working"; } </code></pre> <p>Or:</p> <pre><code>sub status { return "working"; } </code></pre> </blockquote> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Blockquotes with code blocks.text��������������������0000664�0000000�0000000�00000000207�14107073154�0030025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> Example: > > sub status { > print "working"; > } > > Or: > > sub status { > return "working"; > } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Hard-wrapped paragraphs with list-like lines.html����0000664�0000000�0000000�00000000323�14107073154�0032760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.</p> <p>Here's one with a bullet. * criminey.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Hard-wrapped paragraphs with list-like lines.text����0000664�0000000�0000000�00000000305�14107073154�0033000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item. Here's one with a bullet. * criminey. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Horizontal rules.html��������������������������������0000664�0000000�0000000�00000000661�14107073154�0025675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Dashes:</p> <hr /> <hr /> <hr /> <hr /> <pre><code>--- </code></pre> <hr /> <hr /> <hr /> <hr /> <pre><code>- - - </code></pre> <p>Asterisks:</p> <hr /> <hr /> <hr /> <hr /> <pre><code>*** </code></pre> <hr /> <hr /> <hr /> <hr /> <pre><code>* * * </code></pre> <p>Underscores:</p> <hr /> <hr /> <hr /> <hr /> <pre><code>___ </code></pre> <hr /> <hr /> <hr /> <hr /> <pre><code>_ _ _ </code></pre> �������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Horizontal rules.text��������������������������������0000664�0000000�0000000�00000000416�14107073154�0025713�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Dashes: --- --- --- --- --- - - - - - - - - - - - - - - - Asterisks: *** *** *** *** *** * * * * * * * * * * * * * * * Underscores: ___ ___ ___ ___ ___ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML (Advanced).html��������������������������0000664�0000000�0000000�00000000224�14107073154�0026176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Simple block on one line:</p> <div>foo</div> <p>And nested without indentation:</p> <div> <div> <div> foo </div> </div> <div>bar</div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML (Advanced).tags��������������������������0000664�0000000�0000000�00000000121�14107073154�0026164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure dontcare # need a re-write based on html5lib (or something) to fix �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML (Advanced).text��������������������������0000664�0000000�0000000�00000000206�14107073154�0026216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Simple block on one line: <div>foo</div> And nested without indentation: <div> <div> <div> foo </div> </div> <div>bar</div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML (Simple).html����������������������������0000664�0000000�0000000�00000001420�14107073154�0025721�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Here's a simple block:</p> <div> foo </div> <p>This should be a code block, though:</p> <pre><code><div> foo </div> </code></pre> <p>As should this:</p> <pre><code><div>foo</div> </code></pre> <p>Now, nested:</p> <div> <div> <div> foo </div> </div> </div> <p>This should just be an HTML comment:</p> <!-- Comment --> <p>Multiline:</p> <!-- Blah Blah --> <p>Code block:</p> <pre><code><!-- Comment --> </code></pre> <p>Just plain comment, with trailing spaces on the line:</p> <!-- foo --> <p>Code:</p> <pre><code><hr /> </code></pre> <p>Hr's:</p> <hr> <hr/> <hr /> <hr> <hr/> <hr /> <hr class="foo" id="bar" /> <hr class="foo" id="bar"/> <hr class="foo" id="bar" > ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML (Simple).text����������������������������0000664�0000000�0000000�00000001051�14107073154�0025741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Here's a simple block: <div> foo </div> This should be a code block, though: <div> foo </div> As should this: <div>foo</div> Now, nested: <div> <div> <div> foo </div> </div> </div> This should just be an HTML comment: <!-- Comment --> Multiline: <!-- Blah Blah --> Code block: <!-- Comment --> Just plain comment, with trailing spaces on the line: <!-- foo --> Code: <hr /> Hr's: <hr> <hr/> <hr /> <hr> <hr/> <hr /> <hr class="foo" id="bar" /> <hr class="foo" id="bar"/> <hr class="foo" id="bar" > ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML comments.html����������������������������0000664�0000000�0000000�00000000274�14107073154�0026202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Paragraph one.</p> <!-- This is a simple comment --> <!-- This is another comment. --> <p>Paragraph two.</p> <!-- one comment block -- -- with two comments --> <p>The end.</p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Inline HTML comments.text����������������������������0000664�0000000�0000000�00000000244�14107073154�0026217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Paragraph one. <!-- This is a simple comment --> <!-- This is another comment. --> Paragraph two. <!-- one comment block -- -- with two comments --> The end. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Links, inline style.html�����������������������������0000664�0000000�0000000�00000000431�14107073154�0026140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Just a <a href="/url/">URL</a>.</p> <p><a href="/url/" title="title">URL and title</a>.</p> <p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p> <p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p> <p><a href="">Empty</a>.</p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Links, inline style.text�����������������������������0000664�0000000�0000000�00000000256�14107073154�0026165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Just a [URL](/url/). [URL and title](/url/ "title"). [URL and title](/url/ "title preceded by two spaces"). [URL and title](/url/ "title preceded by a tab"). [Empty](). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Links, reference style.html��������������������������0000664�0000000�0000000�00000000627�14107073154�0026627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Foo <a href="/url/" title="Title">bar</a>.</p> <p>Foo <a href="/url/" title="Title">bar</a>.</p> <p>Foo <a href="/url/" title="Title">bar</a>.</p> <p>With <a href="/url/">embedded [brackets]</a>.</p> <p>Indented <a href="/url">once</a>.</p> <p>Indented <a href="/url">twice</a>.</p> <p>Indented <a href="/url">thrice</a>.</p> <p>Indented [four][] times.</p> <pre><code>[four]: /url </code></pre> ���������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Links, reference style.text��������������������������0000664�0000000�0000000�00000000421�14107073154�0026637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Foo [bar] [1]. Foo [bar][1]. Foo [bar] [1]. [1]: /url/ "Title" With [embedded [brackets]] [b]. Indented [once][]. Indented [twice][]. Indented [thrice][]. Indented [four][] times. [once]: /url [twice]: /url [thrice]: /url [four]: /url [b]: /url/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Literal quotes in titles.html������������������������0000664�0000000�0000000�00000000243�14107073154�0027176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p> <p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Literal quotes in titles.text������������������������0000664�0000000�0000000�00000000154�14107073154�0027217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Foo [bar][]. Foo [bar](/url/ "Title with "quotes" inside"). [bar]: /url/ "Title with "quotes" inside" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Markdown Documentation - Basics.html�����������������0000664�0000000�0000000�00000022250�14107073154�0030305�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Markdown: Basics</h1> <ul id="ProjectSubmenu"> <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> <li><a class="selected" title="Markdown Basics">Basics</a></li> <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li> <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> </ul> <h2>Getting the Gist of Markdown's Formatting Syntax</h2> <p>This page offers a brief overview of what it's like to use Markdown. The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown.</p> <p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a web application that allows you type your own Markdown-formatted text and translate it to XHTML.</p> <p><strong>Note:</strong> This document is itself written using Markdown; you can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p> <h2>Paragraphs, Headers, Blockquotes</h2> <p>A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs.</p> <p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>. Setext-style headers for <code><h1></code> and <code><h2></code> are created by "underlining" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively. To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the beginning of the line -- the number of hashes equals the resulting HTML header level.</p> <p>Blockquotes are indicated using email-style '<code>></code>' angle brackets.</p> <p>Markdown:</p> <pre><code>A First Level Header ==================== A Second Level Header --------------------- Now is the time for all good men to come to the aid of their country. This is just a regular paragraph. The quick brown fox jumped over the lazy dog's back. ### Header 3 > This is a blockquote. > > This is the second paragraph in the blockquote. > > ## This is an H2 in a blockquote </code></pre> <p>Output:</p> <pre><code><h1>A First Level Header</h1> <h2>A Second Level Header</h2> <p>Now is the time for all good men to come to the aid of their country. This is just a regular paragraph.</p> <p>The quick brown fox jumped over the lazy dog's back.</p> <h3>Header 3</h3> <blockquote> <p>This is a blockquote.</p> <p>This is the second paragraph in the blockquote.</p> <h2>This is an H2 in a blockquote</h2> </blockquote> </code></pre> <h3>Phrase Emphasis</h3> <p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p> <p>Markdown:</p> <pre><code>Some of these words *are emphasized*. Some of these words _are emphasized also_. Use two asterisks for **strong emphasis**. Or, if you prefer, __use two underscores instead__. </code></pre> <p>Output:</p> <pre><code><p>Some of these words <em>are emphasized</em>. Some of these words <em>are emphasized also</em>.</p> <p>Use two asterisks for <strong>strong emphasis</strong>. Or, if you prefer, <strong>use two underscores instead</strong>.</p> </code></pre> <h2>Lists</h2> <p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>, <code>+</code>, and <code>-</code>) as list markers. These three markers are interchangable; this:</p> <pre><code>* Candy. * Gum. * Booze. </code></pre> <p>this:</p> <pre><code>+ Candy. + Gum. + Booze. </code></pre> <p>and this:</p> <pre><code>- Candy. - Gum. - Booze. </code></pre> <p>all produce the same output:</p> <pre><code><ul> <li>Candy.</li> <li>Gum.</li> <li>Booze.</li> </ul> </code></pre> <p>Ordered (numbered) lists use regular numbers, followed by periods, as list markers:</p> <pre><code>1. Red 2. Green 3. Blue </code></pre> <p>Output:</p> <pre><code><ol> <li>Red</li> <li>Green</li> <li>Blue</li> </ol> </code></pre> <p>If you put blank lines between items, you'll get <code><p></code> tags for the list item text. You can create multi-paragraph list items by indenting the paragraphs by 4 spaces or 1 tab:</p> <pre><code>* A list item. With multiple paragraphs. * Another item in the list. </code></pre> <p>Output:</p> <pre><code><ul> <li><p>A list item.</p> <p>With multiple paragraphs.</p></li> <li><p>Another item in the list.</p></li> </ul> </code></pre> <h3>Links</h3> <p>Markdown supports two styles for creating links: <em>inline</em> and <em>reference</em>. With both styles, you use square brackets to delimit the text you want to turn into a link.</p> <p>Inline-style links use parentheses immediately after the link text. For example:</p> <pre><code>This is an [example link](http://example.com/). </code></pre> <p>Output:</p> <pre><code><p>This is an <a href="http://example.com/"> example link</a>.</p> </code></pre> <p>Optionally, you may include a title attribute in the parentheses:</p> <pre><code>This is an [example link](http://example.com/ "With a Title"). </code></pre> <p>Output:</p> <pre><code><p>This is an <a href="http://example.com/" title="With a Title"> example link</a>.</p> </code></pre> <p>Reference-style links allow you to refer to your links by names, which you define elsewhere in your document:</p> <pre><code>I get 10 times more traffic from [Google][1] than from [Yahoo][2] or [MSN][3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" </code></pre> <p>Output:</p> <pre><code><p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> </code></pre> <p>The title attribute is optional. Link names may contain letters, numbers and spaces, but are <em>not</em> case sensitive:</p> <pre><code>I start my morning with a cup of coffee and [The New York Times][NY Times]. [ny times]: http://www.nytimes.com/ </code></pre> <p>Output:</p> <pre><code><p>I start my morning with a cup of coffee and <a href="http://www.nytimes.com/">The New York Times</a>.</p> </code></pre> <h3>Images</h3> <p>Image syntax is very much like link syntax.</p> <p>Inline (titles are optional):</p> <pre><code>![alt text](/path/to/img.jpg "Title") </code></pre> <p>Reference-style:</p> <pre><code>![alt text][id] [id]: /path/to/img.jpg "Title" </code></pre> <p>Both of the above examples produce the same output:</p> <pre><code><img src="/path/to/img.jpg" alt="alt text" title="Title" /> </code></pre> <h3>Code</h3> <p>In a regular paragraph, you can create code span by wrapping text in backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or <code>></code>) will automatically be translated into HTML entities. This makes it easy to use Markdown to write about HTML example code:</p> <pre><code>I strongly recommend against using any `<blink>` tags. I wish SmartyPants used named entities like `&mdash;` instead of decimal-encoded entites like `&#8212;`. </code></pre> <p>Output:</p> <pre><code><p>I strongly recommend against using any <code>&lt;blink&gt;</code> tags.</p> <p>I wish SmartyPants used named entities like <code>&amp;mdash;</code> instead of decimal-encoded entites like <code>&amp;#8212;</code>.</p> </code></pre> <p>To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>, and <code>></code> characters will be escaped automatically.</p> <p>Markdown:</p> <pre><code>If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes: <blockquote> <p>For example.</p> </blockquote> </code></pre> <p>Output:</p> <pre><code><p>If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes:</p> <pre><code>&lt;blockquote&gt; &lt;p&gt;For example.&lt;/p&gt; &lt;/blockquote&gt; </code></pre> </code></pre> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Markdown Documentation - Basics.text�����������������0000664�0000000�0000000�00000017600�14107073154�0030330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Markdown: Basics ================ <ul id="ProjectSubmenu"> <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> <li><a class="selected" title="Markdown Basics">Basics</a></li> <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li> <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> </ul> Getting the Gist of Markdown's Formatting Syntax ------------------------------------------------ This page offers a brief overview of what it's like to use Markdown. The [syntax page] [s] provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown. It's also helpful to simply try Markdown out; the [Dingus] [d] is a web application that allows you type your own Markdown-formatted text and translate it to XHTML. **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL] [src]. [s]: /projects/markdown/syntax "Markdown Syntax" [d]: /projects/markdown/dingus "Markdown Dingus" [src]: /projects/markdown/basics.text ## Paragraphs, Headers, Blockquotes ## A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs. Markdown offers two styles of headers: *Setext* and *atx*. Setext-style headers for `<h1>` and `<h2>` are created by "underlining" with equal signs (`=`) and hyphens (`-`), respectively. To create an atx-style header, you put 1-6 hash marks (`#`) at the beginning of the line -- the number of hashes equals the resulting HTML header level. Blockquotes are indicated using email-style '`>`' angle brackets. Markdown: A First Level Header ==================== A Second Level Header --------------------- Now is the time for all good men to come to the aid of their country. This is just a regular paragraph. The quick brown fox jumped over the lazy dog's back. ### Header 3 > This is a blockquote. > > This is the second paragraph in the blockquote. > > ## This is an H2 in a blockquote Output: <h1>A First Level Header</h1> <h2>A Second Level Header</h2> <p>Now is the time for all good men to come to the aid of their country. This is just a regular paragraph.</p> <p>The quick brown fox jumped over the lazy dog's back.</p> <h3>Header 3</h3> <blockquote> <p>This is a blockquote.</p> <p>This is the second paragraph in the blockquote.</p> <h2>This is an H2 in a blockquote</h2> </blockquote> ### Phrase Emphasis ### Markdown uses asterisks and underscores to indicate spans of emphasis. Markdown: Some of these words *are emphasized*. Some of these words _are emphasized also_. Use two asterisks for **strong emphasis**. Or, if you prefer, __use two underscores instead__. Output: <p>Some of these words <em>are emphasized</em>. Some of these words <em>are emphasized also</em>.</p> <p>Use two asterisks for <strong>strong emphasis</strong>. Or, if you prefer, <strong>use two underscores instead</strong>.</p> ## Lists ## Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, `+`, and `-`) as list markers. These three markers are interchangable; this: * Candy. * Gum. * Booze. this: + Candy. + Gum. + Booze. and this: - Candy. - Gum. - Booze. all produce the same output: <ul> <li>Candy.</li> <li>Gum.</li> <li>Booze.</li> </ul> Ordered (numbered) lists use regular numbers, followed by periods, as list markers: 1. Red 2. Green 3. Blue Output: <ol> <li>Red</li> <li>Green</li> <li>Blue</li> </ol> If you put blank lines between items, you'll get `<p>` tags for the list item text. You can create multi-paragraph list items by indenting the paragraphs by 4 spaces or 1 tab: * A list item. With multiple paragraphs. * Another item in the list. Output: <ul> <li><p>A list item.</p> <p>With multiple paragraphs.</p></li> <li><p>Another item in the list.</p></li> </ul> ### Links ### Markdown supports two styles for creating links: *inline* and *reference*. With both styles, you use square brackets to delimit the text you want to turn into a link. Inline-style links use parentheses immediately after the link text. For example: This is an [example link](http://example.com/). Output: <p>This is an <a href="http://example.com/"> example link</a>.</p> Optionally, you may include a title attribute in the parentheses: This is an [example link](http://example.com/ "With a Title"). Output: <p>This is an <a href="http://example.com/" title="With a Title"> example link</a>.</p> Reference-style links allow you to refer to your links by names, which you define elsewhere in your document: I get 10 times more traffic from [Google][1] than from [Yahoo][2] or [MSN][3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" Output: <p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> The title attribute is optional. Link names may contain letters, numbers and spaces, but are *not* case sensitive: I start my morning with a cup of coffee and [The New York Times][NY Times]. [ny times]: http://www.nytimes.com/ Output: <p>I start my morning with a cup of coffee and <a href="http://www.nytimes.com/">The New York Times</a>.</p> ### Images ### Image syntax is very much like link syntax. Inline (titles are optional): ![alt text](/path/to/img.jpg "Title") Reference-style: ![alt text][id] [id]: /path/to/img.jpg "Title" Both of the above examples produce the same output: <img src="/path/to/img.jpg" alt="alt text" title="Title" /> ### Code ### In a regular paragraph, you can create code span by wrapping text in backtick quotes. Any ampersands (`&`) and angle brackets (`<` or `>`) will automatically be translated into HTML entities. This makes it easy to use Markdown to write about HTML example code: I strongly recommend against using any `<blink>` tags. I wish SmartyPants used named entities like `—` instead of decimal-encoded entites like `—`. Output: <p>I strongly recommend against using any <code><blink></code> tags.</p> <p>I wish SmartyPants used named entities like <code>&mdash;</code> instead of decimal-encoded entites like <code>&#8212;</code>.</p> To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, and `>` characters will be escaped automatically. Markdown: If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes: <blockquote> <p>For example.</p> </blockquote> Output: <p>If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes:</p> <pre><code><blockquote> <p>For example.</p> </blockquote> </code></pre> ��������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Markdown Documentation - Syntax.html�����������������0000664�0000000�0000000�00000076051�14107073154�0030377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Markdown: Syntax</h1> <ul id="ProjectSubmenu"> <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li> <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li> <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> </ul> <ul> <li><a href="#overview">Overview</a> <ul> <li><a href="#philosophy">Philosophy</a></li> <li><a href="#html">Inline HTML</a></li> <li><a href="#autoescape">Automatic Escaping for Special Characters</a></li> </ul></li> <li><a href="#block">Block Elements</a> <ul> <li><a href="#p">Paragraphs and Line Breaks</a></li> <li><a href="#header">Headers</a></li> <li><a href="#blockquote">Blockquotes</a></li> <li><a href="#list">Lists</a></li> <li><a href="#precode">Code Blocks</a></li> <li><a href="#hr">Horizontal Rules</a></li> </ul></li> <li><a href="#span">Span Elements</a> <ul> <li><a href="#link">Links</a></li> <li><a href="#em">Emphasis</a></li> <li><a href="#code">Code</a></li> <li><a href="#img">Images</a></li> </ul></li> <li><a href="#misc">Miscellaneous</a> <ul> <li><a href="#backslash">Backslash Escapes</a></li> <li><a href="#autolink">Automatic Links</a></li> </ul></li> </ul> <p><strong>Note:</strong> This document is itself written using Markdown; you can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p> <hr /> <h2 id="overview">Overview</h2> <h3 id="philosophy">Philosophy</h3> <p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p> <p>Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions. While Markdown's syntax has been influenced by several existing text-to-HTML filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>, <a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email.</p> <p>To this end, Markdown's syntax is comprised entirely of punctuation characters, which punctuation characters have been carefully chosen so as to look like what they mean. E.g., asterisks around a word actually look like *emphasis*. Markdown lists look like, well, lists. Even blockquotes look like quoted passages of text, assuming you've ever used email.</p> <h3 id="html">Inline HTML</h3> <p>Markdown's syntax is intended for one purpose: to be used as a format for <em>writing</em> for the web.</p> <p>Markdown is not a replacement for HTML, or even close to it. Its syntax is very small, corresponding only to a very small subset of HTML tags. The idea is <em>not</em> to create a syntax that makes it easier to insert HTML tags. In my opinion, HTML tags are already easy to insert. The idea for Markdown is to make it easy to read, write, and edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em> format. Thus, Markdown's formatting syntax only addresses issues that can be conveyed in plain text.</p> <p>For any markup that is not covered by Markdown's syntax, you simply use HTML itself. There's no need to preface it or delimit it to indicate that you're switching from Markdown to HTML; you just use the tags.</p> <p>The only restrictions are that block-level HTML elements -- e.g. <code><div></code>, <code><table></code>, <code><pre></code>, <code><p></code>, etc. -- must be separated from surrounding content by blank lines, and the start and end tags of the block should not be indented with tabs or spaces. Markdown is smart enough not to add extra (unwanted) <code><p></code> tags around HTML block-level tags.</p> <p>For example, to add an HTML table to a Markdown article:</p> <pre><code>This is a regular paragraph. <table> <tr> <td>Foo</td> </tr> </table> This is another regular paragraph. </code></pre> <p>Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an HTML block.</p> <p>Span-level HTML tags -- e.g. <code><span></code>, <code><cite></code>, or <code><del></code> -- can be used anywhere in a Markdown paragraph, list item, or header. If you want, you can even use HTML tags instead of Markdown formatting; e.g. if you'd prefer to use HTML <code><a></code> or <code><img></code> tags instead of Markdown's link or image syntax, go right ahead.</p> <p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within span-level tags.</p> <h3 id="autoescape">Automatic Escaping for Special Characters</h3> <p>In HTML, there are two characters that demand special treatment: <code><</code> and <code>&</code>. Left angle brackets are used to start tags; ampersands are used to denote HTML entities. If you want to use them as literal characters, you must escape them as entities, e.g. <code>&lt;</code>, and <code>&amp;</code>.</p> <p>Ampersands in particular are bedeviling for web writers. If you want to write about 'AT&T', you need to write '<code>AT&amp;T</code>'. You even need to escape ampersands within URLs. Thus, if you want to link to:</p> <pre><code>http://images.google.com/images?num=30&q=larry+bird </code></pre> <p>you need to encode the URL as:</p> <pre><code>http://images.google.com/images?num=30&amp;q=larry+bird </code></pre> <p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to forget, and is probably the single most common source of HTML validation errors in otherwise well-marked-up web sites.</p> <p>Markdown allows you to use these characters naturally, taking care of all the necessary escaping for you. If you use an ampersand as part of an HTML entity, it remains unchanged; otherwise it will be translated into <code>&amp;</code>.</p> <p>So, if you want to include a copyright symbol in your article, you can write:</p> <pre><code>&copy; </code></pre> <p>and Markdown will leave it alone. But if you write:</p> <pre><code>AT&T </code></pre> <p>Markdown will translate it to:</p> <pre><code>AT&amp;T </code></pre> <p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use angle brackets as delimiters for HTML tags, Markdown will treat them as such. But if you write:</p> <pre><code>4 < 5 </code></pre> <p>Markdown will translate it to:</p> <pre><code>4 &lt; 5 </code></pre> <p>However, inside Markdown code spans and blocks, angle brackets and ampersands are <em>always</em> encoded automatically. This makes it easy to use Markdown to write about HTML code. (As opposed to raw HTML, which is a terrible format for writing about HTML syntax, because every single <code><</code> and <code>&</code> in your example code needs to be escaped.)</p> <hr /> <h2 id="block">Block Elements</h2> <h3 id="p">Paragraphs and Line Breaks</h3> <p>A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs.</p> <p>The implication of the "one or more consecutive lines of text" rule is that Markdown supports "hard-wrapped" text paragraphs. This differs significantly from most other text-to-HTML formatters (including Movable Type's "Convert Line Breaks" option) which translate every line break character in a paragraph into a <code><br /></code> tag.</p> <p>When you <em>do</em> want to insert a <code><br /></code> break tag using Markdown, you end a line with two or more spaces, then type return.</p> <p>Yes, this takes a tad more effort to create a <code><br /></code>, but a simplistic "every line break is a <code><br /></code>" rule wouldn't work for Markdown. Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a> work best -- and look better -- when you format them with hard breaks.</p> <h3 id="header">Headers</h3> <p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p> <p>Setext-style headers are "underlined" using equal signs (for first-level headers) and dashes (for second-level headers). For example:</p> <pre><code>This is an H1 ============= This is an H2 ------------- </code></pre> <p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p> <p>Atx-style headers use 1-6 hash characters at the start of the line, corresponding to header levels 1-6. For example:</p> <pre><code># This is an H1 ## This is an H2 ###### This is an H6 </code></pre> <p>Optionally, you may "close" atx-style headers. This is purely cosmetic -- you can use this if you think it looks better. The closing hashes don't even need to match the number of hashes used to open the header. (The number of opening hashes determines the header level.) :</p> <pre><code># This is an H1 # ## This is an H2 ## ### This is an H3 ###### </code></pre> <h3 id="blockquote">Blockquotes</h3> <p>Markdown uses email-style <code>></code> characters for blockquoting. If you're familiar with quoting passages of text in an email message, then you know how to create a blockquote in Markdown. It looks best if you hard wrap the text and put a <code>></code> before every line:</p> <pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing. </code></pre> <p>Markdown allows you to be lazy and only put the <code>></code> before the first line of a hard-wrapped paragraph:</p> <pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. </code></pre> <p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of <code>></code>:</p> <pre><code>> This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level. </code></pre> <p>Blockquotes can contain other Markdown elements, including headers, lists, and code blocks:</p> <pre><code>> ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script"); </code></pre> <p>Any decent text editor should make email-style quoting easy. For example, with BBEdit, you can make a selection and choose Increase Quote Level from the Text menu.</p> <h3 id="list">Lists</h3> <p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p> <p>Unordered lists use asterisks, pluses, and hyphens -- interchangably -- as list markers:</p> <pre><code>* Red * Green * Blue </code></pre> <p>is equivalent to:</p> <pre><code>+ Red + Green + Blue </code></pre> <p>and:</p> <pre><code>- Red - Green - Blue </code></pre> <p>Ordered lists use numbers followed by periods:</p> <pre><code>1. Bird 2. McHale 3. Parish </code></pre> <p>It's important to note that the actual numbers you use to mark the list have no effect on the HTML output Markdown produces. The HTML Markdown produces from the above list is:</p> <pre><code><ol> <li>Bird</li> <li>McHale</li> <li>Parish</li> </ol> </code></pre> <p>If you instead wrote the list in Markdown like this:</p> <pre><code>1. Bird 1. McHale 1. Parish </code></pre> <p>or even:</p> <pre><code>3. Bird 1. McHale 8. Parish </code></pre> <p>you'd get the exact same HTML output. The point is, if you want to, you can use ordinal numbers in your ordered Markdown lists, so that the numbers in your source match the numbers in your published HTML. But if you want to be lazy, you don't have to.</p> <p>If you do use lazy list numbering, however, you should still start the list with the number 1. At some point in the future, Markdown may support starting ordered lists at an arbitrary number.</p> <p>List markers typically start at the left margin, but may be indented by up to three spaces. List markers must be followed by one or more spaces or a tab.</p> <p>To make lists look nice, you can wrap items with hanging indents:</p> <pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. </code></pre> <p>But if you want to be lazy, you don't have to:</p> <pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. </code></pre> <p>If list items are separated by blank lines, Markdown will wrap the items in <code><p></code> tags in the HTML output. For example, this input:</p> <pre><code>* Bird * Magic </code></pre> <p>will turn into:</p> <pre><code><ul> <li>Bird</li> <li>Magic</li> </ul> </code></pre> <p>But this:</p> <pre><code>* Bird * Magic </code></pre> <p>will turn into:</p> <pre><code><ul> <li><p>Bird</p></li> <li><p>Magic</p></li> </ul> </code></pre> <p>List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be intended by either 4 spaces or one tab:</p> <pre><code>1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing. </code></pre> <p>It looks nice if you indent every line of the subsequent paragraphs, but here again, Markdown will allow you to be lazy:</p> <pre><code>* This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list. </code></pre> <p>To put a blockquote within a list item, the blockquote's <code>></code> delimiters need to be indented:</p> <pre><code>* A list item with a blockquote: > This is a blockquote > inside a list item. </code></pre> <p>To put a code block within a list item, the code block needs to be indented <em>twice</em> -- 8 spaces or two tabs:</p> <pre><code>* A list item with a code block: <code goes here> </code></pre> <p>It's worth noting that it's possible to trigger an ordered list by accident, by writing something like this:</p> <pre><code>1986. What a great season. </code></pre> <p>In other words, a <em>number-period-space</em> sequence at the beginning of a line. To avoid this, you can backslash-escape the period:</p> <pre><code>1986\. What a great season. </code></pre> <h3 id="precode">Code Blocks</h3> <p>Pre-formatted code blocks are used for writing about programming or markup source code. Rather than forming normal paragraphs, the lines of a code block are interpreted literally. Markdown wraps a code block in both <code><pre></code> and <code><code></code> tags.</p> <p>To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab. For example, given this input:</p> <pre><code>This is a normal paragraph: This is a code block. </code></pre> <p>Markdown will generate:</p> <pre><code><p>This is a normal paragraph:</p> <pre><code>This is a code block. </code></pre> </code></pre> <p>One level of indentation -- 4 spaces or 1 tab -- is removed from each line of the code block. For example, this:</p> <pre><code>Here is an example of AppleScript: tell application "Foo" beep end tell </code></pre> <p>will turn into:</p> <pre><code><p>Here is an example of AppleScript:</p> <pre><code>tell application "Foo" beep end tell </code></pre> </code></pre> <p>A code block continues until it reaches a line that is not indented (or the end of the article).</p> <p>Within a code block, ampersands (<code>&</code>) and angle brackets (<code><</code> and <code>></code>) are automatically converted into HTML entities. This makes it very easy to include example HTML source code using Markdown -- just paste it and indent it, and Markdown will handle the hassle of encoding the ampersands and angle brackets. For example, this:</p> <pre><code> <div class="footer"> &copy; 2004 Foo Corporation </div> </code></pre> <p>will turn into:</p> <pre><code><pre><code>&lt;div class="footer"&gt; &amp;copy; 2004 Foo Corporation &lt;/div&gt; </code></pre> </code></pre> <p>Regular Markdown syntax is not processed within code blocks. E.g., asterisks are just literal asterisks within a code block. This means it's also easy to use Markdown to write about Markdown's own syntax.</p> <h3 id="hr">Horizontal Rules</h3> <p>You can produce a horizontal rule tag (<code><hr /></code>) by placing three or more hyphens, asterisks, or underscores on a line by themselves. If you wish, you may use spaces between the hyphens or asterisks. Each of the following lines will produce a horizontal rule:</p> <pre><code>* * * *** ***** - - - --------------------------------------- _ _ _ </code></pre> <hr /> <h2 id="span">Span Elements</h2> <h3 id="link">Links</h3> <p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p> <p>In both styles, the link text is delimited by [square brackets].</p> <p>To create an inline link, use a set of regular parentheses immediately after the link text's closing square bracket. Inside the parentheses, put the URL where you want the link to point, along with an <em>optional</em> title for the link, surrounded in quotes. For example:</p> <pre><code>This is [an example](http://example.com/ "Title") inline link. [This link](http://example.net/) has no title attribute. </code></pre> <p>Will produce:</p> <pre><code><p>This is <a href="http://example.com/" title="Title"> an example</a> inline link.</p> <p><a href="http://example.net/">This link</a> has no title attribute.</p> </code></pre> <p>If you're referring to a local resource on the same server, you can use relative paths:</p> <pre><code>See my [About](/about/) page for details. </code></pre> <p>Reference-style links use a second set of square brackets, inside which you place a label of your choosing to identify the link:</p> <pre><code>This is [an example][id] reference-style link. </code></pre> <p>You can optionally use a space to separate the sets of brackets:</p> <pre><code>This is [an example] [id] reference-style link. </code></pre> <p>Then, anywhere in the document, you define your link label like this, on a line by itself:</p> <pre><code>[id]: http://example.com/ "Optional Title Here" </code></pre> <p>That is:</p> <ul> <li>Square brackets containing the link identifier (optionally indented from the left margin using up to three spaces);</li> <li>followed by a colon;</li> <li>followed by one or more spaces (or tabs);</li> <li>followed by the URL for the link;</li> <li>optionally followed by a title attribute for the link, enclosed in double or single quotes.</li> </ul> <p>The link URL may, optionally, be surrounded by angle brackets:</p> <pre><code>[id]: <http://example.com/> "Optional Title Here" </code></pre> <p>You can put the title attribute on the next line and use extra spaces or tabs for padding, which tends to look better with longer URLs:</p> <pre><code>[id]: http://example.com/longish/path/to/resource/here "Optional Title Here" </code></pre> <p>Link definitions are only used for creating links during Markdown processing, and are stripped from your document in the HTML output.</p> <p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p> <pre><code>[link text][a] [link text][A] </code></pre> <p>are equivalent.</p> <p>The <em>implicit link name</em> shortcut allows you to omit the name of the link, in which case the link text itself is used as the name. Just use an empty set of square brackets -- e.g., to link the word "Google" to the google.com web site, you could simply write:</p> <pre><code>[Google][] </code></pre> <p>And then define the link:</p> <pre><code>[Google]: http://google.com/ </code></pre> <p>Because link names may contain spaces, this shortcut even works for multiple words in the link text:</p> <pre><code>Visit [Daring Fireball][] for more information. </code></pre> <p>And then define the link:</p> <pre><code>[Daring Fireball]: http://daringfireball.net/ </code></pre> <p>Link definitions can be placed anywhere in your Markdown document. I tend to put them immediately after each paragraph in which they're used, but if you want, you can put them all at the end of your document, sort of like footnotes.</p> <p>Here's an example of reference links in action:</p> <pre><code>I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" </code></pre> <p>Using the implicit link name shortcut, you could instead write:</p> <pre><code>I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [google]: http://google.com/ "Google" [yahoo]: http://search.yahoo.com/ "Yahoo Search" [msn]: http://search.msn.com/ "MSN Search" </code></pre> <p>Both of the above examples will produce the following HTML output:</p> <pre><code><p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> </code></pre> <p>For comparison, here is the same paragraph written using Markdown's inline link style:</p> <pre><code>I get 10 times more traffic from [Google](http://google.com/ "Google") than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or [MSN](http://search.msn.com/ "MSN Search"). </code></pre> <p>The point of reference-style links is not that they're easier to write. The point is that with reference-style links, your document source is vastly more readable. Compare the above examples: using reference-style links, the paragraph itself is only 81 characters long; with inline-style links, it's 176 characters; and as raw HTML, it's 234 characters. In the raw HTML, there's more markup than there is text.</p> <p>With Markdown's reference-style links, a source document much more closely resembles the final output, as rendered in a browser. By allowing you to move the markup-related metadata out of the paragraph, you can add links without interrupting the narrative flow of your prose.</p> <h3 id="em">Emphasis</h3> <p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an HTML <code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML <code><strong></code> tag. E.g., this input:</p> <pre><code>*single asterisks* _single underscores_ **double asterisks** __double underscores__ </code></pre> <p>will produce:</p> <pre><code><em>single asterisks</em> <em>single underscores</em> <strong>double asterisks</strong> <strong>double underscores</strong> </code></pre> <p>You can use whichever style you prefer; the lone restriction is that the same character must be used to open and close an emphasis span.</p> <p>Emphasis can be used in the middle of a word:</p> <pre><code>un*fucking*believable </code></pre> <p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a literal asterisk or underscore.</p> <p>To produce a literal asterisk or underscore at a position where it would otherwise be used as an emphasis delimiter, you can backslash escape it:</p> <pre><code>\*this text is surrounded by literal asterisks\* </code></pre> <h3 id="code">Code</h3> <p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>). Unlike a pre-formatted code block, a code span indicates code within a normal paragraph. For example:</p> <pre><code>Use the `printf()` function. </code></pre> <p>will produce:</p> <pre><code><p>Use the <code>printf()</code> function.</p> </code></pre> <p>To include a literal backtick character within a code span, you can use multiple backticks as the opening and closing delimiters:</p> <pre><code>``There is a literal backtick (`) here.`` </code></pre> <p>which will produce this:</p> <pre><code><p><code>There is a literal backtick (`) here.</code></p> </code></pre> <p>The backtick delimiters surrounding a code span may include spaces -- one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span:</p> <pre><code>A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` `` </code></pre> <p>will produce:</p> <pre><code><p>A single backtick in a code span: <code>`</code></p> <p>A backtick-delimited string in a code span: <code>`foo`</code></p> </code></pre> <p>With a code span, ampersands and angle brackets are encoded as HTML entities automatically, which makes it easy to include example HTML tags. Markdown will turn this:</p> <pre><code>Please don't use any `<blink>` tags. </code></pre> <p>into:</p> <pre><code><p>Please don't use any <code>&lt;blink&gt;</code> tags.</p> </code></pre> <p>You can write this:</p> <pre><code>`&#8212;` is the decimal-encoded equivalent of `&mdash;`. </code></pre> <p>to produce:</p> <pre><code><p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p> </code></pre> <h3 id="img">Images</h3> <p>Admittedly, it's fairly difficult to devise a "natural" syntax for placing images into a plain text document format.</p> <p>Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p> <p>Inline image syntax looks like this:</p> <pre><code>![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title") </code></pre> <p>That is:</p> <ul> <li>An exclamation mark: <code>!</code>;</li> <li>followed by a set of square brackets, containing the <code>alt</code> attribute text for the image;</li> <li>followed by a set of parentheses, containing the URL or path to the image, and an optional <code>title</code> attribute enclosed in double or single quotes.</li> </ul> <p>Reference-style image syntax looks like this:</p> <pre><code>![Alt text][id] </code></pre> <p>Where "id" is the name of a defined image reference. Image references are defined using syntax identical to link references:</p> <pre><code>[id]: url/to/image "Optional title attribute" </code></pre> <p>As of this writing, Markdown has no syntax for specifying the dimensions of an image; if this is important to you, you can simply use regular HTML <code><img></code> tags.</p> <hr /> <h2 id="misc">Miscellaneous</h2> <h3 id="autolink">Automatic Links</h3> <p>Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p> <pre><code><http://example.com/> </code></pre> <p>Markdown will turn this into:</p> <pre><code><a href="http://example.com/">http://example.com/</a> </code></pre> <p>Automatic links for email addresses work similarly, except that Markdown will also perform a bit of randomized decimal and hex entity-encoding to help obscure your address from address-harvesting spambots. For example, Markdown will turn this:</p> <pre><code><address@example.com> </code></pre> <p>into something like this:</p> <pre><code><a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65; &#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111; &#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61; &#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a> </code></pre> <p>which will render in a browser as a clickable link to "address@example.com".</p> <p>(This sort of entity-encoding trick will indeed fool many, if not most, address-harvesting bots, but it definitely won't fool all of them. It's better than nothing, but an address published in this way will probably eventually start receiving spam.)</p> <h3 id="backslash">Backslash Escapes</h3> <p>Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown's formatting syntax. For example, if you wanted to surround a word with literal asterisks (instead of an HTML <code><em></code> tag), you can backslashes before the asterisks, like this:</p> <pre><code>\*literal asterisks\* </code></pre> <p>Markdown provides backslash escapes for the following characters:</p> <pre><code>\ backslash ` backtick * asterisk _ underscore {} curly braces [] square brackets () parentheses # hash mark + plus sign - minus sign (hyphen) . dot ! exclamation mark </code></pre> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Markdown Documentation - Syntax.text�����������������0000664�0000000�0000000�00000065447�14107073154�0030426�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Markdown: Syntax ================ <ul id="ProjectSubmenu"> <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li> <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li> <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> </ul> * [Overview](#overview) * [Philosophy](#philosophy) * [Inline HTML](#html) * [Automatic Escaping for Special Characters](#autoescape) * [Block Elements](#block) * [Paragraphs and Line Breaks](#p) * [Headers](#header) * [Blockquotes](#blockquote) * [Lists](#list) * [Code Blocks](#precode) * [Horizontal Rules](#hr) * [Span Elements](#span) * [Links](#link) * [Emphasis](#em) * [Code](#code) * [Images](#img) * [Miscellaneous](#misc) * [Backslash Escapes](#backslash) * [Automatic Links](#autolink) **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL][src]. [src]: /projects/markdown/syntax.text * * * <h2 id="overview">Overview</h2> <h3 id="philosophy">Philosophy</h3> Markdown is intended to be as easy-to-read and easy-to-write as is feasible. Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions. While Markdown's syntax has been influenced by several existing text-to-HTML filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], [Grutatext] [5], and [EtText] [6] -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email. [1]: http://docutils.sourceforge.net/mirror/setext.html [2]: http://www.aaronsw.com/2002/atx/ [3]: http://textism.com/tools/textile/ [4]: http://docutils.sourceforge.net/rst.html [5]: http://www.triptico.com/software/grutatxt.html [6]: http://ettext.taint.org/doc/ To this end, Markdown's syntax is comprised entirely of punctuation characters, which punctuation characters have been carefully chosen so as to look like what they mean. E.g., asterisks around a word actually look like \*emphasis\*. Markdown lists look like, well, lists. Even blockquotes look like quoted passages of text, assuming you've ever used email. <h3 id="html">Inline HTML</h3> Markdown's syntax is intended for one purpose: to be used as a format for *writing* for the web. Markdown is not a replacement for HTML, or even close to it. Its syntax is very small, corresponding only to a very small subset of HTML tags. The idea is *not* to create a syntax that makes it easier to insert HTML tags. In my opinion, HTML tags are already easy to insert. The idea for Markdown is to make it easy to read, write, and edit prose. HTML is a *publishing* format; Markdown is a *writing* format. Thus, Markdown's formatting syntax only addresses issues that can be conveyed in plain text. For any markup that is not covered by Markdown's syntax, you simply use HTML itself. There's no need to preface it or delimit it to indicate that you're switching from Markdown to HTML; you just use the tags. The only restrictions are that block-level HTML elements -- e.g. `<div>`, `<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding content by blank lines, and the start and end tags of the block should not be indented with tabs or spaces. Markdown is smart enough not to add extra (unwanted) `<p>` tags around HTML block-level tags. For example, to add an HTML table to a Markdown article: This is a regular paragraph. <table> <tr> <td>Foo</td> </tr> </table> This is another regular paragraph. Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an HTML block. Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be used anywhere in a Markdown paragraph, list item, or header. If you want, you can even use HTML tags instead of Markdown formatting; e.g. if you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's link or image syntax, go right ahead. Unlike block-level HTML tags, Markdown syntax *is* processed within span-level tags. <h3 id="autoescape">Automatic Escaping for Special Characters</h3> In HTML, there are two characters that demand special treatment: `<` and `&`. Left angle brackets are used to start tags; ampersands are used to denote HTML entities. If you want to use them as literal characters, you must escape them as entities, e.g. `<`, and `&`. Ampersands in particular are bedeviling for web writers. If you want to write about 'AT&T', you need to write '`AT&T`'. You even need to escape ampersands within URLs. Thus, if you want to link to: http://images.google.com/images?num=30&q=larry+bird you need to encode the URL as: http://images.google.com/images?num=30&q=larry+bird in your anchor tag `href` attribute. Needless to say, this is easy to forget, and is probably the single most common source of HTML validation errors in otherwise well-marked-up web sites. Markdown allows you to use these characters naturally, taking care of all the necessary escaping for you. If you use an ampersand as part of an HTML entity, it remains unchanged; otherwise it will be translated into `&`. So, if you want to include a copyright symbol in your article, you can write: © and Markdown will leave it alone. But if you write: AT&T Markdown will translate it to: AT&T Similarly, because Markdown supports [inline HTML](#html), if you use angle brackets as delimiters for HTML tags, Markdown will treat them as such. But if you write: 4 < 5 Markdown will translate it to: 4 < 5 However, inside Markdown code spans and blocks, angle brackets and ampersands are *always* encoded automatically. This makes it easy to use Markdown to write about HTML code. (As opposed to raw HTML, which is a terrible format for writing about HTML syntax, because every single `<` and `&` in your example code needs to be escaped.) * * * <h2 id="block">Block Elements</h2> <h3 id="p">Paragraphs and Line Breaks</h3> A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs. The implication of the "one or more consecutive lines of text" rule is that Markdown supports "hard-wrapped" text paragraphs. This differs significantly from most other text-to-HTML formatters (including Movable Type's "Convert Line Breaks" option) which translate every line break character in a paragraph into a `<br />` tag. When you *do* want to insert a `<br />` break tag using Markdown, you end a line with two or more spaces, then type return. Yes, this takes a tad more effort to create a `<br />`, but a simplistic "every line break is a `<br />`" rule wouldn't work for Markdown. Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] work best -- and look better -- when you format them with hard breaks. [bq]: #blockquote [l]: #list <h3 id="header">Headers</h3> Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. Setext-style headers are "underlined" using equal signs (for first-level headers) and dashes (for second-level headers). For example: This is an H1 ============= This is an H2 ------------- Any number of underlining `=`'s or `-`'s will work. Atx-style headers use 1-6 hash characters at the start of the line, corresponding to header levels 1-6. For example: # This is an H1 ## This is an H2 ###### This is an H6 Optionally, you may "close" atx-style headers. This is purely cosmetic -- you can use this if you think it looks better. The closing hashes don't even need to match the number of hashes used to open the header. (The number of opening hashes determines the header level.) : # This is an H1 # ## This is an H2 ## ### This is an H3 ###### <h3 id="blockquote">Blockquotes</h3> Markdown uses email-style `>` characters for blockquoting. If you're familiar with quoting passages of text in an email message, then you know how to create a blockquote in Markdown. It looks best if you hard wrap the text and put a `>` before every line: > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing. Markdown allows you to be lazy and only put the `>` before the first line of a hard-wrapped paragraph: > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of `>`: > This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level. Blockquotes can contain other Markdown elements, including headers, lists, and code blocks: > ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script"); Any decent text editor should make email-style quoting easy. For example, with BBEdit, you can make a selection and choose Increase Quote Level from the Text menu. <h3 id="list">Lists</h3> Markdown supports ordered (numbered) and unordered (bulleted) lists. Unordered lists use asterisks, pluses, and hyphens -- interchangably -- as list markers: * Red * Green * Blue is equivalent to: + Red + Green + Blue and: - Red - Green - Blue Ordered lists use numbers followed by periods: 1. Bird 2. McHale 3. Parish It's important to note that the actual numbers you use to mark the list have no effect on the HTML output Markdown produces. The HTML Markdown produces from the above list is: <ol> <li>Bird</li> <li>McHale</li> <li>Parish</li> </ol> If you instead wrote the list in Markdown like this: 1. Bird 1. McHale 1. Parish or even: 3. Bird 1. McHale 8. Parish you'd get the exact same HTML output. The point is, if you want to, you can use ordinal numbers in your ordered Markdown lists, so that the numbers in your source match the numbers in your published HTML. But if you want to be lazy, you don't have to. If you do use lazy list numbering, however, you should still start the list with the number 1. At some point in the future, Markdown may support starting ordered lists at an arbitrary number. List markers typically start at the left margin, but may be indented by up to three spaces. List markers must be followed by one or more spaces or a tab. To make lists look nice, you can wrap items with hanging indents: * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. But if you want to be lazy, you don't have to: * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. If list items are separated by blank lines, Markdown will wrap the items in `<p>` tags in the HTML output. For example, this input: * Bird * Magic will turn into: <ul> <li>Bird</li> <li>Magic</li> </ul> But this: * Bird * Magic will turn into: <ul> <li><p>Bird</p></li> <li><p>Magic</p></li> </ul> List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be intended by either 4 spaces or one tab: 1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing. It looks nice if you indent every line of the subsequent paragraphs, but here again, Markdown will allow you to be lazy: * This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list. To put a blockquote within a list item, the blockquote's `>` delimiters need to be indented: * A list item with a blockquote: > This is a blockquote > inside a list item. To put a code block within a list item, the code block needs to be indented *twice* -- 8 spaces or two tabs: * A list item with a code block: <code goes here> It's worth noting that it's possible to trigger an ordered list by accident, by writing something like this: 1986. What a great season. In other words, a *number-period-space* sequence at the beginning of a line. To avoid this, you can backslash-escape the period: 1986\. What a great season. <h3 id="precode">Code Blocks</h3> Pre-formatted code blocks are used for writing about programming or markup source code. Rather than forming normal paragraphs, the lines of a code block are interpreted literally. Markdown wraps a code block in both `<pre>` and `<code>` tags. To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab. For example, given this input: This is a normal paragraph: This is a code block. Markdown will generate: <p>This is a normal paragraph:</p> <pre><code>This is a code block. </code></pre> One level of indentation -- 4 spaces or 1 tab -- is removed from each line of the code block. For example, this: Here is an example of AppleScript: tell application "Foo" beep end tell will turn into: <p>Here is an example of AppleScript:</p> <pre><code>tell application "Foo" beep end tell </code></pre> A code block continues until it reaches a line that is not indented (or the end of the article). Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) are automatically converted into HTML entities. This makes it very easy to include example HTML source code using Markdown -- just paste it and indent it, and Markdown will handle the hassle of encoding the ampersands and angle brackets. For example, this: <div class="footer"> © 2004 Foo Corporation </div> will turn into: <pre><code><div class="footer"> &copy; 2004 Foo Corporation </div> </code></pre> Regular Markdown syntax is not processed within code blocks. E.g., asterisks are just literal asterisks within a code block. This means it's also easy to use Markdown to write about Markdown's own syntax. <h3 id="hr">Horizontal Rules</h3> You can produce a horizontal rule tag (`<hr />`) by placing three or more hyphens, asterisks, or underscores on a line by themselves. If you wish, you may use spaces between the hyphens or asterisks. Each of the following lines will produce a horizontal rule: * * * *** ***** - - - --------------------------------------- _ _ _ * * * <h2 id="span">Span Elements</h2> <h3 id="link">Links</h3> Markdown supports two style of links: *inline* and *reference*. In both styles, the link text is delimited by [square brackets]. To create an inline link, use a set of regular parentheses immediately after the link text's closing square bracket. Inside the parentheses, put the URL where you want the link to point, along with an *optional* title for the link, surrounded in quotes. For example: This is [an example](http://example.com/ "Title") inline link. [This link](http://example.net/) has no title attribute. Will produce: <p>This is <a href="http://example.com/" title="Title"> an example</a> inline link.</p> <p><a href="http://example.net/">This link</a> has no title attribute.</p> If you're referring to a local resource on the same server, you can use relative paths: See my [About](/about/) page for details. Reference-style links use a second set of square brackets, inside which you place a label of your choosing to identify the link: This is [an example][id] reference-style link. You can optionally use a space to separate the sets of brackets: This is [an example] [id] reference-style link. Then, anywhere in the document, you define your link label like this, on a line by itself: [id]: http://example.com/ "Optional Title Here" That is: * Square brackets containing the link identifier (optionally indented from the left margin using up to three spaces); * followed by a colon; * followed by one or more spaces (or tabs); * followed by the URL for the link; * optionally followed by a title attribute for the link, enclosed in double or single quotes. The link URL may, optionally, be surrounded by angle brackets: [id]: <http://example.com/> "Optional Title Here" You can put the title attribute on the next line and use extra spaces or tabs for padding, which tends to look better with longer URLs: [id]: http://example.com/longish/path/to/resource/here "Optional Title Here" Link definitions are only used for creating links during Markdown processing, and are stripped from your document in the HTML output. Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: [link text][a] [link text][A] are equivalent. The *implicit link name* shortcut allows you to omit the name of the link, in which case the link text itself is used as the name. Just use an empty set of square brackets -- e.g., to link the word "Google" to the google.com web site, you could simply write: [Google][] And then define the link: [Google]: http://google.com/ Because link names may contain spaces, this shortcut even works for multiple words in the link text: Visit [Daring Fireball][] for more information. And then define the link: [Daring Fireball]: http://daringfireball.net/ Link definitions can be placed anywhere in your Markdown document. I tend to put them immediately after each paragraph in which they're used, but if you want, you can put them all at the end of your document, sort of like footnotes. Here's an example of reference links in action: I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" Using the implicit link name shortcut, you could instead write: I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [google]: http://google.com/ "Google" [yahoo]: http://search.yahoo.com/ "Yahoo Search" [msn]: http://search.msn.com/ "MSN Search" Both of the above examples will produce the following HTML output: <p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> For comparison, here is the same paragraph written using Markdown's inline link style: I get 10 times more traffic from [Google](http://google.com/ "Google") than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or [MSN](http://search.msn.com/ "MSN Search"). The point of reference-style links is not that they're easier to write. The point is that with reference-style links, your document source is vastly more readable. Compare the above examples: using reference-style links, the paragraph itself is only 81 characters long; with inline-style links, it's 176 characters; and as raw HTML, it's 234 characters. In the raw HTML, there's more markup than there is text. With Markdown's reference-style links, a source document much more closely resembles the final output, as rendered in a browser. By allowing you to move the markup-related metadata out of the paragraph, you can add links without interrupting the narrative flow of your prose. <h3 id="em">Emphasis</h3> Markdown treats asterisks (`*`) and underscores (`_`) as indicators of emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML `<strong>` tag. E.g., this input: *single asterisks* _single underscores_ **double asterisks** __double underscores__ will produce: <em>single asterisks</em> <em>single underscores</em> <strong>double asterisks</strong> <strong>double underscores</strong> You can use whichever style you prefer; the lone restriction is that the same character must be used to open and close an emphasis span. Emphasis can be used in the middle of a word: un*fucking*believable But if you surround an `*` or `_` with spaces, it'll be treated as a literal asterisk or underscore. To produce a literal asterisk or underscore at a position where it would otherwise be used as an emphasis delimiter, you can backslash escape it: \*this text is surrounded by literal asterisks\* <h3 id="code">Code</h3> To indicate a span of code, wrap it with backtick quotes (`` ` ``). Unlike a pre-formatted code block, a code span indicates code within a normal paragraph. For example: Use the `printf()` function. will produce: <p>Use the <code>printf()</code> function.</p> To include a literal backtick character within a code span, you can use multiple backticks as the opening and closing delimiters: ``There is a literal backtick (`) here.`` which will produce this: <p><code>There is a literal backtick (`) here.</code></p> The backtick delimiters surrounding a code span may include spaces -- one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span: A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` `` will produce: <p>A single backtick in a code span: <code>`</code></p> <p>A backtick-delimited string in a code span: <code>`foo`</code></p> With a code span, ampersands and angle brackets are encoded as HTML entities automatically, which makes it easy to include example HTML tags. Markdown will turn this: Please don't use any `<blink>` tags. into: <p>Please don't use any <code><blink></code> tags.</p> You can write this: `—` is the decimal-encoded equivalent of `—`. to produce: <p><code>&#8212;</code> is the decimal-encoded equivalent of <code>&mdash;</code>.</p> <h3 id="img">Images</h3> Admittedly, it's fairly difficult to devise a "natural" syntax for placing images into a plain text document format. Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: *inline* and *reference*. Inline image syntax looks like this: ![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title") That is: * An exclamation mark: `!`; * followed by a set of square brackets, containing the `alt` attribute text for the image; * followed by a set of parentheses, containing the URL or path to the image, and an optional `title` attribute enclosed in double or single quotes. Reference-style image syntax looks like this: ![Alt text][id] Where "id" is the name of a defined image reference. Image references are defined using syntax identical to link references: [id]: url/to/image "Optional title attribute" As of this writing, Markdown has no syntax for specifying the dimensions of an image; if this is important to you, you can simply use regular HTML `<img>` tags. * * * <h2 id="misc">Miscellaneous</h2> <h3 id="autolink">Automatic Links</h3> Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: <http://example.com/> Markdown will turn this into: <a href="http://example.com/">http://example.com/</a> Automatic links for email addresses work similarly, except that Markdown will also perform a bit of randomized decimal and hex entity-encoding to help obscure your address from address-harvesting spambots. For example, Markdown will turn this: <address@example.com> into something like this: <a href="mailto:addre ss@example.co m">address@exa mple.com</a> which will render in a browser as a clickable link to "address@example.com". (This sort of entity-encoding trick will indeed fool many, if not most, address-harvesting bots, but it definitely won't fool all of them. It's better than nothing, but an address published in this way will probably eventually start receiving spam.) <h3 id="backslash">Backslash Escapes</h3> Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown's formatting syntax. For example, if you wanted to surround a word with literal asterisks (instead of an HTML `<em>` tag), you can backslashes before the asterisks, like this: \*literal asterisks\* Markdown provides backslash escapes for the following characters: \ backslash ` backtick * asterisk _ underscore {} curly braces [] square brackets () parentheses # hash mark + plus sign - minus sign (hyphen) . dot ! exclamation mark �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Nested blockquotes.html������������������������������0000664�0000000�0000000�00000000151�14107073154�0026161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>foo</p> <blockquote> <p>bar</p> </blockquote> <p>foo</p> </blockquote> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Nested blockquotes.text������������������������������0000664�0000000�0000000�00000000030�14107073154�0026175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> foo > > > bar > > foo ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Ordered and unordered lists.html���������������������0000664�0000000�0000000�00000003062�14107073154�0027625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h2>Unordered</h2> <p>Asterisks tight:</p> <ul> <li>asterisk 1</li> <li>asterisk 2</li> <li>asterisk 3</li> </ul> <p>Asterisks loose:</p> <ul> <li><p>asterisk 1</p></li> <li><p>asterisk 2</p></li> <li><p>asterisk 3</p></li> </ul> <hr /> <p>Pluses tight:</p> <ul> <li>Plus 1</li> <li>Plus 2</li> <li>Plus 3</li> </ul> <p>Pluses loose:</p> <ul> <li><p>Plus 1</p></li> <li><p>Plus 2</p></li> <li><p>Plus 3</p></li> </ul> <hr /> <p>Minuses tight:</p> <ul> <li>Minus 1</li> <li>Minus 2</li> <li>Minus 3</li> </ul> <p>Minuses loose:</p> <ul> <li><p>Minus 1</p></li> <li><p>Minus 2</p></li> <li><p>Minus 3</p></li> </ul> <h2>Ordered</h2> <p>Tight:</p> <ol> <li>First</li> <li>Second</li> <li>Third</li> </ol> <p>and:</p> <ol> <li>One</li> <li>Two</li> <li>Three</li> </ol> <p>Loose using tabs:</p> <ol> <li><p>First</p></li> <li><p>Second</p></li> <li><p>Third</p></li> </ol> <p>and using spaces:</p> <ol> <li><p>One</p></li> <li><p>Two</p></li> <li><p>Three</p></li> </ol> <p>Multiple paragraphs:</p> <ol> <li><p>Item 1, graf one.</p> <p>Item 2. graf two. The quick brown fox jumped over the lazy dog's back.</p></li> <li><p>Item 2.</p></li> <li><p>Item 3.</p></li> </ol> <h2>Nested</h2> <ul> <li>Tab <ul> <li>Tab <ul> <li>Tab</li> </ul></li> </ul></li> </ul> <p>Here's another:</p> <ol> <li>First</li> <li>Second: <ul> <li>Fee</li> <li>Fie</li> <li>Foe</li> </ul></li> <li>Third</li> </ol> <p>Same thing but with paragraphs:</p> <ol> <li><p>First</p></li> <li><p>Second:</p> <ul> <li>Fee</li> <li>Fie</li> <li>Foe</li> </ul></li> <li><p>Third</p></li> </ol> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Ordered and unordered lists.text���������������������0000664�0000000�0000000�00000001511�14107073154�0027642�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Unordered Asterisks tight: * asterisk 1 * asterisk 2 * asterisk 3 Asterisks loose: * asterisk 1 * asterisk 2 * asterisk 3 * * * Pluses tight: + Plus 1 + Plus 2 + Plus 3 Pluses loose: + Plus 1 + Plus 2 + Plus 3 * * * Minuses tight: - Minus 1 - Minus 2 - Minus 3 Minuses loose: - Minus 1 - Minus 2 - Minus 3 ## Ordered Tight: 1. First 2. Second 3. Third and: 1. One 2. Two 3. Three Loose using tabs: 1. First 2. Second 3. Third and using spaces: 1. One 2. Two 3. Three Multiple paragraphs: 1. Item 1, graf one. Item 2. graf two. The quick brown fox jumped over the lazy dog's back. 2. Item 2. 3. Item 3. ## Nested * Tab * Tab * Tab Here's another: 1. First 2. Second: * Fee * Fie * Foe 3. Third Same thing but with paragraphs: 1. First 2. Second: * Fee * Fie * Foe 3. Third ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Parens around urls.html������������������������������0000664�0000000�0000000�00000000223�14107073154�0026072�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>(<a href="/url/">link text</a>)</p> <p>(<a href="/url/" title="title">link text</a>)</p> <p>(<a href="/url/" title="title">link text</a>)</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Parens around urls.text������������������������������0000664�0000000�0000000�00000000121�14107073154�0026107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������([link text](/url/)) ([link text](/url/ "title")) ([link text](/url/ 'title')) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Parens in urls.html����������������������������������0000664�0000000�0000000�00000000524�14107073154�0025214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="/ur(inparen)l/">link text</a></p> <p><a href="/ur(inparen)l/" title="title">link text</a></p> <p><a href="/ur(inparen)l/" title="title">link text</a></p> <p><a href="/ur(unblancedr/">link text</a></p> <p><a href="/ur(unblancedr/" title="title">link text</a></p> <p><a href="/ur(unblancedr/" title="title">link text</a></p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Parens in urls.text����������������������������������0000664�0000000�0000000�00000000320�14107073154�0025226�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[link text](/ur(inparen)l/) [link text](/ur(inparen)l/ "title") [link text](/ur(inparen)l/ 'title') [link text](/ur(unblancedr/) [link text](/ur(unblancedr/ "title") [link text](/ur(unblancedr/ 'title') ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Spaces in urls.html����������������������������������0000664�0000000�0000000�00000000505�14107073154�0025201�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="/ur space l/">link text</a></p> <p><a href="/ur space l/" title="title">link text</a></p> <p><a href="/ur space l/" title="title">link text</a></p> <p><a href="/ur(space l/">link text</a></p> <p><a href="/ur(space l/" title="title">link text</a></p> <p><a href="/ur(space l/" title="title">link text</a></p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Spaces in urls.text����������������������������������0000664�0000000�0000000�00000000301�14107073154�0025213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[link text](/ur space l/) [link text](/ur space l/ "title") [link text](/ur space l/ 'title') [link text](/ur(space l/) [link text](/ur(space l/ "title") [link text](/ur(space l/ 'title') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Strong and em together.html��������������������������0000664�0000000�0000000�00000000327�14107073154�0026613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><strong><em>This is strong and em.</em></strong></p> <p>So is <strong><em>this</em></strong> word.</p> <p><strong><em>This is strong and em.</em></strong></p> <p>So is <strong><em>this</em></strong> word.</p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Strong and em together.text��������������������������0000664�0000000�0000000�00000000153�14107073154�0026630�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������***This is strong and em.*** So is ***this*** word. ___This is strong and em.___ So is ___this___ word. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Tabs.html��������������������������������������������0000664�0000000�0000000�00000000667�14107073154�0023330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><p>this is a list item indented with tabs</p></li> <li><p>this is a list item indented with spaces</p></li> </ul> <p>Code:</p> <pre><code>this code block is indented by one tab </code></pre> <p>And:</p> <pre><code> this code block is indented by two tabs </code></pre> <p>And:</p> <pre><code>+ this is an example list item indented with tabs + this is an example list item indented with spaces </code></pre> �������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Tabs.text��������������������������������������������0000664�0000000�0000000�00000000467�14107073154�0023346�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������+ this is a list item indented with tabs + this is a list item indented with spaces Code: this code block is indented by one tab And: this code block is indented by two tabs And: + this is an example list item indented with tabs + this is an example list item indented with spaces ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Tidyness.html����������������������������������������0000664�0000000�0000000�00000000205�14107073154�0024225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>A list within a blockquote:</p> <ul> <li>asterisk 1</li> <li>asterisk 2</li> <li>asterisk 3</li> </ul> </blockquote> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Tidyness.tags����������������������������������������0000664�0000000�0000000�00000000015�14107073154�0024216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/markdowntest-cases/Tidyness.text����������������������������������������0000664�0000000�0000000�00000000116�14107073154�0024246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> A list within a blockquote: > > * asterisk 1 > * asterisk 2 > * asterisk 3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/�����������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0021425�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Backslash escapes.html�������������������������������0000664�0000000�0000000�00000000234�14107073154�0025611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Tricky combinaisons:</p> <p>backslash with \-- two dashes</p> <p>backslash with \> greater than</p> <p>\[test](not a link)</p> <p>\*no emphasis*</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Backslash escapes.tags�������������������������������0000664�0000000�0000000�00000000133�14107073154�0025601�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This fails only because python-markdown2 now escapes the naked '>'. knownfailure issue21 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Backslash escapes.text�������������������������������0000664�0000000�0000000�00000000176�14107073154�0025636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tricky combinaisons: backslash with \\-- two dashes backslash with \\> greater than \\\[test](not a link) \\\*no emphasis*��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Code Spans.html��������������������������������������0000664�0000000�0000000�00000000217�14107073154�0024232�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>From <code><!--</code> to <code>--></code> on two lines.</p> <p>From <code><!--</code> to <code>--></code> on three lines.</p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Code Spans.text��������������������������������������0000664�0000000�0000000�00000000111�14107073154�0024243�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������From `<!--` to `-->` on two lines. From `<!--` to `-->` on three lines. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Code block in a list item.html�����������������������0000664�0000000�0000000�00000000171�14107073154�0026702�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><p>List Item:</p> <pre><code>code block with a blank line </code></pre> <p>within a list item.</p></li> </ul>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Code block in a list item.tags�����������������������0000664�0000000�0000000�00000000077�14107073154�0026701�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure eol dontcare # fails just because of trailing EOL �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Code block in a list item.text�����������������������0000664�0000000�0000000�00000000106�14107073154�0026720�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ * List Item: code block with a blank line within a list item.����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Email auto links.html��������������������������������0000664�0000000�0000000�00000001146�14107073154�0025376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="mailto:michel.fortin@michelf.com">michel.fortin@michelf.com</a></p> <p>International domain names: <a href="mailto:help@tūdaliņ.lv">help@tūdaliņ.lv</a></p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Email auto links.text��������������������������������0000664�0000000�0000000�00000000114�14107073154�0025410�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<michel.fortin@michelf.com> International domain names: <help@tūdaliņ.lv>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Emphasis.html����������������������������������������0000664�0000000�0000000�00000003516�14107073154�0024071�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Combined emphasis:</p> <ol> <li><strong><em>test test</em></strong></li> <li><strong><em>test test</em></strong></li> <li><em>test <strong>test</strong></em></li> <li><strong>test <em>test</em></strong></li> <li><strong><em>test</em> test</strong></li> <li><em><strong>test</strong> test</em></li> <li><strong><em>test</em> test</strong></li> <li><strong>test <em>test</em></strong></li> <li><em>test <strong>test</strong></em></li> <li><em>test <strong>test</strong></em></li> <li><strong>test <em>test</em></strong></li> <li><strong><em>test</em> test</strong></li> <li><em><strong>test</strong> test</em></li> <li><strong><em>test</em> test</strong></li> <li><strong>test <em>test</em></strong></li> <li><em>test <strong>test</strong></em></li> </ol> <p>Incorrect nesting:</p> <ol> <li>*test <strong>test* test</strong></li> <li>_test <strong>test_ test</strong></li> <li>**test <em>test</em>* test*</li> <li>__test <em>test</em>_ test_</li> <li><em>test *test</em> test*</li> <li><em>test _test</em> test_</li> <li><strong>test <strong>test</strong> test</strong></li> <li><strong>test <strong>test</strong> test</strong></li> </ol> <p>No emphasis:</p> <ol> <li>test* test *test</li> <li>test** test **test</li> <li>test_ test _test</li> <li>test__ test __test</li> </ol> <p>Middle-word emphasis (asterisks):</p> <ol> <li><em>a</em>b</li> <li>a<em>b</em></li> <li>a<em>b</em>c</li> <li><strong>a</strong>b</li> <li>a<strong>b</strong></li> <li>a<strong>b</strong>c</li> </ol> <p>Middle-word emphasis (underscore):</p> <ol> <li><em>a</em>b</li> <li>a<em>b</em></li> <li>a<em>b</em>c</li> <li><strong>a</strong>b</li> <li>a<strong>b</strong></li> <li>a<strong>b</strong>c</li> </ol> <p>my<em>precious</em>file.txt</p> <h2>Tricky Cases</h2> <p>E**. <strong>Test</strong> TestTestTest</p> <p>E**. <strong>Test</strong> Test Test Test</p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Emphasis.tags����������������������������������������0000664�0000000�0000000�00000000121�14107073154�0024050�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure dontcare # need a re-write based on html5lib (or something) to fix �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Emphasis.text����������������������������������������0000664�0000000�0000000�00000001733�14107073154�0024110�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Combined emphasis: 1. ***test test*** 2. ___test test___ 3. *test **test*** 4. **test *test*** 5. ***test* test** 6. ***test** test* 7. ***test* test** 8. **test *test*** 9. *test **test*** 10. _test __test___ 11. __test _test___ 12. ___test_ test__ 13. ___test__ test_ 14. ___test_ test__ 15. __test _test___ 16. _test __test___ Incorrect nesting: 1. *test **test* test** 2. _test __test_ test__ 3. **test *test** test* 4. __test _test__ test_ 5. *test *test* test* 6. _test _test_ test_ 7. **test **test** test** 8. __test __test__ test__ No emphasis: 1. test* test *test 2. test** test **test 3. test_ test _test 4. test__ test __test Middle-word emphasis (asterisks): 1. *a*b 2. a*b* 3. a*b*c 4. **a**b 5. a**b** 6. a**b**c Middle-word emphasis (underscore): 1. _a_b 2. a_b_ 3. a_b_c 4. __a__b 5. a__b__ 6. a__b__c my_precious_file.txt ## Tricky Cases E**. **Test** TestTestTest E**. **Test** Test Test Test �������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Headers.html�����������������������������������������0000664�0000000�0000000�00000000512�14107073154�0023664�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Header</h1> <h2>Header</h2> <h3>Header</h3> <hr /> <h1>Header</h1> <p>Paragraph</p> <h2>Header</h2> <p>Paragraph</p> <h3>Header</h3> <p>Paragraph</p> <hr /> <p>Paragraph</p> <h1>Header</h1> <p>Paragraph</p> <p>Paragraph</p> <h2>Header</h2> <p>Paragraph</p> <p>Paragraph</p> <h3>Header</h3> <p>Paragraph</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Headers.text�����������������������������������������0000664�0000000�0000000�00000000346�14107073154�0023711�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Header ====== Header ------ ### Header - - - Header ====== Paragraph Header ------ Paragraph ### Header Paragraph - - - Paragraph Header ====== Paragraph Paragraph Header ------ Paragraph Paragraph ### Header Paragraph������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Images (Untitled).html�������������������������������0000664�0000000�0000000�00000000200�14107073154�0025402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><img src="/url/" alt="alt text" /></p> <p><img src="/url/" alt="alt text" /></p> <p><img src="/url/" alt="alt text" /></p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Images (Untitled).text�������������������������������0000664�0000000�0000000�00000000112�14107073154�0025424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������![alt text](/url/) ![alt text](</url/>) ![alt text][foo] [foo]: /url/������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Simple).html����������������������������0000664�0000000�0000000�00000000234�14107073154�0025610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>With some attributes:</p> <div id="test"> foo </div> <div id="test" class="nono"> foo </div> <p>Hr's:</p> <hr class="foo" id="bar" >��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Simple).tags����������������������������0000664�0000000�0000000�00000000077�14107073154�0025607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure eol dontcare # fails just because of trailing EOL �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Simple).text����������������������������0000664�0000000�0000000�00000000212�14107073154�0025624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������With some attributes: <div id="test"> foo </div> <div id="test" class="nono"> foo </div> Hr's: <hr class="foo" id="bar" > ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Span).html������������������������������0000664�0000000�0000000�00000000254�14107073154�0025262�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><abbr title="` **Attribute Content Is Not A Code Span** `">ACINACS</abbr></p> <p><abbr title="`first backtick!">SB</abbr> <abbr title="`second backtick!">SB</abbr></p>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Span).tags������������������������������0000664�0000000�0000000�00000000121�14107073154�0025245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure dontcare # need a re-write based on html5lib (or something) to fix �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML (Span).text������������������������������0000664�0000000�0000000�00000000236�14107073154�0025302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<abbr title="` **Attribute Content Is Not A Code Span** `">ACINACS</abbr> <abbr title="`first backtick!">SB</abbr> <abbr title="`second backtick!">SB</abbr>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML comments.html����������������������������0000664�0000000�0000000�00000000212�14107073154�0026057�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Paragraph one.</p> <!-- double--dash (invalid SGML comment) --> <p>Paragraph two.</p> <!-- enclosed tag </div> --> <p>The end.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Inline HTML comments.text����������������������������0000664�0000000�0000000�00000000165�14107073154�0026106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Paragraph one. <!-- double--dash (invalid SGML comment) --> Paragraph two. <!-- enclosed tag </div> --> The end. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Ins & del.html���������������������������������������0000664�0000000�0000000�00000000507�14107073154�0023701�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Here is a block tag ins:</p> <ins> <p>Some text</p> </ins> <p><ins>And here it is inside a paragraph.</ins></p> <p>And here it is <ins>in the middle of</ins> a paragraph.</p> <del> <p>Some text</p> </del> <p><del>And here is ins as a paragraph.</del></p> <p>And here it is <del>in the middle of</del> a paragraph.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Ins & del.text���������������������������������������0000664�0000000�0000000�00000000444�14107073154�0023721�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Here is a block tag ins: <ins> <p>Some text</p> </ins> <ins>And here it is inside a paragraph.</ins> And here it is <ins>in the middle of</ins> a paragraph. <del> <p>Some text</p> </del> <del>And here is ins as a paragraph.</del> And here it is <del>in the middle of</del> a paragraph. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Links, inline style.html�����������������������������0000664�0000000�0000000�00000000077�14107073154�0026033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="?}]*+|&)">silly URL w/ angle brackets</a>.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Links, inline style.text�����������������������������0000664�0000000�0000000�00000000053�14107073154�0026045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[silly URL w/ angle brackets](<?}]*+|&)>). �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/MD5 Hashes.html��������������������������������������0000664�0000000�0000000�00000000372�14107073154�0024076�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Character Escapes</h1> <p>The MD5 value for <code>+</code> is "26b17225b626fb9238849fd60eabdf60".</p> <h1>HTML Blocks</h1> <p>test</p> <p>The MD5 value for <code><p>test</p></code> is:</p> <p>6205333b793f34273d75379350b36826</p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/MD5 Hashes.text��������������������������������������0000664�0000000�0000000�00000000264�14107073154�0024116�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Character Escapes The MD5 value for `+` is "26b17225b626fb9238849fd60eabdf60". # HTML Blocks <p>test</p> The MD5 value for `<p>test</p>` is: 6205333b793f34273d75379350b36826��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Nesting.html�����������������������������������������0000664�0000000�0000000�00000000366�14107073154�0023727�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Valid nesting:</p> <p><strong><a href="url">Link</a></strong></p> <p><a href="url"><strong>Link</strong></a></p> <p><strong><a href="url"><strong>Link</strong></a></strong></p> <p>Invalid nesting:</p> <p><a href="url">[Link](url)</a></p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Nesting.tags�����������������������������������������0000664�0000000�0000000�00000000026�14107073154�0023712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure dontcare ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Nesting.text�����������������������������������������0000664�0000000�0000000�00000000153�14107073154�0023741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Valid nesting: **[Link](url)** [**Link**](url) **[**Link**](url)** Invalid nesting: [[Link](url)](url)���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/PHP-Specific Bugs.html�������������������������������0000664�0000000�0000000�00000001066�14107073154�0025351�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This tests for a bug where quotes escaped by PHP when using <code>preg_replace</code> with the <code>/e</code> modifier must be correctly unescaped (hence the <code>_UnslashQuotes</code> function found only in PHP Markdown).</p> <p>Headers below should appear exactly as they are typed (no backslash added or removed).</p> <h1>Header "quoted\" again \""</h1> <h2>Header "quoted\" again \""</h2> <h3>Header "quoted\" again \""</h3> <p>Test with tabs for <code>_Detab</code>:</p> <pre><code>Code 'block' with some "tabs" and "quotes" </code></pre> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/PHP-Specific Bugs.text�������������������������������0000664�0000000�0000000�00000000777�14107073154�0025401�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This tests for a bug where quotes escaped by PHP when using `preg_replace` with the `/e` modifier must be correctly unescaped (hence the `_UnslashQuotes` function found only in PHP Markdown). Headers below should appear exactly as they are typed (no backslash added or removed). Header "quoted\" again \\"" =========================== Header "quoted\" again \\"" --------------------------- ### Header "quoted\" again \\"" ### Test with tabs for `_Detab`: Code 'block' with some "tabs" and "quotes" �python-markdown2-2.4.1/test/php-markdown-cases/Parens in URL.html�����������������������������������0000664�0000000�0000000�00000000730�14107073154�0024555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="/url(test)" title="title">Inline link 1 with parens</a>.</p> <p><a href="/url(test)" title="title">Inline link 2 with parens</a>.</p> <p><a href="/url(test)" title="title">Inline link 3 with non-escaped parens</a>.</p> <p><a href="/url(test)" title="title">Inline link 4 with non-escaped parens</a>.</p> <p><a href="/url(test)" title="title">Reference link 1 with parens</a>.</p> <p><a href="/url(test)" title="title">Reference link 2 with parens</a>.</p>����������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Parens in URL.tags�����������������������������������0000664�0000000�0000000�00000000026�14107073154�0024545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������dontcare knownfailure ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Parens in URL.text�����������������������������������0000664�0000000�0000000�00000000546�14107073154�0024602�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Inline link 1 with parens](/url\(test\) "title"). [Inline link 2 with parens](</url\(test\)> "title"). [Inline link 3 with non-escaped parens](/url(test) "title"). [Inline link 4 with non-escaped parens](</url(test)> "title"). [Reference link 1 with parens][1]. [Reference link 2 with parens][2]. [1]: /url(test) "title" [2]: </url(test)> "title" ����������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Tight blocks.html������������������������������������0000664�0000000�0000000�00000000450�14107073154�0024627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Paragraph and no space: * ciao</p> <p>Paragraph and 1 space: * ciao</p> <p>Paragraph and 3 spaces: * ciao</p> <p>Paragraph and 4 spaces: * ciao</p> <p>Paragraph before header:</p> <h1>Header</h1> <p>Paragraph before blockquote:</p> <blockquote> <p>Some quote.</p> </blockquote> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Tight blocks.tags������������������������������������0000664�0000000�0000000�00000000036�14107073154�0024621�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure dontcare issue90 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-cases/Tight blocks.text������������������������������������0000664�0000000�0000000�00000000321�14107073154�0024644�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Paragraph and no space: * ciao Paragraph and 1 space: * ciao Paragraph and 3 spaces: * ciao Paragraph and 4 spaces: * ciao Paragraph before header: #Header Paragraph before blockquote: >Some quote. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/�����������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0022546�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Abbr.html��������������������������������������0000664�0000000�0000000�00000001600�14107073154�0024277�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Some text about <abbr title="Hyper Text Markup Language">HTML</abbr>, <abbr title="Standard Generalized Markup Language">SGML</abbr> and <abbr title="Hyper Text Markup Language version 4">HTML4</abbr>.</p> <p>Let's talk about the <abbr title="United States of America">U.S.A.</abbr>, (<abbr title="États-Unis d'Amérique">É.U.</abbr> or <abbr title="États-Unis d'Amérique">É.-U. d'A.</abbr> in French).</p> <p>And here we have a <abbr title="Compact Disk">CD</abbr>, some CDs, and some other <abbr title="Compact Disk">CD</abbr>'s.</p> <p>Let's transfert documents through <abbr title="Transmission Control Protocol">TCP</abbr>/<abbr title="Internet Protocol">IP</abbr>, using <abbr title="Transmission Control Protocol">TCP</abbr> packets.</p> <hr /> <p>Bienvenue sur <a href="http://www.bidulecms.com" title="Bidule CMS"><abbr title="Content Management System">CMS</abbr></a>.</p> ��������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Abbr.tags��������������������������������������0000664�0000000�0000000�00000000015�14107073154�0024270�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Abbr.text��������������������������������������0000664�0000000�0000000�00000001207�14107073154�0024322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Some text about HTML, SGML and HTML4. Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French). *[HTML4]: Hyper Text Markup Language version 4 *[HTML]: Hyper Text Markup Language *[SGML]: Standard Generalized Markup Language *[U.S.A.]: United States of America *[É.U.] : États-Unis d'Amérique *[É.-U. d'A.] : États-Unis d'Amérique And here we have a CD, some CDs, and some other CD's. *[CD]: Compact Disk Let's transfert documents through TCP/IP, using TCP packets. *[IP]: Internet Protocol *[TCP]: Transmission Control Protocol --- Bienvenue sur [CMS](http://www.bidulecms.com "Bidule CMS"). *[CMS]: Content Management System�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Definition Lists.html��������������������������0000664�0000000�0000000�00000004351�14107073154�0026606�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>A simple definition list:</p> <dl> <dt>Term 1</dt> <dd>Definition 1</dd> <dt>Term 2</dt> <dd>Definition 2</dd> </dl> <p>With multiple terms:</p> <dl> <dt>Term 1</dt> <dt>Term 2</dt> <dd>Definition 1</dd> <dt>Term 3</dt> <dt>Term 4</dt> <dd>Definition 2</dd> </dl> <p>With multiple definitions:</p> <dl> <dt>Term 1</dt> <dd>Definition 1</dd> <dd>Definition 2</dd> <dt>Term 2</dt> <dd>Definition 3</dd> <dd>Definition 4</dd> </dl> <p>With multiple lines per definition:</p> <dl> <dt>Term 1</dt> <dd>Definition 1 line 1 ... Definition 1 line 2</dd> <dd>Definition 2 line 1 ... Definition 2 line 2</dd> <dt>Term 2</dt> <dd>Definition 3 line 2 ... Definition 3 line 2</dd> <dd>Definition 4 line 2 ... Definition 4 line 2</dd> </dl> <p>With paragraphs:</p> <dl> <dt>Term 1</dt> <dd> <p>Definition 1 (paragraph)</p> </dd> <dt>Term 2</dt> <dd> <p>Definition 2 (paragraph)</p> </dd> </dl> <p>With multiple paragraphs:</p> <dl> <dt>Term 1</dt> <dd> <p>Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2</p> <p>Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2</p> </dd> <dt>Term 2</dt> <dd> <p>Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2 (lazy)</p> <p>Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2 (lazy)</p> </dd> </dl> <hr /> <p>A mix:</p> <dl> <dt>Term 1</dt> <dt>Term 2</dt> <dd> <p>Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2 (lazy)</p> <p>Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2</p> </dd> <dd> <p>Definition 2 paragraph 1 line 1 ... Definition 2 paragraph 1 line 2 (lazy)</p> </dd> <dt>Term 3</dt> <dd>Definition 3 (no paragraph)</dd> <dd>Definition 4 (no paragraph)</dd> <dd>Definition 5 line 1 ... Definition 5 line 2 (no paragraph)</dd> <dd> <p>Definition 6 paragraph 1 line 1 ... Definition 6 paragraph 1 line 2</p> </dd> <dd>Definition 7 (no paragraph)</dd> <dd> <p>Definition 8 paragraph 1 line 1 (forced paragraph) ... Definition 8 paragraph 1 line 2</p> <p>Definition 8 paragraph 2 line 1</p> </dd> <dt>Term 4</dt> <dd> <p>Definition 9 paragraph 1 line 1 (forced paragraph) ... Definition 9 paragraph 1 line 2</p> <p>Definition 9 paragraph 2 line 1</p> </dd> <dd>Definition 10 (no paragraph)</dd> </dl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Definition Lists.tags��������������������������0000664�0000000�0000000�00000000015�14107073154�0026571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Definition Lists.text��������������������������0000664�0000000�0000000�00000003416�14107073154�0026627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������A simple definition list: Term 1 : Definition 1 Term 2 : Definition 2 With multiple terms: Term 1 Term 2 : Definition 1 Term 3 Term 4 : Definition 2 With multiple definitions: Term 1 : Definition 1 : Definition 2 Term 2 : Definition 3 : Definition 4 With multiple lines per definition: Term 1 : Definition 1 line 1 ... Definition 1 line 2 : Definition 2 line 1 ... Definition 2 line 2 Term 2 : Definition 3 line 2 ... Definition 3 line 2 : Definition 4 line 2 ... Definition 4 line 2 With paragraphs: Term 1 : Definition 1 (paragraph) Term 2 : Definition 2 (paragraph) With multiple paragraphs: Term 1 : Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2 Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2 Term 2 : Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2 (lazy) Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2 (lazy) * * * A mix: Term 1 Term 2 : Definition 1 paragraph 1 line 1 ... Definition 1 paragraph 1 line 2 (lazy) Definition 1 paragraph 2 line 1 ... Definition 1 paragraph 2 line 2 : Definition 2 paragraph 1 line 1 ... Definition 2 paragraph 1 line 2 (lazy) Term 3 : Definition 3 (no paragraph) : Definition 4 (no paragraph) : Definition 5 line 1 ... Definition 5 line 2 (no paragraph) : Definition 6 paragraph 1 line 1 ... Definition 6 paragraph 1 line 2 : Definition 7 (no paragraph) : Definition 8 paragraph 1 line 1 (forced paragraph) ... Definition 8 paragraph 1 line 2 Definition 8 paragraph 2 line 1 Term 4 : Definition 9 paragraph 1 line 1 (forced paragraph) ... Definition 9 paragraph 1 line 2 Definition 9 paragraph 2 line 1 : Definition 10 (no paragraph)��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Emphasis.html����������������������������������0000664�0000000�0000000�00000003413�14107073154�0025206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Combined emphasis:</p> <ol> <li><strong><em>test test</em></strong></li> <li><strong><em>test test</em></strong></li> <li><em>test <strong>test</strong></em></li> <li><strong>test <em>test</em></strong></li> <li><strong><em>test</em> test</strong></li> <li><em><strong>test</strong> test</em></li> <li><strong><em>test</em> test</strong></li> <li><strong>test <em>test</em></strong></li> <li><em>test <strong>test</strong></em></li> <li><em>test <strong>test</strong></em></li> <li><strong>test <em>test</em></strong></li> <li><strong><em>test</em> test</strong></li> <li><em><strong>test</strong> test</em></li> <li><strong><em>test</em> test</strong></li> <li><strong>test <em>test</em></strong></li> <li><em>test <strong>test</strong></em></li> </ol> <p>Incorrect nesting:</p> <ol> <li>*test <strong>test* test</strong></li> <li>_test <strong>test_ test</strong></li> <li>**test <em>test</em>* test*</li> <li>__test <em>test</em>_ test_</li> <li><em>test *test</em> test*</li> <li><em>test _test</em> test_</li> <li><strong>test <strong>test</strong> test</strong></li> <li><strong>test <strong>test</strong> test</strong></li> </ol> <p>No emphasis:</p> <ol> <li>test* test *test</li> <li>test** test **test</li> <li>test_ test _test</li> <li>test__ test __test</li> </ol> <p>Middle-word emphasis (asterisks):</p> <ol> <li><em>a</em>b</li> <li>a<em>b</em></li> <li>a<em>b</em>c</li> <li><strong>a</strong>b</li> <li>a<strong>b</strong></li> <li>a<strong>b</strong>c</li> </ol> <p>Middle-word emphasis (underscore):</p> <ol> <li>_a_b</li> <li>a_b_</li> <li>a_b_c</li> <li>__a__b</li> <li>a__b__</li> <li>a__b__c</li> </ol> <p>my_precious_file.txt</p> <h2>Tricky Cases</h2> <p>E**. <strong>Test</strong> TestTestTest</p> <p>E**. <strong>Test</strong> Test Test Test</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Emphasis.tags����������������������������������0000664�0000000�0000000�00000000015�14107073154�0025173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Emphasis.text����������������������������������0000664�0000000�0000000�00000001733�14107073154�0025231�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Combined emphasis: 1. ***test test*** 2. ___test test___ 3. *test **test*** 4. **test *test*** 5. ***test* test** 6. ***test** test* 7. ***test* test** 8. **test *test*** 9. *test **test*** 10. _test __test___ 11. __test _test___ 12. ___test_ test__ 13. ___test__ test_ 14. ___test_ test__ 15. __test _test___ 16. _test __test___ Incorrect nesting: 1. *test **test* test** 2. _test __test_ test__ 3. **test *test** test* 4. __test _test__ test_ 5. *test *test* test* 6. _test _test_ test_ 7. **test **test** test** 8. __test __test__ test__ No emphasis: 1. test* test *test 2. test** test **test 3. test_ test _test 4. test__ test __test Middle-word emphasis (asterisks): 1. *a*b 2. a*b* 3. a*b*c 4. **a**b 5. a**b** 6. a**b**c Middle-word emphasis (underscore): 1. _a_b 2. a_b_ 3. a_b_c 4. __a__b 5. a__b__ 6. a__b__c my_precious_file.txt ## Tricky Cases E**. **Test** TestTestTest E**. **Test** Test Test Test �������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Footnotes.html���������������������������������0000664�0000000�0000000�00000005054�14107073154�0025420�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is the first paragraph.<sup id="fnref:first"><a href="#fn:first" rel="footnote">1</a></sup></p> <ul> <li>List item one.<sup id="fnref:second"><a href="#fn:second" rel="footnote">2</a></sup></li> <li>List item two.<sup id="fnref:third"><a href="#fn:third" rel="footnote">3</a></sup></li> </ul> <h1>Header<sup id="fnref:fourth"><a href="#fn:fourth" rel="footnote">4</a></sup></h1> <p>Some paragraph with a footnote<sup id="fnref:1"><a href="#fn:1" rel="footnote">5</a></sup>, and another<sup id="fnref:2"><a href="#fn:2" rel="footnote">6</a></sup>.</p> <p>Another paragraph with a named footnote<sup id="fnref:fn-name"><a href="#fn:fn-name" rel="footnote">7</a></sup>.</p> <p>This paragraph should not have a footnote marker since the footnote is undefined.[^3]</p> <p>This paragraph should not have a footnote marker since the footnote has already been used before.[^1]</p> <p>This paragraph links to a footnote with plenty of block-level content.<sup id="fnref:block"><a href="#fn:block" rel="footnote">8</a></sup></p> <p>This paragraph host the footnote reference within a footnote test<sup id="fnref:reference"><a href="#fn:reference" rel="footnote">9</a></sup>.</p> <div class="footnotes"> <hr /> <ol> <li id="fn:first"> <p>This is the first note. <a href="#fnref:first" rev="footnote">↩</a></p> </li> <li id="fn:second"> <p>This is the second note. <a href="#fnref:second" rev="footnote">↩</a></p> </li> <li id="fn:third"> <p>This is the third note, defined out of order. <a href="#fnref:third" rev="footnote">↩</a></p> </li> <li id="fn:fourth"> <p>This is the fourth note. <a href="#fnref:fourth" rev="footnote">↩</a></p> </li> <li id="fn:1"> <p>Content for fifth footnote. <a href="#fnref:1" rev="footnote">↩</a></p> </li> <li id="fn:2"> <p>Content for sixth footnote spaning on three lines, with some span-level markup like <em>emphasis</em>, a <a href="http://www.michelf.com/">link</a>. <a href="#fnref:2" rev="footnote">↩</a></p> </li> <li id="fn:fn-name"> <p>Footnote beginning on the line next to the marker. <a href="#fnref:fn-name" rev="footnote">↩</a></p> </li> <li id="fn:block"> <p>Paragraph.</p> <ul> <li>List item</li> </ul> <blockquote> <p>Blockquote</p> </blockquote> <pre><code>Code block </code></pre> <p><a href="#fnref:block" rev="footnote">↩</a></p> </li> <li id="fn:reference"> <p>This footnote attemps to refer to another footnote. This should be impossible.[^impossible] <a href="#fnref:reference" rev="footnote">↩</a></p> </li> </ol> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Footnotes.tags���������������������������������0000664�0000000�0000000�00000000015�14107073154�0025402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Footnotes.text���������������������������������0000664�0000000�0000000�00000002412�14107073154�0025433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is the first paragraph.[^first] [^first]: This is the first note. * List item one.[^second] * List item two.[^third] [^third]: This is the third note, defined out of order. [^second]: This is the second note. [^fourth]: This is the fourth note. # Header[^fourth] Some paragraph with a footnote[^1], and another[^2]. [^1]: Content for fifth footnote. [^2]: Content for sixth footnote spaning on three lines, with some span-level markup like _emphasis_, a [link][]. [link]: http://www.michelf.com/ Another paragraph with a named footnote[^fn-name]. [^fn-name]: Footnote beginning on the line next to the marker. This paragraph should not have a footnote marker since the footnote is undefined.[^3] This paragraph should not have a footnote marker since the footnote has already been used before.[^1] This paragraph links to a footnote with plenty of block-level content.[^block] [^block]: Paragraph. * List item > Blockquote Code block This paragraph host the footnote reference within a footnote test[^reference]. [^reference]: This footnote attemps to refer to another footnote. This should be impossible.[^impossible] [^impossible]: This footnote should not appear, as it is refered from another footnote, which is not allowed. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Inline HTML with Markdown content.html���������0000664�0000000�0000000�00000003450�14107073154�0031533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Markdown inside code blocks</h1> <div> <p>foo</p> </div> <div> <p>foo</p> </div> <div> <p>foo</p> </div> <table> <tr><td>test <em>emphasis</em> (span)</td></tr> </table> <table> <tr><td>test <em>emphasis</em> (span)</td></tr> </table> <table> <tr><td> <p>test <em>emphasis</em> (block)</p> </td></tr> </table> <h2>More complicated</h2> <table> <tr><td> * this is <em>not</em> a list item</td></tr> <tr><td> * this is <em>not</em> a list item</td></tr> <tr><td> <ul> <li>this <em>is</em> a list item</li> </ul> </td></tr> </table> <h2>With indent</h2> <div> <div> <p>This text is no code block: if it was, the closing <code><div></code> would be too and the HTML block would be invalid.</p> <p>Markdown content in HTML blocks is assumed to be indented the same as the block opening tag.</p> <p><strong>This should be the third paragraph after the header.</strong></p> </div> </div> <h2>Code block with rogue <code></div></code>s in Markdown code span and block</h2> <div> <div> <p>This is a code block however:</p> <pre><code></div> </code></pre> <p>Funny isn't it? Here is a code span: <code></div></code>.</p> </div> </div> <div> <div> <ul> <li>List item, not a code block</li> </ul> <p>Some text</p> <pre><code>This is a code block. </code></pre> </div> </div> <h2>No code block in markdown span mode</h2> <p> This is not a code block since Markdown parse paragraph content as span. Code spans like <code></p></code> are allowed though. </p> <p><em>Hello</em> <em>world</em></p> <h2>Preserving attributes and tags on more than one line:</h2> <p class="test" id="12"> Some <em>span</em> content. </p> <h2>Header confusion bug</h2> <table class="canvas"> <tr> <td id="main">Hello World! ============ Hello World!</td> </tr> </table>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Inline HTML with Markdown content.tags���������0000664�0000000�0000000�00000000015�14107073154�0031517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������knownfailure �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Inline HTML with Markdown content.text���������0000664�0000000�0000000�00000003325�14107073154�0031554�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Markdown inside code blocks <div markdown="1"> foo </div> <div markdown='1'> foo </div> <div markdown=1> foo </div> <table> <tr><td markdown="1">test _emphasis_ (span)</td></tr> </table> <table> <tr><td markdown="span">test _emphasis_ (span)</td></tr> </table> <table> <tr><td markdown="block">test _emphasis_ (block)</td></tr> </table> ## More complicated <table> <tr><td markdown="1"> * this is _not_ a list item</td></tr> <tr><td markdown="span"> * this is _not_ a list item</td></tr> <tr><td markdown="block"> * this _is_ a list item </td></tr> </table> ## With indent <div> <div markdown="1"> This text is no code block: if it was, the closing `<div>` would be too and the HTML block would be invalid. Markdown content in HTML blocks is assumed to be indented the same as the block opening tag. **This should be the third paragraph after the header.** </div> </div> ## Code block with rogue `</div>`s in Markdown code span and block <div> <div markdown="1"> This is a code block however: </div> Funny isn't it? Here is a code span: `</div>`. </div> </div> <div> <div markdown="1"> * List item, not a code block Some text This is a code block. </div> </div> ## No code block in markdown span mode <p markdown="1"> This is not a code block since Markdown parse paragraph content as span. Code spans like `</p>` are allowed though. </p> <p markdown="1">_Hello_ _world_</p> ## Preserving attributes and tags on more than one line: <p class="test" markdown="1" id="12"> Some _span_ content. </p> ## Header confusion bug <table class="canvas"> <tr> <td id="main" markdown="1">Hello World! ============ Hello World!</td> </tr> </table> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Tables.html������������������������������������0000664�0000000�0000000�00000007557�14107073154�0024664�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Simple tables</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <p>With leading pipes:</p> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <p>With tailing pipes:</p> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <p>With leading and tailing pipes:</p> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <hr /> <h1>One-column one-row table</h1> <p>With leading pipes:</p> <table> <thead> <tr> <th>Header</th> </tr> </thead> <tbody> <tr> <td>Cell</td> </tr> </tbody> </table> <p>With tailing pipes:</p> <table> <thead> <tr> <th>Header</th> </tr> </thead> <tbody> <tr> <td>Cell</td> </tr> </tbody> </table> <p>With leading and tailing pipes:</p> <table> <thead> <tr> <th>Header</th> </tr> </thead> <tbody> <tr> <td>Cell</td> </tr> </tbody> </table> <hr /> <p>Table alignment:</p> <table> <thead> <tr> <th>Default</th> <th style="text-align:left;">Left</th> <th style="text-align:center;">Center</th> <th style="text-align:right;">Right</th> </tr> </thead> <tbody> <tr> <td>Long Cell</td> <td style="text-align:left;">Long Cell</td> <td style="text-align:center;">Long Cell</td> <td style="text-align:right;">Long Cell</td> </tr> <tr> <td>Cell</td> <td style="text-align:left;">Cell</td> <td style="text-align:center;">Cell</td> <td style="text-align:right;">Cell</td> </tr> </tbody> </table> <p>Table alignment (alternate spacing):</p> <table> <thead> <tr> <th>Default</th> <th style="text-align:left;">Left</th> <th style="text-align:center;">Center</th> <th style="text-align:right;">Right</th> </tr> </thead> <tbody> <tr> <td>Long Cell</td> <td style="text-align:left;">Long Cell</td> <td style="text-align:center;">Long Cell</td> <td style="text-align:right;">Long Cell</td> </tr> <tr> <td>Cell</td> <td style="text-align:left;">Cell</td> <td style="text-align:center;">Cell</td> <td style="text-align:right;">Cell</td> </tr> </tbody> </table> <hr /> <h1>Empty cells</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>A</td> <td>B</td> </tr> <tr> <td>C</td> <td></td> </tr> </tbody> </table> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>A</td> <td>B</td> </tr> <tr> <td></td> <td>D</td> </tr> </tbody> </table> <hr /> <h1>Missing tailing pipe</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> </tr> </tbody> </table> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> </tr> </tbody> </table> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> </tr> </tbody> </table> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> </tr> </tbody> </table> <h1>With a space at the end of the underline row</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> �������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Tables.opts������������������������������������0000664�0000000�0000000�00000000027�14107073154�0024666�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["tables"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/php-markdown-extra-cases/Tables.text������������������������������������0000664�0000000�0000000�00000003560�14107073154�0024672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Simple tables Header 1 | Header 2 --------- | --------- Cell 1 | Cell 2 Cell 3 | Cell 4 With leading pipes: | Header 1 | Header 2 | --------- | --------- | Cell 1 | Cell 2 | Cell 3 | Cell 4 With tailing pipes: Header 1 | Header 2 | --------- | --------- | Cell 1 | Cell 2 | Cell 3 | Cell 4 | With leading and tailing pipes: | Header 1 | Header 2 | | --------- | --------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | * * * # One-column one-row table With leading pipes: | Header | ------- | Cell With tailing pipes: Header | ------- | Cell | With leading and tailing pipes: | Header | | ------- | | Cell | * * * Table alignment: | Default | Left | Center | Right | | --------- |:--------- |:---------:| ---------:| | Long Cell | Long Cell | Long Cell | Long Cell | | Cell | Cell | Cell | Cell | Table alignment (alternate spacing): | Default | Left | Center | Right | | --------- | :-------- | :-------: | --------: | | Long Cell | Long Cell | Long Cell | Long Cell | | Cell | Cell | Cell | Cell | * * * # Empty cells | Header 1 | Header 2 | | --------- | --------- | | A | B | | C | | | Header 1 | Header 2 | --------- | --------- | A | B | | D * * * # Missing tailing pipe Header 1 | Header 2 --------- | --------- | Cell | Cell | Cell | Cell | Header 1 | Header 2 | --------- | --------- Cell | Cell | Cell | Cell | Header 1 | Header 2 | --------- | --------- | Cell | Cell Cell | Cell | Header 1 | Header 2 | --------- | --------- | Cell | Cell | Cell | Cell # With a space at the end of the underline row Header 1 | Header 2 | --------- | --------- | Cell 1 | Cell 2 | Cell 3 | Cell 4 | ������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/test.py�����������������������������������������������������������������0000775�0000000�0000000�00000002366�14107073154�0017265�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # Copyright (c) 2007-2008 ActiveState Software Inc. # License: MIT (http://www.opensource.org/licenses/mit-license.php) """The markdown2 test suite entry point.""" import os from os.path import exists, join, abspath, dirname, normpath import sys import logging import testlib log = logging.getLogger("test") testdir_from_ns = { None: os.curdir, } def setup(): top_dir = dirname(dirname(abspath(__file__))) lib_dir = join(top_dir, "lib") sys.path.insert(0, lib_dir) # Attempt to get 'pygments' on the import path. try: # If already have it, use that one. import pygments except ImportError: pygments_dir = join(top_dir, "deps", "pygments") if sys.version_info[0] <= 2: sys.path.insert(0, pygments_dir) else: sys.path.insert(0, pygments_dir + "3") if __name__ == "__main__": logging.basicConfig() setup() default_tags = [] try: import pygments except ImportError: log.warning("skipping pygments tests ('pygments' module not found)") default_tags.append("-pygments") retval = testlib.harness(testdir_from_ns=testdir_from_ns, default_tags=default_tags) sys.exit(retval) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/test_markdown2.py�������������������������������������������������������0000775�0000000�0000000�00000051510�14107073154�0021244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # Copyright (c) 2007-2008 ActiveState Software Inc. # License: MIT (http://www.opensource.org/licenses/mit-license.php) """Test the Python markdown2.py.""" import os import sys from os.path import join, dirname, abspath, exists, splitext, basename import re from glob import glob from pprint import pprint import unittest import codecs import difflib import doctest from json import loads as json_loads from testlib import TestError, TestSkipped, tag sys.path.insert(0, join(dirname(dirname(abspath(__file__))))) try: import markdown2 finally: del sys.path[0] #---- Python version compat # Use `bytes` for byte strings and `unicode` for unicode strings (str in Py3). if sys.version_info[0] <= 2: py3 = False try: bytes except NameError: bytes = str base_string_type = basestring elif sys.version_info[0] >= 3: py3 = True unicode = str base_string_type = str unichr = chr #---- Test cases class _MarkdownTestCase(unittest.TestCase): """Helper class for Markdown tests.""" maxDiff = None def _assertMarkdownParity(self, text): """Assert that markdown2.py produces same output as Markdown.pl.""" #TODO add normalization python_html = markdown2.markdown(text) perl_html = _markdown_with_perl(text) close_though = "" if python_html != perl_html \ and (python_html.replace('\n', '') == perl_html.replace('\n', '')): close_though = " (close though -- all but EOLs match)" self.assertEqual(python_html, perl_html, _dedent("""\ markdown2.py didn't produce the same output as Markdown.pl%s: ---- text ---- %s ---- Python markdown2.py HTML ---- %s ---- Perl Markdown.pl HTML ---- %s""") % (close_though, _display(text), _display(python_html), _display(perl_html))) def _assertMarkdownPath(self, text_path, encoding="utf-8", opts=None, toc_html_path=None, metadata_path=None): text = codecs.open(text_path, 'r', encoding=encoding).read() html_path = splitext(text_path)[0] + ".html" html = codecs.open(html_path, 'r', encoding=encoding).read() extra = {} if toc_html_path: extra["toc_html"] = codecs.open(toc_html_path, 'r', encoding=encoding).read() extra["toc_html_path"] = toc_html_path if metadata_path: extra["metadata"] = json_loads( codecs.open(metadata_path, 'r', encoding=encoding).read()) extra["metadata_path"] = metadata_path self._assertMarkdown(text, html, text_path, html_path, opts=opts, **extra) def _assertMarkdown(self, text, html, text_path=None, html_path=None, opts=None, toc_html=None, toc_html_path=None, metadata=None, metadata_path=None): """Assert that markdown2.py produces the expected HTML.""" if text_path is None: text_path = "<text content>" if html_path is None: html_path = "<html content>" if opts is None: opts = {} norm_html = norm_html_from_html(html) python_html = markdown2.markdown(text, **opts) python_norm_html = norm_html_from_html(python_html) close_though = "" if python_norm_html != norm_html \ and (python_norm_html.replace('\n', '') == norm_html.replace('\n', '')): close_though = " (close though -- all but EOLs match)" diff = '' if python_norm_html != norm_html: diff = difflib.unified_diff( norm_html.splitlines(1), python_norm_html.splitlines(1), html_path, "markdown2 "+text_path) diff = ''.join(diff) errmsg = _dedent("""\ markdown2.py didn't produce the expected HTML%s: ---- text (escaping: .=space, \\n=newline) ---- %s ---- Python markdown2.py HTML (escaping: .=space, \\n=newline) ---- %s ---- expected HTML (escaping: .=space, \\n=newline) ---- %s ---- diff ---- %s""") % (close_though, _display(text), _display(python_html), _display(html), _indent(diff)) def charreprreplace(exc): if not isinstance(exc, UnicodeEncodeError): raise TypeError("don't know how to handle %r" % exc) if py3: obj_repr = repr(exc.object[exc.start:exc.end])[1:-1] else: # repr -> remote "u'" and "'" obj_repr = repr(exc.object[exc.start:exc.end])[2:-1] return (unicode(obj_repr), exc.end) codecs.register_error("charreprreplace", charreprreplace) self.assertEqual(python_norm_html, norm_html, errmsg) if toc_html: python_toc_html = python_html.toc_html python_norm_toc_html = norm_html_from_html(python_toc_html) norm_toc_html = norm_html_from_html(toc_html) diff = '' if python_norm_toc_html != norm_toc_html: diff = difflib.unified_diff( norm_toc_html.splitlines(1), python_norm_toc_html.splitlines(1), toc_html_path, "`markdown2 %s`.toc_html" % text_path) diff = ''.join(diff) errmsg = _dedent("""\ markdown2.py didn't produce the expected TOC HTML%s: ---- text (escaping: .=space, \\n=newline) ---- %s ---- Python markdown2.py TOC HTML (escaping: .=space, \\n=newline) ---- %s ---- expected TOC HTML (escaping: .=space, \\n=newline) ---- %s ---- diff ---- %s""") % (close_though, _display(text), _display(python_toc_html), _display(toc_html), _indent(diff)) self.assertEqual(python_norm_toc_html, norm_toc_html, errmsg.encode('utf-8', 'charreprreplace')) if metadata: self.assertEqual(python_html.metadata, metadata) def generate_tests(cls): """Add test methods to this class for each test file in `cls.cases_dir'. """ cases_pat = join(dirname(__file__), cls.cases_dir, "*.text") for text_path in glob(cases_pat): # Load an options (`*.opts` file, if any). # It must be a Python dictionary. It will be passed as # kwargs to the markdown function. opts = {} opts_path = splitext(text_path)[0] + ".opts" if exists(opts_path): try: opts = eval(open(opts_path, 'r').read()) except Exception: _, ex, _ = sys.exc_info() print("WARNING: couldn't load `%s' opts file: %s" \ % (opts_path, ex)) toc_html_path = splitext(text_path)[0] + ".toc_html" if not exists(toc_html_path): toc_html_path = None metadata_path = splitext(text_path)[0] + ".metadata" if not exists(metadata_path): metadata_path = None test_func = lambda self, t=text_path, o=opts, c=toc_html_path, \ m=metadata_path: \ self._assertMarkdownPath(t, opts=o, toc_html_path=c, metadata_path=m) tags_path = splitext(text_path)[0] + ".tags" if exists(tags_path): tags = [] for line in open(tags_path): if '#' in line: # allow comments in .tags files line = line[:line.index('#')] tags += line.split() test_func.tags = tags name = splitext(basename(text_path))[0] name = name.replace(' - ', '_') name = name.replace(' ', '_') name = re.sub("[(),]", "", name) test_name = "test_%s" % name setattr(cls, test_name, test_func) generate_tests = classmethod(generate_tests) class TMTestCase(_MarkdownTestCase): cases_dir = "tm-cases" class MarkdownTestTestCase(_MarkdownTestCase): """Test cases from MarkdownTest-1.0.""" cases_dir = "markdowntest-cases" class PHPMarkdownTestCase(_MarkdownTestCase): """Test cases from MDTest.""" cases_dir = "php-markdown-cases" class PHPMarkdownExtraTestCase(_MarkdownTestCase): """Test cases from MDTest. These are all knownfailures because these test non-standard Markdown syntax no implemented in markdown2.py. See <http://www.michelf.com/projects/php-markdown/extra/> for details. """ cases_dir = "php-markdown-extra-cases" class DirectTestCase(_MarkdownTestCase): """These are specific test that I found were broken in Python-markdown (markdown.py). """ def test_slow_hr(self): import time text = """\ * * * This on *almost* looks like an hr, except for the trailing '+'. In older versions of markdown2.py this was pathologically slow: - - - - - - - - - - - - - - - - - - - - - - - - - + """ html = """\ <hr /> <p>This on <em>almost</em> looks like an hr, except for the trailing '+'. In older versions of markdown2.py this was pathologically slow:</p> <p>- - - - - - - - - - - - - - - - - - - - - - - - - +</p> """ start = time.time() self._assertMarkdown(text, html) end = time.time() delta = end - start self.assertTrue(delta < 1.0, "It took more than 1s to process " "'slow-hr'. It took %.2fs. Too slow!" % delta) test_slow_hr.tags = ["perf"] def test_code_in_strong(self): self._assertMarkdown( '**look at `this code` call**', '<p><strong>look at <code>this code</code> call</strong></p>\n') test_code_in_strong.tags = ["code", "strong"] def test_starter_pre(self): self._assertMarkdown( _indent('#!/usr/bin/python\nprint "hi"'), '<pre><code>#!/usr/bin/python\nprint "hi"\n</code></pre>\n') test_starter_pre.tags = ["pre", "recipes"] def test_pre(self): self._assertMarkdown(_dedent('''\ some starter text #!/usr/bin/python print "hi"'''), '<p>some starter text</p>\n\n<pre><code>#!/usr/bin/python\nprint "hi"\n</code></pre>\n') def test_russian(self): ko = '\u043b\u0449' # 'ko' on russian keyboard self._assertMarkdown("## %s" % ko, '<h2>%s</h2>\n' % ko) test_russian.tags = ["unicode", "issue3"] def test_toc_with_persistent_object(self): """ Tests that the toc is the same every time it's run on HTML, even if the Markdown object isn't disposed of. """ md = markdown2.Markdown(extras=["toc"]) html = """ # Header 1 ## Header 1.1 ## Header 1.2 ### Header 1.3 # Header 2 ## Header 2.1 """ expected_toc_html = """<ul> <li><a href="#header-1">Header 1</a> <ul> <li><a href="#header-11">Header 1.1</a></li> <li><a href="#header-12">Header 1.2</a> <ul> <li><a href="#header-13">Header 1.3</a></li> </ul></li> </ul></li> <li><a href="#header-2">Header 2</a> <ul> <li><a href="#header-21">Header 2.1</a></li> </ul></li> </ul> """ self.assertEqual(expected_toc_html, md.convert(html).toc_html) # Do it again, to check if the toc_html is just appended rather than replaced self.assertEqual(expected_toc_html, md.convert(html).toc_html) # Create different html, and confirm toc_html is replaced html = """ # I'm new html ## I don't have to be long, just different """ expected_toc_html = """<ul> <li><a href="#im-new-html">I'm new html</a> <ul> <li><a href="#i-dont-have-to-be-long-just-different">I don't have to be long, just different</a></li> </ul></li> </ul> """ self.assertEqual(expected_toc_html, md.convert(html).toc_html) test_toc_with_persistent_object.tags = ["toc", "issue208"] class DocTestsTestCase(unittest.TestCase): def test_api(self): test = doctest.DocFileTest("api.doctests") test.runTest() # Don't bother on Python 3 because (a) there aren't many inline doctests, # and (b) they are more to be didactic than comprehensive test suites. if not py3: def test_internal(self): doctest.testmod(markdown2) #---- internal support stuff _xml_escape_re = re.compile(r'&#(x[0-9A-Fa-f]{2,3}|[0-9]{2,3});') def _xml_escape_sub(match): escape = match.group(1) if escape[0] == 'x': return unichr(int('0'+escape, base=16)) else: return unichr(int(escape)) _markdown_email_link_re = re.compile(r'<a href="(.*?&#.*?)">(.*?)</a>', re.U) def _markdown_email_link_sub(match): href, text = match.groups() href = _xml_escape_re.sub(_xml_escape_sub, href) text = _xml_escape_re.sub(_xml_escape_sub, text) return '<a href="%s">%s</a>' % (href, text) def norm_html_from_html(html): """Normalize (somewhat) Markdown'd HTML. Part of Markdown'ing involves obfuscating email links with randomize encoding. Undo that obfuscation. Also normalize EOLs. """ if not isinstance(html, unicode): html = html.decode('utf-8') html = _markdown_email_link_re.sub( _markdown_email_link_sub, html) if sys.platform == "win32": html = html.replace('\r\n', '\n') return html def _display(s): """Markup the given string for useful display.""" if not isinstance(s, unicode): s = s.decode("utf-8") s = _indent(_escaped_text_from_text(s, "whitespace"), 4) if not s.endswith('\n'): s += '\n' return s def _markdown_with_perl(text): markdown_pl = join(dirname(__file__), "Markdown.pl") if not exists(markdown_pl): raise OSError("`%s' does not exist: get it from " "http://daringfireball.net/projects/markdown/" % markdown_pl) i, o = os.popen2("perl %s" % markdown_pl) i.write(text) i.close() html = o.read() o.close() return html # Recipe: dedent (0.1.2) def _dedentlines(lines, tabsize=8, skip_first_line=False): """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines "lines" is a list of lines to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. Same as dedent() except operates on a sequence of lines. Note: the lines list is modified **in-place**. """ DEBUG = False if DEBUG: print("dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\ % (tabsize, skip_first_line)) indents = [] margin = None for i, line in enumerate(lines): if i == 0 and skip_first_line: continue indent = 0 for ch in line: if ch == ' ': indent += 1 elif ch == '\t': indent += tabsize - (indent % tabsize) elif ch in '\r\n': continue # skip all-whitespace lines else: break else: continue # skip all-whitespace lines if DEBUG: print("dedent: indent=%d: %r" % (indent, line)) if margin is None: margin = indent else: margin = min(margin, indent) if DEBUG: print("dedent: margin=%r" % margin) if margin is not None and margin > 0: for i, line in enumerate(lines): if i == 0 and skip_first_line: continue removed = 0 for j, ch in enumerate(line): if ch == ' ': removed += 1 elif ch == '\t': removed += tabsize - (removed % tabsize) elif ch in '\r\n': if DEBUG: print("dedent: %r: EOL -> strip up to EOL" % line) lines[i] = lines[i][j:] break else: raise ValueError("unexpected non-whitespace char %r in " "line %r while removing %d-space margin" % (ch, line, margin)) if DEBUG: print("dedent: %r: %r -> removed %d/%d"\ % (line, ch, removed, margin)) if removed == margin: lines[i] = lines[i][j+1:] break elif removed > margin: lines[i] = ' '*(removed-margin) + lines[i][j+1:] break else: if removed: lines[i] = lines[i][removed:] return lines def _dedent(text, tabsize=8, skip_first_line=False): """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text "text" is the text to dedent. "tabsize" is the tab width to use for indent width calculations. "skip_first_line" is a boolean indicating if the first line should be skipped for calculating the indent width and for dedenting. This is sometimes useful for docstrings and similar. textwrap.dedent(s), but don't expand tabs to spaces """ lines = text.splitlines(1) _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line) return ''.join(lines) # Recipe: indent (0.2.1) def _indent(s, width=4, skip_first_line=False): """_indent(s, [width=4]) -> 's' indented by 'width' spaces The optional "skip_first_line" argument is a boolean (default False) indicating if the first line should NOT be indented. """ lines = s.splitlines(1) indentstr = ' '*width if skip_first_line: return indentstr.join(lines) else: return indentstr + indentstr.join(lines) # Recipe: text_escape (0.1) def _escaped_text_from_text(text, escapes="eol"): r"""Return escaped version of text. "escapes" is either a mapping of chars in the source text to replacement text for each such char or one of a set of strings identifying a particular escape style: eol replace EOL chars with '\r' and '\n', maintain the actual EOLs though too whitespace replace EOL chars as above, tabs with '\t' and spaces with periods ('.') eol-one-line replace EOL chars with '\r' and '\n' whitespace-one-line replace EOL chars as above, tabs with '\t' and spaces with periods ('.') """ #TODO: # - Add 'c-string' style. # - Add _escaped_html_from_text() with a similar call sig. import re if isinstance(escapes, base_string_type): if escapes == "eol": escapes = {'\r\n': "\\r\\n\r\n", '\n': "\\n\n", '\r': "\\r\r"} elif escapes == "whitespace": escapes = {'\r\n': "\\r\\n\r\n", '\n': "\\n\n", '\r': "\\r\r", '\t': "\\t", ' ': "."} elif escapes == "eol-one-line": escapes = {'\n': "\\n", '\r': "\\r"} elif escapes == "whitespace-one-line": escapes = {'\n': "\\n", '\r': "\\r", '\t': "\\t", ' ': '.'} else: raise ValueError("unknown text escape style: %r" % escapes) # Sort longer replacements first to allow, e.g. '\r\n' to beat '\r' and # '\n'. escapes_keys = list(escapes.keys()) escapes_keys.sort(key=lambda a: len(a), reverse=True) def repl(match): val = escapes[match.group(0)] return val escaped = re.sub("(%s)" % '|'.join([re.escape(k) for k in escapes_keys]), repl, text) return escaped def _one_line_summary_from_text(text, length=78, escapes={'\n':"\\n", '\r':"\\r", '\t':"\\t"}): r"""Summarize the given text with one line of the given length. "text" is the text to summarize "length" (default 78) is the max length for the summary "escapes" is a mapping of chars in the source text to replacement text for each such char. By default '\r', '\n' and '\t' are escaped with their '\'-escaped repr. """ if len(text) > length: head = text[:length-3] else: head = text escaped = _escaped_text_from_text(head, escapes) if len(text) > length: summary = escaped[:length-3] + "..." else: summary = escaped return summary #---- hook for testlib def test_cases(): """This is called by test.py to build up the test cases.""" TMTestCase.generate_tests() yield TMTestCase MarkdownTestTestCase.generate_tests() yield MarkdownTestTestCase PHPMarkdownTestCase.generate_tests() yield PHPMarkdownTestCase PHPMarkdownExtraTestCase.generate_tests() yield PHPMarkdownExtraTestCase yield DirectTestCase yield DocTestsTestCase ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/testall.py��������������������������������������������������������������0000664�0000000�0000000�00000003120�14107073154�0017740�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # # Run the test suite against all the Python versions we can find. # from __future__ import print_function import sys import os from os.path import dirname, abspath, join import re TOP = dirname(dirname(abspath(__file__))) sys.path.insert(0, join(TOP, "tools")) import which def _python_ver_from_python(python): assert ' ' not in python o = os.popen('''%s -c "import sys; print(sys.version)"''' % python) ver_str = o.read().strip() ver_bits = re.split(r"\.|[^\d]", ver_str, 2)[:2] ver = tuple(map(int, ver_bits)) return ver def _gen_python_names(): yield "python" for ver in [(2,6), (2,7), (3,3), (3,4), (3,5), (3,6), (3,7)]: yield "python%d.%d" % ver if sys.platform == "win32": yield "python%d%d" % ver def _gen_pythons(): python_from_ver = {} for name in _gen_python_names(): for python in which.whichall(name): ver = _python_ver_from_python(python) if ver not in python_from_ver: python_from_ver[ver] = python for ver, python in sorted(python_from_ver.items()): yield ver, python def testall(): for ver, python in _gen_pythons(): if ver < (2,6) or ver in ((3,0), (3,1), (3,2)): # Don't support Python < 2.6, 3.0/3.1/3.2. continue ver_str = "%s.%s" % ver print("-- test with Python %s (%s)" % (ver_str, python)) assert ' ' not in python rv = os.system("MACOSX_DEPLOYMENT_TARGET= %s test.py -- -knownfailure" % python) if rv: sys.exit(os.WEXITSTATUS(rv)) testall() ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/testlib.py��������������������������������������������������������������0000664�0000000�0000000�00000062613�14107073154�0017752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!python # Copyright (c) 2000-2008 ActiveState Software Inc. # License: MIT License (http://www.opensource.org/licenses/mit-license.php) """ test suite harness Usage: test --list [<tags>...] # list available tests modules test [<tags>...] # run test modules Options: -v, --verbose more verbose output -q, --quiet don't print anything except if a test fails -d, --debug log debug information -h, --help print this text and exit -l, --list Just list the available test modules. You can also specify tags to play with module filtering. -n, --no-default-tags Ignore default tags -L <directive> Specify a logging level via <logname>:<levelname> For example: codeintel.db:DEBUG This option can be used multiple times. By default this will run all tests in all available "test_*" modules. Tags can be specified to control which tests are run. For example: test python # run tests with the 'python' tag test python cpln # run tests with both 'python' and 'cpln' tags test -- -python # exclude tests with the 'python' tag # (the '--' is necessary to end the option list) The full name and base name of a test module are implicit tags for that module, e.g. module "test_xdebug.py" has tags "test_xdebug" and "xdebug". A TestCase's class name (with and without "TestCase") is an implicit tag for an test_* methods. A "test_foo" method also has "test_foo" and "foo" implicit tags. Tags can be added explicitly added: - to modules via a __tags__ global list; and - to individual test_* methods via a "tags" attribute list (you can use the testlib.tag() decorator for this). """ #TODO: # - Document how tests are found (note the special "test_cases()" and # "test_suite_class" hooks). # - See the optparse "TODO" below. # - Make the quiet option actually quiet. __version_info__ = (0, 6, 6) __version__ = '.'.join(map(str, __version_info__)) import os from os.path import join, basename, dirname, abspath, splitext, \ isfile, isdir, normpath, exists import sys import getopt import glob import time import types import tempfile import unittest from pprint import pprint import imp import optparse import logging import textwrap import traceback #---- globals and exceptions log = logging.getLogger("test") #---- exports generally useful to test cases class TestError(Exception): pass class TestSkipped(Exception): """Raise this to indicate that a test is being skipped. ConsoleTestRunner knows to interpret these at NOT failures. """ pass class TestFailed(Exception): pass def tag(*tags): """Decorator to add tags to test_* functions. Example: class MyTestCase(unittest.TestCase): @testlib.tag("knownfailure") def test_foo(self): #... """ def decorate(f): if not hasattr(f, "tags"): f.tags = [] f.tags += tags return f return decorate #---- timedtest decorator # Use this to assert that a test completes in a given amount of time. # This is from http://www.artima.com/forums/flat.jsp?forum=122&thread=129497 # Including here, because it might be useful. # NOTE: Untested and I suspect some breakage. TOLERANCE = 0.05 class DurationError(AssertionError): pass def timedtest(max_time, tolerance=TOLERANCE): """ timedtest decorator decorates the test method with a timer when the time spent by the test exceeds max_time in seconds, an Assertion error is thrown. """ def _timedtest(function): def wrapper(*args, **kw): start_time = time.time() try: function(*args, **kw) finally: total_time = time.time() - start_time if total_time > max_time + tolerance: raise DurationError(('Test was too long (%.2f s)' % total_time)) return wrapper return _timedtest #---- module api class Test(object): def __init__(self, ns, testmod, testcase, testfn_name, testsuite_class=None): self.ns = ns self.testmod = testmod self.testcase = testcase self.testfn_name = testfn_name self.testsuite_class = testsuite_class # Give each testcase some extra testlib attributes for useful # introspection on TestCase instances later on. self.testcase._testlib_shortname_ = self.shortname() self.testcase._testlib_explicit_tags_ = self.explicit_tags() self.testcase._testlib_implicit_tags_ = self.implicit_tags() def __str__(self): return self.shortname() def __repr__(self): return "<Test %s>" % self.shortname() def shortname(self): bits = [self._normname(self.testmod.__name__), self._normname(self.testcase.__class__.__name__), self._normname(self.testfn_name)] if self.ns: bits.insert(0, self.ns) return '/'.join(bits) def _flatten_tags(self, tags): """Split tags with '/' in them into multiple tags. '/' is the reserved tag separator and allowing tags with embedded '/' results in one being unable to select those via filtering. As long as tag order is stable then presentation of these subsplit tags should be fine. """ flattened = [] for t in tags: flattened += t.split('/') return flattened def explicit_tags(self): tags = [] if hasattr(self.testmod, "__tags__"): tags += self.testmod.__tags__ if hasattr(self.testcase, "__tags__"): tags += self.testcase.__tags__ testfn = getattr(self.testcase, self.testfn_name) if hasattr(testfn, "tags"): tags += testfn.tags return self._flatten_tags(tags) def implicit_tags(self): tags = [ self.testmod.__name__.lower(), self._normname(self.testmod.__name__), self.testcase.__class__.__name__.lower(), self._normname(self.testcase.__class__.__name__), self.testfn_name, self._normname(self.testfn_name), ] if self.ns: tags.insert(0, self.ns) return self._flatten_tags(tags) def tags(self): return self.explicit_tags() + self.implicit_tags() def doc(self): testfn = getattr(self.testcase, self.testfn_name) return testfn.__doc__ or "" def _normname(self, name): if name.startswith("test_"): return name[5:].lower() elif name.startswith("test"): return name[4:].lower() elif name.endswith("TestCase"): return name[:-8].lower() else: return name def testmod_paths_from_testdir(testdir): """Generate test module paths in the given dir.""" for path in glob.glob(join(testdir, "test_*.py")): yield path for path in glob.glob(join(testdir, "test_*")): if not isdir(path): continue if not isfile(join(path, "__init__.py")): continue yield path def testmods_from_testdir(testdir): """Generate test modules in the given test dir. Modules are imported with 'testdir' first on sys.path. """ testdir = normpath(testdir) for testmod_path in testmod_paths_from_testdir(testdir): testmod_name = splitext(basename(testmod_path))[0] log.debug("import test module '%s'", testmod_path) try: iinfo = imp.find_module(testmod_name, [dirname(testmod_path)]) testabsdir = abspath(testdir) sys.path.insert(0, testabsdir) old_dir = os.getcwd() os.chdir(testdir) try: testmod = imp.load_module(testmod_name, *iinfo) finally: os.chdir(old_dir) sys.path.remove(testabsdir) except TestSkipped: _, ex, _ = sys.exc_info() log.warning("'%s' module skipped: %s", testmod_name, ex) except Exception: _, ex, _ = sys.exc_info() log.warning("could not import test module '%s': %s (skipping, " "run with '-d' for full traceback)", testmod_path, ex) if log.isEnabledFor(logging.DEBUG): traceback.print_exc() else: yield testmod def testcases_from_testmod(testmod): """Gather tests from a 'test_*' module. Returns a list of TestCase-subclass instances. One instance for each found test function. In general the normal unittest TestLoader.loadTests*() semantics are used for loading tests with some differences: - TestCase subclasses beginning with '_' are skipped (presumed to be internal). - If the module has a top-level "test_cases", it is called for a list of TestCase subclasses from which to load tests (can be a generator). This allows for run-time setup of test cases. - If the module has a top-level "test_suite_class", it is used to group all test cases from that module into an instance of that TestSuite subclass. This allows for overriding of test running behaviour. """ class TestListLoader(unittest.TestLoader): suiteClass = list loader = TestListLoader() if hasattr(testmod, "test_cases"): try: for testcase_class in testmod.test_cases(): if testcase_class.__name__.startswith("_"): log.debug("skip private TestCase class '%s'", testcase_class.__name__) continue for testcase in loader.loadTestsFromTestCase(testcase_class): yield testcase except Exception: _, ex, _ = sys.exc_info() testmod_path = testmod.__file__ if testmod_path.endswith(".pyc"): testmod_path = testmod_path[:-1] log.warning("error running test_cases() in '%s': %s (skipping, " "run with '-d' for full traceback)", testmod_path, ex) if log.isEnabledFor(logging.DEBUG): traceback.print_exc() else: class_names_skipped = [] for testcases in loader.loadTestsFromModule(testmod): for testcase in testcases: class_name = testcase.__class__.__name__ if class_name in class_names_skipped: pass elif class_name.startswith("_"): log.debug("skip private TestCase class '%s'", class_name) class_names_skipped.append(class_name) else: yield testcase def tests_from_manifest(testdir_from_ns): """Return a list of `testlib.Test` instances for each test found in the manifest. There will be a test for (a) each "test*" function of (b) each TestCase-subclass in (c) each "test_*" Python module in (d) each test dir in the manifest. If a "test_*" module has a top-level "test_suite_class", it will later be used to group all test cases from that module into an instance of that TestSuite subclass. This allows for overriding of test running behaviour. """ for ns, testdir in testdir_from_ns.items(): for testmod in testmods_from_testdir(testdir): if hasattr(testmod, "test_suite_class"): testsuite_class = testmod.test_suite_class if not issubclass(testsuite_class, unittest.TestSuite): testmod_path = testmod.__file__ if testmod_path.endswith(".pyc"): testmod_path = testmod_path[:-1] log.warning("'test_suite_class' of '%s' module is not a " "subclass of 'unittest.TestSuite': ignoring", testmod_path) else: testsuite_class = None for testcase in testcases_from_testmod(testmod): yield Test(ns, testmod, testcase, testcase._testMethodName, testsuite_class) def tests_from_manifest_and_tags(testdir_from_ns, tags): include_tags = [tag.lower() for tag in tags if not tag.startswith('-')] exclude_tags = [tag[1:].lower() for tag in tags if tag.startswith('-')] for test in tests_from_manifest(testdir_from_ns): test_tags = [t.lower() for t in test.tags()] matching_exclude_tags = [t for t in exclude_tags if t in test_tags] if matching_exclude_tags: #log.debug("test '%s' matches exclude tag(s) '%s': skipping", # test.shortname(), "', '".join(matching_exclude_tags)) continue if not include_tags: yield test else: for tag in include_tags: if tag not in test_tags: #log.debug("test '%s' does not match tag '%s': skipping", # test.shortname(), tag) break else: #log.debug("test '%s' matches tags: %s", test.shortname(), # ' '.join(tags)) yield test def test(testdir_from_ns, tags=[], setup_func=None): log.debug("test(testdir_from_ns=%r, tags=%r, ...)", testdir_from_ns, tags) if setup_func is not None: setup_func() tests = list(tests_from_manifest_and_tags(testdir_from_ns, tags)) if not tests: return None # Groups test cases into a test suite class given by their test module's # "test_suite_class" hook, if any. suite = unittest.TestSuite() suite_for_testmod = None testmod = None for test in tests: if test.testmod != testmod: if suite_for_testmod is not None: suite.addTest(suite_for_testmod) suite_for_testmod = (test.testsuite_class or unittest.TestSuite)() testmod = test.testmod suite_for_testmod.addTest(test.testcase) if suite_for_testmod is not None: suite.addTest(suite_for_testmod) runner = ConsoleTestRunner(sys.stdout) result = runner.run(suite) return result def list_tests(testdir_from_ns, tags): # Say I have two test_* modules: # test_python.py: # __tags__ = ["guido"] # class BasicTestCase(unittest.TestCase): # def test_def(self): # def test_class(self): # class ComplexTestCase(unittest.TestCase): # def test_foo(self): # def test_bar(self): # test_perl/__init__.py: # __tags__ = ["larry", "wall"] # class BasicTestCase(unittest.TestCase): # def test_sub(self): # def test_package(self): # class EclecticTestCase(unittest.TestCase): # def test_foo(self): # def test_bar(self): # The short-form list output for this should look like: # python/basic/def [guido] # python/basic/class [guido] # python/complex/foo [guido] # python/complex/bar [guido] # perl/basic/sub [larry, wall] # perl/basic/package [larry, wall] # perl/eclectic/foo [larry, wall] # perl/eclectic/bar [larry, wall] log.debug("list_tests(testdir_from_ns=%r, tags=%r)", testdir_from_ns, tags) tests = list(tests_from_manifest_and_tags(testdir_from_ns, tags)) if not tests: return WIDTH = 78 if log.isEnabledFor(logging.INFO): # long-form for i, t in enumerate(tests): if i: print() testfile = t.testmod.__file__ if testfile.endswith(".pyc"): testfile = testfile[:-1] print("%s:" % t.shortname()) print(" from: %s#%s.%s" % (testfile, t.testcase.__class__.__name__, t.testfn_name)) wrapped = textwrap.fill(' '.join(t.tags()), WIDTH-10) print(" tags: %s" % _indent(wrapped, 8, True)) if t.doc(): print(_indent(t.doc(), width=2)) else: for t in tests: line = t.shortname() + ' ' if t.explicit_tags(): line += '[%s]' % ' '.join(t.explicit_tags()) print(line) #---- text test runner that can handle TestSkipped reasonably class ConsoleTestResult(unittest.TestResult): """A test result class that can print formatted text results to a stream. Used by ConsoleTestRunner. """ separator1 = '=' * 70 separator2 = '-' * 70 def __init__(self, stream): unittest.TestResult.__init__(self) self.skips = [] self.stream = stream def getDescription(self, test): if test._testlib_explicit_tags_: return "%s [%s]" % (test._testlib_shortname_, ', '.join(test._testlib_explicit_tags_)) else: return test._testlib_shortname_ def startTest(self, test): unittest.TestResult.startTest(self, test) self.stream.write(self.getDescription(test)) self.stream.write(" ... ") def addSuccess(self, test): unittest.TestResult.addSuccess(self, test) self.stream.write("ok\n") def addSkip(self, test, err): why = str(err[1]) self.skips.append((test, why)) self.stream.write("skipped (%s)\n" % why) def addError(self, test, err): if isinstance(err[1], TestSkipped): self.addSkip(test, err) else: unittest.TestResult.addError(self, test, err) self.stream.write("ERROR\n") def addFailure(self, test, err): unittest.TestResult.addFailure(self, test, err) self.stream.write("FAIL\n") def printSummary(self): self.stream.write('\n') self.printErrorList('ERROR', self.errors) self.printErrorList('FAIL', self.failures) def printErrorList(self, flavour, errors): for test, err in errors: self.stream.write(self.separator1 + '\n') self.stream.write("%s: %s\n" % (flavour, self.getDescription(test))) self.stream.write(self.separator2 + '\n') self.stream.write("%s\n" % err) class ConsoleTestRunner(object): """A test runner class that displays results on the console. It prints out the names of tests as they are run, errors as they occur, and a summary of the results at the end of the test run. Differences with unittest.TextTestRunner: - adds support for *skipped* tests (those that raise TestSkipped) - no verbosity option (only have equiv of verbosity=2) - test "short desc" is it 3-level tag name (e.g. 'foo/bar/baz' where that identifies: 'test_foo.py::BarTestCase.test_baz'. """ def __init__(self, stream=sys.stderr): self.stream = stream def run(self, test_or_suite, test_result_class=ConsoleTestResult): """Run the given test case or test suite.""" result = test_result_class(self.stream) start_time = time.time() test_or_suite.run(result) time_taken = time.time() - start_time result.printSummary() self.stream.write(result.separator2 + '\n') self.stream.write("Ran %d test%s in %.3fs\n\n" % (result.testsRun, result.testsRun != 1 and "s" or "", time_taken)) details = [] num_skips = len(result.skips) if num_skips: details.append("%d skip%s" % (num_skips, (num_skips != 1 and "s" or ""))) if not result.wasSuccessful(): num_failures = len(result.failures) if num_failures: details.append("%d failure%s" % (num_failures, (num_failures != 1 and "s" or ""))) num_errors = len(result.errors) if num_errors: details.append("%d error%s" % (num_errors, (num_errors != 1 and "s" or ""))) self.stream.write("FAILED (%s)\n" % ', '.join(details)) elif details: self.stream.write("OK (%s)\n" % ', '.join(details)) else: self.stream.write("OK\n") return result #---- internal support stuff # Recipe: indent (0.2.1) def _indent(s, width=4, skip_first_line=False): """_indent(s, [width=4]) -> 's' indented by 'width' spaces The optional "skip_first_line" argument is a boolean (default False) indicating if the first line should NOT be indented. """ lines = s.splitlines(1) indentstr = ' '*width if skip_first_line: return indentstr.join(lines) else: return indentstr + indentstr.join(lines) #---- mainline #TODO: pass in add_help_option=False and add it ourself here. ## Optparse's handling of the doc passed in for -h|--help handling is ## abysmal. Hence we'll stick with getopt. #def _parse_opts(args): # """_parse_opts(args) -> (options, tags)""" # usage = "usage: %prog [OPTIONS...] [TAGS...]" # parser = optparse.OptionParser(prog="test", usage=usage, # description=__doc__) # parser.add_option("-v", "--verbose", dest="log_level", # action="store_const", const=logging.DEBUG, # help="more verbose output") # parser.add_option("-q", "--quiet", dest="log_level", # action="store_const", const=logging.WARNING, # help="quieter output") # parser.add_option("-l", "--list", dest="action", # action="store_const", const="list", # help="list available tests") # parser.set_defaults(log_level=logging.INFO, action="test") # opts, raw_tags = parser.parse_args() # # # Trim '.py' from user-supplied tags. They might have gotten there # # via shell expansion. # ... # # return opts, raw_tags def _parse_opts(args, default_tags): """_parse_opts(args) -> (log_level, action, tags)""" opts, raw_tags = getopt.getopt(args, "hvqdlL:n", ["help", "verbose", "quiet", "debug", "list", "no-default-tags"]) log_level = logging.WARN action = "test" no_default_tags = False for opt, optarg in opts: if opt in ("-h", "--help"): action = "help" elif opt in ("-v", "--verbose"): log_level = logging.INFO elif opt in ("-q", "--quiet"): log_level = logging.ERROR elif opt in ("-d", "--debug"): log_level = logging.DEBUG elif opt in ("-l", "--list"): action = "list" elif opt in ("-n", "--no-default-tags"): no_default_tags = True elif opt == "-L": # Optarg is of the form '<logname>:<levelname>', e.g. # "codeintel:DEBUG", "codeintel.db:INFO". lname, llevelname = optarg.split(':', 1) llevel = getattr(logging, llevelname) logging.getLogger(lname).setLevel(llevel) # Clean up the given tags. if no_default_tags: tags = [] else: tags = default_tags for raw_tag in raw_tags: if splitext(raw_tag)[1] in (".py", ".pyc", ".pyo", ".pyw") \ and exists(raw_tag): # Trim '.py' from user-supplied tags if it looks to be from # shell expansion. tags.append(splitext(raw_tag)[0]) elif '/' in raw_tag: # Split one '/' to allow the shortname from the test listing # to be used as a filter. tags += raw_tag.split('/') else: tags.append(raw_tag) return log_level, action, tags def harness(testdir_from_ns={None: os.curdir}, argv=sys.argv, setup_func=None, default_tags=None): """Convenience mainline for a test harness "test.py" script. "testdir_from_ns" (optional) is basically a set of directories in which to look for test cases. It is a dict with: <namespace>: <testdir> where <namespace> is a (short) string that becomes part of the included test names and an implicit tag for filtering those tests. By default the current dir is use with an empty namespace: {None: os.curdir} "setup_func" (optional) is a callable that will be called once before any tests are run to prepare for the test suite. It is not called if no tests will be run. "default_tags" (optional) Typically, if you have a number of test_*.py modules you can create a test harness, "test.py", for them that looks like this: #!/usr/bin/env python if __name__ == "__main__": retval = testlib.harness() sys.exit(retval) """ if not logging.root.handlers: logging.basicConfig() try: log_level, action, tags = _parse_opts(argv[1:], default_tags or []) except getopt.error: _, ex, _ = sys.exc_info() log.error(str(ex) + " (did you need a '--' before a '-TAG' argument?)") return 1 log.setLevel(log_level) if action == "help": print(__doc__) return 0 if action == "list": return list_tests(testdir_from_ns, tags) elif action == "test": result = test(testdir_from_ns, tags, setup_func=setup_func) if result is None: return None return len(result.errors) + len(result.failures) else: raise TestError("unexpected action/mode: '%s'" % action) ���������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/���������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0017436�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/CVE-2018-5773.html���������������������������������������������0000664�0000000�0000000�00000000265�14107073154�0021737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><img src="" onerror=alert(/XSS/) </p> <p></img src="" onerror=alert(/XSS/) </p> <p><img/src="" onerror=alert(/XSS/) </p> <p></img/src="" onerror=alert(/XSS/) </p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/CVE-2018-5773.opts���������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0021747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "replace"} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/CVE-2018-5773.text���������������������������������������������0000664�0000000�0000000�00000000215�14107073154�0021752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<img src="" onerror=alert(/XSS/) </img src="" onerror=alert(/XSS/) <img/src="" onerror=alert(/XSS/) </img/src="" onerror=alert(/XSS/) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/ampersands.html������������������������������������������������0000664�0000000�0000000�00000000131�14107073154�0022454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>&</p> <p>AT&T</p> <p>AT&T</p> <p><a href="/">AT&T AT&T</a></p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/ampersands.tags������������������������������������������������0000664�0000000�0000000�00000000015�14107073154�0022447�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������htmlentities �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/ampersands.text������������������������������������������������0000664�0000000�0000000�00000000046�14107073154�0022501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������& AT&T AT&T [AT&T AT&T](/) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link.html�������������������������������������������������0000664�0000000�0000000�00000000613�14107073154�0022311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>I can has autolink? <a href="http://icanhascheeseburger.com">http://icanhascheeseburger.com</a></p> <p>Ask garfield: <a href="mailto:garfield@example.com">garfield@example.com</a></p> ���������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link.text�������������������������������������������������0000664�0000000�0000000�00000000133�14107073154�0022326�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������I can has autolink? <http://icanhascheeseburger.com> Ask garfield: <garfield@example.com> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_email_with_underscore.html���������������������������0000664�0000000�0000000�00000002643�14107073154�0026751�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Auto-link email with underscores failed at one point: - <a href="mailto:foo_bar@example.com">foo_bar@example.com</a> - <a href="mailto:foo@_example.com">foo@_example.com</a> - <a href="mailto:foo@an_example.com">foo@an_example.com</a> - <a href="mailto:foo@_example_.com">foo@_example_.com</a> - <a href="mailto:nounderscore@example.com">nounderscore@example.com</a> - <a href="mailto:check_this_out@coolpeople.com">check_this_out@coolpeople.com</a></p> ���������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_email_with_underscore.tags���������������������������0000664�0000000�0000000�00000000010�14107073154�0026725�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue26 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_email_with_underscore.text���������������������������0000664�0000000�0000000�00000000317�14107073154�0026765�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Auto-link email with underscores failed at one point: - <foo_bar@example.com> - <foo@_example.com> - <foo@an_example.com> - <foo@_example_.com> - <nounderscore@example.com> - <check_this_out@coolpeople.com> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_safe_mode.html���������������������������������������0000664�0000000�0000000�00000000613�14107073154�0024313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>I can has autolink? <a href="http://icanhascheeseburger.com">http://icanhascheeseburger.com</a></p> <p>Ask garfield: <a href="mailto:garfield@example.com">garfield@example.com</a></p> ���������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_safe_mode.opts���������������������������������������0000664�0000000�0000000�00000000024�14107073154�0024330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{'safe_mode': True} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_safe_mode.tags���������������������������������������0000664�0000000�0000000�00000000021�14107073154�0024276�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue7 safe_mode ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/auto_link_safe_mode.text���������������������������������������0000664�0000000�0000000�00000000133�14107073154�0024330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������I can has autolink? <http://icanhascheeseburger.com> Ask garfield: <garfield@example.com> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode.html�������������������������������������������0000664�0000000�0000000�00000002136�14107073154�0023411�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>blah [HTML_REMOVED] blah</p> <p>[HTML_REMOVED]yowzer![HTML_REMOVED]</p> <p>blah</p> <p>[HTML_REMOVED]alert(1)[HTML_REMOVED]</p> <p><a href="http://example.com"onclick="alert(1)">link1</a></p> <p><a href="http://example.com" title="title"onclick="alert(1)">link2</a></p> <p><a href="http://example.com>[HTML_REMOVED]alert(1)[HTML_REMOVED]">link3</a></p> <p><a href="http://example.com>[HTML_REMOVED]alert(1)[HTML_REMOVED]">link4 >[HTML_REMOVED]alert(1)[HTML_REMOVED]</a></p> <p><a href="#">link5</a></p> <p><a href="#">link6</a></p> <p><a href="#">link7</a></p> <p><img src="http://example.com/image.gif?h=200&w=500" alt="ok img" /></p> <p><img src="http://example.com"onclick="alert(1)" alt="img" /></p> <p><img src="http://example.com" alt="img2" title="text"onclick="alert(1)" /></p> <p><img src="http://example.com>[HTML_REMOVED]alert(1)[HTML_REMOVED]" alt="img3" /></p> <p><img src="javascript:alert(1)"</p> <p><img src="http://example.com/image.gif?h=200&w=500" alt="ok img" /></p> <p><a href="http://example.com">link ok</a></p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode.opts�������������������������������������������0000664�0000000�0000000�00000000133�14107073154�0023425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Use the old (for-compat-only) way of specifying "replace" safe mode. {"safe_mode": True} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode.tags�������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0023372�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������safe_mode ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode.text�������������������������������������������0000664�0000000�0000000�00000001541�14107073154�0023430�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������blah <img src="dangerous"> blah <div>yowzer!</div> blah <script>alert(1)</script> [link1](http://example.com"onclick="alert(1)) [link2](http://example.com "title"onclick="alert(1)") [link3](http://example.com><script>alert(1)</script>) [link4 ><script>alert(1)</script>](http://example.com><script>alert(1)</script>) [link5](javascript:alert('XSS')) [link6](javascript:alert('XSS')) [link7][1] ![ok img](http://example.com/image.gif?h=200&w=500) ![img](http://example.com"onclick="alert(1)) ![img2](http://example.com "text"onclick="alert(1)") ![img3](http://example.com><script>alert(1)</script>) <img src="javascript:alert(1)" [1]: javascript:alert('XSS') ![ok img](http://example.com/image.gif?h=200&w=500) [link ok](http://example.com) ���������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode_escape.html������������������������������������0000664�0000000�0000000�00000000141�14107073154�0024723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>blah <img src="dangerous"> blah</p> <p><div>yowzer!</div></p> <p>blah</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode_escape.opts������������������������������������0000664�0000000�0000000�00000000030�14107073154�0024741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "escape"} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode_escape.tags������������������������������������0000664�0000000�0000000�00000000012�14107073154�0024712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������safe_mode ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/basic_safe_mode_escape.text������������������������������������0000664�0000000�0000000�00000000072�14107073154�0024746�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������blah <img src="dangerous"> blah <div>yowzer!</div> blah ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote.html������������������������������������������������0000664�0000000�0000000�00000000177�14107073154�0022501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>[Trent wrote]</p> <blockquote> <p>no way</p> </blockquote> <p>[Jeff wrote]</p> <blockquote> <p>way</p> </blockquote> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote.text������������������������������������������������0000664�0000000�0000000�00000000053�14107073154�0022512�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Trent wrote] > no way [Jeff wrote] > way �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_containing_empty_lines.html�������������������������0000664�0000000�0000000�00000000073�14107073154�0027315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>no way</p> <p>way</p> </blockquote> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_containing_empty_lines.text�������������������������0000664�0000000�0000000�00000000023�14107073154�0027330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> no way > > > way �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_two_in_a_row.html�����������������������������������0000664�0000000�0000000�00000000124�14107073154�0025237�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>no way</p> </blockquote> <blockquote> <p>way</p> </blockquote> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_two_in_a_row.text�����������������������������������0000664�0000000�0000000�00000000020�14107073154�0025252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> no way > way ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_with_pre.html���������������������������������������0000664�0000000�0000000�00000000310�14107073154�0024367�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<blockquote> <p>Markdown indents blockquotes a couple of spaces necessitating some tweaks for pre-blocks in that blockquote:</p> <pre><code>here is a check for that </code></pre> </blockquote> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/blockquote_with_pre.text���������������������������������������0000664�0000000�0000000�00000000232�14107073154�0024412�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> Markdown indents blockquotes a couple of spaces > necessitating some tweaks for pre-blocks in that > blockquote: > > here is a check > for that ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/break_on_newline.html������������������������������������������0000664�0000000�0000000�00000000315�14107073154�0023624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Ring forth, ye bells,<br /> With clarion sound</p> <p>Forget your knells,<br /> For joys abound.</p> <p>Forget your notes<br /> Of mournful lay,<br /> And from your throats<br /> Pour joy to-day.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/break_on_newline.opts������������������������������������������0000664�0000000�0000000�00000000041�14107073154�0023641�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["break-on-newline"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/break_on_newline.text������������������������������������������0000664�0000000�0000000�00000000232�14107073154�0023642�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ring forth, ye bells, With clarion sound Forget your knells, For joys abound. Forget your notes Of mournful lay, And from your throats Pour joy to-day. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_block_with_tabs.html��������������������������������������0000664�0000000�0000000�00000000176�14107073154�0024460�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Test with tabs for <code>_Detab</code>:</p> <pre><code>Code 'block' with some "tabs" and "quotes" </code></pre> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_block_with_tabs.tags��������������������������������������0000664�0000000�0000000�00000000077�14107073154�0024452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fromphpmarkdown # from PHP Markdown test "Parens in URL.text" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_block_with_tabs.text��������������������������������������0000664�0000000�0000000�00000000112�14107073154�0024466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Test with tabs for `_Detab`: Code 'block' with some "tabs" and "quotes" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_blocks_leading_line.html����������������������������������0000664�0000000�0000000�00000000220�14107073154�0025257�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>print "hi" </code></pre> <p>That <em>single</em> leading line was problematic at one time. E.g. Markdown.pl 1.0.1 suffers here.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_blocks_leading_line.text����������������������������������0000664�0000000�0000000�00000000156�14107073154�0025307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ print "hi" That *single* leading line was problematic at one time. E.g. Markdown.pl 1.0.1 suffers here. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_safe_emphasis.html����������������������������������������0000664�0000000�0000000�00000000216�14107073154�0024124�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is <em>italic</em> and this is <strong>bold</strong>. This is NOT _italic_ and this is __bold__ because --code-safe is turned on.</p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_safe_emphasis.opts����������������������������������������0000664�0000000�0000000�00000000036�14107073154�0024145�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["code-friendly"]} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_safe_emphasis.tags����������������������������������������0000664�0000000�0000000�00000000016�14107073154�0024114�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������code_friendly ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/code_safe_emphasis.text����������������������������������������0000664�0000000�0000000�00000000165�14107073154�0024147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is *italic* and this is **bold**. This is NOT _italic_ and this is __bold__ because --code-safe is turned on. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codeblock.html�������������������������������������������������0000664�0000000�0000000�00000000155�14107073154�0022252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>some code </code></pre> <p>some 'splaining</p> <pre><code>some more code 2 > 1 </code></pre> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codeblock.text�������������������������������������������������0000664�0000000�0000000�00000000076�14107073154�0022274�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ some code some 'splaining some more code 2 > 1 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans.html�������������������������������������������������0000664�0000000�0000000�00000000143�14107073154�0022301�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><code>This</code> is a code span. And <code>This is one with an `embedded backtick`</code>.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans.text�������������������������������������������������0000664�0000000�0000000�00000000111�14107073154�0022314�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������`This` is a code span. And ``This is one with an `embedded backtick` ``. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans_safe_mode.html���������������������������������������0000664�0000000�0000000�00000000143�14107073154�0024303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><code>This</code> is a code span. And <code>This is one with an `embedded backtick`</code>.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans_safe_mode.opts���������������������������������������0000664�0000000�0000000�00000000024�14107073154�0024322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{'safe_mode': True} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans_safe_mode.tags���������������������������������������0000664�0000000�0000000�00000000021�14107073154�0024270�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue9 safe_mode ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/codespans_safe_mode.text���������������������������������������0000664�0000000�0000000�00000000111�14107073154�0024316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������`This` is a code span. And ``This is one with an `embedded backtick` ``. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_list_indented.html�������������������������������������0000664�0000000�0000000�00000000342�14107073154�0024634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>With no indent:</p> <ul> <li>one</li> <li>two</li> </ul> <p>With 4 space indent: * one * two</p> <p>With one tab indent: * one * two</p> <p>With 3 space indent:</p> <ul> <li>one</li> <li>two</li> </ul> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_list_indented.opts�������������������������������������0000664�0000000�0000000�00000000036�14107073154�0024655�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["cuddled-lists"]} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_list_indented.tags�������������������������������������0000664�0000000�0000000�00000000044�14107073154�0024625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������smedberg issue36 extra cuddle-lists ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_list_indented.text�������������������������������������0000664�0000000�0000000�00000000222�14107073154�0024651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������With no indent: * one * two With 4 space indent: * one * two With one tab indent: * one * two With 3 space indent: * one * two ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_para_and_list.html�������������������������������������0000664�0000000�0000000�00000001200�14107073154�0024601�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>I did these things:</p> <ul> <li>bullet1</li> <li>bullet2</li> <li>bullet3</li> </ul> <p>I did these too:</p> <ul> <li>bullet1</li> <li>bullet2</li> <li>bullet3 this is a longer one.</li> </ul> <p>And these in order:</p> <ol> <li>bullet1</li> <li>bullet2</li> <li>bullet3</li> </ol> <p>Here is an asterisk, * What do you think about it?</p> <p>I suggest using version 8. Oops, now this line is treated as a sub-list.</p> <p>List with single item:</p> <ul> <li>bullet1</li> </ul> <p>Another list with single item:</p> <ul> <li>bullet1</li> </ul> <p>Yet, another list with single item:</p> <ul> <li>bullet1</li> </ul> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_para_and_list.opts�������������������������������������0000664�0000000�0000000�00000000036�14107073154�0024630�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["cuddled-lists"]} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_para_and_list.tags�������������������������������������0000664�0000000�0000000�00000000044�14107073154�0024600�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������smedberg issue33 extra cuddle-lists ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_para_and_list.text�������������������������������������0000664�0000000�0000000�00000000664�14107073154�0024636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������I did these things: * bullet1 * bullet2 * bullet3 I did these too: * bullet1 * bullet2 * bullet3 this is a longer one. And these in order: 1. bullet1 2. bullet2 3. bullet3 Here is an asterisk, * What do you think about it? I suggest using version 8. Oops, now this line is treated as a sub-list. List with single item: * bullet1 Another list with single item: * bullet1 Yet, another list with single item: * bullet1 ����������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_with_para.html�����������������������������������������0000664�0000000�0000000�00000001230�14107073154�0023762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Cuddled with paragraph</h1> <p><?meta command?> Paragraph preceded by an XML processing instruction.</p> <p><!-- comment --> Paragraph preceded by an HTML/XML comment.</p> <p><img src="bar.png"/> Paragraph preceded by an HTML span element.</p> <div>div1</div> <p>Paragraph preceded by an HTML block element.</p> <h1>Not cuddled with paragraph</h1> <p><?meta command?></p> <p>Paragraph preceded by an XML processing instruction.</p> <!-- comment --> <p>Paragraph preceded by an HTML/XML comment.</p> <p><img src="bar.png"/></p> <p>Paragraph preceded by an HTML span element.</p> <div>div2</div> <p>Paragraph preceded by an HTML block element.</p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/cuddled_with_para.text�����������������������������������������0000664�0000000�0000000�00000001105�14107073154�0024003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Cuddled with paragraph <?meta command?> Paragraph preceded by an XML processing instruction. <!-- comment --> Paragraph preceded by an HTML/XML comment. <img src="bar.png"/> Paragraph preceded by an HTML span element. <div>div1</div> Paragraph preceded by an HTML block element. # Not cuddled with paragraph <?meta command?> Paragraph preceded by an XML processing instruction. <!-- comment --> Paragraph preceded by an HTML/XML comment. <img src="bar.png"/> Paragraph preceded by an HTML span element. <div>div2</div> Paragraph preceded by an HTML block element. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/demote_headers.html��������������������������������������������0000664�0000000�0000000�00000000257�14107073154�0023300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h3>this was h1</h3> <h4>this was h2</h4> <h5>this was h3</h5> <h6>this was h4</h6> <h6>this was h5</h6> <h6>this was h6</h6> <h3>this was h1</h3> <h3>this was h2</h3> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/demote_headers.opts��������������������������������������������0000664�0000000�0000000�00000000042�14107073154�0023311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": {"demote-headers": 2}} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/demote_headers.text��������������������������������������������0000664�0000000�0000000�00000000233�14107073154�0023312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# this was h1 ## this was h2 ### this was h3 #### this was h4 ##### this was h5 ###### this was h6 this was h1 =========== this was h2 =========== ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_head_vars.html�������������������������������������������0000664�0000000�0000000�00000000250�14107073154�0023425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- markdown-extras: code-friendly -*- --> <p>This sentence talks about the Python __init__ method, which I'd rather not be interpreted as Markdown's strong.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_head_vars.opts�������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0023442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"use_file_vars": True} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_head_vars.tags�������������������������������������������0000664�0000000�0000000�00000000006�14107073154�0023416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������emacs ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_head_vars.text�������������������������������������������0000664�0000000�0000000�00000000241�14107073154�0023445�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- markdown-extras: code-friendly -*- --> This sentence talks about the Python __init__ method, which I'd rather not be interpreted as Markdown's strong. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_tail_vars.html�������������������������������������������0000664�0000000�0000000�00000000276�14107073154�0023465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This sentence talks about the Python __init__ method, which I'd rather not be interpreted as Markdown's strong.</p> <!-- Local Variables: markdown-extras: code-friendly End: --> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_tail_vars.opts�������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0023472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"use_file_vars": True} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_tail_vars.tags�������������������������������������������0000664�0000000�0000000�00000000006�14107073154�0023446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������emacs ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emacs_tail_vars.text�������������������������������������������0000664�0000000�0000000�00000000267�14107073154�0023505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This sentence talks about the Python __init__ method, which I'd rather not be interpreted as Markdown's strong. <!-- Local Variables: markdown-extras: code-friendly End: --> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emphasis.html��������������������������������������������������0000664�0000000�0000000�00000000202�14107073154�0022127�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is <em>italic</em> and this is <strong>bold</strong>. This is also <em>italic</em> and this is <strong>bold</strong>.</p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/emphasis.text��������������������������������������������������0000664�0000000�0000000�00000000125�14107073154�0022153�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is *italic* and this is **bold**. This is also _italic_ and this is __bold__. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/escapes.html���������������������������������������������������0000664�0000000�0000000�00000003160�14107073154�0021747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Backslash-escapes: basics</h1> <p>**don't shout**</p> <p>*don't emphasize*</p> <p>_literal underscores_</p> <p>__more literal underscores__</p> <h2>This header has trailing hash marks ##</h2> <h1>Backslash-escapes: links</h1> <p>This is not a [link](/url/).</p> <p>This is a link, not an image link: !<a href="/url/">link</a>.</p> <p>Should this be an <a href="http://autolink\">http://autolink\</a> or not? I'll ask on markdown-discuss. I suspect PHP markdown is considering this NOT an autolink.</p> <p>This is not a [link definition][link1] but <a href="/url/">this is</a>.</p> <h1>Backslash-escapse: code blocks</h1> <p>In a code block:</p> <pre><code>escapes should \*not\* be \_interpreted\_ even \`backticks\` </code></pre> <h1>Backslash-escapse: code spans</h1> <p>Getting backticks and backslash-escapes working correctly with code spans can be tricky:</p> <p><code>a normal code span</code></p> <p><code>need multiple backticks to include a literal ` backtick</code></p> <p><code>`use a leading space to start a code span with a backtick</code></p> <p><code>use a trailing space to end a code span with a backtick`</code></p> <p><code>backslash-escapes \(are\) \*not\* \`interpreted\` in a code span</code></p> <p>`<code>a code span prefixed with a literal backtick</code></p> <p>`not a code span`</p> <p><em>Note A</em>: The <code>(?!`)</code> after the <code>\1</code> group in the <code>_DoCodeSpans()/_do_code_spans()</code> regex is necessary to ensure that a backtick doesn't match at the start of the code block (group <code>\2</code>) in an example like this:</p> <ul> <li>`<code>foo</code></li> </ul> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/escapes.tags���������������������������������������������������0000664�0000000�0000000�00000000010�14107073154�0021730�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue15 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/escapes.text���������������������������������������������������0000664�0000000�0000000�00000002463�14107073154�0021774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Backslash-escapes: basics \*\*don't shout\*\* \*don't emphasize\* \_literal underscores\_ \_\_more literal underscores\_\_ ## This header has trailing hash marks \#\# # Backslash-escapes: links This is not a \[link](/url/). This is a link, not an image link: \![link](/url/). Should this be an <http://autolink\> or not? I'll ask on markdown-discuss. I suspect PHP markdown is considering this NOT an autolink. This is not a [link definition\][link1] but [this is][link1]. [link1]: /url/ # Backslash-escapse: code blocks In a code block: escapes should \*not\* be \_interpreted\_ even \`backticks\` # Backslash-escapse: code spans Getting backticks and backslash-escapes working correctly with code spans can be tricky: `a normal code span` ``need multiple backticks to include a literal ` backtick`` `` `use a leading space to start a code span with a backtick`` ``use a trailing space to end a code span with a backtick` `` ``backslash-escapes \(are\) \*not\* \`interpreted\` in a code span`` \``a code span prefixed with a literal backtick` \`not a code span\` *Note A*: The `` (?!`) `` after the `\1` group in the `_DoCodeSpans()/_do_code_spans()` regex is necessary to ensure that a backtick doesn't match at the start of the code block (group `\2`) in an example like this: - ``foo` �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue113.html�������������������������������0000664�0000000�0000000�00000000541�14107073154�0025534�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code><script type="text/javascript" src="{{ static_url('shadowbox/shadowbox.js') }}"> </script> <script type="text/javascript"> Shadowbox.init({ handleOversize: "drag" }); window.onload = function() { Shadowbox.setup(".entry-content img", { gallery: "{{post.title}}", counterType: "skip" }); }; </script> </code></pre> ���������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue113.opts�������������������������������0000664�0000000�0000000�00000000043�14107073154�0025552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue113.tags�������������������������������0000664�0000000�0000000�00000000042�14107073154�0025522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks issue113 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue113.text�������������������������������0000664�0000000�0000000�00000000470�14107073154�0025555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` <script type="text/javascript" src="{{ static_url('shadowbox/shadowbox.js') }}"> </script> <script type="text/javascript"> Shadowbox.init({ handleOversize: "drag" }); window.onload = function() { Shadowbox.setup(".entry-content img", { gallery: "{{post.title}}", counterType: "skip" }); }; </script> ``` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue127.html�������������������������������0000664�0000000�0000000�00000000061�14107073154�0025536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code><div></div> </code></pre> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue127.opts�������������������������������0000664�0000000�0000000�00000000043�14107073154�0025557�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue127.tags�������������������������������0000664�0000000�0000000�00000000042�14107073154�0025527�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks issue127 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue127.text�������������������������������0000664�0000000�0000000�00000000024�14107073154�0025555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` <div></div> ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue135.html�������������������������������0000664�0000000�0000000�00000000040�14107073154�0025532�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>[] []: </code></pre> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue135.opts�������������������������������0000664�0000000�0000000�00000000043�14107073154�0025556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue135.tags�������������������������������0000664�0000000�0000000�00000000042�14107073154�0025526�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks issue135 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue135.text�������������������������������0000664�0000000�0000000�00000000017�14107073154�0025556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` [] []: ``` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue161.html�������������������������������0000664�0000000�0000000�00000000425�14107073154�0025540�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>here is some code </code></pre> <p>That's using the <em>fenced-code-blocks</em> extra.</p> <p>Here is an empty one (just to check):</p> <pre><code> </code></pre> <p>Here is one at the end of the file:</p> <pre><code> is indentation maintained? </code></pre> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue161.opts�������������������������������0000664�0000000�0000000�00000000072�14107073154�0025557�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"], "safe_mode": "escape"} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue161.tags�������������������������������0000664�0000000�0000000�00000000031�14107073154�0025523�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue161.text�������������������������������0000664�0000000�0000000�00000000305�14107073154�0025555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` here is some code ``` That's using the *fenced-code-blocks* extra. Here is an empty one (just to check): ``` ``` Here is one at the end of the file: ``` is indentation maintained? ``` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue86.html��������������������������������0000664�0000000�0000000�00000000276�14107073154�0025472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code># this should not be a heading print "hi" </code></pre> <pre><code># first comment a = 1 # second comment b = 2 </code></pre> <pre><code>void foo() { x = 1; </code></pre> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue86.opts��������������������������������0000664�0000000�0000000�00000000043�14107073154�0025503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue86.tags��������������������������������0000664�0000000�0000000�00000000061�14107073154�0025454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks issue86 issue84 issue87 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_issue86.text��������������������������������0000664�0000000�0000000�00000000213�14107073154�0025501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` # this should not be a heading print "hi" ``` ``` # first comment a = 1 # second comment b = 2 ``` ``` void foo() { x = 1; ``` �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_lang_space.html���������������������0000664�0000000�0000000�00000000334�14107073154�0027736�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span> <span class="nb">print</span> <span class="s2">"hi"</span> </code></pre></div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_lang_space.opts���������������������0000664�0000000�0000000�00000000043�14107073154�0027754�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_lang_space.tags���������������������0000664�0000000�0000000�00000000042�14107073154�0027724�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks pygments ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_lang_space.text���������������������0000664�0000000�0000000�00000000047�14107073154�0027757�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` python if True: print "hi" ``` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_line.html���������������������������0000664�0000000�0000000�00000000220�14107073154�0026563�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>print "hi" </code></pre> <p>That <em>single</em> leading line was problematic at one time. E.g. Markdown.pl 1.0.1 suffers here.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_line.opts���������������������������0000664�0000000�0000000�00000000043�14107073154�0026607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_line.tags���������������������������0000664�0000000�0000000�00000000031�14107073154�0026555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_line.text���������������������������0000664�0000000�0000000�00000000162�14107073154�0026610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ``` print "hi" ``` That *single* leading line was problematic at one time. E.g. Markdown.pl 1.0.1 suffers here. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_paragraph.html����������������������0000664�0000000�0000000�00000000104�14107073154�0027602�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is python code.</p> <pre><code>print 'hello' </code></pre> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_paragraph.opts����������������������0000664�0000000�0000000�00000000043�14107073154�0027625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_paragraph.tags����������������������0000664�0000000�0000000�00000000032�14107073154�0027574�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_leading_paragraph.text����������������������0000664�0000000�0000000�00000000053�14107073154�0027625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is python code. ``` print 'hello' ``` �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_safe_highlight.html�������������������������0000664�0000000�0000000�00000001263�14107073154�0027126�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span> <span class="nb">print</span> <span class="s2">"hi"</span> </code></pre></div> <p>That's using the <em>fenced-code-blocks</em> extra with Python syntax coloring, if <code>pygments</code> is installed. See <a href="http://github.github.com/github-flavored-markdown/">http://github.github.com/github-flavored-markdown/</a>.</p> <div class="codehilite"><pre><span></span><code><span class="k">def</span> <span class="nf">foo</span> <span class="nb">puts</span> <span class="s2">"hi"</span> <span class="k">end</span> </code></pre></div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_safe_highlight.opts�������������������������0000664�0000000�0000000�00000000072�14107073154�0027144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"], "safe_mode": "escape"} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_safe_highlight.tags�������������������������0000664�0000000�0000000�00000000042�14107073154�0027112�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks pygments ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_safe_highlight.text�������������������������0000664�0000000�0000000�00000000355�14107073154�0027147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������```python if True: print "hi" ``` That's using the *fenced-code-blocks* extra with Python syntax coloring, if `pygments` is installed. See <http://github.github.com/github-flavored-markdown/>. ```ruby def foo puts "hi" end ``` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_simple.html���������������������������������0000664�0000000�0000000�00000000425�14107073154�0025451�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code>here is some code </code></pre> <p>That's using the <em>fenced-code-blocks</em> extra.</p> <p>Here is an empty one (just to check):</p> <pre><code> </code></pre> <p>Here is one at the end of the file:</p> <pre><code> is indentation maintained? </code></pre> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_simple.opts���������������������������������0000664�0000000�0000000�00000000043�14107073154�0025466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_simple.tags���������������������������������0000664�0000000�0000000�00000000031�14107073154�0025434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_simple.text���������������������������������0000664�0000000�0000000�00000000305�14107073154�0025466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������``` here is some code ``` That's using the *fenced-code-blocks* extra. Here is an empty one (just to check): ``` ``` Here is one at the end of the file: ``` is indentation maintained? ``` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_highlighting.html��������������������0000664�0000000�0000000�00000001263�14107073154�0030234�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span> <span class="nb">print</span> <span class="s2">"hi"</span> </code></pre></div> <p>That's using the <em>fenced-code-blocks</em> extra with Python syntax coloring, if <code>pygments</code> is installed. See <a href="http://github.github.com/github-flavored-markdown/">http://github.github.com/github-flavored-markdown/</a>.</p> <div class="codehilite"><pre><span></span><code><span class="k">def</span> <span class="nf">foo</span> <span class="nb">puts</span> <span class="s2">"hi"</span> <span class="k">end</span> </code></pre></div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_highlighting.opts��������������������0000664�0000000�0000000�00000000043�14107073154�0030250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_highlighting.tags��������������������0000664�0000000�0000000�00000000042�14107073154�0030220�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks pygments ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_highlighting.text��������������������0000664�0000000�0000000�00000000355�14107073154�0030255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������```python if True: print "hi" ``` That's using the *fenced-code-blocks* extra with Python syntax coloring, if `pygments` is installed. See <http://github.github.com/github-flavored-markdown/>. ```ruby def foo puts "hi" end ``` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_indentation.html���������������������0000664�0000000�0000000�00000000452�14107073154�0030102�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div class="codehilite"><pre><span></span><code><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="nb">print</span> <span class="s2">"foo"</span> <span class="nb">print</span> <span class="s2">"bar"</span> </code></pre></div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_indentation.opts���������������������0000664�0000000�0000000�00000000043�14107073154�0030117�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_indentation.tags���������������������0000664�0000000�0000000�00000000056�14107073154�0030074�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks pygments indentation ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/fenced_code_blocks_syntax_indentation.text���������������������0000664�0000000�0000000�00000000072�14107073154�0030120�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������```python def foo(): print "foo" print "bar" ``` ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes.html�������������������������������������������������0000664�0000000�0000000�00000002254�14107073154�0022347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <p>This is another para with a footnote<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup> in it. Actually it has two<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup> of them. No, three<sup class="footnote-ref" id="fnref-4"><a href="#fn-4">4</a></sup>.</p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>Here is the body of the first footnote. <a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> <li id="fn-2"> <p>And of the second footnote.</p> <p>This one has multiple paragraphs. <a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p> </li> <li id="fn-3"> <p>Here is a footnote body that starts on next line. <a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">↩</a></p> </li> <li id="fn-4"> <p>quickie "that looks like a link ref if not careful" <a href="#fnref-4" class="footnoteBackLink" title="Jump back to footnote 4 in the text.">↩</a></p> </li> </ol> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes.opts�������������������������������������������������0000664�0000000�0000000�00000000032�14107073154�0022360�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes.text�������������������������������������������������0000664�0000000�0000000�00000000572�14107073154�0022370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^1] This is another para with a footnote[^2] in it. Actually it has two[^3] of them. No, three[^4]. [^1]: Here is the body of the first footnote. [^2]: And of the second footnote. This one has multiple paragraphs. [^3]: Here is a footnote body that starts on next line. [^4]: quickie "that looks like a link ref if not careful" ��������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_custom.html������������������������������������������0000664�0000000�0000000�00000002240�14107073154�0023734�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <p>This is another para with a footnote<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup> in it. Actually it has two<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup> of them. No, three<sup class="footnote-ref" id="fnref-4"><a href="#fn-4">4</a></sup>.</p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>Here is the body of the first footnote. <a href="#fnref-1" class="footnoteBackLink" title="Yo Dawg, I heard you came from 1.">↩</a></p> </li> <li id="fn-2"> <p>And of the second footnote.</p> <p>This one has multiple paragraphs. <a href="#fnref-2" class="footnoteBackLink" title="Yo Dawg, I heard you came from 2.">↩</a></p> </li> <li id="fn-3"> <p>Here is a footnote body that starts on next line. <a href="#fnref-3" class="footnoteBackLink" title="Yo Dawg, I heard you came from 3.">↩</a></p> </li> <li id="fn-4"> <p>quickie "that looks like a link ref if not careful" <a href="#fnref-4" class="footnoteBackLink" title="Yo Dawg, I heard you came from 4.">↩</a></p> </li> </ol> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_custom.opts������������������������������������������0000664�0000000�0000000�00000000125�14107073154�0023755�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"], "footnote_title" : "Yo Dawg, I heard you came from %d." } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_custom.text������������������������������������������0000664�0000000�0000000�00000000572�14107073154�0023762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^1] This is another para with a footnote[^2] in it. Actually it has two[^3] of them. No, three[^4]. [^1]: Here is the body of the first footnote. [^2]: And of the second footnote. This one has multiple paragraphs. [^3]: Here is a footnote body that starts on next line. [^4]: quickie "that looks like a link ref if not careful" ��������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_letters.html�����������������������������������������0000664�0000000�0000000�00000001754�14107073154�0024115�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-foo"><a href="#fn-foo">1</a></sup></p> <p>This is another para with a footnote<sup class="footnote-ref" id="fnref-hyphen-ated"><a href="#fn-hyphen-ated">2</a></sup> in it. Actually it has two<sup class="footnote-ref" id="fnref-Capital"><a href="#fn-Capital">3</a></sup> of them.</p> <div class="footnotes"> <hr /> <ol> <li id="fn-foo"> <p>Here is the body of the first footnote. <a href="#fnref-foo" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> <li id="fn-hyphen-ated"> <p>And of the second footnote.</p> <p>This one has multiple paragraphs. <a href="#fnref-hyphen-ated" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p> </li> <li id="fn-Capital"> <p>Here is a footnote body that starts on next line. <a href="#fnref-Capital" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">↩</a></p> </li> </ol> </div> ��������������������python-markdown2-2.4.1/test/tm-cases/footnotes_letters.opts�����������������������������������������0000664�0000000�0000000�00000000032�14107073154�0024122�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_letters.tags�����������������������������������������0000664�0000000�0000000�00000000012�14107073154�0024071�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������footnotes ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_letters.text�����������������������������������������0000664�0000000�0000000�00000000523�14107073154�0024126�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^foo] This is another para with a footnote[^hyphen-ated] in it. Actually it has two[^Capital] of them. [^foo]: Here is the body of the first footnote. [^hyphen-ated]: And of the second footnote. This one has multiple paragraphs. [^Capital]: Here is a footnote body that starts on next line. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_markup.html������������������������������������������0000664�0000000�0000000�00000001442�14107073154�0023724�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <p>This is another para with a footnote.<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup></p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>And the <strong>body</strong> of the footnote has <code>markup</code>. For example, a <a href="http://digg.com">link to digg</a>. And some code:</p> <pre><code>print "Hello, World!" </code></pre> <p><a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> <li id="fn-2"> <p>This body has markup too, <em>but</em> doesn't end with a code block. <a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p> </li> </ol> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_markup.opts������������������������������������������0000664�0000000�0000000�00000000032�14107073154�0023737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_markup.tags������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0023706�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������footnotes ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_markup.text������������������������������������������0000664�0000000�0000000�00000000455�14107073154�0023747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^1] This is another para with a footnote.[^2] [^1]: And the **body** of the footnote has `markup`. For example, a [link to digg](http://digg.com). And some code: print "Hello, World!" [^2]: This body has markup too, *but* doesn't end with a code block. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_safe_mode_escape.html��������������������������������0000664�0000000�0000000�00000000725�14107073154�0025672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>Here is the <em>body</em> of <span class="yo">the</span> footnote.</p> <p><div class="blah">And here is the second para of the footnote.</div> <a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> </ol> </div> �������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_safe_mode_escape.opts��������������������������������0000664�0000000�0000000�00000000061�14107073154�0025704�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "escape", "extras": ["footnotes"]} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_safe_mode_escape.tags��������������������������������0000664�0000000�0000000�00000000024�14107073154�0025654�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������safe_mode footnotes ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_safe_mode_escape.text��������������������������������0000664�0000000�0000000�00000000271�14107073154�0025706�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^1] [^1]: Here is the <em>body</em> of <span class="yo">the</span> footnote. <div class="blah">And here is the second para of the footnote.</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_smarty-pants.html������������������������������������0000664�0000000�0000000�00000000655�14107073154�0025074�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>Here is the <em>body</em> of <span class="yo">the</span> footnote.</p> <div class="blah">And here is the second para of the footnote.</div> <p><a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> </ol> </div> �����������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_smarty-pants.opts������������������������������������0000664�0000000�0000000�00000000052�14107073154�0025104�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes", "smarty-pants"]} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_smarty-pants.text������������������������������������0000664�0000000�0000000�00000000270�14107073154�0025105�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a para with a footnote.[^1] [^1]: Here is the <em>body</em> of <span class="yo">the</span> footnote. <div class="blah">And here is the second para of the footnote.</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_underscores.html�������������������������������������0000664�0000000�0000000�00000001424�14107073154�0024761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>memcpy<em>from</em>tvm</p> <p>Testing<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup>, more testing <sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup>, more<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup>.</p> <div class="footnotes"> <hr /> <ol> <li id="fn-1"> <p>memcpy<em>from</em>tvm <a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> <li id="fn-2"> <p><code>memcpy_from_tvm</code> <a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p> </li> <li id="fn-3"> <p>memcpy_from_tvm <a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">↩</a></p> </li> </ol> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_underscores.opts�������������������������������������0000664�0000000�0000000�00000000032�14107073154�0024774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_underscores.tags�������������������������������������0000664�0000000�0000000�00000000010�14107073154�0024741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue27 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/footnotes_underscores.text�������������������������������������0000664�0000000�0000000�00000000202�14107073154�0024772�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������memcpy_from_tvm Testing[^1], more testing [^2], more[^3]. [^1]: memcpy_from_tvm [^2]: `memcpy_from_tvm` [^3]: memcpy\_from\_tvm ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header.html����������������������������������������������������0000664�0000000�0000000�00000000111�14107073154�0021545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>an h1</h1> <h2>an h2</h2> <h1>another h1</h1> <h2>another h2</h2> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header.text����������������������������������������������������0000664�0000000�0000000�00000000111�14107073154�0021565�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# an h1 ## an h2 another h1 ========== another h2 ---------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_atx_no_preceeding_space.html����������������������������0000664�0000000�0000000�00000000037�14107073154�0026464�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>an h1</h1> <h2>an h2</h2> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_atx_no_preceeding_space.text����������������������������0000664�0000000�0000000�00000000020�14107073154�0026474�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#an h1 ##an h2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_1.html����������������������������������������������0000664�0000000�0000000�00000000271�14107073154�0022633�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="fruit-i-like">Fruit I Like</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h1 id="trents-fav-veggies">Trent's fav Veggies</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_1.opts����������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0022650�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["header-ids"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_1.tags����������������������������������������������0000664�0000000�0000000�00000000021�14107073154�0022616�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra header-ids ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_1.text����������������������������������������������0000664�0000000�0000000�00000000121�14107073154�0022645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Fruit I Like - apples - bananas # Trent's fav Veggies - carrots - lettuce �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_2.html����������������������������������������������0000664�0000000�0000000�00000000301�14107073154�0022626�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="foo-fruit-i-like">Fruit I Like</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h1 id="foo-trents-fav-veggies">Trent's fav Veggies</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_2.opts����������������������������������������������0000664�0000000�0000000�00000000042�14107073154�0022651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": {"header-ids": "foo"}} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_2.tags����������������������������������������������0000664�0000000�0000000�00000000021�14107073154�0022617�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra header-ids ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_2.text����������������������������������������������0000664�0000000�0000000�00000000121�14107073154�0022646�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Fruit I Like - apples - bananas # Trent's fav Veggies - carrots - lettuce �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_3.html����������������������������������������������0000664�0000000�0000000�00000000271�14107073154�0022635�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="fruit-i-like">Fruit I Like</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h2 id="trents-fav-veggies">Trent's fav Veggies</h2> <ul> <li>carrots</li> <li>lettuce</li> </ul> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_3.opts����������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0022652�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["header-ids"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_3.tags����������������������������������������������0000664�0000000�0000000�00000000021�14107073154�0022620�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra header-ids ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_3.text����������������������������������������������0000664�0000000�0000000�00000000155�14107073154�0022656�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Fruit I Like ============ - apples - bananas Trent's fav Veggies ------------------- - carrots - lettuce �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_4.html����������������������������������������������0000664�0000000�0000000�00000000444�14107073154�0022640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- coding: utf-8 -*- --> <h1 id="fruit-really-likes">Fruit заголовок <em>really</em> likes</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h1 id="trents-fav-veggies-stuff">Trent's <strong>fav</strong> Veggies & stuff</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_4.opts����������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0022653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["header-ids"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_4.tags����������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0022622�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra header-ids unicode �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_4.text����������������������������������������������0000664�0000000�0000000�00000000227�14107073154�0022657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- coding: utf-8 -*- --> # Fruit заголовок *really* likes - apples - bananas # Trent's **fav** Veggies & stuff - carrots - lettuce �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_5.html����������������������������������������������0000664�0000000�0000000�00000000356�14107073154�0022643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="section-1">Section 1</h1> <h2 id="intro">Intro</h2> <h2 id="deep-stuff">Deep stuff</h2> <h1 id="section-2">Section 2</h1> <h2 id="intro-2">Intro</h2> <h2 id="deep-stuff-2">Deep stuff</h2> <h2 id="more-stuff">More stuff</h2> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_5.opts����������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0022654�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["header-ids"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_5.tags����������������������������������������������0000664�0000000�0000000�00000000021�14107073154�0022622�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra header-ids ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/header_ids_5.text����������������������������������������������0000664�0000000�0000000�00000000132�14107073154�0022653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Section 1 ## Intro ## Deep stuff # Section 2 ## Intro ## Deep stuff ## More stuff ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/headers_tag_friendly.html��������������������������������������0000664�0000000�0000000�00000000035�14107073154�0024464�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>#tag</p> <h2>header</h2> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/headers_tag_friendly.opts��������������������������������������0000664�0000000�0000000�00000000035�14107073154�0024505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["tag-friendly"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/headers_tag_friendly.tags��������������������������������������0000664�0000000�0000000�00000000023�14107073154�0024453�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra tag-friendly �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/headers_tag_friendly.text��������������������������������������0000664�0000000�0000000�00000000020�14107073154�0024476�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#tag ## header ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/highlightjs_lang.html������������������������������������������0000664�0000000�0000000�00000000744�14107073154�0023636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre><code class="cpp language-cpp">here is some cpp code </code></pre> <pre><code class="nohighlight language-nohighlight">some code without highlighting </code></pre> <p>That's using the <em>fenced-code-blocks</em> and <em>highlightjs-lang</em> extra.</p> <p>Here is an empty one (just to check):</p> <pre><code class="cpp language-cpp"> </code></pre> <p>Here is one at the end of the file:</p> <pre><code class="cpp language-cpp"> is indentation maintained? </code></pre> ����������������������������python-markdown2-2.4.1/test/tm-cases/highlightjs_lang.opts������������������������������������������0000664�0000000�0000000�00000000067�14107073154�0023655�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["fenced-code-blocks", "highlightjs-lang"]} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/highlightjs_lang.tags������������������������������������������0000664�0000000�0000000�00000000052�14107073154�0023620�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks highlightjs-lang ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/highlightjs_lang.text������������������������������������������0000664�0000000�0000000�00000000434�14107073154�0023652�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������```cpp here is some cpp code ``` ```nohighlight some code without highlighting ``` That's using the *fenced-code-blocks* and *highlightjs-lang* extra. Here is an empty one (just to check): ```cpp ``` Here is one at the end of the file: ```cpp is indentation maintained? ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr.html��������������������������������������������������������0000664�0000000�0000000�00000000115�14107073154�0020732�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Dashes:</p> <hr /> <hr /> <hr /> <hr /> <pre><code>--- </code></pre> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr.text��������������������������������������������������������0000664�0000000�0000000�00000000052�14107073154�0020752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Dashes: --- --- --- --- --- ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr_length.html�������������������������������������������������0000664�0000000�0000000�00000000222�14107073154�0022272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>horizontal rules need to be at least 3 characters</h1> <p>-</p> <p>*</p> <p>_</p> <p>--</p> <p>**</p> <p>__</p> <hr /> <hr /> <hr /> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr_length.text�������������������������������������������������0000664�0000000�0000000�00000000130�14107073154�0022310�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# horizontal rules need to be at least 3 characters - * _ -- ** __ --- *** ___ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr_spaces.html�������������������������������������������������0000664�0000000�0000000�00000001225�14107073154�0022273�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>On the number of spaces in horizontal rules: The spec is fuzzy: "If you wish, you may use spaces between the hyphens or asterisks." Markdown.pl 1.0.1's hr regexes limit the number of spaces between the hr chars to one or two. We'll reproduce that limit here.</p> <h1>no spaces</h1> <hr /> <hr /> <hr /> <h1>one space</h1> <hr /> <hr /> <hr /> <h1>one space with some leading space</h1> <hr /> <hr /> <hr /> <h1>two spaces</h1> <hr /> <hr /> <hr /> <h1>three spaces (these shouldn't be hr)</h1> <p>- - -</p> <p>* * *</p> <p>_ _ _</p> <h1>one or two spaces</h1> <hr /> <hr /> <hr /> <h1>longer</h1> <hr /> <hr /> <hr /> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/hr_spaces.text�������������������������������������������������0000664�0000000�0000000�00000001166�14107073154�0022317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������On the number of spaces in horizontal rules: The spec is fuzzy: "If you wish, you may use spaces between the hyphens or asterisks." Markdown.pl 1.0.1's hr regexes limit the number of spaces between the hr chars to one or two. We'll reproduce that limit here. # no spaces --- *** ___ # one space - - - * * * _ _ _ # one space with some leading space - - - * * * _ _ _ # two spaces - - - * * * _ _ _ # three spaces (these shouldn't be hr) - - - * * * _ _ _ # one or two spaces - - - * * * _ _ _ # longer - - - - - - - - * * * * * * * * _ _ _ ___ _ _ _ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html5_block_tags.html������������������������������������������0000664�0000000�0000000�00000000255�14107073154�0023547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<aside>This should *not* be emphasized.</aside> <section> Likewise *this* emphasis should be ignored. </section> <p>The <em>emphasis</em> above should be ignored.</p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html5_block_tags.tags������������������������������������������0000664�0000000�0000000�00000000007�14107073154�0023534�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue57�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html5_block_tags.text������������������������������������������0000664�0000000�0000000�00000000237�14107073154�0023567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<aside>This should *not* be emphasized.</aside> <section> Likewise *this* emphasis should be ignored. </section> The *emphasis* above should be ignored. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html_classes.html����������������������������������������������0000664�0000000�0000000�00000002165�14107073154�0023011�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table class="table table-striped"> <thead> <tr> <th>Header 1</th> <th><em>Header</em> 2</th> </tr> </thead> <tbody> <tr> <td><code>Cell 1</code></td> <td><a href="http://example.com">Cell 2</a> link</td> </tr> <tr> <td>Cell 3</td> <td><strong>Cell 4</strong></td> </tr> </tbody> </table> <table class="table table-striped"> <thead> <tr> <th>Year</th> <th>Temperature (low)</th> <th>Temperature (high)</th> </tr> </thead> <tbody> <tr> <td>1900</td> <td>-10</td> <td>25</td> </tr> <tr> <td>1910</td> <td>-15</td> <td>30</td> </tr> <tr> <td>1920</td> <td>-10</td> <td>32</td> </tr> </tbody> </table> <p class="col-xs-3 custom-paragraph-class">For example:</p> <pre class="syntaxcolor"><code class="codesyntaxcolor">if cond: print doit() </code></pre> <p class="col-xs-3 custom-paragraph-class"><img src="http://www.google.com/images/logo.gif" alt="the google logo" class="custom-image-class" /></p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html_classes.opts����������������������������������������������0000664�0000000�0000000�00000000420�14107073154�0023022�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "extras": { "tables": {}, "wiki-tables": {}, "html-classes": { "pre": "syntaxcolor", "code": "codesyntaxcolor", "img": "custom-image-class", "table": "table table-striped", "p": "col-xs-3 custom-paragraph-class", } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html_classes.tags����������������������������������������������0000664�0000000�0000000�00000000040�14107073154�0022771�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras html-classes code.as.com ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/html_classes.text����������������������������������������������0000664�0000000�0000000�00000000577�14107073154�0023036�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������| Header 1 | *Header* 2 | | -------- | -------- | | `Cell 1` | [Cell 2](http://example.com) link | | Cell 3 | **Cell 4** | ||~ Year ||~ Temperature (low) ||~ Temperature (high) || || 1900 || -10 || 25 || || 1910 || -15 || 30 || || 1920 || -10 || 32 || For example: if cond: print doit() ![the google logo][logo] [logo]: http://www.google.com/images/logo.gif ���������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/img_in_link.html�����������������������������������������������0000664�0000000�0000000�00000000477�14107073154�0022613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This example from <a href="http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/">http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/</a>:</p> <p><a href="http://www.google.com/" title="click to visit Google.com"><img src="http://www.google.com/images/logo.gif" alt="the google logo" /></a></p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/img_in_link.text�����������������������������������������������0000664�0000000�0000000�00000000353�14107073154�0022624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This example from <http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/>: [![the google logo][logo]][google] [logo]: http://www.google.com/images/logo.gif [google]: http://www.google.com/ "click to visit Google.com" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/incorrect_list_parse.html��������������������������������������0000664�0000000�0000000�00000000466�14107073154�0024547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Section one</h1> <ol> <li><p>Test li 1</p> <pre><code>111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111 1 </code></pre></li> </ol> <h1>Section two</h1> <ol> <li><p>Test li 2</p> <ol> <li>subli a</li> <li>subli b</li> </ol></li> <li><p>Test li 3</p></li> </ol> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/incorrect_list_parse.tags��������������������������������������0000664�0000000�0000000�00000000011�14107073154�0024523�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue165 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/incorrect_list_parse.text��������������������������������������0000664�0000000�0000000�00000000333�14107073154�0024560�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Section one 1. Test li 1 111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111 1 # Section two 1. Test li 2 1. subli a 2. subli b 1. Test li 3 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/inline_links.html����������������������������������������������0000664�0000000�0000000�00000000461�14107073154�0023003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>an inline <a href="/url/">link</a></p> <p>a <a href="/url/" title="title">link "with" title</a></p> <p>an inline <a href="/url/">link with <code>code</code></a></p> <p>an inline <img src="/url/" alt="image link" /></p> <p>an <img src="/url/" alt="image "with" title" title="title" /></p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/inline_links.text����������������������������������������������0000664�0000000�0000000�00000000254�14107073154�0023023�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������an inline [link](/url/) a [link "with" title](/url/ "title") an inline [link with `code`](/url/) an inline ![image link](/url/) an ![image "with" title](/url/ "title") ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue21_gt_escaping.html���������������������������������������0000664�0000000�0000000�00000000165�14107073154�0024164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>http://code.google.com/p/python-markdown2/issues/detail?id=21</p> <p>></p> <p><></p> <p><b></p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue21_gt_escaping.opts���������������������������������������0000664�0000000�0000000�00000000030�14107073154�0024174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "escape"} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue21_gt_escaping.tags���������������������������������������0000664�0000000�0000000�00000000017�14107073154�0024152�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue21 escape �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue21_gt_escaping.text���������������������������������������0000664�0000000�0000000�00000000112�14107073154�0024174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������http://code.google.com/p/python-markdown2/issues/detail?id=21 > <> <b> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue2_safe_mode_borks_markup.html�����������������������������0000664�0000000�0000000�00000000256�14107073154�0026322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h2>Heading 2</h2> <p>blah [HTML_REMOVED]alert('this should be removed')[HTML_REMOVED] <strong>blah</strong></p> <p>[HTML_REMOVED]alert('as should this')[HTML_REMOVED]</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue2_safe_mode_borks_markup.opts�����������������������������0000664�0000000�0000000�00000000031�14107073154�0026332�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "replace"} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue2_safe_mode_borks_markup.tags�����������������������������0000664�0000000�0000000�00000000012�14107073154�0026302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������safe_mode ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue2_safe_mode_borks_markup.text�����������������������������0000664�0000000�0000000�00000000170�14107073154�0026335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Heading 2 blah <script>alert('this should be removed')</script> **blah** <script>alert('as should this')</script> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue341_xss.html����������������������������������������������0000664�0000000�0000000�00000000437�14107073154�0022605�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Example 1: <ftp:<a href="#">[HTML_REMOVED]alert(1);//</a>><ftp:<a href="#">[HTML_REMOVED]</a>></p> <p>Example 2: <http://g<!s://q?<!-<<a href="http://g">[HTML_REMOVED]alert(1);/*</a>->a><http://g<!s://g.c?<!-<<a href="http://g">a\\*/[HTML_REMOVED]alert(1);/*</a>->a></p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue341_xss.opts����������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0022614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "replace"} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue341_xss.text����������������������������������������������0000664�0000000�0000000�00000000301�14107073154�0022613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Example 1: <ftp:[<script>alert(1);//]()><ftp:[</script>]()> Example 2: <http://g<!s://q?<!-<[<script>alert(1);/\*](http://g)->a><http://g<!s://g.c?<!-<[a\\*/</script>alert(1);/*](http://g)->a>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue348_incomplete_tag.html�����������������������������������0000664�0000000�0000000�00000000106�14107073154�0024762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><lol@/ //id="pwn"//onclick="alert(1)"//<strong>abc</strong></p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue348_incomplete_tag.opts�����������������������������������0000664�0000000�0000000�00000000030�14107073154�0024777�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "escape"} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue348_incomplete_tag.text�����������������������������������0000664�0000000�0000000�00000000057�14107073154�0025007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<lol@/ //id="pwn"//onclick="alert(1)"//**abc** ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue3_bad_code_color_hack.html��������������������������������0000664�0000000�0000000�00000001010�14107073154�0025513�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- coding: utf-8 -*- --> <h2>заголовок</h2> <p>Example from <a href="http://code.google.com/p/python-markdown2/issues/detail?id=3#c8">http://code.google.com/p/python-markdown2/issues/detail?id=3#c8</a>.</p> <p>Some python code:</p> <div class="codehilite"><pre><span></span><code><span class="c1"># комментарий</span> <span class="k">if</span> <span class="kc">True</span><span class="p">:</span> <span class="nb">print</span> <span class="s2">"hi"</span> </code></pre></div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue3_bad_code_color_hack.opts��������������������������������0000664�0000000�0000000�00000000033�14107073154�0025540�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["code-color"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue3_bad_code_color_hack.tags��������������������������������0000664�0000000�0000000�00000000051�14107073154�0025511�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra code-color unicode pygments issue3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue3_bad_code_color_hack.text��������������������������������0000664�0000000�0000000�00000000345�14107073154�0025545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- -*- coding: utf-8 -*- --> ## заголовок Example from <http://code.google.com/p/python-markdown2/issues/detail?id=3#c8>. Some python code: :::python # комментарий if True: print "hi"�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue52_hang.html����������������������������������������������0000664�0000000�0000000�00000000005�14107073154�0022613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������blah ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue52_hang.tags����������������������������������������������0000664�0000000�0000000�00000000025�14107073154�0022607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue52 knownfailure �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue52_hang.text����������������������������������������������0000664�0000000�0000000�00000000436�14107073154�0022643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + howdy + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Privacy Policy: http://www.PetitionOnline.org/privacy-pets.html + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue54_escape_link_title.html���������������������������������0000664�0000000�0000000�00000001027�14107073154�0025363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="http://example.com" title="lorem [ipsum] dolor <sit> amet">foo</a></p> <p><img src="http://example.com/foo.gif" alt="fooimg" title="lorem [ipsum] dolor <sit> amet" /></p> <p><img src="http://example.com/foo.gif" alt=""this" [is] my <alt> text" title="lorem [ipsum] dolor <sit> amet" /></p> <p><a href="http://example.com" title="lorem [ipsum] dolor <sit> amet">bar</a></p> <p><img src="http://example.com/bar.png" alt="barimg" title="lorem [ipsum] dolor <sit> amet" /></p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue54_escape_link_title.tags���������������������������������0000664�0000000�0000000�00000000010�14107073154�0025344�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue54 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/issue54_escape_link_title.text���������������������������������0000664�0000000�0000000�00000000573�14107073154�0025410�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[foo](http://example.com "lorem [ipsum] dolor <sit> amet") ![fooimg](http://example.com/foo.gif "lorem [ipsum] dolor <sit> amet") !["this" [is] my <alt> text](http://example.com/foo.gif "lorem [ipsum] dolor <sit> amet") [bar][id] ![barimg][idimg] [id]: http://example.com "lorem [ipsum] dolor <sit> amet" [idimg]: http://example.com/bar.png "lorem [ipsum] dolor <sit> amet" �������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_defn_alt_title_delims.html��������������������������������0000664�0000000�0000000�00000000630�14107073154�0025652�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Alternative delimiters for <a href="http://daringfireball.net/projects/markdown/syntax#link" title="link syntax">link definitions</a> are allowed -- as of Markdown 1.0.2, I think. Hence, <a href="http://daringfireball.net/projects/markdown/syntax#link" title="link syntax">this link</a> and <a href="http://daringfireball.net/projects/markdown/syntax#link" title="link syntax">this link</a> work too.</p> ��������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_defn_alt_title_delims.text��������������������������������0000664�0000000�0000000�00000000614�14107073154�0025674�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Alternative delimiters for [link definitions][link1] are allowed -- as of Markdown 1.0.2, I think. Hence, [this link][link2] and [this link][link3] work too. [link1]: http://daringfireball.net/projects/markdown/syntax#link "link syntax" [link2]: http://daringfireball.net/projects/markdown/syntax#link 'link syntax' [link3]: http://daringfireball.net/projects/markdown/syntax#link (link syntax) ��������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_defn_spaces_in_url.html�����������������������������������0000664�0000000�0000000�00000000455�14107073154�0025167�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is <a href="javascript:alert("hi there");">a link</a> and <a href="javascript:alert("hi again");" title="that's twice now">another</a>.</p> <p>This is a <a href="/images/thumbs/phpThumb.php?src=/archive/img/1241/1241_10_game.jpg&w=200">crazy one</a> from issue18.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_defn_spaces_in_url.tags�����������������������������������0000664�0000000�0000000�00000000010�14107073154�0025144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue18 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_defn_spaces_in_url.text�����������������������������������0000664�0000000�0000000�00000000373�14107073154�0025206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is [a link][1] and [another][2]. This is a [crazy one][3] from issue18. [1]: javascript:alert("hi there"); [2]: javascript:alert("hi again"); "that's twice now" [3]: /images/thumbs/phpThumb.php?src=/archive/img/1241/1241_10_game.jpg&w=200 () ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_nofollow.html���������������������������������������������0000664�0000000�0000000�00000001436�14107073154�0023204�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a rel="nofollow" href="http://example.com">link</a></p> <p><a rel="nofollow" href="http://example.com/test#fragment">foo</a></p> <p><a href="#fragment">bar</a></p> <p>Pre-block:</p> <pre><code>Here is a raw link: <a href="http://example.com/one">one</a> </code></pre> <p>Raw HTML links: <a rel="nofollow" href="http://example.com/two">two</a> <a rel="nofollow" href="http://example.com/three" rel="nofollow">three</a> <a rel="nofollow" href="http://example.com/four" rel="foo">four</a> <a>five</a> <a rel="nofollow" href="//example.com/six">six</a> <A rel="nofollow" HREF="http://example.com/seven">seven</A> <a rel="nofollow" foo=bar href="http://example.com/eight">eight</a> <a rel="nofollow" href="http://example.com/test#fragment">nine</a> <a href="#fragment">ten</a> </p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_nofollow.opts���������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0023213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["nofollow"]} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_nofollow.tags���������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0023163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras issue74 issue104 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_nofollow.text���������������������������������������������0000664�0000000�0000000�00000001100�14107073154�0023210�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[link](http://example.com) [foo](http://example.com/test#fragment) [bar](#fragment) Pre-block: Here is a raw link: <a href="http://example.com/one">one</a> <p>Raw HTML links: <a href="http://example.com/two">two</a> <a href="http://example.com/three" rel="nofollow">three</a> <a href="http://example.com/four" rel="foo">four</a> <a>five</a> <a href="//example.com/six">six</a> <A HREF="http://example.com/seven">seven</A> <a foo=bar href="http://example.com/eight">eight</a> <a href="http://example.com/test#fragment">nine</a> <a href="#fragment">ten</a> </p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns.html���������������������������������������������0000664�0000000�0000000�00000000403�14107073154�0023176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="http://code.activestate.com/recipes/123/">Recipe 123</a> and <a href="http://bugs.activestate.com/show_bug.cgi?id=234">Komodo bug 234</a> are related.</p> <p><a href="http://www.python.org/dev/peps/pep-0042/">PEP 42</a> might be related too.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns.opts���������������������������������������������0000664�0000000�0000000�00000000546�14107073154�0023227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["link-patterns"], "link_patterns": [ (re.compile("recipe\s+(\d+)", re.I), r"http://code.activestate.com/recipes/\1/"), (re.compile("(?:komodo\s+)?bug\s+(\d+)", re.I), r"http://bugs.activestate.com/show_bug.cgi?id=\1"), (re.compile("PEP\s+(\d+)", re.I), lambda m: "http://www.python.org/dev/peps/pep-%04d/" % int(m.group(1))), ], } ����������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns.text���������������������������������������������0000664�0000000�0000000�00000000110�14107073154�0023211�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Recipe 123 and Komodo bug 234 are related. PEP 42 might be related too.��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_double_hit.html����������������������������������0000664�0000000�0000000�00000000272�14107073154�0025400�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>There once was a <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=123">Mozilla bug 123</a> and a <a href="http://bugs.activestate.com/show_bug.cgi?id=123">Komodo bug 123</a>.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_double_hit.opts����������������������������������0000664�0000000�0000000�00000000406�14107073154�0025420�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["link-patterns"], "link_patterns": [ (re.compile(r'mozilla\s+bug\s+(\d+)', re.I), r'http://bugzilla.mozilla.org/show_bug.cgi?id=\1'), (re.compile("(?:komodo\s+)?bug\s+(\d+)", re.I), r"http://bugs.activestate.com/show_bug.cgi?id=\1"), ], } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_double_hit.tags����������������������������������0000664�0000000�0000000�00000000016�14107073154�0025366�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������link_patterns ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_double_hit.text����������������������������������0000664�0000000�0000000�00000000067�14107073154�0025422�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������There once was a Mozilla bug 123 and a Komodo bug 123. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_edge_cases.html����������������������������������0000664�0000000�0000000�00000000145�14107073154�0025343�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="http://foo.com/blah_blah_blah/123">Blah 123</a> becomes a line with two underscores.</p> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_edge_cases.opts����������������������������������0000664�0000000�0000000�00000000206�14107073154�0025362�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["link-patterns"], "link_patterns": [ (re.compile("Blah\s+(\d+)", re.I), r"http://foo.com/blah_blah_blah/\1"), ], } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_edge_cases.tags����������������������������������0000664�0000000�0000000�00000000016�14107073154�0025332�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������link_patterns ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_edge_cases.text����������������������������������0000664�0000000�0000000�00000000056�14107073154�0025364�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Blah 123 becomes a line with two underscores. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_escape.html��������������������������������������0000664�0000000�0000000�00000000730�14107073154�0024521�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Recipe 123 and <a href="http://bugs.activestate.com/show_bug.cgi?id=234">a link to Komodo bug 234</a> are related.</p> <p><a href="http://example.org/Recipe 123">This is a link which has a pattern inside the url that shouldn't expand.</a></p> <p>Matched pattern is escaped: PEP 42 might be related too.</p> <p>Triple quotes not surrounding a matched pattern: PEP """42""" might be related too.</p> <p>"""This is some random text which should not be touched."""</p> ����������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_escape.opts��������������������������������������0000664�0000000�0000000�00000000546�14107073154�0024547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["link-patterns"], "link_patterns": [ (re.compile("recipe\s+(\d+)", re.I), r"http://code.activestate.com/recipes/\1/"), (re.compile("(?:komodo\s+)?bug\s+(\d+)", re.I), r"http://bugs.activestate.com/show_bug.cgi?id=\1"), (re.compile("PEP\s+(\d+)", re.I), lambda m: "http://www.python.org/dev/peps/pep-%04d/" % int(m.group(1))), ], } ����������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_escape.text��������������������������������������0000664�0000000�0000000�00000000715�14107073154�0024544�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Recipe 123""" and <a href="http://bugs.activestate.com/show_bug.cgi?id=234">a link to """Komodo bug 234"""</a> are related. <a href="http://example.org/"""Recipe 123"""">This is a link which has a pattern inside the url that shouldn't expand.</a> Matched pattern is escaped: """PEP 42""" might be related too. Triple quotes not surrounding a matched pattern: PEP """42""" might be related too. """This is some random text which should not be touched.""" ���������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_markdown_syntax.html�����������������������������0000664�0000000�0000000�00000000356�14107073154�0026515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="Recipe 123">This is a markdown link</a></p> <p><a href="Recipe 123" title="Recipe 123">This is a markdown link with title</a></p> <p>[Recipe 123]</p> <p><a href="http://code.activestate.com/recipes/123/">Recipe 123</a></p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_markdown_syntax.opts�����������������������������0000664�0000000�0000000�00000000215�14107073154�0026530�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["link-patterns"], "link_patterns": [ (re.compile("recipe\s+(\d+)", re.I), r"http://code.activestate.com/recipes/\1/"), ], }�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_patterns_markdown_syntax.text�����������������������������0000664�0000000�0000000�00000000176�14107073154�0026535�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[This is a markdown link](Recipe 123) [This is a markdown link with title](Recipe 123 "Recipe 123") [Recipe 123] Recipe 123��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_safe_urls.html��������������������������������������������0000664�0000000�0000000�00000000440�14107073154�0023322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="https://www.example.com">Safe link 1</a></p> <p><a href="http://www.example.com">Safe link 2</a></p> <p><a href="ftp://www.example.com">Safe link 3</a></p> <p><a href="#anchor">Safe link 4</a></p> <p><a href="#">Unsafe link 1</a></p> <p><a href="#">Unsafe link 2</a></p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_safe_urls.opts��������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0023336�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"safe_mode": "escape"} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_safe_urls.tags��������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0023307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������safe_mode ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_safe_urls.text��������������������������������������������0000664�0000000�0000000�00000000322�14107073154�0023341�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Safe link 1](https://www.example.com) [Safe link 2](http://www.example.com) [Safe link 3](ftp://www.example.com) [Safe link 4](#anchor) [Unsafe link 1](unknown://www.example.com) [Unsafe link 2](example) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank.html�������������������������������������������0000664�0000000�0000000�00000000310�14107073154�0023455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a rel="noopener" target="_blank" href="http://www.example.com">Ref</a></p> <p><a href="#bar">Foo</a></p> <p><a rel="noopener" target="_blank" href="http://www.example.com/two#three">One</a></p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank.opts�������������������������������������������0000664�0000000�0000000�00000000043�14107073154�0023501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["target-blank-links"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank.tags�������������������������������������������0000664�0000000�0000000�00000000020�14107073154�0023445�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras issue213 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank.text�������������������������������������������0000664�0000000�0000000�00000000124�14107073154�0023500�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Ref](http://www.example.com) [Foo](#bar) [One](http://www.example.com/two#three) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank_nofollow.html����������������������������������0000664�0000000�0000000�00000000332�14107073154�0025400�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a rel="nofollow noopener" target="_blank" href="http://www.example.com">Ref</a></p> <p><a href="#bar">Foo</a></p> <p><a rel="nofollow noopener" target="_blank" href="http://www.example.com/two#three">One</a></p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank_nofollow.opts����������������������������������0000664�0000000�0000000�00000000057�14107073154�0025425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["target-blank-links", "nofollow"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank_nofollow.tags����������������������������������0000664�0000000�0000000�00000000026�14107073154�0025372�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras nofollow blank ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/link_with_blank_nofollow.text����������������������������������0000664�0000000�0000000�00000000124�14107073154�0025417�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Ref](http://www.example.com) [Foo](#bar) [One](http://www.example.com/two#three) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/lists.html�����������������������������������������������������0000664�0000000�0000000�00000000221�14107073154�0021455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>count:</p> <ul> <li>one</li> <li>two</li> <li>three</li> </ul> <p>count in spanish:</p> <ol> <li>uno</li> <li>dos</li> <li>tres</li> </ol> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/lists.text�����������������������������������������������������0000664�0000000�0000000�00000000106�14107073154�0021477�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������count: * one * two * three count in spanish: 1. uno 2. dos 3. tres ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/lists2.html����������������������������������������������������0000664�0000000�0000000�00000000242�14107073154�0021542�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>mixed bullets:</p> <ul> <li>a</li> <li>b</li> <li>c</li> </ul> <p>ul followed by ol:</p> <ul> <li>a</li> <li>b</li> </ul> <ol> <li>1</li> <li>2</li> </ol> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/lists2.tags����������������������������������������������������0000664�0000000�0000000�00000000010�14107073154�0021525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue16 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/lists2.text����������������������������������������������������0000664�0000000�0000000�00000000105�14107073154�0021560�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mixed bullets: * a - b + c ul followed by ol: - a - b 1. 1 2. 2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/long_link.html�������������������������������������������������0000664�0000000�0000000�00000002120�14107073154�0022273�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>works</h1> <p><a href="http://tuxdeluxe.org/node/287">wever installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems</a></p> <h1>issue 24: these fail</h1> <p><a href="http://tuxdeluxe.org/node/287">wever installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems</a></p> <p><a href="http://tuxdeluxe.org/node/287">However installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems</a></p> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/long_link.tags�������������������������������������������������0000664�0000000�0000000�00000000010�14107073154�0022261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue24 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/long_link.text�������������������������������������������������0000664�0000000�0000000�00000002015�14107073154�0022316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# works [wever installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems](http://tuxdeluxe.org/node/287) # issue 24: these fail [wever installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems](http://tuxdeluxe.org/node/287) [However installation of Kunnafonix was resisted by many of the local organizations they had to work with The local "computer person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems](http://tuxdeluxe.org/node/287) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/markdown_in_html.html������������������������������������������0000664�0000000�0000000�00000001343�14107073154�0023661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="using-headings-to-test-toc-and-markdown-in-html-together">Using headings to test toc and markdown-in-html together</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <div> <p>This is <em>true</em> markdown text.</p> </div> <div class="bar"> <h2 id="this-too">This <strong>too</strong>.</h2> <p>And a paragraph</p> </div> <div class="foo"> <p>And <strong>this</strong>.</p> </div> <section> <p>And even <strong>this</strong> in an HTML5 block tag.</p> </section> <h1 id="veggies">Veggies</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> <!-- This isn't currently supported (as it is in PHP Markdown), but it might be one day. --> <table> <tr> <td markdown="1">This is *true* markdown text.</td> </tr> </table> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/markdown_in_html.opts������������������������������������������0000664�0000000�0000000�00000000050�14107073154�0023674�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["markdown-in-html", "toc"]} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/markdown_in_html.tags������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0023646�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������markdown-in-html toc extra �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/markdown_in_html.text������������������������������������������0000664�0000000�0000000�00000001045�14107073154�0023700�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Using headings to test toc and markdown-in-html together - apples - bananas <div markdown="1"> This is *true* markdown text. </div> <div class="bar" markdown="1"> ## This **too**. And a paragraph </div> <div markdown="1" class="foo"> And **this**. </div> <section markdown="1"> And even **this** in an HTML5 block tag. </section> # Veggies - carrots - lettuce <!-- This isn't currently supported (as it is in PHP Markdown), but it might be one day. --> <table> <tr> <td markdown="1">This is *true* markdown text.</td> </tr> </table> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/markdown_in_html.toc_html��������������������������������������0000664�0000000�0000000�00000000420�14107073154�0024521�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#using-headings-to-test-toc-and-markdown-in-html-together">Using headings to test toc and markdown-in-html together</a> <ul> <li><a href="#this-too">This <strong>too</strong>.</a></li> </ul></li> <li><a href="#veggies">Veggies</a></li> </ul> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata.html��������������������������������������������������0000664�0000000�0000000�00000000171�14107073154�0022103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>The real text</h1> <p>This should be parsed as before</p> <p>This should not be included in the metadata: test</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata.metadata����������������������������������������������0000664�0000000�0000000�00000001003�14107073154�0022712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "test": "abc", "leading~space": "is okay", "And": "some, cvs, data, which, you, must, parse, yourself", "this-is": "a hyphen test", "empty": "", "and some": "long value\n that goes multiline", "another": "example", "alist": ["a", "b", "c"], "adict": {"key": "foo", "a nested list": ["one", "two", "Even multiline strings are allowed\n in nested structured data\n if linebreaks and indent are respected !", {"subkey": "and another dict in a list"}, "but one-liners remains: simple strings"]} } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata.opts��������������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0022117�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["metadata"]} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata.tags��������������������������������������������������0000664�0000000�0000000�00000000027�14107073154�0022075�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra metadata issue78 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata.text��������������������������������������������������0000664�0000000�0000000�00000001130�14107073154�0022117�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- test: abc this-is : a hyphen test leading~space : is okay And: some, cvs, data, which, you, must, parse, yourself empty : and some: > long value that goes multiline another: example alist: - a - b - c adict: key: foo a nested list: - one - two - > Even multiline strings are allowed in nested structured data if linebreaks and indent are respected ! - subkey: and another dict in a list - but one-liners remains: simple strings --- # The real text This should be parsed as before This should not be included in the metadata: test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata2.html�������������������������������������������������0000664�0000000�0000000�00000000171�14107073154�0022165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>The real text</h1> <p>This should be parsed as before</p> <p>This should not be included in the metadata: test</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata2.metadata���������������������������������������������0000664�0000000�0000000�00000000355�14107073154�0023005�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "test": "abc", "leading~space": "is okay", "And": "some, cvs, data, which, you, must, parse, yourself", "this-is": "a hyphen test", "empty": "", "another long": "long value\n that goes multiline", "another": "example" } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata2.opts�������������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0022201�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["metadata"]} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata2.tags�������������������������������������������������0000664�0000000�0000000�00000000027�14107073154�0022157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra metadata issue78 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/metadata2.text�������������������������������������������������0000664�0000000�0000000�00000000453�14107073154�0022210�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test: abc this-is : a hyphen test leading~space : is okay And: some, cvs, data, which, you, must, parse, yourself empty : another long: > long value that goes multiline another: example # The real text This should be parsed as before This should not be included in the metadata: test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/mismatched_footnotes.html��������������������������������������0000664�0000000�0000000�00000001212�14107073154�0024536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is sentence has a footnote foo<sup class="footnote-ref" id="fnref-foo"><a href="#fn-foo">1</a></sup> and whamo[^whamo].</p> <p>This is another para with a numbered footnote<sup class="footnote-ref" id="fnref-6"><a href="#fn-6">2</a></sup>.</p> <div class="footnotes"> <hr /> <ol> <li id="fn-foo"> <p>Here is the body of the footnote foo. <a href="#fnref-foo" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p> </li> <li id="fn-6"> <p>Here is the body of the footnote 6. <a href="#fnref-6" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p> </li> </ol> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/mismatched_footnotes.opts��������������������������������������0000664�0000000�0000000�00000000032�14107073154�0024556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["footnotes"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/mismatched_footnotes.text��������������������������������������0000664�0000000�0000000�00000000372�14107073154�0024564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is sentence has a footnote foo[^foo] and whamo[^whamo]. This is another para with a numbered footnote[^6]. [^foo]: Here is the body of the footnote foo. [^bar]: Here is the body of the footnote bar. [^6]: Here is the body of the footnote 6. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/missing_link_defn.html�����������������������������������������0000664�0000000�0000000�00000000127�14107073154�0024006�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is a [missing link][missing] and a <a href="http://foo.com">used link</a>.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/missing_link_defn.text�����������������������������������������0000664�0000000�0000000�00000000157�14107073154�0024031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ This is a [missing link][missing] and a [used link][used]. [used]: http://foo.com [unused]: http://foo.com �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list.html�����������������������������������������������0000664�0000000�0000000�00000000266�14107073154�0022645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>shopping list:</p> <ul> <li>veggies <ul> <li>carrots</li> <li>lettuce</li> </ul></li> <li>fruits <ul> <li>oranges</li> <li>apples</li> <li><em>peaches</em></li> </ul></li> </ul> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list.text�����������������������������������������������0000664�0000000�0000000�00000000152�14107073154�0022657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������shopping list: - veggies + carrots + lettuce - fruits + oranges + apples + *peaches* ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list_safe_mode.html�������������������������������������0000664�0000000�0000000�00000000266�14107073154�0024647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>shopping list:</p> <ul> <li>veggies <ul> <li>carrots</li> <li>lettuce</li> </ul></li> <li>fruits <ul> <li>oranges</li> <li>apples</li> <li><em>peaches</em></li> </ul></li> </ul> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list_safe_mode.opts�������������������������������������0000664�0000000�0000000�00000000024�14107073154�0024660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{'safe_mode': True} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list_safe_mode.tags�������������������������������������0000664�0000000�0000000�00000000021�14107073154�0024626�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue9 safe_mode ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/nested_list_safe_mode.text�������������������������������������0000664�0000000�0000000�00000000152�14107073154�0024661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������shopping list: - veggies + carrots + lettuce - fruits + oranges + apples + *peaches* ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/not_quite_a_list.html������������������������������������������0000664�0000000�0000000�00000000611�14107073154�0023664�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li>This</li> <li>is</li> <li>a list.</li> </ul> <p>And:</p> <ul> <li><em>This</em> is</li> <li>a list</li> <li>too.</li> </ul> <p>However, because ASCII art can have long dash/asterisk lines let ensure that:</p> <p>- - - - - - - This isn't a list.</p> <p>* * Nor is this a list.</p> <p>- - - Or this.</p> <p>- - - - - - - - - - + hi there ascii art - - - - - - - - - - +</p> �����������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/not_quite_a_list.text������������������������������������������0000664�0000000�0000000�00000000432�14107073154�0023705�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- This - is - a list. And: * *This* is * a list * too. However, because ASCII art can have long dash/asterisk lines let ensure that: - - - - - - - This isn't a list. * * Nor is this a list. - - - Or this. - - - - - - - - - - + hi there ascii art - - - - - - - - - - + ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/numbering.html�������������������������������������������������0000664�0000000�0000000�00000002366�14107073154�0022321�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is an image with a caption</p> <p><img src="https://consequenceofsound.files.wordpress.com/2015/10/screen-shot-2015-10-17-at-6-57-13-pm.png?w=807"</img></p> <figcaption class="imagenumbers" id="counter-ref-rickroll">Image 1: Let's Rick Roll You</figcaption> <p>And we can refer to the rickrolling image as Image <a class="imagenumbers" href="#counter-ref-rickroll">1</a>. There is a second image of something else</p> <p><img src="https://wonderifyouwonder.files.wordpress.com/2012/02/anchor.jpg"></img></p> <figcaption class="imagenumbers" id="counter-ref-kent">Figure 2: I for one welcome our new insect overlords</figcaption> <p>So we can refer to Figure <a class="imagenumbers" href="#counter-ref-rickroll">1</a> and Figure <a class="imagenumbers" href="#counter-ref-kent">2</a> separately.</p> <h1>Here is a table</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <figcaption class="tablenumbers" id="counter-ref-exampletable">Table 1: An example table</figcaption> <p>Which we can refer to as table <a class="tablenumbers" href="#counter-ref-exampletable">1</a></p> <p>And so we are done.</p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/numbering.opts�������������������������������������������������0000664�0000000�0000000�00000000032�14107073154�0022326�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["numbering"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/numbering.text�������������������������������������������������0000664�0000000�0000000�00000002365�14107073154�0022340�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is an image with a caption</p> <p><img src="https://consequenceofsound.files.wordpress.com/2015/10/screen-shot-2015-10-17-at-6-57-13-pm.png?w=807"</img></p> <figcaption class="imagenumbers" id="counter-ref-rickroll">Image 1: Let's Rick Roll You</figcaption> <p>And we can refer to the rickrolling image as Image <a class="imagenumbers" href="#counter-ref-rickroll">1</a>. There is a second image of something else</p> <p><img src="https://wonderifyouwonder.files.wordpress.com/2012/02/anchor.jpg"></img></p> <figcaption class="imagenumbers" id="counter-ref-kent">Figure 2: I for one welcome our new insect overlords</figcaption> <p>So we can refer to Figure <a class="imagenumbers" href="#counter-ref-rickroll">1</a> and Figure <a class="imagenumbers" href="#counter-ref-kent">2</a> separately.</p> <h1>Here is a table</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <figcaption class="tablenumbers" id="counter-ref-exampletable">Table 1: An example table</figcaption> <p>Which we can refer to as table <a class="tablenumbers" href="#counter-ref-exampletable">1</a></p> <p>And so we are done.</p>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/parens_in_url_4.html�������������������������������������������0000664�0000000�0000000�00000000125�14107073154�0023405�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="/url(test)" title="title">Inline link 4 with non-escaped parens</a>.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/parens_in_url_4.tags�������������������������������������������0000664�0000000�0000000�00000000077�14107073154�0023405�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fromphpmarkdown # from PHP Markdown test "Parens in URL.text" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/parens_in_url_4.text�������������������������������������������0000664�0000000�0000000�00000000077�14107073154�0023433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Inline link 4 with non-escaped parens](</url(test)> "title"). �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pi_and_xinclude.html�������������������������������������������0000664�0000000�0000000�00000000317�14107073154�0023452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>'xml' Extra</h1> <?meta @notes @workinprogress?> <p>Here comes the part that i'm still quite unsure about, but anyway:</p> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="chapter_1.md"/> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pi_and_xinclude.opts�������������������������������������������0000664�0000000�0000000�00000000024�14107073154�0023466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["xml"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pi_and_xinclude.tags�������������������������������������������0000664�0000000�0000000�00000000020�14107073154�0023433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml pi xinclude ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pi_and_xinclude.text�������������������������������������������0000664�0000000�0000000�00000000313�14107073154�0023466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������'xml' Extra =========== <?meta @notes @workinprogress?> Here comes the part that i'm still quite unsure about, but anyway: <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="chapter_1.md"/> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell.html���������������������������������������������������0000664�0000000�0000000�00000000574�14107073154�0022012�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>From Recipe 302035</h1> <p>Some examples:</p> <pre><code>>>> nprint(9876543210) '9 876 543 210' >>> nprint(987654321, period=1, delimiter=",") '9,8,7,6,5,4,3,2,1,0' </code></pre> <p>Indented a bit:</p> <pre><code>>>> 1 + 1 2 </code></pre> <p>Cuddled to previous para (and at end of document):</p> <pre><code>>>> 2 + 2 4 </code></pre> ������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell.opts���������������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0022016�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["pyshell"]} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell.text���������������������������������������������������0000664�0000000�0000000�00000000362�14107073154�0022025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# From Recipe 302035 Some examples: >>> nprint(9876543210) '9 876 543 210' >>> nprint(987654321, period=1, delimiter=",") '9,8,7,6,5,4,3,2,1,0' Indented a bit: >>> 1 + 1 2 Cuddled to previous para (and at end of document): >>> 2 + 2 4 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell_and_fenced_code_blocks.html����������������������������0000664�0000000�0000000�00000002331�14107073154�0026460�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>From Recipe 302035</h1> <p>Some examples:</p> <div class="codehilite"><pre><span></span><code><span class="gp">>>> </span><span class="n">nprint</span><span class="p">(</span><span class="mi">9876543210</span><span class="p">)</span> <span class="go">'9 876 543 210'</span> <span class="gp">>>> </span><span class="n">nprint</span><span class="p">(</span><span class="mi">987654321</span><span class="p">,</span> <span class="n">period</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s2">","</span><span class="p">)</span> <span class="go">'9,8,7,6,5,4,3,2,1,0'</span> </code></pre></div> <p>Indented a bit:</p> <div class="codehilite"><pre><span></span><code><span class="gp">>>> </span><span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span> <span class="go">2</span> </code></pre></div> <p>Cuddled to previous para (and at end of document):</p> <div class="codehilite"><pre><span></span><code><span class="gp">>>> </span><span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="go">4</span> </code></pre></div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell_and_fenced_code_blocks.opts����������������������������0000664�0000000�0000000�00000000056�14107073154�0026503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["pyshell", "fenced-code-blocks"]} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell_and_fenced_code_blocks.tags����������������������������0000664�0000000�0000000�00000000052�14107073154�0026450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra fenced-code-blocks pygments pyshell ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/pyshell_and_fenced_code_blocks.text����������������������������0000664�0000000�0000000�00000000362�14107073154�0026502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# From Recipe 302035 Some examples: >>> nprint(9876543210) '9 876 543 210' >>> nprint(987654321, period=1, delimiter=",") '9,8,7,6,5,4,3,2,1,0' Indented a bit: >>> 1 + 1 2 Cuddled to previous para (and at end of document): >>> 2 + 2 4 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/raw_html.html��������������������������������������������������0000664�0000000�0000000�00000000143�14107073154�0022137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Hi, <span foo="*bar*"><em>there</em></span>. <!-- *blah* --> blah</p> <div> **ack** </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/raw_html.text��������������������������������������������������0000664�0000000�0000000�00000000126�14107073154�0022160�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Hi, <span foo="*bar*">*there*</span>. <!-- *blah* --> blah <div> **ack** </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/ref_links.html�������������������������������������������������0000664�0000000�0000000�00000000143�14107073154�0022276�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="http://www.google.com/">Google</a> is fast <img src="/img/star.png" alt="star" />.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/ref_links.text�������������������������������������������������0000664�0000000�0000000�00000000130�14107073154�0022312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[Google][] is fast ![star][]. [google]: http://www.google.com/ [star]: /img/star.png ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants.html����������������������������������������������0000664�0000000�0000000�00000007337�14107073154�0023062�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h2>Simple substitutions</h2> <p>Here I interrupt myself with an en dash – no, now it’s with—an em dash.</p> <p>And finally…wait for it, and again with spaces…I’ve tested ellipses…and also with even more spaces.</p> <h2>Escapes</h2> <p>Before getting to the hard stuff, I’ll run through all the escape sequences — they shouldn’t need to become HTML entities.</p> <pre><code>\\ \" \' \` \- \. \> </code></pre> <p>The “smarty-pants” extra adds escapes for 'single quotes' and "double quotes" in case you want to force dumb quotes.</p> <h2>Quotation marks</h2> <p>You’ll notice that I began this document with a quotation to test a potential error: $ is zero-width and \s is one-width, and you can’t have both in a backreference. Meanwhile, I’ve this paragraph has tested contractions four times; ’tis close, but this last apostrophe should fool the regex.</p> <p>“This text” tests to see whether an adjacent <p> tag messes up detection of quotation marks.</p> <p>The docs say, “You can open and close quotations with quotation marks, and they don’t both have to be single or double.” So ‘this” works. And “this.’ And finally, ‘this.’</p> <p>Most of the corrections are consistent with what a word processor might do when autoformatting:</p> <ul> <li>When a single- or double-prime falls between text and whitespace, it opens facing the text.</li> <li>Edge case: in “British grammar”, quotations are closed just before punctuation, so a closing quotation mark may be followed not by whitespace but by one of ,;.?!</li> <li>Other edge cases: nested quotation marks, or perhaps an apostrophe (see directly above) neighboring a quotation mark. The only “easy” solution is to have such quotation marks adjust to actual text, or if they’re only neighbored by whitespace and/or quotation marks, wait for those quotation marks to pick a direction, and then match it. Ick!</li> <li>Other edge cases: opening or closing quotations just within parentheses or brackets of some kind, generally in code, etc. Transformations here are <strong>not</strong> supported because said transformations are only meant to apply to plain English or other natural language; trying to satisfy such edge cases would lead to a slippery slope and bloat.</li> </ul> <h3>Edge case: contractions</h3> <p>A single-prime can be surrounded by text, in which case it becomes an apostrophe and opens left.</p> <p>For common contractions, a space single-prime non-space combination should produce an apostrophe (&#8217;) instead of an opening scare quote (&#8216;).</p> <p>Here is the full list: ’tis, ’twas, ’twer, ’neath, ’o, ’n, ’round, ’bout, ’twixt, ’nuff, ’fraid, ’sup <br /> The full list, capitalized: ’Tis, ’Twas, ’Twer, ’Neath, ’O, ’N, ’Round, ’Bout, ’Twixt, ’Nuff, ’Fraid, ’Sup <br /> And normal text: ‘random ‘stuff ‘that ‘shouldn’t ‘be ‘detected ‘as ‘contractions <br /> And years: ’29 ’91 ‘1942 ‘2001 ‘2010</p> <p>Like quotation marks, the year shorthand expects a year, e.g. '29, to be followed by whitespace or sentence-ending punctuation. Numbers like '456.7 will throw it off, but those aren’t entered very often.</p> <p>These transformations don’t consider whether or not the contraction was preceded by whitespace. If it was preceded by text, then it would have been converted by the standard contraction rule (see the first line of this section).</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants.opts����������������������������������������������0000664�0000000�0000000�00000000035�14107073154�0023067�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["smarty-pants"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants.tags����������������������������������������������0000664�0000000�0000000�00000000025�14107073154�0023037�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������smarty-pants issue42 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants.text����������������������������������������������0000664�0000000�0000000�00000006176�14107073154�0023102�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Simple substitutions Here I interrupt myself with an en dash -- no, now it's with---an em dash. And finally...wait for it, and again with spaces. . .I've tested ellipses . . . and also with even more spaces. ## Escapes Before getting to the hard stuff, I'll run through all the escape sequences --- they shouldn't need to become HTML entities. \\ \" \' \` \- \. \> The "smarty-pants" extra adds escapes for \'single quotes\' and \"double quotes\" in case you want to force dumb quotes. ## Quotation marks You'll notice that I began this document with a quotation to test a potential error: $ is zero-width and \\s is one-width, and you can't have both in a backreference. Meanwhile, I've this paragraph has tested contractions four times; 'tis close, but this last apostrophe should fool the regex. "This text" tests to see whether an adjacent <p> tag messes up detection of quotation marks. The docs say, "You can open and close quotations with quotation marks, and they don't both have to be single or double." So 'this" works. And "this.' And finally, 'this.' Most of the corrections are consistent with what a word processor might do when autoformatting: * When a single- or double-prime falls between text and whitespace, it opens facing the text. * Edge case: in "British grammar", quotations are closed just before punctuation, so a closing quotation mark may be followed not by whitespace but by one of ,;.?! * Other edge cases: nested quotation marks, or perhaps an apostrophe (see directly above) neighboring a quotation mark. The only "easy" solution is to have such quotation marks adjust to actual text, or if they're only neighbored by whitespace and/or quotation marks, wait for those quotation marks to pick a direction, and then match it. Ick! * Other edge cases: opening or closing quotations just within parentheses or brackets of some kind, generally in code, etc. Transformations here are **not** supported because said transformations are only meant to apply to plain English or other natural language; trying to satisfy such edge cases would lead to a slippery slope and bloat. ### Edge case: contractions A single-prime can be surrounded by text, in which case it becomes an apostrophe and opens left. For common contractions, a space single-prime non-space combination should produce an apostrophe (&#8217;) instead of an opening scare quote (&#8216;). Here is the full list: 'tis, 'twas, 'twer, 'neath, 'o, 'n, 'round, 'bout, 'twixt, 'nuff, 'fraid, 'sup The full list, capitalized: 'Tis, 'Twas, 'Twer, 'Neath, 'O, 'N, 'Round, 'Bout, 'Twixt, 'Nuff, 'Fraid, 'Sup And normal text: 'random 'stuff 'that 'shouldn't 'be 'detected 'as 'contractions And years: '29 '91 '1942 '2001 '2010 Like quotation marks, the year shorthand expects a year, e.g. \'29, to be followed by whitespace or sentence-ending punctuation. Numbers like \'456.7 will throw it off, but those aren't entered very often. These transformations don't consider whether or not the contraction was preceded by whitespace. If it was preceded by text, then it would have been converted by the standard contraction rule (see the first line of this section). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants_image_links.html����������������������������������0000664�0000000�0000000�00000000473�14107073154�0025416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><img src="/path/to/image.jpg" alt="alt text" /></p> <p>How about <img src="/path/to/image.jpg" alt="alt text" /> in other paragraph content?</p> <p>How about <img src="/path/to/image.jpg" alt="" /> sans alt text?</p> <p>How about a <a href="http://example.com" title="with a title">regular link</a> here?</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants_image_links.opts����������������������������������0000664�0000000�0000000�00000000035�14107073154�0025431�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["smarty-pants"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants_image_links.tags����������������������������������0000664�0000000�0000000�00000000025�14107073154�0025401�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������smarty-pants issue76 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/smarty_pants_image_links.text����������������������������������0000664�0000000�0000000�00000000336�14107073154�0025434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������![alt text](/path/to/image.jpg) How about ![alt text](/path/to/image.jpg) in other paragraph content? How about ![](/path/to/image.jpg) sans alt text? How about a [regular link](http://example.com "with a title") here? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/spoiler.html���������������������������������������������������0000664�0000000�0000000�00000000777�14107073154�0022014�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>[First]</p> <blockquote class="spoiler"> <p>This is a spoiler</p> </blockquote> <p>[Second]</p> <blockquote> <p>! But this is <br /> not a spoiler</p> </blockquote> <p>[Third]</p> <blockquote class="spoiler"> <p>A multi-line spoiler <br /> has ! multiple times</p> </blockquote> <p>[Fourth]</p> <blockquote class="spoiler"> <p>Alignment <br /> has no effect <br /> on spoilers</p> </blockquote> <p>[Last]</p> <blockquote class="spoiler"> <p><- still a spoiler</p> </blockquote> �python-markdown2-2.4.1/test/tm-cases/spoiler.opts���������������������������������������������������0000664�0000000�0000000�00000000027�14107073154�0022021�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["spoiler"]}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/spoiler.text���������������������������������������������������0000664�0000000�0000000�00000000341�14107073154�0022017�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[First] >! This is a spoiler [Second] >! But this is > not a spoiler [Third] >! A multi-line spoiler >! has ! multiple times [Fourth] >! Alignment > ! has no effect > ! on spoilers [Last] > ! <- still a spoiler �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/strike.html����������������������������������������������������0000664�0000000�0000000�00000000127�14107073154�0021625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><strike>This is strike line.</strike></p> <p>So is <strike>this</strike> word.</p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/strike.opts����������������������������������������������������0000664�0000000�0000000�00000000027�14107073154�0021645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["strike"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/strike.tags����������������������������������������������������0000664�0000000�0000000�00000000016�14107073154�0021614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras strike ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/strike.text����������������������������������������������������0000664�0000000�0000000�00000000057�14107073154�0021647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������~~This is strike line.~~ So is ~~this~~ word. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-ordered-para.html��������������������������������������0000664�0000000�0000000�00000000623�14107073154�0024355�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>Fails (or used to)</h1> <ol> <li>one</li> <li><p>two</p> <ul> <li>sub one</li> <li>sub two</li> </ul></li> <li><p>three</p></li> </ol> <h1>Works</h1> <ol> <li>one</li> <li><p>two</p> <ul> <li>sub one</li> <li>sub two</li> </ul></li> <li><p>three</p></li> </ol> <h1>Works too</h1> <ol> <li>one</li> <li><p>two</p> <ol> <li>sub one</li> <li>sub two</li> </ol></li> <li><p>three</p></li> </ol> �������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-ordered-para.tags��������������������������������������0000664�0000000�0000000�00000000010�14107073154�0024335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue67 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-ordered-para.text��������������������������������������0000664�0000000�0000000�00000000315�14107073154�0024373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Fails (or used to) 1. one 2. two - sub one - sub two 3. three # Works 1. one 2. two - sub one - sub two 3. three # Works too 1. one 2. two 1. sub one 2. sub two 3. three �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-para.html����������������������������������������������0000664�0000000�0000000�00000001204�14107073154�0022727�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Some quick thoughts from a coder's perspective:</p> <ul> <li><p>The source will be available in a Mercurial ...</p></li> <li><p>Komodo is a Mozilla-based application...</p> <ul> <li>Get a slightly tweaked mozilla build (C++, JavaScript, XUL).</li> <li>Get a slightly tweaks Python build (C).</li> <li>Add a bunch of core logic (Python)...</li> <li>Add Komodo chrome (XUL, JavaScript, CSS, DTDs).</li> </ul> <p><p>What this means is that work on and add significant functionality...</p></li> <li><p>Komodo uses the same extension mechanisms as Firefox...</p></li> <li><p>Komodo builds and runs on Windows, Linux and ...</p></li> </ul></p> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-para.tags����������������������������������������������0000664�0000000�0000000�00000000115�14107073154�0022721�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������questionable # <p><p> isn't really correct, but Markdown.pl does the same ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/sublist-para.text����������������������������������������������0000664�0000000�0000000�00000001023�14107073154�0022746�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Some quick thoughts from a coder's perspective: - The source will be available in a Mercurial ... - Komodo is a Mozilla-based application... - Get a slightly tweaked mozilla build (C++, JavaScript, XUL). - Get a slightly tweaks Python build (C). - Add a bunch of core logic (Python)... - Add Komodo chrome (XUL, JavaScript, CSS, DTDs). What this means is that work on and add significant functionality... - Komodo uses the same extension mechanisms as Firefox... - Komodo builds and runs on Windows, Linux and ... �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color.html����������������������������������������������0000664�0000000�0000000�00000002036�14107073154�0023051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Here is some sample code:</p> <div class="codehilite"><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span> <span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">):</span> <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">()</span> <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'hi'</span><span class="p">)</span> </code></pre></div> <p>and:</p> <div class="codehilite"><pre><span></span><code><span class="n">use</span> <span class="s1">'zlib'</span> <span class="nb">sub</span> <span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span> <span class="nb">puts</span> <span class="s1">'hi'</span> <span class="k">end</span> </code></pre></div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color.opts����������������������������������������������0000664�0000000�0000000�00000000033�14107073154�0023065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["code-color"]} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color.tags����������������������������������������������0000664�0000000�0000000�00000000032�14107073154�0023035�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra code-color pygments ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color.text����������������������������������������������0000664�0000000�0000000�00000000331�14107073154�0023065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Here is some sample code: :::python import sys def main(argv=sys.argv): logging.basicConfig() log.info('hi') and: :::ruby use 'zlib' sub main(argv) puts 'hi' end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color_opts.html�����������������������������������������0000664�0000000�0000000�00000001777�14107073154�0024131�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Here is some sample code:</p> <div class="codehilite" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><code><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">sys</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">main</span>(argv<span style="color: #666666">=</span>sys<span style="color: #666666">.</span>argv): logging<span style="color: #666666">.</span>basicConfig() log<span style="color: #666666">.</span>info(<span style="color: #BA2121">'hi'</span>) </code></pre></div> <p>and:</p> <div class="codehilite" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><code>use <span style="color: #BA2121">'zlib'</span> <span style="color: #008000">sub</span> main(argv) <span style="color: #008000">puts</span> <span style="color: #BA2121">'hi'</span> <span style="color: #008000; font-weight: bold">end</span> </code></pre></div> �python-markdown2-2.4.1/test/tm-cases/syntax_color_opts.opts�����������������������������������������0000664�0000000�0000000�00000000060�14107073154�0024132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": {"code-color": {"noclasses": True}}} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color_opts.tags�����������������������������������������0000664�0000000�0000000�00000000032�14107073154�0024102�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra code-color pygments ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/syntax_color_opts.text�����������������������������������������0000664�0000000�0000000�00000000331�14107073154�0024132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Here is some sample code: :::python import sys def main(argv=sys.argv): logging.basicConfig() log.info('hi') and: :::ruby use 'zlib' sub main(argv) puts 'hi' end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tables.html����������������������������������������������������0000664�0000000�0000000�00000011031�14107073154�0021572�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1>table no pipes</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <h1>tables with leading pipe</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <h1>tables with full bars</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <h1>tables with mixed bars</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <h1>tables with bars and leading spacing</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <p><em>Note:</em> This fails in GFM but works with PHP-Markdown.</p> <h1>table with cuddled following content</h1> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </tbody> </table> <p>after</p> <p><em>Note:</em> This passes GFM, but fails in PHP-Markdown.</p> <h1>FAIL: table with cuddled leading content</h1> <p>before | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 |</p> <h1>single column single leading bar</h1> <table> <thead> <tr> <th>Header 1</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> </tr> <tr> <td>Cell 3</td> </tr> </tbody> </table> <h1>single column single trailing bar</h1> <table> <thead> <tr> <th>Header 1</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> </tr> <tr> <td>Cell 3</td> </tr> </tbody> </table> <h1>single column full bars</h1> <table> <thead> <tr> <th>Header 1</th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> </tr> <tr> <td>Cell 3</td> </tr> </tbody> </table> <h1>narrow col 1</h1> <table> <thead> <tr> <th>H</th> </tr> </thead> <tbody> <tr> <td>1</td> </tr> <tr> <td>2</td> </tr> </tbody> </table> <p><em>Note:</em> This works in PHP-Markdown, fails in GFM.</p> <h1>narrow col 2</h1> <table> <thead> <tr> <th>He</th> </tr> </thead> <tbody> <tr> <td>1</td> </tr> <tr> <td>2</td> </tr> </tbody> </table> <p><em>Note:</em> This works in PHP-Markdown, fails in GFM.</p> <h1>narrow col 3</h1> <table> <thead> <tr> <th>He</th> </tr> </thead> <tbody> <tr> <td>1</td> </tr> <tr> <td>2</td> </tr> </tbody> </table> <p><em>Note:</em> Works in both PHP-Markdown and GFM.</p> <h1>FAIL: no dash</h1> <p>| He | | :: | | 1 | | 2 |</p> <p><em>Note</em>: This fails in GFM and <em>sort of</em> works in PHP-Markdown, where it sets to align=center. I'm going to make this <em>fail</em> in markdown2.py, i.e. the rule is it must have at least a single dash in there.</p> <h1>table with markup in cells</h1> <table> <thead> <tr> <th>Header 1</th> <th><em>Header</em> 2</th> </tr> </thead> <tbody> <tr> <td><code>Cell 1</code></td> <td><a href="http://example.com">Cell 2</a> link</td> </tr> <tr> <td>Cell 3</td> <td><strong>Cell 4</strong></td> </tr> </tbody> </table> <h1>table in blockquote</h1> <blockquote> <table> <thead> <tr> <th>One</th> <th>Two</th> <th>Three</th> </tr> </thead> <tbody> <tr> <td>grinch</td> <td>stole</td> <td>xmas</td> </tr> <tr> <td>green</td> <td><strong>eggs</strong></td> <td>ham</td> </tr> </tbody> </table> <p>-- Dr. Seuss</p> </blockquote> <h1>table with blank cells</h1> <table> <thead> <tr> <th>Header 1</th> <th></th> </tr> </thead> <tbody> <tr> <td>Cell 1</td> <td></td> </tr> <tr> <td></td> <td>Cell 4</td> </tr> </tbody> </table> <h1>table in blockquote with empty cells</h1> <blockquote> <table> <thead> <tr> <th></th> <th>Two</th> <th>Three</th> </tr> </thead> <tbody> <tr> <td>grinch</td> <td>stole</td> <td></td> </tr> <tr> <td>green</td> <td><strong>eggs</strong></td> <td>ham</td> </tr> </tbody> </table> <p>-- Dr. Seuss</p> </blockquote> <h1>escaping of pipes</h1> <table> <thead> <tr> <th>A</th> <th>|</th> <th>C | C</th> </tr> </thead> <tbody> <tr> <td>||</td> <td>BB</td> <td>C</td> </tr> </tbody> </table> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tables.opts����������������������������������������������������0000664�0000000�0000000�00000000027�14107073154�0021616�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["tables"]} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tables.tags����������������������������������������������������0000664�0000000�0000000�00000000015�14107073154�0021564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra tables �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tables.text����������������������������������������������������0000664�0000000�0000000�00000004416�14107073154�0021623�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# table no pipes Header 1 | Header 2 -------- | -------- Cell 1 | Cell 2 Cell 3 | Cell 4 # tables with leading pipe | Header 1 | Header 2 | -------- | -------- | Cell 1 | Cell 2 | Cell 3 | Cell 4 # tables with full bars | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | # tables with mixed bars Header 1 | Header 2 | -------- | -------- Cell 1 | Cell 2 | | Cell 3 | Cell 4 | # tables with bars and leading spacing | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | *Note:* This fails in GFM but works with PHP-Markdown. # table with cuddled following content | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | after *Note:* This passes GFM, but fails in PHP-Markdown. # FAIL: table with cuddled leading content before | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | # single column single leading bar | Header 1 | -------- | Cell 1 | Cell 3 # single column single trailing bar Header 1 | -------- | Cell 1 | Cell 3 | # single column full bars | Header 1 | | -------- | | Cell 1 | | Cell 3 | # narrow col 1 | H | | - | | 1 | | 2 | *Note:* This works in PHP-Markdown, fails in GFM. # narrow col 2 | He | | -- | | 1 | | 2 | *Note:* This works in PHP-Markdown, fails in GFM. # narrow col 3 | He | | --- | | 1 | | 2 | *Note:* Works in both PHP-Markdown and GFM. # FAIL: no dash | He | | :: | | 1 | | 2 | *Note*: This fails in GFM and *sort of* works in PHP-Markdown, where it sets to align=center. I'm going to make this *fail* in markdown2.py, i.e. the rule is it must have at least a single dash in there. # table with markup in cells | Header 1 | *Header* 2 | | -------- | -------- | | `Cell 1` | [Cell 2](http://example.com) link | | Cell 3 | **Cell 4** | # table in blockquote > | One | Two | Three | > | --- | --- | --- | > |grinch|stole|xmas| > |green|**eggs**|ham| > > -- Dr. Seuss # table with blank cells | Header 1 | | | -------- | -------- | | Cell 1 | | | | Cell 4 | # table in blockquote with empty cells > | | Two | Three | > | --- | --- | --- | > |grinch|stole|| > |green|**eggs**|ham| > > -- Dr. Seuss # escaping of pipes | A | \| | C \| C | |--- |--- | ------ | |\|\|| BB | C | ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/task_list.html�������������������������������������������������0000664�0000000�0000000�00000000413�14107073154�0022317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><input type="checkbox" class="task-list-item-checkbox" checked disabled> item1</li> <li><input type="checkbox" class="task-list-item-checkbox" disabled> item2</li> <li><input type="checkbox" class="task-list-item-checkbox" checked disabled> item3</li> </ul> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/task_list.opts�������������������������������������������������0000664�0000000�0000000�00000000031�14107073154�0022334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["task_list"]}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/task_list.tags�������������������������������������������������0000664�0000000�0000000�00000000030�14107073154�0022304�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra task_list issue216��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/task_list.text�������������������������������������������������0000664�0000000�0000000�00000000047�14107073154�0022342�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- [x] item1 - [ ] item2 - [X] item3 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_1.html�����������������������������������������������������0000664�0000000�0000000�00000000224�14107073154�0021327�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="fruit">Fruit</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h1 id="veggies">Veggies</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_1.opts�����������������������������������������������������0000664�0000000�0000000�00000000024�14107073154�0021346�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["toc"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_1.tags�����������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0021314�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_1.text�����������������������������������������������������0000664�0000000�0000000�00000000075�14107073154�0021353�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Fruit - apples - bananas # Veggies - carrots - lettuce �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_1.toc_html�������������������������������������������������0000664�0000000�0000000�00000000133�14107073154�0022173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#fruit">Fruit</a></li> <li><a href="#veggies">Veggies</a></li> </ul> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_2.html�����������������������������������������������������0000664�0000000�0000000�00000000571�14107073154�0021335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="readme-for-blah">README for Blah</h1> <h2 id="introduction">Introduction</h2> <h2 id="the-meat">The Meat</h2> <h3 id="beef">Beef</h3> <h5 id="steak">Steak</h5> <h5 id="burgers">Burgers</h5> <h3 id="chicken">Chicken</h3> <h3 id="pork">Pork</h3> <h4 id="mmmmmmmm-bacon">Mmmmmmmm, bacon</h4> <h1 id="at-the-top-level-again">At the <em>top</em> level again!?</h1> ���������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_2.opts�����������������������������������������������������0000664�0000000�0000000�00000000024�14107073154�0021347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["toc"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_2.tags�����������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0021315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_2.text�����������������������������������������������������0000664�0000000�0000000�00000000242�14107073154�0021350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# README for Blah ## Introduction ## The Meat ### Beef ##### Steak ##### Burgers ### Chicken ### Pork #### Mmmmmmmm, bacon # At the *top* level again!? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_2.toc_html�������������������������������������������������0000664�0000000�0000000�00000001145�14107073154�0022200�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#readme-for-blah">README for Blah</a> <ul> <li><a href="#introduction">Introduction</a></li> <li><a href="#the-meat">The Meat</a> <ul> <li><a href="#beef">Beef</a> <ul> <li><a href="#steak">Steak</a></li> <li><a href="#burgers">Burgers</a></li> </ul></li> <li><a href="#chicken">Chicken</a></li> <li><a href="#pork">Pork</a> <ul> <li><a href="#mmmmmmmm-bacon">Mmmmmmmm, bacon</a></li> </ul></li> </ul></li> </ul></li> <li><a href="#at-the-top-level-again">At the <em>top</em> level again!?</a></li> </ul> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_3.html�����������������������������������������������������0000664�0000000�0000000�00000000571�14107073154�0021336�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="readme-for-blah">README for Blah</h1> <h2 id="introduction">Introduction</h2> <h2 id="the-meat">The Meat</h2> <h3 id="beef">Beef</h3> <h5 id="steak">Steak</h5> <h5 id="burgers">Burgers</h5> <h3 id="chicken">Chicken</h3> <h3 id="pork">Pork</h3> <h4 id="mmmmmmmm-bacon">Mmmmmmmm, bacon</h4> <h1 id="at-the-top-level-again">At the <em>top</em> level again!?</h1> ���������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_3.opts�����������������������������������������������������0000664�0000000�0000000�00000000024�14107073154�0021350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["toc"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_3.tags�����������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0021316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_3.text�����������������������������������������������������0000664�0000000�0000000�00000000266�14107073154�0021357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������README for Blah =============== ## Introduction The Meat -------- ### Beef ##### Steak ##### Burgers ### Chicken ### Pork #### Mmmmmmmm, bacon # At the *top* level again!? ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_3.toc_html�������������������������������������������������0000664�0000000�0000000�00000001145�14107073154�0022201�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#readme-for-blah">README for Blah</a> <ul> <li><a href="#introduction">Introduction</a></li> <li><a href="#the-meat">The Meat</a> <ul> <li><a href="#beef">Beef</a> <ul> <li><a href="#steak">Steak</a></li> <li><a href="#burgers">Burgers</a></li> </ul></li> <li><a href="#chicken">Chicken</a></li> <li><a href="#pork">Pork</a> <ul> <li><a href="#mmmmmmmm-bacon">Mmmmmmmm, bacon</a></li> </ul></li> </ul></li> </ul></li> <li><a href="#at-the-top-level-again">At the <em>top</em> level again!?</a></li> </ul> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_4.html�����������������������������������������������������0000664�0000000�0000000�00000000331�14107073154�0021331�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="python">Python</h1> <h2 id="-1">蟒蛇</h2> <ul> <li>外形特性</li> <li>生活习性</li> </ul> <h2 id="markdown">Markdown</h2> <h2 id="-2">标记语言</h2> <ul> <li>类型</li> <li>历史</li> </ul> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_4.opts�����������������������������������������������������0000664�0000000�0000000�00000000024�14107073154�0021351�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["toc"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_4.tags�����������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0021317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_4.text�����������������������������������������������������0000664�0000000�0000000�00000000144�14107073154�0021353�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Python ## 蟒蛇 - 外形特性 - 生活习性 ## Markdown ## 标记语言 - 类型 - 历史 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_4.toc_html�������������������������������������������������0000664�0000000�0000000�00000000302�14107073154�0022174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#python">Python</a> <ul> <li><a href="#-1">蟒蛇</a></li> <li><a href="#markdown">Markdown</a></li> <li><a href="#-2">标记语言</a></li> </ul></li> </ul> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_5.html�����������������������������������������������������0000664�0000000�0000000�00000000224�14107073154�0021333�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="fruit">Fruit</h1> <ul> <li>apples</li> <li>bananas</li> </ul> <h1 id="veggies">Veggies</h1> <ul> <li>carrots</li> <li>lettuce</li> </ul> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_5.opts�����������������������������������������������������0000664�0000000�0000000�00000000042�14107073154�0021352�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["toc", "header-ids"]} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_5.tags�����������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0021320�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_5.text�����������������������������������������������������0000664�0000000�0000000�00000000075�14107073154�0021357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Fruit - apples - bananas # Veggies - carrots - lettuce �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_5.toc_html�������������������������������������������������0000664�0000000�0000000�00000000133�14107073154�0022177�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#fruit">Fruit</a></li> <li><a href="#veggies">Veggies</a></li> </ul> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_depth.html�������������������������������������������������0000664�0000000�0000000�00000000571�14107073154�0022300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<h1 id="readme-for-blah">README for Blah</h1> <h2 id="introduction">Introduction</h2> <h2 id="the-meat">The Meat</h2> <h3 id="beef">Beef</h3> <h5 id="steak">Steak</h5> <h5 id="burgers">Burgers</h5> <h3 id="chicken">Chicken</h3> <h3 id="pork">Pork</h3> <h4 id="mmmmmmmm-bacon">Mmmmmmmm, bacon</h4> <h1 id="at-the-top-level-again">At the <em>top</em> level again!?</h1> ���������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_depth.opts�������������������������������������������������0000664�0000000�0000000�00000000056�14107073154�0022317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "extras": { "toc": {"depth": 3} } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_depth.tags�������������������������������������������������0000664�0000000�0000000�00000000012�14107073154�0022260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������toc extra ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_depth.text�������������������������������������������������0000664�0000000�0000000�00000000242�14107073154�0022313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# README for Blah ## Introduction ## The Meat ### Beef ##### Steak ##### Burgers ### Chicken ### Pork #### Mmmmmmmm, bacon # At the *top* level again!? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/toc_depth.toc_html���������������������������������������������0000664�0000000�0000000�00000000634�14107073154�0023145�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ul> <li><a href="#readme-for-blah">README for Blah</a> <ul> <li><a href="#introduction">Introduction</a></li> <li><a href="#the-meat">The Meat</a> <ul> <li><a href="#beef">Beef</a></li> <li><a href="#chicken">Chicken</a></li> <li><a href="#pork">Pork</a></li> </ul></li> </ul></li> <li><a href="#at-the-top-level-again">At the <em>top</em> level again!?</a></li> </ul> ����������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tricky_anchors.html��������������������������������������������0000664�0000000�0000000�00000000622�14107073154�0023346�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><a href="/url/">with [brackets][] in text</a></p> <p><a href="/url/" title="a title">with [[brackets][]] in text</a></p> <p><a href="/url/">full link [like](/this/) in text</a></p> <p><a href="/url/">full link to img <img src="/this/" alt="like" /> is ok</a></p> <p>[only open <a href="/url/" title="a title">bracket(/in/) text</a></p> <p><a href="/in/">only close bracket</a> text](/url/)</p> ��������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/tricky_anchors.text��������������������������������������������0000664�0000000�0000000�00000000414�14107073154�0023365�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[with [brackets][] in text](/url/) [with [[brackets][]] in text](/url/ "a title") [full link [like](/this/) in text](/url/) [full link to img ![like](/this/) is ok](/url/) [only open [bracket(/in/) text](/url/ 'a title') [only close bracket](/in/) text](/url/) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/two_comments.html����������������������������������������������0000664�0000000�0000000�00000000126�14107073154�0023041�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><!-- comment one --> paragraph one</p> <p>paragraph two</p> <!-- comment two --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/two_comments.text����������������������������������������������0000664�0000000�0000000�00000000110�14107073154�0023052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- comment one --> paragraph one paragraph two <!-- comment two --> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline.html�������������������������������������������������0000664�0000000�0000000�00000000053�14107073154�0022307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>This is some <u>underline</u> text.</p> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline.opts�������������������������������������������������0000664�0000000�0000000�00000000032�14107073154�0022325�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["underline"]} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline.tags�������������������������������������������������0000664�0000000�0000000�00000000021�14107073154�0022274�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extras underline ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline.text�������������������������������������������������0000664�0000000�0000000�00000000041�14107073154�0022324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is some --underline-- text. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline_in_autolink.html�������������������������������������0000664�0000000�0000000�00000000347�14107073154�0024711�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>Eric wrote up a (long) intro to writing UDL definitions a while back on his blog: <a href="http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html">http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html</a></p> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/underline_in_autolink.text�������������������������������������0000664�0000000�0000000�00000000224�14107073154�0024723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Eric wrote up a (long) intro to writing UDL definitions a while back on his blog: <http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/wiki_tables.html�����������������������������������������������0000664�0000000�0000000�00000004630�14107073154�0022624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tbody> <tr> <td><em>Year</em></td> <td><em>Temperature (low)</em></td> <td><em>Temperature (high)</em></td> </tr> <tr> <td>1900</td> <td>-10</td> <td>25</td> </tr> <tr> <td>1910</td> <td>-15</td> <td>30</td> </tr> <tr> <td>1920</td> <td>-10</td> <td>32</td> </tr> </tbody> </table> <h1>With header row</h1> <table> <thead> <tr> <th>Name</th> <th>Class</th> <th>Race</th> <th>Level</th> </tr> </thead> <tbody> <tr> <td>Vlad</td> <td>Barbarian</td> <td>Dragonborn</td> <td>12</td> </tr> <tr> <td>Jimbo</td> <td>Rogue</td> <td>Halfling</td> <td>13</td> </tr> </tbody> </table> <h1>With only header row</h1> <table> <thead> <tr> <th>Name</th> <th>Class</th> <th>Race</th> <th>Level</th> </tr> </thead> </table> <h1>With header row, alternate spacing</h1> <table> <thead> <tr> <th>Name</th> <th>Class</th> <th>Race</th> <th>Level</th> </tr> </thead> <tbody> <tr> <td>Vlad</td> <td>Barbarian</td> <td>Dragonborn</td> <td>12</td> </tr> <tr> <td>Jimbo</td> <td>Rogue</td> <td>Halfling</td> <td>13</td> </tr> </tbody> </table> <h1>just one line</h1> <table> <tbody> <tr> <td>foo</td> <td>bar</td> <td>baz</td> </tr> </tbody> </table> <h1>blockquote</h1> <blockquote> <table> <tbody> <tr> <td>grinch</td> <td>stole</td> <td>xmas</td> </tr> <tr> <td>green</td> <td><strong>eggs</strong></td> <td>ham</td> </tr> </tbody> </table> <p>-- Dr. Seuss</p> </blockquote> <h1>end of file</h1> <table> <tbody> <tr> <td>ResourceNotFound</td> <td>If :login does not exist</td> </tr> </tbody> </table> ��������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/wiki_tables.opts�����������������������������������������������0000664�0000000�0000000�00000000034�14107073154�0022637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"extras": ["wiki-tables"]} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/wiki_tables.tags�����������������������������������������������0000664�0000000�0000000�00000000022�14107073154�0022605�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������extra wiki-tables ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/wiki_tables.text�����������������������������������������������0000664�0000000�0000000�00000001263�14107073154�0022643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������|| *Year* || *Temperature (low)* || *Temperature (high)* || || 1900 || -10 || 25 || || 1910 || -15 || 30 || || 1920 || -10 || 32 || # With header row ||~ Name ||~ Class ||~ Race ||~ Level || || Vlad || Barbarian || Dragonborn || 12 || || Jimbo || Rogue || Halfling || 13 || # With only header row ||~ Name ||~ Class ||~ Race ||~ Level || # With header row, alternate spacing || ~Name || ~Class || ~Race || ~Level || || Vlad || Barbarian || Dragonborn || 12 || || Jimbo || Rogue || Halfling || 13 || # just one line ||foo||bar||baz|| # blockquote > ||grinch||stole||xmas|| > ||green||**eggs**||ham|| > > -- Dr. Seuss # end of file ||ResourceNotFound||If :login does not exist|| ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/xss_quotes.html������������������������������������������������0000664�0000000�0000000�00000000174�14107073154�0022543�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p><img src="http://static.reddit.com/reddit.com.header.png" onload="alert('javascript injected')" alt="a" /></p> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/xss_quotes.tags������������������������������������������������0000664�0000000�0000000�00000000010�14107073154�0022522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������issue30 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/test/tm-cases/xss_quotes.text������������������������������������������������0000664�0000000�0000000�00000000142�14107073154�0022556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������![a][b] [b]: http://static.reddit.com/reddit.com.header.png" onload="alert('javascript injected') ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/tools/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�14107073154�0016103�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/tools/cutarelease.py���������������������������������������������������������0000775�0000000�0000000�00000051514�14107073154�0020763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2009-2012 Trent Mick """cutarelease -- Cut a release of your project. A script that will help cut a release for a git-based project that follows a few conventions. It'll update your changelog (CHANGES.md), add a git tag, push those changes, update your version to the next patch level release and create a new changelog section for that new version. Conventions: - XXX """ __version_info__ = (1, 0, 7) __version__ = '.'.join(map(str, __version_info__)) import sys import os from os.path import exists, basename, splitext import re import codecs import logging import optparse import json #---- globals and config log = logging.getLogger("cutarelease") class Error(Exception): pass #---- main functionality def cutarelease(project_name, version_files, dry_run=False): """Cut a release. @param project_name {str} @param version_files {list} List of paths to files holding the version info for this project. If none are given it attempts to guess the version file: package.json or VERSION.txt or VERSION or $project_name.py or lib/$project_name.py or $project_name.js or lib/$project_name.js. The version file can be in one of the following forms: - A .py file, in which case the file is expect to have a top-level global called "__version_info__" as follows. [1] __version_info__ = (0, 7, 6) Note that I typically follow that with the following to get a string version attribute on my modules: __version__ = '.'.join(map(str, __version_info__)) - A .js file, in which case the file is expected to have a top-level global called "VERSION" as follows: ver VERSION = "1.2.3"; - A "package.json" file, typical of a node.js npm-using project. The package.json file must have a "version" field. - TODO: A simple version file whose only content is a "1.2.3"-style version string. [1]: This is a convention I tend to follow in my projects. Granted it might not be your cup of tea. I should add support for just `__version__ = "1.2.3"`. I'm open to other suggestions too. """ dry_run_str = dry_run and " (dry-run)" or "" if not version_files: log.info("guessing version file") candidates = [ "package.json", "VERSION.txt", "VERSION", "%s.py" % project_name, "lib/%s.py" % project_name, "%s.js" % project_name, "lib/%s.js" % project_name, ] for candidate in candidates: if exists(candidate): version_files = [candidate] break else: raise Error("could not find a version file: specify its path or " "add one of the following to your project: '%s'" % "', '".join(candidates)) log.info("using '%s' as version file", version_files[0]) parsed_version_files = [_parse_version_file(f) for f in version_files] version_file_type, version_info = parsed_version_files[0] version = _version_from_version_info(version_info) # Confirm if not dry_run: answer = query_yes_no("* * *\n" "Are you sure you want cut a %s release?\n" "This will involved commits and a push." % version, default="no") print("* * *") if answer != "yes": log.info("user abort") return log.info("cutting a %s release%s", version, dry_run_str) # Checks: Ensure there is a section in changes for this version. changes_path = "CHANGES.md" changes_txt, changes, nyr = parse_changelog(changes_path) #pprint(changes) top_ver = changes[0]["version"] if top_ver != version: raise Error("changelog '%s' top section says " "version %r, expected version %r: aborting" % (changes_path, top_ver, version)) top_verline = changes[0]["verline"] if not top_verline.endswith(nyr): answer = query_yes_no("\n* * *\n" "The changelog '%s' top section doesn't have the expected\n" "'%s' marker. Has this been released already?" % (changes_path, nyr), default="yes") print("* * *") if answer != "no": log.info("abort") return top_body = changes[0]["body"] if top_body.strip() == "(nothing yet)": raise Error("top section body is `(nothing yet)': it looks like " "nothing has been added to this release") # Commits to prepare release. changes_txt_before = changes_txt changes_txt = changes_txt.replace(" (not yet released)", "", 1) if not dry_run and changes_txt != changes_txt_before: log.info("prepare `%s' for release", changes_path) f = codecs.open(changes_path, 'w', 'utf-8') f.write(changes_txt) f.close() run('git commit %s -m "prepare for %s release"' % (changes_path, version)) # Tag version and push. curr_tags = set(t for t in _capture_stdout(["git", "tag", "-l"]).split(b'\n') if t) if not dry_run and version not in curr_tags: log.info("tag the release") run('git tag -a "%s" -m "version %s"' % (version, version)) run('git push --tags') # Optionally release. if exists("package.json"): answer = query_yes_no("\n* * *\nPublish to npm?", default="yes") print("* * *") if answer == "yes": if dry_run: log.info("skipping npm publish (dry-run)") else: run('npm publish') elif exists("setup.py"): answer = query_yes_no("\n* * *\nPublish to pypi?", default="yes") print("* * *") if answer == "yes": if dry_run: log.info("skipping pypi publish (dry-run)") else: run("rm -rf dist") run("%spython setup.py sdist bdist_wheel" % _setup_command_prefix()) run("twine upload dist/*") run("rm -rf dist") # Commits to prepare for future dev and push. # - update changelog file next_version_info = _get_next_version_info(version_info) next_version = _version_from_version_info(next_version_info) log.info("prepare for future dev (version %s)", next_version) marker = "## " + changes[0]["verline"] if marker.endswith(nyr): marker = marker[0:-len(nyr)] if marker not in changes_txt: raise Error("couldn't find `%s' marker in `%s' " "content: can't prep for subsequent dev" % (marker, changes_path)) next_verline = "%s %s%s" % (marker.rsplit(None, 1)[0], next_version, nyr) changes_txt = changes_txt.replace(marker + '\n', "%s\n\n(nothing yet)\n\n\n%s\n" % (next_verline, marker)) if not dry_run: f = codecs.open(changes_path, 'w', 'utf-8') f.write(changes_txt) f.close() # - update version file next_version_tuple = _tuple_from_version(next_version) for i, ver_file in enumerate(version_files): ver_content = codecs.open(ver_file, 'r', 'utf-8').read() ver_file_type, ver_info = parsed_version_files[i] if ver_file_type == "json": marker = '"version": "%s"' % version if marker not in ver_content: raise Error("couldn't find `%s' version marker in `%s' " "content: can't prep for subsequent dev" % (marker, ver_file)) ver_content = ver_content.replace(marker, '"version": "%s"' % next_version) elif ver_file_type == "javascript": marker = 'var VERSION = "%s";' % version if marker not in ver_content: raise Error("couldn't find `%s' version marker in `%s' " "content: can't prep for subsequent dev" % (marker, ver_file)) ver_content = ver_content.replace(marker, 'var VERSION = "%s";' % next_version) elif ver_file_type == "python": marker = "__version_info__ = %r" % (version_info,) if marker not in ver_content: raise Error("couldn't find `%s' version marker in `%s' " "content: can't prep for subsequent dev" % (marker, ver_file)) ver_content = ver_content.replace(marker, "__version_info__ = %r" % (next_version_tuple,)) elif ver_file_type == "version": ver_content = next_version else: raise Error("unknown ver_file_type: %r" % ver_file_type) if not dry_run: log.info("update version to '%s' in '%s'", next_version, ver_file) f = codecs.open(ver_file, 'w', 'utf-8') f.write(ver_content) f.close() if not dry_run: run('git commit %s %s -m "prep for future dev"' % ( changes_path, ' '.join(version_files))) run('git push') #---- internal support routines def _indent(s, indent=' '): return indent + indent.join(s.splitlines(True)) def _tuple_from_version(version): def _intify(s): try: return int(s) except ValueError: return s return tuple(_intify(b) for b in version.split('.')) def _get_next_version_info(version_info): next = list(version_info[:]) next[-1] += 1 return tuple(next) def _version_from_version_info(version_info): v = str(version_info[0]) state_dot_join = True for i in version_info[1:]: if state_dot_join: try: int(i) except ValueError: state_dot_join = False else: pass if state_dot_join: v += "." + str(i) else: v += str(i) return v _version_re = re.compile(r"^(\d+)\.(\d+)(?:\.(\d+)([abc](\d+)?)?)?$") def _version_info_from_version(version): m = _version_re.match(version) if not m: raise Error("could not convert '%s' version to version info" % version) version_info = [] for g in m.groups(): if g is None: break try: version_info.append(int(g)) except ValueError: version_info.append(g) return tuple(version_info) def _parse_version_file(version_file): """Get version info from the given file. It can be any of: Supported version file types (i.e. types of files from which we know how to parse the version string/number -- often by some convention): - json: use the "version" key - javascript: look for a `var VERSION = "1.2.3";` - python: Python script/module with `__version_info__ = (1, 2, 3)` - version: a VERSION.txt or VERSION file where the whole contents are the version string @param version_file {str} Can be a path or "type:path", where "type" is one of the supported types. """ # Get version file *type*. version_file_type = None match = re.compile("^([a-z]+):(.*)$").search(version_file) if match: version_file = match.group(2) version_file_type = match.group(1) aliases = { "js": "javascript" } if version_file_type in aliases: version_file_type = aliases[version_file_type] f = codecs.open(version_file, 'r', 'utf-8') content = f.read() f.close() if not version_file_type: # Guess the type. base = basename(version_file) ext = splitext(base)[1] if ext == ".json": version_file_type = "json" elif ext == ".py": version_file_type = "python" elif ext == ".js": version_file_type = "javascript" elif content.startswith("#!"): shebang = content.splitlines(False)[0] shebang_bits = re.split(r'[/ \t]', shebang) for name, typ in {"python": "python", "node": "javascript"}.items(): if name in shebang_bits: version_file_type = typ break elif base in ("VERSION", "VERSION.txt"): version_file_type = "version" if not version_file_type: raise RuntimeError("can't extract version from '%s': no idea " "what type of file it it" % version_file) if version_file_type == "json": obj = json.loads(content) version_info = _version_info_from_version(obj["version"]) elif version_file_type == "python": m = re.search(r'^__version_info__ = (.*?)$', content, re.M) version_info = eval(m.group(1)) elif version_file_type == "javascript": m = re.search(r'^var VERSION = "(.*?)";$', content, re.M) version_info = _version_info_from_version(m.group(1)) elif version_file_type == "version": version_info = _version_info_from_version(content.strip()) else: raise RuntimeError("unexpected version_file_type: %r" % version_file_type) return version_file_type, version_info def parse_changelog(changes_path): """Parse the given changelog path and return `(content, parsed, nyr)` where `nyr` is the ' (not yet released)' marker and `parsed` looks like: [{'body': u'\n(nothing yet)\n\n', 'verline': u'restify 1.0.1 (not yet released)', 'version': u'1.0.1'}, # version is parsed out for top section only {'body': u'...', 'verline': u'1.0.0'}, {'body': u'...', 'verline': u'1.0.0-rc2'}, {'body': u'...', 'verline': u'1.0.0-rc1'}] A changelog (CHANGES.md) is expected to look like this: # $project Changelog ## $next_version (not yet released) ... ## $version1 ... ## $version2 ... and so on The version lines are enforced as follows: - The top entry should have a " (not yet released)" suffix. "Should" because recovery from half-cutarelease failures is supported. - A version string must be extractable from there, but it tries to be loose (though strict "X.Y.Z" versioning is preferred). Allowed ## 1.0.0 ## my project 1.0.1 ## foo 1.2.3-rc2 Basically, (a) the " (not yet released)" is stripped, (b) the last token is the version, and (c) that version must start with a digit (sanity check). """ if not exists(changes_path): raise Error("changelog file '%s' not found" % changes_path) content = codecs.open(changes_path, 'r', 'utf-8').read() parser = re.compile( r'^##\s*(?P<verline>[^\n]*?)\s*$(?P<body>.*?)(?=^##|\Z)', re.M | re.S) sections = parser.findall(content) # Sanity checks on changelog format. if not sections: template = "## 1.0.0 (not yet released)\n\n(nothing yet)\n" raise Error("changelog '%s' must have at least one section, " "suggestion:\n\n%s" % (changes_path, _indent(template))) nyr = ' (not yet released)' items = [] for i, section in enumerate(sections): item = { "verline": section[0], "body": section[1] } if i == 0: # We only bother to pull out 'version' for the top section. verline = section[0] if verline.endswith(nyr): verline = verline[0:-len(nyr)] version = verline.split()[-1] try: int(version[0]) except ValueError: msg = '' if version.endswith(')'): msg = " (cutarelease is picky about the trailing %r " \ "on the top version line. Perhaps you misspelled " \ "that?)" % nyr raise Error("changelog '%s' top section version '%s' is " "invalid: first char isn't a number%s" % (changes_path, version, msg)) item["version"] = version items.append(item) return content, items, nyr ## {{{ http://code.activestate.com/recipes/577058/ (r2) def query_yes_no(question, default="yes"): """Ask a yes/no question via input() and return their answer. "question" is a string that is presented to the user. "default" is the presumed answer if the user just hits <Enter>. It must be "yes" (the default), "no" or None (meaning an answer is required of the user). The "answer" return value is one of "yes" or "no". """ valid = {"yes":"yes", "y":"yes", "ye":"yes", "no":"no", "n":"no"} if default == None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("invalid default answer: '%s'" % default) while 1: sys.stdout.write(question + prompt) choice = input().lower() if default is not None and choice == '': return default elif choice in valid.keys(): return valid[choice] else: sys.stdout.write("Please respond with 'yes' or 'no' "\ "(or 'y' or 'n').\n") ## end of http://code.activestate.com/recipes/577058/ }}} def _capture_stdout(argv): import subprocess p = subprocess.Popen(argv, stdout=subprocess.PIPE) return p.communicate()[0] class _NoReflowFormatter(optparse.IndentedHelpFormatter): """An optparse formatter that does NOT reflow the description.""" def format_description(self, description): return description or "" def run(cmd): """Run the given command. Raises OSError is the command returns a non-zero exit status. """ log.debug("running '%s'", cmd) fixed_cmd = cmd if sys.platform == "win32" and cmd.count('"') > 2: fixed_cmd = '"' + cmd + '"' retval = os.system(fixed_cmd) if hasattr(os, "WEXITSTATUS"): status = os.WEXITSTATUS(retval) else: status = retval if status: raise OSError(status, "error running '%s'" % cmd) def _setup_command_prefix(): prefix = "" if sys.platform == "darwin": # http://forums.macosxhints.com/archive/index.php/t-43243.html # This is an Apple customization to `tar` to avoid creating # '._foo' files for extended-attributes for archived files. prefix = "COPY_EXTENDED_ATTRIBUTES_DISABLE=1 " return prefix #---- mainline def main(argv): logging.basicConfig(format="%(name)s: %(levelname)s: %(message)s") log.setLevel(logging.INFO) # Parse options. parser = optparse.OptionParser(prog="cutarelease", usage='', version="%prog " + __version__, description=__doc__, formatter=_NoReflowFormatter()) parser.add_option("-v", "--verbose", dest="log_level", action="store_const", const=logging.DEBUG, help="more verbose output") parser.add_option("-q", "--quiet", dest="log_level", action="store_const", const=logging.WARNING, help="quieter output (just warnings and errors)") parser.set_default("log_level", logging.INFO) parser.add_option("--test", action="store_true", help="run self-test and exit (use 'eol.py -v --test' for verbose test output)") parser.add_option("-p", "--project-name", metavar="NAME", help='the name of this project (default is the base dir name)', default=basename(os.getcwd())) parser.add_option("-f", "--version-file", metavar="[TYPE:]PATH", action='append', dest="version_files", help='The path to the project file holding the version info. Can be ' 'specified multiple times if more than one file should be updated ' 'with new version info. If excluded, it will be guessed.') parser.add_option("-n", "--dry-run", action="store_true", help='Do a dry-run', default=False) opts, args = parser.parse_args() log.setLevel(opts.log_level) cutarelease(opts.project_name, opts.version_files, dry_run=opts.dry_run) ## {{{ http://code.activestate.com/recipes/577258/ (r5+) if __name__ == "__main__": try: retval = main(sys.argv) except KeyboardInterrupt: sys.exit(1) except SystemExit: raise except: import traceback, logging if not log.handlers and not logging.root.handlers: logging.basicConfig() skip_it = False exc_info = sys.exc_info() if hasattr(exc_info[0], "__name__"): exc_class, exc, tb = exc_info if isinstance(exc, IOError) and exc.args[0] == 32: # Skip 'IOError: [Errno 32] Broken pipe': often a cancelling of `less`. skip_it = True if not skip_it: tb_path, tb_lineno, tb_func = traceback.extract_tb(tb)[-1][:3] log.error("%s (%s:%s in %s)", exc_info[1], tb_path, tb_lineno, tb_func) else: # string exception log.error(exc_info[0]) if not skip_it: if log.isEnabledFor(logging.DEBUG): traceback.print_exception(*exc_info) sys.exit(1) else: sys.exit(retval) ## end of http://code.activestate.com/recipes/577258/ }}} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/tools/tables-align-columns.py������������������������������������������������0000775�0000000�0000000�00000011426�14107073154�0022504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python """ Convert [tables](https://github.com/trentm/python-markdown2/wiki/tables) a given Markdown document such that columns are aligned. Limitations: - Can't handle tables where cells have a pipe. """ from __future__ import print_function __version__ = "1.0.0" import codecs import os from pprint import pprint, pformat import re import sys from collections import defaultdict p = print def e(*args, **kwargs): kwargs['file'] = sys.stderr p(*args, **kwargs) #---- internal support stuff def tables_align_columns(path): def _table_sub(match): head, underline, body = match.groups() data_rows = [ [cell.strip() for cell in head.strip().strip('|').split('|')], ] for line in body.strip('\n').split('\n'): data_rows.append([cell.strip() for cell in line.strip().strip('|').split('|')]) width_from_col_idx = defaultdict(int) for data_row in data_rows: for col_idx, cell in enumerate(data_row): width_from_col_idx[col_idx] = max( 2, width_from_col_idx[col_idx], len(cell)) # Determine aligns for columns. ucells = [cell.strip() for cell in underline.strip('| \t\n').split('|')] align_from_col_idx = {} for col_idx, cell in enumerate(ucells): if cell[0] == ':' and cell[-1] == ':': align_from_col_idx[col_idx] = 'center' elif cell[0] == ':': align_from_col_idx[col_idx] = 'left' elif cell[-1] == ':': align_from_col_idx[col_idx] = 'right' else: align_from_col_idx[col_idx] = None table = [] for data_row in data_rows: row = [] #e('align_from_col_idx:', align_from_col_idx) #e('data_row:', data_row) for col_idx, cell in enumerate(data_row): width = width_from_col_idx[col_idx] try: align = align_from_col_idx[col_idx] except KeyError: # Limitation: We hit a table row where a cell has a # literal `|` in it. We can't currently handle that, so # lets just skip this table. e('tables-align-columns: warning: skipping a table ' 'with literal `|`: %r' % match.group(0)) return match.group(0) if align == 'center': space = width - len(cell) left = space / 2 right = space - left row.append(' '*left + cell + ' '*right) elif align == 'right': row.append('%%%ds' % width % cell) else: row.append('%%-%ds' % width % cell) table.append(row) underline = [] for col_idx, cell in enumerate(data_rows[0]): width = width_from_col_idx[col_idx] align = align_from_col_idx[col_idx] if align == 'center': underline.append(':' + u'-'*(width-2) + ':') elif align == 'right': underline.append(u'-'*(width-1) + ':') elif align == 'left': underline.append(':' + u'-'*(width-1)) else: underline.append(u'-'*width) table[1:1] = [underline] #e(pformat(table, width=200)) table_str = u'\n'.join(('| ' + u' | '.join(r) + ' |') for r in table) return table_str + '\n' text = codecs.open(path, 'rb', 'utf8').read() less_than_tab = 3 table_re = re.compile(r''' (?:(?<=\n\n)|\A\n?) # leading blank line ^[ ]{0,%d} # allowed whitespace (.*[|].*) \n # $1: header row (at least one pipe) ^[ ]{0,%d} # allowed whitespace ( # $2: underline row # underline row with leading bar (?: \|\ *:?-+:?\ * )+ \|? \n | # or, underline row without leading bar (?: \ *:?-+:?\ *\| )+ (?: \ *:?-+:?\ * )? \n ) ( # $3: data rows (?: ^[ ]{0,%d}(?!\ ) # ensure line begins with 0 to less_than_tab spaces .*\|.* \n )+ ) ''' % (less_than_tab, less_than_tab, less_than_tab), re.M | re.X) return table_re.sub(_table_sub, text) #---- mainline def main(argv): for path in argv[1:]: text = tables_align_columns(path) sys.stdout.write(text.encode( sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) if __name__ == "__main__": sys.exit( main(sys.argv) ) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/tools/which.py���������������������������������������������������������������0000775�0000000�0000000�00000030231�14107073154�0017561�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # Copyright (c) 2002-2007 ActiveState Software Inc. # See LICENSE.txt for license details. # Author: # Trent Mick (TrentM@ActiveState.com) # Home: # http://trentm.com/projects/which/ r"""Find the full path to commands. which(command, path=None, verbose=0, exts=None) Return the full path to the first match of the given command on the path. whichall(command, path=None, verbose=0, exts=None) Return a list of full paths to all matches of the given command on the path. whichgen(command, path=None, verbose=0, exts=None) Return a generator which will yield full paths to all matches of the given command on the path. By default the PATH environment variable is searched (as well as, on Windows, the AppPaths key in the registry), but a specific 'path' list to search may be specified as well. On Windows, the PATHEXT environment variable is applied as appropriate. If "verbose" is true then a tuple of the form (<fullpath>, <matched-where-description>) is returned for each match. The latter element is a textual description of where the match was found. For example: from PATH element 0 from HKLM\SOFTWARE\...\perl.exe """ from __future__ import print_function _cmdlnUsage = """ Show the full path of commands. Usage: which [<options>...] [<command-name>...] Options: -h, --help Print this help and exit. -V, --version Print the version info and exit. -a, --all Print *all* matching paths. -v, --verbose Print out how matches were located and show near misses on stderr. -q, --quiet Just print out matches. I.e., do not print out near misses. -p <altpath>, --path=<altpath> An alternative path (list of directories) may be specified for searching. -e <exts>, --exts=<exts> Specify a list of extensions to consider instead of the usual list (';'-separate list, Windows only). Show the full path to the program that would be run for each given command name, if any. Which, like GNU's which, returns the number of failed arguments, or -1 when no <command-name> was given. Near misses include duplicates, non-regular files and (on Un*x) files without executable access. """ __revision__ = "$Id$" __version_info__ = (1, 1, 3) __version__ = '.'.join(map(str, __version_info__)) __all__ = ["which", "whichall", "whichgen", "WhichError"] import os import sys import getopt import stat #---- exceptions class WhichError(Exception): pass #---- internal support stuff def _getRegisteredExecutable(exeName): """Windows allow application paths to be registered in the registry.""" registered = None if sys.platform.startswith('win'): if os.path.splitext(exeName)[1].lower() != '.exe': exeName += '.exe' import _winreg try: key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" +\ exeName value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, key) registered = (value, "from HKLM\\"+key) except _winreg.error: pass if registered and not os.path.exists(registered[0]): registered = None return registered def _samefile(fname1, fname2): if sys.platform.startswith('win'): return ( os.path.normpath(os.path.normcase(fname1)) ==\ os.path.normpath(os.path.normcase(fname2)) ) else: return os.path.samefile(fname1, fname2) def _cull(potential, matches, verbose=0): """Cull inappropriate matches. Possible reasons: - a duplicate of a previous match - not a disk file - not executable (non-Windows) If 'potential' is approved it is returned and added to 'matches'. Otherwise, None is returned. """ for match in matches: # don't yield duplicates if _samefile(potential[0], match[0]): if verbose: sys.stderr.write("duplicate: %s (%s)\n" % potential) return None else: if not stat.S_ISREG(os.stat(potential[0]).st_mode): if verbose: sys.stderr.write("not a regular file: %s (%s)\n" % potential) elif sys.platform != "win32" \ and not os.access(potential[0], os.X_OK): if verbose: sys.stderr.write("no executable access: %s (%s)\n"\ % potential) else: matches.append(potential) return potential #---- module API def whichgen(command, path=None, verbose=0, exts=None): """Return a generator of full paths to the given command. "command" is a the name of the executable to search for. "path" is an optional alternate path list to search. The default it to use the PATH environment variable. "verbose", if true, will cause a 2-tuple to be returned for each match. The second element is a textual description of where the match was found. "exts" optionally allows one to specify a list of extensions to use instead of the standard list for this system. This can effectively be used as an optimization to, for example, avoid stat's of "foo.vbs" when searching for "foo" and you know it is not a VisualBasic script but ".vbs" is on PATHEXT. This option is only supported on Windows. This method returns a generator which yields either full paths to the given command or, if verbose, tuples of the form (<path to command>, <where path found>). """ matches = [] if path is None: usingGivenPath = 0 path = os.environ.get("PATH", "").split(os.pathsep) if sys.platform.startswith("win"): path.insert(0, os.curdir) # implied by Windows shell else: usingGivenPath = 1 # Windows has the concept of a list of extensions (PATHEXT env var). if sys.platform.startswith("win"): if exts is None: exts = os.environ.get("PATHEXT", "").split(os.pathsep) # If '.exe' is not in exts then obviously this is Win9x and # or a bogus PATHEXT, then use a reasonable default. for ext in exts: if ext.lower() == ".exe": break else: exts = ['.COM', '.EXE', '.BAT'] elif not isinstance(exts, list): raise TypeError("'exts' argument must be a list or None") else: if exts is not None: raise WhichError("'exts' argument is not supported on "\ "platform '%s'" % sys.platform) exts = [] # File name cannot have path separators because PATH lookup does not # work that way. if os.sep in command or os.altsep and os.altsep in command: if os.path.exists(command): match = _cull((command, "explicit path given"), matches, verbose) if verbose: yield match else: yield match[0] else: for i in range(len(path)): dirName = path[i] # On windows the dirName *could* be quoted, drop the quotes if sys.platform.startswith("win") and len(dirName) >= 2\ and dirName[0] == '"' and dirName[-1] == '"': dirName = dirName[1:-1] for ext in ['']+exts: absName = os.path.abspath( os.path.normpath(os.path.join(dirName, command+ext))) if os.path.isfile(absName): if usingGivenPath: fromWhere = "from given path element %d" % i elif not sys.platform.startswith("win"): fromWhere = "from PATH element %d" % i elif i == 0: fromWhere = "from current directory" else: fromWhere = "from PATH element %d" % (i-1) match = _cull((absName, fromWhere), matches, verbose) if match: if verbose: yield match else: yield match[0] match = _getRegisteredExecutable(command) if match is not None: match = _cull(match, matches, verbose) if match: if verbose: yield match else: yield match[0] def which(command, path=None, verbose=0, exts=None): """Return the full path to the first match of the given command on the path. "command" is a the name of the executable to search for. "path" is an optional alternate path list to search. The default it to use the PATH environment variable. "verbose", if true, will cause a 2-tuple to be returned. The second element is a textual description of where the match was found. "exts" optionally allows one to specify a list of extensions to use instead of the standard list for this system. This can effectively be used as an optimization to, for example, avoid stat's of "foo.vbs" when searching for "foo" and you know it is not a VisualBasic script but ".vbs" is on PATHEXT. This option is only supported on Windows. If no match is found for the command, a WhichError is raised. """ try: match = whichgen(command, path, verbose, exts).next() except StopIteration: raise WhichError("Could not find '%s' on the path." % command) return match def whichall(command, path=None, verbose=0, exts=None): """Return a list of full paths to all matches of the given command on the path. "command" is a the name of the executable to search for. "path" is an optional alternate path list to search. The default it to use the PATH environment variable. "verbose", if true, will cause a 2-tuple to be returned for each match. The second element is a textual description of where the match was found. "exts" optionally allows one to specify a list of extensions to use instead of the standard list for this system. This can effectively be used as an optimization to, for example, avoid stat's of "foo.vbs" when searching for "foo" and you know it is not a VisualBasic script but ".vbs" is on PATHEXT. This option is only supported on Windows. """ return list( whichgen(command, path, verbose, exts) ) #---- mainline def main(argv): all = 0 verbose = 0 altpath = None exts = None try: optlist, args = getopt.getopt(argv[1:], 'haVvqp:e:', ['help', 'all', 'version', 'verbose', 'quiet', 'path=', 'exts=']) except getopt.GetoptError as msg: sys.stderr.write("which: error: %s. Your invocation was: %s\n"\ % (msg, argv)) sys.stderr.write("Try 'which --help'.\n") return 1 for opt, optarg in optlist: if opt in ('-h', '--help'): print(_cmdlnUsage) return 0 elif opt in ('-V', '--version'): print("which %s" % __version__) return 0 elif opt in ('-a', '--all'): all = 1 elif opt in ('-v', '--verbose'): verbose = 1 elif opt in ('-q', '--quiet'): verbose = 0 elif opt in ('-p', '--path'): if optarg: altpath = optarg.split(os.pathsep) else: altpath = [] elif opt in ('-e', '--exts'): if optarg: exts = optarg.split(os.pathsep) else: exts = [] if len(args) == 0: return -1 failures = 0 for arg in args: #print "debug: search for %r" % arg nmatches = 0 for match in whichgen(arg, path=altpath, verbose=verbose, exts=exts): if verbose: print("%s (%s)" % match) else: print(match) nmatches += 1 if not all: break if not nmatches: failures += 1 return failures if __name__ == "__main__": sys.exit( main(sys.argv) ) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������python-markdown2-2.4.1/tools/wiki-tables-to-tables.py�����������������������������������������������0000775�0000000�0000000�00000006773�14107073154�0022600�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python """ Convert a Markdown document using [wiki-tables](https://github.com/trentm/python-markdown2/wiki/wiki-tables) to a Markdown document using [tables](https://github.com/trentm/python-markdown2/wiki/tables) Limitations: - Doesn't handle tables inside blockquotes. - "tables" require a head section, "wiki-tables" does not. That creates an ambiguity on conversion: what to use for the head row? We'll do the following. First we'll look at the first row, and if the cells are em'd or strong'd like this: ||**Param**||**Type**||**Description**|| ||kernel_args||Object||Boot parms to update|| ||boot_modules||Array||List of boot module objects|| ||kernel_flags||Object||Kernel flags to update|| ||platform||String||Set platform as the bootable platform|| ||*Code*||*Type*||*Description*|| ||204||None||Boot parameters successfully set|| ||404||None||No such Server|| Then we'll use that as the header row. If not we'll bail. This is "strict" mode... and the only supported mode for now. """ from __future__ import print_function __version__ = "1.0.0" import codecs import os from pprint import pprint, pformat import re import sys p = print def e(*args, **kwargs): kwargs['file'] = sys.stderr p(*args, **kwargs) #---- internal support stuff def wiki_tables_to_tables(path): def _wiki_table_sub(match): ttext = match.group(0).strip() #e('wiki table: %r' % match.group(0)) rows = [] for line in ttext.splitlines(0): line = line.strip()[2:-2].strip() row = [c.strip() for c in re.split(r'(?<!\\)\|\|', line)] rows.append(row) #e(pformat(rows)) head = [] for cell in rows[0]: if cell.startswith('**') and cell.endswith('**'): head.append(cell[2:-2].strip()) elif cell.startswith('*') and cell.endswith('*'): head.append(cell[1:-1].strip()) else: raise RuntimeError( 'wiki-table in "%s" has no header row, bailing: %r' % (path, ttext)) underline = [] for cell in head: underline.append('-' * max(1, len(cell))) body = rows[1:] table = [head, underline] + body table_str = '\n'.join(('| ' + ' | '.join(r) + ' |') for r in table) return table_str + '\n' text = codecs.open(path, 'rb', 'utf8').read() # If there is a leading markdown2 metadata block with; # markdown2extras: ..., wiki-tables, ... # then update that to 'tables'. _metadata_pat = re.compile("""^---[ \t]*\n((?:[ \t]*[^ \t:]+[ \t]*:[^\n]*\n)+)---[ \t]*\n""") match = _metadata_pat.match(text) if match: metadata_str = match.group(0) if re.search(r'^markdown2extras\s*:.*?\bwiki-tables\b', metadata_str, re.M): text = text.replace('wiki-tables', 'tables', 1) less_than_tab = 3 wiki_table_re = re.compile(r''' (?:(?<=\n\n)|\A\n?) # leading blank line ^([ ]{0,%d})\|\|.+?\|\|[ ]*\n # first line (^\1\|\|.+?\|\|\n)* # any number of subsequent lines ''' % less_than_tab, re.M | re.X) return wiki_table_re.sub(_wiki_table_sub, text) #---- mainline def main(argv): for path in argv[1:]: tables = wiki_tables_to_tables(path) sys.stdout.write(tables.encode( sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) if __name__ == "__main__": sys.exit( main(sys.argv) ) �����python-markdown2-2.4.1/tox.ini����������������������������������������������������������������������0000664�0000000�0000000�00000000511�14107073154�0016253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tox (http://tox.testrun.org/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] envlist = py35, py36, py37, py38, py39, pypy [testenv] commands = make testone ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������