「 今どきクラウドやるなら npm / Node.js ぐらい使うのが 平凡の真ん中 ぐらいだと思うんだが、
クラウド別にやりたくないし、誰も保守できないデスクトップ・アプリを 何か新しいものに移行したい……☆
そんなとき Java とか PHP / Laravel とか候補が上がるわけだが、言うこと聞かん坊のわたしが
Elixir ! Golang ! Scalar ! Type script ! とか ミーティングに ジャミング攻撃をするわけだぜ☆」
「 すると チームのみんなが知っていて、使える言語は Python という戦わない民主主義みたいな結果に落ち着くわけだぜ☆」
「 知名度 1位、2位を争う プログラム言語なのよ! 順当なのよ!」
「 で、話しはさかのぼって 面接のときだぜ☆
何か質問は、という いつものやつで質問は適当な1つで済ませて ついでに ジョブ・ディスクリプション に 基本設計 を入れてもらっておいた☆
基本設計、詳細設計、作成、テスト 4つ入っている☆」
「 お父んの開発スキルは わたし ぐらいしか 世に公開されてないだろ☆
Git hub を見ても 作りかけのクソ・コードばかり☆」
「 わたしの派遣社員マンの価値としては だいたいの案件を できます、と言って取って できたり できなかったり することだからな☆」
「 お父んは 転職11回分の気違いネタは いっぱい持ってるよな☆
そのうちの7回 契約期間延長なし、クビになったときの会議室ネタとか 持ってるよな☆」
「 もうかばうことはできません!の回とか、 もっと雑談をしてください、の回は面白かったよな☆
ウソは付かないでくださいの回も 外せない☆ 経営者が金持って逃げたことも☆
2004年頃の IT 下請け編 は わたしの社会経験が無い頃で、ウケる☆ 山ほどしゃべれる☆」
「 で、 Ubuntu、 Nginx、 uWSGI、 Python3, Jinja2、 Pyodbc、 MSSQL という平凡な構成にしてみたわけだぜ☆」
「 わたしは知ってるぜ☆ その7つは お父ん 未経験だろ☆」
「 まず Ubuntu☆ コンピューター将棋選手権でカパックが使っているのを 見たことがある☆」
「 はい、疑義! 見たことがある、 は、経験ではないのでは☆?」
「 できなかった こともあるが、 何もしないタイプよりは 少しは できることが多いだろ☆
ちょっとの差も 実務16年 続けば ある程度の差だぜ☆」
「 で、コンピューターについて 押さえておきたいことは 山ほどある☆
OS編、Web編、システム設計編 の3つぐらいに大きく分けれるだろうか☆」
「 ツクールで 社内システムを作りなさいよ! Dante98 とか入れないの!?」
「 ほとんどのことは 他の人が記事にしているはずだから、あんたしか知らないことを選んだ方がよくない?」
「 ほとんどの記事は 入門編とか言って 全然 説明足りないだろ☆
このコードは ベスト・プラクティスではない可能性があります、とか 書いてるだろ☆」
「 flaskr
は チュートリアルのブログ・アプリケーションの名前だから 別の名前でもいいのに、
フォルダー名を flaskr
にしてるだろ☆?
末尾の r
って何なのか分からん☆」
「 名前を考えるのも大変だし、 flaskr
でいいだろ☆」
「 ↑ 最初は だいたい これぐらいの ファイル、ディレクトリ から始まるだろ☆
これが だんだん 増えていくぜ☆
Python のモジュール・システムの分け分からん具合には 日を跨って悩まされた☆」
「 というか、 Python2、3の違い、pip、venv に悩まされた☆ もうレガシーの名前は 思い出したくないぜ☆」
「 じゃあ すごく大事な話をするかだぜ☆ ディレクトリの分け方について☆」
「 設定ファイルをいじるだけで上手く行きます、という手順書を書くために settings があるといい感じ☆
ただ、ファイル数が多くなると マイナス印象☆ 1つのファイルに 複数の違うものの設定を 共存して詰め込めるようにしておけだぜ☆」
「 JSONって何☆? みたいなチームだとパーサーに苦しめられるぜ☆」
「 あとは base_type には わたしが作った模範となるものを入れて、
customize_type は誰でも勝手に改造したものを入れろということにする☆
恐らく プログラムの意味ではなく、チームの運用で分けた方がいいはずだぜ、結果は どうなるか知らん☆」
ダメな例:
「 ↑ みたいに 意味別で分けたいんだが、そうすると 『これは何ですか』 『これはどこにありますか』 みたいな
質問や、学習が増えてしまう☆
できれば ディレクトリー名に 専門用語は付けない 方が実践的だぜ☆」
「 ディレクトリ名の極意は、 『わたしには関係ない』 『わたしには関係がある』 の2つだぜ☆」
「 メンテナンスや、引継ぎでは、ディレクトリ、全部 開けることになる☆
ディレクトリは 無ければ無いほど 実践的だぜ☆」
「 JSON が使えるかどうかで 困難さは大きく変わる☆
.ini ファイルじゃないと嫌だ、という人もいれば JSON みたいな得体の知れないものは嫌だという人もいる☆」
「 ぶつくさいいながら バリバリ JSON を使ってるじゃないか☆」
{
"apple": {
"banana": {
"cherry": 100
}
}
}
[apple]
apple_banana_cherry = 100
「 のようにする☆ 配列のイテレーションができなくなるが、まあ そのとき考えようぜ☆」
「 あとは メソッド名の種類は少ない方がいい☆
read とか get とか set とか、数を絞るべき☆」
./flaskr/settings/banana.json:
{
"food" : {
"snack": 100,
"noodle": 110,
"juice": 120
}
}
app.py
banana = Banana().read('./flaskr/settings/banana.json', 'food')
「 ↑ 見た目は よくてここまで☆
これ以上 むずかしかったら 驚き最小の法則 に反する☆ そもそも JSON であることがヤバい☆」
app.py:
if request.method == 'POST':
banana.post(request)
else:
banana.get(request)
「 Banana は Uniform Resource だったの?」
「 正確には Banana は 画面操作のよくあるパターンの1つだぜ☆ 型にあたる☆
Uniform Resouce は JSON で設定する☆」
「 なんかもう この先 面白いことは無さそうに思える☆ 話題を変えようぜ☆?」
banana.py
from flaskr.base_type.banana_base import Banana as BananaBase
class Banana(BananaBase):
def __init__(self):
self.__creation = Creation()
self.__reading = Reading()
self.__update = Update()
self.__deletion = Deletion()
def read(path:str, section:str):
settings = # Omit. Read section on file.
self.__creation.set_settings(settings)
self.__reading.set_settings(settings)
self.__update.set_settings(settings)
self.__deletion.set_settings(settings)
return self
class Creation(BananaBase.Creation):
def execute():
# Omit
pass
class Reading(BananaBase.Reading):
def execute():
# Omit
pass
class Update(BananaBase.Update):
def execute():
# Omit
pass
class Deletion(BananaBase.Deletion):
def execute():
# Omit
pass
「 これぐらい 特に不思議はないだろ☆
コンストラクタで 例外が起こってほしくないので、ファイルの読み込みは 別メソッドにしてるぐらいで☆」
「 1単語の変数名、メソッド名は 避けるんじゃなかったの?」
「 オブジェクト指向は使わないんじゃなかったの? 継承していいの?」
「 post( )
、 get( )
をグローバル関数にする手もあったんだが、ごちゃごちゃして嫌になったので、
やってはいけない例、 機能を継承させるだけの親クラス とかちゅうちょなく作るぜ☆」
「 ただ、コンストラクターで、使わないものまで メモリに展開するのは 大富豪だぜ☆
あとで CPU使用率が高い とか 言われるの 立腹 なんで……☆、」
class Banana(BananaBase):
def __init__(self, operation):
self.__reading = Reading()
if operation == 'add':
self.__creation = Creation()
elif operation == 'update':
self.__update = Update()
elif operation == 'delete':
self.__deletion = Deletion()
「 コンストラクターに フラグ1個 渡すのは 人権を主張しようぜ☆」
class Banana(BananaBase):
def __init__(self, operation):
self.__reading = Reading()
if operation == 'add':
self.__changing = Creation()
elif operation == 'update':
self.__changing = Update()
elif operation == 'delete':
self.__changing = Deletion()
def read(path:str, section:str):
settings = # Omit. Read section on file.
self.__reading.set_settings(settings)
self.__changing.set_settings(settings)
return self
「 オブジェクト指向は使わず、プロシージャ言語程度の知識で、オブジェクト指向ぐらいの利便性を得るのが
社会で生きていくコツだぜ☆」
./base_type/banana.py:
class Banana:
@property
def reading(self):
return self.__reading
@reading.setter
def reading(self, val):
self.__reading = val
@property
def changing(self):
return self.__changing
@reading.setter
def changing(self, val):
self.__changing = val
「 ↑ そういえば Python はプライベート・フィールドを継承できないのだった☆ 親クラスに プロパティを用意しておけだぜ☆」
「 Banana が Banana を継承したら 循環参照するだろ☆」
class Banana(BananaBase):
def __init__(self, operation):
self.reading = Reading()
if operation == 'add':
self.changing = Creation()
elif operation == 'update':
self.changing = Update()
elif operation == 'delete':
self.changing = Deletion()
def read(path:str, section:str):
settings = # Omit. Read section on file.
self.reading.set_settings(settings)
self.changing.set_settings(settings)
return self
「 オブジェクト指向は使ってなくても オブジェクト指向の継承の機能は使ってんじゃないの?」
「 もう この時点で かなり まずいコードだぜ☆
むしろ 親バナナは Python3 が不出来で必要になってしまうゴミ・コードです と言い張り、
self.changing はグローバル変数です とか 独自の説明をして逃げきれだぜ☆」
「 しかし あまり ゴミ、ゴミ 言っていると 本当に 消されてしまうんで
キャッシュ・ファイルです とか 逃げ道を残しておけだぜ☆」
「 やってることは インスタンスのメモリ展開と 設定ファイル読込の2つなんで、5秒ぐらいで終わらせたいんだが
雰囲気がまずくなると プロジェクトを引き上げ られたりするんで なるべく イカしたコード であることを強調しろだぜ☆」
「 read()
ってメソッド名じゃ 通らないんじゃないの? made_by()
じゃないの?」
「 プログラムのメソッド名の慣習に倣うと make_by()
だな☆」
class Banana(BananaBase):
def __init__(self, operation):
self.reading = Reading()
if operation == 'add':
self.changing = Creation()
elif operation == 'update':
self.changing = Update()
elif operation == 'delete':
self.changing = Deletion()
def make_by(path:str, section:str):
settings = # Omit. Read section on file.
self.reading.make_by(settings)
self.changing.make_by(settings)
return self
「 ↑ 逆に プログラマーから 文句が出そうだよな☆ make_by()
とか慣習にない☆」
app.py
banana = Banana().make_by('food', './flaskr/settings/banana.json')
if request.method == 'POST':
banana.post(request)
else:
banana.get(request)
「 make by
とか聞きなれないから made by
にしたくなるが、文系は黙らせようぜ☆」
「 もっと 適当にプログラム書いたらいかんのか……☆ こんなん5秒で流すとこだろ……☆」
「 パッと見の 好き嫌い で決まるんだぜ☆
客は プログラムの知識でプログラムを見るのではなく、 本人の知識で本人の思ったプログラムを見るんだぜ☆!」
./base_type/banana.py:
class Banana:
def get(self, request):
pass
def post(self, request):
pass
「 get()
と post()
から ようやく コード・レビュー感が出てくるよな☆」
./base_type/banana.py:
class Banana:
def get(self, request):
my_request = MyRequest().make_by_getted(request)
pass
def post(self, request):
my_request = MyRequest().make_by_posted(request)
pass
「 早速 さっき使った make_by()
の亜種を作ろうぜ☆」
「 わたしの知見では、 request オブジェクトの中身はバラバラなので、中身を整形する振る舞いをする MyRequest クラスを用意しろだぜ☆」
./base_type/banana.py:
def get(self, request):
web_confing = # Omit Read file.
my_request = MyRequest().make_by_getted(request)
try:
credentials = web_config.get_credentials()
db_conn = # DB connection with credentials
db_cursor = db_conn.get_cursor()
self.reading.execute_by(db_cursor)
for row in db_cursor.fetch_row():
pass
render( )
except Exception as e:
render( )
「 ↑ 雰囲気的には だいたい こんな感じになる……、だんだん嫌になってきたぜ☆
Flask でどうやって 非同期処理 書くんだぜ☆?」
PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
「 ↑ 今どき Flask より Responder か FastAPI が流行りかだぜ☆」
「 Flask で コーディングを努力するより、 FastAPI に乗り換えて楽にコーディングした方が速いわよ?」
「 Python 選んでる時点で 遅いのだから 性能に こだわるなだぜ☆
現状 Flask 未満なのだから マシには なる☆」
<書きかけ>
Crieitは個人で開発中です。
興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!