My/Ham/Log (3)
前回は枕でリークしてやるって、よた話を書いたけど、ここでもリークされてました。
リークはYoutubeで、てのが定番。まだ、本家には 出てない模様。 このおっさんひょっとして、しゃちょさん?
そしてこんなのも
気の早い人は、予想価格を上げている。年末に発売とか。しっかり貯金しましょう。
$800 KX3 10W Transceiver $130 KXFLE Roofing Filter Module (500/1500/2700/3800 Hz) $160 KXAT3 Internal, Wide-Range 20-W Automatic Antenna Tuner $120 KXAM3 Broadcast Band Filter Module (0.5-1.6 MHz) $50 KXBT3 Internal 8-AA Cell Battery Pack with NiMH Charger $80 KXPD3 Precision Keyer Paddle $20 KXMM3 Mobile Mount Bracket $60 MH3 Hand Microphone with UP/DN Controls $40 KUSB RS232 to USB Adapter $400 KXPA100 High-Performance 160-6 meter, 100-W Amplifier; $250 KXAT100 Wide-Range 100-W ATU
これで、1.8-50MHzのオールモード・ハンディー機が手に入るなら、FT-817との住み分けはいかに?
sqlite3
sqlite3は手軽に使えるので、愛好者も多い。よって、ネットを探せばいろいろな解説サイトに行き当たると 思うけど、例によって、リンクを幾つか載せておく。
sqlite3を使ってみる
前回、コールサインの入力ミスチェックをどうしようって、プチ思い悩んだ。簡単に思いつくのは、 正規表現の技だけど、真面目に考えると破綻するのは目に見えている。
ならば、コールサインが登録されてるか、総務省のデータベースから引いて来るって手があるな。 でも、日本以外はどうよ。そんなデータベースを公開してくれてる所ってあるんか?識者に相談して みた所、 http://www.supercheckpartial.com/を紹介頂けた。やっぱり、 同好の士は居るのね。これを使えば、各国のコールサインのパターンが分かるな。 早速、MASTER.SCPと言うASCIIフォーマットのデータを頂いてきた。4万局も網羅されてるよ。
sqlite3の使用も兼ねて、登録してみるかな。このファイルの元データは、こんな感じね。
# # RELEASE 2011.05.21.00 # by Bob Raymond, WA1Z # 2E0AOZ 2E0BFJ : ZZ5Z ZZ6Z
種のDBは出来上がっているとして、そこに上記の4万局余りを追加してみよう。これだけのデータが有れば、 優に『読売1万局アワード』を、4回は貰えるはずだから、十分だろう。
import sqlite3 from random import randint,shuffle import datetime DB = 'JA8IOC.db' SEED = 'MASTER.SCP' BAND = ['3.5', '7', '10', '14', '18', '21', '24', '28', '50'] MODE = ['CW', 'SSB', 'AM', 'FM', 'RTTY'] con = sqlite3.connect(DB) cur = con.cursor() now = datetime.datetime.today() with open(SEED) as f: all = f.readlines() shuffle(all) sn = 0 for cs in all: callsign = cs.rstrip('\n') old = now - datetime.timedelta(randint(0,3650), randint(0,86399)) utc = old.strftime("%Y-%m-%d %H:%M:%S") mode = MODE[randint(0,4)] band = BAND[randint(0,8)] rcvd = randint(111,599) send = randint(111,599) comment = 'Serial Number is {0}.'.format(sn) cur.execute( "INSERT INTO qsolog VALUES(datetime('{0}'),?,?,?,?,?,?)".format(utc), (callsign,rcvd,send,band,mode,comment)) if sn % 1000 == 0: print(sn) con.commit() sn += 1 con.commit() cur.close() con.close()
リアリティーを出す為、コールサインは、一気読みした後、トランプ宜しくシャッフルしておいた。 交信日時は、現在から過去10年以内で、ランダムな日時を発生させた。乱数はrandintで、下限と上限を 指定して発生出来るのね。これ、わりとしゃれった機能じゃん。 modeとかbandは、表を引くようにした。
最初、一件毎にコミットしてたら、全件の登録まで、21分もかかってしまったけど、1000件まとめて コミットするようにしたら、10秒で終わった。コミットってオーバーヘッドの大きな操作なんだな。 みずほ銀行のバッチがさっぱり終わらなかったのは、こういう事だったのね。
そうそう、最初登録した時、utcとCallsignが欠落した状態で登録されちゃった。何で何でと思って debggerを立ち上げて、DBに渡るデータを確認したら、コールサインの終端にCRコードが紛れていた。 これを取り除いてから走らせたら、正常に登録出来た。危うく嵌まる所だったわい。
そんじゃ、データベースを直接触ってみる。気分はボラクルのオペレータ。懐かしいねぇ。 まあ、おいらが良く触っていたのは、MySQLをadminMySQL(だったかな)経由だったけど。
[sakae@cdr ~/my/DB]$ sqlite3 JA8IOC.db SQLite version 3.7.6.1 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select count(callsign) from qsolog; 43281 sqlite> select * from qsolog limit 10; 2011-05-15 03:25:11|8J1RL|599|589|7|CW| 2011-05-15 03:30:17|JA0ZZZ|599|599|7|CW|試験ですよ 2011-01-08 12:34:44|SP9RI|204|502|24|FM|Serial Number is 0. 2008-06-10 21:18:41|K9NO|123|324|14|FM|Serial Number is 1. 2001-05-24 01:44:18|G3MYI|140|570|28|AM|Serial Number is 2. 2005-02-09 05:20:16|YP9W|472|325|50|RTTY|Serial Number is 3. 2006-06-21 03:21:28|NN2Y|141|347|24|FM|Serial Number is 4. 2004-08-05 05:34:49|CW3D|518|213|24|AM|Serial Number is 5. 2003-01-25 22:28:52|IZ2EID|398|560|7|CW|Serial Number is 6. 2007-06-24 11:54:29|EA5HKQ|130|351|24|AM|Serial Number is 7.
4万3千局余登録されてる。普通に参照すると、登録順に出てくるのか。これって、SQLの仕様で規定されてる のかな? 良く知らないや。で、これだけ登録されてて、ファイルのサイズはと言うと。
[sakae@cdr ~/my/DB]$ ls -lh JA8IOC.db -rw-r--r-- 1 sakae kuma 3.1M 5 25 09:05 JA8IOC.db
こんなものなんですかね。(ファイルサイズは、データ量に比例するみたい。どこかのNoSQLみたいに ガクガクしないよ)
sqlite> select * from qsolog where callsign like 'JA8__'; 2003-03-15 01:09:25|JA8NF|197|343|50|SSB|Serial Number is 8481. 2009-09-22 01:43:19|JA8LN|374|491|18|RTTY|Serial Number is 21753. 2002-04-17 01:46:36|JA8RY|346|451|50|AM|Serial Number is 22159. 2010-04-15 04:30:27|JA8WY|145|189|24|SSB|Serial Number is 32353. 2002-01-30 01:03:03|JA8QO|546|280|3.5|AM|Serial Number is 37618. 2008-10-26 15:13:07|JA8TR|381|455|14|CW|Serial Number is 40911. 2008-08-08 18:40:53|JA8ZO|268|177|7|FM|Serial Number is 41598. 2001-07-17 09:33:15|JA8MS|437|315|28|SSB|Serial Number is 43109.
これ、JA8の2文字OM様、アンダーバーは、任意の一文字。パーセントは、任意の0文字以上にマッチ。 これって、旧式な正規表現だな。
sqlite> select * from qsolog where callsign glob 'JA8[R-Z]?'; 2002-04-17 01:46:36|JA8RY|346|451|50|AM|Serial Number is 22159. 2010-04-15 04:30:27|JA8WY|145|189|24|SSB|Serial Number is 32353. 2008-10-26 15:13:07|JA8TR|381|455|14|CW|Serial Number is 40911. 2008-08-08 18:40:53|JA8ZO|268|177|7|FM|Serial Number is 41598.
glob句なら、正規表現っぽく使えるのね。こういうのは、ばりばりに方言なんだろうな。
sqlite> select count(mode) from qsolog where mode == 'CW'; 8668
こうすると、完全一致か。
sqlite> select count(callsign) from qsolog where utc between date('2010-01-01') and date('2010-12-31'); 4368
これは、去年の交信件数だな。ああ、上記の指定だと、12月31日の深夜0時となるので、晦日の交信は 含まれないんだ。これ、落とし穴。
このDBを使って、Webから登録してみたけど、さしたるストレスもなく使えた。これでsqlite3を心おきなく 使える事が判明しました。
コールサインのパターンについて
って、やけに難しそうなタイトルだけど、どうって事ないからね。仮にコールサインを正規表現もどきで(強引に) 表すとしたら、どんな風になるかなと。。。
import string SEED = 'MASTER.SCP' def pat(cs): rv = '' for c in cs: if c in string.letters: rv += 'a' elif c.isdigit(): rv += 'N' else: rv += c return rv with open(SEED) as f: all = f.readlines() result = {} for cs in all: callsign = cs.rstrip('\r\n') k = pat(callsign) if k in result: result[k] += 1 else: result[k] = 1 for k, v in sorted(result.items(), key=lambda x: x[1]): print('{0:5d} {1}'.format(v,k))
コールサインに含まれるアルファベットと数字とそれ以外(って、スラッシュしか思いあたらんけど)を、 'a' と 'N' と 文字そのものに置き換えパターン化します。そして、その件数を表示します。
例えば、JA1ABC/9 は、aaNaaa/N 。 8J1RL は、NaNaa と言った具合になります。
実行結果は長くなったけど、そのまま載せます。
1 NaNa/N 1 NaNa/a 1 aaNaNaaa 1 a/aNaaa 1 aaN/aNaaa/aa 1 aNaa/NNN 1 aNaa/aNa 1 NaN/aaNa 1 aN/aaNa 1 aaNaa/aa 1 NaN/aaNaaa 1 aaNNNaaaaa 1 aN/NaNa 1 aaNaaa/aaNaa 1 aaaNNNNNNNN 1 NaNaaaa 1 aaaNaa 1 aa/NaNa 1 aa/aaNa 1 NaN/aNaa 1 aaNaaaaa 1 NaaNaa 1 aNNNa 1 a/aaNaa 1 aNNa/a 1 aaN/NaNaa 1 aaNNNaa/a 1 aaNa/aNa 1 aN/aaNaaa/a 1 aNNaa/a 1 aN/aNaaa 1 aN/aNaa 1 NNaNNa 1 Na/aNNaa 1 aaaNa 1 aaNa/aNaa 1 aaNNNaaaa 1 aaNaaa/aa 1 NaNNNa 1 NaNaaaaa/N 1 aNaaa/aN 1 aaNNaa/N 1 aNNaaa/N 1 aaNa/aaNaaa 2 aNNaaaa 2 NaNNaa 2 NaNNNaa 2 Na/aNNa 2 aa/aaNaaa/a 2 aN/aNNaa 2 aNaa/a 2 aaNNaaaaa 3 Na/aaNa 3 NaNaaa/N 3 NaN/aaNaa 3 aaN/aaNaa/a 3 aa/aNaaa 3 aaNaa/aaN 4 NaNNa 4 Na/aNaaa 4 Na/aaNaa 4 aaNa/a 4 NaNNaaa 4 aaNaaa/aaN 5 aa/aNaa 5 aNaaa/aaN 5 aaNNNNa 5 aaNa/aN 5 aaNNNa 5 aaNNNNaaa 6 aaNNNNaa 7 aaNa/aaN 8 aNaa/aaN 8 aa/aaNaaa 8 aaNNaaaa 8 aaNaaa/aN 8 aaNNNaaa 8 Na/aaNaaa 10 aN/aaNaaa 11 aaN/aaNa 12 aaN/aNaa 12 aN/aaNaa 13 aa/aaNaa 14 aaNaa/aN 17 aaNNNaa 17 aaNaaaa 19 aaN/aNaaa 26 aaNNa 27 aaNa/N 30 aaNaa/a 30 aNaaa/a 34 aaN/aaNaa 37 aaN/aaNaaa 38 aaNaaa/a 42 aaNNaa 42 aNaaa/N 52 aNaa/N 52 aaNNaaa 55 aaNaa/N 73 aNNaaa 85 aNa 131 aaNaaa/N 158 NaNa 232 aNNa 280 NaNaaa 317 NaNaa 322 aNNaa 4122 aNaa 4402 aaNa 6696 aNaaa 10411 aaNaa 15267 aaNaaa
上位5つぐらいのパターンで大概は収まりそうだなあ。
世界にはたった3文字のコールサインが有るんだ。 どんなコールか調べてみっかな。12文字長のコールサインって、どんだけーーーー。
1 aaN/aNaaa/aa 1 aaNaaa/aaNaa 1 aaaNNNNNNNN 3 aaN/aaNaa/a 1 aN/aaNaaa/a : 1 aaaNa 232 aNNa 158 NaNa 4122 aNaa 4402 aaNa 85 aNa
上記は、スクリプトの最後の部分を下記のように変更すれば、簡単に列挙できます。
for k, v in sorted(result.items(), key=lambda x: len(x[0]), reverse=True): print('{0:5d} {1}'.format(v,k))
今月のCQ誌見てたら、13文字長のコールサインが出てた。キー叩くの嫌になるね。落語に出てくる、 『じゅげむじゅげむ...』みたいで! このコールサイン、幸い日本と中国の合作だったけど、単独で 長いのはどれぐらい? 上のデータを見たら、aaaNNNNNNNN これが最長みたい。こんなコールサインは 嫌だな。
やっぱり考える事は同じで、 最長のコールサインや 最短のコールサイン等 コールサイン秘話が、面白いです。 ついでに商用局のコールサインも載せておきます。