LoginSignup
2
3

More than 5 years have passed since last update.

PythonでCSVからC#のコンテナクラスを生成するジェネレータを作ってみた

Posted at

CSVのコンテナクラスを手動で作成するのが面倒なので
CSVの型等を自動で解析してC#のコンテナクラスを作成する
ジェネレータを作成してみました。
CSVの形式に簡単な規約があるのでご注意を。

ちなみにPythonは勉強し始めたばかりなので
コードがおかしい所があるかもしれません。
その場合はご指摘いただけると非常に助かります。

元となるCSV

こんな感じになります。

test_csv.csv
id,key1,key2,key3
1,テスト1,1.0,1,
2,テスト2,2.0,2,
3,テスト3,3.0,3,

一番上の行がkeyの名前。これが変数名となります。
あとは2番目の行からはcsvのデータの中身を入れてください。

ジェネレート結果

CSVContainerTestCsv.cs
using System.Collections;
using System.Collections.Generic;

namespace CSVContainer
{
    //コンテナの実データ
    public class TestCsv
    {
        public int       id{ get; private set;}
        public string    key1{ get; private set;}
        public float     key2{ get; private set;}
        public int       key3{ get; private set;}
    }

}

こんな感じになります。
色々と便利なのでnamespaceで囲ってあります。

クラス名はCSVのファイル名をキャメルケースにしたものに、
.cs名は「CSVContainer」+クラス名にしています。

Pythonコード

CSVContainerGenerator.py
# -*- coding: utf-8 -*-

import glob
import os.path

def convert(file):
    count = 0
    culam = ""
    val = ""

    for line in open(file, 'r'):
        if count == 0:
            culam = line
            count += 1
        else:
            val = line
            break

    out_put(file, culam, val)


def out_put(file, culam, val):
    file_name = os.path.basename(file)
    base_name = file_name.replace(".csv","")
    cs_name = "CSVContainer" + to_camel_case(base_name) + ".cs"
    f = create_file(cs_name, base_name)
    create_class(culam, val, f, to_camel_case(base_name))
    # print file_name


def create_file(file, base_name):
    f = open(file, 'w')
    f.write("using System.Collections;\n")
    f.write("using System.Collections.Generic;\n")
    f.write("\n")
    f.write("namespace CSVContainer\n")
    f.write("{\n")
    f.write("\t//コンテナの実データ\n")
    f.write("\tpublic class "+to_camel_case(base_name)+"\n")

    return f

def create_class(culam, val, f, base_name):
    f.write("\t{\n")
    culams = culam.split(",")
    vals = val.split(",")
    for i, v in enumerate(culams):
        type_str = ""

        if vals[i].find('.') != -1:
            type_str = "float\t"
        elif vals[i].isdigit():
            type_str = "int\t\t"
        else :
            type_str = "string\t"

        v = v.replace("\n", "")
        v = v.replace("¥n", "")


        f.write("\t\tpublic " + type_str + " " + v + "{ get; private set;}\n")

    f.write("\t}\n")
    f.write("\n")
    f.write("}\n")

def to_camel_case(text):
    text = text.lower()
    text = text.capitalize()

    while '_' in text:
        ix = text.index('_')
        next = text[ix + 1].upper()
        text = text[0:ix] + next + text[ix + 2:]
    return text


for file in glob.glob('CSV/*.csv'):
    print "conv  " , file
    convert(file)

現状はCSVディレクトリにあるCSVを見に行くようにしています。
出力先はpyコードと同階層です。
この辺りは、適度にいじっていただければと。
ディレクトリを直値にしているのは、正直怠けです。

以上

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3