Skip to main content

Infix piping operator

Project description

Ipo

Infix piping operator for Python. Iterator-native decluttering of your code.

Demo

from ipo import list, str, write, sort, take

# Chaining without adding data yet. And this ipo will be useful for the later examples, too. Bam!
print_as_list = list | str | write  # No output yet


# Ipo makes data flows much easier to follow.
[5, 2, 3, 1, 4] | sort           | print_as_list  # [1, 2, 3, 4, 5]
[5, 2, 3, 1, 4] | take(3)        | print_as_list  # [5, 2, 3]
[5, 2, 3, 1, 4] | sort | take(3) | print_as_list  # [1, 2, 3]
[5, 2, 3, 1, 4] | take(3) | sort | print_as_list  # [2, 3, 5]

# Much more readable than the original!
#   sort(itertools.islice([5, 2, 3, 1, 4], 3))
from ipo import from_csv, skip, starmap, to_csv, before, write

# Ipo is ideally suited for working with CSV data.
"""
#Voltage,Current
12,1
8,2
220,6
""".strip().split() | from_csv | skip(1) | \
	starmap(lambda v, a: (v, a, float(v) * float(a))) | \
	to_csv | before(["#Voltage,Current,Power"]) | write
# #Voltage,Current,Power
# 12,1,12.0
# 8,2,16.0
# 220,6,1320.0
from ipo import read, map, write

# Most ipo chains that work over iterable data are lazy by default. You can load huge files,
# process them and write the results to another file.
with open("bigfile.txt") as f_in, open("processed.txt") as f_out:
	read(file=f_in) | map(some_preprocessing) | \
	map(some_advanced_function) | \
	map(some_formatting) | write(file=f_out)
import math

# Don't confuse the module and the function.
# You can do `import ipo` and then use `ipo.ipo()`, or you can do...
from ipo import ipo
# ...and then use `ipo()`.

# Ipo-ify any function where it makes sense to pass the first argument by pipe.
# Functions that work with iterables make a great fit, but any function will work.

# Call ipo as a function...
sqrt = ipo(math.sqrt)

# ...or use it as a decorator.
@ipo
def double(x):
	return 2 * x

# More arguments are supported.
@ipo
def times(x, y):
	return x * y

9 | double | times(2) | sqrt  # 6.0

# Psst: times(2) is actually the same as double! Now that times exists, we could also define it as
double = times(2)

Troubleshooting

  • “I'm experimenting with ipo in Python's interactive mode (REPL), but I get ipo(<function ipo.__or__.<locals>.<lambda> at ...>).”

Make sure that the first object in your pipe chain is not an ipo object. It should be data.

  • TypeError: unsupported operand type(s) for |: '...' and '...' and other weird errors

Make sure the rightmost element is an ipo object. If you want to use one of ipo objects that ship in this module, make sure you imported it.

Ipo's magic | works by overriding __ror__ and __or__. Make sure the data does not override the __or__ function, because that would mess with the order of precedence.

To nail down the expression that is causing errors, you can break up your pipe, insert a pipe to ipo.list and assign to a variable. If you have huge amounts of data or expensive computations in your chain, try limiting the flow with take(n).

foo = stdin | take(500) | map(random_function) | list
foo | write

Inspiration

Inspired by but not based on

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ipo-0.0.2.tar.gz (21.8 kB view hashes)

Uploaded Source

Built Distribution

ipo-0.0.2-py3-none-any.whl (20.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page