jsonファイルをパースして処理するサンプル

叡王戦で公開されている棋譜JSONをkif形式のファイルに変換するスクリプトを書いてみた。
いろいろ未完成で適当だがShougGUIで読み込めたのでまぁ良しとする。

```bash
python3 json2kif.py <URL> kif.json a.kif
```

```py:json2kif.py
# -*- coding: utf-8 -*-
from logging import getLogger, StreamHandler, DEBUG

import sys
import os
import json
import unicodedata
import re
import urllib.request

# ログ出力のための print と import logging はやめてほしい - Qiita
# https://qiita.com/amedama/items/b856b2f30c2f38665701

logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False


class FileWriter:
    filename = None
    tiow = None

    def __init__(self, fname):
        self.filename = fname
        self.tiow = open(self.filename, mode='a', encoding="utf-8")

    def write(self, msg):
        self.tiow.write(msg + "\n")

    def __del__(self):
        self.tiow.close()


def file_download(url, filename):
    """
    :param url:
    :param filename:
    :return:
    """
    urllib.request.urlretrieve(url, filename)


def get_east_asian_width_count(text):
    """
    Pythonで半角1文字、全角2文字として文字数（幅）カウント | note.nkmk.me
    https://note.nkmk.me/python-unicodedata-east-asian-width-count/

    :param text:
    :return:
    """
    count = 0
    for c in text:
        if unicodedata.east_asian_width(c) in 'FWA':
            count += 2
        else:
            count += 1
    return count


def space_ume(text):
    """
    12byteまで半角スペースで埋める
    :param text:
    :return:
    """
    for i in range(10):
        if get_east_asian_width_count(text) >= 12:
            break
        text = "{} ".format(text)
    return text


def main():
    args = sys.argv
    url = args[1]
    json_path = args[2]
    kif_path = args[3]

    file_download(url, json_path)

    # json.loadsでjsonを読み込み、for ループで特定の要素を抜き出すサンプル - Database JUNKY
    # https://hit.hateblo.jp/entry/python3/json
    f = open(json_path, 'r', encoding="utf-8")
    json_dict = json.load(f)

    if os.path.exists(kif_path):
        os.remove(kif_path)
    tiow = FileWriter(kif_path)

    outlist = list(['# --- 棋譜解説 V1.70 棋譜ファイル ---'])
    outlist.append("開始時刻：{}".format(json_dict['data'][0]['starttime']))
    outlist.append("終了時刻：{}".format(json_dict['data'][0]['endtime']))
    outlist.append("棋戦：{}".format(json_dict['data'][0]['event']))
    outlist.append("持ち時間：{}時間".format(json_dict['data'][0]['timelimit']))
    outlist.append("場所：{}".format(json_dict['data'][0]['place']))
    outlist.append("備考：{}".format(json_dict['data'][0]['note'].strip()))
    outlist.append("振り駒：あり")
    outlist.append("計測時方式：{}".format(json_dict['data'][0]['gametype']))
    outlist.append("秒読み：{}".format(json_dict['data'][0]['countdown']))
    dinnertime_start = json_dict['data'][0]['dinnertime_start']
    dinnertime_end = json_dict['data'][0]['dinnertime_end']
    outlist.append("夕食休憩：{}～{}".format(dinnertime_start, dinnertime_end))
    outlist.append("封じ手手数：0")
    outlist.append("手合割：{}".format(json_dict['data'][0]['handicap']))
    outlist.append("先手：{}".format(json_dict['data'][0]['player1']))
    outlist.append("後手：{}".format(json_dict['data'][0]['player2']))
    outlist.append("手数----指手---------消費時間--")

    for item in outlist:
        tiow.write(item)

    for key in json_dict['data'][0]['kif']:
        move = key['move']

        # 左成、右成から左右を削除
        # move.replace('左', '') # これは効かない
        move = re.sub(r'左', '', move)
        move = re.sub(r'右', '', move)

        if move == "投了":
            break

        if len(move) == 2:
            m = move
            m = "{}{}{}".format(m[:1], "　", m[1:])
            move = m

        if key['frY'] == 0 or key['frY'] == 10:
            move = "{}{}".format(move, "打")
        else:
            xy = key['frX'] * 10 + key['frY']
            move = "{}({})".format(move, xy)

        move = space_ume(move)

        tiow.write("{:4d} {:<8} ({})".format(key['num'], move, " 0:00/00:00:00"))


if __name__ == "__main__":
    main()

```