お茶漬けびより

"あなたに教わったことを、噛んでいるのですよ" 五等分の花嫁 7巻 「最後の試験が五月の場合」より

Google Cloud OnBoard In Osaka に行ってきた。

f:id:pickles-ochazuke:20180427223322j:plain

cloudplatformonline.com

GCP の無料トレーニングがあったので、行ってきました。 内容は入門的な内容で GCP 触ったことがない人にはぴったりな内容でした。 ただ、サーバの負荷分散に使われる技術(ツール)とかの用語がびゃびゃっと出てきて理解できないところが多々ありました。

内容は、

  • GCP の概要
  • 事例紹介
  • GCP のサービス概要
  • コンピューティング
  • ストレージとデータベース
  • 機械学習
  • 今後の学習方法
    といった内容でした。

ここでは、ストレージとデータベース、機械学習、今後の学習方法の紹介はしません。
本人が理解しきれていないからです……

GCP の概要

まとめると

  • Google は完全なサーバ管理不要な環境を作ろうとしている
  • GCP は、Google が長年培ってきたインフラを提供している
  • GCP のインフラは Google が提供しているサービス(Gmail や Gmaps)と同じ環境で動いているので、セキュリティも同じ。
  • お金の計算は、自動で最安になるようになっている。
  • GCP のネットワークは、Google のプライベートネットワークと同じなので高速。

事例紹介

  • Abema TV は、GKE(Google Container Engine), GCLB(GC Load Balancing) を使っている
  • Spotify は、独自のインフラから GCP に移行。
  • airbnb は Cloud Translation API を活用している。
    などなど

GCP のサービス概要

GCP には、大量のサービスがありますが、カテゴリに分けると6個になります。

  • マネジメント - 権限やログ、リソースなどの管理ツール
  • コンピューティング - インフラの提供。
  • ネットワーキング - 負荷分散や VPC などを提供
  • ストレージとデータベース - MySQL や NoSQL、ストレージの提供
  • ビッグデータ - BigQuery, データ解析のサービスを提供
  • 機械学習 - TensorFlow, 学習済みモデルの提供

GCP を利用するときは、3つのアクセス方法があります。

  • Cloud Console - Web ブラウザ上で GCP にアクセスできる。人用
  • Cloud SDK / Cloud Shell - PC に Cloud SDK を入れて使う。機械的作業用
  • Cloud API - REST 形式の API インタフェース。プログラム用

ちなみにCloud Shell は、毎回インスタンスを立てているので、前回入れたものは消えるそうです。あと 5 GB まで使えるようです。

基本用語

まずは、クラウドサービスで基本となる用語だと思います。

  • リージョン
    特定の地理的な位置。日本だと大阪や東京にリージョンがあります。
  • ゾーン
    リージョンの中にさらに区分けしたロケーション。リージョンによって数は違いますが、大阪と東京にはそれぞれ3つのゾーンがあるようです。
    GCP はリージョンを超えてもプライベートネットワークを維持出来るそうです。
    リージョン間は海底ケーブルで繋がっているため、回線は速いそうです。
    以下は、GCP で使われる用語です。
  • プロジェクト
    GCP のサービス(Compute Engine, BigQueryなど)やリソース(お金に関係する部分)の作成、管理(有効化や停止、削除)を行う。
    まとめると、プロジェクトの中に、リージョンがあり、その中にゾーンがあるイメージです。

また、リソースという用語の意味が理解しきれていないですが、たぶんお金に影響する部分のことだと思います。例えば、Compute Engine だと CPU, メモリ, ディスクであり、BigQuery だと ストレージや長期保存、クエリ(分析)のことだと思います。

サービスは基本的にゾーンごとに作成されますが、モノによっては、プロジェクト単位で作成されるサービスもあります(Cloud Load Balancing)。

管理

Cloud IAM というサービスによって、誰が、どんな役割を、どのサービスに持つかを設定できます。
このサービスは無料で使うことが出来ます。

