Kuzunoha-NEのブログ

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

Pythonでバブルソートアルゴリズムを作ろうの巻

Pythonバブルソートアルゴリズムを作ろうの巻

こんばんは、葛の葉です。最近、電車乗ってるときにスマートフォンPythonのプログラミングの勉強してます。やらない日もあるけど……ちなみにiPhone7を使用しています。

なお、使っているアプリはPythonista3です。

Pythonista for iOS

Pythonista 3

Pythonista 3

  • omz:software
  • Productivity
  • $9.99

f:id:Kuzunoha-NE:20181012191103p:plain

このアプリはPythonを実行することが出来るし、オリジナルな自分用アプリを作ることが出来ます。pipが使えなかったりgitが使えなかったりですが、iPhoneでカーソル移動が出来たりと結構かゆいところに手が届くアプリです。

アルゴリズムをやってみようって思ったんだ

アルゴリズムが出来ないのはよろしくないんだと、どっかで聞きました。どこかは忘れましたが、とにかくプログラマーがアルゴリズムを実装出来ないはよくないんだと。

どういうアルゴリズムが実装出来ないのがダメなのかがよくわからんけれども、とりあえずソートアルゴリズムは出来たほうがよかろうということで、とりあえず作ってみることにしました。

バブルソートアルゴリズムについて

バブルソートアリゴリズムについては、はてなキーワードにも載ってますね。

d.hatena.ne.jp

ソートとは並び替えのことで、ソートアルゴリズムは並び替えを実施するための仕組みです。

バブルソートアルゴリズムはリストの要素を読んでいき、その要素とその隣の要素のほうが大きい(または小さい)場合、値を取り換えるというものです。

それを繰り返していくことで降順、昇順にソートすることが出来るようです。

環境

Pythonista Ver3.2 Python Ver3.6.1

私のプログラミング例

私はこんな感じにプログラミングしてみました。

def bubble_sort(arrs):
    if type(arrs) is list:
        flag = True  ...(1)
        while flag == True: ...(1) 
            flag = False ...(1)
            for i in range(len(arrs)):
                if i == len(arrs) - 1: ...(2)
                    pass
                elif arrs[i] > arrs[i + 1]:
                    arrs[i], arrs[i + 1] = arrs[i + 1], arrs[i] ...(3)
                    flag = True
                else:
                    pass
        return arrs
    else:
        return 'list de ok' ...(4)


test = [1, 2, 5, 8, 6, 7, 3, 4, 9]
print(bubble_sort(test))

なんか、もっといいやり方があるような気がするけど、それは君自身で確かめてみてくれ!!!!

(1) ... フラグを作っています。隣の要素をみて、値を交換した時にこのフラグがTrueになり、繰り返しが再び始まります。逆に一回も交換しなかった場合、フラグはFalseのままとなりますので、繰り返しが止まります。

(2) ... len(arrs) -1 はlen(arrs)が要素数+1で出力されているため、-1しています。

(3) ... arrs[i], arrs[i + 1] = arrs[i + 1], arrs[i]Python特有の値の交換方法です tmp = a a = b b = tmp ということをやらなくていいのがpythonのいいところですね。(a + b) = (b + a)のほうが正しいみたいな話はどっかで聞いた気がする。

(4) ... 'list de ok'は引数がリスト型でない場合怒られるようにしています。

他のアルゴリズムもやってみたいです。

このアルゴリズムは勉強になるよ~ってのがあったら教えてください~

Mercari TECH CONF 18に行ってきました。「マイクロサービスプラットフォームチーム」のお話を聞いて。

Mercari TECH CONF 18に行ってきました

こんにちは、葛の葉です。

2018/10/04に行われましたMercari TECH CONFに行ってきました。

techconf.mercari.com

今回はそのときのことをお話しします。

キーワードは「MicroService」

speakerdeck.com

今回の公演ではMicroServiceという言葉をよく耳にしました。もともと、メルカリさんは大きなサーバを使用していたらしいのですが、そのサーバにはMercariAPIと呼ばれるメルカリの販売や記録などを取り扱っている複合的なAPIサーバがあります。巨大でかつ一つのサービスであるから、これをMonolithicと呼んでいました。最近では「小さなサービスの複合体」という体制に移行していて、それをMicroServiceとよび、これを「Google Cloud Platform(以下、GCP)」にて実運用しているとのことです。

