ターミナルの画面を消去する方法
特別なインストールなしで実現したい。
- POSIX互換環境(Linux/Unix/Mac): clear
- Windows
- コマンドプロンプト (cmd.exe): cls
- CygWin (2011以前): cmd /c cls
- CygWin (mintty): echo -en "\ec"
CygWin の闇は深い。
ターミナルの画面を消去する方法
特別なインストールなしで実現したい。
CygWin の闇は深い。
エレガントなメモ化のやり方
同僚から教えてもらったテクニックを忘れそうになったのでメモ。
#include <cstdio>
int memo[100][100];
int main() {
memset(memo, -1, sizeof memo);
// call f with parameters
f(???, ???)
}
int f(int x, int y) {
int& res = memo[x][y];
if (res < 0) {
// do the work when the value has not been calculated
res = ???
}
return res;
}
適当なn次配列をメモ化の領域として使い、1のビット(-1)で初期化するところまでは一般的なやり方。
ポイントは、実際にメモ化したデータを使う部分。
はじめに配列の要素の参照を取り、初期状態でない場合にのみその値を更新する。
いずれのケースでも最後にその参照を返す。
これで処理の流れがシンプルになるし、メモの更新し忘れを防ぐこともできる。
同様に、Python で値が None で初期化されているならこんな感じ。
def f():
if cache is None:
# do the work
cache = ???
return cache
Python: リスト内の True の個数を数える
sum を使えば、True: 1, False: 0 としてカウントされるので便利。
>>> [False, True, True, False, True].count(True) 3 >>> sum([False, True, True, False, True]) 3 >>> sum(x % 2 == 1 for x in range(5)) 2
Travis CI: Scalaプロジェクトのビルドを高速化させる
sbt-assembly で使われていたテクニックを学ぶ。
現時点において、Travis CI におけるビルド環境は以下の3種類。
sudo に false を明示的に指定すると、コンテナベースのインフラが選択されるようになる。(未指定時はVMベース)
コンテナベースのほうが起動時間の短縮を見込める。
sudo: false
Travis CI のキャッシュ機能を利用すれば、更新のないライブラリなどのダウンロード処理をスキップできる。
cache:
directories:
- $HOME/.ivy2/cache
- $HOME/.sbt/boot/scala-$TRAVIS_SCALA_VERSION
実際には Amazon S3 に対するダウンロード/アップロードが行われている。
容量にもよるが、ダウンロードで30秒、アップロードで1分程度はどうしてもかかってしまう。
キャッシュに更新がなければ、Amazon S3 へのアップロード処理は省略される。
ビルド実行後に一時的なファイルを削除すれば、このアップロード処理の発生を必要最低限にできるはずだ。
これは before_cache ステージにコマンドを記述することで実現できる。
before_cache: - find $HOME/.sbt -name "*.lock" -delete - find $HOME/.ivy2 -name "ivydata-*.properties" -delete
これでももし、Travis CI のログに以下のようなメッセージが出ていたら、何か意図しない差分が存在しているということ。
store build cache changes detected, packing new archive
このように表示されればOK。
store build cache nothing changed, not updating cache
複数のGitHubアカウントを使い分ける
ディレクトリを作成
mkdir -p ~/.git-wrapper/shims mkdir -p ~/.git-wrapper/ssh
ssh ディレクトリに実行ファイルを作り、SSH鍵との紐付けを定義
例
#! /bin/sh exec ssh -oIdentitiesOnly=yes -oIdentityFile=~/.ssh/yourname1.github "$@"
#! /bin/sh exec ssh -oIdentitiesOnly=yes -oIdentityFile=~/.ssh/yourname2.github "$@"
shims ディレクトリにラッパーシェルを作る。18-26行目は適宜書き換える。
.bashrc または .zshrc で以下のようにパスを追加
export PATH="${HOME}/.git-wrapper/shims:${PATH}"
A-7 無料アカウントを複数作るのは規約違反。
GitHub Terms of Service - User Documentation
Travis CI で時間のかかるコマンドを実行する
C++ でコンパイル時計算を多用すると、ビルドだけで 10分以上かかってしまうことも珍しくない。
しかし、Travis CI では 10分間何も出力がないと強制終了となってしまう。
No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself. The build has been terminated
途方に暮れていたら、なんと公式アカウントから直々にメンションをもらった。
@mogproject You can use the bash function "travis_wait" to lengthen the timeout; e.g., travis_wait CMD, or travis_wait 30 CMD
— Travis CI (@travisci) 2015, 2月 11
このような目的のために、travis_wait という bash の関数が用意されているらしい。
before_script: - travis_wait make build
こう書けば、20分間無出力の状態が続いても、Travis CI は待っていてくれる。
しかしそれでも時間が足りないと、やはりタイムアウトとなってしまう。
Still running (20 of 20): make build Timeout (20 minutes) reached. Terminating "make build" The command "travis_wait make build" failed and exited with 1 during . Your build has been stopped.
こんな場合は、以下のように待機時間(分)をパラメータに付け加えればよい。
before_script: - travis_wait 60 make build
これで、ビルドのタイムアウトが 60分に延長された。
pep8: 行あたりの最大文字数の拡張
pep8 を流した時、E501がうるさい。
$ pep8 src tests tests/test_xxx.py:30:80: E501 line too long (112 > 79 characters) ...
--max-line-length オプションを使えばスッキリ。
$ pep8 --max-line-length 120 src tests
~/.config/pep8 ファイルにあらかじめ書いておけば、オプション指定を省略できるので便利。
[pep8] max-line-length = 120
Python: PostgreSQL への高速インサート
Python + Psycopg で PostgreSQL の操作。
テーブルに大量データを投入する場合、INSERT よりも TSV (or CSV) ファイルを作って COPY で読み込んだ方が速いというのは知られているが、StringIO を利用すれば実際にファイルを作成する必要すらない、という例。
from StringIO import StringIO
import psycopg2
data = [[42, 'foo'], [74, 'bar']]
conn = psycopg2.connect(host = "localhost", port = 5432, database="dbname", user="user", password="pass")
cur = conn.cursor()
f = StringIO()
f.write('\n'.join('\t'.join(str(s) for s in r) for r in data))
f.seek(0)
cur.copy_from(f, 'tablename')
cur.close()
conn.close()
from StringIO import StringIO
import psycopg2
data = [[42, 'foo'], [74, 'bar']]
conn = psycopg2.connect(host = "localhost", port = 5432, database="dbname", user="user", password="pass")
cur = conn.cursor()
cur.execute('CREATE TABLE awesome_table (id integer NOT NULL, name character varying(40));')
f = StringIO()
f.write('\n'.join('\t'.join(str(s) for s in r) for r in data))
f.seek(0)
cur.copy_from(f, 'awesome_table')
cur.execute("select * from awesome_table;")
print(cur.fetchall())
cur.close()
conn.close()
[(42, 'foo'), (74, 'bar')]
Mac + tmux + ターミナル上のEmacs でクリップボードを連携する方法
tmux 上で Emacs を利用する場合、
OS のクリップボードとその内容をシームレスに連携するためには多少の手順が必要となる。
Emacs 初期設定ファイル (~/.emacs/init.el など) に以下の内容を記述。
(defun copy-from-osx ()
(shell-command-to-string "pbpaste"))
(defun paste-to-osx (text &optional push)
(let ((process-connection-type nil))
(let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
(process-send-string proc text)
(process-send-eof proc))))
(setq interprogram-cut-function 'paste-to-osx)
(setq interprogram-paste-function 'copy-from-osx)
tmux 内部での Mac OS X クリップボードのやりとり (pbcopy/pbpaste) を可能にするツール。
Homebrew でインストールするのが一番簡単だ。
$ brew install reattach-to-user-namespace
tmux 初期設定ファイル (~/.tmux.conf) に以下の内容を記述し、tmux を再起動。
set-option -g default-command "reattach-to-user-namespace -l zsh"
$ tmux kill-server
これで
が可能となった。
Python: 辞書内包表記
Python3 および Python2.7 では集合と辞書の内包表記を利用でき、よりシンプルな表現ができるようになった。
>>> d = {1: 'a', 2: 'b', 3: 'c'}
>>> {v: k for k, v in d.items()}
{'a': 1, 'c': 3, 'b': 2}
dict#iteritems は Python3 では廃止され、dict#items でも同等の性能が出るようになった。
>>> {x: x for x in ['a', 'e']}
{'a': 'a', 'e': 'e'}
ちなみに、辞書のキーが全て文字列なら、このような方法で複数の辞書をマージすることも可能。
>>> dict({x: x for x in ['a', 'e']}, **{v: k for k, v in d.items()})
{'a': 1, 'c': 3, 'b': 2, 'e': 'e'}
Emacs: 行番号表示のフォーマット指定
忘れがちなのでメモ。
Emacs における行番号表示は、init.el で global-linum-mode を指定すれば実現できるが、
以下のように linum-format を指定すればそのフォーマットをカスタマイズすることも可能だ。
(require 'linum) (global-linum-mode t) (setq linum-format "%4d ")
フォーマット文字列は C のアレと同じで、上記の例であれば
4桁分の領域に行番号の数字が表示され、その後に一個スペースが入る。
巨大な Git リポジトリを少しずつクローンする方法
ファイルサイズの非常に大きな Git リポジトリの場合、git clone を行った時に メモリが不足しエラーとなってしまうケースがある。
$ git clone git://xxxxxxxx.xxx:awesome-project.git Cloning into 'awesome-project'... remote: Counting objects: 9999, done. remote: warning: suboptimal pack - out of memory remote: fatal: Out of memory, malloc failed error: git upload-pack: git-pack-objects died with error. fatal: git upload-pack: aborting due to possible repository corruption on the remote side. remote: aborting due to possible repository corruption on the remote side. fatal: early EOF fatal: index-pack failed
depth を指定して shallow copy を行うことで解決できる場合がある。
具体的な手順は、以下のブログが参考になった。
HBase: hbase shell でのカウント間隔を変える
hbase shell で count コマンドを実行し行数をカウントする際、10,000件ごとに表示が出るのが煩わしければ
count '<テーブル名>', INTERVAL => 100000
のようにオプションを指定して表示間隔を変えることが可能。
HBase: テーブルのディスク使用量を調べる方法
hbase/テーブル名 ディレクトリの総容量を測ればよい。
OS のファイルシステムなら
du -sh パス/hbase/テーブル名
など。
HDFS なら
hadoop hdfs -du -s /hbase/テーブル名
でよい。
TopCoder: KawigiEdit のセットアップ手順
Kawigi氏が作成した、TopCoder 用のエディタプラグイン。(最新版は Pivanof 氏がメンテ)
以下の特徴を持つ。
SRMでこのようなプラグインを利用するのは許可されており、チートとは見なされない。
Competing in a Rated Algorithm Competition - TopCoder Wiki
ドキュメント
KawigiEdit Documentation
KawigiEdit_x.x.jar を適当な場所に保存。 (私はDropbox上に置いている)
他はデフォルトのままでも基本的に問題なさそう。
テンプレートを変えたい場合は言語ごとに .ket ファイルを作成する。
また、デフォルトのプログラミング言語の変更はこの画面ではなく
Arena のメニューから Options -> Setup User Preferences を開き、
Editors タブ -> Default Language で行うのを忘れがち。
Scala: 関数をn回適用した結果のリストを作る
scala.collection.immutable.Stream を使うと簡単にできる。
以下は、適当な文字列の左右を「#」で囲む関数を 1回, 2回, ... と適用した結果をリストにして返す例。
(Scala 2.10, REPLで実行)
scala> def f(s: String) = s"#${s}#"
f: (s: String)String
scala> def g(s: String): Stream[String] = s #:: g(f(s))
g: (s: String)Stream[String]
scala> g("x").tail.take(5).toList
res0: List[String] = List(#x#, ##x##, ###x###, ####x####, #####x#####)
今回の目的であれば、iterate メソッドを使った方が適しているとご指摘をいただきました。
List#iterate, Iterator#iterate, Stream#iterate を使った例です。
scala> def f(s: String) = s"#${s}#"
f: (s: String)String
scala> List.iterate(f("x"), 5)(f)
res0: List[String] = List(#x#, ##x##, ###x###, ####x####, #####x#####)
scala> Iterator.iterate("x")(f).drop(1).take(5).toList
res19: List[String] = List(#x#, ##x##, ###x###, ####x####, #####x#####)
scala> Stream.iterate("x")(f).tail.take(5).toList
res26: List[String] = List(#x#, ##x##, ###x###, ####x####, #####x#####)
こちらの方が素敵ですね。
Mac: Alfred 活用術
Alfred は、Mac を使うなら是非インストールしておきたいフリーソフト。
呼び出し用のキーバインド(私は option + SPACE に設定)を叩いた後、テキストを数文字打って
Enter を押すだけで様々なアプリケーション・OS機能を呼び出すことができる。
WEB のカスタムサーチは特に秀逸で、
することが可能だ。
有料の PowerPack を使えば、より生産性が上がるらしいので目下検討中。
Mac: KeySnail で option キーを メタキーとして使う方法
Firefox の (主にEmacsユーザ向けの) キーボード・ブラウジング環境構築プラグイン KeySnail を使っている。
これを Mac 環境で使用したところ、option キーをメタキーとして使おうとしてもうまくいかず、
メタキーを使うキーバインドが一切動作しない状況に陥った。
試行錯誤の末、正しく動作するようになったのでその方法を記録しておく。
デフォルト状態の KeySnail では、Altキー・Command キーの入力がメタキーとして解釈される。
keysnail/wiki/howto.ja.wiki at master · mooz/keysnail
Firefox では、Mac の optionキーが Altキーの働きと同等となるので、
optionキーを使ってメタキーのキーバインド (M-w, M-x など) ができると期待した。
(Command キーをメタキーとして扱うのは違和感があるのであまり使いたくない。)
ところが optionキーを使ったメタキー操作は全く動作しない。
OS X では (デフォルト状態では)、option キーを押しながら他のキーを入力すると特殊文字(å∫ç∂...)の入力が
行われる。
これらのキーを押下したときのイベントでは event.altKey が true にならないので
メタキーかどうかを判定する key.isMetaKey 関数を素通りしてしまう。
key.keyEventToString 関数をフックして、イベントを特定するための文字列を書き換えればそれなりに動くようだ。
charCode を取得し、特殊文字 かどうかを判定した上で "M-" で始まる文字列に置換する。
(例えば、∑ (charCode=8721) が入力されたらなら "M-w" に置き換える)
このような処理を行う option-as-meta というプラグインが既に存在していたので、それをそのまま利用する。
これで optionキーをメタキーとして使えるようになった。
optionキーではなく ESCキーをメタキーとして使用したいのであれば、「Metaplus」プラグインを利用するのが
最も確実な方法と思われる。
iTerm2 で Mac の option キーを Meta キーとして使う方法
iTerm -> Preferences -> Profiles -> Keys
設定としては、「Meta」よりも「+Esc」が推奨されるとのこと。
これで Emacs 周りの操作性が改善された。