公式のPython チュートリアルをざっと見る

「6 モジュール」まで。
個人的に知らなかったことや覚えておきたいことに絞り書き留めました。
Pythonはある程度知っているが、公式のチュートリアルをざっと見ておきたいと思ったのが動機。

はじめに
--

- [このチュートリアル](https://docs.python.org/ja/3/tutorial/)は、Pythonのすべてを包括的に記しているわけではないが、中心的・特徴的な機能を十分にまとめている。
- 読み終えれば、Pythonのモジュールやプログラムを読み書きできるようになっているはずである。また、[標準ライブラリ](https://docs.python.org/ja/3/library/index.html#library-index)のさまざまなライブラリモジュールについて詳しく調べられる力がつく。

1. やる気を高めよう
--
- Pythonは簡単な言語であるが多くの機構があり、大きなプログラムの開発にも適している。高級な型を組み込みで持つ"超"高級言語である。
- インタプリタ言語であり、コンパイルやリンクの必要がないので、開発の際かなりの時間を節約できる。実験的にプログラムを動かしたり、便利な電卓にもなりうる。
- CやJavaなどと比べ、とてもコンパクトで読みやすいプログラムを書ける。理由は、高レベルのデータ型や、宣言が省略できる点など様々。
- プログラミングを習得する最良の方法は、使ってみることだ。早速、次の項目からPythonインタプリタを使ってみよう。

2. Pythonインタプリタを使う
--

> Python インタプリタは、それが使えるマシン上では通常 /usr/local/bin/python3.8 としてインストールされています; Unix シェルの検索パスに /usr/local/bin を入れることによって、次のコマンドをタイプしてインタプリタを開始することができます:

```
Python3.8
```

- インタプリタは、Unixシェルと同じように使える。端末が標準入力なら、コマンドを対話的に読み込んで実行する。ファイルからスクリプトを読み込んで実行することももちろん可能。
- Pythonを起動する際のコマンドについては、[こちら](https://docs.python.org/ja/3/using/cmdline.html#using-on-general)を参照。
- インタプリタが命令待ちをしているとき、対話モードで動作していると言う。コマンド入力を促す際、一次プロンプト（>>>）を表示し、複合文の継続行を入力する際は二次プロンプト（...）を表示します。
- 対話モードの詳細は[こちら](https://docs.python.org/ja/3/tutorial/appendix.html#tut-interac)。
- デフォルトの文字コードはUTF-8である。

3. 形式ばらないPythonの紹介
--

- Pythonを電卓として使おう。
- 文字列は、単引用符('...')もしくは二重引用符("...")で囲って使う。
- 三連引用符を用いて複数行にわたる文字列を書くとき、改行文字が自動的に含まれるが、行末に￥をつけることで改行を含めないようにできる：

```python
print("""¥
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")
```

- スライスのイメージは、次のようになる：

```
 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1
```

- 最も汎用性の高いコンテナはリストで、コンマ区切りの値（要素）を角カッコに囲んだものとして書き表される。異なるデータ型の要素を１つのリストに含むこともできるが、通常は統一される。

```python
>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
```

- リストは可変なので、要素を自由に入れ替えられる。
- 入れ子のリストを作ることもできる：

```python
>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]     # 入れ子のリスト
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'
```

- 複雑な課題にも、もちろんPythonは使える。例えば、フィボナッチ数列の先頭の部分列を計算しよう：

```python

>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while a < 10:
...     print(a)
...     a, b = b, a+b
...
0
1
1
2
3
5
8
```
- 変数a, bを、複数同時代入している。
- インデントはPythonにおいて、実行分をグループにまとめるのに用いる。複合文を対話的に入力するときは、入力完了を示すために空行をEnterする。これにより、最後の行を判断できるようになる。

- キーワード引数 end を使うと、出力の末尾に改行文字を出力しないようにしたり、別の文字列を末尾に出力したりできる:

```python

>>> a, b = 0, 1
>>> while a < 1000:
...     print(a, end=',')
...     a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
```

4. その他の制御フローツール
--

- if文 ...if elif elseのキーワード
- for文 ...C言語やPascal等の言語で慣れ親しんでいるものとは少し違う。Pythonのfor文は、任意のシーケンス型(反復可能なデータ型(リスト、文字列))にわたって反復を行う。
- 反復の順番は、要素を先頭から見る。

```python
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12
```

- 通常のC言語などの数列にわたる反復を行いたい場合は、組み込み関数range()が便利。次のように使おう：
```python
>>> for i in range(5):
...     print(i)
...
0
1
2
3
4
```
- こんな使い方もできる：

```python
range(5, 10)
   5, 6, 7, 8, 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70
```

- range()は、イテラブルを返す。rangeからリストを作りたいなら、こうする。

```python
>>> list(range(4))
[0, 1, 2, 3]
```

- ループ文は、else節をもつことができる。これは、イテラブルを使い切ってループが終了したときに実行されるのだが、breakでループを抜け出した際には、実行されない。

```python
# 素数を探すプログラム
>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
```

- pass文は、何もしない。最小のクラスを定義するときなどによく使われる。関数や条件文の「仮置き」としても使える。

```python
>>> class MyEmptyClass:
...     pass
...
```

- Pythonの関数定義は、fibキーワードを使う。例えば、次の例のようにする。

```python
>>> def fib(n):    
...     """nまでのフィボナッチ数列"""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # 関数呼び出し
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
```

- returnがない関数は、実際にはNone値を返している。returnを使えば、関数から値を1つだけ受け取れる。
- メソッドは、オブジェクトに"属している"関数である。
- 関数について。デフォルトの引数値を`default=4`のように与えられる。キーワード引数と呼ばれるものがある。（関数引数を今は詳しくやらない。必要なとき、またまとめる）
- ラムダ式（キーワードlambda）を使うと、名前のない小さな関数を作れる。
- ドキュメンテーション文字列の例と、その表示：

```python
>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.
```

- 他人にとって読み易いコードを書くことはよいことだ。Pythonのコーディングスタイルとして、ほとんどのプロジェクトが守っているスタイルガイドで[PEP 8](https://www.python.org/dev/peps/pep-0008/)がある。
- その内容は、「インデントはタブを使わず、空白4つにすべきである」「演算子の前後とコンマの後には空白を入れ、括弧類のすぐ内側には空白を入れないこと: ``a = f(1, 2) + g(3, 4)``。」「クラスや関数名に一貫性のある名前をつけること」などがある。
- すべてのPython開発者はある時点でこれを読むべきである。

5. データ構造
--

- **リスト**のほぼすべてのメソッドを使った例を次に示す：

```python
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'
```

- リストをスタックとしてすぐに使える。プッシュはappend()、ポップはpop()を引数なしでリストに呼び出せば、実現できる。
- キューの実装には、 collections.deque クラスを使うとよい。
- リスト内包表記は、括弧の中の 式、 for 句、そして0個以上の for か if 句で構成される。例えば、次のように書く。

```python

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
```

- これは、次のコードと等価であるが、その簡潔さ、短さに差がみられる。

```python

>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
```

リスト内包表記の式には、複雑な式や関数呼び出しのネストができます:

```python
>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
```
コードが短く、分かりやすくかけるので積極的に使おう。

- del文を使えば、リストのインデックスを指定して値を削除できる。pop()と違い、値を返さない。スライスを除去することも可能である。

```python

>>> a = [1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
```

変数全体を削除したければ、``del a``　と書く。

- リストや文字列の他に、代表的なシーケンス（sequence）型として**タプル**がある。()丸カッコを使い、コンマで値を区切る。

```python
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
```

- タプルは不変（イミュータブル）であり、リストと異なる。
- 要素が0、もしくは1つのタプルを作成したいときは、次のようにする：

```python

empty = ()
singetion = 'hello', # string型と区別（,を置く）
```

- タプルのパックは``t = 12345, 54321, 'hello!'``、アンパックは``x, y, z = t``(右辺のシーケンスの長さは3）のように行う。
- Pythonでは**集合**（set)を扱える。和や積などの集合演算も行える。中カッコ｛｝、もしくはset()でsetオブジェクトを作成する。

```python

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
```

- **辞書型**は、「キー」（文字列や数値など）でインデクス化している。
- 辞書は キー(key): 値(value) のペアの集合であり、キーが (辞書の中で)一意でなければならない。

```python

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)  #　キーの列挙
['jack', 'guido', 'irv']  
>>> sorted(tel) # キーのソート
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
```
- 各データ型に関するループのテクニックがまとめられている。
- Pythonでは、Cとは異なり、式の中での代入は セイウチ演算子 ``:=`` を使用して明示的に行う必要があることに注意しよう。

6．モジュール
--
- 長いプログラムを書きたければ、テキストエディタ等を使ってインタプリタへの入力をファイルで用意しておき、そのファイルを入力して動作させるとよい。Pythonの定義や文が入ったファイルのことをモジュールと呼び、``.py``拡張子がついたファイルになる。
- 例えば、次のようなファイルをテキストエディタで作ってみよう：

```fibo.py
# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result
```

Pythonインタプリタで、このモジュールをインポートすれば、関数を使用できる。

```python
# インタプリタ上
>>> import fibo

>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
```
次のように、特定の関数だけをインポートすることもできる：

```python
# fromキーワード
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
```

- モジュールをスクリプトとして実行したければ、

```python

python fibo.py <引数名>
```
と書けばよい。

- パッケージについて詳しく書かれているが、飛ばす。

おわりに
--

まだ残っているが、残りは必要を感じた時に調べる。
チュートリアルにどんなことが書かれているか大体分かったのでよかった。
「[標準ライブラリミニツアー](https://docs.python.org/ja/3/tutorial/stdlib.html)」は、見て理解しておくと役に立ちそう。