モブプロな人たちのブログ

横浜で Web サービス開発しているエンジニアの日記です。Python 大好き Flask 大好き。たまに SpriteKit でゲーム開発も。

「会社というモンスターが、僕たちを不幸にしているのかもしれない。」を読んだ感想など

最近話題の本を読んだので、感想などをまとめておきたいと思います。

会社というモンスターが、僕たちを不幸にしているのかもしれない。

会社というモンスターが、僕たちを不幸にしているのかもしれない。

内容を事細かに書いてしまうのはアレなのですが、1箇所だけ引用させていただきます!

よく見ておかないといけないのは、カイシャというモンスターのブランドやイメージではなく、生身の人間である代表取締役が本当に信頼できる人なのかどうか。

そこを間違えると、知らぬ間に搾取されていたり、仕事が全然楽しくなかったりしてしまうわけです。

コレは結構考えさせられました・・・。

最近はそうでもないんですが、前職の頃などを振り返ると「組織のために」生きていた時期がありました。ホント、よくよく考えると、組織のためってなんなんだろうって話ですよね。

社長は「会社のために」と言うでしょうし、事業部長は「事業部のために」と言うでしょうし、部長は「部のために」と言うでしょう。

ただ、「組織のために」と言いながら結局は「自分のため(自分のやりたいことをやるため、評価を上げるため、給与を上げるため)」なんですよね。

もちろん、社会のことだけを考えて行動している方もいるとは思いますが、そういった方はホントごくわずかで、多くの方は「組織のために」という大義名分を振りかざしながら自分のために行動をしているんだと思います。

そう考えると、引用した上記の言葉は分かりやすいですね。

例えば、社長が「会社のために」と言ったとき、その言葉をそのまま受け取るのではなく「あの社長のために」と置き換え、それでも自分の中で納得感を持てるのか。

あの事業部長のために」「あの部長のために」「あの課長のために」と、抽象的な組織ではなく生身の一個人に置き換えたとき、しっかりとした納得感を持てるのか。

そこで納得感を持てているうちは良いです。そのまま、その方向で進みましょう。

ただ、そこで「ん?」と感じる瞬間がきたら、それは自分のキャリアについてしっかりと考え直さないといけない時期がきたということだと思います。

おわりに

この本は、「自分がやりたいことは何なのか?」を改めて考えさせてくれるキッカケになりました。

ぜひ、多くの方(特に若い方で、会社について悩まれている方)に読んで欲しいと思います。

「BPStudy#125〜テスト駆動開発(TDD)の真髄」に参加してみて

先日、以下の勉強会に参加してきました。

まとめもあります。

社外の勉強会というと、以前に主催(というほど何もしてないけど)側で参加して以来でした。

学生時代は、大規模なイベントに足を運んで、そこで開催されているセミナーとかに参加したことがありましたが、アプリケーション開発のエンジニアとして働き出してから参加するのは初めてだったので「はてさてどんなものかしら?」という感じでした。

f:id:kaorr_mob:20180101080410p:plain

結果、めちゃくちゃ面白かったです! また機会があれば参加したいと思いました。

ただ同時に、よく Twitter などで登壇者側の人が言う「登壇しない立場で勉強会に何度も参加しても意味ない」みたいな言葉の意味も理解できました。

参加して楽しかった!」で終わることがほとんどのパターンですよね。それを実際の仕事に結びつけて価値を出すのって、かなり大変。

なので、今回の勉強会で得たものをしっかりと仕事なりプライベートプロダクトに結びつけることが出来るまでは、他の勉強会は良いかなぁという感じです。もしくは、LT 枠で登壇するか。

当日のメモ

当日、勢いでメモったものがあるので、改めてまとめておきます。未来の自分のために。

テスト駆動開発は自習(写経)に向いている

テスト駆動開発

テスト駆動開発

t_wada 先生が翻訳された本です。

本の中にはコードが大量に出てくるので、写経するのに向いていると説明されていました。

今読んでる本が読み終わり次第、購入して写経したいと考えています。

設計をせずにテストから書き始める方法「ではない」

よくある勘違いのようです。

