MetaData収集ひな形（PysimpleGUI,HTML）

##はじめに

データを収集するとき、そのデータの説明であるメタデータも同時に収集することが重要です。データを提供してくれる人に「データの説明をつけてください」とお願いしてもなかなか難しいので、こちらであらかじめデータ説明のテンプレートをつける必要があります。もっとも簡単なのはEXCELですが、フォーマットが勝手に変えられていたりと意外に、そのあとの処理が面倒なことがあります。

そこで、（1）HTMLのFileAPIとJavascriptを用いて、オフラインで必要な情報を入れることができるHTMLファイルを配り、情報を入れてJSONファイルにして出力するひな形と（2）PysimpleGUIで作成したひな形、を覚えとして記載します。

##環境（Python）
Win10Pro
Anaconda
Python3.7

Visual studio code

インストールモジュール
PySimpleGUI



## HTML + Javascript
HTMLのFileAPIとJavascriptを用いて、オフラインで必要な情報を入れるHTMLファイルを配り、情報を入れてJSONファイルにして提供してもらうタイプ。
参考：
(1) [JavaScriptのオブジェクト（連想配列）をjsonファイルとしてダウンロードする]
(https://diwao.com/2017/06/js-object-file-download.html)
(2) [JavaScriptでファイル操作！？ File APIを使いこなそう (1/2)]
(http://www.atmarkit.co.jp/ait/articles/1112/16/news135.html)
(3) [Blob と File クラスについて]
(https://hakuhin.jp/js/file.html#FILE_00)

参考（1）をほぼコピーペーストしただけです。

```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>

<body>
    <div id="json_root">
        <ul id="base">
            <li>
                <label for="name"> Name:</label>
                <input type="text" id="name" placeholder="input name" />
            </li>
            <li>
                <label for="description"> description:</label>
                <input type="text" id="description" placeholder="description" />
            </li>
            <li>
                <label for="filename"> File Name:</label>
                <input type="text" id="filename" placeholder="file name" />
            </li>
            <li>
                <label for="comment"> comment:</label>
                <input type="text" id="comment" placeholder="comment" />
            </li>
        </ul>
    </div>

    <button id="download">ダウンロード</button>

    <script type="text/javascript">
        window.onload = () => {
            const download = document.getElementById('download');
            const getData = () => {
                return {
                    name: document.getElementById('name').value,
                    description: document.getElementById('description').value,
                    filename: document.getElementById('filename').value,
                    comment: document.getElementById('comment').value,
                };
            };

            download.addEventListener('click', function() {
                const data = getData();
                const blob = new Blob([JSON.stringify(data, null, '  ')], {
                    type: 'application\/json'
                });
                const url = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                link.download = document.getElementById('name').value + '.json';
                link.click();
                URL.revokeObjectURL(url);
            });
        };
    </script>
</body>

</html>
```

実行すると以下のようになります。
![meta00.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/51756fe8-e0ee-ce7b-10ff-d3b0a7b176bc.jpeg)



## Python

あまりHTML、Javascriptが得意ではないので、それと同じ機能をPysimpleGUIで作成しました。配布するにはexe形式にするのが良いのですが、なかなか面倒なので今回はそのままです。

```python
"""
Metadata -> JSON

"""
import re
from pathlib import Path
import json

import PySimpleGUI as sg

sg.theme('Light Blue 2')

# MetaDataにしたいKeyのリストを作成
key_lists = ['name','description','filename', 'comment']

layout_list = []
for key_name in key_lists:
    temp =[]
    temp = [sg.Text(f'{key_name}', size=(12, 2)),sg.InputText(size=(60, 2),key=f'-{key_name}-')]
    layout_list.append(temp)
layout_list.append([sg.Text('Save path', size=(12, 2)),sg.InputText(default_text='./data',key='-savepath-')])
layout_list.append([sg.Submit(), sg.Cancel()])

window = sg.Window('Metadata to JSON', layout_list)

while True:
    event, values = window.read()
    if event in (None, 'Cancel'):
        break
    elif event in 'Submit':
        
        data_dict ={}
        for i in key_lists:
            
            #この辺りは好きにアレンジ
            # タブや改行は削除
            data_value =re.sub('\t|\n', '', values[f'-{i}-'])
            # data_value = ' '.join(data_value.splitlines())
            
            # 先頭の空白だけ削除
            data_dict[f'{i}'] = data_value.lstrip() 
        
        # print(f'Data: {data_dict}')
        
        # Save Path & save name
        Path(values['-savepath-']).mkdir(exist_ok=True)
        file_name = '{}/{}.json'.format(values['-savepath-'],data_dict[key_lists[0]])
        
        # 辞書型をJSONに変換してSave
        with open(file_name, 'w') as f:
            json.dump(data_dict, f, indent=4)
            
        # 入力されているデータをクリア
        for key_name in key_lists:
            window[f'-{key_name}-'].update('')
            
window.close()

```

実行するとGUIが立ち上がります。
![meta01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/44b795c3-773b-541c-c58d-e0cbb377af74.jpeg)


メタデータを入力してSubmitを押すとJSONファイルが作成されて、入力したデータがクリアーされます。

![meta02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/6eecb293-98ed-33fc-37ff-da3b654de03d.jpeg)


メタデータはJSON形式で保存されます。
![meta03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/39479f82-92f4-e1d1-bed2-2631bd868258.jpeg)


JSON形式で保存されているので、後の処理は簡単にできるのではないでしょうか？YAMLファイル形式でもよいかもしれません。



##まとめ

データ分析を行う上でメタデータは重要ですが、それを集めて整理するのはなかなか面倒です。PysimpleGUIをコンパイルして配ることを考えるとhtmlファイルの配布の方がやっぱり楽かな。