Ipython magic that replaces some text and runs the cell afterwards - ipython

I'm trying to create an ipython magic somewhat akin to the %pylab, but more explicit (probably a follow-up from here ):
When run, it would ideally replace itself with a commented version + append the lines that do the imports and run the cell:
%mymagic
# some code
would turn into
# %mymagic
import numpy as np
%matplotlib qt
import matplotlib.pyplot as plt
# ..some other imports
# the same code from earlier
The thinking being that not only the magic will only do extremely explicit things - i.e. you will actually see the code that it run / it will be saved explicitly in the notebook, but also convenient as usual - just a quick few symbols for the imports (useful in consoles).
The problem for me is then running the cell after changing it (I used %load magic as an example, so I use set_next_input to change the cell).
I've tried running the imports inside the magic (i.e. exactly how the %pylab did it) and then changing the cell, but that has the disadvantage of leaving the cell in the "not run" state, and does not work as well then the magic is called in the ipython console (you have to press enter to get rid of the explicit text). Also, the the same code has to be maintained twice (one for "printing", and second time - for actual import when executing the magic)
Any advice how to approach this?
Thanks

Related

Stop NetBeans "fixing" imports

How do I stop Netbeans (8.2) automatically "fixing" imports, on every keystroke?
For example,
deleting an import statement halfway through typing the statement [presumably because 'import x' isn't used when you are trying to type 'import x.y' ].
Removing all the imports when I type a ", /*. {, or anything that makes the rest of the program syntactically invalid [presumably because it is "not using" the imports.
It is annoying to have to 'fix-imports' on almost every keystroke, but awful when fix-imports gets it wrong (eg. a program that using java.awt.* and java.util.List, but not java.awt.List)
To be honset I don't get your question exactly. What you describe seems not to be the default behaviour of NetBeans.
From your question it seems that you're writing your imports on your own. This is not necessary. When you want to use an non imported class just use the autocompletion (Ctrl+Space) or organize imports (Ctrl+Shift+i).
I've never had any of the issues that you describe. You might have installed some additional plugins.
The particular plugin that seemed to be causing the problem is
https://github.com/rsmz/AutoSaveModified
It saves every 1 second but that causes imports to be fixed every 1 second.

How to cleanly pass command-line parameters when test-running my Python script?

So I'm writing Python with IDLE and my usual workflow is to have two windows (an editor and a console), and run my script with F5 to quickly test it.
My script has some non-optional command line parameters, and I have two conflicting desires:
If someone launches my script without passing any parameters, I'd like him to get an error telling him to do so (argparse does this well)
When I hit F5 in IDLE, I'd like to have my script run with dummy parameters (and I don't want to have more keystrokes than F5 to have this work, and I don't want to have a piece of code I have to remember to remove when I'm not debugging any more)
So far my solution has been that if I get no parameters, I look for a params.debug file (that's not under source control), and if so, take that as default params, but it's a bit ugly... so would there be a cleaner, more "standard" solution to this? Do other IDEs offer easier ways of doing this?
Other solutions I can think of: environment variables, having a separate "launcher" script that's the one taking the "official" parameters.
(I'm likely to try out another IDE anyway)
With some editors you can define the 'execute' command,
For example with Geany, for Python files, F5 is python2.7 %f. That could be modified to something like python2.7 %f dummy parameters. But I use an attached terminal window and its line history more than F5 like commands.
I'm an Ipython user, so don't remember much about the IDLE configuration. In Ipython I usually use the %run magic, which is more like invoking the script from a shell than from an IDE. Ipython also has a better previous line history than the shell.
For larger scripts I like to put the guts of the code (classes, functions) in one file, and test code in the if __name__ block. The user interface is in another file that imports this core module.
Thanks for your question. I also searched for a way to do this. I found that Spyder which is the IDE I use has an option under Run/Configure to enter the command line parameters for running the program. You can even configure different ones for the different editors you have open.
Python tracker issue 5680 is a proposal to add to Idle a way to set command lines args for F5 Run module. You are free to test any of the proposed patches if you are able to apply them.
In the meanwhile conditionally extending sys.argv as done below should fulfill your requirements.
import sys
in __name__ == '__main__':
if 'idlelib.PyShell' in sys.modules:
sys.argv.extend(('a', '-2')) # add your argments here.
print(sys.argv) # in use, parse sys.argv after extending it
# ['C:\\Programs\\python34\\tem.py', 'a', '-2']

Is there a way to add timing by default to ipython?

When using IPython, it's often convenient to see how long your commands take to run by using the %time magic function. When you use this often enough, you start to wish that you could just get toggle a setting to get this metadata by default whenever you enter a query. Psql lets you do this with \timing. GHCi lets you do this with :set s+. Does IPython let you do this? And if not, why not?
The "ipythonic" way of timing code is using the %timeit or %%timeit magic function (respectively for online, and multi-line code).
These functions provide quite accurate results by running the code multiple times (the exact number is adaptive if not specified).
The global flag you are asking does not exist in ipython. Furthermore, just adding %%timeit to all the cells will not work because global variables are not modified when calling %%timeit. This "feature" is directly inherited from the timeitmodule.
For more info see this ipython issue.

Execute another ipython notebook in a separate namespace

I've been using some very nice code from this example to run one ipython notebook from another, which I (basically) copy below. This turns out to be a very nice way to organize my code.
But now, I want to compare some sympy expressions that I've coded up with roughly equivalent sympy expressions that someone else has coded up. And since there are some name clashes, I'd like to be able to execute the two notebooks in their own namespaces, so that if Bob and I both define a sympy expression x, I can just evaluate
Bob.x - Me.x
to see if they are the same (or find their differences). [Note that it's easy to change a namespace dictionary into a "dottable" namespace using something like this Bunch object.]
Here's the function:
def exec_nb(nbfile):
from io import open
from IPython.nbformat import current
with open(nbfile) as f:
nb = current.read(f, 'json')
ip = get_ipython()
for cell in nb.worksheets[0].cells:
if cell.cell_type != 'code':
continue
ip.run_cell(cell.input)
The basic problem is the get_ipython gets the currently running ipython instance, and then run_cell executes the cells from the other notebook in the current namespace of that instance.
I can't figure out how to change this. For example, running the whole command in exec with a different namespace still finds the current ipython instance, and uses that namespace.
Also, both notebooks actually need to be run in ipython; I can't export them to a script and execute the scripts in a namespace.
For the record, the link Jakob pointed to has now moved here, and answered my question perfectly.

Preserving ipython's input prompt filtering in customized prompts

As described in the manual, ipython is smart enough to automatically strip the default prompt from pasted lines of code -- very handy. I have customized my prompt to my liking, which unfortunately seems to have broken this logic. Is it possible to adapt the pattern match logic in my startup files to reflect a customized prompt, and if so, how?
If you're using the latest IPython (1.0 or the development version), then yes, although it's not something that we particularly support (i.e. the API might change in the future). Define a regex which will match your prompts - like this one for classic Python prompts: re.compile(r'^(>>> ?|\.\.\. ?)').
Then you'll need some code like this (not tested):
from IPython.core.inputtransformer import CoroutineInputTransformer, _strip_prompts
#CoroutineInputTransformer.wrap
def my_prompt():
prompt_re = re.compile(r'foo')
return _strip_prompts(prompt_re)
ip = get_ipython()
ip.input_splitter.physical_line_transforms.insert(0, my_prompt())
ip.input_transformer_manager.physical_line_transforms.insert(0, my_prompt())
You can put that in a startup file (IPYTHONDIR/profile_default/startup/prompts.py) to have it run automatically when you start IPython.