Package: expr
Create simple visualisations of mathematical operations onsmall datasetsby rendering anexpression graph, show your friends or serialise it for later.ContentsUsageStarting outLess verbosityInvolving pandasSerialisingKnown issuesAlsoUsageExamples follow using the Python interactive shellStarting outImport some things from the modulefromexprimportExpr,NumExprConstruct an expressionexpr=Expr(operation_name='+',arguments=[NumExpr(number=1),Expr(operation_name='/',arguments=[NumExpr(number=2),NumExpr(number=3),])])Get an answer>>expr.resolve()1.6666666666666665Draw a graph>>graph=expr.graph()>>graph.write_png('example.png')Trueexample.pngLess verbosityImport things usingasto save your typing fingers by aliasing those
characters away. In Python we don’t really need to care if functions specify
keyword or positional signatures, so let’s not bother with those wordy
keywords, hey.>>>fromexprimportExprasE,NumExprasN>>>expr=E('/',[N(22),N(7)])>>>expr.resolve()3.142857142857143>>>expr.graph().write_png('pi.png')Truepi.pngInvolving pandasWe can create expressions that involve more than just numbers …>>>importpandas>>>fromexprimport(...ExprasE,...NumExprasN,...DataFrameExprasD,...)Create some stupid datasets>>>deftwo_by_four():...data=[(n+1,n+1)forninrange(4)]...returnpandas.DataFrame.from_records(data=data,columns=['a','b'])>>>df_A=two_by_four()>>>df_B=two_by_four()>>>df_Aab011122233344Create the expression object, theDataFrameExprobject (aliased here
asD) takes an optional argumentnamewhich will be used as a label if
present, otherwise an automatically generated label will applied.>>>expr=E('*',[N(3),E('+',[D(df_A,'A'),D(df_B,'B')])])>>>expr.graph().write_png('dataframe.png')True>>>expr.resolve()01066112122181832424dataframe.pngSerialisingLet’s serialise the above example using JSON, any arguments passed to theserialisemethod are used when the serialiser function is applied.>>>importjson>>>print(expr.serialise(json.dumps,indent=4)){"__type__":"Expr","operation_name":"*","arguments":[{"__type__":"NumExpr","number":3.0},{"__type__":"Expr","operation_name":"+","arguments":[{"__type__":"DataFrameExpr","name":"A","dataframe":{"a":{"0":1,"1":2,"2":3,"3":4},"b":{"0":1,"1":2,"2":3,"3":4}}},{"__type__":"DataFrameExpr","name":"B","dataframe":{"a":{"0":1,"1":2,"2":3,"3":4},"b":{"0":1,"1":2,"2":3,"3":4}}}]}]}Getting funccyThe final expression provided in this package isFuncExpr, which applies
arbitrary functions to the arguments supplied (which should be objects
implementing aresolvemethod). Keywords are also applied, probably for
specifying options, which do not have to be expression objects.  A contrived
example ofFuncExpruse follows.Do some smart importsimportpandasfromexprimport(ExprasE,NumExprasN,DataFrameExprasD,FuncExprasF,)Define a factory function for creatingDataFrameobjectsdefx_by_y(x,y,columns=False):data=[[a+bforbinrange(x)]forainrange(y)]ifcolumnsisFalse:columns=[chr(97+c)forcinrange(x)]returnpandas.DataFrame.from_records(data=data,columns=columns)Crank out some df’s for later usedf_A=x_by_y(3,4)df_B=x_by_y(3,4)df_C=x_by_y(3,4)Now set up out expression and look at its graphexpr=E('+',[E('*',[N(3),F('pandas.concat',[D(x_by_y(1,4,['a'])),D(x_by_y(1,4,['b'])),D(x_by_y(1,4,['c'])),],axis=1)]),D(x_by_y(3,4))])G=expr.graph()G.write_png('func.png')func.pngCrazy ishWhy not very clumsily visualise a call stack for your audience’s pleasure?Known IssuesIf you like YAML, serialisingpandasobjects,maybeproblematic, but
JSON should be fine.AlsoColours courtesy ofclrs.cc