Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

Python3でUnittestっていうのを触ってみたんだけど、誰かもっと教えてくれ

Python3でUnittestっていうのを触ってみたんだけど、誰かもっと教えてくれ

こんばんは、葛の葉です。

プログラミングにはユニットテストとか単体テストってのがあるんだそうですね。

www.techmatrix.co.jp

要するに、自分の作った関数がキチンと動いてるかを保証するためのものらしいんです。みんなは、自分の作ったプログラムを知らない他人に見せられる自信ありますか?私はちょっと自信ないです(^ω^;)

ただまぁ、自分が作ったプログラムは、いつかは知らん人が直したり機能を追加したりするわけですから、引継ぎ資料ってのは作っておくのがベターなのかなと思ってます。

引継ぎとはとても大事ですね。無いと夜中に電話かかってきてドス聞いた声で怒られますからね~。交代勤務してた前の職場ではそういう経験しました。あーあ。もっとも、引継ぎをちゃんとしなかった私が悪かったんですけどね。と、いうわけで、安眠を勝ち取るためにも引継ぎ資料はキチンとしたものを作らなきゃいけません。

importはこんな感じやけん

Python3だと内部Moduleにunittestというのが入っているので、pipとかでインストールする必要はありません。

最もnoseっていう外部Moduleでテスト用のものがあるらしいですけど、今回はunittestを使います。

import unittest

とりあえず関数を作る

引数に1を足した値を返す関数を作ります。ただし、整数以外の値が入るのは想定外です。そこで、引数の型がint以外はNoneを返すものにします。

kansu.py

def plus_one(alpha):
    if type(alpha) is int:
        alpha += 1
        return alpha
    else:
        return None

テストプログラムを作る

同じディレクトリ内test_kansu.pyを作りましょう。kansu.pyプログラムのテストなのでtest_kansu.pyがいいらしいです。 test_kansu.py

import unittest

import kansu


class TestMethods(unittest.TestCase):
    def test_plus_one(self):
        self.assertEqual(3, kansu.plus_one(2))
        self.assertNotEqual(3, kansu.plus_one(2.0))
        self.assertNotEqual(3, kansu.plus_one('1'))
        self.assertEqual(None, kansu.plus_one(1.0))
        self.assertEqual(None, kansu.plus_one('1'))


if __name__ == '__main__':
    unittest.main()

テストの実行

test_kansu.pyCLIから実行します。

python test_kansu.py

テストコードのファイル名がtest_*とか*_testとかだと、以下のようなものでも実行してくれるみたい。

python -m unittest

結果はこのような形になるかと思います。

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

self.assertEqual(3, kansu.plus_one(2))assertの意味はよくわからないですけど(オイ)、Equalつまりイコールになります。第1引数と第2引数がイコールなら良いということみたいです。

kansu.plus_oneは先に作ったkansu.pyの関数です。2を入れたら3が返ってきます。assert.Equal(3,3)になるので、第1引数と第2引数はイコールになります。よってテストが成功となります。

一方で、kansu.plus_oneは整数じゃなければNoneを返すようにしています。ですので、kansu.plus_one(2.0)kansu.plus_one('1') はそれぞれNoneが返ります。

assert.NotEqual(3,None)になります。第1引数と第2引数は同じではありません。ただ、assert.NotEqualとあるようにノットイコールでテストしているので、これはテストが成功しています。

kansu.plus_one(2) は 3 である → ただしい!
kansu.plus_one(2.0) は 3 ではない → ただしい!
kansu.plus_one('2') は 3 ではない → ただしい!

ここまでの説明は以上のようにまとめることができます。複雑やな(^ω^;)。ちなみに、残りの部分はassert.Equalとして、第1引数がNoneで第2引数もNoneとなります。これもTrueです。

kansu.plus_one(2.0) は None である → ただしい!
kansu.plus_one('2') は None である → ただしい!

全部正しいので、この関数は問題がないってことみたいです。

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

ちなみに、失敗していると、1行目.Eとなったり、Fとなったりします。 Eはプログラミングとして、エラー文の検出でFはFailedでテスト失敗のときに出ているようです。

