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 これが最長みたい。こんなコールサインは 嫌だな。
やっぱり考える事は同じで、 最長のコールサインや 最短のコールサイン等 コールサイン秘話が、面白いです。 ついでに商用局のコールサインも載せておきます。