Don't write scripts, just write ipyscripts!

  |   Source   |   Minimap

I usually have some repetitive tasks in my daily work-flow. You probably have some of those too. To save some minutes from your day, you probably write little scripts to do these jobs.

I used to do that... but now I am only writing little IPython notebooks to do these simple jobs, I call them ipyscripts (yes, I won a prize for originality, he he!).

These ipyscripts are IPython-powered, so we can use all the IPython's machinery to do complex things in a simple way...

In fact, you are reading a example ipyscript, because this is an IPython notebook (and a blog post too), and the following example deal with a repetitive task I do frequently: the git update of some projects (I contribute to some of them, I follow some others).

First, I load a simple list with the projects I want to update:

In [1]:
list_of_projects = ["ipython", 
                    "kilink", 
                    "live_reveal", 
                    "nbviewer", 
                    "nikola", 
                    "reveal.js"]
  Click me to hide the output

Second, I save my current directory using the IPython bookmark system:

In [2]:
%bookmark root
  Click me to hide the output

Third, I define a function to deal with the git update itself:

In [3]:
def update(folder):
    %cd {folder}
    !git status
    !git checkout master
    !git remote -v
    !git pull origin
    %cd -b root
  Click me to hide the output

You can see here how I am using a lot of tricks from the IPython machinery to make a lot of things in a couple of lines.

The main idea is cd into a specific project folder. I use the braces to pass python variables and expressions to the shell. In this case, I will pass an element of the list_of_projects, I mean the name of the folder containing the desired project. Then, I do the git stuff, just prepending the command with the ! sign to pass them to the underlying shell. Finally, I cd into the main directory to get the things prepared to the next loop.

Fourth, I do a simple for loop to iterate through the elements inside the list_of_projects and to do the git update in each of these projects.

In [4]:
for i in xrange(len(list_of_projects)):
    update(list_of_projects[i])
    print "---------------------------------"
  Click me to hide the output
/media/datos/Desarrollos/ipython
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
damianavila	git@github.com:damianavila/ipython.git (fetch)
damianavila	git@github.com:damianavila/ipython.git (push)
origin	git@github.com:ipython/ipython.git (fetch)
origin	git@github.com:ipython/ipython.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------
/media/datos/Desarrollos/kilink
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
damianavila	git@github.com:damianavila/kilink.git (fetch)
damianavila	git@github.com:damianavila/kilink.git (push)
origin	git@github.com:facundobatista/kilink.git (fetch)
origin	git@github.com:facundobatista/kilink.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------
/media/datos/Desarrollos/live_reveal
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
origin	git@github.com:ipython-contrib/live_reveal.git (fetch)
origin	git@github.com:ipython-contrib/live_reveal.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------
/media/datos/Desarrollos/nbviewer
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
heroku	git@heroku.com:zarara.git (fetch)
heroku	git@heroku.com:zarara.git (push)
origin	git@github.com:ipython/nbviewer.git (fetch)
origin	git@github.com:ipython/nbviewer.git (push)
zarara	git@heroku.com:zarara.git (fetch)
zarara	git@heroku.com:zarara.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------
/media/datos/Desarrollos/nikola
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
damianavila	git@github.com:damianavila/nikola.git (fetch)
damianavila	git@github.com:damianavila/nikola.git (push)
origin	git@github.com:getnikola/nikola.git (fetch)
origin	git@github.com:getnikola/nikola.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------
/media/datos/Desarrollos/reveal.js
# En la rama master
nothing to commit, working directory clean
Ya está en «master»
origin	git@github.com:hakimel/reveal.js.git (fetch)
origin	git@github.com:hakimel/reveal.js.git (push)
Already up-to-date.
(bookmark:root) -> /media/datos/Desarrollos
/media/datos/Desarrollos
---------------------------------

ADDENDUM:

You can actually do:

for i in list_of_projects: 
    update(i)
print "---------------------------------"

But, this is an example, and I wanted to emphasize the fact that you can pass complex arguments inside the braces... Thanks Lex for your comment, I forgot to add this explanation!


And that's all! The next time you have to do this task, just run this notebook (properly customized for your projects) and you will get the job done!

NOTE: And now, the icing on the cake... if you are in IPython master, you do not even need to open the notebook to run it... just open an IPython console or notebook and write the next sentence:

%run your_ipyscript.ipynb

Yes, you can use the %run magic to run all the code cells from the notebook you pass as an argument ;-) Niceeeeeeeeeee!

NOTE 2: There is an ongoing PR to make this %run notebook extensive to notebooks containing non-code cells.

OK, I hope you enjoy this post. And I also hope you begin to write ipyscripts.

See you!

Damián

Don't forget this blog post is an ipynb file itself! So, you can download it from the "Source" link at the top of the post if you want to play with it ;-)

Comments powered by Disqus