pythonの学習をするにあたって開発エンジニアではない私のようなインフラエンジニアでも
すごくわかりやすく説明してくれるudemyのpython講座をお勧めしたい
特に講師の酒井潤さんは話し方も聞き取りやすく内容もかなり広い部分を網羅しているので、
実際にコードスタイルにも言及していたり実務的なナレッジも学べるのでありがたい
(※個人的にはこういうのはあまり市販の本を読んでもわからないとことだと思う)
その課題の中にQ&Aでロボットがお勧めのレストランを聞いてきてその答えをCSVに書き出して答えの数をカウントアップしていくという課題があるのだがこれが難しい。。。
正直ここで一度挫折して投げたのだが最近また別件でPythonを触れる機会がありまた勉強意欲が再燃した
まだ先の課題の完成には程遠いがCSVにカウントアップされる処理について根底の部分はできたので、
自分がハマったところについて備忘録として残しておく。
【はまった部分】
まずCSV上で入力した内容のカウントアップという処理ができない。
ググってみたところ色々な人が同じ内容で悩んでいて世界は狭いんだなあと実感した
具体的にはCSVでファイルを読みだした時にそのままファイルに書き込もうとしてもできない
よく考えれば読み出す時点でreadモードでopenメソッドを呼び出しているので
そのまま書き込めるわけがないのだが、ここら辺は同じことではまっている人が何人かいた。
なので読み出した時点で読み出した内容を変数に書き出して
その書き出した変数を処理の最後にまとめてCSVへ書き込むということをしないといけない。
よって具体的な処理の流れは以下の通りとなる
-
- 出力するCSVファイルが存在するかしないか?
- 1-1. 存在する場合
最初に存在するCSVファイルを全行読み込む
- 1-1-1. もし既にキーが存在したらそのキーのバリューをカウントアップして変数に格納して最後にまとめてCSVへ書き出し
- 1-1-2. キーが存在しなかったら新規にキーとバリューをCSVへ書き出し
- 1-2. 存在しない場合 新規にCSVを作成する→この処理は上記のudemyのpython講座で説明されているため簡単
以上を踏まえて以下のようなコードを書いてみた
import csv
import os
from termcolor import colored
while True:
print(colored('=' * 20, 'green'))
print(colored('どこのレストランが好きですか?', 'green'))
print(colored('=' * 20, 'green'))
name = input()
name = name.title()
if name:
break
#CSVを新規に作成するためのメソッド
def new_csv():
with open('data.csv', 'w', newline='', encoding='utf-8') as csv_file:
fieldnames = ['Name', 'Count']
writer = csv.DictWriter(csv_file,fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'Name': name,'Count': 1})
#data変数を最後にCSVへ書き出すためのメソッド
def csv_output():
with open('data.csv', 'w', newline='', encoding='utf-8') as csv_file:
fieldnames = ['Name', 'Count']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
data_sorted = sorted(data, key=lambda x: int(x['Count']),reverse=True)
writer.writerows(data_sorted)
#CSVへ新しいデータを追記するためのメソッド
def csv_appending():
with open('data.csv', 'a', newline='', encoding='utf-8') as csv_file:
fieldnames = ['Name', 'Count']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writerow({'Name': name,'Count': 1})
"""
data.csvが存在すればdata変数にCSVの内容を読み込み
存在しなければnew_csvメソッドをcall
"""
if os.path.exists('data.csv'):
with open('data.csv', 'r', newline='', encoding='utf-8') as csv_file:
reader =csv.DictReader(csv_file)
data = [row for row in reader]
# 既にキーが存在すればカウントアップ、一通りループを回して存在しなければcsv_appendingメソッドを呼び出し
for row in data:
if row['Name'] == name:
row['Count'] = int(row['Count']) + 1
csv_output()
break
else:
csv_appending()
else:
new_csv()
一旦これでやりたいことはできているが、多分もっといい書き方があると思う。
あとオブジェクト指向?MVCフレームワーク?って感じなのでもう少しなれたらもっと洗練されたかっこいいコードが書けると思うが一旦ベースのロジックの部分はできているのであとは如何に拡張性とか視認性とかを上げていくかという部分かなと思う。
他には作成したCSVファイルを最終的に集計するなんて処理を追加しても面白いかも。。。
個人的にはこうするとコードもっと良くなりますよってアドバイスが欲しいです!!
ありがとうございました。