diff --git a/Makefile b/Makefile
index bc870bf46540b407c246577a5f103d0125f82d25..b64f958b4d07ad53d304cd1c37e965a0fcdb0118 100644
--- a/Makefile
+++ b/Makefile
@@ -3,51 +3,36 @@
 
 MAINTEXFILE = main.tex
 TEXFILES = ${MAINTEXFILE}
-SAGETEXSCRIPT = main.sagetex.sage
+NOTEBOOKBASENAMES = plots_and_expressions examples characteristic_curves rank_zero_case other_P_choice
 
 main.pdf: ${TEXFILES}  main.sagetex.sout.tmp
 	latexmk
 
-main.sagetex.sout.tmp: ${SAGETEXSCRIPT} plots_and_expressions.py examples.py characteristic_curves.py rank_zero_case.py other_P_choice.py
+sage_artifacts: main.sagetex.sout.tmp
+
+SAGETEXSCRIPT = main.sagetex.sage
+main.sagetex.sout.tmp: ${SAGETEXSCRIPT} notebook_py_libs
 	PYTHONPATH=./sagetexscripts/ sage ${SAGETEXSCRIPT}
 
 ${SAGETEXSCRIPT}: ${TEXFILES}
 	latexmk || echo this shoud fail
 
-plots_and_expressions.py: plots_and_expressions.ipynb
-	jupyter nbconvert --to script plots_and_expressions.ipynb
-	mv plots_and_expressions.py plots_and_expressions.sage
-	sed -e "/get_ipython/d" -i plots_and_expressions.sage
-	sage --preparse plots_and_expressions.sage
-	mv plots_and_expressions.sage.py plots_and_expressions.py
-
-examples.py: plots_and_expressions.py examples.ipynb
-	jupyter nbconvert --to script examples.ipynb
-	mv examples.py examples.sage
-	sed -e "/get_ipython/d" -i examples.sage
-	sage --preparse examples.sage
-	mv examples.sage.py examples.py
-
-characteristic_curves.py: characteristic_curves.ipynb
-	jupyter nbconvert --to script characteristic_curves.ipynb
-	mv characteristic_curves.py characteristic_curves.sage
-	sed -e "/get_ipython/d" -i characteristic_curves.sage
-	sage --preparse characteristic_curves.sage
-	mv characteristic_curves.sage.py characteristic_curves.py
-
-rank_zero_case.py: rank_zero_case.ipynb
-	jupyter nbconvert --to script rank_zero_case.ipynb
-	mv rank_zero_case.py rank_zero_case.sage
-	sed -e "/get_ipython/d" -i rank_zero_case.sage
-	sage --preparse rank_zero_case.sage
-	mv rank_zero_case.sage.py rank_zero_case.py
-
-other_P_choice.py: other_P_choice.ipynb
-	jupyter nbconvert --to script other_P_choice.ipynb
-	mv other_P_choice.py other_P_choice.sage
-	sed -e "/get_ipython/d" -i other_P_choice.sage
-	sage --preparse other_P_choice.sage
-	mv other_P_choice.sage.py other_P_choice.py
+# PYTHON LIBS FROM NOTEBOOKS
+
+define NOTEBOOK_TO_LIB_RULE
+$(1).py: $(1).ipynb
+	jupyter nbconvert --to script $(1).ipynb
+	mv $(1).py $(1).sage
+	sed -e "/get_ipython/d" -i $(1).sage
+	sage --preparse $(1).sage
+	mv $(1).sage.py $(1).py
+endef
+
+$(foreach _base, $(NOTEBOOKBASENAMES), $(eval $(call NOTEBOOK_TO_LIB_RULE, $(_base))))
+
+notebook_py_libs: $(addsuffix .py, $(NOTEBOOKBASENAMES))	
+
+# MISCELANEOUS
 
 .PHONY: clean nosage noappendix
 clean: