31年目のRealize

プログラミング、イラスト、家族の事を書いたりするブログにする予定

プログラミング修行中

何にしてもプログラミング

インフラからフロントエンドまで、色々できるようになりたいとは言っても、まずはプログラミングスキルが無いと転職もできない、ということで力を入れないといけない。

アウトプットしていく

年末から時間を見つけては競技プログラミングの問題を解いていました。 数をこなすのはいいけど、自分のコードを見直したり、レベル高い人のコードと比べたりして復習の時間も必要…ということでアウトプットしながら頭の中を整理していく習慣をつける!

今回のアウトプット

競技プログラミングとは別で、Udemyで購入したシリコンバレー流のpythonコードスタイルを学ぶ!という動画も視聴進めています。そちらもかなりインプットが溜まっているので、整理整理。

CSVファイルの読み込み、書き込み

よく使いそうな処理をピックアップして書いてみます。

configファイルでcsvファイルパスを指定

configparserパッケージを使ってみます。 まずは、config.iniファイルを作成。

import configparser

# ConfigParserクラスのオブジェクトを作成
config = configparser.ConfigParser()

# 辞書形式でカテゴリと各要素を指定
config['CSV_FILE'] = {
    'path': 'tmp/',
    'name': 'counter.csv',
}

# config.iniファイルを新規作成し、writeメソッドにオブジェクトを渡し書き込む
# ファイルのclose忘れを防止するため、withステートメントを使用している
with open('config.ini','w') as config_file:
    config.write(config_file)

これで出来上がったconfig.iniファイルの中身が以下。

[CSV_FILE]
path = tmp/
name = counter.csv

csvファイルの存在を確認、無ければ新規作成

CsvModelというクラスを作って、オブジェクト生成時に存在確認する。

class CsvModel():
    def __init__(self):
        self.csv_file = self.get_csv_file_path()
        
        # csvファイルが存在しなかったら新規作成
        if not os.path.exists(self.csv_file):
            pathlib.Path(self.csv_file).touch()
        
        self.header = [CSV_HEADER_NAME, CSV_HEADER_COUNT]

        # csvデータの格納領域を作っておく。
        # (keyがない場合、int型のデフォルト値(0)が設定される、defaultdictオブジェクト)
        self.data = collections.defaultdict(int)
        self.load_data()

get_csv_file_pathメソッドでは、configparserを使ってconfigファイルの内容を読み込み、csvのパスを返すようにしている。

    def get_csv_file_path(self):
        config = configparser.ConfigParser()
        config.read(CONFIG_FILE)
        return config['CSV_FILE']['path'] + config['CSV_FILE']['name']

また、load_dataメソッドでは、既にcsvファイルが存在していた場合、オブジェクト生成時にcsvの内容を読み込む。

    def load_data(self):
        with open(self.csv_file, 'r+') as csv_file:
            reader = csv.DictReader(csv_file)
            for row in reader:
                self.data[row[CSV_HEADER_NAME]] = int(row[CSV_HEADER_COUNT])
        return self.data

csvファイルにデータを書き込む

csvパッケージのDictWriterを使うと簡単!

    def save(self):
        with open(self.csv_file,'w+') as csv_file:
            # DictWriterを使うと、辞書形式でcsvファイルに書き込める
            writer = csv.DictWriter(csv_file,fieldnames=self.header)
            writer.writeheader()
            for name, count in self.data.items():
                writer.writerow({
                    CSV_HEADER_NAME: name,
                    CSV_HEADER_COUNT: count
                })

csvファイルに書き込むデータを作成

csvのカラムNAMEを指定したら、対応するCOUNTカラムの値が増えていくメソッドを作成。

    def increment(self, name):
        self.data[name] += 1
        self.save()

ではこれを使ってcsvファイルに書き込もう!

import csvmodel

csv_file = csvmodel.CsvModel()
csv_file.increment('rabbit')
csv_file.increment('cat')
csv_file.increment('dog')
csv_file.increment('rabbit')

結果は…

NAME,COUNT
rabbit,2
cat,1
dog,1

できました!

動画の演習内容をもとに自分なりにカスタマイズしたけど、色々と歪な設計になってしまったような気がするorz

オブジェクト指向的なコーディングも鍛えなきゃ…。

一応、読み込みも確認のため、別のオブジェクト生成してみる。

csv_file2 = csvmodel.CsvModel()
csv_file2.increment('rabbit')
csv_file2.increment('cat')
csv_file2.increment('rabbit')
csv_file2.increment('rabbit')

NAME,COUNT
rabbit,5
cat,2
dog,1

あってます。

家族が増えました

全然関係ないですが、癒しのため。