pc [One Line Python(SymPy) Code Calculator]

ターミナル立ち上げてすぐに数式を入力できる

数値計算・代数計算にとって強力な助っ人SymPyをもっと簡単に
Pythonは素晴らしい言語です
SymPyライブラリは数学の強力助っ人

でも使うためにはいくつものお膳立てが必要

ターミナルにコマンドpcを打ち込むだけでPython一行コードを即入力・即出力を可能にします

Pythonを立ち上げる必要なし
Pythonのコーディングも必要なし
SymPyライブラリのインポートはじめお膳立ても必要なし
シェルスクリプトは1つpc.shだけだから設置が容易

3ステップで高度な数学計算ができる
1.ターミナルを立ち上げる
2.コマンドpcを打ち込む
3.数式 expand((x+y+z)**3)を入力

スクリーンショット 2024-06-26 23.30.36.

【更新】

20240626
・マニュアルを拡充
SymPyに加え-math — 数学関数-を追加

・オプションに
[math]Open Math module Web
を追加
python標準モジュールmath
math module Doc Web表示

20230908
・インストールするファイルを1つだけにした
・モードを9つにした
・出力を7つにした
・カラー表示にした
・複数行コード入力メニュー[2c]Codeを追加

【動作確認環境】

【macOS14.5】
M3Mac
Python 3.11.9
zsh

【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
を配置

もし設置するディレクトリを変更する場合
変数PCDIRを変更

# pc.sh
# pc.shの設置ディレクトリ
PCDIR=$HOME/myscript/pc

MacOS .zshrcに以下を追記

# .zshrc
source $HOME/myscript/pc/pc.sh

ubuntu .bashrcに以下を追記

# .bashrc
alias open=xdg-open
source $HOME/myscript/pc/pc.sh

【OPTION】

[n] set precision n digits (default:16 digits)
[c] Enter multiple Code TAB OK Press ‘##’ to Stop inputting
[f] 2/3 -> Fraction(“2/3”).limit_denominator()
[mpf] 3.14 -> mpf(“3.14”) mp(multiple-precision)f(Real float)
[r] verify Rumps example
[m] less manual This manual page Press ‘q’ to stop
[M] open manual
[h] open history open $PCDIR/pchistory.txt
[s] open SymPy Web Site
[math] Open Math module Web
[qq] 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 Line Python(SymPy) Code Calculator --

pcversion='20240626'

# Select Color Set
# Terminal Back Color : Black (Font Color : White)
blue='\033[94m';violet='\033[95m';green='\033[92m';mizu='\033[96m';red='\033[91m';yellow='\033[93m'

# Terminal Back Color : White (Font Color : Black)
# blue='\033[1;30m';violet='\033[1;30m';green='\033[1;30m';mizu='\033[1;30m'

# pc.shの設置ディレクトリ
PCDIR=$HOME/myscript/pc

# コマンド pce
# pc.sh 編集
function pce(){
open $PCDIR/pc.sh
}

# コマンド pcl
# 入力履歴表示
function pcl(){
open $PCDIR/pchistory.txt
}

# コマンド pcd
# SymPy Doc Web表示
function pcd(){
open 'https://docs.sympy.org/latest/tutorials/intro-tutorial/features.html'
}

# コマンド pcmath
# math module Doc Web表示
function pcmath(){
open 'https://docs.python.org/ja/3/library/math.html'
}


# コマンド help
function helppc(){
echo -e "$helptxt" | less -R -X
}

# コマンド helpe Manual外部エディターに表示
function helpe(){
echo -e "$helptxt" | sed -e 's%[[]9[2-6]m%%g' -e 's%[[]1;30m%%g' -e 's%[[]0m%%g' -e 's%[[]m%%g'>$PCDIR/help.txt
open $PCDIR/help.txt
}