TDD というと「とにかくテストを書き始めることからスタート!」のイメージがありましたが、そんなことはもちろんありません。ちゃんと設計はしますよ、という話。

たくさんテストを書くことになるが、まずは小さいところからクリアにしよう

結果的には多くのテストコードが必要になりますが、その最終形ばかりを見てウッとならずに、小さいところから進めていきましょう。

ひょっとすると実は一番難しいかもしれないのは、大きい問題を分解して、順番を決めて、着手すること

うーん。これは TDD の文脈だけではなく、仕事など全般に言えることですね。

大きい問題は、どこから手をつけて良いか分からなくなり、モチベーションが低下しがちですね。

大きい問題を大きいまま解決できる人なんてそうそういないので、しっかりと自分が理解できる大きさにまで分解して、進める必要がありますね。

最初に文章として書いて、それをリスト化していく

これは面白いやり方だなぁと思いました。

自分がその機能に求めること、そのテストに求めることをまずは普通の(箇条書きではない)文章で書いていく。

その後、その文章を分解してリスト化していく。そして、そのリストにそってテストを書いていく。

ぜひ実践したいです。

コアロジックから優先的にテストを書いていく

MVC モデルの V などは、テストを書く手間がかかる割りに、賞味期限が短い(ことが多い)のです。

全部のテスト書かなきゃ!」と思うことは多いでしょう。そして、全部書かないとなんか見栄えが悪い、ということもあるでしょう。

テストに理解のない人が周りに多いと、「なんでちゃんと全部書かないの?」と詰められることもあるかもしれません。

しかし、時間などのリソースは有限です。コストパフォーマンスの悪いテストコードをたくさん書くより、コストパフォーマンスの良いテストコードに集中していきましょう!

テストの内容を具体的にする(考える負荷を減らす)

「数値を文字列に変換する」ではなく「数値 1 を文字列 '1' に変換する」といったイメージです。

曖昧なゴールを設定すると、コードを書いているときに思考がブレてきて、考える負荷が上がってきます。

なので、より具体的なゴールに変更できないか、考え直すのが大事です。

意味のないテストが意味ありげに見えるのは問題

これは反省ポイントですね・・・。

なんとなく追加したテストとか、不必要に重複したテストとか、書いた本人は経緯を知っていても、他人は知らないことがほとんどです。

また、書いた本人でさえ、しばらくしたら忘れるものです。そうすると、そういったテストコードが、今度は全体の生産性を下げだします。

「このテスト、なんで追加したんだろう・・・? でも、あるから保守しないとなぁ・・・」となるのです。

自分の記憶が鮮明なうちに、不要なテストコードは大胆に削除しましょう!

プライベート Web サービス開発に向けて、ようやく重い腰が上がった・・・

表題の通りですが、昨年末頃にネタを思いつき、「うおおおおおお!」と燃えていた Web サービス開発熱。

しかし、年末年始のドタバタや、まぁその他色々あって、未着手のままズーーーっときてました。

「いや、マジでこのままじゃいけないな・・・」

と一人で反省し、今日ようやく重い腰が上がりました。

いや、そんな重い腰になるほどの規模のサービスではなくて、自分が楽になるためだけの小さいサービスなんですけどね。なぜか、フットワーク重くなってて、進められていませんでした。

環境大事

いやはやホント、環境って大事ですね。

今日はコメダ珈琲で開発していたのですが、自宅では何かと集中できないことが多く、程よく周囲がガヤガヤしている環境での集中力は我ながらビックリするほどのものでした。

このままの勢いで、今月中にリリースまでいきたい・・・!

Python で get や set メソッドよりも素のままの属性を使う

「Effective Python」を久しぶりに読み返して、当時は特に何も思わなかった箇所に引っかかったのでメモを残しておきますシリーズ第7弾。

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

Python で get や set メソッドよりも素のままの属性を使う

他の言語から Python に移ってきたプログラマは、ごく自然にクラスの中でゲッターやセッターメソッドを明示的に実装しようとする

ふむふむ、なるほど。確かに昔 Java を勉強してた時、ゲッターとかセッターとかちょくちょく書いてました。

