#概要
C++は使えるけどpythonがわからないという人が素早く機械学習ができる最低限のプログラミング記法を身につけるためのポイントをまとめました。これを知っていれば最低限の機能は使えると思います。
#Pythonのメリット
ライブラリが充実しているのでC++で書くと複雑なコードも簡単に書けます。web連携が比較的簡単。
ネットに載っている情報が多い。
#Pythonの使いみち(例)
以下は全てライブラリが存在します。ライブラリを使いこなすことはすなわちpythonを使いこなすことです。
・機械学習
・Webスクレイピング
・エクセル操作
・データ前処理
・ビジュアライズ
#検証環境
python 3.8.2
Ubuntu 18.04
#環境構築
linuxの場合は標準でpython3が入っているので環境構築の必要がありません。
Anacondaで動かしたい場合にはこちらを参考に導入してください。
Anacondaの説明はこちら
Anacondaを使うと仮想環境を簡単に作ることができます。パッケージをたくさんインストールするpythonにおいては、環境を変えたいことが多くなるので、本腰を入れて使いたいならAnacondaは必須かもしれません。
##おすすめの開発環境
IDE
・PyCharm
・Spyder
エディタ
・Atom
・VS code
#C++とPythonの違い一覧
C++ | Python | |
---|---|---|
変数型 | あり | なし |
変数の代入 | コピー | ポインタ |
関数の区切り | {}中括弧 | :とインデント |
算術演算子 | C++のものに加えて** べき乗を追加 |
|
論理演算子 | &&,ll,! | and,or,not |
コードの区切り | ; | 改行 |
ポインタ | 明確 | 不明確 |
コメントアウト | // | # |
外部ライブラリのインポート | #include | import |
コンパイル | 必要 | 不要 |
main関数 | あり | なし |
行列計算(標準) | 不可能 | numpyライブラリで可能 |
##変数型の違い | ||
pythonは動的型付け言語のため、C++に当たり前のようにある変数型が存在しません。そのため、変数はそのまま変数名のみで定義します。代入した値によって型が決定します。 |
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はインデントがスコープの範囲を示しています。そのため、一文字でもインデントがずれていると同じ範囲のコードとして認識されません。とてもインデントに厳しい言語なので、エディタのインデント整形機能を使わないとコーディングが厳しいかもしれません。例えば、以下のコードはインデンテーションエラーになります。ループの中でインデントがずれてバグが出ることがしばしばあるので気をつけましょう。
a=1234
b=12.345
c="hello world" #同じ範囲でない
d=[1,2,3,4]
##グローバル変数
C++のグローバル変数は関数からそのままアクセスできますが、pythonの場合は関数内でglobal 変数名
とローカル内で宣言しないと代入はできません。
a = 123
def Global():
global a
a = 456
print("global variable:", a)
Global()
#書き方の違い
見やすくするために一部main関数を省略しています。
##標準出力
pythonは自動改行なので\n
は要りません。
int a=123;
printf("%d\n",a);
a=123
print(a)
##外部ライブラリのインポート
#include "hogohoge.h"
import hogehoge
##配列
pythonでは「リスト」と呼びます。pythonの配列はメモリ領域が動的に確保されているので、後から要素を追加することができます。要素を追加する場合はappend()を使います。C++のようにa[3] = 4
で代入するとエラーになるので気をつけましょう。
int a[4]={1,2,3,};
int b = a[2];
printf("%d\n", b);
a[3] = 4;
printf("%d\n", a);
a=[1,2,3]
b=a[2]
print(b)
a.append(4)
print(a)
pythonのコードを見てみると、a.append(4)
があります。これはリストメソッドと言って、リストを操作するときに使う関数です。pythonでは変数や外部ライブラリを一種のオブジェクトとして扱い、.メソッド
でpythonに用意されているメソッドにアクセスできます。他にも途中に挿入するメソッドなどいろいろ存在するのでこちらが参考になると思います。
##不可変配列
後から値を変更することができない配列です。c++ではconstで宣言しますが、pytonの場合はタプルと言ってリストと別の書き方をします。
const int a[4] = {1, 2, 3, 4};
b = a[2];
printf("%d", b);
a = (1, 2, 3, 4)
b = a[2]#要素を取得
print(b)
##変数のラベル付け
pythonには辞書という機能があります。キーと値の組み合わせでデータを格納できる配列のようなものです。呼び出すときはキーを指定することで呼び出すことができます。そのため可読性が上がります。c++のenumと似たようなものとイメージしてももらうとわかりやすいかもしれません。
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にはどちらかに統一する機能があります。
int a = 7;
int b = 12;
if (a <= 10 && b <= 10)
{
printf("aもbも10以下");
}
else if (a % 2 == 0)
{
printf("aは偶数");
}
else
{
printf("条件に適合しません")
}
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の場合はリストを投げるだけで全要素をひとつずつ取り出してくれます。
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);
}
ls = [1, 2, 5]
for i in ls:
print(i)
for i in range(3):
print(i)
1
2
5
0
1
2
##while文
int a = 0;
while(a < 3)
{
printf("%d", a);
a += 1;
}
a = 0
while a < 3:
print(a)
a += 1
0
1
2
##関数
可変長引数を受け取るときは仮引数の前に*
を付けます。
リストやタプルの内容を引数に展開して引き渡すときは実引数の前に*
をつけます。
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));
}
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()
##クラス
###クラスの定義
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);
}
}
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を書きましょう。
###クラスの操作
Hoge hoge(3);
hoge.add(4);
hoge.mutipl(4);
hoge = Hoge(3)
hoge.add(4)
hoge.mutipl(4)
###クラスの継承
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);
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(行列演算ライブラリ)
これを使うことで行列演算が非常に簡単にできます。機械学習では必須です。
こちらの方が詳しく使い方を書いてあるので参考にしてください。
##Matplotlib(グラフ描画ライブラリ)
書き方はこちらの記事を参考にしてください。
#補足
##importモジュールの置き換え
pythonでは、外部ライブラリはオブジェクトとして扱われますが、長い名前を書くのが面倒なのでas
で置き換えることもできます。
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で学ぶニューラルネットワークとバックプロパゲーション"