下部のOKFailedになったりします。その時はどう失敗したかが、簡単にですが出力されるようです。

とまぁ、正直よくわかってねぇデス。

なんか、まぁ関数作ると、複雑になっちゃうんだけど、ユニットテストがあればこういう用途の関数なんですっていうのを説明できるんじゃあないかなって思います。あと、こういうエラー対応していますっていうの明示できる……かな……よくわかんないわ(^ω^;)

VSCodeを好きなテーマにしようぜ

VSCodeを好きなテーマにしようぜ

こんばんは、葛の葉です。

VSCodeっていうナウいテキストエディタがあると思うんですよ。

code.visualstudio.com

このテキストエディタのテーマは自由に切り替えられるんですよ実は!

変更するのは結構簡単ですよ

(デフォルトだと)左下の歯車のマークを押すと、メニューが出ます。そのメニューから「配色テーマ」を選択しましょう。

f:id:Kuzunoha-NE:20180928194606j:plain

そうすると、色々とぞろぞろ出てきます。私は拡張のテーマを入れているので沢山表示されていますが、皆さんの場合、少ないかもしれません。

f:id:Kuzunoha-NE:20180928194948j:plain

選択するとそのテーマに切り替わります。今回はRedを選択してみました。

f:id:Kuzunoha-NE:20180928195124j:plain

f:id:Kuzunoha-NE:20180928195355j:plain

こんな感じで赤くかっこいいテーマになりました!これも結構お気に入りですよ!かっこいいから!!テーマによって、例えば構文の色とかも決まってきます。Classなら緑色とかdefなら紫色ですとか。あれこれテーマを弄ってみると、エディタとしての使いやすさにも影響が出てきますね。

テーマを追加しましょ

下記のページにて、テーマの一覧を見ることが出来ます。Search Visual ....のフォームに何か単語を入れてみましょう。

marketplace.visualstudio.com

気になったテーマを見つけてみましょう。ちなみに私はDraculaっていうテーマが好きです。

marketplace.visualstudio.com

installというボタンがあると思うので、それを押すと、ブラウザによって形は違うかもしれませんがVisual Stadio Code で開きますか?といったメッセージが出てきますのでVSCodeで開きましょう。

VSCodeで以下のような画面になると思うのでインストールを押して、再読み込みも押します。そうしたら、VSCodeが再起動されますので、前述した歯車のボタンから配色テーマを選びましょう。リストにDraculaDracula Softの二つが追加されているはずです。

f:id:Kuzunoha-NE:20180928200410j:plain

好きなテーマにカスタマイズしよう

色んなテーマがありますので、目にいいテーマ、自分にとって使いやすいテーマ、それぞれ探してみてみるといいと思います。そういうのも楽しみの一つなんじゃないかなぁって思いますよ~

FlaskチュートリアルでFlask-Migrateを実施 + flaskrをuwsgiで配信する方法

FlaskチュートリアルでFlask-Migrateを実施 + flaskrをuwsgiで配信する方法

こんにちは、葛の葉です。「くずのは」って読むんですよ。よろしくお願いします。

さて、今回は、Flaskチュートリアルflaskrを見ながらアプリケーションを作っていたのですが、そのうち、Flask-Migrateっていうのを使って、マイグレーションを行おうと思いました。

2. Flaskチュートリアル — study flask 1 ドキュメント

ここの項目を見ればわかるのですが、

$ python
>>> from flaskr.models import init
>>> init()

このようなコマンドを打たないと、DBとPythonが連携されないようです。都度、pythonを起動して行うのは面倒なので、Flask-Migrateを使うことにします。


Flask-Migrateを使う

モジュールのインストールの実施

pip install Flask-Migrate

flaskr/__init__.pyを以下のように編集

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)
app.config.from_object('flaskr.config')

db = SQLAlchemy(app)

migrate = Migrate(app, db)

import flaskr.views

ちなみに2行目なんだけど、

from flask.ext.sqlalchemy import SQLAlchemyではなくて

from flask_sqlalchemy import SQLAlchemyになります。

flask.ext.sqlalchemyというのが廃止されたみたいです。

