IPython Notebook, Take 2
by Willie Wong
With the help of Fernando Perez, some aspects of my IPython Notebook code has been improved.
Changelog:
- Instead of using
.show()and.fullshow()methods to display the content of the objects with dependence on a global toggle for MathJax, now we use the_repr_latex_method (which hooks into IPython’s display functionality). This allows one to enter justm = math_expr([insert atoms here])followed bymto display the content of the math expression. - Whether the default display mentioned above shows the atom number labels is now configured via a boolean: one can play with it using the
.labeledproperty - To show the LaTeX code, we now use the
.latexproperty - Operations are no longer in place. Instead they return a new
math_exprobject. This has the advantage that if you can keep playing with the entry until you get it right, and then afterwords you can dom = m.replace(...). This makes it better for for interactive computations. - By default, on object creation it will print its own content.
The code now looks like
from IPython.core.display import *
def add(x,y): return x+y
def MDPL(string): display(Math(string))
def comp_str(listofstrings): return reduce(add,listofstrings)
class math_expr(object):
'''''Math Expression object'''''
def __init__(self,atomslist, labeldefault = True, highlight = []):
'''''init takes arg: list of atoms, each atom being a compilable chunck of LaTeX expression'''''
self.listofatoms = atomslist
self.labels = labeldefault
MDPL(comp_str(self.__colouratoms(highlight)))
def _repr_latex_(self):
'''''Returns a latex expression of the object. Will be parsed by MathJax'''''
self.__labelatoms()
latexstring = comp_str(self.labeledatoms) if self.labels else comp_str(self.listofatoms)
return "$" + latexstring + "$"
@property
def labeled(self):
'''''Tells you whether labelling is turned on by default'''''
return self.labels
@labeled.setter
def label(self,boolean):
'''''Sets the default labelling'''''
self.labels = boolean
@property
def latex(self):
'''''Accesses the LaTeX code snip for the expression'''''
display(Latex(comp_str(self.listofatoms)))
def __labelatoms(self):
'''''Label atoms by adding underbraces'''''
self.labeledatoms = [ "\underbrace{" + self.listofatoms[i] + "}_{" + str(i) + "}" for i in range(len(self.listofatoms)) ]
def replace(self,pos,newstr):
'''''Replaces an atom with another atom'''''
MDPL(comp_str(self.__colouratoms([pos])))
newstrings = list(self.listofatoms)
newstrings[pos] = newstr
return math_expr(newstrings,self.labels,[pos])
def merge(self,positions):
'''''Merges atoms: the input is a list of positions. The new atom is placed at the position of the foremost of the positions'''''
MDPL(comp_str(self.__colouratoms(positions)))
newstrings = list(self.listofatoms)
temp = [ newstrings[i] for i in positions ]
positions.sort()
positions.reverse()
for i in positions: del newstrings[i]
newstrings.insert(positions[-1],comp_str(temp))
return math_expr(newstrings,self.labels,[positions[-1]])
def split(self,pos,newatoms):
'''''Splits atoms: replaces an atom in place with multiple sub atoms'''''
MDPL(comp_str(self.__colouratoms([pos])))
newstrings = list(self.listofatoms)
del newstrings[pos]
templen = len(newatoms)
while len(newatoms) > 0:
newstrings.insert(pos,newatoms.pop())
return math_expr(newstrings,self.labels,range(pos,pos+templen))
def cancel(self,positions):
'''''Cancels a bunch of terms: input a list of positions'''''
MDPL(comp_str(self.__colouratoms(positions)))
positions.sort()
positions.reverse()
newstrings = list(self.listofatoms)
for i in positions: del newstrings[i]
return math_expr(newstrings,self.labels)
def move(self,posini,posfin):
'''''Move atom at posini to posfin, pushing all others back'''''
MDPL(comp_str(self.__colouratoms([posini])))
newstrings = list(self.listofatoms)
temp = newstrings.pop(posini)
newstrings.insert(posfin if posfin < posini else posfin-1, temp)
return math_expr(newstrings,self.labels,[posfin if posfin < posini else posfin - 1])
def __colouratoms(self,positions,labelled=False):
'''''Returns the list of atoms, but with selected terms coloured'''''
temp = list(self.listofatoms)
if labelled:
self.labelatoms()
temp = list(self.labeledatoms)
for i in positions: temp[i] = "\color{red}{"+temp[i]+"}"
return temp
[…] (Edit July 27: please see this update) […]
This is great.
Any chance you could upload or link to some notebook files to give some examples of this magic in action?
Ta!
Hi John, WordPress.com does not allow uploads of notebook files, so instead I pasted a demonstration notebook at pastebin.ca http://pastebin.ca/2466537 You’ll need to download the paste and save as filename.ipynb and then it should be able to be loaded.
[…] little bit of a shameless plug: I wrote some code sometime ago for helping with algebraic computations using IPython Notebook. There is no built-in […]