# Manual TEXT
helptxt=$(cat << EOF
General Commands Manual
NAME
   pc -  One Line Python(SymPy) Code Calculator

SYNTAX
   pc

VERSION
   This man page documents pc version ${pcversion}

Copyright 2023 sakurAi Science Factory, Inc.
This is free software with ABSOLUTELY NO WARRANTY.

Recommended Terminal Font
Ubuntu Mono

DESCRIPTION
Enter One Line Code > \$eq [n]16digits [c][f][mpf][r][m][M][h][s][qq]
One Line Python(SymPy) Code
you can use '^' instead of '**'

IMPORT LIBRARY・MODULE
import math
from fractions import Fraction as Frac
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
from spb import *  # SymPy Plotting Backends (SPB)
import japanize_matplotlib
import matplotlib.pyplot as plt

init_printing() #降べきの順
# init_printing(order='rev-lex') #昇べきの順
var('a:z')
f = Function('f')



OPTION
[n] set precision n digits (default:16 digits)
[c] Enter multiple Code     TAB OK  Press '##' to Stop inputting
[f] 2/3 -> Fraction("2/3").limit_denominator()
[mpf] 3.14 -> mpf("3.14")  mp(multiple-precision)f(Real float)
[r] verify Rumps example
[m] less manual  This manual page   Press 'q' to stop
[M] open manual
[h] open history   open \$PCDIR/pchistory.txt
[s] open SymPy Web Site
[math] Open Math module Web
[qq] quit pc

OUTPUT  One Line Python(SymPy) Code [f]Frac [mpf]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  [c]multiple Code
[8]exec('eq')

[EXPRESSION] All SymPy Code OK
${blue}────────────────────────────────────────────────────────────────────
${violet}Math\033[0m
SymPy Code
${green}OUTPUT\033[0m


${mizu}-BASIC-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}algebra symbolic variable\033[0m
from a to z

${blue}────────────────────────────────────────────────────────────────────
${violet}algebra symbolic function\033[0m
default only f
x, y = symbols('x y', positive=True)
a, b = symbols('a b', real=True)

${blue}────────────────────────────────────────────────────────────────────
${violet}Natural Representation\033[0m
print(expand((x+y)**2))
${green}x**2 + 2*x*y + y**2\033[0m

pprint(expand((x+y)**2))
${green} 2            2
${green}x  + 2⋅x⋅y + y \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}substitution\033[0m
(x^2+x+1).subs(x, 1)
${green}3\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}quotient\033[0m
13 // 5
${green}2\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}remainder\033[0m
13 % 5
${green}3\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}quotient and remainder\033[0m
divmod(25, 3)
${green}(8, 1)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}fraction\033[0m
2/3
${green}0.6666666666666666\033[m

Frac(2,3)
${green}2/3\033[m

Frac("2/3")
${green}6004799503160661/9007199254740992\033[m

Frac("2/3").limit_denominator()
${green}2/3\033[m

[c]Code
pprint(Frac("2/3")+Frac("1/7"))
${green}17
${green}──
${green}21\033[m

[f]Frac
2/3+1/7
${green}17
${green}──
${green}21\033[0m


${mizu}-NUMBER-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}Pi\033[0m
pi
${green}3.141592653589793 (default 16digits)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Napier Constant\033[0m
E
${green}2.718281828459045 (default 16digits)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}imaginary unit\033[0m
(2+3j)*(5-7j)
${green}(31+1j)
${green}31.0 + 1.0⋅ⅈ\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}imaginary unit(SymPy)\033[0m
exp(cos(E**I)+sin(E*pi))
${green}    ⎛ ⅈ⎞           
${green} cos⎝ℯ ⎠ + sin(ℯ⋅π)
${green}ℯ                  

${green}6.237024243670621 - 3.292937458733587⋅ⅈ\033[0m

I**I
${green} ⅈ
${green}ⅈ 

${green}0.2078795763507619\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Degree\033[0m
mp.degree
${green}0.0174532925199433\033[0m

pi/180
${green}0.01745329251994330\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Golden Ratio\033[0m
phi
${green}1.618033988749895\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Euler's constant Gamma\033[0m
mp.euler
${green}0.5772156649015329\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Catalan’s constant\033[0m
mp.catalan
${green}0.915965594177219\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Khinchin’s constant\033[0m
mp.khinchin
${green}2.685452001065306\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Glaisher’s constant\033[0m
mp.glaisher
${green}1.282427129100623\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Mertens constant\033[0m
mp.mertens
${green}0.2614972128476428\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Twin prime constant\033[0m
mp.twinprime
${green}0.6601618158468696\033[0m


${mizu}-FUNCTION-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}square root\033[0m
sqrt(2)
${green}1.414213562373095 (default 16digits)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}LCM (Least Common Multiple)\033[0m
lcm(120, 99)
${green}3960\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}GCD (Greatest Common Divisor)\033[0m
gcd(12, 18)
${green}6\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}trigonometry\033[0m
sin(pi/3)
${green}  ___
${green}\/ 3 
${green}-----
${green} 2  \033[0m

sin(radians(60))
${green}0.8660254037844387\033[0m

degrees(pi/3).evalf()
${green}60.0000000000000\033[0m

asin()
sinh()
asinh()

${blue}────────────────────────────────────────────────────────────────────
${violet}exponential\033[0m
exp(1)
${green}e
${green}ℯ
${green}E
${green}2.718281828459045\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}natural logarithm\033[0m
log(E**2)
${green}2\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}common lagarithm\033[0m
log(2,10)  log(x, base)
${green}log(2)/log(10)
${green}0.3010299956639812\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}gamma function\033[0m
gamma(4)
${green}6\033[0m
gamma(sqrt(2))
${green}0.8865814287192591\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}binomial\033[0m
binomial(5,2)
${green}10\033[0m
binomial(n,3)
${green}⎛n⎞
${green}⎜ ⎟
${green}⎝3⎠\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}permutation\033[0m
math.perm(5,2)
${green}20\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}combination\033[0m
math.comb(5,2)
${green}10\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}absolute value\033[0m
abs(-3)
${green}3\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}prime factorization\033[0m
factorint(60)
${green}{2: 2, 3: 1, 5: 1}\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}factorial\033[0m
factorial(10)
${green}3628800\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}KroneckerDelta\033[0m
KroneckerDelta(1, 2)
${green}0\033[0m

KroneckerDelta(i, j)
${green}δ   
${green} i,j\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}besseli\033[0m
besselj(n, z).diff(z)
${green}besselj(n - 1, z)   besselj(n + 1, z)
${green}───────────────── - ─────────────────
${green}        2                   2        \033[0m

besselj(n, z).rewrite(jn)
${green}√2⋅√z⋅jn(n - 1/2, z)
${green}────────────────────
${green}         √π         \033[0m


${mizu}-SIMPILIFICATION-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}simplify\033[0m
simplify(cos(x)**2+sin(x)**2)
${green}1\033[0m

(x**2 + 2*x + 1)/(x**2 + x)
${green} 2          
${green}x  + 2⋅x + 1
${green}────────────
${green}    2       
${green}   x  + x \033[0m

simplify((x**2 + 2*x + 1)/(x**2 + x))
${green}x + 1
${green}─────
${green}  x \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand\033[0m
expand((x+y+z)**3)
${green} 3      2        2          2                  2    3      2          2    3
${green}x  + 3⋅x ⋅y + 3⋅x ⋅z + 3⋅x⋅y  + 6⋅x⋅y⋅z + 3⋅x⋅z  + y  + 3⋅y ⋅z + 3⋅y⋅z  + z \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}factor\033[0m
factor(a^8-b^8)
${green}                ⎛ 2    2⎞ ⎛ 4    4⎞
${green}(a - b)⋅(a + b)⋅⎝a  + b ⎠⋅⎝a  + b ⎠\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}collec\033[0m
x*y^2+3*x^3*y+5*x*y-7*x^3*y^2
${green}     3  2      3        2        
${green}- 7⋅x ⋅y  + 3⋅x ⋅y + x⋅y  + 5⋅x⋅y\033[0m

collect(x*y^2+3*x^3*y+5*x*y-7*x^3*y^2, x)
${green} 3 ⎛     2      ⎞     ⎛ 2      ⎞
${green}x ⋅⎝- 7⋅y  + 3⋅y⎠ + x⋅⎝y  + 5⋅y⎠\033[0m

collect(x*y^2+3*x^3*y+5*x*y-7*x^3*y^2, y)
${green} 2 ⎛     3    ⎞     ⎛   3      ⎞
${green}y ⋅⎝- 7⋅x  + x⎠ + y⋅⎝3⋅x  + 5⋅x⎠\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}cancel\033[0m
(x**2 + 2*x + 1)/(x**2 + x)
${green} 2          
${green}x  + 2⋅x + 1
${green}────────────
${green}    2       
${green}   x  + x   \033[0m

cancel((x**2 + 2*x + 1)/(x**2 + x))
${green}x + 1
${green}─────
${green}  x \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}apart\033[0m
1/((x-1)*(x+1))
${green}       1       
${green}───────────────
${green}(x - 1)⋅(x + 1)\033[0m

apart(1/((x-1)*(x+1)))
${green}      1           1    
${green}- ───────── + ─────────
${green}  2⋅(x + 1)   2⋅(x - 1)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}separatevars\033[0m
(x*y)**y
${green}     y
${green}(x⋅y) \033[0m

separatevars((x*y)**y, force=True)
${green} y  y
${green}x ⋅y \033[0m

x*y*z*sin(x)*cos(x)+x^2*y*z^3*cos(x)
${green} 2    3                             
${green}x ⋅y⋅z ⋅cos(x) + x⋅y⋅z⋅sin(x)⋅cos(x)\033[0m

separatevars(x*y*z*sin(x)*cos(x)+x^2*y*z^3*cos(x))
${green}      ⎛            2⎞       
${green}x⋅y⋅z⋅⎝sin(x) + x⋅z ⎠⋅cos(x)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}ratsimp\033[0m
reduce fractions to a common denominator

ratsimp(1/x + 1/y)
${green}x + y
${green}─────
${green} x⋅y \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}radsimp\033[0m
Rationalize the denominator by removing square roots

1/(1 + sqrt(2) + sqrt(3) + sqrt(5))
${green}       1        
${green}────────────────
${green}1 + √2 + √3 + √5\033[0m

radsimp(1/(1 + sqrt(2) + sqrt(3) + sqrt(5)))
${green}-34⋅√10 - 26⋅√15 - 55⋅√3 - 61⋅√2 + 14⋅√30 + 93 + 46⋅√6 + 53⋅√5
${green}──────────────────────────────────────────────────────────────
${green}                              71                              \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand_trig\033[0m
expand_trig(sin(x + y))
${green}sin(x)⋅cos(y) + sin(y)⋅cos(x)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}trigsimp\033[0m
trigsimp(sin(x)*cos(y) + sin(y)*cos(x))
${green}sin(x + y)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand_log\033[0m
expand_log(log(x*y), force=True)
${green}log(x) + log(y)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}logcombine\033[0m
logcombine(log(x) + log(y), force=True)
${green}log(x⋅y)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}powsimp\033[0m
x**a*x**b
${green} a  b
${green}x ⋅x \033[0m

powsimp(x**a*x**b)
${green} a + b
${green}x     \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand_power_exp\033[0m
3**(y + 2)
${green} y + 2
${green}3     \033[0m

expand_power_exp(3**(y + 2))
${green}   y
${green}9⋅3 \033[0m

pprint(expand_power_exp(Symbol('x', zero=False)**(y + 2)))
${green} 2  y
${green}x ⋅x \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand_power_base\033[0m
(x*y)**z
${green}     z
${green}(x⋅y) \033[0m

expand_power_base((x*y)**z, force=True)
${green} z  z
${green}x ⋅y \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}powdenest\033[0m
(x**a)**b
${green}    b
${green}⎛ a⎞ 
${green}⎝x ⎠ \033[0m

powdenest((x**a)**b, force=True)
${green} a⋅b
${green}x   \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}expand_func\033[0m
expand_func(gamma(x+3))
${green}x⋅(x + 1)⋅(x + 2)⋅Γ(x)\033[0m

expand_func(binomial(n,3))
${green}n⋅(n - 2)⋅(n - 1)
${green}─────────────────
${green}        6        \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}FUNCsimp\033[0m
gammasimp(gamma(x)*gamma(1-x))
${green}   π    
${green}────────
${green}sin(π⋅x)c

combsimp(binomial(n+2,k)/binomial(n,k))
${green}    (n + 1)⋅(n + 2)    
${green}───────────────────────
${green}(k - n - 2)⋅(k - n - 1)\033[0m

kroneckersimp( 1+KroneckerDelta(0, j) * KroneckerDelta(1, j))
${green}1\033[0m

besselsimp(z*besseli(0, z) + z*(besseli(2, z))/2 + besseli(1, z))
${green}3⋅z⋅besseli(0, z)
${green}─────────────────
${green}        2        \033[0m

hypersimp(factorial(n)**2 / factorial(2*n), n)
${green}   n + 1   
${green}───────────
${green}2⋅(2⋅n + 1)\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}.rewrite\033[0m
tan(x).rewrite(sin)
${green}     2   
${green}2⋅sin (x)
${green}─────────
${green} sin(2⋅x)\033[0m

(cos(x)).rewrite(sin)
${green}   ⎛    π⎞
${green}sin⎜x + ─⎟
${green}   ⎝    2⎠\033[0m

factorial(x).rewrite(gamma)
${green}Γ(x + 1)\033[0m


${mizu}-SEQUENCE-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}sequence\033[0m
sequence(k**2,(k,1,10))
${green}[1, 4, 9, 16, …]\033[0m

sequence(k**2,(k,1,10))[9]
${green}100\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}summation of a sequence\033[0m
Sum(k**2,(k,1,n))
${green}  n     
${green} ___    
${green} ╲      
${green}  ╲    2
${green}  ╱   k 
${green} ╱      
${green} ‾‾‾    
${green}k = 1  \033[0m

Sum(k**2,(k,1,n)).doit()
${green} 3    2    
${green}n    n    n
${green}── + ── + ─
${green}3    2    6\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}product of a sequence\033[0m
Product(k,(k,1,10))
${green}  10   
${green}─┬─┬─  
${green} │ │  k
${green} │ │   
${green}k = 1  \033[0m

product(k,(k,1,10))
${green}3628800\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Seki-Bernoulli number\033[0m
bernoulli(1)
${green}1/2\033[0m

bernoulli(2)
${green}1/6\033[0m


${mizu}-EQUATION-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}Eq\033[0m
Eq(x^3, x^2-1)
${green} 3    2    
${green}x  = x  - 1\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}solve\033[0m
solve(x^2+x+4)
${green}⎡  1   √15⋅ⅈ    1   √15⋅ⅈ⎤
${green}⎢- ─ - ─────, - ─ + ─────⎥
${green}⎣  2     2      2     2  ⎦\033[0m

solve(a*x**2+b*x+c, x)
${green}⎡        _____________          _____________⎤
${green}⎢       ╱           2          ╱           2 ⎥
${green}⎢-b - ╲╱  -4⋅a⋅c + b    -b + ╲╱  -4⋅a⋅c + b  ⎥
${green}⎢─────────────────────, ─────────────────────⎥
${green}⎣         2⋅a                    2⋅a         ⎦\033[0m

solve(x**2-1,x)[0]
${green}-1\033[0m

[f]Frac
solve([2/3*x-y-1,3/7*x-2*y-5/9],[x,y])
${green}⎧   91      11⎫
${green}⎨x: ──, y: ───⎬
${green}⎩   57     171⎭\033[0m

solve([x+y-4,x-y-2],[x,y])
${green}{x: 3, y: 1}\033[0m

list(solve([x+y-4,x-y-2]).items())[0]
${green}(x, 3)\033[0m

list(solve([x+y-4,x-y-2],[x,y]).items())[0][1]
${green}3\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}dsolve\033[0m
variable function f
Eq(Derivative(f(t),t,2)-f(t),exp(t))
${green}  2                  
${green} d                  t
${green}───(f(t)) - f(t) = ℯ 
${green}  2                  
${green}dt                   \033[0m

dsolve(Eq(f(t).diff(t, 2) - f(t), exp(t)), f(t))
${green}           -t   ⎛     t⎞  t
${green}f(t) = C₂⋅ℯ   + ⎜C₁ + ─⎟⋅ℯ 
${green}                ⎝     2⎠   \033[0m

dsolve(Eq(f(t).diff(t, 2) - f(t), exp(t)), f(t), ics={f(0):1, f(t).diff(t,1).subs(t, 0):1})
${green}                     -t
${green}       ⎛t   3⎞  t   ℯ  
${green}f(t) = ⎜─ + ─⎟⋅ℯ  + ───
${green}       ⎝2   4⎠       4 \033[0m


${mizu}-CALCULUS-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}differential\033[0m
diff(x^3+x^2+x+1)
${green}   2          
${green}3⋅x  + 2⋅x + 1\033[0m

diff(sin(x),x,3)
${green}-cos(x)\033[0m

Derivative(exp(x**2),x,3)
${green}  3⎛ ⎛ 2⎞⎞
${green} d ⎜ ⎝x ⎠⎟
${green}───⎝ℯ    ⎠
${green}  3       
${green}dx        \033[0m

Derivative(exp(x**2),x,3).doit()
${green}                ⎛ 2⎞
${green}    ⎛   2    ⎞  ⎝x ⎠
${green}4⋅x⋅⎝2⋅x  + 3⎠⋅ℯ    \033[0m

[c]Code
f = Function('f')
g = Function('g')
eq = (f(x) * g(x)).diff(x)
pprint(eq)
${green}     d               d       
${green}f(x)⋅──(g(x)) + g(x)⋅──(f(x))
${green}     dx              dx      \033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}indefinite integral\033[0m
integrate(3*x^2+2*x+1)
${green} 3    2    
${green}x  + x  + x\033[0m

[f]Frac
Integral(3*x^2+2*x-2/3)
${green}⌠                    
${green}⎮ ⎛   2         2⎞   
${green}⎮ ⎜3⋅x  + 2⋅x - ─⎟ dx
${green}⎮ ⎝             3⎠   
${green}⌡                    \033[0m

[f]Frac
Integral(3*x^2+2*x-2/3).doit()
${green} 3    2   2⋅x
${green}x  + x  - ───
${green}           3 \033[0m

${violet}definite integral\033[0m
integrate(x**3,(x,0,1))
${green}1/4\033[0m

[f]Frac
Integral(2/3*x^5, (x, 0, 2/3))
${green}2/3        
${green} ⌠         
${green} ⎮     5   
${green} ⎮  2⋅x    
${green} ⎮  ──── dx
${green} ⎮   3     
${green} ⌡         
${green} 0         \033[0m

[f]Frac
Integral(2/3*x^5, (x, 0, 2/3)).doit()
${green} 64 
${green}────
${green}6561\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}Taylor series\033[0m
series(sin(x),x, 0, 12)
${green}     3     5     7       9        11            
${green}    x     x     x       x        x         ⎛ 12⎞
${green}x - ── + ─── - ──── + ────── - ──────── + O⎝x  ⎠
${green}    6    120   5040   362880   39916800         \033[0m

${violet}Taylor series coefficient list\033[0m
taylor(sin, 0, 5)
${green}[0.0, 1.0, 0.0, -0.1666666666666667, 0.0, 0.008333333333333333]\033[0m

series(sin(x),x, 0, 12).removeO()
${green}     3     5     7       9        11   
${green}    x     x     x       x        x     
${green}x - ── + ─── - ──── + ────── - ────────
${green}    6    120   5040   362880   39916800\033[0m

series(sin(x),x, 0, 12).removeO().subs(x,1)
${green}0.8414709846480680\033[0m


${mizu}-INFINITY-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}infinity\033[0m
oo
${green}∞\033[0m

Integral(1/(1+x**2), (x, -oo, oo))
${green}∞           
${green}⌠           
${green}⎮    1      
${green}⎮  ────── dx
${green}⎮   2       
${green}⎮  x  + 1   
${green}⌡           
${green}-∞          \033[0m

Integral(1/(1+x**2), (x, -oo, oo)).doit()
${green}π\033[0m

integrate(1/(1+x**2), (x, -oo, oo))
${green}π\033[0m


${mizu}-LIMIT-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}limit\033[0m
limit(sin(x)/x, x, 0)
${green}1\033[0m

Limit((x^2+x-1)/(2*x^2-x+2), x, oo)
${green}    ⎛  2         ⎞
${green}    ⎜ x  + x - 1 ⎟
${green}lim ⎜────────────⎟
${green}x─→∞⎜   2        ⎟
${green}    ⎝2⋅x  - x + 2⎠\033[0m

Limit((x^2+x-1)/(2*x^2-x+2), x, oo).doit()
${green}1/2\033[0m

limit((x^2+x-1)/(2*x^2-x+2), x, oo)
${green}1/2\033[0m

limit(tan(x), x, pi/2, '+')
${green}-∞\033[0m

limit(tan(x), x, pi/2, '-')
${green}∞\033[0m


${mizu}-MATRIX-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}Matrix\033[0m
Matrix([[1, 2], [2, 2]])
${green}⎡1  2⎤
${green}⎢    ⎥
${green}⎣2  2⎦\033[0m

Matrix([[1, 2], [2, 2]])**2
${green}⎡5  6⎤
${green}⎢    ⎥
${green}⎣6  8⎦\033[0m

eye(3)
${green}⎡1  0  0⎤
${green}⎢       ⎥
${green}⎢0  1  0⎥
${green}⎢       ⎥
${green}⎣0  0  1⎦\033[0m

zeros(3)
${green}⎡0  0  0⎤
${green}⎢       ⎥
${green}⎢0  0  0⎥
${green}⎢       ⎥
${green}⎣0  0  0⎦\033[0m

ones(3)
${green}⎡1  1  1⎤
${green}⎢       ⎥
${green}⎢1  1  1⎥
${green}⎢       ⎥
${green}⎣1  1  1⎦\033[0m

diag(1, 2, 3)
${green}⎡1  0  0⎤
${green}⎢       ⎥
${green}⎢0  2  0⎥
${green}⎢       ⎥
${green}⎣0  0  3⎦\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.det()\033[0m
Matrix([[1, 2], [2, 2]]).det()
${green}-2\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.inv()\033[0m
Matrix([[1, 2], [2, 2]]).inv()
${green}⎡-1   1  ⎤
${green}⎢        ⎥
${green}⎣1   -1/2⎦\033[0m

Matrix([[1, 2], [2, 2]])**(-1)
${green}⎡-1   1  ⎤
${green}⎢        ⎥
${green}⎣1   -1/2⎦\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.adjugate()\033[0m
Matrix([[1, 2], [3, 4]]).adjugate()
${green}⎡4   -2⎤
${green}⎢      ⎥
${green}⎣-3  1 ⎦\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.transpose()\033[0m
Matrix([[1, 2], [3, 4]]).transpose()
${green}⎡1  3⎤
${green}⎢    ⎥
${green}⎣2  4⎦\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.rank()\033[0m
Matrix([[1, 2, 3], [4, 5, 0], [0, 0, 0]]).rank()
${green}2\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.eigenvals()\033[0m
Matrix([[1, 2], [2, 2]]).eigenvals()
${green}⎧3   √17     3   √17   ⎫
${green}⎨─ - ───: 1, ─ + ───: 1⎬
${green}⎩2    2      2    2    ⎭\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}A.eigenvects()\033[0m
Matrix([[1, 2], [2, 2]]).eigenvects()
${green}⎡⎛            ⎡⎡  √17   1⎤⎤⎞  ⎛            ⎡⎡  1   √17⎤⎤⎞⎤
${green}⎢⎜3   √17     ⎢⎢- ─── - ─⎥⎥⎟  ⎜3   √17     ⎢⎢- ─ + ───⎥⎥⎟⎥
${green}⎢⎜─ - ───, 1, ⎢⎢   4    4⎥⎥⎟, ⎜─ + ───, 1, ⎢⎢  4    4 ⎥⎥⎟⎥
${green}⎢⎜2    2      ⎢⎢         ⎥⎥⎟  ⎜2    2      ⎢⎢         ⎥⎥⎟⎥
${green}⎣⎝            ⎣⎣    1    ⎦⎦⎠  ⎝            ⎣⎣    1    ⎦⎦⎠⎦\033[0m


${mizu}-ZETA-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}zeta\033[0m
zeta(2)
${green} 2
${green}π 
${green}──
${green}6 \033[0m

zeta(-1)
${green}-1/12\033[0m

${blue}────────────────────────────────────────────────────────────────────
${violet}zetazero\033[0m
zetazero(1)
${green}(0.5 + 14.13472514173469j)\033[0m


${mizu}-Boolean-valued check-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}==\033[0m
1+1 == 3
${green}False\033[0m

expand((x+y)**2) == x**2+2*x*y+y**2
${green}True\033[0m


${mizu}-mpmath floating-point-\033[0m
${blue}────────────────────────────────────────────────────────────────────
(-2)**mpf("0.5")
${green}(0.0 + 1.4142135623730950488016887242096980785696718753769j)\033[0m


${mizu}-PLOT-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}from spb import *  # SymPy Plotting Backends (SPB)\033[0m
${violet}import japanize_matplotlib\033[0m
${violet}import matplotlib.pyplot as plt\033[0m

plot(sin(x), (x, 0, 7), ylabel = "y")

graphics(line(sin(x)),axis_center="auto", grid=False)

p1 = plot_list([2], [4],
legend=True,
is_point = True,
line_color = "red",
show = False)
p2 = plot(x**2, (x, 0, 3),
line_color = "blue",
show = False)
(p1+p2).show()

f1 = x
f2 = x**2
f3 = sin(x)
plot((f1,"1次関数"), (f2, "2次関数"),(f3,"三角関数"),
(x, 0, 4),
rendering_kw=[{"color":"red"},{"color":"blue"},{"color":"green"}],
backend=MB,  # Choromeブラウザー出力
title = "backend=MB (MatplotlibBackend)",
axis_center="auto",
grid=True,
xlabel = "x",
ylabel = "y")

f1 = x
f2 = x**2
f3 = sin(x)
plot((f1,"1次関数"), (f2, "2次関数"),(f3,"三角関数"),
(x, -2, 2),
backend=BB,  # Choromeブラウザー出力
title = "backend=BB (BokehBackend)",
xlabel = "x",
ylabel = "y")

f1 = x
f2 = x**2
f3 = sin(x)
plot((f1,"1次関数"), (f2, "2次関数"),(f3,"三角関数"),
(x, -2, 2),
backend=PB,  # Choromeブラウザー出力
title = "backend=PB (PlotyBackend)",
xlabel = "x",
ylabel = "y")

p = plot(sin(x), (x, -pi, pi), ylabel="sin x", axis_center="auto",backend=MB, show=False)
ax = p.ax
ax.set_xlabel("x:時間", loc="right")
ax.set_ylabel("y:長さ", loc="top", rotation=0,labelpad=-30)
plt.legend()
plt.show()

plot_parametric(2 * cos(u) + 5 * cos(2 * u / 3),
2 * sin(u) - 5 * sin(2 * u / 3),
(u, 0, 6 * pi), 
aspect='equal')


${mizu}-math -- 数学関数-\033[0m
${blue}────────────────────────────────────────────────────────────────────
${violet}math.ceil(x)\033[0m
${violet}math.comb(n, k)\033[0m
${violet}math.copysign(x, y)\033[0m
x の大きさ (絶対値) で y と同じ符号の浮動小数点数を返します。
${violet}math.fabs(x)\033[0m
${violet}math.factorial(n)\033[0m
${violet}math.floor(x)\033[0m
${violet}math.fmod(x, y)\033[0m
一般には浮動小数点の場合には関数 fmod() 、整数の場合には x % y を使う方がよい
${violet}math.frexp(x)\033[0m
x の仮数と指数を (m, e) のペアとして返します
${violet}math.fsum(iterable)\033[0m
${violet}math.gcd(*integers)\033[0m
${violet}math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)\033[0m
値 a と b が互いに近い場合 True を、そうでない場合は False を返します。
${violet}math.isfinite(x)\033[0m
${violet}math.isinf(x)\033[0m
${violet}math.isnan(x)\033[0m
${violet}math.lcm(*integers)\033[0m
${violet}math.ldexp(x, i)\033[0m
x * (2**i) を返します
${violet}math.modf(x)\033[0m
x の小数部分と整数部分を返します。
${violet}math.nextafter(x, y, steps=1)\033[0m
${violet}math.perm(n, k=None)\033[0m
${violet}math.prod(iterable, *, start=1)\033[0m
${violet}math.remainder(x, y)\033[0m
${violet}math.sumprod(p, q)\033[0m
${violet}math.trunc(x)\033[0m
${violet}math.ulp(x)\033[0m
${violet}math.cbrt(x)\033[0m
${violet}math.exp(x)\033[0m
${violet}math.exp2(x)\033[0m
${violet}math.expm1(x)\033[0m
${violet}math.log(x[, base])\033[0m
${violet}math.log1p(x)\033[0m
${violet}math.log2(x)\033[0m
${violet}math.log10(x)\033[0m
${violet}math.sqrt(x)\033[0m
${violet}math.acos(x)\033[0m
${violet}math.asin(x)\033[0m
${violet}math.atan(x)\033[0m
${violet}math.atan2(y, x)\033[0m
${violet}math.cos(x)\033[0m
${violet}math.dist(p, q)\033[0m
${violet}math.hypot(*coordinates)\033[0m
${violet}math.sin(x)\033[0m
${violet}math.tan(x)\033[0m
${violet}math.degrees(x)\033[0m
${violet}math.radians(x)\033[0m
${violet}math.acosh(x)\033[0m
${violet}math.asinh(x)\033[0m
${violet}math.atanh(x)\033[0m
${violet}math.cosh(x)\033[0m
${violet}math.sinh(x)\033[0m
${violet}math.tanh(x)\033[0m
${violet}math.erf(x)\033[0m
${violet}math.erfc(x)\033[0m
${violet}math.gamma(x)\033[0m
${violet}math.lgamma(x)\033[0m
${violet}math.pi\033[0m
${violet}math.e\033[0m
${violet}math.tau\033[0m
${violet}math.inf\033[0m
${violet}math.nan\033[0m

EOF
)




# 複数行コード ヘッダー部分 ライブラリ
EXECPRE=$(cat << EOF
import math
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
from spb import *  # SymPy Plotting Backends (SPB)
import japanize_matplotlib
import matplotlib.pyplot as plt

from fractions import Fraction as Frac
init_printing()
#init_printing(order='rev-lex')
var('a:z')
f = Function('f')

#
# Enter your code below
# Press ## in Last Line
#
EOF
)



# 本体
# コマンド pc
function pc(){


echo -e "${green}pc $pcversion\n\033[0mOne Line Python(SymPy) Code Calculator"
echo -e "Type [n][c][f][mpf][r][m][M][h][s][math][qq] for option"
echo -e " ${mizu}[n]\033[0mprecision n digits ${mizu}[c]\033[0mMultiple Code ${mizu}[f]\033[0mFrac ${mizu}[mpf]\033[0mmpf ${mizu}[r]\033[0mRump ${mizu}[m]\033[0mless Manual"
echo -e " ${mizu}[M]\033[0mOpen Manual ${mizu}[h]\033[0mOpen history ${mizu}[s]\033[0mOpen SymPy Web ${mizu}[math]\033[0mOpen Math module Web ${mizu}[qq]\033[0mQuit pc\n"


unset eq
unset N
mode=''

while :
do

while :
do
    echo -e "One Line Code > \$eq ${mizu}[n]\033[0m${yellow}${N:-16}\033[0m${mizu}digits [c][f][mpf][r][m][M][h][s][math][qq]\033[0m"

    read VAR
    case "$VAR" in
    n )  echo -e -n "${mizu}precision \033[0m${green}${N:-16}\033[0m${mizu}digits > \033[0m" && read N ; continue ;;
    c )  mode="exec" ; break ;;
    f )  mode="frac" ; break ;;
    mpf )  mode="mpf" ; break ;;
    r )  mode="rump" ; break ;;
    m )  helppc ; continue ;;
    M )  helpe ; continue ;;
    h )  pcl ; continue ;;
    s )  pcd && continue ;;
    math )  pcmath && continue ;;
#  c1 )   blue='\033[94m';violet='\033[95m';green='\033[92m';mizu='\033[96m';red='\033[91m' ; continue ;;
#  c2 )   blue='\033[1;30m';violet='\033[1;30m';green='\033[1;30m';mizu='\033[1;30m'; continue ;;
    qq )  mode="quit" ; break ;;
#  sss ) sss ; break ;;
     * )  mode="just" ; echo -n "" > $PCDIR/pceq.txt ; echo $VAR | sed -e 's%\^%**%g' > $PCDIR/pceq.txt && eq=$(<$PCDIR/pceq.txt) ; break ;;
    esac
done

[ "$mode" = "exec" ] && echo -e "${green}[c]Multiple Code + ## >\033[0m" && echo "$EXECPRE" && 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 "${green}[f]eq(one liner code) >\033[0m" && read eqq && echo "$eqq" >> $PCDIR/pchistory.txt && echo $eqq | sed -e 's%[0-9]\+/[0-9]\+%Frac("&").limit_denominator()%g' -e 's%\^%**%g' > $PCDIR/pceq.txt && eq=$(<$PCDIR/pceq.txt)

[ "$mode" = "mpf" ] && echo -e "${green}[mpf]eq(one liner code) >\033[0m" && read eqq && echo $eqq | sed -e 's%[0-9]\+\.*[0-9]*%mpf("&")%g' -e 's%\^%**%g' > $PCDIR/pceq.txt && eq=$(<$PCDIR/pceq.txt)

[ "$mode" = "rump" ] && echo -e "${green}Rump"\'"s example Test\033[0m" && eq="rump"

[ "$mode" = "quit" ] && echo -e "${green}Quit pc\033[0m" && break



COMMAND=$(cat << EOF
$(echo date "+%Y.%m.%d-%H:%M:%S") >> $PCDIR/pchistory.txt
echo "$eq" >> $PCDIR/pchistory.txt
echo "" >> $PCDIR/pchistory.txt
echo -E "
import math
from fractions import Fraction as Frac
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
from spb import *  # SymPy Plotting Backends (SPB)
import japanize_matplotlib
import matplotlib.pyplot as plt

init_printing() #降べきの順
# init_printing(order='rev-lex') #昇べきの順
var('a:z')
f = Function('f')

GRE='$green'
RED='$red'
VIO='$violet'
END='\033[0m'

mp.dps = ${N:-16}
# mp.prec = 200
# print(GRE+'\n[0]print(eq)'+END)
# print($eq)

print(VIO+'\n[1]pprint(eq,use_unicode=False)'+END)
print(GRE,end='')
pprint($eq,use_unicode=False)
print(END,end='')

print(VIO+'\n[2]pprint(eq,use_unicode=True)'+END)
print(GRE,end='')
pprint($eq,use_unicode=True)
print(END,end='')

print(VIO+'\n[3]pprint(eval(eq), order="rev-lex")'+END)
print(GRE,end='')
pprint(eval('$eq'), order='rev-lex')
print(END,end='')

print(VIO+'\n[4]print(eval(eq))'+END)
print(GRE,end='')
print(eval('$eq'))
print(END,end='')

print(VIO+'\n[5]N(eq,${N:-16})'+END)
try:
    N($eq,${N:- 16})
except AttributeError:
    print(RED+'No Numerical Evaluation'+END)
else:
    print(GRE,end='')
    pprint(N($eq,${N:-16}))
    print(END,end='')

print(VIO+'\n[6]latex(eval(eq))'+END)
try:
    latex(eval('$eq'))
except AttributeError:
    print(RED+'No Output in LaTeX'+END)
else:
    print(GRE,end='')
    print(latex(eval('$eq')))
    print(END,end='')

print(VIO+'\n[7]latex(N(eq,${N:-16}))'+END)
try:
    latex(N($eq,${N:-16}))
except AttributeError:
    print(RED+'No Output in LaTeX'+END)
else:
    print(GRE,end='')
    print(latex(N($eq,${N:-16})))
    print(END,end='')
print('\n')
" | python

EOF

)


# モード毎
case $mode in
just )
eval "${COMMAND}"
;;


exec )
date "+%Y.%m.%d-%H:%M:%S" >> $PCDIR/pchistory.txt
echo -e "$eqq" >> $PCDIR/pchistory.txt
echo -E "
import math
from mpmath import *
from pprint import pprint
mp.pretty = True
from sympy import *
from spb import *  # SymPy Plotting Backends (SPB)
import japanize_matplotlib
import matplotlib.pyplot as plt

from fractions import Fraction as Frac
init_printing()
#init_printing(order='rev-lex')
var('a:z')
f = Function('f')

GRE='$green'
RED='$red'
VIO='$violet'
END='\033[0m'

mp.dps = ${N:- 16}

print(VIO+'\n[8]exec(eq)'+END)
f = open('$PCDIR/pceq.txt')
cmd = f.read()
print(GRE,end='')
exec(cmd)
print(END)
" | python
echo -n "" > $PCDIR/pceq.txt
;;


frac )
echo $eq && echo -n -e "${green}expression 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 "${green}expression change? [n(ENTER)/y]\033[0m " ; read yn
case "$yn" in [Yy])
read eq ;;
[])
;;
[n])
;;
esac
eval "${COMMAND}"
;;


rump )
echo -e -n "${green}precision[default:16] > \033[0m"
read N
$(echo date "+%Y.%m.%d-%H:%M:%S") >> $PCDIR/pchistory.txt
echo "$eq" >> $PCDIR/pchistory.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

}

option[m] Manual

スクリーンショット 2024-06-27 18.53.58.
スクリーンショット 2024-06-27 14.18.24.
スクリーンショット 2024-06-27 14.20.10.
スクリーンショット 2024-06-27 14.20.41.
スクリーンショット 2024-06-27 14.21.15.
スクリーンショット 2024-06-27 14.21.38.
スクリーンショット 2024-06-27 14.21.57.
スクリーンショット 2024-06-27 14.22.16.
スクリーンショット 2024-06-27 14.22.37.
スクリーンショット 2024-06-27 14.23.10.
スクリーンショット 2024-06-27 14.23.26.
スクリーンショット 2024-06-27 14.23.43.
スクリーンショット 2024-06-27 14.24.05.
スクリーンショット 2024-06-27 14.24.21.
スクリーンショット 2024-06-27 14.24.37.
スクリーンショット 2024-06-27 14.24.59.
スクリーンショット 2024-06-27 14.25.17.
スクリーンショット 2024-06-27 14.27.13.

Jupyter Notebook PDF出力 日本語設定

毎月開催している桜井進のPython・UNIX教室ではJupyter Notebookファイルをテキストにしています
受講生にはhoge.ipynbと全セル出力したhoge.pdfを配付するので
hoge.ipynbをhoge.pdfに変換します
以下の方法がわかるまでは印刷からPDF出力する方法を用いてきましたが
印刷レイアウトがイマイチでした

ようやくNotebook 7.0.0がリリースされました
これを機にnbconvertとjupyterで日本語PDF変換できるようにするための方法を探りました

Jupyter Notebookファイル hoge.ipynbをPDFに変換する方法は2つ
ターミナルから

$ jupyter nbconvert hoge.ipynb --to pdf

jupyterから
File -> Save and Export Notebook As… -> PDF

スクリーンショット 2023 07 27 15 49 05

どちらもLaTeX経由でPDFに変換するので
TeX Live等がインストールされていることが必須です
デフォルトでは日本語は通りません
それぞれの設定ファイルを編集して日本語が通るようにします

設定ファイルの場所を調べる

$ jupyter --path
config:
    /Users/sakuraisusumu/.jupyter
    /Users/sakuraisusumu/.local/etc/jupyter
    /Users/sakuraisusumu/.pyenv/versions/3.11.4/etc/jupyter
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/sakuraisusumu/Library/Jupyter
    /Users/sakuraisusumu/.local/share/jupyter
    /Users/sakuraisusumu/.pyenv/versions/3.11.4/share/jupyter
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/sakuraisusumu/Library/Jupyter/runtime

dataに示されたディレクトリを1つずつ調べて
index.tex.j2
base.tex.j2
を探します

jupyter nbconvert の設定ファイル

~/.pyenv/versions/3.11.4/share/jupyter/nbconvert/templates/latex/index.tex.j2

これを開いて次のように書き換えます

%===============================================================================
% Latex Article
%===============================================================================

((*- block docclass -*))
\documentclass[xelatex,ja=standard]{bxjsarticle}
((*- endblock docclass -*))

jupyter の設定ファイル

~/.pyenv/versions/3.11.4/share/jupyter/nbconvert/templates/latex/base.tex.j2

これを開いて14行目を次のように書き換えます

((=- Latex base template (must inherit)
This template builds upon the abstract template, adding common latex output
functions. Figures, data_text,
This template defines defines a default docclass, the inheriting class should
override this.-=))

((*- extends 'document_contents.tex.j2' -*))

%===============================================================================
% Abstract overrides
%===============================================================================

((*- block header -*))
    ((* block docclass *))\documentclass[xelatex,ja=standard]{bxjsarticle}((* endblock docclass *))

MacOSでは以上の変更で日本語出力OK
ubuntu 22.04では、以上の設定ではダメで
/Users/sakuraisusumu/.local/share/jupyter
の2つのファイルの変更で日本語出力OKでした

これでどちらの方法でも日本語PDFが出力されるようになります
スクリーンショット 2023 07 27 16 13 35

Mac Pro Early 2009 + Python 3.11.4 + TensorFlow 2.12.0 インストール記録

今日もメインマシンはMac Pro Early 2009
macOS Monterey 12.6.7

2021年9月17日の記事
のときは
macOS Catalina 10.15.6

Pythonもバージョンアップしていることなので
心機一転Pythonのインストールを実施

目標
Python 3.11.4
mayavi
TensorFlow

Python 3.11.4 インストール

$ pyenv install --list
$ pyenv install 3.11.4
$ pyenv global 3.11.4
$ pyenv rehash

問題なく完了
必要なモジュール・ライブラリのインストール

$ pip install -U pip setuptools
$ pip install numpy
$ pip install sympy
$ pip install scipy
$ pip install matplotlib
$ pip install japanize-matplotlib
$ pip install pandas
$ pip install jupyter
$ pip install jupyterlab
$ pip install ipyparallel
$ pip install gmpy2
$ pip install nodejs
$ pip install scikit-image

mayavi インストール

$ pip install vtk
$ pip install PyQt5
$ pip install mayavi

エラーによりインストールできない
前に試したライブラリをbrewインストールしてみる

$ brew install libxkbcommon-x11-0
$ brew install libxkbcommon
$ brew install libxcb-icccm4
$ brew install ibxcb-image0
$ brew install libxdamage
$ brew install libxcb-keysyms1
$ brew install xcb-util-keysyms
$ brew install libxcb-render-util0
$ brew install libxrender
$ brew install libxcb-xinerama0
$ brew install libxinerama
$ pip install mayavi

これでもダメ
対策を調べると
https://github.com/enthought/mayavi/issues/1232
ここに何やら解決策がある

$ brew install libvtk6-dev
$ brew install libpq5
$ brew install vtk6
$ brew install libvtk6-dev-qt 
$ pip install https://github.com/enthought/mayavi/zipball/master

インストールできた!
さっそく次のコードでテスト

from numpy import pi, sin, cos, mgrid
dphi, dtheta = pi/250.0, pi/250.0
[phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi+dtheta*1.5:dtheta]
m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;
r = 2*sin(5*phi+cos(10*theta))
x = r*sin(phi)*cos(theta)
y = r*cos(phi)
z = r*sin(phi)*sin(theta)

from mayavi import mlab
mlab.figure(1, bgcolor=(0, 0, 0), fgcolor=(0, 0, 0), size=(600, 400)) # 背景色,サイズ等を設定
mlab.clf()
s = mlab.mesh(x, y, z)
mlab.show()

OK!

TensorFlow インストール

いつものように試行錯誤の連続
頼ったのはAppleのページ
https://developer.apple.com/metal/tensorflow-plugin/

これを信じてすべてを試してもTensorFlowはうまく動いてくれない

$ pip install tensorflow

だめ

$ pip install tensorflow
$ pip install tensorflow-metal

だめ

$ pip install tensorflow-macos
$ pip install tensorflow-metal

これもだめ

そもそもMacPro2009のCPUが古いせいで
2021年9月17日の記事
のときはPython 3.6.5でしかTensorFlowは動かせなかった
それもTensorFlow 1.5.0
いろいろ試して動かないのも無理はないかと諦めかけたとき
やっと成功!

$ pip install tensorflow-macos

これでOK
TensorFlow 2.12.0
が動いた
tensorflow-metalが要らなかった!

TensorFlowで次のHello Worldを実行して動作確認

$ python
Python 3.11.4 (main, Jul  5 2023, 13:11:04) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
>>> import tensorflow as tf
>>> hello = tf.constant('MacPro2009 Python 3.11.4 TensorFlow 2.12.0 Hello World')
>>> tf.print(hello)
MacPro2009 Python 3.11.4 TensorFlow 2.12.0 Hello World
>>> 

OK!

昔につくった画像認識のコードも動いた

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
from tensorflow.keras.preprocessing import image
import numpy as np
import sys

# 画像を読み込み
input_filename = sys.argv[1] #コマンドライン引数で画像のファイルパスを指定
input_image = image.load_img(input_filename, target_size=(224, 224))
input = np.expand_dims(image.img_to_array(input_image), axis=0)

# モデル定義と認識処理
model = VGG16(weights='imagenet')
results = model.predict(preprocess_input(input))

# Kerasが提供するdecode_predictionsを用いて結果出力
decoded_result = decode_predictions(results, top=5)[0]

# 結果を整形して表示
print(' ')
print('TensorFlow(Keras)による画像認識結果')
print(' '.rjust(16), '\t', '確率')
for i in range(5):
    name = decoded_result[i][1]
    ratio = decoded_result[i][2]
    name_rjust = name.rjust(16)
    print(name_rjust , "\t", '{:.2f}'.format(ratio * 100.0)+'%')
print(' ')
Cat
cat.jpg
$ python ai.py cat.jpg         
1/1 [==============================] - 1s 662ms/step

TensorFlow(Keras)による画像認識結果
                     確率
           tabby     71.12%
    Egyptian_cat     14.72%
       tiger_cat     10.62%
        radiator     0.55%
         doormat     0.27%

これでミッションコンプリート!

One liner SymPy Calculator(一行数式SymPy計算機)Ver.20230508

ターミナルだけですぐに計算できる

基本は一行のPythonSymPyコードをpythonに渡すだけの仕組み
SymPyとmpmathライブラリの関数を使った一行コードが実行できる
以下仕様のようにもろもろのセッティングが不必要
いちいちpythonを起動、コーディングをしなくても計算できることを追求

【条件】

Bash、zshでの使用OK
python実行環境インストール済み
SymPyライブラリ
mpmathライブラリ

実装環境
macOS12.6.5
Python 3.9.16

Ubuntu22.04.2LTS
Python 3.8.16

【仕様】

入力数式はpython文法
シンボリック変数はaからz
シンボリック関数はf 微分方程式用
sympyとmpmathの関数はすべて使える
分数 2/3 を Frac(2,3)またはFrac(2/3)とすれば分数として計算・出力
おまけ Rumpの例題の検証 入力にrump

【使い方】

ターミナルで

$ pycalc

で本体起動

数値計算式・代数式を入力(変数eq)・rump:
演算精度の桁数(デフォルト1):

ターミナルで

$ pycalcl

で過去入力コードを記録した
$HOME/myscript/pycalcl.txt
を開く

【5通りの出力】

pprint($eq,use_unicode=False)
pprint($eq,use_unicode=True)
pprint(eval('$eq'))
print(eval('$eq'))
pprint(N($eq,${N:- 1}))

【インストール】

HOMEにディレクトリmyscriptをつくる
HOME/myscriptに
pycalc.sh
pycalcl.txt
を配置

MacOSのzshの場合.zshrcに
ubuntuのBashの場合.bashrcに
に以下を追記

source $HOME/myscript/pycalc.sh

一行数式SymPy計算機シェルスクリプト pycalc.sh

# pycalc.sh
function pycalcl(){
open $HOME/myscript/pycalcl.txt
}

function pycalc(){
echo '【One liner SymPy Calculator(一行数式SymPy計算機)】Ver.20230508'
echo ' 商// 剰余% 商と剰余divmod()分数2/3 Frac(2,3) 平方根sqrt(2) 三角関数sin(pi/3) 指数exp() 自然対数log(E**2) 常用対数log(2,10)'
echo ' 虚数j(標準) (2+3j)*(5-7j)'
echo ' 虚数I(SymPy) exp(cos(E**I)+sin(E*pi)) I**I'
echo ' 素因数分解 factorint(1000) 階乗factorial(10)'
echo ' 代数演算 シンボリック変数aからz expand((x+y)**10) factor(a**10-b**10) '
echo ' 数列 Sum(k**2,(k,1,n)).doit()'
echo ' 方程式 solve(a*x**2+b*x+c,x) 連立方程式 solve([x+y-4,x-y-2],[x,y])'
echo ' 微分方程式 変数はf限定 dsolve(Eq(f(t).diff(t, t) - f(t), exp(t)), f(t))'
echo ' 微分 diff(x**2,x) 積分integrate(x**3,x) 定積分integrate(x**3,(x,0,1))'
echo ' 無限oo integrate(1/(1+x**2), (x, -oo, oo)) '
echo ' テイラー展開 series(sin(x),x, 0, 12)'
echo ' テイラー展開 係数リスト taylor(sin, 0, 5)'
echo ' 行列 Matrix([[1, 2], [2, 2]]).eigenvals()'
echo ' 関・ベルヌーイ数 bernoulli()'
echo ' ゼータ zeta() zetazero()'
echo ' ブール値検算 1+1 == 3   expand((x+y)**2) == x**2 + 2*x*y + y**2'
echo ' グラフ plot(x**2, (x, -1, 2), ylabel = "y")'
echo ' mpmath任意精度浮動小数点演算パッケージによる精度計算 (-2)**mpf("0.5")'
echo ' Rumpの例題 入力にrump https://ja.wikipedia.org/wiki/%E7%B2%BE%E5%BA%A6%E4%BF%9D%E8%A8%BC%E4%BB%98%E3%81%8D%E6%95%B0%E5%80%A4%E8%A8%88%E7%AE%97'

echo -e '\n数値計算式・代数式(変数eq)・rump:'
read eq
echo -n '\n演算精度の桁数(デフォルト1):'
read N
echo "$eq" >> $HOME/myscript/pycalcl.txt
echo -E "
from mpmath import *
mp.pretty = True
from sympy import *
from fractions import Fraction as Frac
init_printing()
var('a:z')
f = Function('f')

rump = 'rump'
if $eq == 'rump':
    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'通常計算{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))
    for mp.dps in range(1, $N+1):
        print(mp.dps,g(mpf('77617'), mpf('33096')))
else:
    mp.dps = ${N:- 1}
    # mp.prec = 200
    print('\npprint($eq,use_unicode=False)')
    pprint($eq,use_unicode=False)

    print('\npprint($eq,use_unicode=True)')
    pprint($eq,use_unicode=True)

    print('\npprint(eval(eq))')
    pprint(eval('$eq'))

    print('\nprint(eval(eq))')
    print(eval('$eq'))

    print('\nN($eq,${N:- 1})')
    pprint(N($eq,${N:- 1}))
" | python
}

使用例

初等関数・分数

スクリーンショット 2023 05 08 12 00 14

虚数

スクリーンショット 2023 05 08 12 00 35

分数

スクリーンショット 2023 05 08 12 00 50

方程式

スクリーンショット 2023 05 08 12 01 05

逆行列

スクリーンショット 2023 05 08 12 01 19

微分方程式

スクリーンショット 2023 05 08 12 01 32

検算

スクリーンショット 2023 05 08 12 01 46

検算

スクリーンショット 2023 05 08 12 01 59

任意精度浮動小数点演算

スクリーンショット 2023 05 08 12 02 43

Rumpの例題の検証

スクリーンショット 2023 05 08 12 03 21

PDFを回転・保存するqpdfコマンド

MacOSのプレビューの不満
コマンド+Rで回転して保存しても変更が保存されない
非常に不便

そこでUNIXの出番
org.pdfを
時計回り(右回り)90度回転 +90
して、new.pdfをつくる

$ qpdf --rotate=+90 org.pdf new.pdf

これでOK

注意は、+90が数学における反時計周り・左回りではなく、その反対である点

qpdfはbrewでインストール

$ brew install qpdf
$ brew info qpdf
qpdf: stable 10.6.3 (bottled)
Tools for and transforming and inspecting PDF files
https://github.com/qpdf/qpdf
/usr/local/Cellar/qpdf/10.6.3 (81 files, 9.4MB) *
  Poured from bottle on 2022-03-14 at 22:21:47
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/qpdf.rb
License: Apache-2.0
==> Dependencies
Required: jpeg ✔, openssl@1.1 ✔
==> Analytics
install: 2,815 (30 days), 14,484 (90 days), 48,488 (365 days)
install-on-request: 2,148 (30 days), 10,922 (90 days), 33,609 (365 days)
build-error: 0 (30 days)

qpdfの詳細
https://qpdf.readthedocs.io/en/stable/cli.html?highlight=rotate#option-rotate

MacPro2009でTensorflow+Kerasを使う

私のメインマシンはMacPro2009
拡張性の大きさから10年以上現役バリバリ
M1MacBook Proはサブ
他に
MacBook Pro Late 2013
MacBook Air Mid 2012
Dell OPTIPLEX 3020(Ubuntuメイン+NAS)
HP EliteBook 820(SSD分割Ubuntu+Win10)
東芝DynaBook T350(win7)
Macpc 001
これだけのマシンを駆使して
桜井進のPython・UNIX教室で使うUSBメモリーブートUbuntuシステムを作成できます
本当はテスト用に2016年〜2020年のMacBook Proが欲しい

さて本題
これらのマシンにPythonの実行環境がある
Pythonのバージョンメンテナンスで面倒なのがTensorFlow
それぞれのマシンで動くバージョンが違う(CPU、GPUの性能に異存)
Tensorflowのインストールだけでも手間がかかるのに
異存するライブラリのバージョンも関係するのでさらに面倒

なかでもメインマシンMacPro2009(10.15.6)はCPUが古いので
新しいTensorFlowは入らない
それでもTesorFlow 1.5.0なら動くことがわかった

ところが、
そこに画像認識をさせようとKerasを動かそうとするとこれが中々動いてくれない

試行錯誤の末、ようやくTnsorflow+Kerasが動く組合せを見つけた

Macにはpyenvを使ってPythonをインストール
これでPythonのバージョンを自在にコントロールできる
Python 3.6.5のインストール

$ pyenv install --list
$ pyenv install 3.6.5
$ pyenv global 3.6.5
$ pyenv rehash

同様にPython 3.6.6のインストールすると
次のように異なるバージョンのスイッチングが簡単にできて便利

$ pyenv versions
  system
* 3.6.5 (set by /Users/sakuraisusumu/.pyenv/version)
  3.6.6

TensorFlow 1.5.0 インストール

$ python -m pip install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.5.0-py3-none-any.whl

組合せその1
Python 3.6.6
TensorFlow 1.5.0
keras 2.6.0(最新)

TensorFlow OK
Tnsorflow+Keras NG

組合せその2
Python 3.6.6
TensorFlow 1.5.0
keras 2.4.3(2.3.0、2.2.1)

TensorFlow OK
Tnsorflow+Keras NG

組合せその3
Python 3.6.5
TensorFlow 1.5.0
keras 2.2.1

TensorFlow OK
Tnsorflow+Keras OK

これでMacPro2009でもTnsorflow+Keraを使った画像認識ができるようになった
本当に微妙なバージョン違いです

$ python ai.py cat.jpg
Using TensorFlow backend.
2021-09-17 03:28:56.088497: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.2

keras+TensorFlowによる画像認識結果
                     確率
           tabby     71.12%
    Egyptian_cat     14.72%
       tiger_cat     10.62%
        radiator     0.55%
         doormat     0.27%

桜井進のPython・UNIX教室(入門コース全3回Zoom)の第3回授業風景
Dell OPTIPLEX 3020(Ubuntuメイン+NAS)でTnsorflow+Keraを使った画像認識を実行しているところ
スクリーンショット 66

MacOS UNIXコマンド locate

$ locate pytest

pipでpytestをインストールした際、whichとwhereisでpytestを探しても見つけられなかった
pipでアンインストールしようとしたら

$ python -m pip uninstall pytest
Found existing installation: pytest 6.2.4
Uninstalling pytest-6.2.4:
  Would remove:
    /Users/sakuraisusumu/.local/bin/py.test
    /Users/sakuraisusumu/.local/bin/pytest
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/_pytest/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest-6.2.4.dist-info/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest/*
Proceed (Y/n)? 

となり、/Users/sakuraisusumu/.local/bin/pytest にあることがわかった
これはこれで解決だが、
UNIXコマンドに検索があったはず(使ったことがなかった)と思いだし
findとlocateでpytestを探してみた

findは使い物にならない
locateはあらかじめデータベースを作っておくので全検索に近い
ところがだ
/Users/sakuraisusumu/.local/bin/pytest
が引っかからない
なぜだ?

locateを調べる

GNU版locateはfindutilsに入っているので

$ brew install findutils

によりインストールできる
glocateでpytestを検索するも変わらない

locateがデータベースをつくる歳にすべての領域を範囲とするわけでないことが判明
パーミッションが700である自分のディレクトリィの下は検索しない
そうだ

ということでHOMEにあるディレクトリでパーミッションが700のものを755に変更して
データベースをつくりなおしたところ今度は
/Users/sakuraisusumu/.local/bin/pytest
が見つかった

おかげでlocateについてだいぶわかった

MacOS Pythonにpytest インストール

$ python -m pip install pytest

インストールできたものの

$ pytest
zsh: command not found: pytest

あれれ?

$ which pytest
$ whereis pytest

だめだ、見つからない!
そこで一旦アンインストールすることに

$ python -m pip uninstall pytest
Found existing installation: pytest 6.2.4
Uninstalling pytest-6.2.4:
  Would remove:
    /Users/sakuraisusumu/.local/bin/py.test
    /Users/sakuraisusumu/.local/bin/pytest
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/_pytest/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest-6.2.4.dist-info/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest/*
Proceed (Y/n)? 

ここでようやくpytestの場所が判明
さっそく.zprofileにPATHを通してOK

dateで元号(令和平成昭和大正明治)表示

date → gdate

MacOS標準シェルzshのdateコマンドよりも
GNU系のdateコマンド(gdateコマンド)の方が気に入っている

$ which date
/bin/date
$ date
2021年 8月25日 水曜日 03時28分37秒 JST

このdateコマンドは次のようなGNU系dateコマンド(gdateコマンド)の作文ができない

$ date -d'10year 6month 3day 5hour 23minute 10second ago'

そこでgdateが使えるようにする

$ brew install coreutils

これによりglsやgdateのようなGNU版コマンドが100以上インストールされる
コマンドリストは次により確認できる

$ brew ls coreutils

ただgdateの標準出力が気にくわない

$ gdate
火  9  7 12:41:56 JST 2021

これはdateの出力のいいのでそれにあわせる
ついでに元号表示も工夫してみる

シェルスクリプト

.zprofile
に以下を追加

alias date="gdate +'%Y年%m月%d日%A%T'"
# 元号表示
function gendate()
{
y=$(gdate +'%Y')
r=$((y+1-2019))
h=$((y+1-1989))
s=$((y+1-1926))
t=$((y+1-1912))
m=$((y+1-1868))
n=$(gdate +'%Y年%m月%d日%A%T')
echo '令和'$r'年 平成'$h'年 昭和'$s'年 大正'$t'年 明治'$m'年 '$n
}

これで

$ date
2021年09月07日火曜日12:46:08

MacPro:~
$ date -d'10year 6month 3day 5hour 23minute 10second ago'
2032年03月10日水曜日18:09:05

MacPro:~
$ gendate
令和3年 平成33年 昭和96年 大正110年 明治154年 2021年09月07日火曜日12:46:19

これでOK

2段組PDFからテキスト抽出するコマンド

Mac標準でPDFからテキストを抜き出す簡単な方法はありません
Mac標準のAutomatorや専用アプリを使う必要があります
さらに二段組みPDFからテキスト抽出となると難しくなります

unixの「pdftotext」コマンドを使う方法なら1行でOK
二段組みのPDFにも対応します
hoge.pdf
から
hoge.txt
を生成するコマンドです

pdftotext -raw hoge.pdf - | sed ':loop; N; $!b loop; ;s/\n//g' >> hoge.txt
pdftotextのインストール

brewでpopplerをインストールすればOK

brew install poppler

次のコマンドがすべてインストールされる

pdftotext: converts PDF to text
pdftops: converts PDF to PostScript
pdftoppm: converts PDF pages to netpbm (PPM/PGM/PBM) image files
pdftopng: converts PDF pages to PNG image files
pdftohtml: converts PDF to HTML
pdfinfo: extracts PDF metadata
pdfimages: extracts raw images from PDF files
pdffonts: lists fonts used in PDF files
pdfdetach: extracts attached files from PDF files
pdfseparate: PDF to PNG/JPEG/TIFF/PDF/PS/EPS/SVG
pdfunite: PDF page merger

https://poppler.freedesktop.org/