Pythonエンジニア認定試験対策用メモ


##はじめに
Pythonエンジニア認定試験の受験対策用のメモです。
主教材であるオライリー・ジャパン「Pythonチュートリアル 第3版」の掲載内容を参照しています。
その中から特筆すべき点を記載しています。

##Pythonエンジニア認定試験の出題範囲
|章立て|	出題数|	出題率|
|:-----------------|------------------:|:------------------:|
|1章　食欲をそそってみようか	|1|	2.5%|
|2章　Pythonインタープリタの使い方	|1|2.5%|
|3章　気楽な入門編	|6|	15.0%|
|4章　制御構造ツール|	9	|22.5%|
|5章　データ構造	|7|	17.5%|
|6章　モジュール	|2|	5.0%|
|7章　入出力	|1|	2.5%|
|8章　エラーと例外|	4	|10.0%|
|9章　クラス|	2|	5.0%|
|10章　標準ライブラリめぐり	|4	|10.0%|
|11章　標準ライブラリめぐり─PartII|	1|	2.5%|
|12章　仮想環境とパッケージ|	1|	2.5%|
|13章　次はなに?	|0|	0.0%|
|14章　対話環境での入力行編集とヒストリ置換|	1	|2.5%|
|合計|	40	|100.0%|


##2章 Pythonインタープリタの使い方

###インタープリターを終了する
```python:Python
>>> quit()  
```
###モジュールの指定を行う
> インタープリンタを起動時のオプションとして「-m モジュール名」を指定した場合、
sys.argv[0]には指定したモジュールのファイル名が完全な形で入る。

###ソースコード・エンコーディング

PythtonのファイルはUTF-8でエンコードしてあるものとして扱われる。
他のエンコーディングに変更する際は、以下の一文を１行目または２行目に記載し指定する。

```python:Python
# -*- coding: エンコーディング名 -*-
```

この記述によって、ソースファイルの全てのキャラクタはUTF-8ではなく、
エンコーディング名に指定したエンコーディングを持つものとして扱われる。


##3章 気軽な入門編
###数値
```python:実装例
>>> 25//7 # 切り下げ徐算は小数点以下を捨てる
# 3
```

演算対象の型が混同していた場合は、整数は浮動小数点に変換される

```python:実装例
>>> 3 * 3.75 / 1.5
# 7.5
>>> 7.0 /2
# 3.5
```

####対話モード時の「_ 」(アンダースコア)

最後に表示した式を格納している

```python:Python
>>> tax = 12.5 / 100
>>> price= 100.5
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_,2)
113.06
```

####Python がサポートする複素数の虚部を表す接尾辞
####「j」または「J」

###文字列
- バックスラッシュ(\)でクォート文字のエスケープができる。
- 「\n」は改行の意味

```python:実装例

d = 'dive\ninto\ncode\t'
print(d)

# dive
# into
# code	
```
***しかし、長さに「n」や「t」は含まれる***

```python:実装例

d = 'dive\ninto\ncode\t'

print(len(d))

# 正解: 15
```

##4章 制御構造ツール
###range()

```python:Python
range(5, 10)
# 5から9まで

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

range(10)
# 0から9まで

print(range(10))
# range(0,10)
```
###キーワード引数

***関数をコールする時は、必ず位置引数が先でキーワード引数を後にしなければならない。***

```python:実装例
sample_function('a', b='keyword')
```

###引数リストのアンパック
>*演算子を使って関数をコールすることで、リストやタプルからアンパックした引数を渡すことができる。

```python:実装例
>>> list(range(3,6))   # 個別の引数を使った普通のコール
[3,4,5]
>>> args = [3, 6]
>>>list(range(*args))  # リストからアンパックした引数でコール
[3,4,5]
```
```python:模擬試験問題
def dive_into_code(teacher, *mentor):
    print(teacher)

dive_into_code('Noro', 'Nakao', 'Miyaoka')
# 正解: Noro
# -----------------------------------------
dic = [
    ['Noro', 'Nakao', 'Miyaoka'],
    ['Kimura', 'Miyashita', 'Shibata'],
    ['Matsumoto', 'Tanaka', 'Ivan'],
]

print(list(zip(*dic)))

# 正解: [('Noro', 'Kimura', 'Matsumoto'), ('Nakao', 'Miyashita', 'Tanaka'), ('Miyaoka', 'Shibata', 'Ivan')]
```

>同じように**演算子を使えば、ディクショナリをキーワード引数にして渡すことができる

