Pythonでやってみよ。小技1
Python対話モードで残念なところをカバーする小技です。
if、while、for、try、withなど、1文(1行)で終わらず、改行後「>>>」ではなく、「...」で文が続く複合文です。途中間違えると普通の文なら、コマンド履歴機能を使って、上矢印押せば以前の文(プログラム)を表示させて、そのまま再実行や、すこし修正して実行できて楽なんです。が、ifなどの複合文は、文の始めになるif、while、for、try、withの文まで戻ってから、修正するその続きのインデントされている文まで戻る必要があるんです。
複合文の途中の文だけを修正することはできずに、やってしまうとエラーになります。プログラムが思うようなかたちになるまで、試行錯誤をするのですが、上矢印でもどるか、自分で最初から入力するか、ストレスがたまります。これはかなり困ったもんです。これは長い行のプログラムでも同じ、長いと最初からうまいこと処理ができてうれしくなるプログラムを書くことはありません。
コツコツと1行1文ずつ結果を見ながら作っていくので、ターミナルの画面をtmuxを使って縦半分の2分割して、片側にvimでプログラムを書いて、それをコピーしてもう片側でPython対話モードに貼り付けて実行、結果を確認しています。これならvim側でできたところまでの数行を1度にコピーして、もう1方のPython対話モードに貼り付ければ、実行できます。
もう1つのやり方は、コピペではなくもう少しプログラムの感じのするものです。vim側で書きかけのプログラムとしてファイルに保存してから、開きます。追加や修正、削除など編集した都度保存します。そして、Python対話モード側で、次のプログラムを実行する方法です。
書きかけのPythonプログラムファイル(ここでは、python_program_test.pyとします)をopenで開いて変数fに読み込み、リスト内包表記でプログラムファイルの中身をリストとして変数fnに代入、openされたfを閉じてから、プログラムファイルの実行したい文(行)をリストのスライスで範囲指定してjoinで文字列としてつないでexecを使ってPythonプログラムとして実行します。
f=open('python_program_test.py',encoding='utf-8',errors='ignore');fn=[x for x in f];f.close();exec(''.join([x for x in fn][:98]))
#自作関数 「fr」を定義しておけば、少し短くなります。
def fr(fnr):f=open(fnr,'r',encoding='utf-8',errors='ignore');fn=[x for x in f];f.close();return fn
fn_='python_protram_test.py';fn=fr(fn_);exec(''.join([x for x in fn][:98]))をPython対話モードで実行、結果を確認、vim側で編集して保存、Python対話モード側で上矢印で1つ戻って範囲が同じならそのまま実行、範囲指定を変えて実行を繰り返します。
希望する処理ができるようになったら、スライスの部分([:98])を[:]にすれば、Pythonプログラムファイルを実行したことと同じになります。コピペの場合、何かの拍子でコピーできていなくて、プログラムではない文をペーストしてしまうこともあって、Python対話モードからエラーを指摘されることもありますが、この方法ならほんとにストレスから解放されますよ。
fn_='python_protram_test.py';fn=fr(fn_);exec(''.join([x for x in fn][:]))
Pythonは標準ライブラリ(モジュール、関数など)が豊富でなんでもできそうですが、正規表現やファイル操作、クリップボード操作、Webスクレイピング操作、表計算形式やデータベース形式の操作など必要に応じて、いろいろな外部モジュールも豊富です。Pythonプログラムをファイルとして保存して使う場合は、そのプログラムファイルごとに必要なモジュールをimportをすればいいのですが、対話モードを起動するたびにimport文を書くのもストレスになります。
プログラムを試行錯誤しているうちに最初にimportしていないモジュールがあったり、それも何気にストレスになります。そこで、もう1つの小技です。いつも使うモジュール、いつもではないがときには使うモジュール、自分の役にたってもらうために作った自作関数を1つのファイルに書き込んで保存したPythonモジュールファイルを対話モードの最初でimportするんです。
import文の最後にコメント(#以降)を書いておきます。ここではgofromとしています。コメントを書いておくことの効用は、「Ctrl+r」でコマンド履歴を検索表示しやすくすることです。いつも使うプログラム文には、コメント書いておくことをおすすめします。探す手間も省け、修正部分も部分的なので、入力間違いによるエラーも回避できます。最近はpandasやopenpyxl、visidataも使うことが増えたので、同じようにモジュールやモジュールのオプション設定を記述して追加しています。これでたくさんのモジュールをひとつひとつimportすることから開放されました。加えて、自作関数(def)もオプション設定が煩雑な外部モジュールの設定もしておけば、この1行ですべて必要なものがimportできるのです。時間もだいぶ節約されてうれしいことだらけ。
from my_module import * #gofrom
この1行は、対話モードだけでなく、ターミナルのコマンドラインでも使いたくなります。コマンド履歴を遡れば入力する必要はありませんが、なにせインポート文だけで文字数が多くなります。そこで、ターミナルで使うときには、シェル(zshやBash)の設定ファイルに変数(わたしは、imt)として設定しておきます。
imt='from import_test import *'
コマンドラインでPythonを使うときには、こうします。
python3 -c "$imt;print('Hello World')"
「$imt」の部分は、実行時に「from import_test import *」に展開されます。
ちょっとしたことで、ストレスから開放され日常的にプログラムが使えるようになりますね。
スケルトンライナーには、「#コメント」つけると、検索と履歴呼び出しが楽になります。
if、for、try、withなど改行が必要で数行になるプログラムや行数が長くなるプログラムの作成時の試しは、プログラムをテキストファイルに保存して「fn_='python_protram_test.py';fn=fr(fn_);exec(''.join([x for x in fn][:]))」で実行したい行範囲を指定する。
このファイルの該当行を指定して実行する方法は、シェルコマンドでもできます。こうします。
6行目のワンライナーを実行したい場合
eval $(cat ~/電子帳簿保存法対応業務フロー.txt|sed -ne'6p')
あるいは
for i in {6..7};do eval $(cat ~/電子帳簿保存法対応業務フロー.txt|sed -ne $i'p');done
行を指定したり範囲指定したい場合
rng=(1 2 4 {5..7} 9);for i in ${rng[@]};do eval $(cat ~/電子帳簿保存法対応業務フロー.txt|sed -ne $i'p');done
「電子行簿保存法対応業務フロー.txt」には、その名の通り必要なワンライナーやスケルトンライナーがフローとして保存されています。実行時は「行番号」を帰るだけなので、毎月の会計処理のときにとても役に立っています。