cloud.google.com

コンピューティング

主なサービスは以下の4つです。

GCE (Google Compute Engine)

cloud.google.com

以下、特徴です。

  • VM 上で動く
  • 自由度が高い(普段のサーバと変わらない)
  • 低コスト、自動で継続利用割引が適用されます。
  • メンテナンスでも自動で VM が移動し、再起動が不要(ライブマイグレーション)。
  • ネットワーキング機能(Cloud Virtual Network: CVN)の結合

ストレージの SSD は二種類あり、ローカル SSD の方が速いですが可用性は下がります。もちろん普通の HDD もあります。
Cloud Virtual Network というサービスのおかげで、リージョンを跨いだ Virtual Private Cloud ネットワークが構築できます。内部 IP アドレスや、ファイアウォールを自由に設定出来るようです。

GAE (Google App Engine)

cloud.google.com

  • インフラ部分が完全に抽象化
  • アプリの使用状況に応じて課金
  • バージョンが異なるアプリも簡単に共用できる

お金は、2 インスタンスからかかります。インスタンスの数は自動で変化するので、リクエストが全くないときは、インスタンスの数が 0 になります(お金がかからない)。サーバ管理は一切不要です。

GKE (Google Kubernetes Engine)

cloud.google.com

  • コンテナオーケストレーションシステム
  • GCE や CVN と連動して動作
  • GKE 自体にお金はかからない(GCE や CVN にかかる)
  • 管理する環境を提供(アプリのデプロイ、更新、管理が簡単。自動スケーリング、アップデート)

GCE をコンテナで動かし、管理するサービスです。Docker や Kubernetes を使って、コンテナ管理することが出来ます。

Google Cloud Function (GCF) Beta

cloud.google.com

  • サーバレスアプリケーション
  • コードが実行される時間に対してのみ、最も近い 100 ミリ秒単位で課金
  • 複数のクラウドサービスを関連付けて拡張
  • Firebase のようなサービスと統合できる

まとめ

コンピューティングの 4 つのサービスを紹介しました。それぞれ特徴が異なり、どういうときにどれを使ったらいいか迷ってしまいますが、発表者の方は以下のように分けるといいと話していました。

  • GCE -> 現在、物理や仮想上で動いている既存のアプリの移動。
  • GAE -> 新しく Web アプリサービスを作る場合におすすめ。
  • GKE -> 社内のセキュリティ上 GAE が難しい場合、こちらを使う。

個人的には、Web アプリサービスを作りたい、サーバ管理したいような学生が使うと良いのではないかと思いました。登録一年は、$300 無料で使えるし、ちょっと試すぐらいならお金はかかりません。チュートリアルも丁寧で、何も知らなくても言われたとおりにするだけで動かすことが出来ます(もちろん理解した方がいいですが)。

ここでは、ストレージとデータベース、機械学習を紹介しませんでしたが、これらを使うことで作りたいサービスに必要な技術の壁をなくすことができます。ぜひ、GCP を使って遊んでみてはいかがでしょうか。

cloud.google.com

Python のパッケージ管理ツールの簡単なまとめ

f:id:pickles-ochazuke:20180207224258j:plain

最近寒すぎて歩くのがつらく、走って帰っています(これはこれでつらい)。
Python を始めてまだ1ヶ月か2ヶ月ほどですが、始めたときに???ってなったことをちまちまと整理していきます。

今回は、パッケージ管理ツールの回りをまとめたいと思います。
先に断っておくと、詳しい話は他の詳しい方に任せてます。自分と同じように Python 始めたけど専門用語が飛び交いすぎて訳が分からない!となっている人に向けて、道しるべになるような簡単な解説にとどめたいと思っています。

パッケージングツールとパッケージインストーラ

