スキップしてメイン コンテンツに移動

投稿

PythonでSlackのボットを作成する

職場でSlackを利用している。なかなか使いやすいし便利だ。しかし、技術者としては与えられた機能を利用するだけではやはり満足できない。自分好みの道具を作りたい。 というわけで、単なるチャットツールとして使うSlackでは物足りなくなったので、Slackのボット(bot)をPythonで作ってみることにした。Hubotのようなボット用フレームワークも利用可能だが、SlackのAPIをガシガシ制御する感じにしたかったので、 Slack Real Time Messaging API をPythonから制御してSlackと連携した。今回は、書き込んだ数字を素因数分解するボットを作ってみた。 まずは、Slack用のボットを利用する準備をする。 Slack API にアクセスして、 Bot users をクリックし、Custom bot usersにある creating a new bot user のリンクからBotsのページを開く。 名前(ここでは @prime_decomposition)を入力したらAdd bot integrationボタンをクリックする。 Integration Settingsの画面ではAPI Tokenが表示されており、ボットのスクリプトでこれを利用する。あとは好みに応じてアイコンの変更やボットの説明を記述しておく。今回のボットでは、デフォルトのフェイスマークに用意してあるロボットのアイコンを使い、説明文は「素因数分解をするよ!」とした。あとは、Save Integrationのボタンをクリックして設定を保存する。 ボットの準備ができたら、それをSlackへメンバーとして加える。ボットを参加させたいチャンネル(ここの画像では #general だが #random に参加させたい場合は #random を選択すること)のChannel Settings(歯車のアイコン)から、Invite team members to join...を選択する。先ほど設定したボットがメンバーとして表示されているのでそれを選ぶ。これで下準備は完了だ。 次にPythonを使ってボット用スクリプトを作成する。目的は、Slack上で誰かが数字を書き込んだ際に、それを取得して素因数分解をすること。そのためには、Slackに書き...

Android端末をサーバにしてPyramidフレームワークを利用する

しばらく前に、PythonのWebフレームワークである Pyramid を利用した。これがなかなか良くできており、Android端末上でも動かしてみたくなったので載せてみた。 ところで、自分が利用しているキャリアはドコモなんだけど、 spモード だとグローバルIPが割り振られないので外部から端末にアクセスできない。なので、spモードを契約せずに、 mopera U を利用している。mopera UであればグローバルIPが割り振られるのでアクセスすることができるからだ。このためだけに、spモードにせず、mopera Uにしていると言っても過言ではない。 閑話休題。まず、Pyramidを動作させるにはAndroid端末用のPython環境である SL4A を入れる必要がある。次にPyramidを入れるのだが、必要なモジュールなどが複数あるのでそれも一緒に入れる。一応、Hello Worldプログラムを動かすのに必要なものはすべて挙げたが、もし足りない場合は実行時に何が足りないかエラー表示が出るので、それを参考に入れて欲しい。また、 Android SDK が導入されていることを前提にしている。 まず、Android端末にシェルで入ってプログラムを展開するディレクトリを準備する。環境に合わせてディレクトリは読み替えて欲しい。 > adb shell * daemon not running. starting it now on port 5037 * * daemon started successfully * $ cd /sdcard/sl4a/scripts $ mkdir pyramid $ exit 適当なディレクトリで以下のプログラム・モジュールをPC側で展開する。 pyramid-master.zip translationstring-1.3.tar.gz venusian-1.0.tar.gz WebOb-1.4.tar.gz zope.deprecation-4.1.2.tar.gz zope.interface-4.1.2.tar.gz repoze.lru-0.6.tar.gz PC側からAndroid端末にプログラム・モジュールをコピーする。 > adb push pyramid /...

IRCボットの作成

久々のブログ更新。書きたいときに書くというスタンスです。最近、会社でも技術ブログを立ち上げたので、そちらで書いても良いかも。 今回はIRCボットの作成について書いてみる。しばらく前から社内IRCで技術関連の雑談用チャンネルを利用している。技術系のメーリングリストもあるのだけど、わざわざメールで話題にするようなことでもない、軽い内容を気軽に議論できる場が欲しかったので有志で立ち上げた。IT企業にとって技術的な雑談をできる場はとても大事だと思う。 素のIRCの場合、発言内容がサーバに保存されず、途中から参加しても話題についていけないという問題が出たので、適当なボットで対応することにしたが、やはりエンジニアがメインの会社なのだからボットも自作が基本でしょ、ということでPythonで作ってみた。まあ、作ったといっても「 Python でシンプルな IRC クライアントを作成する 」のサイトを参考にさせてもらったのでスクラッチから作成したわけではない。 コマンド techlog: を入れると、その日の発言がボットからのtalkで返される。ただ、最初は1日分の発言しか取れない仕様だったので、日を跨ぐとその前の発言が取得できないし、一時的にチャットを抜けた分のログが欲しいだけでも強制的に1日分の発言を取得してしまう。 そこで、SQLite3を使ってユーザ毎にログイン・ログアウト時刻を管理して、ログアウトしてからログインするまでの発言を取得できるように変更することにした。新規に参加したメンバーでも自動的にデータベースに登録される。せっかくユーザの時刻情報があるのだから、 techtime: , techtimeall: というコマンドを作って、それぞれ自分の滞在時間、ユーザ全員分の滞在時間も取得できるようにしてみた。 IRCサーバ上で以下のコマンドを実行すると、IRCにボットが常駐する。 $ ./irc_bot.py > irc_bot.log & ソースコードは以下の通り。 そこそこ社内IRCも使えるようになったのだが、最近、別プロジェクトで利用を始めた Slack がかなり便利だったので、そこに技術系チャンネルを作ったところ、ほとんどのメンバーがSlackに流れてしまった…。次は Slackでボット作成 かなぁ。

スピログラフ

スピログラフに初めて触れたのは小学校に上がる前だった。当時はそれがスピログラフという名称であることを知らず、輪っかをぐるぐる回して綺麗な模様を描ける道具としてお気に入りの玩具になっていた。自分はマンデルブロ集合やジュリア集合のような数学的に表現できる図形や模様にともて魅力を感じるのだが、幼少のころのスピログラフがその切っ掛けだったのかもしれない。 長方形の定規に大きさの異なる3枚の歯車が付属しており、そして2つの円がくり抜かれている。さらに、矢印、五角形、半円などの型が子供心をくすぐったものだ。因みに、歯車と円に付いている歯数は刻印されており、3つの歯車はそれぞれ36、52、63、円の方は96、105の歯を持っている。 幼少のころ以来、スピログラフを見かけることはなかったのだが、最近になって100円ショップでも売られているという噂を聞き、少し探ってみた。近くの100円ショップでは扱っていなかったが、「デザイン定規」という名称でネットで78円で売っていたので思わず購入してしまった(当然だが送料のほうが高くついた…)。 スピログラフは一般的には内トロコイド(hypotrochoid; 内余擺線)といい、以下の式で表現できる(Wikipediaより)。 定円の半径 r c 、動円の半径 r m 、描画点の半径 r d とし、下図では、それぞれ、青、緑、赤の線で示している。そして、回転角を θとした軌跡がスピログラフの模様となる。 スピログラフでは半径よりも、円周の歯の数で示した方が分かりやすいだろう。円周と半径の比は変わらないのだから、歯の数の比がそのまま半径の比となる。例えば定円の歯が30で動円の歯が10ならば、 r c : r m =3:1ということだ。 さて、幼少のころはこんなに綺麗な模様が数式で表現できるなどと夢にも思わなかったわけだが、今はそれを理解し、コンピュータを使って自由に描くことができる。コンピュータであれば、動円が定円の外側に来る外トコロイド(epitrochoid; 外余擺線)も描くことができるし、描画点を動円の外に出すことも思いのままだ。 せっかくコンピュータを使って簡単に表示できるようになったというのに、プログラムを組むことが難しくては意味がない。しかし、Python+matplotlibであれば簡単に...

2013年と2014年の違い

2013年を終え、2014年を迎えた。さて、昨年と今年の違いは何か? 昨年のブログで2013を素因数分解すると「3×11×61」になることを示したが、2014は「2×19×53」となる。そして差を取ると、「2-3, 19-11, 53-61」、つまり、「-1, 8, -8」となり、1月、8月が昨年と今年の差であることがわかる。そして、負を示した1月は運気が下がり、正と負を持つ8月は運気の上下があるに違いない! 因みに2013+2014=4027が素数にあることから、昨年から今年にかけて行っていることは、これまでとは違ったユニークな内容となる! …などと、MMRばりなことを書けるぐらいの余裕を持ちつつ、今年一年を頑張りたいと思いますので、本年もどうぞよろしくお願いいたします。 以下にPython+ NZMATH を使った素因数分解を示す。 >>> import nzmath.factor.methods as methods >>> methods.factor(2013) [(3, 1), (11, 1), (61, 1)] >>> methods.factor(2014) [(2, 1), (19, 1), (53, 1)] >>> methods.factor(2013+2014) [(4027, 1)]

クッキークリッカーとプログラマ

先週ぐらいから クッキークリッカー(Cookie Clicker) というJavaScriptを使ったブラウザゲームが流行っている。クリックするだけのゲームと聞いて、最初はあまり興味を持てなかったのだが、自分の周りであまりにもやっている人が多いので少し遊んでみることにした。 クッキークリッカーを簡単に説明すると、まずはクリックすることでクッキーを作り、作ったクッキーを使ってクッキーの生産性を高めるためのアップグレードやアイテムを購入し、たまに出現するゴールデンクッキー(Golden Cookie)をクリックすることでさらに多量のクッキーが得られるので、それらを駆使してできるだけたくさんのクッキーを作るというゲームだ。 このようにとてもシンプルなゲームなのだが、最初はちまちまとしか作れなかったクッキーが徐々に増えていき、様々なアイテムやイベントを通すことで、終盤では毎秒数千億クッキーを作れるというところに人々を惹きつける魅力があるらしい。しかし、自分は「人間の代わりにプログラムを働かせることでどこまで効率が良くなるか」という目的のために自動化プログラムを作成したくなった。コンピュータは人間を楽にさせるために存在するべきだ。 このゲームはJavaScriptで作られており、そのコードや変数を修正すれば簡単にチートを行うことができる。しかし、自分はそれについては全く興味がない。元のシステムには全く手を入れずに人間が操作する部分のみをプログラムで最適化したいのだ。 まず、最初に考えついたのは自動クリックだ。これは様々なツールが世に溢れているのでそれを使っても良いのだが、プログラマだったら、このぐらいは自分で作りたい。そこで、Pythonと pymouse を使って自動クリックプログラムを作成した。これで、毎秒100~200クリックすることができるようになった。これ以上の速度にするとブラウザがついて行けずプチフリーズを頻繁に起こし逆に生産性が落ちてしまう。因みに画面上のエフェクトなどは設定で消しておくほうが良いだろう。 次に、ゴールデンクッキーへの対処だ。ゴールデンクッキーはランダムな間隔でブラウザ上のどこかに出現する。そのクッキーをクリックすると溜まっているクッキーの1割分の枚数が貰えたり、一定時間現在の7倍の効率でクッキーを焼けるようになったりする。...

Pythonを使って簡単にデータを視覚化する

世の中のことをもっと知るにはどうしたら良いだろうと思うときがある。世の中の多くの事柄はログやデータに落とされる。Googleなどの検索サイトは良い例だろう。さて、そのログやデータをどうすれば良いのか? 多くの場合、視覚化が有効な手段となる。 まずは身の回りの日常的なデータやログを何とかしたい。ただ、日常のデータを視覚化するのに数十行以上のコードは書きたくない。まるで息をするかのごとく自然に視覚化を行いたいのだ。そのためには1~2行、長くて数行で済ませることが必要だ。そこでPythonとmatplotlibを使う。加えて、IPythonがあればなお良い。IPythonの導入については以前のブログ記事である IPythonの埋め込みプロットが素晴らしい を参考にして欲しい。 まずは事前にnumpyとmatplotlibをインポートしておく。できればscipyも。 >>> from numpy import * >>> from pylab import * 短いコードで視覚化を行うためには、Pythonの内包表記は必須だ。例えば、5, 2, 1, 5, 8をデータとするグラフを書きたいのならIPythonを使って以下の1行で実現できる。 >>> plot([5, 2, 1, 5, 8]) 数値が行ごとにinput.txtというファイルに書かれていた場合は以下の通り。 >>> plot([int(x) for x in file("input.txt")]) map関数を使えばもっとスマートに書ける。ファイル内の数値を文字列として配列で読み込み、それらの文字列をmap関数によりintで整数に変換する。 >>> plot(map(int, file("input.txt"))) さて、ログが2次元で書かれていた場合はどうするのか。例えば以下のデータがinput.txtに書かれていたとする。 2, 2.5 5, 6.2 6, 3.6 7, 6.3 10, 1.9 この場合、以下のようにすればプロットできる。ファイルから行ごとの文字列を読み出して、それを","を区切りとしてリス...