###lambda(ラムダ)式
キーワードlambdaを使うと小さな無名関数が書ける。
「lambda a, b: a+b」は、２つの引数の和を返す関数である。

以下のように、小さな関数を引数として渡す時にも使える。

```python:模擬試験問題

dive_into_code = [(1, 'Noro'), (2, 'Nakao'), (3, 'Miyaoka'), (4, 'Kimura')]
dic = dive_into_code
dic.sort(key=lambda dic: dic[1]) #1は第二要素の名前を昇順にする。0の場合、第一要素の数字に対し昇順にする。

print(dic)
# 正解: [(4, 'Kimura'), (3, 'Miyaoka'), (2, 'Nakao'), (1, 'Noro')]
```

###コーディングスタイル
####PEP8重要ポイント
- インデントはスペース４つとし、タブは使わない。
- ４スペースは狭いインデント（深い入れ子が可能になる）と広いインデント（読みやすい）のちょうど良い妥協点だ。タブは混乱の元なので避ける。
- 79文字以下で折り返す。
- 関数やクラス、さらには関数内の大きめのブロックを分離するのに空白行を使う。
- 可能であればコメント行は独立させる。
- docstringを使う。
- 演算子の周囲やカンマの後ろにはスペースを入れるが、カッコのすぐ内側には入れない。「a = f(1, 2) + g(3, 4)」のようにする。
- クラスや関数には一貫した命名を行う。クラスには　CamelCase、関数やメソッドにはlower_case_with_underscoresを使う。メソッドの第一引数としては常にselfを使うようにする。
- 国際的な環境で使うつもりのコードでは手前勝手なエンコーディングは使わない。PythonのデフォルトであるUTF-8か、プレーンなASCIIが常に最良である。
- 同様に、違う言葉を喋る人たちが読んだり保守したりする可能性が少しでもあるコードでは識別子に非ASCIIキャラクタを使わない。

##5章 データ構造
###リスト

```python:Python
# リストから全てのアイテムをクリアする
list.clear()
del list[:]

list = [5,3,1,2,3,4,5,2]
list.remove(2) # 指定した値に初めてマッチしたものを削除する
# [5,3,1,3,4,5,2]
```

####list.count(x)
- リスト中のｘの個数を返す。

```python:Python
num_list  = [2, 4, 6, 4, 4, 2, 6]
for i in range(num_list.count(4)):
    print(i, end=' ')
# 0 1 2
```
###タプルとシーケンス
>タプルは変更不能(immutable)であり、異種の要素によってシーケンスを作り、
各要素にはアンパッキングやインデックスで(そして名前付きタプルの場合は属性でも)アクセスする、というのが通例だ。

###ディクショナリ
###enumerate()
位置インデックスとそれに対応した値を同時に得ることができる

```python:Python
for i,v in enumerate(['tic', 'tac', 'toe']):
    print(i,v)
# 0 tic
# 1 tac
# 2 toe
```

####keys()

辞書オブジェクトに含まれる全てのキーを要素としたリスト型のオブジェクトを返す。
以下、keys()についての模擬試験問題

```python:Python
# 問題文のプログラムを実行した場合の、出力結果を選びなさい。
member = {1: 'Noro', 2: 'Nakao', 3: 'Miyaoka'}
member[4] = 'Kimura'
del member[3]
print(list(member.keys()))
# 正解：[1, 2, 4]
```
####values()
辞書オブジェクトに含まれる全ての値を要素としたリスト型のオブジェクトを返す。

```python:Python
member = {1: 'Noro', 2: 'Nakao', 3: 'Miyaoka'}
member[4] = 'Kimura'
del member[3]
print(list(member.values()))
# 正解：['Noro', 'Nakao', 'Kimura']
```

###dic
```python:実装例
dic = 'diveintocode'
print(dic[1:10:2]) #0から数えて1文字目が始点、位置10(10を含まない)までが終点で、2文字ごとの字を抽出する
# ienoo 
```
###条件についての補足
####ブール演算子
>ブール値でなく一般値が使われた時は、短絡演算子の返り値は最後に評価された引数となる。
>また、比較その他のブール式の結果は変数に代入できる。

```python:実装例
name1,name2,name3,name4= '', 'suzuki','tanaka','sato'
selected_name = name1 or name2 or name3 or name4
print(selected_name)
#　正解: suzuki
```


##6章 モジュール

###モジュールの検索パス
sys.pathの初期化で参照しないもの
スクリプトが存在するフォルダのシンボリック先