パッケージ管理ツールを大きく分けるとパッケージングツールとパッケージインストーラの二つになります。

  • パッケージングツール
    自作したライブラリを外部へ配布する際に使用するツール。PyPI で配布されているパッケージは、全てパッケージングツールを使ってパッケージ化されたものです。ツールは複数あり、 wheel, setup.py sdist(コマンド), setuptools, distutils, distribute などがこちらに当たります。現在は、wheel が普及しています。

  • パッケージインストーラ
    PyPI などで公開されているパッケージをインストールするためのツール。一度は使ったことがあるかもしれません。pip, easy_install などがこちらに当たります。現在は pip が普及しています。easy_install は、setuptools のコマンドラインツールだそうです。

パッケージングツールは複数あります。現在使われているのは、 wheel ですが、そこまで行き着くのにややこしい問題があったようです。特にややこしいのは、setuptools と distribute です。setuptools が登場し(2011年?)、そのフォーク(派生のようなもの)が distribute です(2012年?)。一時期は distribute を使うべきでしたが、2013年に setuptools にマージされます(がっちゃんこ)。

Python 3.3 までは pip がスタンダードで入っていなかったので自分で入れる必要がありました。そのため、setuptools (easy_install)を使って pip を入れていた時期があったようです。3.4 では pip は標準で入っていますので、setuptools(easy_install) を触る必要はありません。

distutils は、標準のパッケージ管理ツール(パッケージングもインストールも可能)です。setuptools や pip はこれを拡張したものだそうです。

さて、整理しましょう。最新の Python(3.4 以上)であれば、インストールするものは wheel だけです。そしてパッケージをインストールする際は、pip を使いましょう。以上です。

パッケージの配布形式

wheelegg です。
昔は egg が使われていましたが、この egg にはいろいろ使いにくいところがありました。それを解決するために現れたのが wheel です。現在では、wheel が一般的に使われています。wheel 形式でパッケージするには、同じ名前のパッケージングツール wheel を使います。

異端児 Anaconda

(実際に使ったことがありませんので、間違いがあるかも……)
さて、さっきまで pip と wheel だけを使えば問題ないよと書いてきました。しかし、この Anaconda というやつには conda という便利なツールが存在します。こいつは、パッケージの管理と 仮想環境管理とバージョン管理が出来るようです。つまり pip, pyenv, virualenv の代わりを一人で担っています。また、パッケージングも行えます。ただし、wheel との互換性はないようです。研究で使う分には問題ないですが、開発となると今後扱いづらいかもしれません。

おわりに

パッケージ管理ツールをまとめると、通常は pip, wheel を使えばいいですが、考えるのが面倒くさい、さっさとコードを書く必要があるという人は、Anaconda をインストールして conda を使うという感じでしょうか。または、Anaconda でも pip は使えるので、パッケージ管理やパッケージングは、pip, wheel を使う(それ以外の環境回りは conda を使う)というのがいいかもしれません。

以上、つたない内容でしたが理解の一助になれば幸いです。

参考資料

歴史的な詳しい解説があります。とても参考になりました。 ymotongpoo.hatenablog.com

Anaconda(conda)の使い方が解説されています。 qiita.com

ちょっと情報が古いですが、よくまとまっているので、かなり参考になります。
Python パッケージ管理技術まとめ (pip, setuptools, easy_install, etc)

Python 3.6 から MySQL データベースへ SSH 接続を試みる

f:id:pickles-ochazuke:20171210160653j:plain

仕事中は、いろいろ書きたい記事を思いつくのですが、いざ書こうとするとネタが思いつかないことがよくあります。
メモ代わりにここに書きますが、カテゴリとしては、Python, MySQL, グラフ描画, ウィンドウハンドルを使った自動化。みたいな感じです。忘れないうちに書かないと……。

そうそう、Google Home を買ったので、それを使って遊んだりもしたい。今は、Python, MySQL が優先なので、そちらを身につけつつその間に Google Home について調べておこうかなと。

無駄話はこれぐらいにして、本題に入ります。
前回は、ローカル(PC 内に入っているデータベース(DB)への接続)な環境の話でしたが、今回は、ネットワーク上の DB への接続を試してみます。

