-
-
Save dpsanders/6723919 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Implementation alternatives for [PR 3801](https://github.com/ipython/ipython/pull/3801)\n", | |
"\n", | |
"This is the code in the PR:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import re\n", | |
"\n", | |
"START_WITH_MAGIC_PATTERN = re.compile(\"%+\") # find %\n", | |
"\n", | |
"def penalize_magics_key(word):\n", | |
" \"\"\"key for sorting that penalizes magic commands in the ordering\n", | |
"\n", | |
" Normal words are left alone.\n", | |
"\n", | |
" Magic commands have the initial % moved to the end, e.g.\n", | |
" %matplotlib is transformed as follows:\n", | |
"\n", | |
" %matplotlib -> matplotlib%\n", | |
"\n", | |
" [The choice of the final % is arbitrary.]\n", | |
"\n", | |
" Since \"matplotlib\" < \"matplotlib%\" as strings, \n", | |
" \"timeit\" will appear before the magic \"%timeit\" in the ordering\n", | |
"\n", | |
" For consistency, move \"%%\" to the end, so cell magics appear *after*\n", | |
" line magics with the same name.\n", | |
"\n", | |
" \"\"\"\n", | |
"\n", | |
" # Move all % to end of the *key* (don't change the actual text, of course)\n", | |
"\n", | |
" m = START_WITH_MAGIC_PATTERN.match(word) # at the start of the string\n", | |
"\n", | |
" if m != None: # if there is a match\n", | |
" word = word[m.end():] + m.group() # move all %'s to the end\n", | |
" \n", | |
" return word" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"This alternative uses only string methods:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def penalize_magics_key2(word):\n", | |
" i = word.rfind('%')\n", | |
" if i in (0,1):\n", | |
" s = i+1\n", | |
" p, w = word[:s], word[s:]\n", | |
" return w+p\n", | |
" else:\n", | |
" return word" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def penalize_magics_key3(word):\n", | |
" if word[:2]==\"%%\":\n", | |
" if not \"%\" in word[2:]:\n", | |
" return word[2:] + \"%%\" \n", | |
"\n", | |
" if word[0]==\"%\":\n", | |
" if not \"%\" in word[2:]:\n", | |
" return word[1:] + \"%\"\n", | |
" \n", | |
" return word" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 27 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def penalize_magics_key4(word):\n", | |
" # Does not check for % in word\n", | |
" if word[:2]==\"%%\":\n", | |
" # if word.startswith(\"%%\")\n", | |
" return word[2:] + \"%%\" \n", | |
"\n", | |
" if word[0]==\"%\":\n", | |
" # if word.startswith(\"%\"):\n", | |
" return word[1:] + \"%\"\n", | |
" \n", | |
" return word" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 38 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Sanity checks:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for s in ['%foo', '%%foo', '%foo%', 'foo%%']:\n", | |
" a = penalize_magics_key(s)\n", | |
" b = penalize_magics_key2(s)\n", | |
" c = penalize_magics_key3(s)\n", | |
" d = penalize_magics_key4(s)\n", | |
" if a!=b:\n", | |
" print 'Ori:', s, 're:', a,'str:', b\n", | |
" if a!=c:\n", | |
" print 'Ori:', s, 're:', a,'str:', c\n", | |
" if a!=d:\n", | |
" print 'Ori:', s, 're:', a,'str:', d\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Ori: %foo% re: foo%% str: %foo%\n", | |
"Ori: %foo% re: foo%% str: %foo%\n" | |
] | |
} | |
], | |
"prompt_number": 32 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"for s in ['%foo', '%%foo', '%foo%', 'foo%%']:\n", | |
" a = penalize_magics_key(s)\n", | |
" b = penalize_magics_key2(s)\n", | |
" c = penalize_magics_key3(s)\n", | |
" d = penalize_magics_key4(s)\n", | |
" print 'Orig:', s, 're:', a,'str:', b, 'str_new:', c, 'str_new2:', d\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Orig: %foo re: foo% str: foo% str_new: foo% str_new2: foo%\n", | |
"Orig: %%foo re: foo%% str: foo%% str_new: foo%% str_new2: foo%%\n", | |
"Orig: %foo% re: foo%% str: %foo% str_new: %foo% str_new2: foo%%\n", | |
"Orig: foo%% re: foo%% str: foo%% str_new: foo%% str_new2: foo%%\n" | |
] | |
} | |
], | |
"prompt_number": 34 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Note that the new version is actually better in terms of behavior, since it only transforms pure magic calls and not other strings." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Performance checks:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"a = '%%foo'\n", | |
"%timeit penalize_magics_key(a)\n", | |
"%timeit penalize_magics_key2(a)\n", | |
"%timeit penalize_magics_key3(a)\n", | |
"%timeit penalize_magics_key4(a)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1000000 loops, best of 3: 985 ns per loop\n", | |
"1000000 loops, best of 3: 720 ns per loop" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"\n", | |
"1000000 loops, best of 3: 428 ns per loop" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"\n", | |
"1000000 loops, best of 3: 321 ns per loop" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"\n" | |
] | |
} | |
], | |
"prompt_number": 39 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"[The string-based code is also almost twice as fast.]\n", | |
"\n", | |
"The simplest version is 3 times faster." | |
] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment