Pythonをすこし転がした話
はじめに
プログラミング頻度月2,3回くらいの理系大学生がAI片手にPython触ったよっていう話です.先のロードバイクの記事に同じくこれも備忘録を兼ねて.
(追記:ヘッダ画像はコードとスクショフォルダにあった謎グラフをリサイクルして作っただけで成果物じゃないです)
きっかけ
私は人様の作った神Excel神Wordの類いが大嫌いです.できのいいものなら全力で乗っかろうと思えるのですが,大抵なにか不具合がありしかも滲み出る作者の「作ってやった」感…
それに加えて作業フォルダが
なんてなっていようものなら最悪です.
マクロ入ってるんだか入っていないんだか開けてみないとわからないxls形式というのも芸術点高いです.
たかが物量の多い反復作業のPOP的な物の作成に神経すり減らしたくないのでPythonでフルオートでこなせるようにします.本来の作業時間以上に時間をかけては生産性が悪いので最近流行りのAIを用いてなるべく短期間の実装を心がけました.
実作業
まず仕様を言語化しChatGPTに方向性についてお伺いを立てました.なるべく短い文で細かく条件は決めていったほうが良かったです.エラー時に問題箇所の特定が面倒なので大きい機能から小出しにしていくとうまく行きました.
Pillowという画像処理のライブラリを使うと良いというお告げが出たので,このまま対話で完成系に持ち込めるか細部のパラメータを弄りました.が,結果どうしても対応できないエッジケースがあったため,関数の使い方のみ参考にして人力でコーディングし直しました.ChatGPTが100行書き,無駄を削りつつバグをとった結果80行近く,作業時間は1h強くらいでした.これならギリやる価値ありそうです.
備忘録
以下完全に備忘録です.多分自分がするっと忘れて検索したりChatGPTに聞いたりするけどちょっと梃子摺りそうなポイントです.
CSVで情報もらう系の処理
N
A[0],B[0],C[0],D[0]
A[1],B[1],C[1],D[1]
A[2],B[2],C[2],D[2]
:
A[N-1],B[N-1],C[N-1],D[N-1]
競技プログラミングにありがちなこの形式でCSVファイルを作成し,それをPythonスクリプトで使ってやろうという場合です.私の技量的にC++ならさくっと書けそうですが慣れていない言語ではあまり考えたくないです.
import csv
:
:
def process_csv_file(file_path):
with open(file_path, newline='') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
next(reader) # ヘッダー行をスキップ
for row in reader:
a_value = row[0]
b_value = row[1]
c_value = row[2]
d_value = row[3]
やりたいこと(a,a_value,b_value,c_value,d_value)
process_csv_file(csvファイルのありか)
Pillowで文字入れ
Pillow自体が人生初の試みだったので残しておきます.別の用途でも画像に文字入れする局面は出そうなので.
from PIL import Image, ImageDraw, ImageFont
background=Image.open(画像のパス).convert("RGBA")
#このRGBAと末尾の保存方法は色や画像によってうまくいく/いかないがあったので書いとけば間違いなさそう
font1=ImageFont.truetype(str(フォントのパスオブジェクト),フォントサイズ) #パスオブジェクトのくだりは後述
draw_img=ImageDraw.Draw(background)
draw_img.text(
(x,y),
入れる文字,
font = font1,
fill = "色" #カラーコードまたは有名な色なら単語でも可
anchor = "mm" #で中央揃えとかできます
)
background=background.convert("RGB")
background.save(保存先パスとファイル名)
後述するpathlibを使ったところ,Pathオブジェクトと文字列とで関数によって使える使えないがあるようで酷い目にあいました.font1を定義している箇所ではPathオブジェクトで怒られたのでstr関数で文字列扱い.次もまた同じ目にあいそうなので今後はここからコピーしたいと思います(白目).
また,文字を入れる座標が左上を(0,0)として右がx増加,下がy増加であることにも注意が要りそう.ここはChatGPTニキのコードを見てから書いたので察せました.
Pathの扱い
従来ではPathはガッツリ文字列として扱うのが主流だったようですが,pathlibを使うのがナウいらしいです.
そもそもPythonではコマンド叩いたときのディレクトリにいるので,pyファイルがどこにいるかは無関係に動くという点で毎回躓きます.しかしフルパスで記述しようものなら別の環境に移植したとき終わるので,pyファイル視点で書けるもんなら書きたいという気持ちがありました.
import pathlib
print(pathlib.path(__file__)) #pyファイル名まで含めたパス
print(pathlib.Path(__file__).parent) #pyファイルが入っているディレクトリまでのパス
基本はこれで良さそうですが,関数によっては明示的に文字列にしてあげる必要があったのでstr(ここ)に入れて渡せば問題ないです.またPathオブジェクトとして扱う際に下の階層に移動するときは"上の階層" + "下の階層"ではなく"上の階層" / "下の階層"で連結するのも忘れそう.
文字列関係の処理
str()関数はC++でも日頃お世話になりますし,なんとなくで使えています.先の目的達成のためにファイル名を連番にしておくと捗ります.
ファイル名をstrとして,
ファイル名=str(カウンタの変数).zfill(2)+".png"
なんてやってあげるとカウンタ数1,2,3…に対してファイル名は01,02,03〜…となってあとから見栄えがいいです.これもzfillが先かstrが先か毎度調べているのでコピペ用に.
まとめ
かなり自己満強めの内容になりましたが,触ったことのない機能に触れる機会を強制的に作り出せるという点でChatGPTを用いた勉強というのは有効なのではないかなと思いました.(レポートだったり競プロの開催中のコンテストだったりは論外ですが)
自分にはない才能を持った存在っていいですよね.