現実逃避的にアナーキーゴルフ。
cf. anarchy golf – delete blank lines
これで26バイト。どうやったら12バイトでできるんだ?
$><<$<.read.gsub(/^\n/,"")
takatoh's blog – Learning programming languages.
現実逃避的にアナーキーゴルフ。
cf. anarchy golf – delete blank lines
これで26バイト。どうやったら12バイトでできるんだ?
$><<$<.read.gsub(/^\n/,"")
以前に試したときにはどういうわけだかうまくいかなかってけど,今度はうまくいったので(ちょっとはまったけど),メモ。
はてなダイアリーライター本体はここから(Version 1.4.1)。マニュアルもここ。
まずは試してみる。テスト用の日記ファイルを作って,設定ファイルはなしでやってみたらすんなり成功。ちょっと拍子抜け。
^o^ >perl hw.pl WARNING: Crypt::SSLeay is not found, use non-encrypted HTTP mode. Username: takatoh Password: ******** Login to http://www.hatena.ne.jp/login as takatoh. Login OK. Post 2007-07-08. Post OK. Logout from http://d.hatena.ne.jp as takatoh. Logout OK.
けどちょっと待て。Cyrpt::SSLeayが無いから暗号化しないモードを使うといってる。
……それで思い出した。以前うまくいかなかったのはこのあたりだった。
というわけで,このへんのページを参考に改めてチャレンジ。
まずはOpenSSLから。上のリストの2番目のページからインストーラ(最新版 Win32OpenSSL v0.9.8e)をダウンロードしてインストールするだけ。
Crypt::SSLeay のほうは上のリストの3番目のページにある「LWPで、「https://」で始まるSSL使用サイトにアクセスできますか?」を参考にした。ppmコマンドでインストールするんだけど,モジュール名ではなくPPDファイル名を指定する必要があるらしい(GUI版ppmのリストに出てこない)。ActivePerl 5.8.8 を使っているので:
^o^ >ppm install http://theoryx5.uwinnipeg.ca/ppms/Crypt-SSLeay.ppd
後半,dllをインストールするか聞いてくるので yes と答えてインストールする。デフォルトが[no]になってるので注意。
さて,改めて試してみよう。ついでに設定ファイルも書いておく。
id:takatoh password:******** cookie:cookie.txt proxy:http://proxy:8080/ client_encoding:Shift_JIS server_encoding:EUC_JP
これでOKのはず。
^o^ >perl hw.pl Login to https://www.hatena.ne.jp/login as takatoh. Login OK. Post 2007-07-08. Old cookie. Retry login. Login to https://www.hatena.ne.jp/login as takatoh. Login OK. Old cookie. Retry login. Login to https://www.hatena.ne.jp/login as takatoh. Login OK. ERROR: try_it: Check username/password.
なんでエラーになるんだ!!……orz
えーと。いろいろ試した結果何とか動くようになった。これについてはエントリーを改めて書く。
さきに書いておくと,インストールや設定ファイルは上の通りで大丈夫(たぶん)。問題はcookie.txtだった。--(つづく)
id:takatoh:20070708:hw のつづき。Crypt::SSLeayをインストールしたらエラーになった件。
いろいろ試した結果,クッキーファイル(cookie.txt)の有無と関係が有ることがわかった。表にするとこんな感じ。
cookie.txtあり | cookie.txtなし | |
Crypt::SSLeayなし | OK | OK |
Crypt::SSLeayあり | OK | エラー |
Crypt::SSLeayが無い場合にはcookie.txtの有無に関わらずOKなんだけど,これは暗号化されないってことなんで非推奨。Crypt::SSLeayをインストールするとcookie.txtが無い場合にエラーになる。無けりゃ作ってくれるはずなんだけど,ここで失敗しているように見える(最後から2行目)。……ちがうのかな。
-d オプションをつけて実行した結果:
^o^ >perl hw.pl -d DEBUG: Debug flag on. Hatena Diary Writer Version 1.4.1 Copyright (C) 2004,2005 by Hiroshi Yuki. DEBUG: Loading config file (config.txt). DEBUG: load_config: id:takatoh DEBUG: load_config: password:******** DEBUG: load_config: cookie:cookie.txt DEBUG: load_config: proxy:http://proxy:8080/ DEBUG: load_config: client_encoding:Shift_JIS DEBUG: load_config: server_encoding:EUC_JP DEBUG: main: files: current dir (.): ./2007-07-08.txt ./touch.txt DEBUG: login: proxy for http: http://proxy:8080/ DEBUG: login: proxy for https: http://proxy:8080/ Login to https://www.hatena.ne.jp/login as takatoh. DEBUG: login: 200 OK DEBUG: login: $r = <HTML></HTML> Login OK. DEBUG: login: Making cookie jar. DEBUG: login: $cookie_jar = DEBUG: read_title_body: input: ./2007-07-08.txt DEBUG: Convert from Shift_JIS to EUC_JP. Post 2007-07-08. DEBUG: create_it: 2007-07-08. DEBUG: create_it: 302 Moved DEBUG: create_it: Location: /takatoh/ DEBUG: create_it: returns 0 (ERROR). DEBUG: try_it: update_diary_entry: CREATE. Old cookie. Retry login. DEBUG: login: proxy for http: http://proxy:8080/ DEBUG: login: proxy for https: http://proxy:8080/ Login to https://www.hatena.ne.jp/login as takatoh. DEBUG: login: 200 OK DEBUG: login: $r = <HTML></HTML> Login OK. DEBUG: login: Making cookie jar. DEBUG: login: $cookie_jar = DEBUG: create_it: 2007-07-08. DEBUG: create_it: 302 Moved DEBUG: create_it: Location: /takatoh/ DEBUG: create_it: returns 0 (ERROR). DEBUG: try_it: update_diary_entry: CREATE. Old cookie. Retry login. DEBUG: login: proxy for http: http://proxy:8080/ DEBUG: login: proxy for https: http://proxy:8080/ Login to https://www.hatena.ne.jp/login as takatoh. DEBUG: login: 200 OK DEBUG: login: $r = <HTML></HTML> Login OK. DEBUG: login: Making cookie jar. DEBUG: login: $cookie_jar = ERROR: try_it: Check username/password.
結局,Crypt::SSLeayをインストール/アンインストールしたり,設定ファイルを書き換えてみたりしてるうちにできた(つまりCrypt::SSLeayなしの時にできた)クッキーファイルがあって動くようになったので今回はOKとする。Crypt::SSLeayありの状態でクッキーファイルを作る方法はわからない。
なんだか中途半端だけど時間切れだ。
hyukiさんのアドバイスに従ってproxyの無い環境で試してみたら,正しく投稿できた。どうやら次の3つが重なったときにエラーになるらしい。
こんどは Ruby で。
require 'date' y, m, d = ARGV.map{|arg| arg.to_i } date = Date.new(y, m, d) sunday = (date - date.wday) (1..5).each do |d| puts((sunday + d).strftime("%Y-%m-%d %a")) end
実行。
^o^ >week.rb 2007 7 7 2007-07-02 Mon 2007-07-03 Tue 2007-07-04 Wed 2007-07-05 Thu 2007-07-06 Fri ^o^ >week.rb 2007 1 1 2007-01-01 Mon 2007-01-02 Tue 2007-01-03 Wed 2007-01-04 Thu 2007-01-05 Fri ^o^ >week.rb 2007 12 30 2007-12-31 Mon 2008-01-01 Tue 2008-01-02 Wed 2008-01-03 Thu 2008-01-04 Fri
条件を満たす行を取り除く
via http://d.hatena.ne.jp/gan2/20070706/1183708048
‘#’で始まる行を取り除く問題。すげーひさしぶりに Haskell で書いてみる。
module Main where import System f :: String -> Bool f (h:tl) | h == '#' = False | otherwise = True main :: IO () main = do fileName <- getArgs contents <- readFile (head fileName) putStr $ unlines $ filter f $ lines contents
実行。
^o^ >type sample.txt hello! # remove this # don't remove this bye! ^o^ >runhaskell filterline.hs sample.txt hello! # don't remove this bye!
ファイルを1行ずつ処理するやり方を忘れててあせった。
追記:id:jmkさんからもらったアドバイスを追記しておこう。ありがとうございます。
f ('#':_) = False f _ = True
与えられた高さのピラミッドを作る
module Main where import System cjust :: Int -> String -> String cjust w s | w <= length s = s | otherwise = margin ++ s ++ margin where margin = replicate ((w - (length s)) `div` 2) ' ' pyramid :: [String] pyramid = map (flip replicate '*') [1,3..] main :: IO () main = do h <- getArgs >>= return.read.head putStr $ unlines $ map (cjust (h*2-1)) $ take h pyramid
実行。
^o^ >runhaskell pyramid.hs 4 * *** ***** ******* ^o^ >runhaskell pyramid.hs 5 * *** ***** ******* ********* ^o^ >runhaskell pyramid.hs 6 * *** ***** ******* ********* *********** ^o^ >runhaskell pyramid.hs 1 * ^o^ >runhaskell pyramid.hs 0
お,高さ0でもちゃんと動く。
proxy 対応がうまくいってない,と書いたら早速対応してくれた。ありがとうございます。
cf. d:id:takatoh:20070522:http_proxy のコメント欄
バージョンアップして,リポジトリに取り込んでもらった Pragger のプラグインを修正した。設定ファイルで proxy のホスト,ポート,ユーザ,パスワードを指定可能。hatenaapigraph の 0.1.2 が必要なので gem でインストールしましょう。
## Post data to Hatena Graph -- takatoh ## ## hatenaapigraph 0.1.2 is required. ## ## see http://d.hatena.ne.jp/takatoh/20070531/hatena_graph ## ## - module: Publish::hatena_graph ## config: ## user_id: your hatena user id ## password: your password ## graph_name: the name of graph ## proxy_host: proxy host name (optional) ## proxy_port: proxy port (optional) ## proxy_user: proxy user (optional) ## proxy_pass: proxy password (optional) begin require 'rubygems' gem 'hatenaapigraph', '>=0.1.2' rescue LoadError end require 'hatena/api/graph' def hatena_graph(config, data) value = data.first.to_f graph = Hatena::API::Graph.new(config['user_id'], config['password']) if config['proxy_host'] proxy_host = config['proxy_host'] proxy_port = config['proxy_port'] proxy_user = config['proxy_user'] proxy_pass = config['proxy_pass'] graph.proxy = ::Net::HTTP.Proxy(proxy_host, proxy_port, proxy_user, proxy_pass) end graph.post(config['graph_name'], Time.now, value) end
昨日の続きでもある。
hatenaapigraph 0.1.1 にあわせて HTTP_PROXY=proxy:8080 としたら wget が動かなくなった。Ruby の open-uri もダメ。
^o^ >echo %HTTP_PROXY% proxy:8080 ^o^ >type get_diary.rb require 'open-uri' puts open("http://d.hatena.ne.jp/takatoh/"){|f| f.read } ^o^ >ruby get_diary.rb C:/usr/ruby/lib/ruby/1.8/open-uri.rb:203:in `open_http': Non-HTTP proxy URI: pro xy:8080 (RuntimeError) from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:626:in `buffer_open' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:164:in `open_loop' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:162:in `catch' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:162:in `open_loop' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:132:in `open_uri' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:528:in `open' from C:/usr/ruby/lib/ruby/1.8/open-uri.rb:30:in `open' from get_diary.rb:3
どちらも HTTP_PROXY=http://proxy:8080/ なら問題なく使える。
「環境変数 HTTP_PROXY」でググってみたけど,”http://” を含めてるのと含めてないのと両方あるな。いったいどうしろっていうんだ。
せっかく簡潔になった Pragger の puglis::hatena_graph.rb だけど結局メソッドを再定義して対処した。”http://” がついてたら取り除く。
## Post a data to Hatena Graph ## ## require gem `hatenaapigraph' 0.1.1 or later. ## ## - module: publish::hatena_graph ## config: ## user_id: your-hatena-user-id ## password: your-password ## graph_name: the-name-of-graph begin require 'rubygems' rescue LoadError end require 'hatena/api/graph' module Hatena::API class Graph private def http_post(url, params, headers) req = ::Net::HTTP::Post.new(url.path, headers) req.form_data = params req.basic_auth url.user, url.password if url.user proxy_host, proxy_port = (ENV['HTTP_PROXY'] || '').sub(/^http:\/\//, '').split (/:/) ::Net::HTTP::Proxy(proxy_host, proxy_port.to_i).start(url.host, url.port) {|ht tp| http.request(req) } end end end def hatena_graph(config, data) value = data.first.to_f graph = Hatena::API::Graph.new(config['user_id'], config['password']) graph.post(config['graph_name'], Time.now, value) end
になってるのに,今日,気がついた。HTTP_PROXYサポートと日本語グラフ名のバグ修正なので,こないだ書いた Prager の publish::hatena_graph プラグインも簡潔になる。
## Post a data to Hatena Graph ## ## require gem `hatenaapigraph' 0.1.1 or later. ## ## - module: publish::hatena_graph ## config: ## user_id: your-hatena-user-id ## password: your-password ## graph_name: the-name-of-graph begin require 'rubygems' rescue LoadError end require 'hatena/api/graph' def hatena_graph(config, data) value = data.first.to_f graph = Hatena::API::Graph.new(config['user_id'], config['password']) graph.post(config['graph_name'], Time.now, value) end
Praggerがどうやら最初のリリースに向けて具体的に動き出したっぽい。
ちょうどいいので今まで作ったプラグインについてまとめておく。どれもPraggerと同じライセンスでOKです。
LIRS を取得するプラグイン。これでいいのか実は不安。
はてなグラフにデータをポストするプラグイン。今日のデータしかポストできない。
はてなグラフからデータをダウンロードするプラグイン。目的のグラフのデータだけを抜き出す。これは公開してなかった。
## Get Hatena Graph data ## ## - module: get_hatena_graph ## config: ## user_id: your-hatena-user-id ## password: your-password ## graph_name: the-name-of-graph begin require 'rubygems' rescue LoadError end require 'mechanize' require 'uri' require 'kconv' require 'csv' class HatenaGraph def initialize(id,password) @id = id @password = password @agent = WWW::Mechanize.new if proxy = ENV['http_proxy'] proxy = URI.parse(proxy) @agent.set_proxy(proxy.host, proxy.port) end @graph = @agent.get("http://graph.hatena.ne.jp/#{id}/") end def login login_link = @graph.links.text("ログイン".toutf8) login_page = @agent.get(login_link.href) login_form = login_page.forms.first login_form['key'] = @id login_form['password'] = @password redirect_page = @agent.submit(login_form) @graph_link = redirect_page.links.text("こちら".toutf8) @graph_page = @agent.get(@graph_link.href) end def fetch_csv @data_link = @graph_page.links.text("データ".toutf8) @data_page = @agent.get(@data_link.href) csv_link = @data_page.links.text("ダウンロード".toutf8) csv_file = @agent.get(csv_link.href) # => WWW::Mechanize::File tmpfile = Tempfile.open("hatenagraph") path = tmpfile.path csv_file.save_as(path) tmpfile.close path end end def get_hatena_graph(config, data) graph = HatenaGraph.new(config['user_id'], config['password']) graph.login csvpath = graph.fetch_csv csv = CSV.open(csvpath, "r").map{|r| r } graph_names = csv.shift i = graph_names.index(config['graph_name'].tosjis) csv.map{|r| r[i].to_f } end
設定ファイルはこんな感じ。
- module: get_hatena_graph config: user_id: takatoh password: xxxxxxxx graph_name: "読んだページ数"
小物その1,コマンドラインからデータを取得。
def argv(config,data) return ARGV.clone end
小物その2,平均。
def average(config, data) sum = data.inject(0.0){|a,b| a + b.to_f } return [ sum / data.size ] end