朝はバナナとヨーグルト

毎日同じ朝食でも大丈夫なタイプ

【Python】よくわからん「or」の使い方

きっかけはx = x or []

GitHubの他人のコードで見たときに、「ん?」と口に出た。

1年ほどPythonに触れながら、今までに見たことがなかった使い方だったので焦るわし。

今回はorの変わった使い方と、使い時、良し悪しについて考えてみます!

結論

使わない。

動くけど、意味がわかりづらいので使わないほうが良いと「私は」思います。

より良いとされるif foo is None:といった判定法が推奨されているようです。

具体例

サンプルコード

def append_num(num, group):
    group = group or []
    group.append(num)
    return group


if __name__ == "__main__":
    group1 = [1, 2, 3]
    group2 = None
    print("Before: {}, {}".format(group1, group2))
    group1 = append_num(100, group1)
    group2 = append_num(100, group2)
    print("After: {}, {}".format(group1, group2))

実行結果

Before: [1, 2, 3], None
After: [1, 2, 3, 100], [100]

or []の意味としては、「左がNoneのとき、右を実行する」という認識でいいのでしょうか…

group2はもともとNoneだったので、関数内で空のリストに置き換わります。

もしor []がなかった場合以下のような実行結果になります。

Before: [1, 2, 3], None
Traceback (most recent call last):
  File "main.py", line 104, in <module>
    group2 = append_num(100, group2)
  File "main.py", line 76, in append_num
    group.append(num)
AttributeError: 'NoneType' object has no attribute 'append'

なので、Noneによるエラーを回避する手段として利用している方もいるようですね。

ただGoogle Style Guideを確認したところ、以下のような記述がありました。

Always use if foo is None: (or is not None) to check for a None value-e.g., when testing whether a variable or argument that defaults to None was set to some other value. The other value might be a value that’s false in a boolean context!

Noneかどうかの判定にはif foo is Noneを使え、Falseを示す値はいくつかあるぞ!って感じでしょうか(笑)

試してみたところ、このorは当然かも知れませんがNoneだけでなくFalseのときも同様に動きます。

group2の初期値を0に変更

if __name__ == "__main__":
    group1 = [1, 2, 3]
    group2 = 0 # initialize 0
    print("Before: {}, {}".format(group1, group2))
    group1 = append_num(100, group1)
    group2 = append_num(100, group2)
    print("After: {}, {}".format(group1, group2))

実行結果

Before: [1, 2, 3], 0
After: [1, 2, 3, 100], [100]

よってNoneによる誤作動を防ぐことはできますが、None以外のFalseになる値(0, [], {}, ())を入れてしまっても動いてしまうプログラムの完成です。あかんですね。

なのでGoogle Style Guideでは以下の記述が推奨されていました。

# BAD
def append_num(num, group):
    group = group or []
    group.append(num)
    return group

# GOOD
def append_num(num, group):
    if group is None:
        group = []
    group.append(num)
    return group

結論・まとめ

結果としては、Googleさんも非推奨ですし使わないようにしようと思うます。

あまり直感的にわからない方が自分も含めいらっしゃると思うので、Python大好き人間の集まりみたいなところでない限りは控えたほうが良いというのが率直な感想です…

ちなみに関数の仮引数に空リストを渡すのはエラーのもとなので非推奨だそうな。

def append_num(num, group=[]):
    group.append(num)
    return group


if __name__ == "__main__":
    a = append_num(10)
    a.append(20)
    print(a)
    b = append_num(30)
    b.append(40)
    print(b)

実行結果

[10, 20]
[10, 20, 30, 40]

2つのリストに分けて初期化していると思いきや、abは繋がっているようです。Pythonは参照渡しという噂を聞いたことがあります(間違っていたらすいません、コメント頂けると助かります)が、仮引数の[]によって作成されたリストの参照をabの両方に渡しているため起こるエラーだそうですよ。

