【備忘録】pythonのコーディング試験に向けて

#はじめに
就職活動でpythonコーディング試験が用意されているところもあり、それに備えて、恥ずかしながら「ちゃんと知らなかった」なことを、**備忘録**として残しておきます。
※途中URLの貼り付けが多くなります。

[こう](https://www.pekita.xyz/entry/2017/09/11/170000)[いった](https://plaza.rakuten.co.jp/eiji0829/diary/?ctgy=8)記事もありました。

#mathモジュール

```python
>>> import math
>>> math.cos(math.pi/3)
0.5000000000000001
```
math.piによってπを呼び出します。πも当然計算式に入れられるので、今回は３で割っています。その値をに対する、コサインをmath.cos()を使って求めるというものです。
pi()ではなくpiであることに注意。

#JSON形式の出力

```python
>>> import json
>>> x = {'name':'hiroyuki','date':[1985,1214]}
>>> print(json.dumps(x))
{"name": "hiroyuki", "date": [1985, 1214]}
```

JSONは、JavaScriptというプログラミング言語のオブジェクト表記法をベースに作られたデータフォーマットのことで、JavaScript、PHP、Rubyを使う人など、このデータを渡すだけで、それぞれが処理することができます。
今はAPIがとても普及?しているので、サービスを提供する側が、どのようなプログラミング言語でも処理をしやすいように、JSON形式にしていることが多いです。

JSONの作りとしては、辞書型のようにkey:valueのペアで成り立っていおり、要素はカンマで区切られ、全体が{　}波括弧で囲まれています。

```json-doc
{"name":"hiroyuki","date":[1985,1214]}
```

JSONのフォーマットを処理するには、JSON形式で記述されたデータフォーマットを使用できる形式に変換(デコード)する必要がありますし、一方でJSON形式に変換(エンコード)したりすることも当然あります。

冒頭記載したように、エンコードする場合にはjson.dumps（）メソッドを使用し、デコードする場合はjson.loads（）メソッドを使用するようになっています。

#内包表記

以下のような内包表記

```python
>>> [(x, y) for x in [0,1,2] for y in [1,2,3] if x != y]
```
があった場合に、出力結果はいかのようになります。
出力結果を見ればどのように処理されてるかわかりますね。

```python
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 1), (2, 3)]
```
というようになります。
つまり
**xの1番目の要素**と**yの1番目の要素**
が最初に呼び出された次にくるのは
**xの1番目の要素**と**yの2番目の要素**
さらに次に来るのは
**xの1番目の要素**と**yの3番目の要素**
さらに次に来るのに注意が必要で、最後のifが適用されるので
xの2番目の要素とyの1番目の要素ではなく
**xの2番目の要素とyの2番目の要素**
となります。あとは同じように考えればいいだけです。

#Pythonにおけるタブ補完について

変数やモジュール名の補完機能については、**インタープリタの起動時**に自動で有効になっています。当たり前のように感じますが。

#print()とlist()とrange()の組み合わせ

```python
>>> print(list(range(5)))
[0, 1, 2, 3, 4]
```
range()によって0から数えた5番目の要素を呼び出し、それをlist()によってリストにパックして、それをprint()によって出力するというとても簡単なもの。

#reprlib

reprlibを利用することで、出力の長さを制限することができます。
またset関数を利用することで、ユニークで集合ができます。

```python
>>> reprlib.repr('111111111111111112222222222222223333333333333333444444444444445555555555')
"'111111111111...4445555555555'"
>>> reprlib.repr(set('111111111111111112222222222222223333333333333333444444444444445555555555'))
"{'1', '2', '3', '4', '5'}"
```

[こちら](http://st-hakky.hatenablog.com/entry/2017/11/28/144751)を一瞬拝見しました。



#シーケンスオブジェクトのそれぞれについて

タプル：イミュータブル(変更できない)
リスト：ミュータブル（変更できる）

アンパッキングしてアクセスすることができる。
※アンパックについては[こちら](https://note.nkmk.me/python-tuple-list-unpack/)を参考に

#def文の書き方

関数を作成する時には、引数でデフォルト値を指定しておくことができる。

```python
>>> def test_func(title = "no_title",content = "no_content",level = 10):
...     print(title, end='\n')
...     print(content, end='\n')
...     print(level)
... 
```
引数の指定をしないと、以下のようにデフォルトで指定したものが返ってくる。

```python
>>> test_func()
no_title
no_content
10
```
引数の指定をすると、指定したものが返ってくる。

```python
>>> test_func(title = "harry_potter",content = "himitsu_no_heya",level = 30)
harry_potter
himitsu_no_heya
30
```

#dir()

ビルトイン関数()を使うことで、モジュールが定義している配下のものを確認できる。

#sort関数とlambda式によるリストの並び替え

```python
>>> dic = [[1, 'D'], [2, 'B'], [3, 'A'], [4, 'C']]
>>> dic.sort(key=lambda dic: dic[1])
>>> print(dic)
[[3, 'A'], [2, 'B'], [4, 'C'], [1, 'D']]
>>> dic.sort(key=lambda dic: dic[0])
>>> print(dic)
[[1, 'D'], [2, 'B'], [3, 'A'], [4, 'C']]
```

[こちら](https://qiita.com/n10432/items/e0315979286ea9121d57)拝見しました。

#フォーマット指定子の利用

%全体の幅.小数点以下の幅fという書き方をします。全体の幅には小数点も含みます。

```python
>>>print("出力結果:")
>>>print('円周率は%5.3fである。'%math.pi)
>>> print('円周率は%10.9fである。'%math.pi)
円周率は3.141592654である。
```

[こちら](http://www.k-cube.co.jp/wakaba/server/format.html)拝見しました。


#スライスの活用

数え方は人それぞれですが、一番後ろの値が−1という感じで良さそうな気はします。それで間違ったこともないですが。


```python
>>> list = ["a","b","c","d","e","f","g"]
>>> print(x[:-3])
["a","b","c","d"]
```

[こちら](https://qiita.com/kaeruair/items/e7f1c08915839ce3c9b4)
の記事見て、ここまでスライス使ったことないなととても興味深かったです。

#変数スコープについて

デフォルト値は**関数が定義された時点**でのスコープで評価されます。
これ知らない時はとてもつまづきました。

```python
>>> i = 5
>>>
>>> def func(arg=i):
...    print(arg)
...
>>> i = 6
>>>
>>> func()
5
```

スコープってとても大事ですね。
[こちら](https://qiita.com/msssgur/items/12992fc816e6adf32cff)は、とても参考になります。[こちらも](http://note.crohaco.net/2017/python-scope/)

#_(アンダーバー)の活用

```python
>>> 1+5
6
>>> 5+_
11
```

_(アンダーバー)は最後に返された値の変数として活用できます。

#リストの削除

pop()は削除されたものが返ってくるが、remove()は返ってこない


```python
>>> a
[2017, 2018, 2019, 2020]
>>> a.pop()
2020
>>> a
[2017, 2018, 2019]
>>> a.remove(2019)
>>> a
[2017, 2018]
```

リストの削除は,pop()もしくはremove()で行う。

#range()の返り値

これ勘違いしている人が多いやつです。for文やlistなどのイテレータによってイテラブルからリストを作成できます。

```python
>>> print(range(5))
range(0, 5)
>>> range(0,5)
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]
>>> for i in range(5):
...     print(i)
... 
0
1
2
3
4
```

#比較演算子について

[こちら](https://qiita.com/Morio/items/ea3710b5411fc18e20d7)と
[こちら](https://snowtree-injune.com/2018/08/14/bool/)
参考にさせていただきました。

#sys.pathによる初期化について
[こちら](
https://docs.python.jp/3/library/sys.html?highlight=sys%20path)
を参照しました。


#関数の引数について

[こちら](https://qiita.com/rsakamot/items/6d809bed894d2b430aad)を参照にしました。

以下では第２引数は任意

```python
>>> def func(name, *name2):
...     print(name)
... 
>>> func('taro')
taro
>>> func('taro','jiro')
taro
>>> func('taro','jiro','saburo')
taro
```
以下では引数は必須になっているため、場合によってはエラーになる。

```python
>>> def func_2(name, name2):
...     print(name)
... 
>>> func_2('taro')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func_2() missing 1 required positional argument: 'name2'
>>> func_2('taro','jiro')
taro
>>> func_2('taro','jiro','saburo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func_2() takes 2 positional arguments but 3 were given
```

#シーケンスの比較

シーケンスは違う型でも比較ができます。
比較する際には**辞書的な(lexicographical)順序が用いられます。

・最初の二つの要素を比較し、その値が等しくなければその時点で比較結果が決まります。
・等しければ次の二つの要素を比較し、以降シーケンスの要素が尽きるまで続けます。

```
>>> (1, 2, 3) < (1, 2, 4)
True
>>> (1, 3, 3) < (1, 2, 4)
False
>>> (1, 3, 3) < (1, 3, 4)
True
>>> (1, 3, 5) < (1, 3, 4)
False
>>> [1, 2, 3] < [1, 2, 4]
True
>>> [1, 3, 3] < [1, 2, 4]
False
>>> [1, 3, 3] < [1, 3, 4]
True
>>> [1, 3, 5] < [1, 3, 4]
False
```

文字列に対する辞書的な順序づけには、個々の文字を並べるのにUnicodeコードポイントの数を用います。

```
>>> 'C' < 'JAVA' < 'PYTHON' < 'PERL'
False
>>> 'C' < 'JAVA' < 'PERL' < 'PYTHON'
True
>>> 'java' == 'JAVA'
False
```

そのほかいかように多様な比較ができます。異なる数値型同士の比較も可能です。

```
>>> (1, 2, 3, 4) < (1, 2, 4)
True
>>> (1, 2) < (1, 2, -1)
True
>>> (1, 2, 3)  == (1.0, 2.0, 3.0)
True
>>> (1, 2, ('aa', 'ab'))  < (1, 2, ('abc', 'a'), 4)
True
```

違う内容ですがリストの比較の記事を調べている時にみつけたので[memo](http://nihaoshijie.hatenadiary.jp/entry/2017/12/23/120513)

#structモジュールについて

structモジュールはバイナリデータを処理するためのモジュールです。
バイナリデータは、bytes型で表現され、structモジュールを使うことでフォーマットを指定してバイナリデータを作成したり、バイナリデータから数値等に変換を行うことができます。
ラズパイなどでアナログ型の入力を行う場合に使われてます。

主な使い方は、値のpackとunpackです。
pack:数値型などの値をbytes型に変換することです。値はカンマで区切って複数指定することができます。unpackはその逆です。

```
>>> data = pack('hhl', 1, 2, 3)
>>> 
>>> type(data)
<class 'bytes'>
>>> data
b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'
>>> 
```
フォーマット指定で使っている「h」はサイズを2バイトで、「l」は4バイトで値を表現することを表しています。

[こちら](https://techacademy.jp/magazine/19058)よりコード引用しました。

#インターフェイスオプション

例えば-mを使うことで、sys.pathから指定されたモジュール名のモジュールを探し、その内容を __main__ モジュールとして実行することができます。

[参照](https://docs.python.jp/3/using/cmdline.html)

#クリーンナップ処理のwith

例外やエラーについての説明は割愛しますが、その時の対応で必要になるのがクリーンアップ処理です。

try文で定義することもありますが、すでに定義されているものも存在します。withです。
これは使わない日はないくらいの処理です。
以下のコードではopenでファイルを開いているのに、閉じていないことから、時には問題を起こすことがあります。

```
for line in open("hoge.txt"):
    print(line, end="")
```
これを

```
with open("hoge.txt") as fl:
    for line in fl:
        print(line, end="")
```
とすることで正しくクリーンアップされることを保証してくれます。


#演算子の返り値

返ってくる時の形式がタプルであることに注意が必要。リストではありません。

```
>>> a = 3
>>> b = 5
>>>
>>> c = 3.0 + b, 5 * a
>>>
>>> print(c)
(8.0, 15)
```


#ネストしたリスト内包表記

以下ような3*4ののリストのリストがある場合に、

```
>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]
```
いかのように、各リストの要素ごとをループで回して、4*3のマトリックスに書き換えることができます。

``` 
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
```

これをもっと簡単にやってくれるのが組み込み関数のzip()です。

```
>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
```

アスタリスクによってmatrixをアンパックして利用できるようにしています。
こちらを[参照](https://docs.python.jp/3/tutorial/controlflow.html#tut-unpacking-arguments)

#キーワード引数

関数を呼び出す時は、**必ず位置引数が先でキーワード引数を後にしなければならない**というルールがあります。

[こちら](https://qiita.com/Tocyuki/items/2c27b9dba3f6fd4a76e8)参照にしました。

#del文

clear()を使うことでリストの要素を削除することができます

```
>>> test_list = ['taro', 'hanako', 'kenta', 'jiro', 'saburo', 'yoko']
>>> test_list.clear()
>>> print(test_list)
[]
```

一方でdel文はこのように使えます。

```
>>> test_list = ['taro', 'hanako', 'kenta', 'jiro', 'saburo', 'yoko']
>>> del test_list[0]
>>> print(test_list)
['hanako', 'kenta', 'jiro', 'saburo', 'yoko']
>>> del test_list[2]
>>> print(test_list)
['hanako', 'kenta', 'saburo', 'yoko']
>>> del test_list[:]
>>> print(test_list)
[]
```

また削除対象が辞書型の時には、delで指定するのはindexではなくkeyになる。

#pipの利用

お馴染みinstall

```
$ pip install
```

パッケージの表示

```
$ pip list
```

#エスケープのカウント

``` 
>>> d = 'watashino\nnamaeha\nojisan\t'
>>> 
>>> print(len(d))
25
```

#roundの使い方

どこで切るかについては以下を参考にするとよくわかります。

```
>>> from math import pi
>>> [str(round(pi, i)) for i in range(0, 5)]
 ['3.0', '3.1', '3.14', '3.142', '3.1416']
```

#dir（）について

初心者ではdir()は関数を全て出力すると勘違いされていることもありますが、実際にはモジュールが定義している名前を確認する関数です。

#orの活用

変数代入についての注意点

```
>>> name1,name2,name3,name4= '', '','tanaka','sato'
>>> selected_name = name1 or name2 or name3 or name4
>>> print(selected_name)
tanaka
```

#.replaceメソッドについて

```
d = 'xxxxAAAxxxxAAAxxxxAAA'

print(d.replace('AAA', 'BBB', 1))
```

とした時に第三引数には、何個めまでreplaceするかの最大回数を指定することができる。

#コメント行について

可能な限り独立して記述することというのがガイドラインには記載してあります。

#set()について

set()は集合を表現するため、重複するものは一つに集約され、かつ順番も元の順番を保持しないので注意。

#コマンドライン引数

Pythonのプログラム実行時に，引数を渡すにはsysモジュールのargvを利用します。なお入力値は文字列として認識されます。

#open関数のmodeについて

| mode= | 説明 |
|:--|:--|
| r | 読み込み |
| w | 書き込み（新規作成） |
| a | 追加書き込み |
| r+ | 既存ファイルの読み書き |
| w+ | ファイルの読み書き（新規作成） |
| a+ | 追記・読み書き |
| t | テキストモード |
| b | バイナリモード |

#演算子の優先順位

比較演算子はブール演算子と共に組み合わせることができますが、優先順位は比較演算子の方が高く、ブール演算子の中でもNOT>AND>ORの順番で評価がされます。

#終わり
備忘録なのでまた更新して行きたいと思います。