# AUTOGENERATED FILE! PLEASE DON'T EDIT
"""
This is for quick modifiers, think of them as changing formats
"""
__all__ = ["lstrip", "rstrip", "strip", "apply",
"upper", "lower", "replace", "remove", "sort"]
from typing import Callable, Iterator
from k1lib.bioinfo.cli.init import patchDefaultDelim, BaseCli
[docs]class lstrip(BaseCli):
"""Strips left of every line"""
def __init__(self, char:str=None): self.char = char
[docs] def __ror__(self, it:Iterator[str]):
if self.char != None:
for line in it: yield line.lstrip(char)
else:
for line in it: yield line.lstrip()
[docs]class rstrip(BaseCli):
"Strips right of every line"
def __init__(self, char:str=None): self.char = char
[docs] def __ror__(self, it:Iterator[str]):
if self.char != None:
for line in it: yield line.rstrip(char)
else:
for line in it: yield line.rstrip()
[docs]class strip(BaseCli):
"""Strips both sides of every line"""
def __init__(self, char:str=None): self.char = char
[docs] def __ror__(self, it:Iterator[str]):
if self.char != None:
for line in it: yield line.strip(char)
else:
for line in it: yield line.strip()
[docs]class apply(BaseCli):
[docs] def __init__(self, f:Callable[[str], str]):
"""Applies a function f to every line"""
self.f = f
[docs] def __ror__(self, it:Iterator[str]):
for line in it: yield self.f(line)
[docs]class upper(BaseCli):
"""Make all characters uppercase"""
[docs] def __ror__(self, it:Iterator[str]):
for line in it: yield line.upper()
[docs]class lower(BaseCli):
"""Make all characters lowercase"""
[docs] def __ror__(self, it:Iterator[str]):
for line in it: yield line.lower()
[docs]class replace(BaseCli):
[docs] def __init__(self, s:str, target:str=None):
"""Replaces substring `s` with `target` for each line"""
self.s = s; self.target = patchDefaultDelim(target)
[docs] def __ror__(self, it:Iterator[str]):
for line in it: yield line.replace(self.s, self.target)
[docs]class remove(replace):
[docs] def __init__(self, s:str):
"""Removes a specific substring in each line"""
super().__init__(s, "")
from k1lib.bioinfo.cli.filt import isNumeric
[docs]class sort(BaseCli):
[docs] def __init__(self, column:int=0, reverse=False, numeric=True, delim:str=None):
"""Sorts all lines based on a specific `column`.
:param reverse: False for smaller to bigger, True for bigger to smaller
:param numeric: whether to treat column as float
:param delim: delimiter that separates columns"""
self.column = column; self.reverse = reverse; self.numeric = numeric
self.filterF = (lambda x: float(x)) if numeric else (lambda x: x)
self.delim = patchDefaultDelim(delim)
[docs] def __ror__(self, it:Iterator[str]):
if self.numeric: it = it | isNumeric(self.column, self.delim)
elems = list(it)
def sortF(line):
elems = line.split(self.delim)
if len(elems) > self.column:
return self.filterF(elems[self.column])
return float("inf")
elems = sorted(elems, key=sortF)
if self.reverse: elems.reverse()
return iter(elems)
[docs] def __invert__(self):
"""Creates a clone that has the opposite sort order"""
return sort(self.column, not self.reverse, self.numeric, self.delim)