【python入門】忙しいC++プログラマのためのPython高速入門講座

#概要
C++は使えるけどpythonがわからないという人が素早く機械学習ができる最低限のプログラミング記法を身につけるためのポイントをまとめました。これを知っていれば最低限の機能は使えると思います。
#Pythonのメリット
ライブラリが充実しているのでC++で書くと複雑なコードも簡単に書けます。web連携が比較的簡単。
ネットに載っている情報が多い。
#Pythonの使いみち(例)
以下は全てライブラリが存在します。ライブラリを使いこなすことはすなわちpythonを使いこなすことです。
・機械学習
・Webスクレイピング
・エクセル操作
・データ前処理
・ビジュアライズ
#検証環境
python 3.8.2
Ubuntu 18.04

#環境構築
linuxの場合は標準でpython3が入っているので環境構築の必要がありません。
Anacondaで動かしたい場合には[こちら](https://qiita.com/t2y/items/2a3eb58103e85d8064b6)を参考に導入してください。
Anacondaの説明は[こちら](https://py-prog.com/whats-anaconda-and-its-merit-for-python-programming/)
Anacondaを使うと仮想環境を簡単に作ることができます。パッケージをたくさんインストールするpythonにおいては、環境を変えたいことが多くなるので、本腰を入れて使いたいならAnacondaは必須かもしれません。
##おすすめの開発環境
**IDE**
・PyCharm
・Spyder
**エディタ**
・Atom
・VS code


#C++とPythonの違い一覧
|  |C++ |Python |
|---|---|---|
|変数型 |あり|なし |
|変数の代入| コピー|ポインタ |
|関数の区切り| {}中括弧 |:とインデント |
|算術演算子|  |C++のものに加えて`**`べき乗を追加 |
|論理演算子|&&,ll,!|and,or,not |
|コードの区切り|;  |改行 |
|ポインタ|明確|不明確|
|コメントアウト|//|#|
|外部ライブラリのインポート|#include|import|
|コンパイル|必要|不要|
|main関数|あり|なし|
|行列計算(標準)|不可能|numpyライブラリで可能|
##変数型の違い
pythonは動的型付け言語のため、C++に当たり前のようにある変数型が存在しません。そのため、変数はそのまま変数名のみで定義します。代入した値によって型が決定します。

```python
a=1234 #整数型
b=12.345 #浮動小数点型
c="hello world" #文字列型
d=[1,2,3,4] #リスト型
```
##ポインタ
pythonには明示的なポインタが存在しません。その代わり、変数が値の保持とポインタの両方の役割を兼ねているので、**変数への代入がコピーではなく参照を渡しています。**
代入先の値を変更すると代入元の変数の値も変わるので扱いの違いに注意してください。(リストの場合)以下参考
https://qiita.com/maruman029/items/21ad04e326bb4fb6f71a
##1コードの範囲
C++の場合は区切り文字である`;`をつけなければどれだけ改行しても1コードの認識ですが、pythonの場合は改行が明確な区切りになります。
##インデント
pythonはインデントがスコープの範囲を示しています。そのため、一文字でもインデントがずれていると同じ範囲のコードとして認識されません。とてもインデントに厳しい言語なので、エディタのインデント整形機能を使わないとコーディングが厳しいかもしれません。例えば、以下のコードはインデンテーションエラーになります。ループの中でインデントがずれてバグが出ることがしばしばあるので気をつけましょう。

```python
a=1234 
b=12.345 
　c="hello world" #同じ範囲でない
d=[1,2,3,4] 
```

##グローバル変数
C++のグローバル変数は関数からそのままアクセスできますが、pythonの場合は関数内で`global 変数名`とローカル内で宣言しないと代入はできません。

```python
a = 123


def Global():
    global a
    a = 456
    print("global variable:", a)


Global()
```

#書き方の違い
見やすくするために一部main関数を省略しています。
##標準出力
pythonは自動改行なので`\n`は要りません。

```c.c
int a=123;
printf("%d\n",a);
```
```python.py
a=123
print(a)
```
##外部ライブラリのインポート
```c++.cpp
#include "hogohoge.h"
```
```python.py
import hogehoge 
```
##配列
pythonでは「リスト」と呼びます。pythonの配列はメモリ領域が動的に確保されているので、後から要素を追加することができます。要素を追加する場合はappend()を使います。C++のように`a[3] = 4`で代入するとエラーになるので気をつけましょう。

```c++.cpp
int a[4]={1,2,3,};
int b = a[2];
printf("%d\n", b);

a[3] = 4;
printf("%d\n", a);
```
```python.py
a=[1,2,3]
b=a[2]
print(b)

a.append(4)
print(a)
```
pythonのコードを見てみると、`a.append(4)`があります。これはリストメソッドと言って、リストを操作するときに使う関数です。pythonでは変数や外部ライブラリを一種のオブジェクトとして扱い、`.メソッド`でpythonに用意されているメソッドにアクセスできます。他にも途中に挿入するメソッドなどいろいろ存在するので[こちら](https://note.nkmk.me/python-list-append-extend-insert/)が参考になると思います。

##不可変配列
後から値を変更することができない配列です。c++ではconstで宣言しますが、pytonの場合はタプルと言ってリストと別の書き方をします。

```tupl.cpp
const int a[4] = {1, 2, 3, 4};
b = a[2];
printf("%d", b);
```
```tupl.py
a = (1, 2, 3, 4)
b = a[2]#要素を取得
print(b)

```
##変数のラベル付け
pythonには辞書という機能があります。キーと値の組み合わせでデータを格納できる配列のようなものです。呼び出すときはキーを指定することで呼び出すことができます。そのため可読性が上がります。c++のenumと似たようなものとイメージしてももらうとわかりやすいかもしれません。

```python.py
lang={"c":1,"python":2,"ruby":3}#辞書の作成
print(lang["python"])

lang["ruby"]=4#要素の入れ替え
print(lang["ruby"])

lang["java"]=3 #要素の追加
print(lang)
```
##if文
pythonにはc++のように{}などの区切り文字がありません。そのため、`if hogehoge:`の次の行を1タブ分開けることによって※インデントを変え、if文の処理であることを明示します。pirntを左端に持ってくるとif文と同じインデントになるので、ifのそとで実行される処理になります。ネストする際もまた、インデントをずらします。
※インデントはタブかスペース4つ開けるかどちらかで統一しましょう。混ぜることは禁止されています。万が一混ざってしまい、どうにもならなくなったときはエディタの修正機能を使うことを勧めます。VS codeにはどちらかに統一する機能があります。

```c++.cpp
int a = 7;
int b = 12;
if (a <= 10 && b <= 10)
{
    printf("aもbも10以下");
}
else if (a % 2 == 0)
{
    printf("aは偶数");
}
else
{
    printf("条件に適合しません")
}
```
```python.py
a = 7
b = 12
if a <= 10 and b <= 10:
    print("aもbも10以下")
elif a % 2 == 0:
    print("aは偶数")
else:
    print("条件に適合しません")

```
##for文
c++の場合は、配列の中身をひとつひとつ取り出す場合に配列の要素数を指定してループしなければできませんが、
pythonの場合はリストを投げるだけで全要素をひとつずつ取り出してくれます。

```for.cpp
int ls[3] = {1, 2, 5};
for (int i = 0; i < sizeof ls / sizeof ls[0]; i++)
{
    printf("%d\n", ls[i]);
}

for (int i = 0; i < 3; i++)
{
    printf("%d\n", i);
}
```
```for.py
ls = [1, 2, 5]
for i in ls:
    print(i)

for i in range(3):
    print(i)

```
>1
2
5
0
1
2

##while文
```while.cpp
int a = 0;
while(a < 3)
{
    printf("%d", a);
    a += 1;
}
```
```while.py
a = 0
while a < 3:
    print(a)
    a += 1
    
```
>0
1
2

##関数
可変長引数を受け取るときは仮引数の前に`*`を付けます。
リストやタプルの内容を引数に展開して引き渡すときは実引数の前に`*`をつけます。

```function.cpp
int Add(a, b)
{
    c = a + b;
    return c;
}

int Add3(int *c)
{
    int d = 0;
    d = c[0] + c[1] + c[2];
    return d;
}

int main()
{
    printf("%d\n", Add(1, 2));

    const int e[3] = {1, 2, 3};
    printf("%d\n", Add3(e));
}
```
```function.py
def Add(a, b):
    c = a + b
    return c

def Add3(*c):  # 可変超引数として引数をまとめて受け取る
    d = c[0] + c[1] + c[2]
    return d


def main():
    print(Add(1, 2))
    print(Add3(1, 2, 3))
    e = (4, 5)
    print(Add(*e))  # リストやタプルを引数展開して渡すことも可
    return


if __name__ == "__main__":
    main()
```

##クラス
###クラスの定義

```classdefine.cpp
class Hoge
{
public:
    int a;
    Hoge(int a)
    {
        this->a = a;
    }
    void add(int b)
    {
        printf("%d\n", a + b);
    }
    void mutipl(int b)
    {
        printf("%d\n", a * b);
    }
}
```
```classdefine.py
class Hoge:
    def __init__(self, a):
        self.a = a
    
    def add(self, b):
        print(self.a + b)
    
    def mutipl(self, b):
        print(self.a * b)

```
c++でコンストラクタをクラスと同じ名前にしますが、pythonの「クラス」ではコンストラクタを`def __init__(self, a):`で表し、クラス内の変数をコンストラクタ内で`self.a`のように宣言します。定義自体はどこからでもできます。メンバ関数の引数にクラス自身の参照である「self」を渡して「self」経由でインスタンス変数にアクセスします。必ず引数にselfを書きましょう。

###クラスの操作

```classcntrol.cpp
Hoge hoge(3);
hoge.add(4);
hoge.mutipl(4);
```
```classcontrol.py
hoge = Hoge(3)
hoge.add(4)
hoge.mutipl(4)
```
###クラスの継承
```Inheritance.cpp
class Fuga : public Hoge
{
public:
    void subtract(int b)
    {
        printf("%d\n", a - b);
    }
    void divide(int b)
    {
        printf("%d\n", a / b);
    }
}

Fuga fuga(3);
fuga.add(4);
fuga.mutipl(4);
fuga.subtract(4);
fuga.divide(4);
```
```Inheritance.py
class Fuga(Hoge): #Hogeを継承
    def subtract(self, b):
        print(self.a - b)

    def divide(self, b):
        print(self.a/b)

fuga = Fuga(3)
fuga.add(4)
fuga.mutipl(4)
fuga.subtract(4)
fuga.divide(4)

```

#Pythonの主力ライブラリ
##Numpy(行列演算ライブラリ)
これを使うことで行列演算が非常に簡単にできます。機械学習では必須です。
[こちらの方](https://qiita.com/jyori112/items/a15658d1dd17c421e1e2)が詳しく使い方を書いてあるので参考にしてください。

##Matplotlib(グラフ描画ライブラリ)
書き方は[こちらの記事](https://qiita.com/iss-f/items/25c95cfbd0a3b87f5d96)を参考にしてください。
#補足
##importモジュールの置き換え
pythonでは、外部ライブラリはオブジェクトとして扱われますが、長い名前を書くのが面倒なので`as`で置き換えることもできます。

```python
import numpy as np
```
##モジュールのインストール
```
pip3 install module_name
```
##Pythonスクリプトの実行
```
python3 file_name
```
anaconda

```
python file_name
```

##標準ライブラリ
pythonではファイル操作がかなり楽です。
https://qiita.com/hiroyuki_mrp/items/8bbd9ab6c16601e87a9c

##オブジェクト指定インポート
https://note.nkmk.me/python-import-usage/
#最後に
まだまだpythonのほんの一部なので、気になった機能はあるかどうか調べてみるとよいです。


#参考
我妻 幸長  (著) "はじめてのディープラーニング　Pythonで学ぶニューラルネットワークとバックプロパゲーション"