orの意外な使い方を説明して燃え尽きてしまいました、andについては実際にやってみてください。私は解説をかけるほどうまい解釈を思いつかなかったので、コメントにandについて残して頂ける方がいらっしゃいましたら、末代まで感謝しますので宜しくおねがいします。

【Python】operatorの勉強(1)

PythonGetterSetter必要…?

まだまだペーペーです。プログラムだけでなく、文章に間違いや語弊がありましたらコメントなどで厳しく教えていただけたら幸いです。

きっかけ

他学科の友人の研究室に呼ばれ、プログラムを見て欲しいと頼まれた。

私「Pythonやってんだね」

友「なんもわからんけどね、卒論やばいから書いて欲しい」

私「おおん…頑張る…」

そんなこんなで、友人のプログラムを開発することになった私。

教授が書いてくれたという原型のプログラムを見ると、ものすごいJavaライクなプログラムが…

私「セッターとかゲッターって、Pythonだと意味なくね?」

友「なにそれおいしいの?」

私「おう…」

とはいったものの、これまで属性に直で値を代入していた自分。 「Javaみたいに、予期せぬ入力に対する処理とかどうすんだ?」と思ったので、調べてみた。

そして、自分の無知を知り恥じるのであった…

カプセル化

Pythonpublicとかprivateを見たことがなかったので、カプセル化とかないと思っていた。

でもpropertyってのがあるらしい。Google Style Guideに載っていたコードを引用したものが以下の通り。

import math


class Square:
    def __init__(self, side: int):
        self.side = side

    @property
    def area(self):
        return self._get_area()

    def _get_area(self):
        return self.side ** 2

    @area.setter
    def area(self, area):
        self._set_area(area)

    def _set_area(self, area):
        self.side = int(math.sqrt(area))

    @property
    def perimeter(self):
        return self.side * 4


def main():
    s1 = Square(3)
    print(s1.side, s1.area, s1.perimeter) # 3 9 12
    s1.area = 25
    print(s1.side, s1.area, s1.perimeter) # 5 25 20
    s1.perimeter = 10 # Attribute Error


if __name__ == '__main__':
    main()

このコードを噛み砕いて説明するとSquareクラスには属性が3つある。それは

  • side(直接読み書きできる)
  • area(メソッドを介して読み書きできる)
  • perimeter(メソッドを介して、読みだけできる)

プロパティと関数の頭につけるだけで、属性のようにアクセスできる。

@area.setterだけでなく、@area.getterもあるが@propertyと動作は同じ。@propertyのみを設定すると、値の書き込みができなくなり、実質読み取り専用の属性を作ることができる。

感想

意図しない値の代入をdefの中で防ぐことができる。(たとえば、areaに負の値が入ったらエラー表示とか)

研究で使うプログラムでそこまでの配慮は求められないが、今後書くプログラムには採用していきたい。

あんまり多用するとコードが読みづらくなりそうだし、使い方をよく考えないとな…

【書評】学びを結果に変えるアウトプット大全

初めての書評

約3ヶ月ぶりの投稿です。 書かなきゃな…という気持ちを抱きつつも、目の前のタスクに追われ続けて結局投稿できていませんでした(笑)

複雑な気持ちですが、新型コロナウイルスの影響で就活が完全に停止した結果、若干の余裕ができました。

TL; DR

私は基本的に技術書か自己啓発しか読みません。

私の彼女も含め小説が好きな人の多くは、頭の中で登場人物が動いたりするそうです。 私は活字に対する苦手意識もさることながら、それがないので読む気になれません。

いつか小説も挑戦したい…

それはさておき、私が自己啓発本を読むようになったきっかけの本があります。それが学びを結果に変えるアウトプット大全です。

この本の作者は「樺沢紫苑」さん。(かばさわって読めませんでした…)精神科医としてお勤めされながらも、10年以上メルマガや書籍の出版に取り組んでいられるすごい方のようです。それだけでなく、月10本以上の映画鑑賞や10回以上の飲み会など、プライベートにも時間を割かれているようです。

「そんなんありえん、絶対嘘だ」と思いつつ、少し気になって買ってしまいました。

