7

Closest related question is this one: In Ipython, how can I pass arguments to a cell as though it were its own script?

I am writing an ipython notebook to make simulations and then create an animation in paraview. The way I do this is run a cell with the magic command

%%script pvpython

since paraview has its own interpreter. The problem is that I need it to pass it the directory of the vtu files as an argument (which are a variable in the IPython kernel). So far I have been unable to figure this out. I have tried:

%%script pvpython path/to/files
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo')
args = parser.parse_args()
print(args.foo)

But this gives an error: `Got unknown argument: path/to/files because the argument is being passed to the magic command not the python script. Is there a way to get around this?

Edit: This is different from the linked question because I am using a cell magic not line magic. I would prefer to have all my code visible in the notebook alone.

Takoda
  • 354
  • 3
  • 12
  • Possible duplicate of [Running a python script in jupyter notebook, with arguments passing](https://stackoverflow.com/questions/51551056/running-a-python-script-in-jupyter-notebook-with-arguments-passing) – Reblochon Masque Aug 07 '18 at 17:20
  • 1
    Noted your edit, I'll retract my duplicate suggestion; indeed the dupe is for a line magic. This is a good question. – Reblochon Masque Aug 07 '18 at 17:42

1 Answers1

1

I don't exactly recall where I found this, and it doesn't seem to be documented, but this is an extremely useful feature for cell magics.

This isn't a python formatting mechanism, it's the same jupyter interpolation used for interpolation in line magics starting with !. Note the absence of quotes in the carelessly-quoted variable.

Cell 1:

simple_var = 123
crazy_var = " with spaces \n 'asdf' $DOLLAR$$ $$SIGNS$$ "
import shlex
tamed_var = shlex.quote(crazy_var)

Cell 2:

%%bash -s '{simple_var}' {tamed_var} '{crazy_var}'

echo $#

for i in $(seq 1 $#) ; do
    echo "$i: ${!i}"
done

Cell 2 output:

3
1: 123
2:  with spaces 
 'asdf' $DOLLAR$$ $$SIGNS$$ 
3:  with spaces 
 asdf $DOLLAR$$ $$SIGNS$$ 

As an aside, the script form is also a convenient way of timing bash cells: %%script time bash -s '{simple_var}' {tamed_var} '{crazy_var}' would be the replacement above.

The docs are here, but they don't go deep into what %%script does. Based on this behavior, though, it looks like jupyter feeds the rest of the cell as standard input. This is interesting, since it says "%%script is basically shebang", which is not the case (otherwise we wouldn't need bash's -s). So in your case you replace the bash -s magic I used above with script pvpython.

VF1
  • 1,594
  • 2
  • 11
  • 31