GMT ver.5 で貸出記録の印刷

2017年6月23日記事 地域図書館の貸出記録を取得  で作成したテーブルが、だいぶ充実してきました。

折角ですので、一度読んだ本を重複して図書館で借りたりしないように読書リストを作ってみようと思います。

上記のテーブルには著者名のフィールド auther、書名のフィールド title、借りた日(正確にはデータベース登録した日)のフィールド insertDateなどが存在します。

そこで、著者名でグループ化したうえで借りた日でソートした表をPDFにしました。これを紙に印刷したり、タブレット端末やスマートフォンにダウンロードして図書館に持って行けば、一度読んだことのある本を重複してまた借りるといった失敗が無くなります。

f:id:S_E_Hyphen:20171119140636j:plain

#!/bin/bash

#著者名を変数 $auther に入力
declare -a auther
auther=(\
`mysql -N -h 192.168.0.16 life_log << _SQL_
select auther from library
group by auther
order by auther;
_SQL_`)

for ( ( i=0; i<${#auther[*]}; i++ ) )
do
echo `expr $i % 2 ` ${auther[$i]}
done > auther_list.txt

# auther_list.txtの各行に該当する著者名のタイトルを
# table.txtに出力
rm table.txt
while read binary auther
do
mysql -N -h 192.168.0.16 life_log << _SQL_ >> table.txt
select $binary,date(insertDate),left(auther,14),left(title,45) from library
where auther="$auther" order by insertDate;
_SQL_
done < auther_list.txt
rm auther_list.txt

MAX_REC=55
nl=`cat table.txt | wc -l`
page=`expr $nl / $MAX_REC + 1`
psfile=temp.ps
rm temp.ps
for ( ( p=0; p<$page; p++ ) )
do
#table.txtを55行ずつに分ける
cat table.txt |\
awk --assign p="$p" --assign MAX_REC="$MAX_REC" 'p*MAX_REC<NR && NR<=(p+1)*MAX_REC {print $0}' > temp

# binary=1にGRAY200で着色
width=17
cat temp |\
awk -F "\t" '$1==1{printf "0.0 -%f\n 17.0 -%f\n 17.0 -%f\n0.0 -%f\n",NR,NR,NR-1,NR-1}' |\
gmt psxy -P -JX${width}c/25c \
-R0/${width}/-${MAX_REC}/0 \
-Bwesn \
-Byg1 \
-G200 \
-K >> $psfile

#著者名欄(4cm)を記入
gmt psbasemap -P -JX4c/25c \
-R0/4/-${MAX_REC}/0 \
-Bwesn \
-Byg1 \
-O -K >> $psfile
cat temp |\
awk -F "\t" '{printf "0.05 -%f %s\n",NR-0.1,$3}' |\
gmt pstext -J -R -F+jBL+a0.0+f8p,GothicBBB-Medium-UniJIS-UTF8-H,0/0/0 -O -K >> $psfile

#書名欄(11cm)を記入
gmt psbasemap -P -JX11c/25c \
-R0/11/-${MAX_REC}/0 \
-Bwesn \
-Byg1 \
-O -K -X4c >> $psfile
cat temp |\
awk -F "\t" '{printf "0.2 -%f %s\n",NR-0.1,$4}' |\
gmt pstext -J -R -F+jBL+a0.0+f8p,GothicBBB-Medium-UniJIS-UTF8-H,0/0/0 -O -K >> $psfile

#記入日(2cm)を記入
gmt psbasemap -P -JX2c/25c \
-R0/2/-${MAX_REC}/0 \
-Bwesn \
-Byg1 \
-O -K -X11c >> $psfile
cat temp |\
awk -F "\t" '{printf "1.0 -%f %s\n",NR-0.1,$2}' |\
gmt pstext -J -R -F+jBC+a0.0+f8p,GothicBBB-Medium-UniJIS-UTF8-H,0/0/0 -O >> $psfile

done
# PDFファイルに変換する
ps2pdf temp.ps library_list.pdf
rm temp.ps temp table.txt

 

 

 

嚥下障害 ~みかん~

みかんが出回ってきましたので、みかんも使ってみようと考えました。

まずは薄皮も剥かず、軽く筋だけを取ってミキサーに…。やっぱり薄皮は口に残りますね。

ただ、ざるなどで濾過することはできそうです。分量が難しいですが、概ね半量になると考えておけば大丈夫そうでした。

写真は薄皮付きのみかん150グラムを濾しとったところです。

いつものように液体100㏄に対してとろみ剤大さじ1杯を加えて撹拌しました。

少し時間が経ってからも味見してみましたが、ビタミンCを添加する必要はなさそうです。

 

f:id:S_E_Hyphen:20171117085656j:plain

MYSQLを使用した「らじる☆らじる」の録音と再生

テーブルは以下の形式としました。

create table if not exists t_sound(
seq int,
estimate datetime,
sound mediumblob
);

 seq はオートインクリメントされる整数とします。

 estimate には 「らじる☆らじる」の音声ファイル名と放送時刻の対応  で作成した推定式を使用して求めた放送時刻をinsertします。

新しい「らじる☆らじる」 録音方法の提案  で紹介した方法により音声をダウンロードし、8000Hzにダウンレートしたraw形式に変換しておきます。

 この音声ファイルを MYSQLでバイナリデータの取り扱い  のようにしてMYSQLに登録します。

 

再生は放送時刻(date1からdate2まで)で指定することが可能となります。estimateの範囲で検索して、select into dumpfile 文で作成したrawファイルをcat でつなぎ合わせた後に、soxコマンドでwav形式に変換します。

 


 

再生用シェルスクリプト

#!/bin/bash
dir_SECURE_FILE_PRIV=/var/lib/mysql-files
temp=`mktemp ${dir_SECURE_FILE_PRIV}/XXXX`
date1=`getparstr $# "$*" "date1"` # この日時から
date2=`getparstr $# "$*" "date2"` # この日時までを再生
declare seq=( \
`mysql nhkradio -N << _SQL_
select seq from t_sound
where "$date1"<=estimate and estimate<="$date2"
order by estimate;
_SQL_` \
) # 再生すべき連番をシェル変数$seq[]に保存

rm playback.raw
# ${seq[$i]}で検索してバイナリフィールドsoundを外部ファイルに書き出す
for ( ( i=0; i<${#seq[*]}; i++ ) )
do
echo ${seq[$i]}
rm $temp
mysql nhkradio << _SQL_
select sound into dumpfile "$temp"
from t_sound where seq=${seq[$i]};
_SQL_
cat $temp >> playback.raw # catでraw形式ファイルに連結する
done
rm $temp

# soxで事前に決めておいたwav形式ファイル playback.wav に変換する
sox -r 8000 -c 1 -b 16 -e signed-integer playback.raw playback.wav
aplay playback.wav # playback.wav ファイルを再生する
rm playback.wav playback.raw

 

 

ブリの照り焼き

フライパンに水1カップ、しょうゆ大さじ1、みりん大さじ1を入れてブリの切り身を加熱します。

アルミホイルなどで落し蓋をしておきます。

調味料は、食材をそのまま食べるのに適量かどうかが目安です。例えば同量の刺身を大さじ1杯の醤油だけでは食べきれないとするならば、大さじ1杯の醤油だけでは煮つけにしても薄味すぎると言えるでしょう。

一方、水の量はいい加減でよいのかもしれません。切り身が浸るのならば、少ない方が煮る時間が短くて済みそうです。

f:id:S_E_Hyphen:20171113091919j:plain

上の写真のような状態になるまで約25分かかりました。

この瞬間が最も大事です。早く火を止めすぎると魚に味が入りきらず、ただの水煮のようになってしまいます。煮汁が無くなるまで、しっかり火を入れましょう。しかし火を止めるのが遅すぎると焦げ付いてしまいます。結局ずっと目が離せないということになります。

f:id:S_E_Hyphen:20171113092300j:plain

塩焼きの方がずっと手早く出来ますし、気を使うことも少ないのですが、たまに食べたくなる味です。

PC再起動にともなうジョブの再開

データをダウンロードするシェルスクリプト one_DL を作成しました。このone_DLについては後日言及することも有るかもしれませんが、とりあえず

1) 計測データをダウンロードするためのもので、実行には20秒程度必要とする。

2) 180秒に1回程度よりは頻繁に、繰り返し実行し続けなくてはならない。

という性質のものであると考えてください。

繰り返し実行するために、10秒間隔にジョブを実行する で作成したinterval_jobを使用して

 interval_job interval=175 job=one_DL

というコマンドを作成し、continuous_download.sh と名前を付けました。

この continuous_download.sh を rc.local に登録しておけば「PCの再起動に伴い自動的に continuous_download.sh も再起動してくれる」と思いきや、そうはなりませんでした。

ubuntu 16.04ではrc.localは無効化されており、systemd と呼ばれるシステムによりブート処理をしているのだそうです。何でもsystemctl とか何とかで登録するのだそうですが、うまくゆきませんでした。

systemd については改めて勉強するとして、continuous_download.sh の中身を

 

 kill `pgrep interval_job`

 kill `pgrep one_DL`

 interval_job interval=175 job=one_DL

 に変更し、crontab に登録することにしました。

user@Virtual-Ubuntu01:~/デスクトップ$ crontab -l
PATH=/home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# m h dom mon dow command
33 */1 * * * /home/user/MyDoc/音声/continuous-download.sh

すなわち毎時33分になると、まず現在実行中のinterval_job がkill されます。その瞬間、たまたまone_DL が実行中ではない「待ち」状態ならば、すぐに次のinterval_job が再起動されることになります(CASE 1)。

あるいは、実行中のinterval_job がkill された瞬間、one_DL が実行中であれば、続けて one_DL もkill した後に次のinterval_job が再起動されることとなります(CASE 2)。これにより one_DL の二重起動を防止することができます。

最後にPCの電源が投入された場合ですが( CASE 3 )、rc.local が有効であったりsystemd の使い方を知っていたならば、Power On の直後速やかにinterval_job も起動してくれるのでしょうが、この作り方では電源を再投入した後、最初の33分が到来すると同時に interval_job も起動することとなります。

f:id:S_E_Hyphen:20171111155416j:plain

一方で、電源OnOffとは別の想定外の理由で、例えば interval_job がハングアップしてしまったとしましょう。その場合、systemd を使用した作り付けでは人間が気付くまで欠測は継続します。

しかしcrontabを使用する場合、ハングアップが発生した次の33分に新たな interval_job が実行されますので、欠測は最長1時間ということになります。

実行するジョブの堅牢性に自信が無い場合は、むしろcrontabを使用する方が良いのかも知れません。

 

RMS値の算出

2バイト長整数を羅列しただけのバイナリファイルからRMS値を算出するには、

rms=`cat temp.raw |\
od -w2 -t d2 -v -An |\
awk '{m+=$1^2} END{print sqrt(m/NR);}'`

echo $rms

だけです。

-w2 は2バイトずつ読み込む、-t d2 は符号付2バイト長整数、 -v は繰り返し省略禁止、-Anはオフセットアドレスの非表示を意味するオプションです。

このあたりのオプションを使いこなせば4バイト長整数や浮動小数点数も計算可能だと思います。またヘッダーやフッターがあってもddコマンドが利用可能です。

 

当初SCILABを使用しました。SCILABでも配列Xに所望のファイルを読み込んだとすると

sqrt(x'*x/size(x,1))

だけで求めることができます。ですから起動さえしてしまえば結構速いのですが、SCILAB自体の起動に時間がかかってしまうため、繰り返しが多い用途には不向きでした。

 

また、bcでも累乗や平方根は計算できるので、オクタルダンプしてforループでbcを回してみました。しかし、これもループに結構時間がかかったため断念しました。

 

その点、awkだと速いし、行数は少ないし、コンパイルしないで済むし、良いことづくめです。

 

「らじる☆らじる」の音声ファイル名と放送時刻の対応

以前「新しい「らじる☆らじる」 録音方法の提案 」でも紹介したように、らじる☆らじるから配信される音声ファイルは1644.tsのように整数値.tsといったファイル名からなっています。このファイル名と放送時刻を対応付けることができないものかと考えました。

ダウンロードをしばらく続けているうちに、このファイル名は下図のように0から始まって1999までインクリメントされると、再び0に戻るということが分かりました。一つのファイルが10.24秒の音声からなっていますので、約20000秒ごとに同じファイル名が繰り返されるということです。

f:id:S_E_Hyphen:20171106144537j:plain

まず11月4日12時の時報が1308.tsというファイルに含まれていたとします。これは放送局に依存するかも知れませんので、実際に時報と合わせて確認する必要があります。このような場合11月4日12時03分00秒に放送されたファイルは1326.tsだろうということは、なんとなく予想できます。

では今日2017年11月6日15時00分00秒の時報が含まれるファイル名は、

kijun_time="2017-11-4 12:00"
kijun_file=1308
now=`date -d "2017-11-06 15:00:00" +'%s'`
kijun=`date -d "$kijun_time" +'%s'`
diff=`bc << _BC_
( $now - $kijun ) /10.24
_BC_`
now_file=`bc << _BC_
( $kijun_file + $diff ) % 2000
_BC_`

echo $now_file

 で求めることができます。上記のスクリプトを実行すると1237.tsとなります。

これを踏まえて、1225.tsというファイルが放送される時刻を求めようとするならば、

file=1225

file_diff=`bc << _BC_
( 2000 + $now_file - $file ) % 2000
_BC_`
file_time=`bc << _BC_
$kijun + ( $diff - $file_diff ) * 10.24
_BC_`
date -d "@"$file_time +'%F %T'

を用います。14時57分50秒と予測されます。

以上を一般化して下記のスクリプトによりダウンロード時刻直近の任意のファイル番号の放送時刻が推定可能となりそうです。スクリプト名をfile2clockとするならば、

file2clock file=1225 のようにして実行します。

 


  

#!/bin/bash
file=`getparstr $# "$*" "file"`
kijun_time="2017-11-4 12:00"
kijun_file=1308
now_time=`date +'%F %T'`

now=`date -d "$now_time" +'%s'`
kijun=`date -d "$kijun_time" +'%s'`
diff=`bc << _BC_
( $now - $kijun ) /10.24
_BC_`
now_file=`bc << _BC_
( $kijun_file + $diff ) % 2000
_BC_`

file_diff=`bc << _BC_
( 2000 + $now_file - $file ) % 2000
_BC_`
file_time=`bc << _BC_
$kijun + ( $diff - $file_diff ) * 10.24
_BC_`
date -d "@"$file_time +'%F %T'