Python基礎のおさらい

Python の基本をおさらいしておきます。
公開している[Udemyコース](https://www.takux.one/)でちょくちょく参照できるように載せておきます。

## 変数

一般的な変数定義(代入)です。

```python
a = 1
b = 2

print(a)
print(b)
# 1
# 2
```

複数の変数定義を 1 行で行うこともできます。

```python
a, b = 1, 2

print(a)
print(b)
# 1
# 2
```

インクリメントの例です。

```python
a = 1
a = a + 1

print(a)
# 2
```

インクリメントの省略記載例です。

```python
a = 1
a += 1

print(a)
# 2
```

## リストのスライス

スライスでは要素数以上のインデックス番号（以下では 100 を指定）を指定してもエラーにはなりません。

```python
sample_deck = ['A', '2', '3', '4', '5']

print(sample_deck[:100])
print(sample_deck[100:])

# ['A', '2', '3', '4', '5']
# []
```

例として、sample_deck を余りなく、２等分したい場合は次のようにすることができます。

```python
n = 3
print(sample_deck[:n])
del sample_deck[:n]
print(sample_deck[:n])

# ['A', '2', '3']
# ['4', '5']
```

## if

通常の if 文です。

```python
if True:
    print(1)

# 1
```

if-else 文です。

```python
if True:
    print(1)
else:
    print(2)

# 1
```

if-elif-else 文です。

```python
n = 12
if n <= 10:
    print(1)
elif n > 10:
    print(2)
else:
    print(3)

# 2
```

## for

通常の for 文です。

```python
# get out an elem
sample = ['hoge', 'fuga', 'piyo']
for v in sample:
    print(f'v == {v}')

# v == hoge
# v == fuga
# v == piyo
```

インデックス番号をループしている例です。

```python
# loop with indexes
sample = ['hoge', 'fuga', 'piyo']
for i in range(len(sample)):
    print(f'i == {i}, v == {sample[i]}')

# i == 0, v == hoge
# i == 1, v == fuga
# i == 2, v == piyo
```

enumerate 関数によって、インデックス番号と要素を同時に取り出している for 文です。

```python
# get out an indexe and an elem
sample = ['hoge', 'fuga', 'piyo']
for i, v in enumerate(sample):
    print(f'i == {i}, v == {v}')

# i == 0, v == hoge
# i == 1, v == fuga
# i == 2, v == piyo
```

## 関数

引数のない関数です。

```python
def foo():
    return 'hoge'

print(foo())

# hoge
```

引数のある関数です。

```python
def foo(x):
    return f'hoge and {x}'

print(foo('fuga'))

# hoge and fuga
```

関数注釈をつけておくと、引数の型や、返り値の型を明示できます。ただし、これは型を強制している訳ではなく、あくまでどういう型であってほしいかを記載しているだけです。

```python
def foo(x: str) -> str:
    return f'hoge and {x}'

print(foo('fuga'))

# hoge and fuga
```

関数の説明を docstring に記載しておくと、関数を使用するときに便利です。

```python
def foo(x: str) -> str:
    """
    Write description here.
    """
    return f'hoge and {x}'

print(foo('fuga'))

# hoge and fuga
```

## 可変長引数

可変長引数(位置引数)のある関数です。 次のコードでは引数にアスタリスク `*` を付けることで可変長引数としています。この場合、args には好きなだけ引数を渡すことができます（だからこそ可変）。args は tuple になっているので、中でそれぞれの引数を取り出して使うことができます。

```python
def foo(x, *args):
    return f'type of args:{type(args)}, args:{args}'

result = foo('fuga', 'a', 'b', 'c')
print(result)
# type of args:<class 'tuple'>, args:('a', 'b', 'c')
```

可変長引数(キーワード引数)のある関数です。 次のコードでは引数にアスタリスク `**` を付けることで可変長引数（キーワード引数）としています。この場合、kwargs には好きなだけキーワード引数を渡すことができます（だからこそ可変）。kwargs は dict になっているので、key を指定してそれぞれの引数を使うことができます。

```python
def foo(x, **kwargs):
    return f'type of kwargs:{type(kwargs)}, kwargs:{kwargs}'

result = foo('fuga', a='A', b='B', c='C')
print(result)
# type of kwargs:<class 'dict'>, kwargs:{'a': 'A', 'b': 'B', 'c': 'C'}
```

## クラス

foo はインスタンス（self）に属するメソッドです。

```python
class MyClass():
    def foo(self, x: str) -> str:
        """
        Write description here.
        """
        return f'hoge and {x}'

myclass = MyClass()
print(myclass.foo('fuga'))

# hoge and fuga
```

_init_メソッドは、初期化メソッドと呼ばれるものです。インスタンス生成時に自動的に実行されます。

```python
class MyClass():
    def __init__(self, name: str):
        self.name = name

myclass = MyClass('piyo')
print(myclass.name)

# piyo
```

## set 関数

set 関数は要素が重複しないので、下記ではリストより要素数が少なくなっています。

```python
hoge = [100, 200, 300, 300, 200]

print(hoge)
print(set(hoge))

# [100, 200, 300, 300, 200]
# {200, 100, 300}
```

## 破壊的処理

append、remove など、リストのメソッドの多くは破壊的処理なので、実行しただけで元のリストを変更します。

```python
a = [100, 200, 300]

x = a.append(400)

print(x)
print(a)

# None
# [100, 200, 300, 400]
```

pop も破壊的処理ですが、返り値はあり、取り出した要素を return します。

```python
a = [100, 200, 300]

x = a.pop()

print(x)
print(a)

# 300
# [100, 200]
```

関数内において、リストなどで破壊的処理を実行する場合は、return しなくても済む場合があります。

```python
# returnしない関数。
# returnしなくてもリストの中身が追加されます。
def hoge(fuga):
    fuga.append('piyo')

a = [100, 200, 300]
hoge(a)

print(a)
# [100, 200, 300, 'piyo']
```

## try-else 文

try 文には else を追加できます。else はエラーが発生しなかった場合に実行されます。

```python
# エラーが発生しないケース
try:
    print('tryの中の初めです。')
    # raise Exception()
    print('tryの中の終了です。')
except Exception:
    print('exceptが実行されました。')
else:
    print('elseが実行されました。')

# tryの中の初めです。
# tryの中の終了です。
# elseが実行されました。
```

```python
# エラーが発生するケース
try:
    print('tryの中の初めです。')
    raise Exception()  # ここで強制的にエラーを発生させてみます。
    print('tryの中の終了です。')
except Exception:
    print('exceptが実行されました。')
else:
    print('elseが実行されました。')

# tryの中の初めです。
# exceptが実行されました。
```