チュートリアルでは古い情報が残ったままみたいです。

そうして、manage.pyがおいてあるディレクトリをカレントディレクトリにした状態(つまりtutorialディレクトリ)で以下のコマンドを実施。

FLASK_APP=manage.py flask db init
FLASK_APP=manage.py flask db migrate
FLASK_APP=manage.py flask db upgrade

そうすると、migrationsディレクトリが作成され、マイグレーションが完了します。

このmigrationsディレクトリってやつが残っているとFLASK_APP=manage.py flask db initが失敗するようなので、やり直したいときは都度削除してください。

ただ、権限がないと削除できないのでsudo rm -rf migrations/みたいな感じで削除してあげてください。


uwsgiで配信する方法

Flask-Migrateとは関係ないですが、こちらも少し手こずったので共有します。

uwsgiについては、以下のリンクをどうぞ。

The uWSGI project — uWSGI 2.0 documentation

pipでのインストールは以下のコマンドになります。

pip install uwsgi

uwsgi.iniといった名前で、以下のテキストファイルを作ります。

[uwsgi]
http = :3031
chdir = /***/tutorial #manage.pyのおいてあるディレクトリ
wsgi-file = manage.py #manage.pyのやつ
module = flaskr #flaskrディレクトリ
callable = app #flaskのappを呼び込むため必要
chmod-socket = 666
master = true

以上のようにwsgi-filemanage.pyに設定。

chdirをmanage.pyがおいてあるディレクトリに設定。

そして、moduleflaskrに設定することが必要のようです。

次に以下のようなコマンドを打ちます。

uwsgi --init /***/uwsgi.ini

これでuwsgiが起動し、127.0.0.1:3031でwebページが見れるようになるはずです。

ついでに、Nginxと連携したいのなら、以下の記事なんかも見てもらえたらなーって思います。

kuzunoha-ne.hateblo.jp

Ngrokを使ってみようの巻‘ Ubuntu18.04編

Ngrokを使ってみようの巻‘ Ubuntu18.04編

こんちは葛の葉です。

この間はwindowsでのNgrokを作ったかなぁって思ってます。

ngrok.com

kuzunoha-ne.hateblo.jp

今回はUbuntuでやってみましょうか。

環境

動かすんぜよ

wgetでngrokのホームページからダウンロードします。コマンドがない場合はapt install wgetで。

wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip

root# wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
~~~~~
省略
~~~~~
2018-09-14 03:22:57 (2.12 MB/s) - 'ngrok-stable-linux-amd64.zip' saved [5363700/5363700]

lsコマンドでどこに落ちたか確認。カレントディレクトリにダウンロードされてるっぽい。

root# ls
bin   dev  home  lib64  mnt                           opt   root  sbin  sys  usr
boot  etc  lib   media  ngrok-stable-linux-amd64.zip  proc  run   srv   tmp  var

続いてunzipコマンドで解凍してあげよう。コマンドがない場合はapt install unzipで。

root# unzip ngrok-stable-linux-amd64.zip
Archive:  ngrok-stable-linux-amd64.zip
  inflating: ngrok

カレントディレクトリ直下にngrokが出てきた。

root# ls
bin   dev  home  lib64  mnt    ngrok-stable-linux-amd64.zip  proc  run   srv  tmp  var
boot  etc  lib   media  ngrok  opt                           root  sbin  sys  usr

mvコマンドを使って、ngrokコマンドを環境変数PATHに当てたらよかたい

root# mv ngrok /usr/bin/ngrok

これでlinuxでも使えるぜ

ngrok http 3031

root# ngrok http 3031

gcloud入りdockerImageをつくった

gcloud入りdockerImageをつくった

はい、こんばんは。葛の葉です。

私はWindowsPCを使っているのですが、Python3.6入っておりましてGoogle-cloud-SDKはPython2.7で動くみたいなのですね。

Cloud SDK のインストール  |  Cloud SDK のドキュメント  |  Google Cloud

