Pythonエンジニア認定基礎試験 最後のツメ

## 模擬試験一覧
- [G検定、Python、Rubyの模擬テスト | DIVE INTO EXAM](https://exam.diveintocode.jp/exam)
- [PRIME STUDY（プライム・スタディ） – Python試験とPHP試験の無料模擬試験サイト](https://study.prime-strategy.co.jp)

## お勉強サイト
- [Pythonエンジニア認定試験対策用メモ - Qiita](https://qiita.com/R1ck29/items/17f8bcf70feb2c3d516c)
- [Pythonチュートリアル(6章)の内容を箇条書きでまとめた - Qiita](https://qiita.com/Wakii/items/be7065faf917d7881610)
- [Pythonの組み込みデータ型の分類表（ミュータブル等） - GAMMASOFT](https://gammasoft.jp/blog/python-built-in-types/)

## 3章 気軽な入門編
#### 除算は割り切れてもfloatを返す
```python
print(type(1/1)) # >>> <class 'float'>
```

#### fstringはindexに注意
```python
print('{1:.5f}, {0:.3f}'.format(math.pi, math.e))
# 2.71828, 3.142
```

## 4章 制御構造ツール
#### 位置引数が先でキーワード引数が後
> キーワード引数には順番はない

```python
def f(a, b="Bob", c="Charly", d="Dom"):
    print(a, b, c, d)

f("Alice", "Mr. Bob", d="Ms. Dom", c="Mrs. Charly")
```

#### 可変長引数には`*`と`**`を使う
> `*`配列、`**`辞書型の順序で書く

```python
def print_args(*args, **kwargs):
    print("Positional arguments:", args)
    print("Keyword arguments:", kwargs)
    
print_args("a", "b", c="cc", d="dd")

# >>> Positional arguments: ('a', 'b')
# >>> Keyword arguments: {'c': 'cc', 'd': 'dd'}
```

#### 配列のアンパッキングには`*`を使う
```python
a = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
print(*a)            # >>> [0, 1, 2] [3, 4, 5] [6, 7, 8]
print(list(zip(*a))) # >>> [(0, 3, 6), (1, 4, 7), (2, 5, 8)]
```

#### 辞書のアンパッキングには`**`を使う
```python
dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
print({*dict1, *dict2})   # >>> {'a', 'b', 'd', 'c'}
print({**dict1, **dict2}) # >>> {'a': 1, 'b': 2, 'c': 3, 'd': 4}
```

## 配列の指定はアドレスであることを忘れるな！
> 以下のようなデフォルト値に`[]`が指定されている場合、その配列はずっと残っている

```python
def f(a, arr=[]): # 関数定義時に配列が初期化される
    arr.append(a)
    print(arr)

f(1) # >>> [1]
f(2) # >>> [1, 2]
f(`a`, []) # >>> [a]
f(3) # >>> [1, 2, 3]
```

## 5章(1) データ構造
#### スライスでディープコピーができる！
```python
old = ['1', '2', '3']
new = old[:]
new.insert(2, 'a')
print(old) # >>> ['1', '2', '3']
print(new) # >>> ['1', '2', 'a', '3']
```

#### リスト内法表記
以下の2つは同じである。

```python
l = [(x, y) for x in [0, 1, 2] for y in [1, 2, 3] if x != y]
```

```python
l = []
for x in [0, 1, 2]:
    for y in [1, 2, 3]:
        if x != y:
            l.append((x, y))
```

#### 始点からマイナスまで取り出す
```python
x = ["a","b","c","d","e"]
print(x[:-3]) # >>> ["a","b"]
```

#### ミュータブルとシーケンス
> 文字列(str)とタプルは変更不可
> 辞書(dict)と集合(set)は順序を持たない

|   | 変更不可(immutable) | 変更可(mutable) | シーケンス |
| ---- | :----: | :----: | :----: |
|str|◎||◎|
|list||◎|◎|
|tuple|◎||◎|
|range|◎||◎|
|dict||◎||
|set||◎||

## 5章(2) 論理演算子
- [Python の or と and 演算子の罠 - Qiita](https://qiita.com/keisuke-nakata/items/e0598b2c13807f102469)

#### 複数並んだ比較演算子は`and`で連結される
```python
print(1 > -1 == (1-2))        # >>> True
print(1 > -1 and -1 == (1-2)) # >>> True
```

#### 論理式の結果はbool値とは限らない！
```python
a = "" or "A" or "B"
print(a) # >>> "A"

b = "" and "A" and "B"
print(b) # >>> "B"
```

## 6章 モジュール
- [Pythonチュートリアル(6章)の内容を箇条書きでまとめた - Qiita](https://qiita.com/Wakii/items/be7065faf917d7881610)

#### コンパイル済みモジュール名
> `pycache`ディレクトリに`module.バージョン名.pyc`で保存する

#### ビルトイン関数dir()
> モジュールが定義している名前を確認することができる
   
```python
dir(モジュール)
dir(パッケージ)
dir(クラス)
```

#### sys.path
> モジュールを検索するパスを示す文字列のリスト。
> PYTHONPATH 環境変数と、インストール時に指定したデフォルトパスで初期化されます。

## 8章 エラーと例外
#### Exceptionのargsって？
```python
except Exception as e:
    print(type(e))    # Exceptionを継承したインスタンス
    print(e.args)     # 引き数のリスト
    print(e)          # __str__が呼ばれ、引き数を表示する
```

## 10章 標準ライブラリめぐり
#### blob
> `blob.blob('*.py')`で指定ディレクトリのpythonファイル一覧を取得する

#### dateとdatetime
```python
from datetime import date
print(date.today()) # >>> 2021-05-18

from datetime import datetime
print(datetime.now()) # >>> 2021-05-18 20:48:34.141743
```

#### random
> `random.sample`は重複なし
> `random.choices`は重複あり

```python
l = [0, 1, 2, 3, 4]
print(random.sample(l, 3))     # >>> [3, 1, 4]
print(random.choices(l, k=10)) # >>> [3, 4, 1, 4, 4, 2, 0, 4, 2, 0]
```

## 12章 仮想環境とパッケージ
#### 仮想環境の作成
```sh
$ python -m venv workspace
$ workspace\\Scripts\\deactivate # アクティベート状態から抜けるコマンド
$ workspace\\Scripts\\activate # アクティベート状態に入るコマンド
```

#### pip
> `pip list`と`pip freeze`はパッケージをすべて表示する

```sh
$ pip list
Package    Version
---------- -------
future     0.16.0
pip        18.1

$ pip freeze
future==0.16.0
six==1.11.0
```

#### pipバージョン指定
> `==`でバージョン指定する

```sh
$ pip install six==1.8.0
```

#### バイトコンパイル
> コンパイルしたファイル名は、`モジュール名.Pythonバージョン.pyc`となる
> ディレクトリ`__pycache__`に保存される

```sh
$ python -m compileall test.py
$ ls __pycache__/
test.cpython-38.pyc
```