以下を参考にしました。

blog.honjala.net

環境の準備

まずは、今回使うモジュールを落としてきます。

pip install sshtunnel

ちなみにモジュールは、Github に公開されています。

github.com

これで SSH 接続するための環境は出来ました。 次は、実際にコードを書いて接続します。

SSH 接続を試みる

以下のコードを実行すると、SSH 接続するためのポート番号(何のポート番号かは分かっていません……)が出力されます。

# -*- coding: utf-8 -*-
from sshtunnel import SSHTunnelForwarder
import mysql.connector

port_num = 22
with SSHTunnelForwarder(
    ('ip_address', port_num),
    ssh_username='user_name',
    ssh_password='user_pass',
    remote_bind_address=('127.0.0.1', 3306)
) as server:

print(server.local_bind_port)

ip_address には、接続したい DB がある IP アドレスを。port_num には、SSH 接続のポート番号を(通常は、22)。remote_bind_address には、DB がある IP アドレスとポート番号を指定するのですが、通常は、SSH 接続先にあると思うので、上記で問題ないと思います。

上手くいけば、ポート番号が表示されていると思います。 問題なければ SSH 接続が成功しています。with を使わずに open(), close() のような方法もあります。以下のようにして、接続します。

port_num = 22
server SSHTunnelForwarder(
    ('ip_address', port_num),
    ssh_username='user_name',
    ssh_password='user_pass',
    remote_bind_address=('127.0.0.1', 3306)
)
server.start()

# 処理

server.stop()

start()open()stop()close() の役割をしています。 では、次に出力したポート番号を使って DB へ接続します。 ここでは、前回使用したモジュール(mysql.connector)を使って接続しています。

前回 pickles-ochazuke.hatenablog.com

conn = mysql.connector.connect(
    host = 'localhost',
    port = server.local_bind_port,
    user = 'user_name',
    password = 'user_pass',
    database = 'db_name',
)

前回とほぼ変わりません。port のところに先ほど出力したポート番号を使っています。

おわり

以上です。とても簡単にできたと思います。

今回の SSH 接続の部分とは関係ありませんが、クエリを実行して、結果を取得する際に単純に受け取るとリストになると思います。一応これでも扱えるのですが、pandas のデータフレームというのを使うともっと便利に扱えるようになります。そこら辺も近いうちに書きたいと思います。

Python 3.6 で MySQL データベースに接続

f:id:pickles-ochazuke:20171209164122j:plain

お久しぶりです。 9月に就職が決定して、そこから空いた一週間で北の方を旅行して、仕事が始まって最初の一ヶ月は給料なくて、11月に初というか3,4ヶ月ぶりの給料でなんとか生活を凌いでいます。
前の仕事は、C言語だったんですけど、今の場所はすることによって言語が変わるそうで、今は Python をメインに触っています。あと初めて SQL を仕事で使っていまして、知らないことだらけで初めてコンピュータサイエンスを学んだ時のようで楽しいです。

さて、今月はなるべく更新をしたいなと思っていますので、小さい内容でも更新していきたいと思っています。主に仕事で学んだことをまとめる方向にしたいので、PythonSQL の話になるかなーと。

では、本題です。 以下を参考にしています。

qiita.com

環境構築

Python のバージョンは、3.6.3 です。 バージョンの確認は、コマンドプロンプトpython --version を実行すれば確認できます。できなければ、パスが通ってないので、通しましょう。

まずは、必要なパッケージをインストールします。

pip install mysql-connector-python-rf

会社の環境だとプロキシの問題で、pip が上手くインストールしてくれないんですよね。そこら辺も覚えている範囲でまとめたい……。

mysql-connector-python も必要っぽいので、以下から落としてきます。
https://pypi.python.org/pypi/mysql-connector-python
こだわりがなければ最新のやつを落としてください。私は、mysql-connector-python-8.0.5.tar.gz を落としました。
落としたファイルの場所でコマンドプロンプトを開いて、以下を実行します。

