Package: slink
slinkGenerate sequencesTo install:pip install slinkHighlights>>>fromslink.sequencesimportIterativeDictProcessing>>>f=IterativeDictProcessing(...phase=lambdasession:session*10,...something_dependent=lambdasession,phase:session+phase,...something_independent=lambda:'hi'...)>>>f({'session':2}){'session':2,'phase':20,'something_dependent':22,'something_independent':'hi'}>>>fromslink.sequencesimportdict_generator>>>importitertools>>>counter=itertools.count()>>>f=dict_generator(dict(...x=7,# will be replaced with ReturnObj(y), an equivalent of lambda: 7..._1=Repeater(3),...y=lambda:next(counter),# will return 0, then 1, then 2,......z=lambdax,y:x*y),...1...)>>>list(f())[{'x':7,'y':0,'z':0},{'x':7,'y':1,'z':7},{'x':7,'y':2,'z':14}]ObjectiveThis package offers tools for generating sequences.
Finite ones like lists and arrays, or infinite ones like streams.The items of the sequences can be anything and often one sequence produced
will be used to produce another (see further design notes).
The target (i.e. final) sequence items would be samples of a signal
(like sound, image, or other data from some sensor source) or typical time-series.For starters, our main focus will be generating sound -- that is,
servicing thehumpackage.Our main tools will be taken fromcreekand possiblylinedDesignOur running examples will be taken from audio production.
We'll usewfto denote a waveform object (usually a list or array of numbers
-- a.k.a. samples or frames).To get a waveform, you specify someparams(including, say, the kind,
or the actual function that the params should be called with to produce
the result),
and you get a waveformwf.Thiswfcould be a fixed-size object like an array, or could be a source of
unbounded amounts of data,
like a generator, a stream object, a or acreek.InfiniteSeqwhich gives you
the array-like ability to slice (i.e.wf[i:j]).The purpose ofslinkis to provide tools to get from params to thiswf,
or what ever the target sequence maybe.
The main means of doing so is through a chain of sequences each one being a
function of the previous.
This function could do things like...a,b,c...->wf_for(a),wf_for(b),wf_for(c),...# generate elements of the next sequence based on the items of the lastwf_a,wf_b,wf_c...->add_noise(wf_a),add_noise(wf_b),add_noise(wf_c),...# transform the items of the last sequence->concatinate(wf_a_with_noise,...)# aggregate these items->chunk->wf_chk_1,wf_chk_2,...# split these itemsAll but the last sequence functions above were allmap(applying the same function to each element of the input sequence)reduce(aggregating all sequence items into one object -- though that object may be a sequence itself)But some functions can have more complex mechanisms such as inner-state and buffers.
This is important to note, since the developer may be tempted to accommodate for sequence functions that operate on a window instead of a single item.
But accommodating for this directly would complexify the interface.
Instead, we propose to use a mechanism likelined.BufferStatsto offer a window-input functionality with a single-item-at-a-time interface.Examples of sequence functionsFor categoricals: Use the__getitem__of a mapping that relates each element of a finite set of seeds to a waveform,
or parameters that will be used to produce the waveform:cat_map={'a':[1,2,3],'b':[4,5,6]}item_func_1=cat_map.__getitem__# to make the sequence function from this item func, you can do:fromlinedimportiterizeseq_func_1=iterize(item_func_1)Could also use finite mappings like above for numericals by first using a function that will map to a categoricalnum_to_cat=lambdanum:list(cat_map)[num%len(cat_map)]fromlinedimportiterize,Lineseq_func_2=iterize(Line(num_to_cat,item_func_1))Linecomposesnum_to_catanditem_func_1anditerizemakes the item-to-item function into a sequence-to-sequence function.