郵便番号から住所検索(Python版)

ここ2週間ほど、平日は毎日12時間平均で仕事のデバッグをやっていたため、かなり心身が疲れきってしまった。ある変数の値がどこでおかしくなるかを確認するために、ひたすらコードの中でwriteしていった。
以前『デバッグが256倍速くなるテクニック』とかいう本を読んだのを思い出し、今こそそのテクニックを活用すべし、とふと思ったが肝心の内容が思い出せなかった。あとで家の本棚を探して読み返してみよう。
まあ、仕事内容は嫌なことをやっているわけではないので、疲れるけれどもストレスは無いと思う。幸せなことだ。でも、さすがに突発的な徹夜はするべきでないということを改めて実感した。間違いなく寿命が縮む。眠気との戦いというより飢えとの戦いだったなー。

デバッグが終わって落ち着いたので、久しぶりにpythonでコードを書くことにする。しばらく書いてないとやはり忘れてしまう。リストってどう書くのだったっけ、と迷ってしまった。思い出すのに5秒かかった。一度書き始めるといろいろなことをすぐに思い出せたけど。
日経ソフトウェア2009年12月号』の特別付録に『かんたん10分プログラミングレシピ』という冊子が付いている。その内容は、実用的であるが簡単なプログラムを紹介している。その中ではVBPHPで実装しているが、これをPythonでやってみることに。いろいろな発見があることを期待。

今回は、郵便番号から住所を検索するプログラム。

  • 日本全国の郵便番号を入力すると住所を表示するプログラムを作る。
  • データファイルは日本郵便のWebページからダウンロードする。
  • wxPythonのライブラリを利用。

全国一括のデータファイル(KEN_ALL.csv)をダウンロードする(下図)。

これは、CSVのファイルで12万行以上ある。日本全土の郵便番号と住所が載っているので、ここから郵便番号に対応する住所を引っ張ってくる。
下図は起動画面。この画面を移動させると、たまにフリーズする。
コードのどこかに問題があるかもしれない。

郵便番号を入力すると、

検索結果のダイアログが開く。

検索速度も気にならない程度だ。コードの大枠の作成は15分程度でできたが、日本語処理にハマった。ダイアログに日本語の表示がなかなかできなかった。UnicodeEncodeError、怖い。

以下はソースコード

# coding: utf-8
import wx
import sys

file_name = "KEN_ALL.csv"

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        width, height = 300, 100
        wx.Frame.__init__(self, id, title=u"郵便番号から住所を検索",
                          size=wx.Size(width, height))
        self.Pan = wx.Panel(self, -1)
        Hsizer = wx.BoxSizer(wx.HORIZONTAL)
        Vsizer = wx.BoxSizer(wx.VERTICAL)

        StTxt1 = wx.StaticText(self.Pan, -1, u"郵便番号を入力してください")
        self.TxtCtrl = wx.TextCtrl(self.Pan, -1, "", size=(200, -1))
        self.RBtn1 = wx.Button(self.Pan, -1, u"検索")
        self.RBtn1.Bind(wx.EVT_BUTTON, self.showAddress)

        Vsizer.Add(StTxt1, 0, wx.ALL, 2)
        Hsizer.Add(self.TxtCtrl, 0, wx.ALL, 2)
        Hsizer.Add(self.RBtn1,   0, wx.ALL, 2)
        Vsizer.Add(Hsizer, 0, wx.ALL, 2)
        self.Pan.SetSizer(Vsizer)
        Vsizer.Fit(self.Pan)

    def showAddress(self, event):
        inputZipCode = self.TxtCtrl.GetValue()
        address = self.getAddress(inputZipCode)
        if address == "":
            dlg = wx.MessageDialog(self.Pan, u"データベースには存在しません",
                                   u"住所の検索結果",
                                   style=wx.ICON_INFORMATION)
        else:
            addr = address.decode(sys.stdin.encoding)
            dlg = wx.MessageDialog(self.Pan, addr,
                                   u"住所の検索結果",
                                   style=wx.ICON_INFORMATION)
        answer = dlg.ShowModal()
        if answer == wx.ID_OK:
            dlg.Destroy()


    def getAddress(self, inputZipCode):
        indata = open(file_name, 'r')
        dataList = indata.read().splitlines()
        totalDataNumber = len(dataList)
        address = ""

        for i in xrange(totalDataNumber):
            zipCode = dataList[i].split('","')[1]
            if zipCode == inputZipCode:
                address = dataList[i].split('","')[5]+\
                          dataList[i].split('","')[6]+\
                          dataList[i].split('","')[7].split('"')[0]
        return address

class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = Application(0)
    app.MainLoop()

if __name__ == '__main__':
    main()

日経ソフトウエア 2009年 12月号 [雑誌]
日経ソフトウエア 2009年 12月号 [雑誌]日経ソフトウエア

日経BP出版センター 2009-10-24
売り上げランキング :


Amazonで詳しく見る
by G-Tools
ひなた先生が教えるデバッグが256倍速くなるテクニック (Software Design Books)
ひなた先生が教えるデバッグが256倍速くなるテクニック (Software Design Books)
おすすめ平均
stars有用ではない内容
stars説明が会話調。読みやすい。
stars後半はネタ切れ感を否めない
starsタイトル負けかな?
stars久しぶりに面白かった技術書、著者に乾杯を。

Amazonで詳しく見る
by G-Tools