@@ -11,25 +11,60 @@ Inspired by https://github.com/matz/streem.
1111pip install syntax_sugar
1212```
1313
14- # Usage
15- This is the only line you need to use this lib.
16- ```
14+ # Use
15+
16+ To test out this lib, you can simply do.
17+
18+ ``` python
1719from syntax_sugar import *
1820```
1921
22+ For serious use, you can explicitly import each component as explained below ... if you dare to use this lib.
23+
2024### pipe
2125``` python
26+ from syntax_sugar import pipe, END
27+ from functools import partial
28+
29+ pipe(10 ) | range | partial(map , lambda x : x** 2 ) | list | print | END
2230# put 10 into the pipe and just let data flow.
23- pipe(10 ) | range | each(lambda x : x ** 2 ) | print
2431# output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
32+ # remember to call END at the end, so the pipe knows you want start the pipe
33+ # NOTE : everything in the middle of the pipe is just normal Python functions
34+
35+ pipe(10 ) | range | (map , lambda x : x** 2 ) | list | print | END
36+ # Tuples are shortcuts for partial functions
2537
26- # save the result to a var
27- x = pipe(10 ) | range | each(lambda x : x ** 2 ) | dump()
28- # remember to call dump at the end, so the pipe will know you want to dump the value
38+ from syntax_sugar import each
39+ x = pipe(10 ) | range | each(lambda x : x ** 2 ) | END
40+ # `each` is just a shortcut of the partial function of `map`
41+ # We can also save the result in a variable
2942
43+ pipe(10 ) | range | each(str ) | ' ' .join > ' test.txt'
3044# wanna write to a file? Why not!
31- pipe(10 ) | range | (map , str ) | concat > ' test.txt'
3245# write "0123456789" to test.txt
46+ # We don't need to put END here.
47+ ```
48+
49+ We can connect multiple pipes to create a longer pipe
50+
51+ ``` python
52+ from syntax_sugar import pipe, each, END
53+ from functools import reduce
54+
55+ p1 = pipe(10 ) | range | each(lambda x : x/ 2 )
56+ # head pipe can have input value
57+ p2 = pipe() | (reduce , lambda acc , x : (acc + x)/ 2 )
58+ p3 = pipe() | int | range | sum
59+ # middle pipes can have no input value
60+
61+ p1 | p2 | p3 | END
62+ # returns 6
63+
64+ # you can also put a different value in the pipe
65+ p = p1 | p2 | p3
66+ p(20 )
67+ # returns 36
3368```
3469
3570### pipe with thread/process and multiprocessing
@@ -39,28 +74,29 @@ You can have a function running in a seperate thread with pipe. Just put it in a
3974Because of the notorious GIL(Global Interpret Lock) of Python, people may want processes instead of threads. Just put a function in ` p[] ` .
4075
4176``` python
42- pipe(10 ) | [print ] # print run in a thread
43- pipe(10 ) | t[print ] # print run in a thread
44- pipe(10 ) | p[print ] # print run in a process
77+ from syntax_sugar import thread_syntax as t, process_syntax as p
78+
79+ pipe(10 ) | [print ] | END # print run in a thread
80+ pipe(10 ) | t[print ] | END # print run in a thread
81+ pipe(10 ) | p[print ] | END # print run in a process
4582```
4683
4784What makes this syntax good is that you can specify how many threads you want to spawn, by doing ` [function] * n ` where ` n ` is the number of threads.
4885
4986``` python
50- pipe([1 ,2 ,3 ,4 ,5 ]) | [print ] * 3 # print will run in a ThreadPool of size 3
87+ pipe([1 ,2 ,3 ,4 ,5 ]) | [print ] * 3 | END # print will run in a ThreadPool of size 3
5188```
5289
5390Here is an example of requesting a list of urls in parallel
5491
5592``` python
5693import requests
57- (
58- pipe([' google' , ' twitter' , ' yahoo' , ' facebook' , ' github' ])
94+ (pipe([' google' , ' twitter' , ' yahoo' , ' facebook' , ' github' ])
5995 | each(lambda name : ' http://' + name + ' .com' )
6096 | [requests.get] * 3 # !! `requests.get` runs in a ThreadPool of size 3
6197 | each(lambda resp : (resp.url, resp.headers.get(' Server' )))
62- | dump()
63- )
98+ | list
99+ | END )
64100
65101# returns
66102# [('http://www.google.com/', 'gws'),
@@ -72,9 +108,14 @@ pipe(['google', 'twitter', 'yahoo', 'facebook', 'github'])
72108
73109### infix function
74110``` python
111+ from syntax_sugar import is_a, hasattr , to, by, drop
112+
751131 / is_a/ int
76114# equivalent to `isinstance(1, int)`
77115
116+ range (10 ) / hasattr / ' __iter__'
117+ # equivalent to `hasattr(range(10), "__iter__")`
118+
781191 / to/ 10
79120# An iterator similar to `range(1, 11)`.
80121# Python's nasty range() is right-exclusive. This is right-inclusive.
@@ -93,9 +134,9 @@ pipe(['google', 'twitter', 'yahoo', 'facebook', 'github'])
93134# Go backward.
94135# Similar to `range(10, 0, -2)`
95136
96- ' A ' / to/ ' Z ' / by / 3
97- # Also works with characters with /by/.
98- # An iterator similar to 'ADGJMPSVY'
137+ 1 / to/ 10 / drop / 5
138+ # there is a `drop` functon which drop N items from the head
139+ # An iterator similar to [6, 7, 8, 9, 10]
99140```
100141
101142` /to/ ` has some advanced features
@@ -106,34 +147,34 @@ pipe(['google', 'twitter', 'yahoo', 'facebook', 'github'])
106147- support pipe.
107148
108149``` python
150+ from syntax_sugar import INF , NEGINF , take, each
151+
109152# CAUTION: this will infinitely print numbers
110153for i in 1 / to/ INF :
111154 print (i)
112155
113- print (1 / to/ INF / take/ 5 )
156+ list (1 / to/ INF / take/ 5 )
114157# there is a `take` functon which is similar to itertools.islice
115158# return [1, 2, 3, 4, 5]
116159
117- print (0 / to/ NEGINF / by/ 2 / take/ 5 )
160+ list (0 / to/ NEGINF / by/ 2 / take/ 5 )
118161# also works with negative infinity.
119162# return [0, -2, -4, -6, -8]
120163
121- print (1 / to/ 10 / drop/ 5 )
122- # there is a `drop` functon which drop N items from the head
123- # return [6, 7, 8, 9, 10]
124-
125- # print all combinations of [1..3] * [4..6]
126- print ([(x, y) for x, y in (1 / to/ 3 ) * (4 / to/ 6 )])
164+ list ((1 / to/ 3 ) * (4 / to/ 6 ))
165+ # all combinations of [1..3] * [4..6]
127166# return [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
128167
129- # Now, these infix functions can also be piped
130- 1 / to / 10 / take / 5 | each( lambda x : x ** 2 ) | print
168+ 1 / to / 10 / take / 5 | each( lambda x : x ** 2 ) | list | END
169+ # These infix functions can also be piped.
131170# [1, 4, 9, 16, 25]
132171```
133172
134173Make your own infix function, so you can append multiple items to a list in one line.
135174
136175``` python
176+ from syntax_sugar import infix
177+
137178@infix
138179def push (lst , x ):
139180 lst.append(x)
@@ -143,78 +184,4 @@ def push(lst, x):
143184# returns [1,2,3]
144185```
145186
146- ### lazy pipe
147-
148- Because our ` pipe ` is quite hard working, it doesn't work well with the lazy ` /to/ ` function.
149-
150- ` lazy_pipe ` works in a "one-by-one" manner. It puts only 1 item into the pipe at each time.
151-
152- ``` python
153- lazy_pipe(1 / to/ INF ) | print | when(lambda x : x < 10 )
154- # this prints 1 to 9
155-
156- lazy_pipe(input ) | (lambda s : s.upper())| print | when(lambda x : x != " " )
157- # lazy_pipe also accepts a function as input. The function is called each time as long as the `when` condition holds.
158- # this changes anything you input to uppercases.
159- ```
160-
161- TODO: support multiprocessing with lazy pipe
162-
163- ### composable function
164-
165- In math, ` (f * g) (x) = f(g(x)) ` . This is called function composition.
166-
167- ``` python
168- # this transfer a map object to list
169- lmap = compose(list , map )
170- # lmap equivalent to `list(map(...))`
171- lmap(lambda x : x ** 2 , range (10 ))
172- ```
173-
174- Let's say we want to represent ` f * g * h ` in a program, i.e. ` fn(x) = f(g(h(x))) `
175-
176- ``` python
177- f = lambda x : x** 2 + 1
178- g = lambda x : 2 * x - 1
179- h = lambda x : - 2 * x** 3 + 3
180-
181- fn = compose(f, g, h)
182-
183- fn(5 ) # 245026
184- ```
185-
186- or you can do
187-
188- ``` python
189- f = composable(lambda x : x** 2 + 1 )
190- g = composable(lambda x : 2 * x - 1 )
191- h = composable(lambda x : - 2 * x** 3 + 3 )
192-
193- fn = f * g * h
194-
195- fn(5 ) # 245026
196- ```
197-
198- Some times you may prefer the decorator way.
199-
200- ``` python
201- # make your own composable functions
202- @composable
203- def add2 (x ):
204- return x + 2
205-
206- @composable
207- def mul3 (x ):
208- return x * 3
209-
210- @composable
211- def pow2 (x ):
212- return x ** 2
213-
214- fn = add2 * mul3 * pow2
215- # equivalent to `add2(mul3(pow2(n)))`
216- fn(5 )
217- # returns 5^2 * 3 + 2 = 77
218- ```
219-
220- more receipes: https://github.com/czheo/syntax_sugar_python/tree/master/recipes
187+ More receipes: https://github.com/czheo/syntax_sugar_python/tree/master/recipes
0 commit comments