徹底攻略Python3エンジニア認定基礎試験 問題集 --impress-- 13章総仕上げ問題 解いてみた

## 「Python3エンジニア認定 ［基礎試験］」 合格を目指します。

試験日まで、1週間を切りました。
ぼちぼち合格ラインの押上に入ります。

使用教材：
・Pythonチュートリアル第4版 --オライリー・ジャパン--
・徹底攻略Python3エンジニア認定基礎試験 問題集 --impress--

徹底攻略Python3エンジニア認定基礎試験 問題集 --impress--
13章 総仕上げ問題
35/40
点数にすると、87.5/100点満点なので、ぎりぎり合格ライン。

間違えた内容の大半は「12章.標準ライブラリ」関係でした。。。
確かにここの部分はあまり力いれていなかったかもしれません。
（というか飛ばしたかも！？）

## 見直し
**【標準ライブラリ】**
**●OSモジュール**
**os.getcwd()**：カレントディレクトリを取得する。
**os.chdir(移動先)**：カレントディレクトリを移動する。

**●コマンドライン引数**
プログラム実行時に指定できる特殊な引数。
　**Python プログラム名.py 引数1 引数2 ...**
コマンドライン引数は、sysモジュールの**argv属性**を使用してリストで取得できる。

例：
[python check.py 1 2]を実行して['check.py', '1', '2']が表示される。
```ruby:【check.py】
import sys
print(sys.argv)
```

**●argparseモジュール**
argparseモジュールのArgumentParser()を使っても、コマンドライン引数を取得できます。
sysモジュールのargv属性よりも、扱いやすいコマンドラインのインターフェースを作成できます。

```ruby:【parse.py】
import argparse

parser = argparse.ArgumentParser() # 【A】
parser.add_argument("--head") # 【B】
parser.add_argument("body", nargs="+") # 【B】
args = parser.parse_args() # 【C】
print(args) # 【D】
```
【A】parserの作成
最初に、parserという名前でパーサ（構文解釈器）のオブジェクトを作成します。

【B】引数の情報を追加
作成したオブジェクトに、add_argument()メソッドで引数の情報を追加します。
追加後は、コマンド実行時に2種類の引数が必要になります。1つは--head=値で、もう一つは1個以上の任意形式の引数です。nargs="+"が「1個以上」の指定です。

【C】引数の情報を取得
変数argsを作成し、引数の情報を代入します。
parser.parse_args()メソッドを使用することで、引数の情報を取得できます。

【D】引数の情報の出力
引数の情報（args）を出力すると、下記のようになります。
```ruby:実行結果
Namespase(head='1', body=['2', '3'])
```

**●mathモジュール**
**log()**
対数を求める関数。
lod(値,底)は、返り値を「n」とした場合、底のn乗が値になります。
例：log(16,2)=4.0 （※2の4乗のため）

**●randomモジュール**
「random.randrange(a, b)」 は、「a以上、b未満」の整数を返します。
「random.randint(a, b)」は、「a以上、b以下」の整数を返します。
「random.sample(シーケンス, 抽出数) 」は、シーケンスの中から指定の数を重複なしで抽出します。
「random.choices(シーケンス, 抽出数) 」は重複ありで抽出します。
「random.choice(シーケンス)」は、シーケンスの中から一つ抽出します。
「random.random()関数」は、0以上1未満のランダムな値（小数）を返します。（引数は設定できない）

**●statisticsモジュール**
数理統計に用いる関数が含まれる。
・statistics.mean()
データの平均を求める。
・statistics.median()
データの中央値を求める。
・statistics.variance()
データの不偏分散を求める。

※不偏分散：平均との差の2乗の和を「データ数-1」で割って求めます。

**●datetimeモジュール**
日時のオブジェクトを作成する
```ruby:
from datetime import datetime

dt = datetime(2000, 12, 31)
```
この変数dtを決められた形式の文字列で表示するには、dt.strftime(フォーマット)のように記述する。
```ruby:
ptint(dt.strftime("%Y-%m-%d")
2000-12-31
```

**●単体テスト**
Pythonで単体テストを実施するには、**unittestモジュール**を使用します。
unittestによる単体テストでは、テスト対象のモジュールとは別に、テスト実行側の.pyファイルを用意する必要があります。
ファイル作成後に、コマンドラインから「python -m unittest」のように実行すると、対象の関数やメソッドのテスト結果を確認できます。

```ruby:
import unittest
import mod #テスト対象をインポートする

class TestSample(unittest.TestCase):
    def test_it(self):
        actual = mod.calc(2, 3) #テスト対象の実行結果
        expected = 5 #期待する結果
        self.assertEqual(actual, expected) #結果が同じことを確認
```
```ruby:
# 結果が同じ場合の最終行
OK

# 結果が異なる場合の途中の出力
AssertionError: 6 != 5
```

**●出力データの整形**
pprint()関数は、1行が80文字を超えると要素ごとに改行します。

```ruby:リストを改行して出力する1
import pprint

pprint.pprint(lines)
```
```ruby:【実行結果】
['sample test string 0000',
 'sample test string 0001',
 'sample test string 0002']
```

なお、下記のようにしても要素ごとに改行されるが、角括弧[]などが表示されない。
```ruby:リストを改行して出力する2
print(",\n".join(lines))
```
```ruby:【実行結果】
sample test string 0000,
sample test string 0001,
sample test string 0002
```
textwrapモジュールのfill()関数を使うと、widthで指定した幅に収まるように整形します。
```ruby:リストを改行して出力する3
import textwrap
print(textwrap.fill(", ".join(lines), width=24))
```
```ruby:【実行結果】
sample test string 0000,
sample test string 0001,
sample test string 0002
```

**●reモジュール**
re.sub(パターン、置換文字列、対象文字列)を使うと、対象文字列内で特定のパターンにマッチする部分を、置換文字列に変換できます。


<table>
 <caption>【特殊文字】</caption>
  <thead>
    <tr>
      <th>特殊文字</th> <th>意味</th>
    </tr>
  </thead>
  <tr>
    <td> () </td> <td>括弧内をグループ化/td>
  </tr>
  <tr>
    <td> [a-z] </td> <td>小文字のアルファベット1文字</td>
  </tr>
  <tr>
    <td> + </td> <td>直前の文字の1回以上の繰り返し</td>
  </tr>
  <tr>
    <td> \1 </td> <td>1番目のグループ</td>
  </tr>
</table>

```ruby:正規表現による文字列の置換
s = "tic tac tac toe"
print(re.sub(r"([a-z]+) \1", r"\1", s))
```
※rを付けるとバックスラッシュ「\」そのものになる。