Pythonって2系と3系って両立するんかな(´ω`;)って思って、じゃあ、Dockerで仮想環境作ったらいいじゃんってことで、imageをつくってみました。


Dockerfileは以下の通り

以下の通りであります。

まぁ↓のリンクをを参考にしたんですけどね

Quickstart for Debian and Ubuntu  |  Cloud SDK Documentation  |  Google Cloud

FROM ubuntu:18.04

RUN apt update && apt install curl python2.7 wget gnupg -y

RUN export CLOUD_SDK_REPO="cloud-sdk-bionic" && \
    echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
    apt update -y && apt install google-cloud-sdk -y

先述のリンクと違うところは、5行目の環境変数CLOUD_SDK_REPOcloud-sdk-bionicの値を入れているところです。bionic部分はディストリビューションのコードネームです。そのリンクにはlsb_release -c -sを使って表示させてますが、Ubuntu:18.04の仕様なのかなんなのか、Permission dennyみたいのが出てうまくいきませんでした。

aptのリポジトリのURLにコードネームが入るみたいですが、lsb_release -c -sを使っても空の値が入っちゃうみたいで、設定は成功するけど、apt installでコケちゃいます。

余談

gcloud initを使うとgcloudの初期化が出来ます。

コマンドを叩けば、あとは英語が出てくるので言われたとおりすれば初期化できると思います。

また、apt install kubectlも出来ます。

kubectlコマンドが使えるようになれば、GKEも使えるようになりますよ。

すでに出来ているクラスタへの侵入方法は以下の通り


  1. GoogleCloudPlatformのポータルサイトにアクセスし、画面上部の検索フォームでkubernetes クラスタをクリック。

  2. ページに飛んだら、クラスタの一覧がでるので、右部の接続ボタンを押す。

  3. 下記のようなコマンドが表示されているので、それをターミナルにコピーペー。

gcloud container clusters get-credentials [クラスタ名] --zone [設定されたゾーン] --project [プロジェクトID]

なお、上部に書いてあるgcloud initでアカウント認証をしていないとエラーが出ます。


いつかGKEの使い方とか書いてみたいけど、いつぐらいになるんだろうな(´`)

Ngrokを使ってみようの巻

Ngrokを使ってみようの巻

こんばんは、葛の葉です。

さて、Ngrokというものがありまして、簡単なWebサーバーなら簡単に立ち上げることが出来るすぐれものがあるんです。

ngrok.com

アカウントを入るように求められるのでGoogleとかのアカウントで好きに入ってください。

そしたらダウンロードが出来るのでインストールします。スゴイ。ここまでが準備。


flaskを公開してみようぜ

いつものhelloworldのプログラム(12行)

import flask

app = flask.Flask(__name__)


@app.route('/')
def index():
    return "Hello, World!"


if __name__ == '__main__':
    app.run(debug=True, port=8080)

で起動するとlocalhost:8080で繋がるはずです。127.0.0.1:8080といったほうがいいかな?

f:id:Kuzunoha-NE:20180831192048j:plain

いつもの画面が出てきた。


ngrokを落とすとngrok.exeというものが出てきて、起動するとコマンドプロンプトが立ち上がる。

f:id:Kuzunoha-NE:20180831192937j:plain

このコマンドプロンプトの画面で以下のコマンドを打ちましょう。

ngrok http 8080

なお、8080はポート番号です。flaskアプリのport=8080と合致させましょう。そうしたら、下図の画面に移ります。

f:id:Kuzunoha-NE:20180831192957j:plain

なんかよくわからんけど、https://f1fba471.ngrok.ioに繋がるようだぜ。もちろん、http://f1fba471.ngrok.ioもOK。

f:id:Kuzunoha-NE:20180831192644j:plain

これでスマホでも見れるはず。

みられたねぇ!

コマンドプロンプト画面でctrl + c を押せばやめられます。

以上!!

python clova_sdkで開発しているんですよ -その1-

python clova_sdkで開発しているんですよ -その1-

久しく、お世話になっております。葛の葉です。

最近はclovaの開発を行っております。clovaの開発の記事はまだまだネット上には少ないので、今は公式のドキュメントを読み解きながらプログラミングをするという状況での開発を行っております。

