tag:blogger.com,1999:blog-55420644189616397412024-02-08T20:56:23.483+09:00技術的生存報告記このblogは、著者である「<a href="http://sakito.jp">sakito</a>」が技術的に生存している事を報告するために存在します<br>
タイトルを「紹介マニアどらふと版」から変更しましたsakitohttp://www.blogger.com/profile/06626498730237959658noreply@blogger.comBlogger164125tag:blogger.com,1999:blog-5542064418961639741.post-28050489597561031012016-04-08T23:01:00.001+09:002016-04-08T23:01:47.180+09:00タイトル変更<p>
タイトル変更しました。<br />
ついでに、一部bootstrapを利用してレイアウト崩れを防ぐようにしてみました。<br />
記事はまた思いついた時にでも投稿してみます。
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-32419095874795478202015-02-09T06:39:00.001+09:002015-02-10T05:56:43.569+09:00Mac OS X で porg を使って "make install"したソフトを管理する<p>
<a href="http://porg.sourceforge.net/">Porg</a>は「make install」でインストールされるファイルの記録を取り、後で削除したりするのを簡単にするためのソフトです。<br>
以前は Paco と言う名前でしたので、Paco に関する記事を見ると良いです。</p>
<p>
<a href="http://d.hatena.ne.jp/rx7/20081011/p2">"make install"したソフトウェアを管理できる超便利ツール「Paco」 - 元RX-7乗りの適当な日々</a>
</p>
<p>こういうのは MacPortsとかHomebrewとかを使うのが普通なのですが、make install も結構してしまうので使うと便利です。</p>
<h4>porgのインストール</h4>
<p>
porg の最新版をダウンロードします。この記事を記述している時点だと「0.7」です。
</p>
<div class="highlight"><pre>curl -LO http://downloads.sourceforge.net/project/porg/porg-0.7.tar.gz
</pre></div>
<p>
Mac で正常に動作させるにはパッチが必要ですのでダウンロードします。
</p>
<div class="highlight"><pre>curl -LO https://trac.macports.org/raw-attachment/ticket/46702/adapt-to-osx.patch
curl -LO https://trac.macports.org/raw-attachment/ticket/46702/patch-doubleDESTDIR.diff
</pre></div>
<p>コンパイルします。gropというGUIツールを一緒にインストールしようとしますが、わたしは使わないのでdisable しておきます。ためしたい人は gtkmm をインストールすると使えるはずです。</p>
<div class="highlight"><pre>tar xvf porg-0.7.tar.gz
<span class="nb">cd </span>porg-0.7
<span class="c"># パッチを当てます</span>
patch -p0 < ../adapt-to-osx.patch
patch -p0 < ../patch-doubleDESTDIR.diff
<span class="c"># disable-grop します</span>
./configure --disable-grop
make
sudo make install
</pre></div>
<p>
「/usr/local/bin」にインストールされるので PATH を通しておいてください。
</p>
<p>
動作確認をします。動作確認には、porg に porg 自身を登録します。
</p>
<div class="highlight"><pre>sudo make logme
porg -a
</pre></div>
<p>
「-a」で管理パッケージ一覧が表示できます。無事 porg 自身が表示できていればインストールに問題ないです。<br>
パッチを当てれば Mac でも動作します。
</p>
<h4>2015/02/09 追記</h4>
<p>どうやら上手く追加できない物が結構あるみたいなので確認中。</p>
<p>パッチを追記。</p>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-61635938601159537572015-02-07T23:15:00.001+09:002015-02-07T23:15:22.327+09:00github から https 経由の clone 時にエラーが発生する場合の対処<p>
github で git clone 等を実施した時に以下のようなエラーが発生した場合の対処。
</p>
<div class="highlight"><pre><span class="n">fatal</span><span class="o">:</span> <span class="n">unable</span> <span class="n">to</span> <span class="n">access</span> <span class="s1">'https://github.com/xxxx/yyyy'</span><span class="o">:</span> <span class="n">SSL</span> <span class="n">certificate</span> <span class="n">problem</span><span class="o">:</span> <span class="n">Invalid</span> <span class="n">certificate</span> <span class="n">chain</span>
</pre></div>
<h4>キーチェンアクセスの確認</h4>
<p>
「アプリケーション」->「ユーティリティ」->「キーチェンアクセス」を起動。
</p>
<p>
「システムルール」の中から「DigiCert High Assurance EV Root CA」を探して「有効期限」を確認します。
</p>
<p>
おそらく有効期限が切れていると思います。
</p>
<h4>証明書の更新</h4>
<p>
以下のサイトにアクセスします。<br>
<a href="https://www.digicert.com/digicert-root-certificates.htm#roots">https://www.digicert.com/digicert-root-certificates.htm#roots</a>
</p>
<p>
「DigiCert High Assurance EV Root CA」の「Download」リンク先を「右クリック」で保存してください。リンクを単純にクリックすると、ブラウザにインストールしようとしていまい、エラーが出てしまうので注意。
</p>
<p>
ダウンロードできた「crt」ファイルをダブルクリックすると、証明書が更新されます。有効期限が更新された事を確認してください。
</p>
<p>
git clone を実施して、問題ない事を確認してください。
</p>
<p>
以上です。
</p>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-45990644821482860092013-04-22T06:00:00.000+09:002013-04-22T06:00:02.951+09:00Tumblr API v2 を利用する<h4>概要</h4>
<p>TumblrのAPIを突然利用したくなったので、利用方法をメモする。</p>
<h4>OAuth Key の取得</h4>
<p>API を利用するには Twitter 等と同様 アプリケーションを登録して OAuth Keyを取得する必要がある。<br />
プリの登録は、「<a href="http://www.tumblr.com/oauth/apps">http://www.tumblr.com/oauth/apps</a>」で行なう。</p>
<p>
<img src="http://lh6.ggpht.com/-mIcWpgtmHK8/UXOCRoTkt-I/AAAAAAAAAG8/Sf4JRXJFOo4/tumblr_reg_app.png?imgmax=800" alt="Tumblr Register application" title="tumblr_reg_app.png" border="0" width="500" height="508" />
</p>
<p>「Register application」ボタンで登録。</p>
<p>
<img src="http://lh6.ggpht.com/-Uxq92VMYKqo/UXOCSPEm1gI/AAAAAAAAAHE/W-0BHk1ev4c/tumblr_reg_app_name.png?imgmax=800" alt="Tumblr reg app name" title="tumblr_reg_app_name.png" border="0" width="298" height="518" />
</p>
<p>「Application name」、「Administrative contact email」、「Default callback URL」が必須なので入力する。<br />
登録内容は後でも変更できる。callback URL はとりあえず自分のサイト等にしておけば良い。</p>
<p>登録が完了すると、「OAuth Consumer Key」、「Secret Key」が取れる。</p>
<h4>クライアントアプリケーション作成</h4>
<p>クライアントアプリケーショを作成する。<br />
Python で rauth を利用して認証と表示までしたサンプルが以下。実際に利用する場合は「OAuth Consumer Key」、「Secret Key」を自分の物に変更する。<br />
rauth は OAuth を簡単に処理する外部ライブラリでかなり便利。「pip install rauth」などであらかじめインストールしておくこと。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">webbrowser</span>
<span class="kn">from</span> <span class="nn">ConfigParser</span> <span class="kn">import</span> <span class="n">SafeConfigParser</span>
<span class="kn">from</span> <span class="nn">rauth</span> <span class="kn">import</span> <span class="n">OAuth1Service</span>
<span class="k">class</span> <span class="nc">TumblrClientTest</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> Tumblr クライアントサンプルテスト</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">test_sample</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> テスト</span>
<span class="sd"> """</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">TumblrClient</span><span class="p">()</span>
<span class="c"># sessin の取得</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get_session</span><span class="p">()</span>
<span class="c"># user/info 取得</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'user/info'</span><span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="p">[</span><span class="s">'meta'</span><span class="p">][</span><span class="s">'status'</span><span class="p">],</span> <span class="mi">200</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="p">[</span><span class="s">'meta'</span><span class="p">][</span><span class="s">'msg'</span><span class="p">],</span> <span class="s">'OK'</span><span class="p">)</span>
<span class="c"># blog/info 取得</span>
<span class="n">path</span> <span class="o">=</span> <span class="s">'blog/scipsy.tumblr.com/info?api_key={api_key}'</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">api_key</span><span class="o">=</span><span class="n">client</span><span class="o">.</span><span class="n">get_api_key</span><span class="p">()))</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="p">[</span><span class="s">'meta'</span><span class="p">][</span><span class="s">'status'</span><span class="p">],</span> <span class="mi">200</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="p">[</span><span class="s">'meta'</span><span class="p">][</span><span class="s">'msg'</span><span class="p">],</span> <span class="s">'OK'</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="p">[</span><span class="s">'response'</span><span class="p">][</span><span class="s">'blog'</span><span class="p">][</span><span class="s">'name'</span><span class="p">],</span> <span class="s">'scipsy'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TumblrClient</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> Tumblr クライアントサンプル</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">get_api_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> API key = OAuth Consumer Key</span>
<span class="sd"> """</span>
<span class="k">return</span> <span class="s">'OAuth Consumer Key'</span>
<span class="k">def</span> <span class="nf">get_consumer_secret</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> Secret Key</span>
<span class="sd"> """</span>
<span class="k">return</span> <span class="s">'Secret Key'</span>
<span class="k">def</span> <span class="nf">get_session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> session の取得</span>
<span class="sd"> """</span>
<span class="c"># 設定ファイルのパス</span>
<span class="n">config_file</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">'tumblr.cfg'</span><span class="p">))</span>
<span class="n">tumblr</span> <span class="o">=</span> <span class="n">OAuth1Service</span><span class="p">(</span>
<span class="n">name</span><span class="o">=</span><span class="s">'tumblr'</span><span class="p">,</span>
<span class="n">consumer_key</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">get_api_key</span><span class="p">(),</span>
<span class="n">consumer_secret</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">get_consumer_secret</span><span class="p">(),</span>
<span class="n">request_token_url</span><span class="o">=</span><span class="s">'https://www.tumblr.com/oauth/request_token'</span><span class="p">,</span>
<span class="n">access_token_url</span><span class="o">=</span><span class="s">'https://www.tumblr.com/oauth/access_token'</span><span class="p">,</span>
<span class="n">authorize_url</span><span class="o">=</span><span class="s">'https://www.tumblr.com/oauth/authorize'</span><span class="p">,</span>
<span class="n">base_url</span><span class="o">=</span><span class="s">'https://api.tumblr.com/v2/'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">config_file</span><span class="p">):</span>
<span class="c"># 設定ファイルが存在する場合、設定ファイル読み込み</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">SafeConfigParser</span><span class="p">()</span>
<span class="n">config</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">config_file</span><span class="p">)</span>
<span class="n">access_token</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'account'</span><span class="p">,</span> <span class="s">'access_token'</span><span class="p">)</span>
<span class="n">access_token_secret</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'account'</span><span class="p">,</span> <span class="s">'access_token_secret'</span><span class="p">)</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">tumblr</span><span class="o">.</span><span class="n">get_session</span><span class="p">((</span><span class="n">access_token</span><span class="p">,</span> <span class="n">access_token_secret</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="c"># 設定ファイルが存在しない場合、初回認証</span>
<span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth</span><span class="p">(</span><span class="n">tumblr</span><span class="p">)</span>
<span class="c"># 設定ファイル出力</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">SafeConfigParser</span><span class="p">()</span>
<span class="n">sec_name</span> <span class="o">=</span> <span class="s">'account'</span>
<span class="n">config</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="n">sec_name</span><span class="p">)</span>
<span class="n">config</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">sec_name</span><span class="p">,</span> <span class="s">'access_token'</span><span class="p">,</span> <span class="n">session</span><span class="o">.</span><span class="n">access_token</span><span class="p">)</span>
<span class="n">config</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">sec_name</span><span class="p">,</span> <span class="s">'access_token_secret'</span><span class="p">,</span>
<span class="n">session</span><span class="o">.</span><span class="n">access_token_secret</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">config_file</span><span class="p">,</span> <span class="s">'wb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">configfile</span><span class="p">:</span>
<span class="n">config</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">configfile</span><span class="p">)</span>
<span class="k">return</span> <span class="n">session</span>
<span class="k">def</span> <span class="nf">auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tumblr</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> ブラウザでの初回認証</span>
<span class="sd"> """</span>
<span class="n">request_token</span><span class="p">,</span> <span class="n">request_token_secret</span> <span class="o">=</span> <span class="n">tumblr</span><span class="o">.</span><span class="n">get_request_token</span><span class="p">()</span>
<span class="n">authorize_url</span> <span class="o">=</span> <span class="n">tumblr</span><span class="o">.</span><span class="n">get_authorize_url</span><span class="p">(</span><span class="n">request_token</span><span class="p">)</span>
<span class="k">print</span> <span class="s">'表示されたURLをブラウザで開きます: '</span> <span class="o">+</span> <span class="n">authorize_url</span>
<span class="n">webbrowser</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">authorize_url</span><span class="p">)</span>
<span class="n">authed_url</span> <span class="o">=</span> <span class="nb">raw_input</span><span class="p">(</span><span class="s">'ブラウザアドレスバーのURLをペースとしてください: '</span><span class="p">)</span>
<span class="n">verifier</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s">r'\oauth_verifier=([^#]*)'</span><span class="p">,</span> <span class="n">authed_url</span><span class="p">)</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># session 取得</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">tumblr</span><span class="o">.</span><span class="n">get_auth_session</span><span class="p">(</span>
<span class="n">request_token</span><span class="p">,</span>
<span class="n">request_token_secret</span><span class="p">,</span>
<span class="n">method</span><span class="o">=</span><span class="s">'POST'</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s">'oauth_verifier'</span><span class="p">:</span> <span class="n">verifier</span><span class="p">})</span>
<span class="k">return</span> <span class="n">session</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>
<p>
正しく認証されていると、設定画面の「Apps」に登録したアプリが表示される。
</p>
<p>
<img src="http://lh6.ggpht.com/-iEsl8JaMfXw/UXOCSvH44CI/AAAAAAAAAHM/JD8A3hZNvvg/tumblr_apps.png?imgmax=800" alt="Tumblr apps" title="tumblr_apps.png" border="0" width="513" height="316" />
</p>
<h4>API のドキュメント</h4>
<p>公式 APIドキュメントが「<a href="http://www.tumblr.com/docs/en/api/v2">http://www.tumblr.com/docs/en/api/v2</a>」に存在するので、あとは必要な物を利用するだけ。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-83469234703270243472013-04-02T06:00:00.000+09:002013-04-02T06:00:00.580+09:00matplotlib 1.2.1 コンパイル時に Tk 8.5 must be compiled with tcl.h from Tcl 8.5 のエラー<h4>現象</h4>
<p>「Tk 8.5 must be compiled with tcl.h from Tcl 8.5」のエラーは Tcl 8.4 と 8.5 が同居している場合に発生する。<br />
Mac OS X の場合、MacPorts や Homebrew、ActiveTck なんかをインストールしている環境で発生しやすい。<br />
Linux 系の場合、パスの設定が変になっている可能性がある。</p>
<h4>対処</h4>
<p>Mac OS X の場合は、tkagg を利用しないのが一番簡単だと思う。<br />
setup.cfg に以下のように設定してコンパイルすれば良い。</p>
<div class="highlight"><pre><span class="p">[</span><span class="n">gui_support</span><span class="p">]</span>
<span class="n">tkagg</span> <span class="o">=</span> <span class="bp">False</span>
</pre></div>
<p>本来は根源的に解決すべきだが、とりあえずはこれでも大体の場合は困らない。<br />
ただ tkagg を必要とする場合は、別途考える必要があるかも。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-28146637209911128952012-12-05T06:00:00.000+09:002012-12-05T06:00:05.535+09:00Riak コンパイルメモ<h4>概要</h4>
<p>Erlang で実装されたNoSQL系のデータベース「<a href="http://basho.com/products/riak-overview/">Riak</a>」の先端をコンパイルする手順メモ。</p>
<h4>手順</h4>
<p>コンパイルする場合 Erlang と Git コマンドが必須なのでパスに存在するか確認しておく。</p>
<p>Riak はビルドに「<a href="https://github.com/basho/rebar">rebar</a>」を利用している。最新である必要は特にないが、これもコンパイルしておく。</p>
<div class="highlight"><pre>git cline git://github.com/basho/rebar.git
<span class="nb">cd </span>rebar
./bootstrap
</pre></div>
<p>Mac OS Xでコンパイルしているが、環境変数に UNICODE が含まれていると認識されコンパイルエラーになった。<br />
「<a href="https://github.com/l4u/rebar-1/commit/61c353dcfdafb87107cc5472709d229c26a8cb6c">Support environment vars with unicode characters · 61c353d · l4u/rebar-1 · GitHub</a>」のパッチをあてたら通過した。</p>
<p>Riak 本体をコンパイルする。rebar のコピーを忘れないようにする。</p>
<div class="highlight"><pre>git clone git://github.com/basho/riak.git
<span class="nb">cd </span>riak
cp /path/to/rebar .
make rel
</pre></div>
<p>関連ライブラリが Git で clone されてコンパイルされるので、環境によっては時間かかる。<br />
途中でコンパイルエラーにたまになったので、rebarのバイナリコピーしてから再度 make するとちゃんと継続してコンパイルしてくれた。<br />
「rel」ディレクトリの下にコンパイルされた。</p>
<p>使い方は確認中なので、また後で書く。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-30468211013705294922012-12-04T06:00:00.000+09:002012-12-04T06:00:00.356+09:00XML ファイルから PO ファイル を作成する<h4>概要</h4>
<p>XML ファイルを翻訳することがそれなりの頻度である。翻訳するなら PO ファイルを生成するのが便利。<br />
XML から PO ファイルを生成するには「xml2po」か、「<a href="http://itstool.org/">ITS Tool</a>」を使う。両方ともGnomeのドキュメント国際化でも使われている Python で作成されたツール。<br />
両方とも XML から PO を生成したり、PO から XML に戻したりできる。<br />
ITS Tool の方が新しい。</p>
<h4>xml2po</h4>
<div class="highlight"><pre>sudo port install gnome-doc-utils
xml2po --version
</pre></div>
<p>POファイルの作成と、XMLへの戻しは以下のようにする。</p>
<div class="highlight"><pre>xml2po -o sample.pot sample.xml
cp sample.pot ja.po
mkdir ja
xml2po -p ja.po sample.xml > ja/sample.xml
</pre></div>
<h4>ITS Tool</h4>
<div class="highlight"><pre><span class="c"># 依存ライブラリインストール</span>
pip install ftp://xmlsoft.org/libxml2/python/libxml2-python-2.6.21.tar.gz
<span class="c"># ダウンロード</span>
curl -O http://files.itstool.org/itstool/itstool-1.2.0.tar.bz2
tar xvfz itstool-1.2.0.tar.bz2
<span class="nb">cd </span>itstool-1.2.0
./configure
sudo make install
<span class="c"># バージョン確認</span>
itstool --version
</pre></div>
<p>POファイルの作成と、XMLへの戻しは以下のようにする。</p>
<div class="highlight"><pre>itstool sample.xml -o sample.pot
cp sample.pot ja.po
msgfmt -o ja.mo ja.po
mkdir ja
itstool -m ja.mo -o ja/ sample.xml
</pre></div>
<h4>まとめ</h4>
<p>翻訳対象の XML にもよるだろうが、自分は xml2po の方を普段は利用している。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-77059090644282374052012-12-03T06:00:00.000+09:002012-12-03T06:00:02.274+09:00Erlang を Emacs でコーディングするための設定<h4>概要</h4>
<p>プログラミング言語<a href="http://www.erlang.org/">Erlang</a>を Emacs でコーディングするための設定。</p>
<h4>Erlangインストール</h4>
<p>Mac の場合は dmg、MacPorts、Homebrew でインストールする方法がある。</p>
<p>dmgの場合</p>
<p>あまり知られていないみたいだが、ちゃんと dmg によるバイナリが配布されている。<br />
以下からダウンロード可能。<br />
<a href="https://www.erlang-solutions.com/downloads/download-erlang-otp">https://www.erlang-solutions.com/downloads/download-erlang-otp</a><br />
アクセスするとブラウザの設定で自動でOperating Systemが選択されるはずだが、Operating Systemが適切でない場合は選択しなおせば dmg がダウンロードできる。<br />
バイナリは通常は 64bit を選択すれば良い。
</p>
<p>MacPortsの場合</p>
<div class="highlight"><pre>sudo port install erlang
</pre></div>
<p>Homebrewの場合</p>
<div class="highlight"><pre>brew install erlang
</pre></div>
<h4>動作確認</h4>
<p>ターミナルから動作するか確認する。「erl」コマンドで Erlang Shell が起動する。</p>
<div class="highlight"><pre>% erl
1 > 2 + 4.
6
2 > halt().
</pre></div>
<p>「.」を忘れないように。「halt()」で終了する。</p>
<h4>Emacsの設定</h4>
<p>erlang-modeとdistelを設定する。<br />
erlang-mode は Erlang と同時にインストールされる。</p>
<p>MacPorts だと「/opt/local/lib/erlang/lib/tools-*/emacs/」に存在する。</p>
<p><a href="https://github.com/jixiuf/distel">distel</a>は補完とか、その他いろいろ便利なので設定している。</p>
<div class="highlight"><pre>git clone git://github.com/jixiuf/distel.git
cd distel
make
</pre></div>
<p>init.el の設定は以下。path 関連の設定が必要だけど、略。</p>
<div class="highlight"><pre><span class="p">(</span><span class="k">setq</span> <span class="nv">erlang-root-dir</span> <span class="s">"/opt/local/lib/erlang"</span><span class="p">)</span>
<span class="p">(</span><span class="nb">require</span> <span class="ss">'erlang-start</span><span class="p">)</span>
<span class="p">(</span><span class="nb">require</span> <span class="ss">'erlang-flymake</span><span class="p">)</span>
<span class="p">(</span><span class="nb">require</span> <span class="ss">'distel</span><span class="p">)</span>
<span class="p">(</span><span class="nv">distel-setup</span><span class="p">)</span>
</pre></div>
<p>Erlang でのプログラム経験がかなり少ないので、ほとんど設定してない。</p>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-41931697342918792192012-11-19T06:00:00.000+09:002012-11-19T06:00:03.987+09:00Cassandra 1.1 簡易メモ<h4>概要</h4>
<p>「<a href="http://cassandra.apache.org/">Apache Cassandra</a>」の 1.1.6 をとりあえず試すためのメモ。<br />
ネット上の記事が結構古い物しかない印象なので、公開しておく。<br />
触りだけで、深い所までは書いてない。</p>
<h4>設置から起動</h4>
<div class="highlight"><pre>curl -O http://ftp.riken.jp/net/apache/cassandra/1.1.6/apache-cassandra-1.1.6-bin.tar.gz
tar xvf apache-cassandra-1.1.6-bin.tar.gz
<span class="nb">cd </span>apache-cassandra-1.1.6
<span class="c"># conf の中で利用しているディレクトリを作成</span>
sudo mkdir -p /var/log/cassandra
sudo chown -R <span class="sb">`</span>whoami<span class="sb">`</span> /var/log/cassandra
sudo mkdir -p /var/lib/cassandra
sudo chown -R <span class="sb">`</span>whoami<span class="sb">`</span> /var/lib/cassandra
<span class="c"># 起動</span>
bin/cassandra -f
</pre></div>
<p>
デフォルトでは Messaging Service が 7000 ポート、thrift server が 9160 ポートを利用する。
</p>
<h4>アクセス</h4>
<p>
標準クライアントは依然から存在する「bin/cassandra-cli」か、新しい「bin/cqlsh」を利用する。<br />
ネットや README だと cassandra-cli を利用しているが、cqlsh の方が使いやすいのでそちらを利用する。
</p>
<div class="highlight"><pre>bin/cqlsh localhost
</pre></div>
<h4>keyspaceの作成</h4>
<p>最初に RDB のデータベース相当 である keyspace を作成する。</p>
<div class="highlight"><pre><span class="k">CREATE</span> <span class="n">KEYSPACE</span> <span class="n">Keyspace1</span>
<span class="k">WITH</span> <span class="n">strategy_class</span> <span class="o">=</span> <span class="s1">'SimpleStrategy'</span>
<span class="k">AND</span> <span class="n">strategy_options</span><span class="p">:</span><span class="n">replication_factor</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</pre></div>
<p>keyspace に移動</p>
<div class="highlight"><pre>cqlsh> use Keyspace1;
cqlsh:Keyspace1>
</pre></div>
<h4>column family の作成</h4>
<p>RDB のテーブル相当である column family を作成する。cqlshを利用すると、「CREATE COLUMNFAMILY」、「CREATE TABLE」のいずれでも作成できる。<br />
「CREATE TABLE」を利用すると 従来の RDB 的に column も同時に作成できる。とりあえずこちらを利用したサンプル。<br />
Snappy による圧縮を指定して作成する場合は以下のようにする。</p>
<div class="highlight"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">Users</span> <span class="p">(</span>
<span class="n">user_id</span> <span class="nb">int</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
<span class="n">user_name</span> <span class="nb">varchar</span><span class="p">,</span>
<span class="n">age</span> <span class="nb">int</span>
<span class="p">)</span>
<span class="k">WITH</span> <span class="n">comparator</span><span class="o">=</span><span class="n">LongType</span>
<span class="k">AND</span> <span class="n">compression_parameters</span><span class="p">:</span><span class="n">sstable_compression</span><span class="o">=</span><span class="s1">'SnappyCompressor'</span>
<span class="k">AND</span> <span class="n">compression_parameters</span><span class="p">:</span><span class="n">chunk_length_kb</span><span class="o">=</span><span class="mi">128</span><span class="p">;</span>
</pre></div>
<p>確認は「DESCRIBE」コマンド。</p>
<div class="highlight"><pre><span class="k">DESCRIBE</span> <span class="n">KEYSPACE</span> <span class="n">Keyspace1</span>
<span class="k">DESCRIBE</span> <span class="n">COLUMNFAMILIE</span>
<span class="k">DESCRIBE</span> <span class="n">COLUMNFAMILY</span> <span class="n">Users</span>
</pre></div>
<h4>データ挿入</h4>
<p>データを挿入してみる。</p>
<div class="highlight"><pre><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">Users</span><span class="p">;</span>
<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">Users</span> <span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">user_name</span><span class="p">,</span> <span class="n">age</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">'John Smith'</span><span class="p">,</span> <span class="mi">42</span><span class="p">);</span>
<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">Users</span> <span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">user_name</span><span class="p">,</span> <span class="n">age</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">'日本語 挿入'</span><span class="p">,</span> <span class="mi">33</span><span class="p">);</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">Users</span><span class="p">;</span>
</pre></div>
<p>INSERT は UPDATE と同じ動作をするので、prymary key が重複するデータを挿入すると上書きする。</p>
<h4>データ参照</h4>
<p>SELECT文を発行する。<br />
まず count で行数を取得してみる。古いバージョンでは count は Row 中の column 数を表示している時もあったが、現在は Row の数を返すようになっている。</p>
<div class="highlight"><pre><span class="k">select</span> <span class="k">count</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">from</span> <span class="n">Users</span><span class="p">;</span>
</pre></div>
<p>普通に SELECT文が発行できる。暗黙に「limit = 10000」が付与される。</p>
<div class="highlight"><pre><span class="k">select</span> <span class="n">user_name</span><span class="p">,</span> <span class="n">age</span> <span class="k">from</span> <span class="n">Users</span> <span class="k">where</span> <span class="n">user_id</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">;</span>
</pre></div>
<h4>データ削除</h4>
<p>DELETE文を発行する。</p>
<div class="highlight"><pre><span class="k">delete</span> <span class="k">from</span> <span class="n">Users</span> <span class="k">where</span> <span class="n">user_id</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</pre></div>
<p>「PRIMARY KEY」を設定していると、「PRIMARY KEY」以外の値が消えるだけで「PRIMARY KEY」の値が残るので、論理削除とかにした方が良い場合もある。</p>
<h4>ソート</h4>
<p>ORDER BY したい場合は、PRIMARY KEY を複合キーで作る必要があるので、PRIMARY KEY を複合キーで作成できる場合にしか使えない。</p>
<h4>参考サイト</h4>
<ul>
<li><a href="http://www.datastax.com/docs/1.1/references/cql/index">CQL 3 Language Reference | DataStax Cassandra 1.1 Documentation</a></li>
<li><a href="http://kaworu.jpn.org/kaworu/2012-05-27-1.php">Cassandra CQLとは</a></li>
</ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-50641181762572638962012-11-13T06:00:00.001+09:002012-11-13T06:00:00.995+09:00Emacs で Python の補完を強化する jedi を設定してみた<h4>概要</h4>
<p>Emacs の Python 補完はいろいろあるが、どれもいまいち遅い。「<a href="https://github.com/tkf/emacs-jedi">emacs-jedi</a>」は結構高速に補完してくれるみたいなので、設定してみた。</p>
<h4>設定</h4>
<p>Python のライブラリをインストール</p>
<div class="highlight"><pre>pip install epc
pip install jedi
</pre></div>
<p>Emacs のライブラリを取得。</p>
<div class="highlight"><pre>git clone git://github.com/kiwanami/emacs-deferred.git
git clone git://github.com/kiwanami/emacs-ctable.git
git clone git://github.com/kiwanami/emacs-epc.git
git clone git://github.com/tkf/emacs-jedi.git
</pre></div>
<p>init.el の設定</p>
<div class="highlight"><pre><span class="p">(</span><span class="nb">require</span> <span class="ss">'jedi</span><span class="p">)</span>
<span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'python-mode-hook</span> <span class="ss">'jedi:ac-setup</span><span class="p">)</span>
</pre></div>
<p>これで auto-complete を利用して補完が可能。eldoc が有効になっていると、関数の引数説明も表示される。<br />
結構高速に動作してくれるのでしばらく利用してみる。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-59633955443645843612012-11-13T06:00:00.000+09:002012-11-13T06:00:01.720+09:00Emacs で似ている文字列を一度に選択して一括編集可能な mark-multiple.el の導入<h4>概要</h4>
<p>簡単に複数の同じ様な文字列を選択して、一括編集可能な「<a href="https://github.com/magnars/mark-multiple.el">mark-multiple.el</a>」を導入してみた。<br />
機能に関しては、「<a href="http://emacsrocks.com/">説明動画</a>」参照。</p>
<h4>設定</h4>
<div class="highlight"><pre>git clone git://github.com/magnars/mark-multiple.el.git
</pre></div>
<p>init.el には以下を設定。</p>
<div class="highlight"><pre><span class="p">(</span><span class="nb">require</span> <span class="ss">'mark-more-like-this</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C-<"</span><span class="p">)</span> <span class="ss">'mark-previous-like-this</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C->"</span><span class="p">)</span> <span class="ss">'mark-next-like-this</span><span class="p">)</span>
</pre></div>
<p>「C-<」で前方一致選択。「C->」で後方一致選択。</p>
<p>矩形選択の機能もあるので設定しておくと便利。</p>
<div class="highlight"><pre><span class="p">(</span><span class="nb">require</span> <span class="ss">'inline-string-rectangle</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C-x r t"</span><span class="p">)</span> <span class="ss">'inline-string-rectangle</span><span class="p">)</span>
</pre></div>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-38475089835428824252012-11-12T06:00:00.000+09:002012-11-12T06:00:03.754+09:00Emacs の region 関連機能をカスタマイズできる expand-region.el の導入<h4>概要</h4>
<p>Emacs で範囲選択をいろいろカスタマイズできる、「<a href="https://github.com/magnars/expand-region.el">expand-region.el</a>」を導入してみた。<br />
機能に関しては文章読むより、「<a href="http://emacsrocks.com/e09.html">解説動画</a>」を見た方が良い。</p>
<h4>設定</h4>
<p>比較的変更が頻繁にはいっているので、git でソースを clone する方がよさそう。</p>
<div class="highlight"><pre>git clone git://github.com/magnars/expand-region.el.git
</pre></div>
<p>init.el への設定は以下。</p>
<div class="highlight"><pre><span class="c1">;; 選択ができるようにしておく</span>
<span class="p">(</span><span class="nv">transient-mark-mode</span> <span class="no">t</span><span class="p">)</span>
<span class="p">(</span><span class="nb">require</span> <span class="ss">'expand-region</span><span class="p">)</span>
<span class="c1">;; リージョンを広げる</span>
<span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C-@"</span><span class="p">)</span> <span class="ss">'er/expand-region</span><span class="p">)</span>
<span class="c1">;; リージョンを狭める</span>
<span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C-M-@"</span><span class="p">)</span> <span class="ss">'er/contract-region</span><span class="p">)</span>
</pre></div>
<p>「C-@」で選択範囲を広げる。「C-M-@」で選択範囲を狭める。<br />
その他選択中に「C-Shift-p」で選択範囲の上移動、「C-Shift-n」で選択範囲の下移動、「C-Shift-x」で選択範囲の先頭、末尾移動が可能。</p>
<p>動作をカスタマイズしたい場合は、言語ごとの「-expansions.el」のファイルが沢山はいっているので、参考にすればとりあえず作成できる。</p>
<h4>参考サイト</h4>
<ul>
<li><a href="http://d.hatena.ne.jp/syohex/20120117/1326814127">expand-region.elの紹介 - Life is very short</a></li>
</ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-45795863076328944342012-11-07T06:00:00.000+09:002012-11-07T06:00:01.008+09:00Python の pip コマンドでライブラリの更新状況を確認する<h4>概要</h4>
<p>Python の pip コマンド最新バージョン 1.2.1 では、ライブラリの更新状況が確認できない。<br />
確認する方法をメモする。</p>
<h4>コマンドの設定</h4>
<p>pip コマンドは「site-packages/pip/commands/」以下にコマンドが存在し、このディレクトリにコマンドプログラムを配置することで、様々な拡張が可能。</p>
<p>listコマンドを追加する「<a href="https://github.com/rafaelcaricio/pip/blob/list_command/pip/commands/list.py">list.py</a>」が公開されているので、ダウンロードして、配置する。<br />
利用可能か確認したり、利用方法を確認するには、以下のようにする。</p>
<div class="highlight"><pre>pip list --help
</pre></div>
<p>ライブラリの更新状況を確認する場合は以下。</p>
<div class="highlight"><pre>pip list -o
</pre></div>
<p>インストールしているライブラリの量にもよるが、結構時間がかかるので注意。</p>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-5358806116172616362012-11-06T06:00:00.000+09:002012-11-06T06:00:03.645+09:00アスキーアートロゴを作成してみる<h4>概要</h4>
<p>現在「<a href="https://bitbucket.org/sakito/tweepy/overview">tweepy のAPI 1.1 対応フォーク</a>」を作成している。<br />
変な所が無いか知人に見てもらった時、いくつかの指摘の中で、READMEファイルのアスキーアートロゴに関して質問があった。<br />
そこで、このようなアスキーアートロゴの作成方法に関してメモしておく。</p>
<h4>bannerコマンド</h4>
<p>Mac OS Xで標準的に利用できるコマンドだと「banner」が存在する。「-w」オプションで幅を指定する。</p>
<div class="highlight"><pre>banner -w 30 Hello
</pre></div>
<p>「banner」コマンドは自由度がほとんど無いので、あまり便利ではない。</p>
<h4>FIGlet</h4>
<p>「<a href="http://www.figlet.org/">FIGlet</a>」はこの分野でかなり利用されていると思われる。MacPorts や Homebrew で簡単にインストールできる。</p>
<div class="highlight"><pre>sudo port install figlet
brew install figlet
</pre></div>
<p>使い方は簡単。</p>
<div class="highlight"><pre>figlet Hello
</pre></div>
<p>フォントの変更も可能なので、参考サイト参照。</p>
<p>FIGletのPython実装「<a href="http://pypi.python.org/pypi/pyfiglet/">pyfiglet</a>」が存在する。</p>
<div class="highlight"><pre>pip install pyfiglet
</pre></div>
<p>pyfigletはモジューで提供されて、コマンドがインストールされない。<br />
以下のようにするとコマンドでも利用できるが、普通は import して利用する物だと思われる。</p>
<div class="highlight"><pre>/path/to/pyfiglet/__init__.py <span class="s2">"Hello"</span>
</pre></div>
<h4>TOIlet</h4>
<p>色付きでアスキーアートロゴが生成できる。名前やサイトデザインが結構酷いが、品質に問題はないようだ。<br />
これも MacPorts や Homebrew で簡単にインストールできる。</p>
<div class="highlight"><pre>sudo port install TOIlet
brew install TOIlet
</pre></div>
<p>使い方は FIGlet とほとんど同じで、色を付けるパターンが存在している。</p>
<h4>参考サイト</h4>
<p>以下のサイトが詳しい。</p>
<ul>
<li><a href="http://blog.azumakuniyuki.org/2011/05/figlet.html">/var/log/azumakuniyuki: サーバ管理に役立つ(かもしれない)FIGletというツール</a></li>
<li><a href="http://99blues.dyndns.org/blog/2011/01/ascii_art_logo/">アスキーアートなロゴを作る « Stop Making Sense</a></li>
</ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-8812891472459477902012-11-05T06:00:00.000+09:002012-11-05T06:00:01.628+09:00pyobjc 2.4 のインストール<h4>概要</h4>
<p>Python の Objective-C ブリッジライブラリ「<a href="http://pypi.python.org/pypi/pyobjc/">pyobjc</a>」の 2.4 が 2012/11/01 にリリースされたのでインストールメモ。</p>
<h4>インストール</h4>
<p>以下は pip でのインストール手順。core を先にインストールしないと依存性が解消されないので注意。</p>
<div class="highlight"><pre>pip install -U pyobjc-core
pip install -U pyobjc
</pre></div>
<h4>ドキュメント</h4>
<p>各種ドキュメントは以下にある。</p>
<ul>
<li><a href="http://pyobjc.sourceforge.net/documentation/index.html">PyObjC - Documentation</a></li>
</ul>
<h4>サンプルソース</h4>
<p>pip でインストールするとサンプルがインストールされないので、以下のURLから取得する。</p>
<ul>
<li><a href="http://svn.red-bean.com/pyobjc/trunk/pyobjc/">http://svn.red-bean.com/pyobjc/trunk/pyobjc/</a></li>
</ul>
<p>サンプルの内容は Mac での Objective-C の知識が無いと意図が理解はできないと思われる。<br />
Python から Objective-C の API が簡単に利用できるというのが便利。</p>Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-5542064418961639741.post-65174392434464012412012-11-01T06:00:00.000+09:002012-11-01T06:00:04.534+09:00Python モジュールバージョン番号フォマットに関してのメモ<h4>概要</h4>
<p>Python モジュールを開発する際のバージョン番号のフォーマットに関してのメモ。</p>
<h4>ドキュメント</h4>
<p>PEPが存在する。</p>
<ul>
<li><a href="http://www.python.org/dev/peps/pep-0386/">PEP 386 -- Changing the version comparison module in Distutils</a></li>
<li><a href="http://www.python.org/dev/peps/pep-0396/">PEP 396 -- Module Version Numbers</a></li>
</ul>
<h4>形式</h4>
<p>形式は以下。</p>
<div class="highlight"><pre>N.N[.N]+[{a|b|c|rc}N[.N]+][.postN][.devN]
</pre></div>
<ul>
<li>major</li>
<li>minor</li>
<li>micro</li>
<li>releaselevel</li>
<ul>
<li>dev</li>
<li>alpha</li>
<li>beta</li>
<li>candidate</li>
<li>final</li>
</ul>
<li>serial</li>
</ul>
<h4>バージョン番号表示</h4>
<p>setup.py でバージョン番号が表示できるように作成する。</p>
<div class="highlight"><pre>python setup.py --version
</pre></div>
<h4>関連プログラム</h4>
<ul>
<li><a href="https://github.com/django/django/blob/master/django/utils/version.py">django/django/utils/version.py at master · django/django · GitHub</a></li>
</ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-38310929451142129372012-10-31T06:00:00.000+09:002012-10-31T06:00:00.450+09:00とりあえず10月も毎日更新してみた<p>ほぼ前日の予約投稿だけれども、10月も毎日更新してみた。<br />
やはり多少の時間がかかるのと、記事の内容が薄くなったりしてしまう。<br />
11月は、更新毎日はやめる事にして、気が向いた時に更新してみる。<br />
更新に利用していた時間を開発に回す予定。
</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-75749912845861416802012-10-30T06:00:00.000+09:002012-10-30T06:00:00.146+09:00Twitter 関連のライブラリを API 1.1 に対応させるのは結構大変<p>
Python から Twitter API を扱うライブラリに「<a href="https://github.com/tweepy/tweepy">tweepy</a>」があるが、これは API 1.1 に対応していない。<br />
そこで、API 1.1 の調査を兼ねていろいろ変更してみている「<a href="https://bitbucket.org/sakito/tweepy/changesets">sakito / tweepy — Bitbucket</a>」。
</p>
<p>単純に endpoint を 1.1 にするだけでも大丈夫そうな感じがするが、細かい所まで対応しようとするとかなり大変。<br />
使う機能以外を気にすると時間がかかりすぎる気がするので主要な機能だけ、徐々に対応してみようと思う。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-39628600838671132592012-10-29T06:00:00.000+09:002012-10-29T06:00:02.749+09:00Python の in 演算子<h4>概要</h4>
<p>Python の in 演算子に関して詳細に記述してある「<a href="http://kracekumar.com/post/22512660850/python-in-operator-use-cases">python `in` operator use cases</a>」という記事を見つけた。<br />
日本語を使うとどうなるかとりあえず試してみた。</p>
<h4>ソース</h4>
<p>いつも通り unittest で記述した。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">TestIn</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_list</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> list</span>
<span class="sd"> """</span>
<span class="n">lst</span> <span class="o">=</span> <span class="p">[</span><span class="s">'あ'</span><span class="p">,</span> <span class="s">'い'</span><span class="p">,</span> <span class="s">'う'</span><span class="p">,</span> <span class="s">'え'</span><span class="p">,</span> <span class="s">'お'</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'あ'</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="s">'か'</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_nested_list</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> nested list</span>
<span class="sd"> """</span>
<span class="n">lst</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span><span class="s">'あ'</span><span class="p">,</span> <span class="s">'い'</span><span class="p">,</span> <span class="s">'う'</span><span class="p">,</span> <span class="s">'え'</span><span class="p">,</span> <span class="s">'お'</span><span class="p">],</span>
<span class="p">[</span><span class="s">'さ'</span><span class="p">,</span> <span class="s">'し'</span><span class="p">,</span> <span class="s">'す'</span><span class="p">,</span> <span class="s">'せ'</span><span class="p">,</span> <span class="s">'そ'</span><span class="p">],</span>
<span class="p">[],</span>
<span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="s">'あ'</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">([</span><span class="s">'あ'</span><span class="p">,</span> <span class="s">'い'</span><span class="p">,</span> <span class="s">'う'</span><span class="p">,</span> <span class="s">'え'</span><span class="p">,</span> <span class="s">'お'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">([]</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> dict</span>
<span class="sd"> """</span>
<span class="n">dct</span> <span class="o">=</span> <span class="p">{</span><span class="s">'名前'</span><span class="p">:</span> <span class="s">'サンプル'</span><span class="p">,</span> <span class="s">'国'</span><span class="p">:</span> <span class="s">'日本'</span><span class="p">,</span> <span class="s">'OS'</span><span class="p">:</span> <span class="s">'Mac'</span><span class="p">,</span>
<span class="s">'言語'</span><span class="p">:</span> <span class="p">{</span><span class="s">'web'</span><span class="p">:</span> <span class="s">'python'</span><span class="p">}}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'名前'</span> <span class="ow">in</span> <span class="n">dct</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="s">'web'</span> <span class="ow">in</span> <span class="n">dct</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_dict_class</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> dict class</span>
<span class="sd"> """</span>
<span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
<span class="k">pass</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">Person</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">({},</span> <span class="n">p</span><span class="p">)</span>
<span class="n">p</span><span class="p">[</span><span class="s">'name'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'名前'</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'name'</span> <span class="ow">in</span> <span class="n">p</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_set</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> set</span>
<span class="sd"> """</span>
<span class="n">stlst</span> <span class="o">=</span> <span class="p">{</span><span class="s">'foo'</span><span class="p">,</span> <span class="s">'bar'</span><span class="p">,</span> <span class="s">'foo'</span><span class="p">}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="s">'foo'</span><span class="p">,</span> <span class="s">'bar'</span><span class="p">]),</span> <span class="n">stlst</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'foo'</span> <span class="ow">in</span> <span class="n">stlst</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_generator</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> generator</span>
<span class="sd"> """</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">test_string</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> string</span>
<span class="sd"> """</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s">'Python はシンプルで強力な言語です'</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'Python'</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s">'強力'</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">msg</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">'Python'</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">25</span><span class="p">,</span> <span class="n">msg</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">'強力'</span><span class="p">))</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>
<h4>まとめ</h4>
<p>当然のように日本語でも特に問題はない。in はそれほど複雑ではないが、いろいろと応用が効いて便利。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-26294138641181506282012-10-28T06:00:00.000+09:002012-10-28T06:00:01.327+09:00多言語対応テンプレート言語 mustache を試してみた<h4>概要</h4>
<p>「<a href="http://mustache.github.com/">{{ mustache }}</a>」は多言語対応のテンプレート言語。各種エディタの plugin も提供されていて便利そうなので、試してみた。</p>
<h4>ドキュメント</h4>
<p>文法は「<a href="http://mustache.github.com/mustache.5.html">mustache</a>」を参照。</p>
<h4>Python で試してみる</h4>
<p>とりあえずPython で試してみる。「<a href="https://github.com/defunkt/pystache">Pystache</a>」を使う。</p>
<div class="highlight"><pre>pip install Pystache
</pre></div>
<p>「pystache」コマンドがインストールされるので、簡単なサンプルを試してみる。</p>
<div class="highlight"><pre>pystache <span class="s1">'Hello {{name}}'</span> <span class="s1">'{"name": "World"}'</span>
</pre></div>
<p>普通はテンプレートファイルを作成する。以下のような内容で「sample.txt」として作成。</p>
<div class="highlight"><pre><span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span>こんにちは {{name}}<span class="nt"></title></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
サンプル
{{#lists}}
<span class="nt"><b></span>{{name}}<span class="nt"></b></span>
{{/lists}}
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
<p>これを利用するソースは以下。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">from</span> <span class="nn">pystache.loader</span> <span class="kn">import</span> <span class="n">Loader</span>
<span class="kn">from</span> <span class="nn">pystache</span> <span class="kn">import</span> <span class="n">Renderer</span>
<span class="k">class</span> <span class="nc">TestPystache</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_file</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">DATA_DIR</span> <span class="o">=</span> <span class="s">'./data'</span>
<span class="n">loader</span> <span class="o">=</span> <span class="n">Loader</span><span class="p">(</span><span class="n">search_dirs</span><span class="o">=</span><span class="p">[</span><span class="n">DATA_DIR</span><span class="p">,</span> <span class="p">],</span>
<span class="n">file_encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">,</span>
<span class="n">extension</span><span class="o">=</span><span class="s">'txt'</span><span class="p">)</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_name</span><span class="p">(</span><span class="s">'sample'</span><span class="p">)</span>
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s">'name'</span><span class="p">:</span> <span class="s">'World'</span><span class="p">,</span>
<span class="s">'lists'</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span><span class="s">'name'</span><span class="p">:</span> <span class="s">'a'</span><span class="p">},</span>
<span class="p">{</span><span class="s">'name'</span><span class="p">:</span> <span class="s">'b'</span><span class="p">},</span>
<span class="p">{</span><span class="s">'name'</span><span class="p">:</span> <span class="s">'c'</span><span class="p">},</span>
<span class="p">],</span>
<span class="p">}</span>
<span class="n">renderer</span> <span class="o">=</span> <span class="n">Renderer</span><span class="p">()</span>
<span class="n">actual</span> <span class="o">=</span> <span class="n">renderer</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s">'<html></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'<head></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'<title>こんにちは World</title></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'</head></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'<body></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'サンプル</span><span class="se">\n</span><span class="s">'</span>
<span class="s">' <b>a</b></span><span class="se">\n</span><span class="s">'</span>
<span class="s">' <b>b</b></span><span class="se">\n</span><span class="s">'</span>
<span class="s">' <b>c</b></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'</body></span><span class="se">\n</span><span class="s">'</span>
<span class="s">'</html></span><span class="se">\n</span><span class="s">'</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">),</span>
<span class="n">actual</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>
<h4>まとめ</h4>
<p>多言語対応なのは利点。<br />
Python だと <a href="http://jinja.pocoo.org/docs/">Jinja2</a> という強力なテンプレートエンジンがあるので、それほど利点がないかもしれない。<br />
テンプレートエンジンの選択肢が少ないような言語だとかなり便利かもしれない。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-42880650700805411032012-10-27T06:00:00.000+09:002012-10-27T06:00:01.570+09:00Python 標準ロギングモジュール logging の使い方メモ<h4>概要</h4>
<p>logging を利用してみる。</p>
<p>ドキュメント</p>
<p>モジュールの使い方は、公式ドキュメント「<a href="http://docs.python.org/library/logging.html">logging — Logging facility for Python</a>」に概要が書いてある。
また「<a href="http://docs.python.org/howto/logging.html">Logging HOWTO</a>」が具体的な使い方に関して書いてある。</p>
<h4>使い方</h4>
<p>以下が一番簡単な例。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'わーにんぐ'</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'いんふぉ'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>実行すると以下のようになる。これはデフォルトレベルが「WARNING」以上だから。</p>
<div class="highlight"><pre>WARNING:root:わーにんぐ
</pre></div>
<p>ログのレベルは以下のようになる。</p>
<table style="border-width: 2px; border-style: solid">
<tr>
<th>レベル</th>
<th>関数</th>
<th>数値</th>
<th>概要</th>
</tr>
<tr>
<td>CRITICAL</td>
<td>logging.critical()</td>
<td>50</td>
<td>停止してしまうような致命的な問題用</td>
</tr>
<tr>
<td>ERROR</td>
<td>logging.error()</td>
<td>40</td>
<td>重大な問題用</td>
</tr>
<tr>
<td>WARNING</td>
<td>logging.warning()</td>
<td>30</td>
<td>実行機能で問題が発生した場合用</td>
</tr>
<tr>
<td>INFO</td>
<td>logging.info()</td>
<td>20</td>
<td>動作情報表示用</td>
</tr>
<tr>
<td>DEBUG</td>
<td>logging.debug()</td>
<td>10</td>
<td>詳細な情報表示用</td>
</tr>
<tr>
<td>NOTSET</td>
<td></td>
<td>0</td>
<td>全てを出力。基本的に設定用の値</td>
</tr>
</table>
<h4>ファイルへの出力</h4>
<p>エラーをファイルに出したい場合があるが以下のようにする。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">'example.log'</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'でばっぐ'</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'いんふぉ'</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'わーにんぐ'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>「sample.log」ファイルに以下のように出力される。</p>
<div class="highlight"><pre>DEBUG:root:でばっぐ
INFO:root:いんふぉ
WARNING:root:わーにんぐ
</pre></div>
<h4>ログ出力形式の指定</h4>
<p>ログの出力形式はいろいろ変更できる。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">format</span><span class="o">=</span><span class="s">'</span><span class="si">%(asctime)s</span><span class="s">:</span><span class="si">%(levelname)s</span><span class="s">:</span><span class="si">%(message)s</span><span class="s">'</span><span class="p">,</span>
<span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'でばっぐ'</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'いんふぉ'</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'わーにんぐ'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>以下のように出力される。</p>
<div class="highlight"><pre>2012-10-01 11:21:46,999:DEBUG:でばっぐ
2012-10-01 11:21:46,999:INFO:いんふぉ
2012-10-01 11:21:47,000:WARNING:わーにんぐ
</pre></div>
<p>使えるフォーマットは「<a href="http://docs.python.org/library/logging.html#logrecord-attributes">LogRecord attributes</a>」に一覧がある。主な物は以下。</p>
<table style="border-width: 2px; border-style: solid">
<tr>
<th>フォーマット</th>
<th>概要</th>
</tr>
<tr>
<td>%(asctime)s</td>
<td>実行時刻</td>
</tr>
<tr>
<td>%(filename)s</td>
<td>ファイル名</td>
</tr>
<tr>
<td>%(funcName)s</td>
<td>関数名</td>
</tr>
<tr>
<td>%(levelname)s</td>
<td>DEBUG、INFO等のレベル名</td>
</tr>
<tr>
<td>%(lineno)d</td>
<td>行番号</td>
</tr>
<tr>
<td>%(name)s</td>
<td>呼びだしたログの定義名</td>
</tr>
<tr>
<td>%(module)s</td>
<td>モジュール名</td>
</tr>
<tr>
<td>%(message)s</td>
<td>ログメッセージ</td>
</tr>
<tr>
<td>%(process)d</td>
<td>プロセスID</td>
</tr>
<tr>
<td>%(thread)d</td>
<td>スレッドID</td>
</tr>
</table>
<h4>設定ファイルの利用</h4>
<p>フォーマットやログレベルの設定は、通常は設定ファイルを書いて利用する。設定ファイルのファイル名な何でも良い。ここでは以下の内容で「logging.conf」として作成する。<br />
以下の例だと、コンソールとファイルに「DEBUG」レベルでログを出力する。</p>
<div class="highlight"><pre><span class="k">[loggers]</span>
<span class="na">keys</span><span class="o">=</span><span class="s">root, logExample</span>
<span class="k">[handlers]</span>
<span class="na">keys</span><span class="o">=</span><span class="s">consoleHandler, fileHandler</span>
<span class="k">[formatters]</span>
<span class="na">keys</span><span class="o">=</span><span class="s">logFormatter</span>
<span class="k">[logger_root]</span>
<span class="na">level</span><span class="o">=</span><span class="s">DEBUG</span>
<span class="na">handlers</span><span class="o">=</span><span class="s">consoleHandler</span>
<span class="k">[logger_logExample]</span>
<span class="na">level</span><span class="o">=</span><span class="s">DEBUG</span>
<span class="na">handlers</span><span class="o">=</span><span class="s">consoleHandler, fileHandler</span>
<span class="na">qualname</span><span class="o">=</span><span class="s">logExample</span>
<span class="na">propagate</span><span class="o">=</span><span class="s">0</span>
<span class="k">[handler_consoleHandler]</span>
<span class="na">class</span><span class="o">=</span><span class="s">StreamHandler</span>
<span class="na">level</span><span class="o">=</span><span class="s">DEBUG</span>
<span class="na">formatter</span><span class="o">=</span><span class="s">logFormatter</span>
<span class="na">args</span><span class="o">=</span><span class="s">(sys.stdout,)</span>
<span class="k">[handler_fileHandler]</span>
<span class="na">class</span><span class="o">=</span><span class="s">handlers.RotatingFileHandler</span>
<span class="na">level</span><span class="o">=</span><span class="s">DEBUG</span>
<span class="na">formatter</span><span class="o">=</span><span class="s">logFormatter</span>
<span class="na">args</span><span class="o">=</span><span class="s">('example.log',)</span>
<span class="k">[formatter_logFormatter]</span>
<span class="na">format</span><span class="o">=</span><span class="s">%(asctime)s - %(name)s - %(levelname)s - %(message)s</span>
<span class="na">datefmt</span><span class="o">=</span>
</pre></div>
<p>利用するソースは以下。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">logging.config</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">logging</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">fileConfig</span><span class="p">(</span><span class="s">'logging.conf'</span><span class="p">)</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'logExample'</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'でばっぐ'</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'いんふぉ'</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'わーにんぐ'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<h4>Handlerの利用</h4>
<p>上記のサンプルだと「RotatingFileHandler」を利用している。これはファイルが一定量になると回転するハンドラ。<br />
標準のハンドラでも十分な場合もあるが、<a href="http://pypi.python.org/pypi">PyPI</a>で探すと他にもいろいろなハンドラが存在している。<br />
以下とか便利かもしれない。</p>
<ul>
<li><a href="http://pypi.python.org/pypi/log4mongo/">log4mongo</a>:mongoDB にログを出力</li>
<li><a href="http://pypi.python.org/pypi/python-redis-log/">python-redis-log</a>:Redis にログを出力</li>
<li><a href="http://pypi.python.org/pypi/td-logger/">td-logger</a>:Treasure Dataにログを出力</li>
<li><a href="http://pypi.python.org/pypi/fluent-logger/">fluent-logger</a>:Fluentdにログを出力</li>
</ul>
<p>存在しない Handler は上記を参考に自作してみると良いかもしれない。</p>
<h4>まとめ</h4>
<p>logging は障害対処時に非常に有効。多用することになるので、使い方に慣れておくと良い。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-74161092019283059302012-10-26T06:00:00.000+09:002012-10-26T06:00:00.969+09:00Python で標準添付の Debuggerのpdb を利用してデバッグするメモ<h4>概要</h4>
<p>pdb を利用してみる。</p>
<h4>ドキュメント</h4>
<p>公式ドキュメント「<a href="http://docs.python.org/library/pdb.html">pdb — The Python Debugger</a>」に概要が書いてある。</p>
<h4>使い方</h4>
<p>スクリプトを直接起動してデバッグする方法と、インタラクティブshell で起動する方法があるが、ここでは、スクリプトを起動してデバッグする方法で書く。<br />
以下がデバッグするスクリプトのサンプル「even.py」。<br />
自分の場合、スクリプトを直接デバッグすることがあまりなく、デバッグするのはライブラリとかをunittest経由でデバッグすることがが多いのでサンプルは unittest で書いている。<br />
以下の例はクラス内の関数が偶数だけ返す所でバグがあり、奇数を返すようになっている。そんなに良い例ではないかも。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">Sample</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> テスト対象のクラス</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">to_even</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lst</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> リストを渡すと、偶数だけにして返す</span>
<span class="sd"> """</span>
<span class="c"># 意図的にバグらせていて、奇数しか返さない</span>
<span class="n">evenlst</span> <span class="o">=</span> <span class="p">[</span><span class="n">v</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">lst</span> <span class="k">if</span> <span class="n">v</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">return</span> <span class="n">evenlst</span>
<span class="k">class</span> <span class="nc">TestSample</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> テストクラス</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">test_main</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">clazz</span> <span class="o">=</span> <span class="n">Sample</span><span class="p">()</span>
<span class="c"># 0 から 10 のリストを生成 [0, 1, 2, .....]</span>
<span class="n">lst</span> <span class="o">=</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="n">evenlst</span> <span class="o">=</span> <span class="n">clazz</span><span class="o">.</span><span class="n">to_even</span><span class="p">(</span><span class="n">lst</span><span class="p">)</span>
<span class="c"># 偶数かテストする</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">evenlst</span><span class="p">:</span>
<span class="n">num</span> <span class="o">=</span> <span class="n">item</span> <span class="o">%</span> <span class="mi">2</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>
<p>とりあえず実行してみると以下のようにエラーになる。</p>
<div class="highlight"><pre>> python even.py
F
======================================================================
FAIL: test_main (__main__.TestSample)
----------------------------------------------------------------------
Traceback (most recent call last):
File "even.py", line 33, in test_main
self.assertEqual(0, num)
AssertionError: 0 != 1
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
</pre></div>
<p>pdbを起動してみる。起動は以下のようにする。</p>
<div class="highlight"><pre>python -m pdb even.py
</pre></div>
<p>起動すると pdb プロンプトが起動する。</p>
<div class="highlight"><pre>> /path/to/even.py(3)<module>()
-> import unittest
(Pdb)
</pre></div>
<p>上記の出力から「3行目」の「import」で実行が停止しているのがわかる。<br />
「list」で停止位置の周辺ソースが表示される。</p>
<div class="highlight"><pre>(Pdb) list
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 -> import unittest
4
5
6 class Sample(object):
7 """
8 テスト対象のクラス
9 """
10 def to_even(self, lst):
11 """
(Pdb)
</pre></div>
<p>行数とともに、現在の停止場所に「->」がある。</p>
<p>「list」のようにデバッグに利用できるコマンドの主な物は以下になる。コマンドには省略形が存在する物もある。</p>
<table style="border-width: 2px; border-style: solid">
<tr>
<th>コマンド</th>
<th>省略形</th>
<th>概要</th>
</tr>
<tr>
<td>help</td>
<td>h</td>
<td>コマンドのヘルプを表示。<br />
「help」でコマンド一覧、<br />
「help コマンド名」でコマンドのヘルプ<br />
が表示される。</td>
</tr>
<tr>
<td>where</td>
<td>w</td>
<td>スタックトレースを表示</td>
</tr>
<tr>
<td>down</td>
<td>d</td>
<td>スタックトレース中に1レベル下げる</td>
</tr>
<tr>
<td>up</td>
<td>u</td>
<td>スタックトレース中に1レベル上げる</td>
</tr>
<tr>
<td>step</td>
<td>s</td>
<td>現在行を実行し、次の行に進む<br />
次の行が関数の場合、関数内で停止</td>
</tr>
<tr>
<td>next</td>
<td>n</td>
<td>現在行を実行し、次の行に進む<br />
次の行が関数でも、関数内では停止しない</td>
</tr>
<tr>
<td>return</td>
<td>r</td>
<td>現在の関数から抜ける</td>
</tr>
<tr>
<td>list</td>
<td>l</td>
<td>現在行周辺のソースを表示<br />
デフォルトは11行表示する</td>
</tr>
<tr>
<td>args</td>
<td>a</td>
<td>現在関数の引数一覧を表示</td>
</tr>
<tr>
<td>p 式</td>
<td></td>
<td>式内容を表示</td>
</tr>
<tr>
<td>pp 式</td>
<td></td>
<td>式内容を pprint で表示</td>
</tr>
<tr>
<td>quit</td>
<td>q</td>
<td>デバッガ終了</td>
</tr>
</table>
<p>現在行が「import」なので「n(ext)」で進める。<br />
間違えて「s(tep)」すると「import」を実行する Python のライブラリ内に入る。その場合は「r(eturn)」とかすると戻ってこれる。</p>
<div class="highlight"><pre>(Pdb) n
> /path/to/even.py(6)<module>()
-> class Sample(object):
(Pdb)
</pre></div>
<p>class の行になるが、実行されるわけではない。<br />
再度「n」するが、この「n」は一度実行すると次回は「リターンキー」で同じ事を実行する。</p>
<div class="highlight"><pre>(Pdb)
> /path/to/even.py(18)<module>()
-> class TestSample(unittest.TestCase):
(Pdb)
</pre></div>
<p>「c(ontinue)」すると、停止するまで実行する。</p>
<div class="highlight"><pre>(Pdb) c
F
======================================================================
FAIL: test_main (__main__.TestSample)
----------------------------------------------------------------------
Traceback (most recent call last):
File "even.py", line 33, in test_main
self.assertEqual(0, num)
AssertionError: 0 != 1
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
The program exited via sys.exit(). Exit status: True
> /path/to/even.py(3)<module>()
-> import unittest
</pre></div>
<h4>ブレークポイント</h4>
<p>通常 step 実行とかしないで、ブレークポイントを利用する。ブレークポイント関連のコマンドは以下。</p>
<table style="border-width: 2px; border-style: solid">
<tr>
<th>コマンド</th>
<th>省略形</th>
<th>概要</th>
</tr>
<tr>
<td>break 行数 or 関数名</td>
<td>b</td>
<td>指定行数にブレークポイントを付ける</td>
</tr>
<tr>
<td>tbreak 行数 or 関数名</td>
<td></td>
<td>一時的ブレークポイントを付ける<br />
一回通過すると消える</td>
</tr>
<tr>
<td>clear 行数 or bp番号</td>
<td>cl</td>
<td>ブレークポイントを削除</td>
</tr>
<tr>
<td>disable bp番号</td>
<td></td>
<td>ブレークポイントを停止</td>
</tr>
<tr>
<td>enable bp番号</td>
<td></td>
<td>ブレークポイントを有効化</td>
</tr>
<tr>
<td>ignore bp番号 回数</td>
<td></td>
<td>ブレークポイントを回数分無視する</td>
</tr>
<tr>
<td>condition bp番号</td>
<td></td>
<td>ブレークポイントの状態を確認</td>
</tr>
<tr>
<td>commands bp番号</td>
<td></td>
<td>ブレークポイントを表示</td>
</tr>
<tr>
<td>continue</td>
<td>c</td>
<td>ブレークポイントで停止してる場合、実行を継続</td>
</tr>
</table>
<p>「33行目」にブレークポイントを設定し「c」して「l」で確認してみる。</p>
<div class="highlight"><pre>(Pdb) b 33
Breakpoint 1 at /path/to/even.py:33
(Pdb) c
> /path/to/even.py(33)test_main()
-> for item in evenlst:
(Pdb) l
28 # 0 から 10 のリストを生成 [0, 1, 2, .....]
29 lst = xrange(10)
30 evenlst = clazz.to_even(lst)
31
32 # 偶数かテストする
33 B-> for item in evenlst:
34 num = item % 2
35 self.assertEqual(0, num)
36
37
38 if __name__ == '__main__':
(Pdb)
</pre></div>
<p>ここで「evenlst」の内容を表示してみる。</p>
<div class="highlight"><pre>(Pdb) p evenlst
[1, 3, 5, 7, 9]
(Pdb)
</pre></div>
<p>バグっている事がわかる。</p>
<p>「n」を2回して「l」して「p」してみる。「p」で複数表示の場合はカンマで区切る。</p>
<div class="highlight"><pre>(Pdb) p item,num
(1, 1)
(Pdb)
</pre></div>
<p>バグ原因が判明したら「q」などで終了すれば良い。</p>
<h4>まとめ</h4>
<p>他者の作成したライブラリ等はソース修正するとまずいので、 print を入れることができない場合が多く、そういう場合は pdb は便利。<br />
本当はライブラリ内で Exception が発生したりするので、結構デバッグは大変だったりする。<br />
自作のスクリプトの場合は、普通は pdb を使うよりも、いかに良くテストを書くかの方が重要な気がしている。pdbを使わなければいけないのはテストが下手だと思った方が良い。</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-5542064418961639741.post-27629337181960281602012-10-24T06:00:00.000+09:002012-10-24T06:00:03.079+09:00pyregexp を利用して Emacs の検索置換に Python の正規表現を利用してみる<h4>概要</h4>
<p>Emacs の正規表現は結構使いずらくて、覚えられないので、「<a href="https://github.com/benma/pyregexp">pyregexp</a>」を利用して、Python の正規表現を利用してみる。</p>
<h4>pyregexpに関して</h4>
<p>Python を利用して Emacs 内の検索・置換の処理で Python の正規表現を利用できるようにする Emacs Lisp。動作には Python が必要。</p>
<h4>設定</h4>
<p>ソースを取得して、pathの通った所に配置。</p>
<div class="highlight"><pre>git clone git://github.com/benma/pyregexp.git
</pre></div>
<p>init.el 等で以下のように設定する。</p>
<div class="highlight"><pre>(require 'pyregexp)
(define-key global-map (kbd "C-c r") 'pyregexp-replace)
(define-key global-map (kbd "C-c q") 'pyregexp-query-replace)
(define-key esc-map (kbd "C-r") 'pyregexp-isearch-backward)
(define-key esc-map (kbd "C-s") 'pyregexp-isearch-forward)
</pre></div>
<h4>使い方</h4>
<p>公式サイト「<a href="https://github.com/benma/pyregexp">pyregexp</a>」の一部をそのまま引用する。</p>
<p>以下のようなテキストを用意。これの重複した文字を検索して、重複を削除してみる。</p>
<div class="highlight"><pre>We we can delete double double words
by by using backreferences.
</pre></div>
<p>「C-c r」して入力を開始すると、「Regexp」になるので、「(?i)(\w+) \1」を入力。一致箇所がハイライトされるる。3箇所一致しているはず。一番最後の文字は「いち」なので間違わないように。<br />
置換する場合は「enter」をすると「Replace」になるので、「\1」を入力。置換結果が「We we => We」のように表示される。問題なければ、enter することで置換される。</p>
<p>Python の式を利用することも可能。</p>
<p>以下のようなファイルを用意。</p>
<div class="highlight"><pre>hoge
foo
bar
</pre></div>
<p>「C-c r」して「^」を入力すると、文字列の先頭が一致する。enter して Replace にして「C-c C-c」すると「Replace (using expression)」になるので「str(i+1) + ": "」を入力すると、先頭に「1: 2: 3:」のような文字が入力される。</p>
<p>str だけでなく、int等も利用できるのでかなり便利。</p>
<p>「wdired-change-to-wdired-mode」でも利用可能。かなり高度な置換ができる。</p>
<h4>まとめ</h4>
<p>まだ使いはじめたばかりだが、自分は Python に慣れているので、かなり便利に利用できている。</p>Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-5542064418961639741.post-25745522864422222802012-10-23T06:00:00.000+09:002012-10-23T06:00:02.251+09:00Python の lambda メモ<h4>概要</h4>
<p>仕事の関係で Python の lambda に関して最近質問された。lambda は結構読みずらいようで質問の回数が多い気がする。毎回似たような質問に答えるのが面倒なので、回答用に概要をメモしておく。</p>
<h4>Python の lambda</h4>
<p>lambda は無名関数を作成するための機能。</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">a</span><span class="p">(</span><span class="n">b</span><span class="p">):</span>
<span class="k">return</span> <span class="n">c</span>
</pre></div>
<p>と同じ物をが、lambda だと以下のように記述できる。</p>
<div class="highlight"><pre><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">b</span><span class="p">:</span> <span class="n">c</span>
</pre></div>
<h4>簡単なサンプル</h4>
<p>とりあえず簡単なサンプルが以下。時々 lambda は改行ができないと思っている人がいるみたいだが、括弧でかこめば普通に改行できる。</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">TestLambda</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_basic</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c"># def を利用</span>
<span class="k">def</span> <span class="nf">a</span><span class="p">(</span><span class="n">b</span><span class="p">):</span>
<span class="k">return</span> <span class="n">b</span> <span class="o">*</span> <span class="mi">10</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="n">a</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
<span class="c"># lambda を利用</span>
<span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">b</span><span class="p">:</span> <span class="n">b</span> <span class="o">*</span> <span class="mi">2</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="n">a</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
<span class="c"># 括弧を利用すると途中改行が可能</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="k">lambda</span> <span class="n">b</span><span class="p">:</span>
<span class="n">b</span> <span class="o">*</span> <span class="mi">4</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">a</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>
<h4>まとめ</h4>
<p>確かに lambda を使うべき場面もあるが、普通はlambda はそんなに多用しない方が良いと思う。利用しても、意味ない場合も多い。<br />
変な所で、変なテクニック使ってもおもしろくともなんとも無いので、普通に読みやすく書くのが一番良い。<br />
あと、書いたは良いが、質問される内容はもっと高度になる場合が多いので、このエントリは自分の手抜き用には役に立たないかもしれない。</p>
Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-5542064418961639741.post-61690713969718552412012-10-22T06:00:00.000+09:002012-10-23T21:15:55.322+09:00Mercurial(hg) を使って GitHub に Pull Request する手順<h4>概要</h4>
<p>分散バージョン管理ツールとして自分は「<a href="http://mercurial.selenic.com/">Mercurial</a>」を利用している。<br />
自分にとって Git は難しすぎるので、できれば使いたくなかったので、Git を利用しないで GitHub に Pull Request する方法を調べた。</p>
<h4>Pull Request が初めての場合</h4>
<p>Pull Request が初めての場合、GitHub の公式マニュアルに従って練習すると良い。Pull Requestのマニュアルは「<a href="https://help.github.com/articles/fork-a-repo">Fork A Repo · github:help</a>」にある。</p>
<p>GitHub のマニュアルに従って、「<a href="https://github.com/octocat/Spoon-Knife">https://github.com/octocat/Spoon-Knife</a>」を Fork して練習する。失敗しても誰も怒ったりしないので、自由にやるのが良い。</p>
<h4>hg-git のインストールと設定</h4>
<p>hg で GitHub のソースを clone するには「<a href="http://pypi.python.org/pypi/hg-git/">hg-git</a>」を利用する。<br />
「<a href="http://pypi.python.org/pypi/hg-git/">hg-git</a>」は Git のバイナリがなくても、単体で Git レポジトリを扱うことができるライブラリ。pip 等で簡単にインストールできる。</p>
<div class="highlight"><pre>pip install hg-git
</pre></div>
<p>hgrcに以下を設定する</p>
<div class="highlight"><pre>[extensions]
hggit=
</pre></div>
<h4>hg で GitHub のソースを clone する</h4>
<p>hg-git を利用して GitHub のレポジトリを clone する。<br />
例えばGitHub で「git@github.com:username/Spoon-Knife.git」のようなレポジトリの場合、以下のように指定すると clone できる。</p>
<div class="highlight"><pre>hg clone git+ssh://github.com/username/Spoon-Knife.git
</pre></div>
<h4>Pull Request用に開発</h4>
<p>master でそのまま開発すると、fork 元の変更に追随することができなくなるので、開発用の branch を作成する。</p>
<div class="highlight"><pre>
cd Spoon-Knife
hg branch <span class="s1">'develop'</span>
<span class="c"># コミット</span>
hg ci -m<span class="s2">"develop"</span>
<span class="c"># 確認</span>
hg branches
</pre></div>
<p>そして、開発用の branch から pull request 用の branch を作成する。</p>
<div class="highlight"><pre>hg branch <span class="s1">'feature/samplespike'</span>
<span class="c"># コミット</span>
hg ci -m<span class="s2">"feature/samplespike"</span>
<span class="c"># 確認</span>
hg branches
</pre></div>
<p>pull request 用の branch で開発する。</p>
<h4>push 用の bookmark 作成</h4>
<p>hg-git では hg の bookmark が Git の branch になる。push を本当にする場合、bookmark を作成する。</p>
<div class="highlight"><pre>hg bookmark -r feature/samplespike pullrequest/samplespike
</pre></div>
<h4>pull requestのために、Commit を一つに纏める</h4>
<p>開発によって、Commit が複数に分割されている場合があるが、分割されたpull request はしない方が良い。<br />
Git の場合 rebase でこれを実施するが、hg では「<a href="http://mercurial.selenic.com/wiki/HisteditExtension">Histedit Extension</a>」を利用する。Mercurial 2.3以降は標準添付なので以下のようにhgrcに設定する。</p>
<div class="highlight"><pre>[extensions]
histedit=
</pre></div>
<p>利用しているバージョンが Mercurial 2.3 以下の場合は「<a href="https://bitbucket.org/durin42/histedit/src">histedit</a>」からソースを取得して設定する必要がある。</p>
<div class="highlight"><pre>hg clone https://bitbucket.org/durin42/histedit
</pre></div>
<p>ソースからの場合は hgrc に以下のように設定する。</p>
<div class="highlight"><pre>[extensions]
histedit = /path/to/hg_histedit.py
</pre></div>
<p>histedit の使い方は「hg help -e histedit」でhg の help を見ると和訳されている。<br />
英語だが公式のマニュアルを見ても良い「<a href="http://mercurial.selenic.com/wiki/HisteditExtension">Histedit Extension</a>」。</p>
<div class="highlight"><pre>hg histedit まとめたいバージョン
</pre></div>
<h4>push の前に確認する</h4>
<p>「hg log」や「hg glog」を利用して意図した通りになっているか十分確認する。push するとhisteditでの変更ができない。</p>
<p>Hg-Gitプラグインは「--HG--」のようなコメントを挿入してしまう。これを抑止するにはソースを直接修正するしかない。<br />
「hggit/git_handler.py」に該当部分が存在するので、気になる場合は、削除かコメントアウトしておくと良い。</p>
<h4>push して pull request </h4>
<p>hg-git でpush するのは hg で push するのと何も変らない。</p>
<div class="highlight"><pre>hg push
</pre></div>
<p>あとは GitHub のWeb から該当の branch を pull request すれば良い。</p>
<h4>本家に追随する</h4>
<p>本家が自分のpull requestを取り込みしてくれたら、追随する必要がある。</p>
<div class="highlight"><pre>hg pull -r master git+ssh://github.com/octocat/Spoon-Knife.git
hg up
</pre></div>
<p>これで取り込める。master に commit していると面倒なことになるので、master では開発しないようにした方が良い。</p>
<h4>まとめ</h4>
<p>これでGitHub の pull request が hg で可能になる。</p>Anonymousnoreply@blogger.com0