###「コンパイル済」Pythonファイル
***モジュール読み込みの高速化の為、Pythonはコンパイル済みのモジュールを
__pycache__ディレクトリにmodule.バージョン名.pycの名前でキャッシュする。***

###dir()
ビルトイン関数dir()は、モジュールが定義している名前を確認するのに使う。

```python:実装例
import fibo,sys
dir(fibo)
# ['__name__', 'fib','fib2']
```

###パッケージ
####パッケージとは、ドット区切りモジュール名を使ってPython のモジュールを構築する方法

##7章 入出力
### ファイルの読み書き
***open()の第二引数は「モード」を指定する。***

- 読み込み専用の場合は、「r」
- 書き出し専用なら、「w」
- 追加、書き込みデータがファイルの末尾に自動的に加えられていくようにするなら、「a」
- 読み書き両用なら、「r+」

```python:実装例
>>> f = open('workfile', 'w')
```

##8章 エラーと例外
##例外の処理
>try...except文には、オプションでelse節が入れられる。
位置は全てのexcept節より後ろでなければならない。
ここに入れたコードはtry節が例外を送出しなかった時にのみ実行される。

```python:実装例
for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()
```

###オブジェクトに定義してあるクリーンアップ動作

>With文を使うと、ファイルのようなオブジェクトを、使用後すぐに適切な方法でクリーンアップされルことを保証した形で
利用できるようになる。

```python:実装例
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")
```

>この文の実行後、ファイルｆは必ずクローズされる。
行の処理中に問題が起きたとしても、常にクローズされる。


##9章クラス

###クラス変数とインスタンス変数

>クラス変数はクラスのすべてのインスタンスが共有する属性やメソッドのためにあり、
>インスタンス変数は、それぞれのインスタンスに固有のデータのためにある。

```python:Python
class Sample:
    c_list = []  # どのインスタンスも持つことになるクラス変数。クラス変数の使い方を間違えた例
    def add_c_list(self, data):
        self.c_list.append(data)  # インスタンスごとに固有のインスタンス変数

print("出力結果:", end=" ")
sample1 = Sample()
sample1.add_c_list("データ1")

sample2 = Sample()
sample2.add_c_list("データ2")

for item_data in sample1.c_list:
    print(item_data, end=" ")

# ["データ1", "データ2"]
```
***インスタンス変数を使うことで共有しない。***

```python:Python
class Sample:
    def __init__(self):
        self.c_list = [] #それぞれのサンプルに新たに空リストを生成
    def add_c_list(self,data):
        self.c_list.append(data) 

print("出力結果:", end=" ")
sample1 = Sample()
sample1.add_c_list("データ1")

sample2 = Sample()
sample2.add_c_list("データ2")

for item_data in sample1.c_list:
    print(item_data, end=" ")

# ["データ1"]
```

##10章 標準ライブラリめぐり
###コマンドライン引数
引数は、sysモジュールのargv属性にリストとして格納されている。
以下は、コマンドラインで「python demo.py one two three」を実行した状態にあるものとする。

```python:Python
>>> import sys
>>> print(sys.argv)
['demo.py', 'one', 'two', 'three']
```

###数学

####平方根を求める

```python:Python
import math
math.sqrt(2)
# 1.414213562
```

##11章 標準ライブラリめぐり - Part2
###出力整形
####reprlib()

```python:Python
from reprlib import repr
many_item_list = [i for i in range(100)]
repr(many_item_list)

# '[0, 1, 2, 3, 4, 5, ...]'

```
###バイナリデータレコード処理
***structモジュールは、可変長のバイナリレコードを処理する関数であるpack()と
unpack()を提供する。***

###ログ取り
***ログを取得するためのモジュールは、「logging」***

```python:実装例
import logging
```

##12章 仮想環境とパッケージ
###pip
```python:Python
>>> pip list # インストール済み確認
```

###アクティベート状態から抜けるコマンド
```python:Python
>>> deactivate 
```

##15章 浮動小数点の演算:その問題と限界
###round()
```python:Python
str(round(pi, i)) for i in range(0, 5)
# 3.0 3.1, 3.14, 3.142, ...  第二引数はどこまで出力するかを設定する
```

##その他(模擬試験問題)

#####1. 対話環境のでヒストリ情報が保存されているファイルを選択肢の中から選びなさい。
***正解: .python_history***

#####2. 以下のプログラムをインタープリタにて実行した際の出力結果を選びなさい。

```python:Python
(1,3,5) < (1,2,3,4)
# 正解: FALSE
```