I’ve been teaching now for several years with Jupyter notebooks, and also using them myself. In my efforts to convince more people to use notebooks, I have encountered a lot of confusion about when / how to use them, and also why people should use them at all and not just use “scripting” and an “IDE”.
I’ve spent some time thinking about this and have collected some thoughts on this, and
in particular even what the word “scripting” means, which I would like to share here. Any thoughts / comments / discussion is welcome!
Scripting vs. coding
What is scripting? I was trying to explain this to the TAs of my first year python course. To try to help, I did some googling, but then after my google searching, I was myself even more confused about how to define “scripting” and how it is different than “programming” or “coding”…and it seems it’s not so easy to define…
Some of this is also historical. In the olden days, there was a clear difference: “bash” was scripting, “C” was programming. Interpreted was “scripting”, compiled was “programming”.
But developments in high level interpreted languages combined with massively faster computers has changed all of that in practice. So what is a good description for the difference between “scripting” and “programming” for python?
Here are some of my thoughts:
I would use the word “scripting” for the case in which I have a single flat python file that I run non-interactively by executing it in one go on the python interpreter:
$ python my_script.py
It would take inputs and produce outputs. You could run it by pushing a button in spyder, or by using the command line.
A script of course contains lines of python code
What things would I not use the word “script” for?
I would definitely not use the word “script” for code that defines “library” functions. For example, a python file that I then import functions from. This code would typically not “do” anything other than define functions. It would make no sense to run it on the command line (although you could).
I would also not typically use the word “script” for a python file that interacts with the user. For example, if the code opens up a window, allow the user to plot stuff, add labels, save a file, open another file, etc, and continues until the user pushed an “exit” button, then I would not call this a “python script” but instead a “python program”
And then finally, we have jupyter notebooks. In general, the code that we put in the code cells of jupyter notebooks are small and “do stuff”. Like a script. But they are not, in my picture above, a “script”: you cannot execute them on the command line. (Although you can run a notebook non-interactively from the command line if you are a nerd…but not a typical usage.) The code block in a jupyter notebook can be built to run independently (a single code block that you push the run button and it does everything). In this case, each code block is “like” a script. And the notebook then can contain many scripts.
But also, in jupyter notebooks, you can “split” you script so that you can run each separate bit one step at a time. This is actually really useful as you can then interleave debugging, take a look at variables on the way, etc, as you write and develop your code. This is why I quite like developing new code inside notebooks: it’s a nice way to build up a complicated script / function or even class step-by-step.
When NOT to use Jupyter Notebooks for your code
Finally, a comment on when NOT to use jupyter notebooks: once your code blocks become really long in a jupyter notebook, the notebooks concept loses it’s usefulness and becomes unmanageable. The notebooks are just not a good tool for large code blocks. In this case, though, once you start writing long code blocks, the proper thing to do is to write your code into functions (or even better, classes) in a plain-text .py file. (And then, at some point, it becomes useful to edit this code inside an IDE that is more sophisticated than the simple text editor that the notebook server provides…).
Once you have abstracted your code into functions / classes, then you can “use” it in both “script” .py files and in Jupyter notebooks by importing the functions from your longer, abstracted code. Then in your script, or in your cells of your Jupyter notebook, you can then just directly “call” the functions / classes you define in your “library” .py file. In this case, I also like using Jupyter notebooks for running code from my library, since I am able to document what I am doing more robustly using the markdown cells, and also because the outputs of my cells are recorded directly below the cell that produced them.