Package: sidis
sidis:simpledatainterfacesis a Python module that aims to reduce common programming tasks to a single line of code, such as typecasting and data conversion, sorting and mapping, accessing and assigning values through loops,etc. The name is a tribute to the early American polymath, William James Sidis. Documentation can be found on the respective pages in the docs website athttps://noeloikeau.github.io/sidis/. Here we give a brief overview of some of the main utilities.Installpip install sidisHow to useimportsidisfromsidisimport*TypecastingSidis supports extensible typecasting between iterables and non-iterables, letting you do intuitive conversions such as:cast(0,list)[0]cast([0.9,1.1],int)[0, 1]or define your own rules:mycast=Caster()mycast[list][float]=lambdat:sum(t)mycast([0.9,1.1],float)2.0Sorting and converting complex datastructuresSidis lets you sort python objects by the result of maps over those objects, and provides convenient conversion functions.fromsidisimportsort,convertConvert the elements of a list to binary arrays, and sort by the length of the array:sort([0,10,3,5],by=convert,key=lambdat:len(t[-1]))[(10, [1, 0, 1, 0]), (5, [1, 0, 1]), (3, [1, 1]), (0, [0])]By default,convertconverts to a binary array. If we want to change the arguments of the map without yet evaluating it, we can usepipe:fromsidisimportpipe#like functools.partial, but also allows for typecasting of input and output dataNow let's convert to hex:sort([0.9,10.5,3.1,5.5],by=pipe(convert,to=hex,otype=int))#convert the elements `otype` into integers, then hex[(10.5, '0xa'), (5.5, '0x5'), (3.1, '0x3'), (0.9, '0x0')]Arbitrary access to data structuresWe can access and change arbitrary datastructures withgetandgive:a=[1]get(a,0)#get 0th level or attribute of a1[give(a,0,a[0]+1)foriinrange(10)]#and can assign arbitrary objects without writing entire loops!a[11]and can apply this level of control to more complex datastructures:importnetworkxasnxg=nx.DiGraph()#create a ring with a loop, 0->1->2->0->0g.add_edges_from([(0,1),(1,2),(2,0)])g.add_edges_from([(0,0)])g.in_degree()InDegreeView({0: 2, 1: 1, 2: 1})fromsidisimportgetget(g,'in_degree',0)#get in-degree of node 02and use this to sort with more abstract methods:sort(g.nodes,by=g.in_degree)[(0, 2), (1, 1), (2, 1)]sort(g.nodes,by=g.edges,key=lambdat:len(list(t[-1])))[(0, OutEdgeDataView([(0, 1), (0, 0)])),
 (1, OutEdgeDataView([(1, 2)])),
 (2, OutEdgeDataView([(2, 0)]))]or even give attributes to objects:fromsidisimportgivegive(g,'nodes',0,newattr='for fun')g.nodes[0]['newattr']'for fun'[give(g,'edges',e,weight=np.random.rand(1))foreing.edges]sort(g.edges,'weight')[array([0.99698538]),
 array([0.90294296]),
 array([0.47634498]),
 array([0.1643804])]Arbitrary mappingsidis also extends mapping usingmaps, which lets you pass in an object and a series of functions and evaluate those functions independently or sequentially over the input to the desired depth:f1=lambdat:tf2=lambdat:t+1f3=lambdat:t+2maps(0,f1,f2,f3)#apply them individually[0, 1, 2]maps(0,f1,f2,f3,depth=-1)#apply them sequentially3maps([0,1],f1,f2,f3,depth=1)#apply f1 to 0, then return f2(f1(0)) and f2(f1(0)), then repeat for 1[[1, 2], [2, 3]]... and more!fromsidisimportdepth,flatten,unflatten,fill,Template,RNGdepth([[0]])2depth({'a':0,'b':{'c':1,'d':3}})2flatten({'a':0,'b':{'c':1,'d':3}}){'a': 0, 'b,c': 1, 'b,d': 3}unflatten({'a':0,'b,c':1,'b,d':3}){'a': 0, 'b': {'c': 1, 'd': 3}}fill([[1],[2,3]],fillwith=1000,mask=False)array([[   1, 1000],
       [   2,    3]])Template('''fill out your _nameand provide{0}ZIP _iter, lambda t: 'embedded iterable functions!'''',_name='name and information',_iter=range(1))fill out your name and information
and provide embedded iterable functions!rng=RNG(0)#globally stablerng.random(0,1,shape=(2,2))array([[0.63696169, 0.26978671],
       [0.04097352, 0.01652764]])