SHOYAN BLOG

I am a pragmatic programmer.

プログラマのための数学勉強会@福岡#2に登壇してきました

2015年11月6日(金)にプログラマのための数学勉強会@福岡#2が開催されました。

前回に続き、今回も発表をさせていただきました。

今回は「コンピュータと数学」というタイトルで、コンピュータでデータがどのように扱われているかや、コンピュータで行われる演算についてお話させていただきました。

他の登壇者のかたのスライド

他の登壇者のかたのスライドを紹介します。

###「無限と計算可能性と対角線論法」
@nakalyさんはコンピュータの停止性問題と対角線論法についてお話をされていました。

「Shinyで中心極限定理」

Tomokazu Fujino(@nonki1974)さんは、R言語とフレームワークのShinyを使って行う統計のお話をされていました。
大学の先生をされているので、発表がとてもお上手でした。
fukuoka.Rを主催されているとのことです。
発表のスライドは公開されていないようでした。

「オイラーの等式」

@ringojuringoさんは、「オイラーの等式」の証明についてお話されていました。
テイラー展開を使って証明ができるとのことでした。
発表のスライドは公開されていないようでした。

Twitterのまとめ

プログラマのための数学勉強会@福岡#2まとめ

おわりに

主催者の@tkengo氏は急用のため、残念ながら今回は欠席でしたが、今回も面白い内容だったなと思います。

場所を提供いただいた、LINE Fukuokaさん、登壇者、参加者のみなさん、ありがとうございました!

Rails4でlibディレクトリをautoloadするときのルール

Rails4でlibディレクトリに作ったライブラリを読み込むときはautoloadを利用すると便利です。
autoloadを利用するにはファイル名とクラス名がautoloadのルールに則っている必要があります。

autoload のパスを設定する

まず config/application.rb に autoload 用の設定を行います。

config/application.rb

