oopman / rightshift Goto Github PK
View Code? Open in Web Editor NEWRightShift is a Python package for writing chained operations in a readable fashion.
License: MIT License
RightShift is a Python package for writing chained operations in a readable fashion.
License: MIT License
Example:
# Current syntax
f = attr.lower
f(data)() == data.lower()
f = attr.join
f(['1','2'])('#') == '1#2'
# Proposed syntax
f = attr.lower >> call
f(data) == data.lower()
f = attr.join >> call('#')
f(['1','2']) == '1#2'
item['x'] works
item['x']['y'] works
item['x']['y']['z] fails
attr.x works
attr.x.y works
attr.x.y.z fails
The reasons for this is that the result of the two-item form a Chain instance rather than an ItemExtractor/AttrExtractor instance.
This can probably be solved by returning a custom Chain instance...
Currently rightshift.matchers
does not have a good way of handling matching on objects that contain other objects.
In order to improve on this we should implement item_is
and attr_is
. These matchers will combine the functionality of the value_is
matcher with the value extraction functionality of the item
and attr
extractors found in rightshift.extractors
Currently
(A & B) & (X & Y) is equivalent to A & B & X & Y
This is not correct. Could probably be solved with a variant operator eg: &= or ^ or something.
It would be useful if normal python values could be mixed in to tupling and detupling expressions. This could be done by wrapping them in a special Value transform. Values can be created by implementing rand and ror on the base Transformer class.
Similarly, it would be useful if the Tupling class could understand normal Python tuples and use them as Tupling instances.
It should be possible to using the indexing and slicing operators on chains to extract transformers or new chains
RIght now various Transformers accept flags and have default values for these flags.
It would be useful if there was a way to change the default value of a given flag.
It's time to ditch old versions of Python
It would be nice if RightShift were usable in the real world, maybe through some compile mode which converts the chains into more basic code.
It would be neat if certain Chain transforms that group multiple other transforms together were able to optionally execute the wrapped transforms in an async fashion.
For example, Tupling and Detupling, as well as maybe Must, Should and MustNot.
See:
Transformer instances should accept allow usage of the =>
operator in the following form as a means of calling the transformer with an input:
f = a >> b
o = "test" >= f
The Identity module is probably too basic to be considered an Extractor.
Currently rrshift, rand and ror are used in the code to implement the basic behaviour of RightShift.
rshift, and and or should be used rather as it will reduce the complexity of the code, as well as obviating the need for mountains of anonymous classes.
item[100] | item[0] | item[5] >> identity() produces a Detupling instance.
(item[100] | item[0] | item[5]) >> identity() produces a Chain instance.
If I don't start TDDing this thing now, it will never happen!
The breakers module will be more useful if it supports general behaviour like:
f = item['x'] >> provided(value_is >= 5).then(identity).otherwise(operand *= 5)
The matchers module will provide Transforms that determine whether the value they are called with matches a given condition, returning True or False in either scenario.
Beyond this, these Transforms will also implement different boolean behaviour for the & and | operators.
Finally, these Transforms should also transform TransformerExceptions to False values.
Transformers that should be added include:
This list draws on the methods available to Seq descendants in Scala
Currently break_if
and break_if_not
need to be instantiated with a single matcher. This limits their flexibility. Altering them to accept any Transformer will enable much richer behaviour.
Breakers are a Transform that raise a TransformerException in order to terminate processing of the Transform chain.
They are used to implement break-out behaviour for chains.
The render function should be called with a chain and produces a string representation of the flow of that chain
The way Flags are currently used doesn't make a whole lot of sense.
The general style with RightShift is x >> y >> z
indicating pass output from x as input to y, pass output from y as input to z.
However, the above with a Flag applied looks like x >> y >> z >> flags(blah=True)
The way this behaves, however, is such that the arguments supplied to flags are made available as kwargs when to the x, y and z functions when they are called.
This is somewhat at odds with the manner in which RightShift functions. It would probably be better if flags the example looked like flags(blah=True) >> x >> y >> z
RightShift will be more useful if it is able to perform operations.
For example, the augmented arithmetic operations:
f = item['x'] >> add(5)
f = item['x'] >> (operand *= 5)
The rightshift.extractors
module should implement an additional Extractor named Obj
which combines the functionality of the Item
and Attr
Extractors in order to provide an Extractor that behaves as per standard Python object access principles.
Additionally, a Matcher hybrid version will need to be added to the rightshift.matchers
.
Currently these extractors fail to work correctly if the attribute being referenced exists on the extractor itself. E.g. __class__
and so forth.
This should be fixable by use __getattribute__
rather than __getattr__
, although there will be some complexity involved due to the sneaky tricks used by the item, attr and obj extractors.
The rightshift.breakers
module should extend the Comparisons found in rightshift.matchers
in order to implement Comparisons that automatically are wrapped within Breakers.
Additions:
break_if(x & y)
to be equivalent to break_if(x) & break_if(y)
rightshift.matchers
in order to allow for common use-cases to be simplified.The default Transform should function as per the following example:
f = item[0] >> default(None)
f([]) == None
f([1] == 1
In order to match this requirement the default Transform will probably need to implement a custom Chain class which intercepts any TransformerExceptions and returns the default value in their place.
The current code is not written with any kind of performance in mind. As such, it's probably a little bit heavy and could do with some paring down. In particular, the chains implementation could probably be improved.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.