pip install mysql-connector-python-8.0.5.tar.gz

そしたらインストールが成功するはずです。しなければ管理者権限でコマンドプロンプトを開いて、実行してみてください。 終わったら、pip list で出力されたパッケージリストに今入れた二つがあるか確認します。

MySQL をインストールしていなければ、インストールしましょう。ここでは、その説明は除きます。MySQL サーバを立ち上げて、データベースとテーブルを作成して、準備完了です。

MySQL データベース(DB)への接続

まずは、接続です。各引数は、自身の環境に合わせて変えてください。

import mysql.connector

conn = mysql.connector.connect(
    host = 'localhost',
    port = 3306,
    user = 'root',
    password = 'pass',
    database = 'test',
)

とくにエラーが発生しなければ成功しているはずです。この conn を使って、データベースに対していろいろ操作します。次に、接続が可能か調べるためには、以下を実行します。

connected = conn.is_connected()
print(connected)
if (not connected):
    conn.ping(True)

conn.is_connected() によって接続が可能か真偽値で返ってきます。True の場合は、接続が可能で、False の場合は、接続が不可能な状態です。conn.ping(True) は再接続を試みているのですが、conn.is_connected() が False なら再接続で解決はしなさそうですね……環境に合わせた対処が必要になると思います。

conn.ping(True) は、長い時間接続していると DB との接続が切れることがあるそうなので、その対処のために使うそうです。つまり、定期的に接続して切られないようにしている感じです。

クエリの実行

次にカーソルオブジェクトを作成します。カーソルというのは、データベースで使われる用語のようです。詳しくは知らないので、ここでは、クエリの実行と結果を受け取るために必要な DB への命令方法だと思えば問題ないと思います。

cur = conn.cursor()
cur.execute('select * from member')
table = cur.fetchall()
print(table)

conn.cursor() で、カーソルオブジェクトを作成し、cur.execute() で文字列をクエリとして DB に送ります。その結果を cur.fetchall() で受け取り、print() 出力しています。

ちなみに cur.fetchall() は、例えば SELECT の結果を全て受け取りますが、 cur.fetchone() は結果を一つだけ受け取ります。fetchone() は、何度も実行することで続きのデータを受け取ることができます。

例として、SELECT * FROM Table; というクエリを実行して、レコードが 3 つ現れるとします。fetchall() の場合は、この結果を全て受け取りますが、fetchone() では、レコードを 1 つだけ受け取ります。全て受け取る場合は、3 回実行する必要があるわけです。

それぞれにメリット、デメリットがあるようですがここでは説明しません(というか知りません……)。ちなみに、レコードを全て受け取った状態で fetchone()print() で出力すると None と出力されるので、 for 文などで簡単に回せそうです。

以上が簡単な MySQL データベースへの接続方法です。重要なのは、 mysql.connector.connect(), connect.cursor(), cursor.execute(), cursor.fetchall() ですかね。

最後に一通り実行できるコードを載せておきます。

# -*- coding: utf-8 -*-
import mysql.connector

conn = mysql.connector.connect(
    host = 'localhost',
    port = 3306,
    user = 'root',
    password = 'pass',
    database = 'test',
)

connected = conn.is_connected()
print(connected)
if(not connected):
    conn.ping(True)

cur = conn.cursor()

cur.execute('SELECT * FROM member')

# table = cur.fetchall()
# print(table)

print(cur.statement)
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchone())

参考

今回出てきた API のドキュメントを載せておきます。

MySQL :: MySQL Connector/Python Developer Guide :: 7.1 Connector/Python Connection Arguments

MySQL :: MySQL Connector/Python Developer Guide :: 10.2.25 MySQLConnection.is_connected() Method

MySQL :: MySQL Connector/Python Developer Guide :: 10.2.27 MySQLConnection.ping() Method

googletest を使ってみた

f:id:pickles-ochazuke:20170828184058j:plain

