Add "py", a CLI for python one-liners
This commit is contained in:
54
.mgr_config/bin/py
Normal file
54
.mgr_config/bin/py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
source = " ".join(sys.argv[1:])
|
||||
INPUT_SRC_NAME = "<py-input>"
|
||||
|
||||
global_vars = {}
|
||||
local_vars = {}
|
||||
|
||||
py_env_conf = Path.home() / ".py-env.py"
|
||||
if py_env_conf.exists():
|
||||
with open(Path.home() / ".py-env.py") as f:
|
||||
code = compile(f.read(), "py-env.py", "exec")
|
||||
exec(code)
|
||||
|
||||
try:
|
||||
code = compile(source, INPUT_SRC_NAME, "eval")
|
||||
val = eval(code)
|
||||
|
||||
# If it's a string, just print it
|
||||
if type(val) == str:
|
||||
print(val)
|
||||
exit(0)
|
||||
|
||||
# If it's not iterable, just print it
|
||||
try:
|
||||
it = iter(val)
|
||||
except TypeError as e:
|
||||
if val is not None:
|
||||
print(val)
|
||||
exit(0)
|
||||
|
||||
# It's iterable, print each element as a line
|
||||
try:
|
||||
for item in val:
|
||||
print(item)
|
||||
exit(0)
|
||||
except Exception as e:
|
||||
e.args = ("Failed to print all elements",) + e.args
|
||||
raise
|
||||
|
||||
except (SyntaxError, NameError) as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
code = compile(source, INPUT_SRC_NAME, "exec")
|
||||
exec(code)
|
||||
except (SyntaxError, NameError) as e:
|
||||
e.args = ("Invalid Python code",) + e.args
|
||||
raise e
|
||||
76
.py-env.py
Normal file
76
.py-env.py
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
import itertools
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
from functools import partial, reduce
|
||||
from math import *
|
||||
from pathlib import Path
|
||||
from itertools import chain
|
||||
|
||||
try:
|
||||
from tabulate import tabulate
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import rich
|
||||
from rich import inspect, print as pp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# Always write heavyweight/blocking code in this file lazily to keep startup
|
||||
# time short. In the same vein, be careful not to consume stdin unless an object
|
||||
# in this file is called or iterated upon, e.g. stdin_str()
|
||||
|
||||
# Returns a lazily-evaluable map which executes multiple map functions
|
||||
def maps(items, *map_funs):
|
||||
it = items
|
||||
for func in map_funs:
|
||||
it = map(func, it)
|
||||
return it
|
||||
|
||||
|
||||
# Returns a lazily-evaluable filter which executes multiple predicate functions
|
||||
def filters(items, *pred_funs):
|
||||
it = items
|
||||
for pred in pred_funs:
|
||||
it = filter(pred, it)
|
||||
return it
|
||||
|
||||
|
||||
# Concatenate two items, there's likely a safer way to do this to avoid summing ints
|
||||
concat = lambda a, b: "".join([a, b])
|
||||
# Joins an interable of strings
|
||||
join = "".join
|
||||
|
||||
|
||||
# Return an iterable for file. This doesn't close the handle, but for this
|
||||
# little scripting interface this is fine.
|
||||
def read(filename):
|
||||
return open(filename, "r")
|
||||
|
||||
|
||||
def read_str(filename):
|
||||
return concats(read(filename))
|
||||
|
||||
|
||||
stdin_str = sys.stdin.read
|
||||
# An iterable which yields the characters of stdin
|
||||
stdin = (c for l in sys.stdin for c in l)
|
||||
# An iterable which yields the lines of stdin
|
||||
lines = map(str.strip, sys.stdin)
|
||||
# An iterable which yields integers supplied via stdin lines
|
||||
ints = map(int, lines)
|
||||
# An iterable which yields the bytes of stdin
|
||||
byts = map(lambda x: bytes(x, "utf-8"), stdin) # better name? 'bytes' is taken
|
||||
|
||||
jr = json.loads
|
||||
jw = json.dumps
|
||||
yr = lambda x: yaml.load(x, Loader=yaml.SafeLoader)
|
||||
yw = yaml.dump
|
||||
pwd = Path.cwd()
|
||||
Reference in New Issue
Block a user