1
2
#to auto load lib/directory
config.autoload_paths += %W(#{config.root}/lib)

これで、lib ディレクトリ以下のファイルが、以降に説明するディレクトリ・ファイル構成と命名の規約に従うと、自動的に読み込まれるようになります。

lib ディレクトリ以下のファイル

ファイル名は小文字、単語の区切りは _ (アンダースコア)にする。
クラス名はアンダースコアの区切りでキャメルケースにする。

以下はファイル名とクラス名の例です。

lib/hoge_fuga.rb

1
2
class HogeFuga
end

lib/hoge ディレクトリにファイルを置くこともできます。

lib/hoge/fuga.rb

1
2
3
4
5
6
7
8
9
module Hoge
  class Fuga
  end
end

# 以下の様にも書けます。

class Hoge::Fuga
end

以下の様な書き方もできます。

lib/hoge_moge/fuga.rb

1
2
3
4
5
6
7
8
9
module HogeMoge
  class Fuga
  end
end

# もしくは

class HogeMoge::Fuga
end

超高速grep「The Silver Searcher(ag)」からhighwayに乗り換えた

プログラマーにとって,grepコマンドはなくてはならない存在です。
基本的かつ古典的なユーティリティであるgrepですが,使いにくい面もあります。

2013年のはじめころから,grepに取って代わるコマンドとして「The Silver Searcher」(以下「ag」)が注目されはじめました。
そして最近、highwayというagライクで高速なgrepツールがリリースされました。

The Silver Searcher(ag)とは?

highwayの紹介の前にagとagが開発された背景について説明したいと思います。

プログラムを書いていると,ソースコード全域にわたって文字列を検索したい,ということはよくあります。
そのようなときにgrepコマンドが活躍するわけですが,ソースコードのディレクトリには検索したくないファイルが往々としてあるわけです。

たとえばバージョン管理システムが使っている「.git」ディレクトリは,検索対象に含めたくありません。
これをgrepで実現しようとすると,オプションやパイプを組み合わせて,少々面倒なワンライナーを書く必要があります。

こういった問題を解決するため,ackというプログラムが作られました。
ackは以下のような特徴を持つ,開発者向けの賢いgrepツールです。

  • デフォルトでディレクトリツリーを再帰検索
  • .gitなどを暗黙的に除外
  • 検索するファイルタイプをオプションで指定可能(–perl,など)
  • 拡張子だけでなく,shebangを見てファイルタイプを判別可能
  • 検索結果をファイル単位でわかりやすくまとめて表示

ackはgrepと比べて使い勝手がよいのですが,Perlで実装されていることもあり,動作速度に難があります。
その動作速度の問題を改善するためにagが開発されました。

agは開発者が「A code searching tool similar to ack, with a focus on speed.」と紹介しているとおり,「高速なack」を目指して開発されたプログラムです。
「ackに比べて3から5倍高速」を謳っており,そして実際非常に高速です。

The Silver Searcher(ag)の問題点

紹介した通り、使い勝手がよく、性能もよいagなのですが、以下の問題点があります。

  • EUC-JPやShift_JISなどの日本語に使われるマルチバイト文字列が検索できない
  • 検索結果の出力順が検索する度に異なる

全てのコードがUTF-8であれば問題ありませんが、日本語圏で使われるファイルでは、なかなかそうもいきません。
検索結果の出力順が検索する度に異なるのも少し使いにくいと感じます。

その点、highwayはEUC-JPやShift_JISをサポートしており、検索結果の表示順の問題もありません。

highwayのメリット

agの問題点であげた点をhighwayはクリアしています。
また、速度もagよりも高速です。

ベンチマークについては以下の記事をご覧ください。
http://tkengo.github.io/blog/2015/10/19/release-highway/

highwayのインストール

For OS X

homebrewでインストールできます。

1
2
$ brew tap tkengo/highway
$ brew install highway

For Fedora Core

1
2
3
4
5
6
7
8
$ sudo vi /etc/yum.repos.d/highway.repo
[repos.highway]
name=highway
baseurl=http://tkengo.github.io/highway/fedora
enabled=0
gpgcheck=0

$ sudo yum install highway --enablerepo="repos.highway"

使い方

1
2
3
4
5
6
7
8
# カレントディレクトリをhogeをいう文字列で再帰的に検索
$ hw hoge

# public_html以下のディレクトリからhogeという文字列を検索し、マッチした行から10行目までを表示
$ hw -A 10 hoge public_html

# オプションは以下のコマンドで参照できます
$ hw -h

unite.vimと連携する

unite.vimのgrepにhighwayを使うようにします。

1
2
3
4
5
6
7
8
9
" grep検索
nnoremap <silent> ,g  :<C-u>Unite grep:. -buffer-name=search-buffer<CR>

" unite grepにhw(highway)を使う
if executable('hw')
  let g:unite_source_grep_command = 'hw'
  let g:unite_source_grep_default_opts = '--no-group --no-color'
  let g:unite_source_grep_recursive_opt = ''
endif

おわりに

grepツールは完全にhighwayに乗り換えましたが、速度面、機能面に関しては問題ありません。
まだgrepで頑張っている人はもちろん,agをすでに使っている人であっても,highwayの利用を検討する価値は充分にあると思います。

C言語でHello World

たくさんのソフトウェアがC言語で作られており、自分もそういうソフトウェアの仕組みを知ったり自分で作れるようになりたいなと思って、C言語の勉強を始めました。

とりあえず、最初はC言語でHello worldをしてみます。
環境はMac OSXです。
X Codeをいれたら、gccが入るのでC言語はすぐ動くようでした。

gccがインストールされているかの確認

gcc -v と入力して、以下のように表示されたらOKです。

1
2
3
4
5
⇒  gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

Hello Worldする

hello.cを作成して以下のように記入します。

1
2
3
4
5
6
#include <stdio.h>
int main(int argc, char **argv)
{
    printf("hello world\n");
    return 0;
}

コンパイルします。

1
$ gcc hello.c -o hello

helloという実行ファイルができるので、実行します。

1
2
$ ./hello
hello world

天気予報をSlackに通知する on Heroku

@keita_kawamotoが天気予報を見ずに出社して、途中で雨に降られて困っていたので天気予報通知をつくってみました。
Herokuでスケジューラーに登録してSlackに通知するようにしています。

weather-nitify-slack

ソースコードは公開しているので参考にどうぞ。

天気情報を取得する

天気情報の取得はweather_hacksのAPIを利用しました。
APIはjsonでレスポンスが返されます。

以下、サンプルコードです。

slack-weather-notifier.rb

1
2
3
4
5
6
7
8
9
10
11
require 'json'
require 'open-uri'

uri = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400010'

res     = JSON.load(open(uri).read)
title   = res['title']
link    = res['link']
weather = res['forecasts'].first
message = "[#{weather['date']}#{title}](#{link})は「#{weather['telop']}」です。"
puts message

ターミナルでruby slack-weather-notifier.rb と実行すると、今日の天気の情報が表示されます。

Slackに通知する

天気情報の取得ができたので、次はSlackに通知します。
Slackの通知にはIncoming WebHooksを使います。
Incoming WebHooksを使うには、Webhook URLの発行が必要です。

Slackの設定画面にアクセスします。
https://example.slack.com/services/new/incoming-webhook
example.slack.comは自分のSlack Teamのドメインをいれてください。

通知先のチャンネルを選んで、Add Incoming Webhooks Integrationのボタンを押すと発行されます。

slack-setting-example.png

設定画面でWebhook URLが確認できます。
このURLにPOSTすると、Slackに通知できるようになります。

Customize NameやCustomize Iconを変更すると、通知するbotの名前やアイコンが変更できます。

slack-setting-example2.png

では、通知をしてみましょう。
通知はslack-incoming-webhooksというgemを使うと簡単にできるので、今回はそれを使います。

slack-incoming-webhooks をインストール

1
$ gem install slack-incoming-webhooks

先ほどのスクリプトにslack通知の設定を追加します。

1
2
3
4
5
6
7
8
9
10
11
12
13
require 'json'
require 'open-uri'
require 'slack/incoming/webhooks'

uri = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400010'

res     = JSON.load(open(uri).read)
title   = res['title']
link    = res['link']
weather = res['forecasts'].first

slack = Slack::Incoming::Webhooks.new "webhook_url"
slack.post "<#{link}|#{weather['date']}#{title}>は「#{weather['telop']}」です。"

ターミナルでruby slack-weather-notifier.rb と実行してみましょう。
Slackに通知されれば成功です。

HerokuでAppを作成

さて、天気情報とSlack通知ができるようになりました。
これが定期的に実行できれば便利ですね。

Herokuを使えば無料でスクリプトを定期実行できます。
Herokuでアカウントを作成します。
https://signup.heroku.com/

アカウント登録をしたら、Toolbeltをインストールします。
Toolbeltは、Herokuをコマンドラインから利用できるようになるツールです。
https://toolbelt.heroku.com/

次に認証を行います。
ターミナルにheroku loginとコマンドを入力します。
メールアドレスとパスワードが聞かれるので、先ほどHerokuで登録したメールアドレスとパスワードを入力してください。

アプリを作成

アプリケーションを登録しましょう。

Herokuにデプロイするには、Gitを使ってリモートリポジトリへプッシュする必要があるので、Gitの登録を行います。

ここでは、slack-weather-notifierというディレクトリを作成し、そこに先ほどのファイルを作成し、Gitで管理します。

また、Herokuでslack-incoming-webhooks gemを使うためにGemfileでgemを管理します。
slack-weather-notifierディレクトリの直下にGemfileを作成します。

Gemfile

1
2
3
source 'https://rubygems.org'

gem 'slack-incoming-webhooks'

ターミナルで bundle installと実行すると、gemがインストールされ、Gemfile.lockファイルが作成されます。

もし、bundlerをインストールしていない場合は、 gem install bundler でインストールしてください。

以下のような構成になります。

1
2
3
4
slack-weather-notifier
├── Gemfile
├── Gemfile.lock
└── slack-weather-notifier.rb

Webhook Urlは外部に公開すべきではないので、環境変数に登録して、それを使うようにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
require 'json'
require 'open-uri'
require 'slack-incoming-webhooks'

uri = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400010'

res     = JSON.load(open(uri).read)
title   = res['title']
link    = res['link']
weather = res['forecasts'].first

slack = Slack::Incoming::Webhooks.new ENV['WEBHOOK_URL']
slack.post "<#{link}|#{weather['date']}#{title}>は「#{weather['telop']}」です。"

Gitに登録しましょう。

1
2
3
$ git init
$ git add .
$ git commit -m "first commit"

Herokuにpushします。

1
$ git push heroku master

WEBHOOK URLを登録します。

1
heroku config:set WEBHOOK_URL=ここにwebhook_urlを入力

スケジューラーを登録

カード登録

スケジューラーを利用するにはカード登録が必要です。
無料利用枠を超過した場合は料金が発生しますが、数秒で終わるスクリプトなので大丈夫です。

以下でカードを登録できます。
https://dashboard.heroku.com/account/billing

スケジューラーを登録

カード登録ができたらAdd-onsにスケジューラーを追加します。

以下のコマンドでコンソールから登録できます。

1
heroku addons:add scheduler:standard

またはaddonページから登録してください。
https://addons.heroku.com/scheduler

スケジュール管理画面を開く

https://heroku-scheduler.herokuapp.com/dashboard

コンソールからも開けます。

1
$ heroku addons:open scheduler

スケジューラーの設定

Select an appで登録したアプリケーションを選び ‘Add Standard for free’ のボタンをクリックすると登録できます。
登録したら、ダッシュボードのアプリケーションのページのAdd-onsにHeroku Schedulerが表示されています。

クリックすると、設定ページに飛ぶので、コマンドと時間を登録します。
ちなみに時間はUTCなので気をつけてください。
0:00で登録すると日本時間の9:00に通知されます。

heroku-scheduler

ソースコードは公開しているので参考にどうぞ。