日常業務の改善とかに取り組むのに、 Python を久しぶりに触ろうかなと思いたってこのポストを書いてます。、
オフィシャルのドキュメントはすでに一通り目を通したことがあるので、別の視点から眺めるために、Google の “Get started with Python” のコースです。
その他のプログラミング言語と比較しながらおさらいできればな、と思ってます。
Module 1: Hello Python
Python とその他のプログラミング言語との比較:
Features by software | Python | R | Java | C++ |
---|---|---|---|---|
Speed | Slower | Depends on configuration and add-ons | Faster | Very fast |
Approachability | Easy to learn | Complex | Easy to learn | Complex |
Variable | Dynamic | Dynamic | Static | Declarative |
Data Science Focus | Machine learning and automated analysis | Exploratory data analysis and building extensive statistical libraries | Used across projects with open-source assets | Not as widely used but very powerful implementations |
Programming Paradigm | Object Oriented | Functional language | Object Oriented | Multi-paradigm (imperative & object-oriented) |
Java が学びやすくて、R が難しいって評価なので、この辺は人によるのかなと思いますね。
Python については、要するに、オブジェクト指向で学びやすくデータ分析等のライブラリが豊富である一方、その他の言語に比べて若干処理が遅いってことです。
Jupyter Notebook は、Python の複数ある実行環境のうちの一つで、イメージとしては、Microsoft Office の Word にコーディング機能を追加したようなものです。
ターミナルやコンソールで実行する Python インタープリタは、最初はなかなかわかりづらかったり、一度実行したコードを再度実行したり編集したりが難しかったりしますが、Jupyter Notebook ではよりインタラクティブにコードの操作が行えます。また、Markdown 形式でのドキュメンテーションも容易に行えるため、Python コードを記述して、それを説明する文章を添えてあげることができます。
少し応用的ですが、数式を記述したり、ライブラリを利用して Notebook 上にグラフをプロットしたり、なんて使い方もできます。
Jupyter Notebook の利点は:
- Modular/interactive computing:
最も大きな強みです。コードをセルと呼ばれる単位に分割して、かつ好きな時に好きなセルを実行したり修正できます。 - Integration of code and documentation:
ドキュメントにコードを埋め込む、または逆にコードにドキュメントを埋め込む、といったような作業が直感的にできます。(コメントやアノテーションを使わなくても) - Support for multiple languages:
Python 以外にもたくさんの言語に対応しています。(R言語など) - Data exploration and analysis:
データの分析や探索に最適です。上の理由から - Cloud-based services:
色々なサービスがクラウド上で展開してあり、場所を問わずアクセスできます。 - Libraries and extensions:
これは Python をはじめとするモダンなプログラミング言語の強みと同じで、拡張性が高いです。
Object-oriented language: オブジェクト指向言語、とは、オブジェクトを扱う言語で、オブジェクトは、データと振る舞いを一つにまとめたグループのようなものです。Python は、オブジェクト指向言語の一種であるため、この概念の理解が重要です。そして、Python でオブジェクトを生成するには、その元になるクラス(型のようなもの)を利用します。
オブジェクトの構成要素:
- Attribute:オブジェクトに属するデータ
- Method:オブジェクトに属する振る舞い(関数のこと)
例えば、人間をオブジェクトとするなら、その人は名前(name)や年齢(age)などのデータを持っていて、動いたり(move)話したり(speak)する、といった感じです。
基本的に、オブジェクトの Attribute にアクセスするには、「.」 ドットを使ってアクセスします。
Person.name で 例えば、”Yamada” とか Person.age で 「25」などなど。
Method の方も同様にドットを使いますが、こちらはメソッドであることの識別として「()」括弧をメソッド名の後に続けます。括弧の中にデータを渡すことで振る舞いに変化を与えることも可能です。
Person.speak()で、「こんにちは」と出力させたり、Person.move(“Tokyo”)で「東京に行く」という表現をすることができます。
モジュール1の「Variables and data type」より、
When assigning a new variable, it’s helpful to answer these questions before you code: What’s the variable’s name? What’s the variable’s type? And what’s the variable’s starting value?
「新しい変数を定義する際には、コーディングを始める前に次の質問を考えると良いです。:変数の名前は何?変数の型は何?変数の初期値は何?」
リーダブルコードでも、言われているように、変数の名前づけはとても重要です。変数の型については、Python ではプログラム動かすだけなら動的型付け言語なので、そこまで気にする必要はないと思いますけど、型ヒント(アノテーション)をサポートしてたりで、プログラムが複雑になればなるほどバグの低減目的や、IDEのプログラミング支援機能の補強目的で使った方が良いです。(個人的に)
プログラミングを勉強していると、シンタックスやセマンティクスという言葉によく遭遇しますが、それらの概念を理解するためのうちの一つの見方として、”Semantics is the meaning conveyed by the syntax.”「セマンティクスは、シンタックスによってもたらされる意味のこと。」とも言えます。
プログラミング言語にも、自然言語(例えば英語)と同じで、名詞、動詞、前置詞のように、グループに分類できます。基本的に英単語が使われるので、そもそも英語ができるとかなりわかりやすいです。
基本的な分類は以下:
- Variables(変数):文字列、リスト、オブジェクトなどのデータを参照するための名前
- e.g. : person_name など
- Keywords(キーワード):プログラム上で特別な意味を持つで、それぞれ特定の目的に対してのみ使うことができる
- e.g. :
- in
- or
- not
- for
- while
- return など
- e.g. :
- Operations(オペレーション):オブジェクトやデータの値に対してオペレーション(操作)を適用するもの
- e.g. :
- + : 足し算
- – : 引き算
- * : 掛け算
- / : 割り算
- ** : べき乗
- % : いわゆる Mod (商の余りを求める). e.g : 10 % 3 = 1
- // : 除算(切り捨て)
- > : 大なり (True / False のブール値で返す)
- == : 等しい (同上、ブール値で)
- e.g. :
- Expressions:変数やシンボル、数値などの組み合わせで、評価されることによって結果を返すもの(式、と訳されるけど、日本語のドキュメントでもそのまま expression で記載がある方が多い気がします)
- e.g : [1, 2, 3] + [4, 5, 6]
- Functions(関数):関連する statement(文)の集まりで、呼び出されると、定義されたタスクをこなしてその値を戻り値として呼び出し元に渡す。
- e.g :
def to_celsius(x):
'''Convert Fahrenheit to Celsius'''
return (x-32) * 5/9
to_celsius(75)
- Conditional statements(条件文):プログラムの実行フローを与えられた条件に基づいて制御する。
- e.g. :
number = -4
if number > 0:
print('Number is positive.')
elif number == 0:
print('Number is zero.')
else:
print('Number is negative.')
この辺りはプログラミング言語によって、若干差がありますけど、だいたい似たようなもんですね。JavaScript では条件式にはカッコをつけてあげる、とか。
Naming convention(名前付の慣習)については、いろいろとありますが、Python ではとりあえず次を覚えておけばなんとかなります。
“Variable names and function names should be written in snake_case, which means that all letters are lowercase and words are separated using an underscore.”
変数名と関数名は、スネークケースで記述されるべき。スネークケースでは、すべての文字が小文字でかつ、単語はアンダースコアで区切られます。」
PEP 8 (Python Enhancement Proposals)と呼ばれる、ほぼデファクトスタンダードなコーディングスタイルのガイドラインがあり、コードエディタの Linter やコードフォーマッタでよく使われてます。その中に、割と有名な “Zen of Python” という詩文があります。
なんとなく訳してみましたが、若干面白いと思った部分があるので以下に残しておきます。
“Zen” という単語は、日本語の「禅」から来ているのですが、これは、英語では禅そのものというより、「悟りを開いた穏やかな心情」の意味に近いようです。
relaxed and not worrying about things that you cannot change:
Cambridge Dictionary – zen
リラックスしていて、自分が変えようのないものについて心配していないこと
“Complex is better than complicated.” ですが、complex は、複雑さ一般(この文脈ではコードの複雑さ)を意味しますが、complicated は、わかりにくさを伴ったネガティブな意味になるみたいですね。
involving a lot of different but related parts:
Cambridge Dictionary – complex
関連しているが、異なった多くの要素を含むこと
involving a lot of different parts, in a way that is difficult to understand:
Cambridge Dictionary – complicated
異なった多くのパーツを、わかりにくい方法で含んでいること
ちなみに、急にオランダ人が登場したのは、Python の生みの親がオランダ人だったから、でしょうね。Guido van Rossum – Wikipedia
Module 2: Functions and conditional statements
続いて、関数と条件文について、です。イントロダクションでちょっと気になる表現がありました。
Data professionals use conditional statements to structure complex operations, and to perform all kinds of practical tasks, such as binning data and organizing files.
データプロフェッショナル達は、条件文を用いて複雑な操作や、データを 保管 廃棄したりファイルを整理したりするような多くの実践的なタスクをこなします。
この、動詞としての “bin” の使い方は初めて見ましたが、Cambridge Dictionary には載ってなかったので、スラングまたは、エンジニアの業界用語かな?と思います。(アメリカ英語って可能性も)
Merriam-Webster Dictionary には “: to put into a bin” 「容器に入れる」とあるので、データストレージに入れて保管する、みたいなニュアンスですね。
ネイティブに聞いてみたんですけど、この表現だと、”Recycle bin” (Windows のゴミ箱) とか “Trash bin” をイメージするみたいです。なので、そのように解釈すると「データを廃棄して、整理する」となりますね。(間違ってたらすいません。)
Python での関数の宣言は、”def” キーワード + 関数名 + ()丸括弧 + コロン となります。その他の多くのプログラミング言語と違って Python は、波括弧でコードブロックを指定せず、インデントで指定するところに特徴があります。
# ----- 次の行から関数スタート -----
#「#」記号の以降から行末までコメントとして扱われ プログラムの文としては解釈されません。
def get_seconds(hours, minutes, seconds):
total_seconds = hours * 3600 + minutes * 60 + seconds
return total_seconds
# ----- ここまでで関数定義終わり -----
だいたいこんな感じです。2行目から1段右によっている(インデントされている)とこが重要で、基本的には、半角スペース 4つで設定されることが多いです。これが3つだったり5つだったり、一貫性がない場合には構文エラーを吐き出します。
関数は、処理装置みたいなものだと思うと解釈しやすいです。
入力(引数) → 関数 → 出力(戻り値)
数学で三角関数とか使いますが、これが、入力(角度) → sin関数 → 出力(正弦) の関係なのと全く同じです。何かしらの処理をするため、言語でいうところの「動詞」にあたります。なので、データ用の変数名が名詞で定義されることが多いのに対して、関数名は、基本的には動詞から始まる名前で定義されます。
クリーンなコードを書くためには以下が重要です。
- Modularity (モジュール性):
コードが別々の分離されたパーツに分解されていて、相互に組み合わせたり、別のプログラムで再利用できること - Refactoring (リファクタリング):
元々あるコードの機能と全く同じ機能をより良いコードで再度書き直すこと - Self-documenting code (コード自体がドキュメントとなること):
明確で適切な変数名や関数名、過不足なくわかりやすいコメントの追記など
Python のコメントは、「#」(ハッシュタグ)以降、改行までの文字ですが、特に関数を定義するときには、Documentation string (ドキュメンテーション文字列)または、docstrings というものを書きます。
これは通常、関数ブロックの最初に記載され、関数を振るまいを説明します。そして、ドキュメンテーション文字列は、三つの連なった引用符の中に書かれます。
ドキュメンテーション文字列は、(英語の)命令のような形で書かれることが一般的で、文末はピリオドで終わります。例えば、”Calculate the number of kilograms of grass seed needed for a border around a square fountain.” 「キログラム単位で、正方形の噴水の周りに使う芝生の種の量を計算する」のように書きます。
続いて、関数のパラメーターそれぞれについての説明をし、最後に、その関数が何を戻り値として返すのかを示します。
全体的には、以下みたいな感じですね。
def seed_calculator(fountain_side, grass_width):
'''
Calculate number of kilograms of grass seed needed for a border around a square fountain.
Parameters:
fountain_side (num): length of 1 side of fountain in meters
grass_width (num): width of grass border in meters
Returns:
seed (float): amount of seed (kg)
'''
# 以下で関数本体の定義をします
そのまま、if文による条件分岐も簡単に、
def hint_username(username):
if len(username) < 8:
print("Invalid username. Must be at least 8 characters long.")
elif len(username) > 15:
print("Invalid username. Cannot exceed 15 characters.")
else:
print("Valid username.")
まるまる、英語で読んでしまえばプログラムの実行フローはわかりますが、Python では、”else if” のような表記ではなく、”elif” と省略して追加の条件分岐を表現するので注意です。
個人的に、プログラミング言語の条件文は、”Conditional statement” だと思ってたんですが、”Branching statement” と呼んでもいいみたいですね。ただし、これは、読んで字の如く、「分岐文」と直訳できるので、プログラムのフローを分岐させるもの、例えば break, continue, goto, return なんかも含むってことでした。
Branching statements allow the flow of execution to jump to a different part of the program. The common branching statements used within other control structures include: break , continue , return , and goto . The goto is rarely used in modular structured programming.
Rebus Press: Branching Statements – Programming Fundamentals
Module 3: Loops and strings
続いて、こちらもプログラムの重要な構成要素、ループです。早速面白い英語表現あったので、メモで。
If you had to do the same thing over and over and over again… well, you might get a bit loopy.
ここで、 loopy は、頭がおかしくなりそう、とかって意味で使われてます。
strange, unusual, or silly:
Cambridge Dictionary – loopy
Python には、while ループと for ループの2種類があります。
while ループ
まずは、while ループからです。例が以下のプログラム。
i = 0
while i < 10:
if i % 2 == 0:
print(i)
i += 1
continue
i += 1
if i >= 8:
break
基本的に、while は接続詞としての英単語の意味のまま、理解すれば問題ないですね。 while とセミコロンの間にある式が Boolean を返す式となっていることに注意です。”i < 10″ が True と評価される間、すなわち、 i が10以下の間はループするって意味です。
during the time that, or at the same time as:
Cambridge Dictionary – while
その時間の間、または、それと同時に
ついでに、break と continue キーワードについても英単語の意味のままです。 “continue” は言わずもがな、「続ける」です。ここで主語を補完すると、「ループを」続けるという意味で、以降のコードは無視され、再度条件式の評価に戻ります。(上の例では、i < 10 の評価が行われれる)
“break” にはもちろん「壊す、破壊する」のような意味もありますが、「割り込む」や「中断させる」といった意味もあります。”continue” とは違い、こちらは、ループ処理そのものを中断して、次のコードに処理を進めます。上の例では、”i >= 8″ が True と評価される場合には、ループ処理を抜けるため、i が 9 になることはありません。
to interrupt or to stop something for a short period:
Cambridge Dictionary – break
中断したり、少しの時間何かを止める
for ループ
お次は、 For ループです。 Python における For ループは、いわゆる “iterable” な一連のデータに対してコードブロックを実行してくれます。
“iterable” は、コンピュータ関係の専門用語です。一般的な辞書には載ってなかったです。iterate + able の意で、以下の意味合いです。そして、Python では、その他の言語と違い、初期値やループの条件文などを for ループで指定する構文がないため、range() 関数を用いて、”iterable” な一連のデータを生成します。
to repeat a process, especially as part of a computer program
Cambridge Dictionary – iterate
プロセスを反復すること(特にコンピュータプログラムの一部として)
for odd_num in range(1, 11, 2):
print(odd_num)
上のコードでは、range()関数によって、1から始まり11より小さい整数まで、2ずつ増得るようなイテラブルなデータ(rangeクラスのインスタンス)を生成して、その要素に対して、コードブロックの実行を反復します。1, 3, 4, … 9 みたいな出力のイメージです。
このコードにおける、odd_num は、for ループのコードブロックで使われる、変数名で、よく見かけるものとして、”for num in numbers”, “for char in <文字列>” があります。もっというと、”for item in items”, “for name in names” のような形で、”for <単数形> in <複数形>”って表現をとてもよく見るので、英単語の単数複数の関係を意識できるとベターですね。
文字列
Python では、string (文字列) に対して、インデックスとスライス表現が利用できます。例えば、
my_name = 'Kazuki Maehara'
print(my_name[0])
のようにすれば、インデックス:0 の位置の文字 “K” が出力されます。Python では0基準のインデックスが使用されます。R言語のインデックスが1で始まるのとは対照的です。
また、ここで、my_name[-1] のようにしてあげると、最後の文字 “a” を選択することができます。
スライスは、インデックスと似たような表現で、以下のように書けます。
my_name = 'Kazuki Maehara'
print(my_name[0:6])
ここで [0:6] は、0〜6、すなわち、0から6まで(6は含まず)の範囲を意味します。この、始点のインデックスは含むが、終点の数字を含まないという表現は、その他のプログラミング言語でも多々見かけるので、慣れておいた方が良いです。
ちなみに、これは初めて知ったのですが、データの範囲外でインデックスを指定するとエラーになるが、スライスではエラーにならずに出力されるんですね。
my_name = 'Kazuki Maehara'
print(my_name[0:100]) # エラーにならない
print(my_name[100]) # エラーになる
文字列フォーマッティング
続いて、文字列のフォーマッティングです。
まずは、format() メソッドから、例は以下となります。
x = 'values'
y = 100
print('''文字列フォーマッティングは、{} を挿入してくれます。
その値は、数値にすることもできます。 {}.'''.format(x, y))
文字列の中で、”{}” として指定されている場所に、format()メソッドの引数としてある値が挿入されます。上記では、引数の順番通りに挿入されますが、これを指定することも可能です。
var_a = 'A'
var_b = 'B'
print('{a}, {b}'.format(b=var_b, a=var_a))
想像できる通り、”{a}” の位置に変数 “var_a” の値が、”{b}” の位置に、変数 “var_b” の値が挿入されます。
また、番号を振って、引数の順番を指定することも可能です。
print('{0}{1}{0}'.format('笑う', '泣く'))
f-string を使うことによって、メソッドの引数を文字列に挿入するのではなく、変数をそのまま文字列に挿入できます。f'<何かしらの文字列>’ といった形式になるのが特徴です。
var_a = 1
var_b = 2
print(f'{var_a} + {var_b}')
print(f'{var_a + var_b}')
print(f'var_a = {var_a} \nvar_b = {var_b}')
また、”{}”の中で、特にフォーマット方法を指定することで、表示方法に色々と調整をかけることができます。{var_a.2f:} とすることで、変数 “var_a” の値を、小数点以下2桁で表示できます。
その他のプログラミング言語と同様に「正規表現」も扱えます。
import re
my_string = 'Three sad tigers swallowed wheat in a wheat field'
re.search('[bms]ad', my_string)
正規表現については、説明しだすとキリがないので、別の記事で。上の例では、bad, mad または sad の文字列を探します。
それから、文字列クラス自体に便利なメソッドが定義されているので、この辺りに親しんでおくとベターです。 str.join() や str.split() などなど。詳細は、Python Documentation > Built-in Types > String Methods
まとめ
と、長々書いてきましたが、あまり長くなりすぎても良くないので(読む方も書く方も)
いったん、この辺りで切ります。まだまだコースの途中ですが、Python を使ってみたい、とか公式のドキュメントちょっとだけかじってみた、とかぐらいのレベルからでも良質な情報が手に入るようなコースかなと思います。
特に、実際のコーディングに直結する、Python の制御構文はコードを組みながら、慣れる必要ありです。
文字列の操作も非常に重要ですね。プログラムの設定ファイルや入力・出力ファイルも基本的にはテキストで記述されていることが多いので、文字列の扱いに長けていることがそのまま、それらのファイルの扱いに長けるのと同等です。
それでは、ひとまず 終了で、また、続編のポストを書いていきます。
コメント