ターミナルからPython一行コードを入力・実行
数値計算・代数計算にとってSymPyは強力な助っ人
Pythonを立ち上げることなく、ターミナルから簡単にPythonコードを一行で入力・実行できるようにするシェルスクリプト
【更新】
20230908
・インストールするファイルを1つだけにした
・モードを9つにした
・出力を7つにした
・カラー表示にした
・複数行コード入力メニュー[2c]Codeを追加
【動作確認環境】
【macOS12.6.5】
Python 3.11.4
Bash、zsh
【Ubuntu22.04.2LTS】
Python 3.11.1
Bash
【必須Pythonライブラリ】
SymPyライブラリ
mpmathライブラリ
【インストール】
HOMEにディレクトリmyscript/pcをつくる
HOME/myscript/pcに
py.sh
を配置
MacOS .zshrcに以下を追記
source $HOME/myscript/pc/pc.sh
ubuntu .bashrcに以下を追記
alias open=xdg-open
source $HOME/myscript/pc/pc.sh
【Menu】
[1ENTER]One-Liner [2c]Code [3f]Frac [4p]mpf [5r]Rump [6m]man [7h]history [8s]SymPyWeb [9q]Quit >
に対して1文字(ENTERなし)入力
[1][ENTER]One-Liner no change (** & ^ OK)
[2][c]Code TAB OK Enter ## to Stop inputting
[3][f]Frac Auto Change 2/3 -> Fraction(“2/3”).limit_denominator()
[4][p]mpf mp(multiple-precision) mpf Real float Auto Change 3.14 -> mpf(“3.14”)
[5][r]rump verification of Rumps example
[6][m]man This manual page
[7][h]history show code history open \$PCDIR/pclist.txt
[8][s]SymPyWeb show SymPy Web Site
[9][q]quit quit pc
【OUTPUT】
[1]pprint(eq,use_unicode=False)
[2]pprint(eq,use_unicode=True)
[3]pprint(eval(eq))
[4]print(eval(eq))
[5]N(eq, precision)
[6]latex(eval(eq))
[7]latex(N(eq,precision))
シェルスクリプト pc.sh
#!/usr/bin/env bash
# pc(one liner Python Calculator)
# Python with SymPy & Shell Scripts
version='20230908'
# 設置ディレクトリ
PCDIR=HOME/myscript/pc
# コマンド pce
# pc.sh 編集
function pce(){
openPCDIR/pc.sh
}
# コマンド pcl
# 入力履歴表示
function pcl(){
open PCDIR/pclist.txt
}
# コマンド pcd
# SymPy Doc Web表示
function pcd(){
open 'https://docs.sympy.org/latest/tutorials/intro-tutorial/features.html'
}
# コマンド help
function help(){
cat << EOF
********** General Commands Manual ***************
NAME
pc - one liner Python Calculator
SYNTAX
pc
VERSION
This man page documents pc version{version}
DESCRIPTION
[Menu]
[1][ENTER]One-Liner no change (** & ^ OK)
[2][c]Code TAB OK Enter ## to Stop inputting
[3][f]Frac Auto Change 2/3 -> Fraction("2/3").limit_denominator()
[4][p]mpf mp(multiple-precision) mpf Real float Auto Change 3.14 -> mpf("3.14")
[5][r]rump verification of Rumps example
[6][m]man This manual page
[7][h]history show code history open \PCDIR/pclist.txt
[8][s]SymPyWeb show SymPy Web Site
[9][q]quit quit pc
[OUTPUT] just Frac mpf
[1]pprint(eq,use_unicode=False)
[2]pprint(eq,use_unicode=True)
[3]pprint(eval(eq))
[4]print(eval(eq))
[5]N(eq, precision)
[6]latex(eval(eq))
[7]latex(N(eq,precision))
[OUTPUT] exec
[0]exec('eq')
[EXPRESSION] All SymPy Code OK
─────────────────────────┬─────────────────────────────────────────────────────
Math │ Python&SymPy Code
─────────────────────────┼─────────────────────────────────────────────────────
quotient │ //
─────────────────────────┼─────────────────────────────────────────────────────
remainder │ %
─────────────────────────┼─────────────────────────────────────────────────────
quotient and remainder │ divmod()
─────────────────────────┼─────────────────────────────────────────────────────
fraction │ 2/3 Frac(2,3) Frac("2/3")
─────────────────────────┼─────────────────────────────────────────────────────
square root │ sqrt(2)
─────────────────────────┼─────────────────────────────────────────────────────
Pi │ pi
─────────────────────────┼─────────────────────────────────────────────────────
Napier Constant │ E
─────────────────────────┼─────────────────────────────────────────────────────
trigonometric function │ sin(pi/3)
│ sin(60*pi/180)
─────────────────────────┼─────────────────────────────────────────────────────
exponential function │ exp()
─────────────────────────┼─────────────────────────────────────────────────────
natural logarithm │ log(E**2)
─────────────────────────┼─────────────────────────────────────────────────────
common logarithm │ log(2,10) log(x, base)
─────────────────────────┼─────────────────────────────────────────────────────
imaginary unit │ (2+3j)*(5-7j)
─────────────────────────┼─────────────────────────────────────────────────────
imaginary unit(SymPy) │ exp(cos(E**I)+sin(E*pi))
│ I**I
─────────────────────────┼─────────────────────────────────────────────────────
prime factorization │ factorint(1000)
─────────────────────────┼─────────────────────────────────────────────────────
factorial │ factorial(10)
─────────────────────────┼─────────────────────────────────────────────────────
algebra symbolic variable│ from a to z
algebra symbolic function│ only f
─────────────────────────┼─────────────────────────────────────────────────────
expand │ expand((x+y)**10)
─────────────────────────┼─────────────────────────────────────────────────────
factor │ factor(a**10-b**10)
─────────────────────────┼─────────────────────────────────────────────────────
simplification │ simplify(1+x+x**2+x**3)
─────────────────────────┼─────────────────────────────────────────────────────
sequence │ sequence(k**2,(k,1,10))
│ sequence(k**2,(k,1,10))[9]
─────────────────────────┼─────────────────────────────────────────────────────
summation of a sequence │ Sum(k**2,(k,1,n)).doit()
─────────────────────────┼─────────────────────────────────────────────────────
product of a sequence │ product(k,(k,1,10))
─────────────────────────┼─────────────────────────────────────────────────────
equation │ solve(a*x**2+b*x+c,x)
│ solve(x**2-1,x)[0]
─────────────────────────┼─────────────────────────────────────────────────────
simultaneous equations │ solve([2/3*x-y-1,3/7*x-2*y-5/9],[x,y])
─────────────────────────┼─────────────────────────────────────────────────────
simultaneous equations │ solve([x+y-4,x-y-2],[x,y])
─────────────────────────┼─────────────────────────────────────────────────────
differential equation │ variable function f
│ dsolve(Eq(f(t).diff(t, t) - f(t), exp(t)), f(t))
─────────────────────────┼─────────────────────────────────────────────────────
differential │ diff(x**2,x)
─────────────────────────┼─────────────────────────────────────────────────────
indefinite integral │ integrate(x**3,x)
─────────────────────────┼─────────────────────────────────────────────────────
definite integral │ integrate(x**3,(x,0,1))
─────────────────────────┼─────────────────────────────────────────────────────
infinity │ oo │ integrate(1/(1+x**2), (x, -oo, oo))
─────────────────────────┼─────────────────────────────────────────────────────
limit │ limit(sin(x)/x, x, 0)
─────────────────────────┼─────────────────────────────────────────────────────
Taylor series │ series(sin(x),x, 0, 12)
─────────────────────────┼─────────────────────────────────────────────────────
Taylor series │ taylor(sin, 0, 5)
coefficient list │
─────────────────────────┼─────────────────────────────────────────────────────
substitution │ (x - x**3/6 + x**5/120 - x**7/5040).subs(x, 1)
─────────────────────────┼─────────────────────────────────────────────────────
matrix │ Matrix([[1, 2], [2, 2]]).det()
─────────────────────────┼─────────────────────────────────────────────────────
matrix │ Matrix([[1, 2], [2, 2]]).eigenvals()
─────────────────────────┼─────────────────────────────────────────────────────
matrix │ Matrix([[1, 2], [2, 2]]).eigenvects()
─────────────────────────┼─────────────────────────────────────────────────────
Seki-Bernoulli number │ bernoulli()
─────────────────────────┼─────────────────────────────────────────────────────
zeta function │ zeta()
│ zetazero()
─────────────────────────┼─────────────────────────────────────────────────────
Boolean-valued check │ 1+1 == 3 │ expand((x+y)**2) == x**2+2*x*y+y**2
─────────────────────────┼─────────────────────────────────────────────────────
plotting graphs │ plot(x**2, (x, -1, 2), ylabel = "y")
─────────────────────────┼─────────────────────────────────────────────────────
mpmath floating-point │ (-2)**mpf("0.5")
─────────────────────────┴─────────────────────────────────────────────────────
********** General Commands Manual ***************
EOF
}
# コマンド pc
# 本体
function pc(){
echo -e "\033[92mpcversion\033[0m"
echo 'Copyright 2023 sakurAi Science Factory, Inc.'
echo 'This is free software with ABSOLUTELY NO WARRANTY.'
unset eq
unset N
mode=''
while :
do
while :
do
echo -e '\033[36m[1ENTER]One-Liner [2c]Code [3f]Frac [4p]mpf [5r]Rump [6m]man [7h]history [8s]SymPyWeb [9q]Quit > \033[0m'
stty raw -echo
VAR=`dd bs=1 count=1 2>/dev/null`
stty -raw echo
case "VAR" in
'') mode="just" ; break ;;
1 ) mode="just" ; break ;;
2 ) mode="exec" ; break ;;
c ) mode="exec" ; break ;;
3 ) mode="frac" ; break ;;
f ) mode="frac" ; break ;;
4 ) mode="mpf" ; break ;;
p ) mode="mpf" ; break ;;
5 ) mode="rump" ; break ;;
r ) mode="rump" ; break ;;
6 ) help ; continue ;;
m ) help ; continue ;;
7 ) pcl ; continue ;;
h ) pcl ; continue ;;
8 ) pcd && continue ;;
s ) pcd && continue ;;
9 ) mode="quit" ; break ;;
q ) mode="quit" ; break ;;
* ) mode="just" ; break ;;
esac
done
echo -n "">PCDIR/pceq.txt
[ "mode" = "just" ] && echo -e "\033[92m[1]eq(one liner code) >\033[0m" && read eqq && echoeqq | sed -e 's%\^%**%g' > PCDIR/pceq.txt && eq=(<PCDIR/pceq.txt) && echo -e -n '\033[92m\nprecision[default:16]>\033[0m' && read N
[ "mode" = "exec" ] && echo -e '\033[92m[2]eq(Multiple Lines + ##) >\033[0m' && eqq="" && IFS='\n' &&
while :
do
read v
eqq+=v'\n'
if [ v = "##" ]; then
break
fi
done
echo -e "eqq" > PCDIR/pceq.txt
[ "mode" = "frac" ] && echo -e "\033[92m[3]eq(one liner code) >\033[0m" && read eqq && echo "eqq" >>PCDIR/pclist.txt && echo eqq | sed -e 's%[0-9]\+/[0-9]\+%Frac("&").limit_denominator()%g' -e 's%\^%**%g'>PCDIR/pceq.txt && eq=(<PCDIR/pceq.txt) && echo -e -n '\033[92m\nprecision[default:16] > \033[0m' && read N
[ "mode" = "mpf" ] && echo -e "\033[92m[4]eq(one liner code) >\033[0m" && read eqq && echoeqq | sed -e 's%[0-9]\+\.*[0-9]*%mpf("&")%g' -e 's%\^%**%g' > PCDIR/pceq.txt && eq=(<PCDIR/pceq.txt) && echo -e -n '\033[92m\nprecision[default:16]>\033[0m' && read N
[ "mode" = "rump" ] && echo -e '\033[92mRump'\''s example Test\033[0m' && eq="rump"
[ "mode" = "quit" ] && echo -e '\033[92mQuit pc\033[0m' && break
COMMAND=(cat << EOF
echo "eq" >>PCDIR/pclist.txt
echo -E "
from fractions import Fraction as Frac
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
init_printing() #降べきの順
# init_printing(order='rev-lex') #昇べきの順
var('a:z')
f = Function('f')
GRE='\033[92m'
RED='\033[91m'
VIO='\033[95m'
END='\033[0m'
mp.dps = {N:-16}
print(VIO+'\n[1]pprint(eq,use_unicode=False)'+END)
pprint(eq,use_unicode=False)
print(VIO+'\n[2]pprint(eq,use_unicode=True)'+END)
pprint(eq,use_unicode=True)
print(VIO+'\n[3]pprint(eval(eq), order="rev-lex")'+END)
pprint(eval('eq'), order='rev-lex')
print(VIO+'\n[4]print(eval(eq))'+END)
print(eval('eq'))
print(VIO+'\n[5]N(eq,{N:-16})'+END)
try:
N(eq,{N:- 16})
except AttributeError:
print(RED+'No Numerical Evaluation'+END)
else:
pprint(N(eq,{N:-16}))
print(VIO+'\n[6]latex(eval(eq))'+END)
try:
latex(eval('eq'))
except AttributeError:
print(RED+'No Output in LaTeX'+END)
else:
print(latex(eval('eq')))
print(VIO+'\n[7]latex(N(eq,{N}))'+END)
try:
latex(N(eq,{N:-16}))
except AttributeError:
print(RED+'No Output in LaTeX'+END)
else:
print(latex(N(eq,{N:-16})))
print('\n')
" | python
EOF
)
# モード毎
casemode in
just )
eval "{COMMAND}"
;;
exec )
echo "eqq" >> PCDIR/pclist.txt
echo -E "
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
from fractions import Fraction as Frac
init_printing()
#init_printing(order='rev-lex')
var('a:z')
f = Function('f')
GRE='\033[92m'
RED='\033[91m'
VIO='\033[95m'
END='\033[0m'
mp.dps ={N:- 16}
print(VIO+'\n[0]exec(eq)'+END)
f = open('PCDIR/pceq.txt')
cmd = f.read()
exec(cmd)
print('\n')
" | python
echo -n "">PCDIR/pceq.txt
;;
frac )
echo eq && echo -n -e '\033[92mexpression change? [n(ENTER)/y]\033[0m ' ; read yn
case "yn" in [Yy])
read eq ;;
[])
;;
[n])
;;
esac
eval echo "COMMAND"
;;
mpf )
echo eq && echo -n -e '\033[92mexpression change? [n(ENTER)/y]\033[0m ' ; read yn
case "yn" in [Yy])
read eq ;;
[])
;;
[n])
;;
esac
eval "{COMMAND}"
;;
rump )
echo -e -n '\033[92mprecision[default:16]>\033[0m'
read N
echo "eq" >> PCDIR/pclist.txt
echo -E "
from mpmath import *
mp.pretty = True
a=77617
b=33096
c=333.75*b**6+a**2*(11*a**2*b**2-b**6-121*b**4-2)+5.5*b**8+a/(2*b)
print(f'Normal {c}')
def g(a, b):
return (mpf('333.75')*b**6 + a**2*(11*a**2*b**2-b**6-121*b**4-2)+mpf('5.5')*b**8+a/(mpf('2')*b))
print('{:6}'.format('mp.dps'))
for mp.dps in range(1,N+1):
print('{:6}'.format(mp.dps),g(mpf('77617'), mpf('33096')))
print('')
" | python
esac
done
}