結論

この本は「よくある自己啓発本」といった印象ですが、内容が濃く感じました。 他のアウトプットに関する本を何冊か読んで得られた知識をまとめて読み返しているような気分を感じらる、体系的に上手くまとめられた良書だと思います。

具体的な内容としては

  1. アウトプットの比率
  2. アウトプットの作法
  3. 成長するマインド

の3点を取り上げていると感じました。

1. アウトプットの比率

この本の、まず一番に伝えたい内容はこれだと感じました。

大体の人がインプット主体の学習をしているのが問題で、アウトプットを増やさないと成長はない。といった内容でした。具体的な比率を挙げており、取り組みの具体例も少しあったのでイメージしやすいと思います。

この本全体を通して言えることですが、引用が多いため書いてある内容に対して懐疑心を持たずに受け入れられます。

アウトプットの重要性をしっかりと理解できる内容です。

2. アウトプットの作法

具体的にどのようにアウトプットするのかを挙げています。

ブログに関しても言及していて、このブログ開設のきっかけでもあります(笑)

本を読んだら3点の気づきを挙げる、資料作成などにおいて100点を目指さない、などのありふれた内容がメインでした。

3. 成長するマインド

この本の意外な部分でした。

アウトプットに一見関連がなさそうな内容も取り上げています。具体的には、ポジティブなワードを使う、睡眠の重要性などです。

この本の軸として、「アウトプットによる成長」があるのかもしれません。そう考えると、ここの内容もアウトプットに結びついてすんなり受け入れられました。

感想・考察

私は大学院に進学しましたが、研究に通じる部分がありましたね… 読んだ論文の内容を忘れる、いつまでたっても同じサイトの情報を見返してしまう。。。など、思い当たる節がありまくりです。

その解決になるかは人それぞれですが、この本でも触れている「アウトプットで得られた気づきから行動を起こすこと」が大切だと思います。

私はこの本を読んでから、論文を1枚の紙にまとめて保存し、いつでも読み返せるようにしています。 また本1冊に対して3つの気づきを見つける、そういった意識を持って読書することで内容の定着度が大きく向上した実感があります。

自己啓発・ビジネス書ですので、社会人の方が読まれる前提の書かれ方をしています。 しかし、中高生をはじめとした勉強に励む方こそ読むべきかと思いました。

まとめ

読む価値は十分にあると思います。

また自己啓発系を日常的に読んでいる方であっても、体系的に知識を整理できる内容になっていると感じました。

この本が中高生から社会人まで、毎日勉強を頑張っている人たちに届くことを願っています。

学びを結果に変えるアウトプット大全 (Sanctuary books)

学びを結果に変えるアウトプット大全 (Sanctuary books)

  • 作者:樺沢紫苑
  • 発売日: 2018/08/03
  • メディア: 単行本(ソフトカバー)

初投稿

始めたきっかけ

情報科学を専攻している大学院生です

HatenaさんとかQiitaさんには、いつもお世話になっております。

文章力の低さを改善しようと、ブログを始めました。

他の人の役に立ちたい、その一心で技術系の内容も投稿します。

なので、間違いとかあればコメントください。

投稿の主な題材

基本的には「プログラミング」と「書評」の2本柱でやっていきたい所存

でもたまには時事関連だったり、日頃感じることなど

いろんな題材で投稿してみたいです。

プログラミング

基本的にはPythonを使ってますが、DockerとかGOとかも独学でやってます。

自分の忘備録のなかでも、有用性を感じるものは投稿していきます。

書評

自己啓発とかビジネス書が大好きです

月8冊くらいしか読みませんが、良いと感じたものだけ投稿します

その他

現在、コロナウイルスが猛威をふるっています。怖いっす。

時事ネタとか日常感じたことを投稿して、自分の考えをまとめたいっす。

そこに共感や反論があれば、より自分の考えが深まると考えてますっす。

文章力と語彙力ともにド底辺の稚拙な文章ですが、できるだけ質を高めて投稿します

よかったら読んでいってください。