# AUTOGENERATED FILE! PLEASE DON'T EDIT
"""
This is for quick modifiers, think of them as changing formats
"""
__all__ = ["apply", "applySingle", "lstrip", "rstrip", "strip",
"upper", "lower", "replace", "remove", "toFloat", "toInt", "sort"]
from typing import Callable, Iterator, Any
from k1lib.bioinfo.cli.init import patchDefaultDelim, BaseCli, settings
import k1lib.bioinfo.cli as cli
[docs]class apply(BaseCli):
[docs] def __init__(self, f:Callable[[str], str], column:int=None):
"""Applies a function f to every line
:param column: if not None, then applies the function to that column only"""
self.f = f; self.column = column
[docs] def __ror__(self, it:Iterator[str]):
f = self.f; c = self.column
if c is None: return (f(line) for line in it)
else: return (((e if i != c else f(e))
for i, e in enumerate(row)) for row in it)
[docs]class applySingle(BaseCli):
[docs] def __init__(self, f:Callable[[Any], Any]):
"""Like :class:`apply`, but much simpler, just operating on the entire input
object, essentially"""
self.f = f
[docs] def __ror__(self, it:Any) -> Any: return self.f(it)
[docs]def lstrip(column:int=None, char:str=None):
"""Strips left of every line"""
return apply(lambda e: e.lstrip(char), column)
[docs]def rstrip(column:int=None, char:str=None):
"""Strips right of every line"""
return apply(lambda e: e.rstrip(char), column)
[docs]def strip(column:int=None, char:str=None):
"""Strips both sides of every line"""
return apply(lambda e: e.strip(char), column)
[docs]def upper(column:int=None):
"""Make all characters uppercase"""
return apply(lambda e: e.upper(), column)
[docs]def lower(column:int=None):
"""Make all characters lowercase"""
return apply(lambda e: e.lower(), column)
[docs]def replace(s:str, target:str=None, column:int=None):
"""Replaces substring `s` with `target` for each line."""
t = patchDefaultDelim(target)
return apply(lambda e: e.replace(s, t), column)
[docs]def remove(s:str, column:int=None):
"""Removes a specific substring in each line."""
return replace(s, "", column)
[docs]def toFloat(column:int=None):
"""Converts every row into a float. Excludes non numbers if not in
:ref:`strict mode <bioinfoSettings>`."""
f = apply(lambda e: float(e), column)
return f if settings["strict"] else cli.isNumeric(column) | f
[docs]def toInt(column:int=None):
"""Converts every row into an integer. Excludes non numbers if not in
:ref:`strict mode <bioinfoSettings>`."""
f = apply(lambda e: int(float(e)), column)
return f if settings["strict"] else cli.isNumeric(column) | f
[docs]class sort(BaseCli):
[docs] def __init__(self, column:int=0, numeric=True, reverse=False):
"""Sorts all lines based on a specific `column`.
:param numeric: whether to treat column as float
:param reverse: False for smaller to bigger, True for bigger to smaller. Use
:meth:`__invert__` to quickly reverse the order instead of using this param"""
self.column = column; self.reverse = reverse; self.numeric = numeric
self.filterF = (lambda x: float(x)) if numeric else (lambda x: x)
[docs] def __ror__(self, it:Iterator[str]):
c = self.column; f = self.filterF
rows = list(it | cli.isNumeric(c) if self.numeric else it)
def sortF(row):
if len(row) > c: return f(row[c])
return float("inf")
return iter(sorted(rows, key=sortF, reverse=self.reverse))
[docs] def __invert__(self):
"""Creates a clone that has the opposite sort order"""
return sort(self.column, self.numeric, not self.reverse)