北海道の土産用お菓子は、どれもおいしくて最高です。

趣味でコードを書いてるけど、テストコードは全く書いてこず、仕事でテストコードを初めて書いて、良いテストコードを書くのは難しいなぁと実感し、ちょっとこれは練習しないとダメだなということで、テストコードを書く環境を作り始めました。

googletest を見つけたので、これでいいかと選択。使う理由は、情報が多そうなのと使いやすそうな感じが理由。

Windows 版の Visual Studio 2017 上で動かしたので、そのまとめを書いておきます。

googletest を落とす

まずは、googletest を落としてこないと始まりません。

github.com

落としたら解凍します。

Google Test を追加

google-master/googletest/msvc/2010/ の中に、gtest.sln というソリューションファイルがあるので、Visual Studio で開きます。 開くと、セキュリティ警告をしてくると思うので、内容を読んで、問題なければ OK を押します。そのあとプロジェクトの再ターゲットが出るので、設定に問題なければ OK を押します。

f:id:pickles-ochazuke:20170828180315p:plain

完了したら gtest.sln を閉じます。次にテスト対象のプロジェクトを用意します。今回は、TestProject というプロジェクトを作成しました。次に、ソリューションに googletest のプロジェクトを追加します。 ソリューションエクスプローラからソリューションを右クリックし、追加 > 既存のプロジェクト を選び、

f:id:pickles-ochazuke:20170828180445p:plain

先ほど解凍した googletest/msvc/2010/gtest.vcxproj を追加します。追加すると以下のようになります。

f:id:pickles-ochazuke:20170828180553p:plain

環境設定

TestProject には、何もコードが書かれていないので追加します。ここでは、main.cpp を追加しました。追加したら、まずは googletest を使えるようにしましょう。TestProjectプロパティを開き、構成プロパティ > C/C++ > 全般 のなかの追加のインクルードディレクトリに新しいパスを追加します。

f:id:pickles-ochazuke:20170828180835p:plain

そこに googletest/include を追加します。もちろん、googletest より前は、googletest を置いている場所のパスが入ります。追加したら OK をクリックし、設定を反映させます。次に、TestProject の参照を追加します。参照を右クリックすると参照の追加が出るので、それをクリックし、gtest にチェックを入れます。

f:id:pickles-ochazuke:20170828180933j:plain

最後に、gtest プロジェクトのプロパティを表示し、構成プロパティ > C/C++ > コード生成 からランタイムライブラリを環境に合わせて設定します。よく分からない場合は、テスト対象のプロジェクトと同じにすれば問題ないはずです。ここでは、構成Debug に変更し、ランタイムライブラリマルチスレッドデバッグDLL(/MDd) にしました。OK をクリックして、プロパティを閉じます。

f:id:pickles-ochazuke:20170828181004p:plain

テストコードの作成

最後にテストコードを作成します。今回は、main.cpp に直接テストコードを作成します。

#include "gtest\gtest.h"

TEST()
{
    EXPECT_EQ(0, 1 - 1);
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

main 関数内の ::testing::InitGoogleTest(&argc, argv)RUN_ALL_TEST() がテスト実行のために必要な処理です。TEST(){} 内の処理が実際にテストしたい内容になります。

これを実行すると以下のように表示されます。

f:id:pickles-ochazuke:20170828181137p:plain

以上で基本的な設定と使い方は、完了です。 詳しく知りたい方は、

入門ガイド — Google Test ドキュメント日本語訳

あたりを参照するといいでしょう。

おまけ

googletest は、include ディレクトリと msvc ディレクトリ、src ディレクトリが同じ階層にあれば問題なさそうなので、この三つをコピーして、ソリューションごとに置くと良さそうです。

おわり

以上が googletest の使い方でした。Visual Studio に googletest を入れていると Visual Studio さんに Test Adapter for Google Test をお勧めされたので、気が向いたら試してみようと思います。Community でも使えるんですかね……?

marketplace.visualstudio.com