class User1:
    def __init__(self, age):
        self.age = age

    def get_age(self):
        return self._age

    def set_age(self, age):
        self._age = age


if __name__ == '__main__':
    user1 = User1(30)
    user1.set_age(user1.get_age() + 1)

↑こんな感じのやつです。

ただ、見てわかる通り、age に 1 を足したいだけなのに、やけにゴチャゴチャした感じになってますね。

こういうのは「Python 流ではない」みたいです。

では、どうするかというと、

class User2:
    def __init__(self, age):
        self.age = age


if __name__ == '__main__':
    user2 = User2(30)
    user2.age += 1

まあ簡単。

いや、ふざけてないです。本当に必要なのか考えずに、おまじない的にゲッターやセッターを書くのはやめましょうという話ですね。

さて、しばらくして特別な振る舞いが必要になった時どうすれば良いんでしょうか?

例えば、年齢は200歳まで許容するが、それ以上は例外処理にしたい場合、

class User3:
    def __init__(self, age):
        self.age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        if age > 200:
            raise ValueError('age must be <= 200')
        self._age = age


if __name__ == '__main__':
    user3 = User3(30)
    user3.age += 1

    user3.age += 170
    # ValueError: age must be <= 200

デコレータを付けました。これで OK です。

Flask + Flask-SQLAlchemy のチュートリアルを日本語で (Relationships 編)

チュートリアル関連記事

はじめに

今回は、既存の Model(User) に Relationships を追加してみたいと思います。

本格的にやるには、もっと色々考慮するポイントがありますが、まずはざっくりと Relationships を追加してみます。

追加する Model ですが、ユーザごとの投稿記事(Post)のものです。

各ファイルの修正

Python ファイル修正

hello.py ファイルを以下のように修正します。

# 〜〜省略〜〜

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    posts = db.relationship('Post', backref='user', lazy=True) # 複数の Post への紐付け

    def __init__(self, username, posts=[]):
        self.username = username
        self.posts = posts # ユーザ追加時は基本的に空だと思いますが、念のため追加できるようにしておく

# Post クラスを追加
class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    body = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # 一人の User への紐付け

    def __init__(self, title, body, user_id):
        self.title = title
        self.body = body
        self.user_id = user_id

    def __str__(self):
        return self.title

# 〜〜省略〜〜

テンプレートファイル修正

templates/top.html ファイルを以下のように修正します。

<!-- 省略 -->

  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>投稿</th> <!-- 項目追加 -->
        <th>詳細</th>
      </tr>
    </thead>
    <tbody>
      {% for user in user_list %}
      <tr>
        <td>{{ user.id }}</td>
        <td>{{ user.username }}</td>
        <td>{{ user.posts|join(', ') }}</td> <!-- 投稿のタイトルをカンマ区切りで表示 -->
        <td>
          <a class="btn btn-success" href="{{ url_for('show_user', user_id=user.id) }}">
            <span class="glyphicon glyphicon-search" aria-hidden="true"></span> 詳細
          </a>
      </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>

<!-- 省略 -->

動作確認前のデータ準備

Python インタプリタを起動し、以下を実行します。

# 色々 import
from hello import db, User, Post

# 一旦データベースを作り直す
db.drop_all()
db.create_all()

# admin ユーザを再作成
user = User('admin')
db.session.add(user)
db.session.commit()

# admin ユーザの投稿を2件作成
post1 = Post('title1', 'body1', user.id)
post2 = Post('title2', 'body2', user.id)
db.session.add(post1)
db.session.add(post2)
db.session.commit()

動作確認

トップページにアクセスすると・・・、

f:id:kaorr_mob:20180121214022p:plain

投稿したタイトルがうまく表示されていますね!

おわりに

今回は、本当にざっくりと Relationships を追加してみました。

また、データベースをばっさりと再作成していますが、本当は Flask-Migrate とか使うと良いと思います。が、説明に時間が掛かりそうなので、今回はばっさりといきました。

次回は、投稿データをどんな感じに表示するのか、どんな感じに変更、削除するのかを考えながら進めていきたいと思います。