with-eval-after-loadとrequireとautoloadとadd-hookと
発端
違いは何だ!!
まとめ
違ったら教えてください
- 起動してずっと使ってる ->
require
- 起動時には必要ないけどmodeごとでは使う ->
autoload
- ライブラリでのsetqとかの設定 ->
add-hook
- ライブラリでのdefine-keyとかの設定 ->
with-eval-after-load
調べた感じ
autoload
とrequire
は使うタイミングは似てる?autolad
は必要なときに読んでくるので起動時に必要ではないものを設定するといいrequire
はこれが呼ばれたタイミングでライブラリ読むので起動時必要なものだけにしたほうが良さそう
起動時にjs2-modeが呼び出される
(require 'js2-mode) (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
初めてjsファイルを開いた時にjs2-modeが読み出される
(autoload 'js2-mode "js2-mode" nil t) (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
eval-after-load
とwith-eval-after-load
とadd-hook
の違い
eval-after-load
とwith-eval-after-load
の違いはwith-eval-after-load
はemacs24.4から新しく入ったマクロでprogn
使わなくて良くなった- add-hookはバッファを呼び出すたびに呼ばれる
eval-after-load
は最初に設定しているライブラリがloadされるたびに呼ばれるが2回目以降は早いらしい
This macro arranges to evaluate body at the end of loading the file library, each time library is loaded. If library is already loaded, it evaluates body right away. 15.10 Hooks for Loading
- setqとかはadd-hookがよくてdefine-keyとかはwith-eval-after-loadかな?
参考
YosemiteにEmacs24.4いれてみた
Yosemiteにする際についでにクリーンインストールしたので設定しなおした記録
書くこと
Emacs24.4をYosemiteに入れたところ
inline patch当てなくていい人は1と5だけやればいい
- 1 何はともあれまずはEmacsを取ってくる
$ curl -L -O http://ftpmirror.gnu.org/emacs/emacs-24.4.tar.gz $ tar zxvf emacs-24.4.tar.gz
- 2 今回はinline-pathもあてようと思うのでそっちも取ってくる
$ curl -L -O http://plamo.linet.gr.jp/~matsuki/mac/emacs-24.4-20140417-inline.patch
- 3 パッチ当てるとビルドするときにライブラリが必要になるのでいくつか入れる
$ brew install autoconf automake
- 4 パッチ当てる
$ cd emacs-24.4 $ patch -p1 < ../emacs-24.4-20140417-inline.patch
5 ビルドする
$ ./configure --with-ns --without-x | make -j2 | make install
以上でnextstep/Emacs
ができてるはずなので/Application
以下に移動すると使えるようになる
困ったところ
1. helmがmakeできない
helmが(require 'cl-lib)
してるんだけど,そんなものはないって怒られる
原因
makeするときは/usr/local/bin/emacs
の方を使っているのが原因っぽかった
/usr/local/bin/emacs
のバージョンが21くらいでcl-lib
が入ったので24からなのでほんとにそんなものはなかった
Cocoa Emacsにしなかったらこんなことにはならなかったな?
解決策
バージョンが24以上のemacsを入れる
brew install emacs
2. zlcが動かない
(wrong-number-of-arguments (2 . 4) 0)
こんなかんじのエラーが出る
以下に詳しくのってた
zlc-minibuffer-complete
の(completion--do-completion)
を(completion--do-completion (minibuffer-prompt-end) (point-max))
にすれば動くようになりました。
らしい
参考
emacsでScala環境設定
Scala開発環境の覚え書き
前提
インストール
brew で入れたもの
- scala
- sbt
el-getでemacsに入れたもの
実際
brew を使って要りそうなものを入れる(sbtが何なのかよくわかってないけどなんかみんな入れてた)
brew install scala brew install sbt
emacsにはel-getでscala-mode2とensimeを入れる
scala-modeもあったんだけどscala-mode2のがemacs24向けらしい
設定
パスは通ってるのでemacsの設定ファイルに以下を書くだけ
(require 'scala-mode2) (require 'ensime) (add-hook 'scala-mode-hook 'ensime-scala-mode-hook)
~/.sbt/0.13/plugins/plugins.sbt
に以下をついか(なかったら作る)
resolvers += Resolver.sonatypeRepo("snapshots") addSbtPlugin("org.ensime" % "ensime-sbt" % "0.1.5-SNAPSHOT")
ちょっと書いて見よう
参考
Rails4でActiveAdminとdeviseとcancancanをつかって管理者ページを作る
環境
Gemfile
gem 'rails', '4.1.2' gem 'cancancan' gem 'devise' gem 'activeadmin', github: 'activeadmin'
bundleする
$ bundle install
まずはdeviseでモデルを作る.
role
でadminかどうかを判定するのでUser
コントローラに追加
$ rails generate devise:install $ rails generate devise User $ rails generate migration add_role_to_users role:integer $ rake db:migrate
Deviseのモデルを使うのでActiveAdminでUserモデルをつくらないようにするために--skip-users
$ rails generate active_admin:install --skip-users create config/initializers/active_admin.rb create app/admin create app/admin/dashboard.rb route ActiveAdmin.routes(self) generate active_admin:assets create app/assets/javascripts/active_admin.js.coffee create app/assets/stylesheets/active_admin.css.scss create db/migrate/20140829091410_create_active_admin_comments.rb $ rake db:migrate
これするとconfig/intializers/active_admin.rb
のなかを幾つか変えないといけない
config.current_user_method = :current_admin_user ↓ config.current_user_method = :current_user config.logout_link_path = :destroy_admin_user_session_path ↓ config.logout_link_path = :destroy_user_session_path
またapp/application_controller.rb
に以下を追加
def authenticate_admin_user! authenticate_user! unless current_user.admin? flash[:alert] = "This area is restricted to administrators only." redirect_to root_path end end
user
モデルはadmin?
は持ってないので以下をmodel/user.rb
に追加(Rails 4からenum
が使える)
enum role: %(admin normal)
cancancanいらなかった!!!
role
が3つ以上あるといる気がするけどめんどくさそう
参考
Railsで新規にWebサービスを立ち上げる際にやったことまとめ [Rails] Devise and Active Admin Single User Model
集合知プログラミング 2章をrubyで書いた
書きました。
APIを使うところは省略しています
critics = { 'Lisa Rose' => { 'Lady in the Water' => 2.5, 'Snakes on a Plane' => 3.5, 'Just My Luck' => 3.0, 'Superman Returns' => 3.5, 'You, Me and Dupree' => 2.5, 'The Night Listener' => 3.0 }, 'Gene Seymour' => { 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 3.5, 'Just My Luck' => 1.5, 'Superman Returns' => 5.0, 'The Night Listener' => 3.0, 'You, Me and Dupree' => 3.5 }, 'Michael Phillips' => { 'Lady in the Water' => 2.5, 'Snakes on a Plane' => 3.0, 'Superman Returns' => 3.5, 'The Night Listener' => 4.0 }, 'Claudia Puig' => { 'Snakes on a Plane' => 3.5, 'Just My Luck' => 3.0, 'The Night Listener' => 4.5, 'Superman Returns' => 4.0, 'You, Me and Dupree' => 2.5 }, 'Mick LaSalle' => { 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 4.0, 'Just My Luck' => 2.0, 'Superman Returns' => 3.0, 'The Night Listener' => 3.0, 'You, Me and Dupree' => 2.0 }, 'Jack Matthews' => { 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 4.0, 'The Night Listener' => 3.0, 'Superman Returns' => 5.0, 'You, Me and Dupree' => 3.5 }, 'Toby' => { 'Snakes on a Plane' => 4.5, 'You, Me and Dupree' => 1.0, 'Superman Returns' => 4.0 } } def sim_distance(prefs, person1, person2) si = prefs[person1].select { |k, _v| prefs[person2].key?(k) }.keys return 0 if si.size.zero? sum_of_square = si.inject(0) do |a, e| a + (prefs[person1][e] - prefs[person2][e])**2 end 1 / (1 + sum_of_square) end def sim_piason(prefs, person1, person2) si = prefs[person1].keys.select { |k| prefs[person2].key?(k) } n = si.size return 0 if n.zero? sum1 = si.inject(0) { |a, e| a + prefs[person1][e] } sum2 = si.inject(0) { |a, e| a + prefs[person2][e] } p_sum = si.inject(0) { |a, e| a + (prefs[person2][e] * prefs[person1][e]) } sum1_sq = si.inject(0) { |a, e| a + prefs[person1][e]**2 } sum2_sq = si.inject(0) { |a, e| a + prefs[person2][e]**2 } s_xy = p_sum - (sum1 * sum2 / n) s_xx = sum1_sq - (sum1**2 / n) s_yy = sum2_sq - (sum2**2 / n) return 0 if Math.sqrt(s_xx * s_yy).zero? s_xy / Math.sqrt(s_xx * s_yy) end def top_match(pref, person, n = 5, similarity = method(:sim_piason)) personp = ->(x) { x == person } cal_sim = ->(p) { [p, similarity.call(pref, p, person)] } descend = ->((_, p1), (_, p2)) { p2 <=> p1 } pref.keys.reject(&personp).map(&cal_sim).sort(&descend)[0...n] end def get_recommendation(pref, person, similarity = method(:sim_piason)) personp = ->(x) { x == person } cal_sim = ->(p) { [p, similarity.call(pref, p, person)] } gt_zero = ->(x) { x[1] > 0 } person_has_item = ->(x) { pref[person].key?(x) } totals = {} sim_sum = {} pref.keys.reject(&personp).map(&cal_sim).select(>_zero).each do |other, sim| pref[other].keys.reject(&person_has_item).each do |item| totals[item] = (totals[item] || 0) + pref[other][item] * sim sim_sum[item] = (sim_sum[item] || 0) + sim end end totals.map do |(k, v)| [(v / sim_sum[k]), k] end.sort.reverse end def transform_prefs(prefs) prefs.each_with_object({}) do |(person, items), a| items.each do |movie, v| a[movie] ||= {} a[movie][person] = v end end end def calculate_similar_item(prefs, n = 10) item_pref = transform_prefs(prefs) item_pref.keys.each_with_object({}) do |item, a| a[item] = top_match(item_pref, item, n, method(:sim_distance)) end end def get_recommended_items(prefs, item_match, user) user_rating = prefs[user] scores = {} total_sim = {} user_rating.each do |item, rating| item_match[item].reject { |item2, _| user_rating.keys.include?(item2) }.each do |item2, sim| scores[item2] = (scores[item2] || 0) + sim * rating total_sim[item2] = (total_sim[item2] || 0) + sim end end scores.map do |item, score| [(score / total_sim[item]), item] end.sort.reverse end if __FILE__ == $PROGRAM_NAME # p transform_prefs(critics) # p sim_piason(critics, 'Lisa Rose', 'Gene Seymour') # p sim_distance(critics, 'Lisa Rose', 'Gene Seymour') # p top_match(critics, 'Toby', 3) # p get_recommendation(critics, 'Toby') item_sim = calculate_similar_item(critics) p get_recommended_items(critics, item_sim, 'Toby') end
今日解いた問題3
今日というか今日と昨日
単一始点最短経路問題(ベルマンフォード)
ある頂点sからのすべての頂点の最短経路
d[j] > d[i] + cost
この条件を1度使っただけでは明らかに最短にならないので
update
変更がなくなるまでループを繰り返す
INF = 100_000 G = [[INF, 2, 5, INF, INF, INF, INF], [2, INF, 4, 6, 10, INF, INF], [5, 4, INF, 2, INF, INF, INF], [INF, 6, 2, INF, INF, 1, INF], [INF, 10, INF, INF, INF, 3, 5], [INF, INF, INF, 1, 3, INF, 9], [INF, INF, INF, INF, 5, 9, INF]] def shotest_path(s) d = Array.new(G.size, INF) d[s] = 0 loop do update = false G.each_with_index do |row, i| row.each_with_index do |cost, j| next if cost == INF || d[i] == INF if d[j] > d[i] + cost d[j] = d[i] + cost update = true end end end break unless update end d end p shotest_path(0) # => [0, 2, 5, 7, 11, 8, 16]
単一始点最短経路問題(ダイクストラ)
ベルマンフォードと目的は一緒
まだ訪れていない頂点の中から最短の頂点を見つけてそこから他の頂点への経路のコストを得る
INF = 100_000 G = [[INF, 2, 5, INF, INF, INF, INF], [2, INF, 4, 6, 10, INF, INF], [5, 4, INF, 2, INF, INF, INF], [INF, 6, 2, INF, INF, 1, INF], [INF, 10, INF, INF, INF, 3, 5], [INF, INF, INF, 1, 3, INF, 9], [INF, INF, INF, INF, 5, 9, INF]] def dijkstra(s) size = G.size d = Array.new(size, INF) used = Array.new(size, false) d[s] = 0 loop do min_node = -1 size.times do |i| min_node = i if !used[i] && (min_node == -1 || d[min_node] > d[i]) end break if min_node == -1 used[min_node] = true size.times do |i| d[i] = [d[min_node] + G[min_node][i], d[i]].min end end d end p dijkstra(0) # => [0, 2, 5, 7, 11, 8, 16]
全点対最短経路( ワーシャルフロイド)
すべての頂点からそれ以外のすべての頂点の最短経路
i
からj
までのパスの中で頂点k
通るか通らないかのDP
通るときはg[i][k] + g[k][j]
で通らない時はg[i][j]
ホントはd[k][i][j]
とかなるんだけどループ内で省略してる
INF = 100_000 def warshall_floyd g = [[0, 2, 5, INF, INF, INF, INF], [2, 0, 4, 6, 10, INF, INF], [5, 4, 0, 2, INF, INF, INF], [INF, 6, 2, 0, INF, 1, INF], [INF, 10, INF, 0, INF, 3, 5], [INF, INF, INF, 1, 3, 0, 9], [INF, INF, INF, INF, 5, 9, 0]] size = g.size size.times do |k| size.times do |i| size.times do |j| g[i][j] = [g[i][j], g[i][k] + g[k][j]].min end end end g end p warshall_floyd # [[0, 2, 5, 7, 11, 8, 16], [2, 0, 4, 6, 10, 7, 15], [5, 4, 0, 2, 6, 3, 11], [7, 6, 2, 0, 4, 1, 9], [7, 6, 2, 0, 4, 1, 5], [8, 7, 3, 1, 3, 0, 8], [12, 11, 7, 5, 5, 6, 0]]
アリ本のP102
2番めの最短経路をだす問題
priority_queueがなかったのでかなり汚い感じになった
基本方針はすべての頂点に対して2番めの最短経路も持っとくこと
N = 4 M = 4 INF = 100_000 G = [[INF, 100, INF, INF], [100, INF, 250, 200], [INF, 250, INF, 100], [INF, 200, 100, INF]] def solve d1 = Array.new(N, INF) used1 = Array.new(N, false) d2 = Array.new(N, INF) used2 = Array.new(N, false) d1[0] = 0 d2[0] = 0 loop do v = [-1, 1] N.times do |i| v = [i, 1] if !used1[i] && (v[0] == -1 || d1[v[0]] > d1[i]) v = [i, 2] if !used2[i] && (v[0] == -1 || d2[v[0]] > d2[i]) end break if v[0] == -1 eval("used#{v[1]}[#{v[0]}]=true") N.times do |i| d = eval("d#{v[1]}[#{v[0]}]") + G[v[0]][i] if d < d1[i] d, d1[i] = d[i], d end if d > d1[i] && d < d2[i] d2[i] = d end end end d2[N-1] end p solve # => 450
今日解いた問題2
彩色問題
アリ本の93ページ
隣接したりノードが同じ色にならないように色をぬる。
今回は2色で塗ることができるかという問題
特に2色でぬれるグラフを2部グラフという
コードで言うと0が塗ってないノードなので下の2つを繰り返す感じ
- 隣接したノード
j
が0ならノードj
に対して色(-c
)を塗る - 隣接したノード
j
と現在のノードがi
が同じ色c(1 or 0)
ならfalse
を返す
G1 = [[0, 1, 1], [1, 0, 1], [1, 1, 0]].freeze G2 = [[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]].freeze s = G2.size $color = Array.new(s, 0) # 0は塗ってない 1と-1が塗った def dfs(i, c) $color[i] = c G2[i].each_with_index do |e, j| next unless e == 1 return false if $color[j] == c return false if $color[j].zero? && !dfs(j, -c) end true end s.times do |i| next unless $color[i].zero? unless dfs(i, 1) puts 'NO' break end puts 'YES' end