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の配布元

全般的な解説所

これも良い解説してる

SQLite が認識できる SQL

色々有って飽きない

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 これが最長みたい。こんなコールサインは 嫌だな。

やっぱり考える事は同じで、 最長のコールサイン最短のコールサインコールサイン秘話が、面白いです。 ついでに商用局のコールサインも載せておきます。