「かつてのMonolithic」対「これからのMicroService」という比較による公演が多かったような気がします。もちろん、MicroServiceはサービス数が増える=複雑になるというデメリットもあるので、如何にそれに対処するかというところもお話されていました。また、そのMonolithicからすぐにMicroServiceに完全移行するのではなくて、2つを共存しつつ、段階的にどう移行するか、がよく話されていた印象です。

人数が増えて「チーム」というより「組織」になった

メルカリさんはたくさんの人を雇い入れることに成功し、2017年から2018年の間で、社員数が120人から350人にまで増えたとこのとです。これに伴い、「チーム」として開発していた感覚が「組織」っぽくなってしまったらしいです。(「組織」というには大げさかもしれない、ともおっしゃっていました。)特に裁量がなくなり、スピードが下がったり、思想でのぶつかり合いも発生したとのことでした。また、工程単位でチームにしていたので、その工程で「待ち」が発生すると「ボトルネック」になってしまうというデメリットを話されていました。

そこで工程単位ではなくサービス単位で開発チームを構成し、そのチームが各工程を全て行うようにした。デプロイから運用までサイクルのすべてを担うというとのことです。その方法については、チームが意思決定を行うので、裁量が高くなるとのことでした。一方で、そのデプロイから運用までのサイクルをどうチームが行うかが課題になったということです。

Kubernetesとマイクロサービスプラットフォームチーム

上記サービス単位でのチームがデプロイと運用までを簡単に行えるように、マイクロサービスプラットフォームチームというチームを作ったとのことです。マイクロサービスプラットフォームチームは開発チームがスムーズにデプロイから運用まで行えるように4つの工夫を行ったとのことです。

1つめに、APIゲートウェイという、クライアントからの要求に対し、MercariAPIとMicroServiceを分離させるサーバの構築を行ったとのことです。2つめに、サービスの単位となるContainerを起動させるKubernetesの採用を行ったとのことです。3つめに、MicroService間の通信にGRPCの採用を行いました。さらに、MicroServiceを一から構築するのが大変なため、テンプレートを作成したとのことでした。最後に、インフラ周りのアクセスはKubernetesの設定にてチーム単位で行うようにしたとのことです。

MicroService単位の開発チームの構成

以前までは、同じような価値観の人同士が集まるようなコミュニティになっていてサイロ化してしまっていたが、上記のように、MicroService単位でのチーム構成にすることで、チーム内の価値観の違う人通しでも多様な思想を巻き込んで開発が出来るようになったり、いろいろな能力を合わせることでシナジーを得ることが出来るようになったとのことです。また、それぞれのMicroService内で出来た知見などは共有できるようになり、より洗練されていったとのことです。

私見

ここからは私の私見ですけど、かつて、工場生産におけるセル生産方式なんてものがあったかなぁいうのを思い出しながら聞いていました。特にMicroService単位でチームを組み、ソフトウェアのライフサイクルを全部担当するという点が、なんだかそれを思い出させました。

工場といえばライン生産方式といって、コンベアから流れてくるものと、手持ちのパーツを組み合わせて次の工程のレーンに流すというのをひたすらに繰り返すというものが基本でしたが、90年代後半になると在庫数の問題の発生や生産数等をフレキシブルに対応するために、一人で殆どの組み立て工程を行うセル生産に着眼されるようになるんです。一人で、と言っても、ワンオペレーションというわけじゃないです。同じように殆どの工程を行う人を何人も雇うんです。

ほとんどの組み立て行程を一人でやることで、それぞれの工程で個々の組み立てにおける工夫だとかこだわりというのが出てくるんですよね。考えて生まれた工夫もあると思うし、偶発的に生まれた工夫もあるんだと思います。その工夫が同じようにセル生産で仕事をしている人同士のコミュニケーションを通して洗練され、組み立てのスピードは徐々に早まっていったと、聞いたことがあります。

大事なのは個性なんだと思います。(あと、それで生まれた情報を共有することも当然ですけど。)

イノベーションが生まれるタイミングについても同じ価値観の人より異なった価値観の人が集まったチームの方がよいとおっしゃっていたのも、なんとなくわかる気がします。

他にもメルカリさんの話は興味深かったです。

例えば機械学習で画像認識と感動出品という話も面白かったですし、MercariXについても気になることが山盛りでした。また別のタイミングでまとめたいと思います。

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の使い方とか書いてみたいけど、いつぐらいになるんだろうな(´`)