前回の記事では、pythonSDKが来たことと、そのpipでのインストール方法、そして、SDKのドキュメントのリンクなどを記載しました。

kuzunoha-ne.hateblo.jp

現在、clovaの開発用SDKのある言語は以下のようになるようですね。

↓引用元

clova-developers.line.me

SDKがあると、開発が簡単になりますね。使える言語がある人はチャレンジされてみてはいかがでしょうか?


それと、今回は私が開発をしていて、気になった点などを記載したいと思います。

clovaのしゃべるセリフが淡々としている

完全に個人的な感想なのですけど、抑揚とブレス、といいますか。人間っぽくない喋り方といいますか。意図してセリフを区切ったりしないと、淡々としゃべり続けてしまうのがclovaなのかなと思いました。(ほかのスマートスピーカーがどうかは知らないですけど…)ですので、長いセリフとかになりますと全部聞き取れないです。勉強の一環として色んなスキルを導入して使ってみていますが、セリフとしては1秒以内に区切りを入れたほうがいいのかな、と思いました。途中でよくなに喋ってるのかよくわからなくなりました。

ビルトインインテントとカスタムインテントの優先順位ってどっちなんだ?

「はい」や「いいえ」という言葉に反応する「ビルトインインテント」がありまして、個人的には「はい」「いいえ」も自分で作ったインテントで反応させたかったのですが、使ってみたところ「ビルトインインテント」が優先されているように感じました。というか、カスタムインテントで呼び出されることはありませんでした。「はい」も「いいえ」もそれぞれ同じインテントで受け取って、プログラミング内で、返答を変えたかったのですが…ちょっと残念。

最初はよくわからなかったsession_attributesという存在

clovaにはsession_attributesというものが存在しています。最初、これを理解することがなかなかできませんでしたが、やってみれば見るほど、必要な存在なのだなと認識するようになりました。session_attributesとは、clovaがスキルの起動中において、データとしてユーザーが発音した内容を記憶しておける部分になります。例えばユーザーが答えた「マカロニピザ」や「ペパロニピザ」というピザの種類の情報と「2枚」「3枚」という枚数の情報を、session_attributesに保存しておくことができます。その保存した情報を使って、プログラムを使ってピザ屋に情報を送信する、ということが可能になります。

pythonsdkではこんな感じ

import cek
extensionId = '************skill.first'
clova = cek.Clova(application_id=extensionId,default_language='ja', debug_mode=True)
response_builder = cek.ResponseBuilder(default_language='ja')
~~~~~~~~
flaskだとかwebアプリ部分
~~~~~~~~

# PizzaInntent(ピザの種類が呼ばれたときに呼び出されるインテント)
@clova.handle.intent('PizzaIntent')
def pizza_handler(clova_request):
message = '何枚欲しいの?'
end_session = False
response = response_builder.simple_speech_text(message=message, end_session=end_session)

response.session_attributes['pizza'] = clova_request.slot_value('pizzaName')

PizzaInntentが呼び出され、そのうち、pizzaName、ピザの種類を表す単語を取得します。 「マカロニピザを頼んで」という言葉のうち「マカロニピザ」という単語を取得します。

これをsession_attributesとして、{"pizza":"マカロニピザ"}というものに保存されます。

{
    "response": {
        "card": {},
        "directives": [],
        "outputSpeech": {
            "type": "SimpleSpeech",
            "values": {
                "lang": "ja",
                "type": "PlainText",
                "value": "何枚欲しいの?"
            }
        },
        "shouldEndSession": false
    },
    "sessionAttributes": {
        "pizza": "マカロニピザ",
     },
    "version": "1.0"
}

逆にsession_attributesから値を取り出す場合は

pizza = clova_request.session_attributes['pizza']

のような形になります。

このように、ユーザーがしゃべった内容を受け取ることで、プログラミング側であれこれ出来るようになるのです。


私、プログラミング歴短いんですけど、Clovaの開発を通して色々なことを学べていっていけているように感じます。とりあえず、今日は気になったところをサクッと書いてみました。来週もclovaについて書いていきます。よかった次も見ていってください。