feat: use hexo
This commit is contained in:
67
source/_posts/2013/install-julius-with-homebrew.md
Normal file
67
source/_posts/2013/install-julius-with-homebrew.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: OSXに音声解析エンジンJuliusを入れる with Homebrew
|
||||
date: 2013-07-07 09:00:00 +09:00
|
||||
redirect_from: "/blog/2013/07/07/install-julius-with-homebrew"
|
||||
---
|
||||
|
||||
Homebrew を使って macOS に音声解析エンジン Julius をインストールします。
|
||||
|
||||
# 前提
|
||||
|
||||
OS X 用のパッケージ管理ツール Homebrew がインストールされている必要がある。
|
||||
|
||||
インストール方法
|
||||
は[こちら](http://www.engineyard.co.jp/blog/2012/homebrew-os-xs-missing-package-manager/)を
|
||||
参照。
|
||||
|
||||
# インストール
|
||||
|
||||
デフォルトの Homebrew リポジトリに Julius は含まれていないので
|
||||
、[homebrew-nlp](https://github.com/uetchy/homebrew-nlp) を tap する。
|
||||
|
||||
```bash
|
||||
$ brew tap uetchy/nlp
|
||||
```
|
||||
|
||||
Tap し終わったら、`julius`と`julius-dictation-kit`をインストールする。
|
||||
|
||||
```bash
|
||||
$ brew install julius julius-dictation-kit
|
||||
```
|
||||
|
||||
これで Julius と Julius ディクテーションキットがインストールされた。
|
||||
|
||||
ディクテーションキットの場所は `brew --prefix julius-dictation-kit` コマンドで調
|
||||
べられる。
|
||||
|
||||
後は、上記の `brew --prefix` コマンドでディクテーションキット内の **main.jconf**
|
||||
と **am-gmm.jconf** のパスを調べて `julius` に渡すことで音声認識が出来るようにな
|
||||
る。
|
||||
|
||||
```bash
|
||||
$ julius \
|
||||
-C `brew --prefix julius-dictation-kit`/share/main.jconf \
|
||||
-C `brew --prefix julius-dictation-kit`/share/am-gmm.jconf
|
||||
```
|
||||
|
||||
上記のコマンドで Julius は GMM モードで待機状態になり、喋った内容をリアルタイム
|
||||
で音声認識してくれるようになる。
|
||||
|
||||
Julius をより精密な DNN モードで起動したい場合は以下のように、**am-gmm.jconf**
|
||||
を **am-dnn.jconf** に変更するだけだ。
|
||||
|
||||
```bash
|
||||
$ julius \
|
||||
-C `brew --prefix julius-dictation-kit`/share/main.jconf \
|
||||
-C `brew --prefix julius-dictation-kit`/share/am-dnn.jconf
|
||||
```
|
||||
|
||||
ディクテーションキットに関するドキュメントは下記のコマンドから参照可能だ。
|
||||
|
||||
```bash
|
||||
$ open `brew --prefix julius-dictation-kit`/share/doc
|
||||
```
|
||||
|
||||
### 実行中の様子
|
||||
|
||||

|
95
source/_posts/2013/osx-http-proxy.md
Normal file
95
source/_posts/2013/osx-http-proxy.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
title: OS Xのネットワーク環境に合わせてHTTP_PROXYを切り替えるシェルスクリプト
|
||||
date: 2013-11-05 09:00:00 +09:00
|
||||
redirect_from: "/blog/2013/11/05/osx-http-proxy"
|
||||
---
|
||||
|
||||

|
||||
|
||||
大学のネットワークに接続している時だけプロキシを設定したい時がある。
|
||||
|
||||
Mac のネットワーク環境は`networksetup -getcurrentlocation`コマンドで取得することが出来るので、
|
||||
|
||||
**.zshrc** 辺りに以下のシェルスクリプトを書いておけば Terminal で新しいタブを開いた時に自動でプロキシを設定してくれるはずである。
|
||||
|
||||
```bash
|
||||
proxy=proxy.hogehoge.ac.jp
|
||||
switch_trigger=大学
|
||||
|
||||
if [ "`networksetup -getcurrentlocation`" = "$switch_trigger" ]; then
|
||||
export HTTP_PROXY=$proxy
|
||||
export FTP_PROXY=$proxy
|
||||
...以下省略
|
||||
fi
|
||||
```
|
||||
|
||||
## Git のプロキシ設定も書き換えたい
|
||||
|
||||
Git は http_proxy を見てくれないのでリモートリポジトリに push 出来なくて困ることがあった。そこで http_proxy と一緒に Git のプロキシ設定も書き換えるようにしたい。
|
||||
|
||||
Git のプロキシは以下のコマンドで設定出来る。`--global`の代わりに`--system`を使っても良い。
|
||||
|
||||
```bash
|
||||
git config --global http.proxy $proxy
|
||||
git config --global https.proxy $proxy
|
||||
git config --global url."https://".insteadOf git://
|
||||
```
|
||||
|
||||
逆に `git config` から設定を削除したい場合は`git config --gobal --unset {item}`を使えば良い。
|
||||
|
||||
先ほどのコマンドと組み合わせることで最終的なコードは以下のようになる。
|
||||
|
||||
```bash:switch_proxy.sh
|
||||
proxy=proxy.hogehoge.ac.jp:80
|
||||
switch_trigger=大学
|
||||
|
||||
function set_proxy() {
|
||||
export http_proxy=$proxy
|
||||
export HTTP_PROXY=$proxy
|
||||
export ftp_proxy=$proxy
|
||||
export FTP_PROXY=$proxy
|
||||
export all_proxy=$proxy
|
||||
export ALL_PROXY=$proxy
|
||||
export https_proxy=$proxy
|
||||
export HTTPS_PROXY=$proxy
|
||||
|
||||
git config --global http.proxy $proxy
|
||||
git config --global https.proxy $proxy
|
||||
git config --global url."https://".insteadOf git://
|
||||
}
|
||||
|
||||
function unset_proxy() {
|
||||
unset http_proxy
|
||||
unset HTTP_PROXY
|
||||
unset ftp_proxy
|
||||
unset FTP_PROXY
|
||||
unset all_proxy
|
||||
unset ALL_PROXY
|
||||
unset https_proxy
|
||||
unset HTTPS_PROXY
|
||||
|
||||
git config --global --unset http.proxy
|
||||
git config --global --unset https.proxy
|
||||
git config --global --unset url."https://".insteadOf
|
||||
}
|
||||
|
||||
if [ "`networksetup -getcurrentlocation`" = "$switch_trigger" ]; then
|
||||
echo "Switch to proxy for university network"
|
||||
set_proxy
|
||||
else
|
||||
unset_proxy
|
||||
fi
|
||||
```
|
||||
|
||||
このコードを **.zshrc** に保存して適当なターミナルで新しいセッションを開くと、`switch_trigger`で指定されたネットワーク環境下にいる時だけプロキシを通すことが出来る。
|
||||
|
||||
既に開いているセッションに対してプロキシを適用する方法がわからなかった。
|
||||
|
||||
Workaround として、コードを **~/.switch_proxy** 辺りに置いて、
|
||||
|
||||
```bash:~/.zshrc
|
||||
alias nswitch=~/.switch_proxy
|
||||
|
||||
```
|
||||
と`.zshrc`に書いておくことで、`nswitch`とタイプしてプロキシを切り替えられるようになる。
|
||||
```
|
26
source/_posts/2013/qiita-alfred-workflow.md
Normal file
26
source/_posts/2013/qiita-alfred-workflow.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Qiitaでストックした記事をインクリメンタルサーチするAlfred 2 Workflow
|
||||
date: 2013-12-05 09:00:00 +09:00
|
||||
redirect_from: "/blog/2013/12/05/qiita-alfred-workflow"
|
||||
---
|
||||
|
||||
コードを書いている時に、ストックしておいた Qiita の記事を検索したくなるシーンが最近増えてきた気がする。
|
||||
|
||||
そこで、以前作った[Qiita の記事をインクリメンタルサーチする Alfred 2 Workflow](http://qiita.com/o_ame/items/f23e75bfc11e9e7b3a08)に、ストックした投稿を検索するコマンドを追加した。
|
||||
|
||||

|
||||
|
||||
> [Github リポジトリ](https://github.com/uetchy/alfred-qiita-workflow)から[ダウンロード](https://github.com/uetchy/alfred-qiita-workflow/archive/master.zip)
|
||||
|
||||
## 使い方
|
||||
|
||||
1. `qiita setup <username> <password>`で Qiita のアクセストークンを取得
|
||||
2. `qiita stocks <query>`でストックした記事の検索
|
||||
3. `qiita search <query>`で普通の検索
|
||||
|
||||
## まとめ
|
||||
|
||||
今度は Ruby で書きなおして日本語も受け付けるように修正したので、需要はともかく個人的にかなり使いやすくなった気がする。
|
||||
|
||||
~~なお、この Workflow は Ruby 2.0.x で動作するので必然的に OS X Mavericks が必要になってくる。~~
|
||||
**Ruby 1.9.x でも動作するように書きなおしたので古い OS X でも動くようになった。**
|
37
source/_posts/2014/2014-03-14-rails-assets-cli.md
Normal file
37
source/_posts/2014/2014-03-14-rails-assets-cli.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Rails Assetsのパッケージをコマンドラインから検索する
|
||||
date: 2014-03-14 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/03/14/rails-assets-cli"
|
||||
---
|
||||
|
||||
[Rails Assets](https://rails-assets.org/) は Bower パッケージを Bundler で管理出
|
||||
来る便利なサービスである。
|
||||
|
||||
ウェブサイトにアクセスして、Rails Assets に登録されているパッケージを検索するの
|
||||
は面倒なので CLI から検索したい。そのためには`gem search --source {url}`オプショ
|
||||
ンを利用したら良い。
|
||||
|
||||
```bash
|
||||
$ gem search {package-name} --source https://rails-assets.org | grep "^rails-assets-"
|
||||
```
|
||||
|
||||
`gem search` は source を指定しているにも関わらず RubyGems.org のパッケージも引
|
||||
っかかってしまうので Rails Assets のプレフィックスで抽出している。
|
||||
|
||||
### シェルスクリプト
|
||||
|
||||
```bash:rails-assets.sh
|
||||
#!/bin/sh
|
||||
# Usage: rails-assets [package-name] [-a]
|
||||
|
||||
gem search $1 $2 --source https://rails-assets.org | grep "^rails-assets-"
|
||||
```
|
||||
|
||||
もっと簡単に、シェル関数を定義することも出来る。
|
||||
|
||||
```bash:~/.zshrc rails-assets(){ gem search $1 $2 --source
|
||||
https://rails-assets.org | grep "^rails-assets-" }
|
||||
|
||||
```
|
||||
|
||||
```
|
87
source/_posts/2014/2014-05-30-dokku-with-dockland.md
Normal file
87
source/_posts/2014/2014-05-30-dokku-with-dockland.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Run dokku with Dockland
|
||||
date: 2014-05-30 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/05/30/dokku-with-dockland"
|
||||
---
|
||||
|
||||
ローカルから heroku-toolbelt ライクに dokku コマンドを叩く dockland gem をリリースした。
|
||||
|
||||
Github: [uetchy/dockland](https://github.com/uetchy/dockland)
|
||||
|
||||
## インストール方法
|
||||
|
||||
```bash
|
||||
gem install dockland
|
||||
```
|
||||
|
||||
## 使い方
|
||||
|
||||
### 普通のやり方
|
||||
|
||||
まずは普通に dokku コマンドを叩く。
|
||||
|
||||
`ssh -t dokku@example.com <command> <app-name> <options>`でリモートの dokku コマンドを直接叩ける。
|
||||
|
||||
```bash
|
||||
$ ssh -t dokku@example.com config:set sushi-app KEY1=VALUE
|
||||
-----> Setting config vars and restarting sushi-app
|
||||
KEY1: VALUE
|
||||
-----> Releasing sushi-app ...
|
||||
-----> Release complete!
|
||||
-----> Deploying sushi-app ...
|
||||
-----> Deploy complete!
|
||||
```
|
||||
|
||||
しかしこれではホスト名やアプリ名を毎回打ち込む羽目になって大変だ。
|
||||
|
||||
### dockland のやり方
|
||||
|
||||
dockland で同じことをやる。
|
||||
|
||||
```bash
|
||||
$ cd sushi-app # ローカルのプロジェクトリポジトリに移動
|
||||
|
||||
$ git config remote.dokku.url # プッシュ先を確認しておく
|
||||
dokku@example.com:sushi-app
|
||||
|
||||
$ dockland config:set KEY1=VALUE # 叩く時はコマンドとオプションだけ
|
||||
-----> Setting config vars and restarting sushi-app
|
||||
KEY1: VALUE
|
||||
-----> Releasing sushi-app ...
|
||||
-----> Release complete!
|
||||
-----> Deploying sushi-app ...
|
||||
-----> Deploy complete!
|
||||
|
||||
$ dockland config
|
||||
=== sushi-app config vars ===
|
||||
KEY1: VALUE
|
||||
```
|
||||
|
||||
このように dockland が `git config` をパースして必要な情報を自動で収集してくれるので、コマンドがシンプルになる。
|
||||
|
||||
ついでに、
|
||||
|
||||
```bash:.zshrc
|
||||
alias dokku='dockland'
|
||||
```
|
||||
|
||||
という具合に alias を張っておけば、まるでリモートで`dokku`を実行している感覚でローカルから`dokku`コマンドを触ることが出来る。
|
||||
|
||||
```bash
|
||||
$ cd rails-app
|
||||
$ dokku logs
|
||||
[2014-05-29 15:38:56] INFO WEBrick 1.3.1
|
||||
[2014-05-29 15:38:56] INFO ruby 2.1.2 (2014-05-08) [x86_64-linux]
|
||||
[2014-05-29 15:38:56] INFO WEBrick::HTTPServer#start: pid=10 port=5000
|
||||
〜〜〜
|
||||
```
|
||||
|
||||
## 結論
|
||||
|
||||
### 良い所
|
||||
|
||||
- リモートの dokku コマンドを叩きたい時はプロジェクトの Git リポジトリに入って dockland コマンドを叩くだけで良い
|
||||
|
||||
### 悪いところ
|
||||
|
||||
- 実装が綺麗じゃないすぎる
|
48
source/_posts/2014/2014-09-23-homebrew-osx-knp.md
Normal file
48
source/_posts/2014/2014-09-23-homebrew-osx-knp.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: HomebrewでmacOSに構文解析システムKNPを入れる
|
||||
date: 2014-09-23 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/09/23/homebrew-osx-knp"
|
||||
---
|
||||
|
||||
Homebrew で macOS に構文解析システム KNP をインストールします。
|
||||
|
||||
# 前提
|
||||
|
||||
OS X 用のパッケージ管理ツール Homebrew がインストールされている必要がある。
|
||||
|
||||
インストール方法は[こちら](http://www.engineyard.co.jp/blog/2012/homebrew-os-xs-missing-package-manager/)
|
||||
|
||||
# インストール
|
||||
|
||||
デフォルトの Homebrew リポジトリに KNP は含まれていないので [homebrew-nlp](https://github.com/uetchy/homebrew-nlp) を tap する。
|
||||
|
||||
```bash
|
||||
brew tap uetchy/nlp
|
||||
```
|
||||
|
||||
Tap し終わったら、`knp`をインストールする。knp が依存している形態素解析システム`juman`とデータベース`tinycdb`は Homebrew によって自動でインストールされる。その内の`juman`は上記の **uetchy/nlp** Tap によって提供されている。
|
||||
|
||||
```bash
|
||||
brew install knp
|
||||
```
|
||||
|
||||
固有表現解析を行いたい場合は **--with-crf++** オプションを付けてインストールする。このオプションを付けると、依存解決のために`crf++`も同時にインストールされる。
|
||||
|
||||
```bash
|
||||
brew install knp --with-crf++
|
||||
```
|
||||
|
||||
KNP のインストールにはありえないくらい時間が掛かる。
|
||||
|
||||
# チェック
|
||||
|
||||
インストールが終わったら動作チェックをする。
|
||||
|
||||
```bash
|
||||
$ juman < test.txt | knp
|
||||
# S-ID:1 KNP:4.11-CF1.1 DATE:2014/09/23 SCORE:-19.04210
|
||||
今日は──┐
|
||||
良い──┤
|
||||
天気です。
|
||||
EOS
|
||||
```
|
95
source/_posts/2014/2014-10-27-brew-cask-downloader.md
Normal file
95
source/_posts/2014/2014-10-27-brew-cask-downloader.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
title: homebrew-caskを単純なダウンローダーとして使う
|
||||
date: 2014-10-27 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/10/27/brew-cask-downloader"
|
||||
---
|
||||
|
||||

|
||||
|
||||
homebrew-cask を単純なダウンローダーとして使う。
|
||||
|
||||
# 理由
|
||||
|
||||
1. **pkg 形式** で配布されているアプリケーションはインストール時にオプションをカ
|
||||
スタマイズ出来ることが多い。
|
||||
2. にも関わらず`brew cask install`を使うと、それらのオプションを選べずにインスト
|
||||
ールされてしまい悲しい。
|
||||
3. そこで、`brew cask`で fetch までは自動化して、インストール自体は手動でやろう
|
||||
( スマートではないが。)
|
||||
|
||||
# 方法
|
||||
|
||||
## 準備
|
||||
|
||||
以下のようなシェルスクリプトを書いて、**/usr/local/bin/brew-smash** など任意の実
|
||||
行パスに配置し、`chmod +x /path/to/brew-smash`等で実行権限を与える。
|
||||
|
||||
```bash:/usr/local/bin/brew-smash
|
||||
#!/bin/sh
|
||||
# Usage: brew smash app-name
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
echo "Usage: brew smash app-name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "Casks" ] ; then
|
||||
KEEP_CLEAN=true
|
||||
else
|
||||
KEEP_CLEAN=false
|
||||
fi
|
||||
|
||||
HOMEBREW_CACHE=. brew cask fetch "$1"
|
||||
|
||||
if [ "$KEEP_CLEAN" = true ] ; then
|
||||
rm -r "Casks"
|
||||
fi
|
||||
```
|
||||
|
||||
もしくは直接ダウンロードしても良い。
|
||||
|
||||
```bash
|
||||
$ curl https://gist.githubusercontent.com/uetchy/eb625f922eff16eb404b/raw/brew-smash.sh -o /usr/local/bin/brew-smash
|
||||
$ chmod +x /usr/local/bin/brew-smash
|
||||
```
|
||||
|
||||
## 実際に使う
|
||||
|
||||
以下のように`brew smash`コマンドを叩く
|
||||
|
||||
```bash
|
||||
$ brew smash send-to-kindle
|
||||
==> Fetching resources for Cask send-to-kindle
|
||||
==> Downloading https://s3.amazonaws.com/sendtokindle/SendToKindleForMac-installer-v1.0.0.220.pkg
|
||||
######################################################################## 100.0%
|
||||
==> Success! Downloaded to -> ./send-to-kindle-1.0.0.220.pkg
|
||||
```
|
||||
|
||||
# シェルスクリプトの解説
|
||||
|
||||
難しいことはやってないが、`brew cask fetch`コマンドはキャッシュ先に**Casks**ディ
|
||||
レクトリを生成するので、それを除去している。また、元々カレントディレクトリに
|
||||
Casks という名前のディレクトリがある場合、それを削除してしまわないようにしている
|
||||
。
|
||||
|
||||
# 本当にやりたかったこと
|
||||
|
||||
こういう機能いれてくれ
|
||||
|
||||
```bash
|
||||
$ brew cask install virtualbox
|
||||
|
||||
==> Fetching resources for Cask virtualbox
|
||||
|
||||
==> Downloading http://download.virtualbox.org/virtualbox/4.3.18/VirtualBox-4.3.18-96516-OSX.dmg
|
||||
|
||||
###### ################################################################## 100.0%
|
||||
|
||||
==> Cask virtualbox has installation options
|
||||
|
||||
==> Do you need to install 'Oracle VM VirtualBox Command Line Utilities'? [y/n]
|
||||
|
||||
==> y
|
||||
|
||||
==> Success!
|
||||
```
|
56
source/_posts/2014/2014-12-03-sketch-plugin-stickygrid-ja.md
Normal file
56
source/_posts/2014/2014-12-03-sketch-plugin-stickygrid-ja.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Sketch 3 plugin 'StickyGrid'
|
||||
date: 2014-12-03 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/12/03/sketch-plugin-stickygrid-ja"
|
||||
---
|
||||
|
||||
選択したシェイプのポイントをグリッドに吸い付かせるプラグイン StickyGrid を作りました。
|
||||
|
||||

|
||||
|
||||
Vector ツールで軽くスケッチしてからこのプラグインを適用することで、簡単に幾何学的なオブジェクトを作ることが出来る。
|
||||
|
||||
# インストール
|
||||
|
||||
[リリースページ](https://github.com/uetchy/Sketch-StickyGrid/releases/latest)から zip アーカイブをダウンロードし、**StickyGrid.sketchplugin** をダブルクリックしてインストールする。
|
||||
|
||||
もし、より*CLI-way*がお好みであれば、以下のコマンドでもインストールすることが出来る。
|
||||
|
||||
```bash
|
||||
cd $HOME/Library/Application Support/com.bohemiancoding.sketch3/Plugins
|
||||
git clone https://github.com/uetchy/Sketch-StickyGrid.git
|
||||
```
|
||||
|
||||
# 使い方
|
||||
|
||||
吸い付かせたいシェイプを 1 つ、または複数選択して **`ctrl` + `⌘` + `G`** を押すと、パスがグリッドの交差点に吸い付く。
|
||||
|
||||
ショートカット以外にも、メニューから**Plugins > Sketch-StickyGrid > Snap to Grid**を選んでも良い。
|
||||
|
||||
シェイプはもちろん、グルーピングされたシェイプも、逆にシェイプポイントだけでも吸い付く。
|
||||
|
||||
# プラグインの開発にあたって
|
||||
|
||||
## プラグインのデバッグ
|
||||
|
||||
デバッギングには[Sketch-DevTools](https://github.com/turbobabr/sketch-devtools)を使っていましたが、最新版の Sketch では使えなくなってしまった。
|
||||
|
||||
その代わりに Mac 標準アプリの **Console.app** を使う方法が公式デベロッパーサイトの記事 [Debugging - Sketch Developer](http://developer.sketchapp.com/code-examples/debugging/) で紹介されている。
|
||||
|
||||
スクリプト内で`log`関数を呼び出すと、Console.app にログが出力される。
|
||||
|
||||
```js
|
||||
log(context.document.gridSize)
|
||||
```
|
||||
|
||||
## ドキュメントの情報源
|
||||
|
||||
ドキュメントは公式デベロッパーサイト [Sketch Developer](http://developer.sketchapp.com) があるものの、パス編集に関するドキュメントは全くなかった。
|
||||
|
||||
そこで、[class-dump](http://stevenygard.com/projects/class-dump/) を使って Sketch.app のヘッダーファイルを抽出し、ひたすら **目 grep** をしてシェイプ操作とグリッドに関する API を探し出し、プラグインの実装に役立てた。
|
||||
|
||||
また、先人によって公開されている数多の Sketch プラグインのソースを見ることも、開発の助けになった。
|
||||
|
||||
# 結論
|
||||
|
||||
苦行僧じみた Sketch プラグインの開発には **class-dump** と **Console.app** が必携。
|
56
source/_posts/2014/2014-12-03-sketch-plugin-stickygrid.md
Normal file
56
source/_posts/2014/2014-12-03-sketch-plugin-stickygrid.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Sketch 3 plugin 'StickyGrid'
|
||||
date: 2014-12-03 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/12/03/sketch-plugin-stickygrid"
|
||||
---
|
||||
|
||||
For practicing Sketch plugin development, I created **StickyGrid** to let shape points sticked with grids.
|
||||
|
||||

|
||||
|
||||
Draw something in rough and apply this plugin then you'll get geometric shapes at ease.
|
||||
|
||||
# How to install
|
||||
|
||||
From [GitHub releases](https://github.com/uetchy/Sketch-StickyGrid/releases/latest), Download a zipped archive then unarchive it then double click **StickyGrid.sketchplugin** so you are prepared for using StickyGrid.
|
||||
|
||||
Loving _CLI-way_ than anything, You also want to run those commands to get the same thing.
|
||||
|
||||
```bash
|
||||
cd $HOME/Library/Application Support/com.bohemiancoding.sketch3/Plugins
|
||||
git clone https://github.com/uetchy/Sketch-StickyGrid.git
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
At first, selecting **`ctrl` + `⌘` + `G`** を押すと、パスがグリッドの交差点に吸い付く。
|
||||
|
||||
ショートカット以外にも、メニューから**Plugins > Sketch-StickyGrid > Snap to Grid**を選んでも良い。
|
||||
|
||||
シェイプはもちろん、グルーピングされたシェイプも、逆にシェイプポイントだけでも吸い付く。
|
||||
|
||||
# プラグインの開発にあたって
|
||||
|
||||
## プラグインのデバッグ
|
||||
|
||||
デバッギングには[Sketch-DevTools](https://github.com/turbobabr/sketch-devtools)を使っていましたが、最新版の Sketch では使えなくなってしまった。
|
||||
|
||||
その代わりに Mac 標準アプリの **Console.app** を使う方法が公式デベロッパーサイトの記事 [Debugging - Sketch Developer](http://developer.sketchapp.com/code-examples/debugging/) で紹介されている。
|
||||
|
||||
スクリプト内で`log`関数を呼び出すと、Console.app にログが出力される。
|
||||
|
||||
```js
|
||||
log(context.document.gridSize)
|
||||
```
|
||||
|
||||
## ドキュメントの情報源
|
||||
|
||||
ドキュメントは公式デベロッパーサイト [Sketch Developer](http://developer.sketchapp.com) があるものの、パス編集に関するドキュメントは全くなかった。
|
||||
|
||||
そこで、[class-dump](http://stevenygard.com/projects/class-dump/) を使って Sketch.app のヘッダーファイルを抽出し、ひたすら**目 grep**をしてシェイプ操作とグリッドに関する API を探し出し、プラグインの実装に役立てた。
|
||||
|
||||
また、先人によって公開されている数多の Sketch プラグインのソースを見ることも、開発の助けになった。
|
||||
|
||||
# 結論
|
||||
|
||||
苦行僧じみた Sketch プラグインの開発には**class-dump**と**Console.app**が必携。
|
176
source/_posts/2014/2014-12-16-myo-armband.md
Normal file
176
source/_posts/2014/2014-12-16-myo-armband.md
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Take control of Chrome with Myo Armband
|
||||
date: 2014-12-16 09:00:00 +09:00
|
||||
redirect_from: "/blog/2014/12/16/myo-armband"
|
||||
---
|
||||
|
||||
Thalmic Labs の MYO アームバンドが届いたので Google Chrome をマイノリティ・リポートっぽいジェスチャーで操作する Myo Scripts を書いてみる。
|
||||
|
||||
### 主な情報源
|
||||
|
||||
- <https://developer.thalmic.com/start/>
|
||||
- <https://www.thalmic.com/blog/tag/myo-scripting-basics/>
|
||||
- <https://developer.thalmic.com/docs/api_reference/platform/script-tutorial.html>
|
||||
|
||||
# 基本
|
||||
|
||||
Lua で記述し、拡張子は**.myo**を使う。
|
||||
|
||||
作成したスクリプトは Myo Connect を経由してアームバンドとやりとりをすることになる。
|
||||
|
||||
> デバッグコマンドとして`myo.debug(obj)`が用意されている。
|
||||
|
||||
## scriptId
|
||||
|
||||
スクリプトを識別するための`scriptId`は必ず書かなければならない。
|
||||
|
||||
```lua
|
||||
scriptId = 'co.randompaper.myo.chrome'
|
||||
```
|
||||
|
||||
## onForegroundWindowChange(app, title)
|
||||
|
||||
```lua
|
||||
function onForegroundWindowChange(app, title)
|
||||
return app == "com.google.Chrome"
|
||||
end
|
||||
```
|
||||
|
||||
onForegroundWindowChange の返り値が**true**の場合、スクリプトをアクティブにする。つまり上のように書けば Google Chrome のウィンドウが最前面に出ている時だけスクリプトを有効化させることが出来る。
|
||||
|
||||
いかなる状況でもジェスチャーをハンドルしたい場合は以下のように書く。
|
||||
|
||||
```lua
|
||||
function onForegroundWindowChange(app, title)
|
||||
return true
|
||||
end
|
||||
```
|
||||
|
||||
実際には、**親指と中指でダブルタップ** するジェスチャーを検知した後に、全ての Myo Scripts の onForegroundWindowChange を呼び出している。そして true が返ってきたスクリプトのみを実行している。
|
||||
|
||||
アクティブになったスクリプトは一定時間が経過してアームバンドがロックされるまでイベントハンドラーが呼ばれ続ける。
|
||||
|
||||
## onPoseEdge(pose, edge)
|
||||
|
||||
スクリプトがアクティブになっている間に行われたジェスチャーをハンドルするメソッド。
|
||||
|
||||
```lua
|
||||
function onPoseEdge(pose, edge)
|
||||
if pose == 'fist' and edge == 'on' then
|
||||
myo.debug("グー")
|
||||
elseif pose == 'fist' and edge == 'off' then
|
||||
myo.debug("グーじゃなくなった")
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### pose の種類
|
||||
|
||||
| pose | 意味 |
|
||||
| ------------- | ------------------------ |
|
||||
| rest | 安静時 |
|
||||
| fist | 握り拳 |
|
||||
| fingersSpread | 手を開く |
|
||||
| waveIn | 手首を手前に曲げる |
|
||||
| waveOut | 手首を手前とは逆に曲げる |
|
||||
| doubleTap | 中指と親指でダブルタップ |
|
||||
| unknown | 判別不能 |
|
||||
|
||||
## onPeriodic()
|
||||
|
||||
```lua
|
||||
function onPeriodic()
|
||||
roll = myo.getRoll()
|
||||
myo.debug(roll)
|
||||
end
|
||||
```
|
||||
|
||||
onPeriodic はスクリプトがアクティブな間ずっと呼ばれ続ける。常にアームバンドのジャイロ情報を取得してなんやかんやしたい時に使う。
|
||||
|
||||
# 実装
|
||||
|
||||
以上のハンドラーを駆使し作ってみる。
|
||||
今回のように Google Chrome のスクロール操作をアームバンドのジェスチャーでやりたい場合、**onPeriodic** で`myo.getRoll()`メソッドを呼び出せば手首の回転する角度を取得出来るわけである。しかし、そのまま**onPeriodic**上にスクロールを行うコードを続けて書くと常にアームバンドの傾き具合でスクロールされてしまい困る。
|
||||
|
||||
そこで、「握り拳を握っている間だけ手首の傾きによってウェブページをスクロールさせる」ようにする。
|
||||
|
||||
## 握り拳を握っている間だけ手首の傾きによってウェブページをスクロールさせる
|
||||
|
||||
初めにグローバルで `enableScroll` 変数を宣言し、false で初期化する。
|
||||
|
||||
```lua
|
||||
enableScroll = false
|
||||
```
|
||||
|
||||
そして、onPoseEdge に握り拳が握られると enableScroll を true に、戻ると false にするコードを書く。
|
||||
|
||||
```lua
|
||||
function onPoseEdge(pose, edge)
|
||||
if pose == 'fist' and edge == 'on' then
|
||||
enableScroll = true
|
||||
elseif pose == 'fist' and edge == 'off' then
|
||||
enableScroll = false
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
最後に onPeriodic で手首の角度を取得してキーボードの ↑ か ↓ を連打するコードを書く。
|
||||
|
||||
```lua
|
||||
function onPeriodic()
|
||||
if enableScroll then
|
||||
roll = myo.getRoll()
|
||||
|
||||
key = ''
|
||||
|
||||
if roll < -0.05 then
|
||||
key = 'up_arrow'
|
||||
elseif roll > 0.05 then
|
||||
key = 'down_arrow'
|
||||
end
|
||||
|
||||
if key ~= '' then
|
||||
myo.keyboard(key, 'press')
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
実際にこのスクリプトを動かしてみると上手くスクロールしない。myo.getRoll()で取得した角度は絶対的な角度だからだ。握り拳が作られた瞬間の角度を 0 として扱った方がプログラムの見通しも良くなる。
|
||||
|
||||
そこで新たに initRoll 変数をグローバルで宣言する。そして onPoseEdge を以下のように修正する。
|
||||
|
||||
```lua
|
||||
function onPoseEdge(pose, edge)
|
||||
if pose == 'fist' and edge == 'on' then
|
||||
initRoll = myo.getRoll()
|
||||
enableScroll = true
|
||||
elseif pose == 'fist' and edge == 'off' then
|
||||
enableScroll = false
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
続けて onPeriodic の
|
||||
|
||||
```lua
|
||||
roll = myo.getRoll()
|
||||
```
|
||||
|
||||
を、
|
||||
|
||||
```lua
|
||||
roll = myo.getRoll() - initRoll
|
||||
```
|
||||
|
||||
に修正する。
|
||||
|
||||
これで、絶対角度を握り拳が握られた瞬間の手首の角度を 0 とする相対角度を取得出来る。
|
||||
|
||||
実際に動くスクリプトを Github で[公開している](https://github.com/uetchy/myo-scripts)。
|
||||
|
||||
### 番外編
|
||||
|
||||
Myo C++ SDK を使ってアイアンマンみたいなジェスチャーでレーザーガンを撃った気分になれるアプリを作った。
|
||||
|
||||
[uetchy/myo-gun](https://github.com/uetchy/myo-gun)
|
34
source/_posts/2015/2015-02-26-cabocha-on-rubygems.md
Normal file
34
source/_posts/2015/2015-02-26-cabocha-on-rubygems.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: CaboCha on RubyGems
|
||||
date: 2015-02-26 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/02/26/cabocha-on-rubygems"
|
||||
---
|
||||
|
||||
日本語係り受け解析器 CaboCha の Ruby バインディング [cabocha-ruby](https://github.com/uetchy/cabocha-ruby) をリリースした。とは言っても [公式](https://code.google.com/p/cabocha/) の SWIG バインディングをベースにしたものだ。
|
||||
|
||||
## 導入
|
||||
|
||||
```bash
|
||||
gem install cabocha
|
||||
```
|
||||
|
||||
でインストール出来る。
|
||||
|
||||
> cabocha-ruby をインストールする前に、CaboCha を`brew install cabocha`かなんかでインストールしておかないと make が失敗するので注意すること。
|
||||
|
||||
## 使う
|
||||
|
||||
require する時は`require "cabocha"`と`require "CaboCha"`、どちらを使っても正しい。
|
||||
|
||||
```ruby
|
||||
require "cabocha"
|
||||
|
||||
parser = CaboCha::Parser.new
|
||||
tree = parser.parse("太郎は次郎に本を貸した")
|
||||
|
||||
p tree
|
||||
```
|
||||
|
||||
これまでソースコードをダウンロードし`ruby extconf.rb && make install`していたのが、これからは`gem install cabocha`で済むようになる。
|
||||
|
||||
バグを見つけたら [Pull request](https://github.com/uetchy/cabocha-ruby/pulls) を送ってほしい。
|
108
source/_posts/2015/2015-02-26-gulp-decomposer-bower-import.md
Normal file
108
source/_posts/2015/2015-02-26-gulp-decomposer-bower-import.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: 'gulp + decomposer: Best way to sassy-@import bower components'
|
||||
date: 2015-02-26 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/02/26/gulp-decomposer-bower-import"
|
||||
---
|
||||
|
||||
gulp + Browserify(+ debowerify)という構成で Web サイトを作っていると、SASS にも debowerify 相当のものが欲しくなってくる。
|
||||
|
||||
ちなみに、**debowerify** というのは、
|
||||
|
||||
```js
|
||||
var Velocity = require('velocity')
|
||||
```
|
||||
|
||||
という JavaScript を、
|
||||
|
||||
```js
|
||||
var Velocity = require('./../../bower_components/velocity/velocity.js')
|
||||
```
|
||||
|
||||
という風に、bower_components 内のパスに解決してくれる Browserify transform だ。
|
||||
欲しいのはこれの SASS 版。
|
||||
|
||||
「あったらいいのにな〜」と思うようなライブラリは Github で検索すれば必ず出てくる。はずだったが、無かった。
|
||||
|
||||
そこで [decomposer](https://www.npmjs.com/package/decomposer) という gulp プラグインを作った。
|
||||
|
||||
# 使い方
|
||||
|
||||
まずは`npm install --save-dev gulp gulp-sass decomposer`で必要なものをインストールしておく。既存のプロジェクトに追加するなら decomposer だけでいい。
|
||||
|
||||
**gulpfile.js** はこのように定義しておく。
|
||||
|
||||
```js
|
||||
var gulp = require('gulp')
|
||||
var sass = require('gulp-sass')
|
||||
var decomposer = require('decomposer')
|
||||
|
||||
gulp.task('styles', function() {
|
||||
gulp
|
||||
.src('src/styles/**/*.sass')
|
||||
.pipe(decomposer())
|
||||
.pipe(sass({ indentedSyntax: true }))
|
||||
.pipe(gulp.dest('dist/css'))
|
||||
})
|
||||
```
|
||||
|
||||
ポイントは`sass` **よりも前** に`decomposer`を挟むこと。なぜなら、外部から@import した mix-ins や変数は SASS コンパイル時に解決されるからだ。`sass`よりも後に置くと、SASS が@import を解決出来ずにエラーが発生する。
|
||||
|
||||
続けて SASS を書こう。
|
||||
|
||||
```scss
|
||||
@import normalize.sass @import styles/font body font-family: $ff-gothic;
|
||||
```
|
||||
|
||||
> `$ff-gothic`は [uetchy/styles](https://github.com/uetchy/styles) の _font.sass_ で定義されている font-family だ。
|
||||
|
||||
最後に Bower を使って必要なアセットをインストールする。
|
||||
|
||||
```bash
|
||||
bower i --save normalize.sass
|
||||
bower i --save uetchy/styles
|
||||
```
|
||||
|
||||
これで完成。後は`gulp styles`を実行するだけだ。
|
||||
|
||||
# ファイルパス解決時のポイント
|
||||
|
||||
decomposer は Bower モジュールに入っている任意のファイルを指定して@import することが出来る。
|
||||
記法はこのようになる。
|
||||
|
||||
```scss
|
||||
@import [Bowerモジュール名]/[ファイル名];
|
||||
```
|
||||
|
||||
例えば、よく使うスタイルをまとめた [uetchy/styles](https://github.com/uetchy/styles) の**\_font.sass** を@import するなら、
|
||||
|
||||
```scss
|
||||
@import styles/font;
|
||||
```
|
||||
|
||||
と書ける。
|
||||
ここでもし`@import styles`と、ファイル名を省略して書くとどうなるのだろうか? コンパイルに失敗する? そんなことはない。
|
||||
|
||||
モジュール名だけを書くと、decomposer は**bower.json**に書かれている main ファイルを見つけ出して、それを@import してくれるのだ。
|
||||
|
||||
もし main ファイルが複数指定されていたら、`index.sass`や`[モジュール名].sass`、または**main っぽい名前** を持つファイルを@import する。
|
||||
|
||||
つまり、
|
||||
|
||||
```scss
|
||||
@import normalize.sass;
|
||||
```
|
||||
|
||||
と書けば、
|
||||
|
||||
```scss
|
||||
@import ../bower_components/normalize.sass/normalize.sass;
|
||||
```
|
||||
|
||||
という風に解決される。
|
||||
|
||||
# まとめ
|
||||
|
||||
これでスタイルの@import をすっきり書けるようになった。
|
||||
とはいえ、component 対応や Plain CSS のインライン展開や.less 対応など、追加したい機能は色々ある。
|
||||
|
||||
もし Contribution に興味があるなら、[Github リポジトリ](https://github.com/uetchy/decomposer)をフォークしてほしい。
|
60
source/_posts/2015/2015-03-10-create-icns-from-sketch.md
Normal file
60
source/_posts/2015/2015-03-10-create-icns-from-sketch.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Create .icns from .sketch
|
||||
date: 2015-03-10 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/03/10/create-icns-from-sketch"
|
||||
---
|
||||
|
||||

|
||||
|
||||
Gulp をつかって .sketch から .icns を生成するために、[gulp-sketch](https://github.com/cognitom/gulp-sketch) の出力結果を.icns へ変換する [gulp-iconutil](https://github.com/uetchy/gulp-iconutil) というプラグインを作りました。
|
||||
|
||||
# はじめに
|
||||
|
||||
.icns を作るには様々なサイズのアイコン画像を格納した **iconset** をつくり、それを `iconutil` に渡します。ここで面倒なのは iconset です。
|
||||
|
||||
iconset の作成には 16×16 ... 512×512 の 6 種類のサイズのアイコンと、さらにそれぞれの Retina 用のアイコンも加えて、計 12 種類ものサイズの画像が必要です。
|
||||
|
||||
唯一の救いは、最大サイズの画像だけ用意しておけば、不足している小さいサイズの画像は`iconutil`が自動で生成するということでしょう。
|
||||
|
||||
今回作った [gulp-iconutil](https://www.npmjs.com/package/gulp-iconutil) は、Gulp からこの`iconutil`コマンドへの橋渡しをしてくれます。
|
||||
|
||||
# アイコンをデザインする
|
||||
|
||||
Sketch 上に 512×512 サイズのアートボードを作成し、アプリのアイコンをデザインします。
|
||||
|
||||

|
||||
|
||||
> Dock 上でアイコンの見栄えをチェックするために、[sketch-dockpreview](https://github.com/fnky/sketch-dockpreview)を使っています。これは本当に便利なプラグインです。
|
||||
|
||||
# .sketch から .icns へ
|
||||
|
||||
.sketch から iconset を作成するために、[gulp-sketch](https://github.com/cognitom/gulp-sketch) を、そして iconset から .icns へ変換するために今回作った [gulp-iconutil](https://www.npmjs.com/package/gulp-iconutil) を使います。npm からインストール出来ます。
|
||||
|
||||
Gulp タスクは以下のように書きます。
|
||||
|
||||
```coffee
|
||||
gulp = require 'gulp'
|
||||
sketch = require 'gulp-sketch'
|
||||
iconutil = require 'gulp-iconutil'
|
||||
|
||||
gulp.task 'icons', ->
|
||||
gulp.src 'icons/sketch/*.sketch'
|
||||
.pipe sketch
|
||||
export: 'artboards'
|
||||
formats: 'png'
|
||||
scales: '1.0,2.0'
|
||||
.pipe iconutil('app.icns')
|
||||
.pipe gulp.dest 'icons/'
|
||||
```
|
||||
|
||||
icons タスクを実行すると、icons フォルダの中に**app.icns**が生成されます。
|
||||
|
||||

|
||||
|
||||
Electron アプリ開発者はこのアイコンファイルを OS X 向けビルドにそのまま使えます。
|
||||
|
||||
# まとめ
|
||||
|
||||
デザインデータのポストプロセスの自動化が Gulp と sketchtool のおかげでやりやすくなりました。
|
||||
|
||||
[gulp-iconutil](https://github.com/uetchy/gulp-iconutil) は今週リリースしたばかりで若干不安定なので、もしバグを見つけたら[Issue](https://github.com/uetchy/gulp-iconutil/issues)を作るか、[PR](https://github.com/uetchy/gulp-iconutil/pulls)を投げてください!
|
15
source/_posts/2015/2015-07-05-hugo-paper.md
Normal file
15
source/_posts/2015/2015-07-05-hugo-paper.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: 'Hugo Paper: well-simplified theme for Hugo'
|
||||
date: 2015-07-05 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/07/05/hugo-paper"
|
||||
---
|
||||
|
||||
When I created my blog, there are no well simplified [Hugo](http://gohugo.io) theme around the world. I need to a theme that just don't interrupt reading experience. [Hugo Paper](https://github.com/uetchy/hugo-paper) is made for that.
|
||||
|
||||
# How to integrate
|
||||
|
||||
Just run following oneliner and you will be ready to start using Hugo Paper.
|
||||
|
||||
```bash
|
||||
$ git submodule add https://github.com/uetchy/hugo-paper.git themes/hugo-paper && git submodule update
|
||||
```
|
41
source/_posts/2015/2015-09-07-alfred-qiita-workflow-in-go.md
Normal file
41
source/_posts/2015/2015-09-07-alfred-qiita-workflow-in-go.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Alfred Qiita Workflow in Go
|
||||
date: 2015-09-07 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/09/07/alfred-qiita-workflow-in-go"
|
||||
---
|
||||
|
||||

|
||||
|
||||
Ruby で書かれている [Alfred Qiita Workflow](https://github.com/uetchy/alfred-qiita-workflow) を[バグ修正](https://github.com/uetchy/alfred-qiita-workflow/issues/3)のついでに Go で書き直した。
|
||||
|
||||
Qiita API v2 に対応し、ユーザー名とパスワードの代わりとして、[Personal Access Token](https://qiita.com/settings/tokens/new)を使い始めた。
|
||||
|
||||
これで、ストックした記事や自分で書いた記事を検索することがより気軽に出来る。
|
||||
|
||||
Alfred に返却する XML の生成には[go-alfred](https://github.com/pascalw/go-alfred)というライブラリを利用した。
|
||||
|
||||
## go-qiita
|
||||
|
||||
Alfred Qiita Workflow の API クライアント部分を切り出して [go-qiita](https://github.com/uetchy/go-qiita) としてリリースした。Workflow で必要だった部分しか実装してないが、記事の検索など基本的なことは出来る。
|
||||
|
||||
設計は Google の [go-github](https://github.com/google/go-github) を参考にしている。クライアントの初期化時に、以下のように http.Client 互換の Interface を渡してやれば、それを経由して通信するようになっている。
|
||||
|
||||
```go
|
||||
// Personal Access Tokenを使ったOAuth2クライアントを作る
|
||||
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: "personal access token"})
|
||||
tc := oauth2.NewClient(oauth2.NoContext, ts)
|
||||
|
||||
// OAuth2クライアントをgo-qiitaに引き渡す
|
||||
client := qiita.NewClient(tc)
|
||||
|
||||
// 今までに書いた記事を取得
|
||||
items, _, _ := client.AuthenticatedUser.Items()
|
||||
```
|
||||
|
||||
このようにすることで、API クライアントは認証系を気にせず API サーバーとのやりとりを考えることが出来る。このやり方はかなりスマートだと思うのでもっと流行って欲しい。
|
||||
|
||||
ちなみに認証をしない場合は`NewClient()`に`nil`を渡せばよい。
|
||||
|
||||
```go
|
||||
client := qiita.NewClient(nil)
|
||||
```
|
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Wallpapers for simple desktop
|
||||
date: 2015-12-07 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/12/07/wallpaper-for-simple-desktop"
|
||||
---
|
||||
|
||||

|
||||
|
||||
[There are](/wallpaper) desktop wallpapers by [Sketch](https://www.sketchapp.com/).
|
||||
|
||||
You can download all of them and use it for personal use.
|
53
source/_posts/2015/2015-12-16-atom-package-diff.md
Normal file
53
source/_posts/2015/2015-12-16-atom-package-diff.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Gluing Installed Atom Packages and apm Stars Together
|
||||
date: 2015-12-16 09:00:00 +09:00
|
||||
redirect_from: "/blog/2015/12/16/atom-package-diff"
|
||||
---
|
||||
|
||||
Atom にインストールしているパッケージと[Atom.io](https://atom.io/packages)上のスターを同期する CLI ツール [Atom Package Diff](https://www.npmjs.com/package/atom-package-diff) を公開した。
|
||||
|
||||
# 導入
|
||||
|
||||
npm 経由でインストールする。
|
||||
|
||||
```bash
|
||||
$ npm install -g atom-package-diff
|
||||
```
|
||||
|
||||
# インストール済みパッケージとスターの diff
|
||||
|
||||
`apd status`コマンドでインストール済みパッケージとスターしているパッケージの diff を見ることができる。
|
||||
|
||||
```bash
|
||||
$ apd status
|
||||
36 packages installed
|
||||
30 packages starred
|
||||
|
||||
# Packages only in apm
|
||||
project-manager react
|
||||
|
||||
# Packages only in local machine
|
||||
Sublime-Style-Column-Selection atom-fuzzy-grep douglas language-babel language-ini language-swift term3 travis-ci-status
|
||||
```
|
||||
|
||||
# 同期
|
||||
|
||||
`apd sync --local`を実行すると、インストール済みパッケージを全部`apm star`し、それ以外を`apm unstar`する。
|
||||
|
||||
`apd sync --remote`でその逆の処理を行う。つまり、スターされているパッケージを全部インストールし、それ以外をアンインストールする。
|
||||
|
||||
```bash
|
||||
$ apd sync --local
|
||||
Unstaring ... project-manager
|
||||
Unstaring ... react
|
||||
Staring ... Sublime-Style-Column-Selection
|
||||
Staring ... atom-fuzzy-grep
|
||||
Staring ... douglas
|
||||
Staring ... language-babel
|
||||
Staring ... language-ini
|
||||
Staring ... language-swift
|
||||
Staring ... term3
|
||||
Staring ... travis-ci-status
|
||||
```
|
||||
|
||||
ソースコードは [Github](uetchy/atom-package-diff) で公開している。
|
155
source/_posts/2016/2016-01-24-essentials-for-new-macbook.md
Normal file
155
source/_posts/2016/2016-01-24-essentials-for-new-macbook.md
Normal file
@@ -0,0 +1,155 @@
|
||||
---
|
||||
title: Essentials for New MacBook
|
||||
date: 2016-01-24 09:00:00 +09:00
|
||||
redirect_from: "/blog/2016/01/24/essentials-for-new-macbook"
|
||||
---
|
||||
|
||||

|
||||
|
||||
新しい MacBook を買ったので、普段使っているアプリの整理も兼ねて、幾つかポリシーを決めてセットアップすることにしました。
|
||||
|
||||
## 1. シンプル
|
||||
|
||||
インストールするアプリは最低限必要なものにしました。コンパクトにまとめると気持ちがいいですし、常駐するアプリを増やしてもバッテリーに悪いです。
|
||||
|
||||
## 2. デフォルト重視
|
||||
|
||||
なるべくデフォルトで用意されているものを使います。カスタマイズも OS X 標準機能の範囲内で行います。
|
||||
|
||||
# 使っているアプリ
|
||||
|
||||
## [Homebrew](http://brew.sh)
|
||||
|
||||
OS X 向けのパッケージマネージャーです。
|
||||
|
||||
## Atom
|
||||
|
||||
Sublime Text も良いのですが、やはりターミナルや Git が一画面で使えるのは MacBook のフルスクリーンアプリに合っています。
|
||||
|
||||
## LaunchControl
|
||||
|
||||
`launchctl`の GUI 版です。変な Agent が差し込まれていることがあるので、たまにチェックしています。
|
||||
|
||||
## [Papers](http://papersapp.com/mac/)
|
||||
|
||||
論文を管理するためのアプリです。これがベストと言えるわけではないですが、数ある中では一番使えます。
|
||||
|
||||
## [Typora](http://www.typora.io)
|
||||
|
||||

|
||||
|
||||
これまで様々な Markdown エディタを試してきましたが、どれもエディタとプレビューが分離している UI を採用しており、それが私には不合理に思えて仕方がありませんでした。
|
||||
|
||||
Typora は入力した記法がリアルタイムに反映されるので直感的に文章を書くことが出来ます。 加えて Github Flavored Markdown、MathJax、Mermaid などのシーケンス図に対応しており、何気にニッチな需要を攻めている、小粋なアプリです。
|
||||
|
||||
## [⌘ 英かな](https://ei-kana.appspot.com)
|
||||
|
||||
US 配列キーボードの左右 ⌘ を英かなに割り振ることが出来るアプリです。実装がシンプルで軽量です。アイコンをデザインして Pull-request を送ったらマージしてくれました。
|
||||
|
||||
## [Paw](https://paw.cloud/)
|
||||
|
||||
Web API を作りたい時に使えます。無くても困りませんが、あると便利です。
|
||||
|
||||
## [Dash](https://kapeli.com/dash)
|
||||
|
||||
API ドキュメントを素早く検索出来るアプリです。
|
||||
|
||||
無いと困るようなアプリではありませんが、遅い Wi-Fi に繋いでいる場合でも素早くドキュメントを閲覧できるので外で作業するならあると便利でしょう。
|
||||
|
||||
## [Tower](http://www.git-tower.com)
|
||||
|
||||
Git の GUI クライアントです。
|
||||
|
||||
> より軽量なクライアントの[GitUp](http://gitup.co)も気になっています。
|
||||
|
||||
## [Google Chrome](https://www.google.com/chrome/browser/desktop/index.html)
|
||||
|
||||
普段は Safari を使っていますが、Chrome でしか動かない前時代的な Web サービスを使う時や、Web アプリケーションをデバッグする時のために入れました。
|
||||
|
||||
## Xcode
|
||||
|
||||
iOS アプリを作るときに必要なので入れました。
|
||||
|
||||
gcc や Git など、基本的なビルドツールチェインが必要な場合、Xcode をインストールする代わりに `sudo xcode-select —install` でそれらを導入できます。
|
||||
|
||||
## [ForkLift 3](http://www.binarynights.com/forklift/)
|
||||
|
||||
SFTP サーバーや S3 に接続するためのアプリです。接続したサーバーのディレクトリを Finder にマウントする機能があるので、ローカルで普通にファイルを扱う感覚でリモートのファイルをやりとり出来ます。Transmit から乗り換えました。
|
||||
|
||||
## [Kaleidoscope](http://www.kaleidoscopeapp.com)
|
||||
|
||||
さすがに標準の FileMerge だと機能不足が否めないので。
|
||||
|
||||
## [Sketch](https://www.sketchapp.com)
|
||||
|
||||
Bohemian Coding が開発しているベクターデザインツールです。アイコンや UI をデザインする時に使っています。
|
||||
|
||||
## RightFont
|
||||
|
||||
フォント管理アプリです。FontCase、FontExplorer X Pro などを使ってきましたが、今はこれに落ち着いています。Google Fonts や TypeKit に対応しており、またアイコンフォントを一覧できる機能が便利です。
|
||||
|
||||
## Adobe Creative Cloud
|
||||
|
||||
Affinity シリーズに乗り換えたので、今は Illustrator と TypeKit を使うために入れています。
|
||||
|
||||
## [Dropbox](https://www.dropbox.com)
|
||||
|
||||
ファイルの同期が出来ます。iCloud Drive も検討しましたが、削除したデータの復活に手間取るので見送りました。
|
||||
|
||||
## 1Password
|
||||
|
||||
パスワードマネージャーです。2 要素認証のトークンもまとめて管理できます。
|
||||
|
||||
## f.lux
|
||||
|
||||
iOS の Night Shift を macOS に持ってきたようなアプリです。長時間の作業でも目が痛くなりません。
|
||||
|
||||
## Reeder
|
||||
|
||||
RSS リーダーです。Feedly Web 版でも良いですが、Readability 機能が便利なので使っています。
|
||||
|
||||
## [AppCleaner](https://freemacsoft.net/appcleaner/)
|
||||
|
||||
アプリを設定ファイルごとまとめて消せます。潔癖性なので、これが無いと不安にな李ます。
|
||||
|
||||
## [Pocket](https://getpocket.com)
|
||||
|
||||
「あとで読む」を管理するためのアプリです。Reading List でもいいと思うので好みですね。
|
||||
|
||||
## [TripMode](https://www.tripmode.ch)
|
||||
|
||||
通信出来るアプリを個別に許可できます。外出先でテザリングをする際に TripMode があれば、データ制限を気にせずインターネット接続ができるので便利です。
|
||||
|
||||
# 導入を見送ったもの
|
||||
|
||||
## [Clear](http://realmacsoftware.com/clear/)
|
||||
|
||||
タスク管理アプリ。標準の Reminders.app に移行しました。
|
||||
|
||||
## [Evernote](https://evernote.com/intl/jp/)
|
||||
|
||||
Notes.app に移行しました。
|
||||
|
||||
## Flash
|
||||
|
||||
ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
|
||||
|
||||
## [VirtualBox](https://www.virtualbox.org)
|
||||
|
||||
仮想環境を構築するためのアプリです。[Docker Machine](https://docs.docker.com/machine/)と組み合わせていましたが、Docker for Mac の登場によって不要になりました。
|
||||
|
||||
## Karabiner
|
||||
|
||||
US 配列キーボードの Command キーを英かなに振り分けるため、Karabiner を使っていましたが、よりシンプルで軽量な[⌘ 英かな](https://ei-kana.appspot.com)に移行しました。
|
||||
|
||||
## Seil
|
||||
|
||||
US 配列の caps lock キーを Ctrl キーへ変更するために使っていましたが、いつからか macOS 標準で出来るようになっていたので不要になりました。
|
||||
|
||||
## Google 日本語入力
|
||||
|
||||
最近の OS 標準の IM に搭載されているライブ変換機能が優秀なので、あえてサードパーティの IM を入れる必要性がなくなりました。
|
||||
|
||||
## Alfred
|
||||
|
||||
便利そうなワークフローを色々入れても、実際に使う頻度はあまり高くないことに気がつき、この際なので Spotlight に切り替えました。
|
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Polyglot Extension for Safari
|
||||
date: 2016-02-11 09:00:00 +09:00
|
||||
redirect_from: "/blog/2016/02/11/polyglot-extension-for-safari"
|
||||
---
|
||||
|
||||

|
||||
|
||||
選択したテキストを翻訳できる Safari Extension を作った。[Polyglot](https://github.com/uetchy/Polyglot) を使えば、選択した文章や、フォームに入力したテキストをその場で好きな言語に翻訳してみせることが出来る。
|
||||
|
||||

|
||||
|
||||
この Extension は **Google Translate API** を使っている。だからこれを Safari で使うためには、まず Google Cloud Platform から API キーを手に入れなくてはならない。その手続きは少しばかり面倒なので、[スクリーンショット付きのガイド](https://github.com/uetchy/Polyglot/wiki/How-to-obtain-Google-Cloud-Platform-API-key)を作った。
|
||||
|
||||
## Inside Safari Extension
|
||||
|
||||
技術的に特段おもしろいことをしているわけではない。ES2015 でコードを書き、webpack と babel を使って Extension 向けにトランスパイルしている。意外だったのは、Safari Extension の構造が Google Chrome 拡張機能のそれとよく似ていたことだ。これならば Chrome 開発者でも容易に Safari Extension を作れるだろう。
|
||||
|
||||
## プラットフォーム間の差異を無くすには
|
||||
|
||||
プログラミング言語 Python は、大きく Python 2 と Python 3 の二つのバージョンに分かれている。双方に互換性は無く、Python 3 で書かれたコードが Python 2 では動かない。しかし、six (ネーミングは 2 × 3 ?)というライブラリを使うことで、バージョン間の差異をライブラリが吸収し、同じコードベースを両方のバージョンで動かすことが出来る。
|
||||
|
||||
これと同じように、Safari と Google Chrome の拡張機能の仕様の違いを吸収してくれるライブラリがあれば、Safari Extension 界隈も賑やかになるのではないか。
|
108
source/_posts/2016/2016-05-26-stairlab-aiseminar-2-memo.md
Normal file
108
source/_posts/2016/2016-05-26-stairlab-aiseminar-2-memo.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: ステアラボ人工知能セミナー#2 メモ
|
||||
date: 2016-05-26 09:00:00 +09:00
|
||||
redirect_from: "/blog/2016/05/26/stairlab-aiseminar-2-memo"
|
||||
---
|
||||
|
||||
走り書きです。
|
||||
|
||||
<https://stairlab.doorkeeper.jp/events/44958>
|
||||
|
||||
> 第 2 回目の今回は、機械学習の研究者で、トピックモデル (機械学習プロフェッショナルシリーズ)の著者でもある、NTT コミュニケーション科学基礎研究所の[岩田具治](http://www.kecl.ntt.co.jp/as/members/iwata/index-j.html)先生をお招きし、「教師なしオブジェクトマッチング」というタイトルで、先生の最近の研究について講演していただきます。
|
||||
|
||||
- 教師なし学習
|
||||
|
||||
- PCA が主流
|
||||
- t-SNE で次元削減してプロット
|
||||
|
||||
- 教師ありオブジェクトマッチング
|
||||
|
||||
- 異なるドメインに含まれる事例間の対応を見つけるタスク
|
||||
- [正準相関分析](http://ibisforest.org/index.php?正準相関分析)
|
||||
- 正解対応データが低次元潜在空間で同じ位置に埋め込まれるよう、線形写像を学習する
|
||||
- テスト時には、低次元潜在空間上で近くに配置されたデータが類似していると判定する
|
||||
- 問題点
|
||||
- 対応データが必要(対訳等)
|
||||
- 対応データが入手困難・不可能な状況もある
|
||||
- プライバシーの保護
|
||||
- データの入手目的や方法が異なる
|
||||
- 人手による対応付けコストが高い
|
||||
|
||||
- 教師なしオブジェクトマッチング
|
||||
|
||||
- ドメイン間のオブジェクトの距離は測れない
|
||||
- ドメイン内のオブジェクト間の距離の相対的な関係を見てマッチングする
|
||||
|
||||
- 教師なしクラスタマッチング
|
||||
|
||||
- 異なるドメイン間のクラスタの対応を教師なしで見つける
|
||||
|
||||
- 提案 : 教師なしクラスタマッチングのための潜在変数モデル
|
||||
|
||||
1. 各ドメインのデータを共通の低次元潜在空間へ埋め込む
|
||||
2. 潜在空間でクラスタリング
|
||||
3. 同じクラスタになったオブジェクトが対応
|
||||
|
||||
- 確率的生成モデルによるクラスタリング
|
||||
|
||||
- データが生成される過程を確率を用いて定義
|
||||
- 実際にはデータが与えられる
|
||||
- データを生成したもっともらしいクラスタを推論
|
||||
- 利点
|
||||
- 不確実性を考慮できる
|
||||
- 確率論の枠組みで異種データを統合できる
|
||||
|
||||
- 混合定期分布によるクラスタリング
|
||||
|
||||
- k-means の確率版
|
||||
- 生成過程
|
||||
- クラスタ毎の平均は $\{\mu_1, \mu_2, … \mu_k\}$
|
||||
- For オブジェクト $n = 1, …, N$
|
||||
- クラスタ割り当てを決める$S_n \sim Categorical(\theta)$
|
||||
|
||||
- 教師なしクラスタマッチング生成モデル
|
||||
|
||||
- [無限混合正規分布](http://www.nejicolab.com/akip/?p=160)
|
||||
`$$ p(X_{dn}|Z,W,\theta) = \sum^\infty_{j=1}{\theta_j N(x_{dn}|W_d z_j, \alpha^{-1} I)} $$`
|
||||
|
||||
- 特徴
|
||||
- ディリクレ過程を用いて無限個のクラスタを想定
|
||||
- 異なるドメインのオブジェクトを共通のクラスタに割り当てできる
|
||||
- ドメイン毎に異なる特徴次元や統計的性質を考慮できる
|
||||
- ドメイン毎に異なるオブジェクト数でも良い
|
||||
- 確率的 EM アルゴリズム
|
||||
- E ステップ : クラスタ割り当て s を gibbs サンプリング
|
||||
- M ステップ : 写像行列 W を最尤推定
|
||||
- 潜在ベクトル z、クラスタ割り当て$\theta$、精度$\alpha$は解析的に積分消去
|
||||
- [Adjusted Rand index](http://y-uti.hatenablog.jp/entry/2014/01/19/133936) (高いほど良い)
|
||||
- 反教師あり
|
||||
- 少数の対応データが得られる場合もある
|
||||
- E ステップで対応データは必ず同じクラスタに割り当てられるとする
|
||||
- 結論
|
||||
- 教師なしクラスタマッチング手法を提案
|
||||
- 対応データ不要
|
||||
- 多ドメイン、多対多、任意のオブジェクト数に対応
|
||||
|
||||
## ネットワークデータのための教師なしクラスタマッチング
|
||||
|
||||
- Find correspondence between clusters in multiple networks without node correspondence
|
||||
- ReMatch
|
||||
- based on [Infinite Relational Models](http://qiita.com/takuti/items/8faf0e686cfbe68c2dfa) (IRM)
|
||||
- is IRM with a combined matrix
|
||||
- Rivals
|
||||
- IRM+KS
|
||||
- KS
|
||||
- MMLVM
|
||||
- AUC: abbr. Area Under the Curve
|
||||
|
||||
## 他言語文書データからの普遍文法の抽出
|
||||
|
||||
- Languages share certain common properties
|
||||
- word order in most European language is SVO
|
||||
- Extract a common grammar from multilingual corpora
|
||||
- Hierarchical Bayesian modeling
|
||||
- Probabilistic(Stochastic) context-free grammar (PCFG, SCFG) = 確率文脈自由文法
|
||||
|
||||
## 質疑応答
|
||||
|
||||
- トピックモデルよりも、一度ネットワークに落とし込んだ方が精度は良い
|
38
source/_posts/2016/2016-10-15-cuda-on-macos.md
Normal file
38
source/_posts/2016/2016-10-15-cuda-on-macos.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: CUDA on macOS
|
||||
date: 2016-10-15 09:00:00 +09:00
|
||||
redirect_from: "/blog/2016/10/15/cuda-on-macos"
|
||||
---
|
||||
|
||||
Install TensorFlow with CUDA 8.0 + cuDNN 5.1 support on macOS.
|
||||
All instructions are based on [TensorFlow Get Started](https://www.tensorflow.org/get_started/os_setup).
|
||||
|
||||
# Install CUDA and cuDNN
|
||||
|
||||
{% gist 568d86da5ce555e9bc6618f59391f9cd 01_install_cuda_cudnn.sh %}
|
||||
|
||||
You also need to add this line to your shell config.
|
||||
|
||||
```bash
|
||||
export CUDA_HOME=/usr/local/cuda
|
||||
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$CUDA_HOME/lib"
|
||||
export PATH="$CUDA_HOME/bin:$PATH"
|
||||
```
|
||||
|
||||
and build deviceQuery as test your environment.
|
||||
|
||||
```bash
|
||||
cd /usr/local/cuda/samples/
|
||||
make -C 1_Utilities/deviceQuery
|
||||
./bin/x86_64/darwin/release/deviceQuery
|
||||
```
|
||||
|
||||
# Install TensorFlow
|
||||
|
||||
## Install from pip
|
||||
|
||||
{% gist 568d86da5ce555e9bc6618f59391f9cd 02_install_tensorflow.sh %}
|
||||
|
||||
## Build from source
|
||||
|
||||
{% gist 568d86da5ce555e9bc6618f59391f9cd 03_build_tensorflow.sh %}
|
15
source/_posts/2017/2017-02-02-sim-card-travel.md
Normal file
15
source/_posts/2017/2017-02-02-sim-card-travel.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: 海外旅行におけるSIMカードの選択
|
||||
date: 2017-02-02 00:20:00 +09:00
|
||||
redirect_from: "/blog/2017/02/02/sim-card-travel"
|
||||
---
|
||||
|
||||
世界中で 3G 通信が出来る[GigSky](http://www.gigsky.jp)の SIM を 3 日間の台湾旅行で使ってみました。
|
||||
|
||||
GigSky では、その国の最初のアクティベーションに限り、3 日・100MB 分が無料で使えるので、今回の旅行では課金をせずに SIM を使うことが出来ました。
|
||||
|
||||
料金設定は現地で購入できる SIM と比べてかなり高く、旅行先で都度 SIM を購入する手間とのトレードオフとなります。
|
||||
|
||||
GigSky アプリをインストールしておくと、データ残量が半分以下になったタイミングでプッシュ通知を飛ばしてくれます。また、データ通信枠をトップアップする仕組みなので、追加データ枠の購入さえしなければ余計な課金をせずに済むという利点があります。
|
||||
|
||||
ただ、やはり価格設定が高めなのに加えて現地での SIM 購入はそこまで苦ではないので、3 日以上の旅行で使う機会は無いでしょう。
|
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Markdownフレンドリーなノートアプリ
|
||||
date: 2017-02-13 21:52:00 +09:00
|
||||
redirect_from: "/blog/2017/02/13/markdown-friendly-note-taking-apps"
|
||||
---
|
||||
|
||||
UI が秀逸な Markdown ノートアプリを紹介します。
|
||||
|
||||
# ノートアプリの種類
|
||||
|
||||
ノートアプリには大きく分けて 2 種類があります。
|
||||
Notes のようにノートを一箇所にまとめて管理するシングルトンタイプと、TextEdit のようにファイル毎にウィンドウが開くタイプです。
|
||||
この記事では、前者を Notes タイプ、後者を TextEdit タイプと呼称し区別します。
|
||||
|
||||
# Notes タイプ
|
||||
|
||||
## Notion
|
||||
|
||||
<https://notion.so>
|
||||
|
||||
サンフランシスコの Notion Lab 社が開発する多機能ノートアプリです。Web 版、iOS/Android 版と Mac 版が用意されており、Markdown ライクな記法で自由度の高いノートテイキングが出来ます。
|
||||
|
||||
## Bear
|
||||
|
||||
<http://www.bear-writer.com>
|
||||
|
||||
北イタリア産のノートアプリです。記事中に **ハッシュタグ** を書き込むと、リストでまとめてくれる機能が秀逸です。
|
||||
iCloud を使って、macOS と iOS アプリの間でノートを同期することが出来ます。
|
||||
|
||||
## SnippetsLab
|
||||
|
||||
<https://www.renfei.org/snippets-lab/>
|
||||
|
||||
正確にはスニペット管理アプリですが、Markdown+MathJax をサポートしており、数式を使ったメモを書くことが出来ます。
|
||||
|
||||
## Inkdrop
|
||||
|
||||
<https://www.inkdrop.info>
|
||||
|
||||
個人開発のノートアプリです。プラグインにより多くの機能を追加することが出来ます。
|
||||
|
||||
# TextEdit タイプ
|
||||
|
||||
## Typora
|
||||
|
||||
<https://typora.io>
|
||||
|
||||
エディタとプレビューが一体化したタイプのエディタです。左右分割よりも WYSIWYG エディタの方がわかりやすい派なので、これ一択です。
|
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Install NVIDIA GeForce GTX TITAN X in MacPro Early 2008
|
||||
date: 2017-02-13 14:20:00 +09:00
|
||||
redirect_from: "/blog/2017/02/13/nvidia-titan-x-macpro-early-2008"
|
||||
---
|
||||
|
||||
MacPro Early 2008 という骨董品に NVIDIA Titan X (Maxwell)を積んだところ、いくつかの問題にぶつかりました。この記事でそれらの問題と解決策について書きます。
|
||||
|
||||
# NVIDIA ドライバーが非対応
|
||||
|
||||
あまりにも古いアーキテクチャの MacPro に対して NVIDIA のグラフィックドライバーが対応していません。
|
||||
そこで、適切なバージョンの[NVIDIA Web Driver](http://www.macvidcards.com/drivers.html)をインストールすることでこれを解決しました。
|
||||
これには問題もあります。macOS のアップデートをインストールするたびに、それに対応したドライバーを都度インストールする必要がありました。
|
||||
|
||||
ドライバーをインストールするまでは画面に何も映りません。そこで、pkg 形式のドライバーを`scp`で MacPro に転送して、`installer`を使ってドライバーをインストールすることにしました。
|
||||
|
||||
```
|
||||
scp driver.pkg MacPro.local:~
|
||||
ssh MacPro.local
|
||||
sudo installer -pkg ./driver.pkg -target /
|
||||
```
|
||||
|
||||
# 電源ユニット(PSU)のパワー不足
|
||||
|
||||
TITAN X(Maxwell)が要求するパワーを MacPro の PSU は提供することが出来ません。
|
||||
そこで、秋葉原の PC パーツショップで追加の PSU を購入して、GPU 専用の電源として使いました。
|
||||
ここで新たな問題が生まれます。正しくパワーを提供するためには MacPro の PSU と追加の PSU を同期させる必要があり、またそれを実現するパーツもあるのですが、場合によっては GPU を破損してしまう危険性がありました。
|
||||
今回は電源を同期することは見送り、個別にスイッチを入れることで解決しました。
|
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Install Python and Jupyter on macOS with Minimal Effort
|
||||
date: 2017-02-28 11:14:00 +09:00
|
||||
redirect_from: "/blog/2017/02/28/minimal-python-jupyter-macos"
|
||||
---
|
||||
|
||||
Maybe you don't need `pyenv` and/or `virtualenv` in most cases.
|
||||
|
||||
## Install Python
|
||||
|
||||
> Don't have `brew`? Go to <https://brew.sh>.
|
||||
|
||||
```
|
||||
brew install python3
|
||||
```
|
||||
|
||||
If you still need Python 2, run `brew install python`.
|
||||
|
||||
## Install Jupyter Notebook
|
||||
|
||||
```
|
||||
pip3 install jupyter
|
||||
python3 -m ipykernel install --user
|
||||
```
|
||||
|
||||
You also want Python 2 kernel, so then:
|
||||
|
||||
```
|
||||
pip install ipykernel
|
||||
python -m ipykernel install --user
|
||||
```
|
||||
|
||||
That's all.
|
||||
|
||||
# How about `virtualenv`?
|
||||
|
||||
Since Python 3 got its own virtual environment tool called [venv](https://docs.python.org/3/library/venv.html), You no longer need `virtualenv` itself.
|
||||
|
||||
If you want a virtual envs on your project, run:
|
||||
|
||||
```
|
||||
python3 -m venv venv
|
||||
source ./venv/bin/activate
|
||||
```
|
||||
|
||||
then `venv` will creates virtual envs on **./venv** folder on the root of your project.
|
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Definitive Guide to Install OpenCV 3 and its Python 3 bindings
|
||||
date: 2017-03-23 15:10:00 +09:00
|
||||
redirect_from: "/blog/2017/03/23/install-opencv3-and-python3-bindings"
|
||||
---
|
||||
|
||||
This article describes how to install OpenCV 3 and its Python 3 bindings on macOS and Ubuntu.
|
||||
|
||||
## `pyenv` users beware
|
||||
|
||||
Make sure to use system python because there is some tricky problem with OpenCV 3 install script.
|
||||
To switch to system python, run `pyenv global system`.
|
||||
|
||||
# macOS
|
||||
|
||||
Install OpenCV 3 package from `homebrew/science`, make sure to add `--with-python3` so we'll also get its Python 3 bindings simultaneously.
|
||||
|
||||
```bash
|
||||
brew tap homebrew/science
|
||||
brew install opencv3 --with-python3
|
||||
```
|
||||
|
||||
After installing OpenCV 3, put OpenCV 3 path file as `opencv3.pth` into brewed-`python3` site-packages directory, which indicates where the OpenCV 3 bindings installed.
|
||||
|
||||
```bash
|
||||
echo /usr/local/opt/opencv3/lib/python3.6/site-packages >> /usr/local/lib/python3.6/site-packages/opencv3.pth
|
||||
```
|
||||
|
||||
# Ubuntu
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opencv/opencv
|
||||
cd opencv
|
||||
git checkout 3.2.0
|
||||
mkdir build
|
||||
cd build
|
||||
cmake \
|
||||
-D CMAKE_BUILD_TYPE=RELEASE \
|
||||
-D CMAKE_INSTALL_PREFIX=/usr/local \
|
||||
-D WITH_TBB=ON \
|
||||
-D WITH_EIGEN=ON \
|
||||
-D BUILD_NEW_PYTHON_SUPPORT=ON \
|
||||
-D INSTALL_PYTHON_EXAMPLES=ON \
|
||||
-D WITH_V4L=ON \
|
||||
-D WITH_FFMPEG=OFF \
|
||||
-D BUILD_EXAMPLES=OFF \
|
||||
-D BUILD_TESTS=OFF \
|
||||
-D BUILD_PERF_TESTS=OFF \
|
||||
-D BUILD_DOCS=OFF \
|
||||
-D BUILD_opencv_python2=OFF \
|
||||
-D BUILD_opencv_python3=ON \
|
||||
-D BUILD_opencv_video=OFF \
|
||||
-D BUILD_opencv_videoio=OFF \
|
||||
-D BUILD_opencv_videostab=OFF \
|
||||
-D PYTHON_EXECUTABLE=$(which python) \
|
||||
"$OPENCV_DIR"
|
||||
make -j2
|
||||
sudo make install
|
||||
pip install opencv-python
|
||||
```
|
||||
|
||||
# Check install
|
||||
|
||||
```
|
||||
python -c "import cv2;print(cv2.__version__)"
|
||||
```
|
||||
|
||||
and you'll got `3.2.0`.
|
31
source/_posts/2017/2017-04-23-apple-pie.markdown
Normal file
31
source/_posts/2017/2017-04-23-apple-pie.markdown
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: アップルパイ
|
||||
date: 2017-04-23T05:48:00.000+00:00
|
||||
categories:
|
||||
- recipe
|
||||
redirect_from: "/blog/2017/04/23/apple-pie"
|
||||
image: "/uploads/apple-pie.jpg"
|
||||
|
||||
---
|
||||

|
||||
|
||||
再現性の高いアップルパイの作り方です。材料は初出時に太字にしました。
|
||||
|
||||
# 注意事項
|
||||
|
||||
* レモン汁はポッカレモンで代用可
|
||||
* 範囲指定されている値は 2 回目から好みで変化させること
|
||||
* 焼きあがったらただちにパイ皿を取り除くこと。冷めてからではより困難になる
|
||||
|
||||
# 手順
|
||||
|
||||
1. **富士りんご(直径 8cm)**3 個の皮を剥いて 2-3 ㎠ に切って鍋に入れる
|
||||
2. **砂糖**60g・**レモン汁**大さじ2 を鍋に入れて、汁気が無くなるまで中火で 10-15 分煮る
|
||||
3. 火を止めて、**切れてるバター**2 個 (= 20g)・**シナモン**を好きなだけ混ぜる
|
||||
4. **冷凍パイシート**を冷蔵庫に移動し 30 分おく
|
||||
5. 18cm パイ皿 (パイシートに合う皿であれば何でも良い) にシートを敷き、よく密着させる
|
||||
6. 鍋の中身の熱が扱える程度に取れたらパイ皿に流し込んで広げる
|
||||
7. 残りのパイシートをカットして格子状にのせる
|
||||
8. **卵黄**に**水・塩**を少し混ぜ卵液を作り、シートに塗る(塗るほど焼けやすくなる)
|
||||
9. 余りのシートをパイの縁にのせて卵液を薄く塗る
|
||||
10. 200℃ のオーブンで 40 分焼く(15 分で 180℃ に落とす; でないと表面だけ焼けて中は生焼けになる)
|
34
source/_posts/2017/2017-05-13-github-repos-comparison.md
Normal file
34
source/_posts/2017/2017-05-13-github-repos-comparison.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: GitHubリポジトリの比較表を gh-compare で作る
|
||||
date: 2017-05-13 12:00:00 +09:00
|
||||
redirect_from: "/blog/2017/05/13/github-repos-comparison"
|
||||
image: http://uechi-public.s3.amazonaws.com/github/gh-compare.gif
|
||||
---
|
||||
|
||||
# GitHub リポジトリの比較表を gh-compare で作る
|
||||
|
||||

|
||||
|
||||
[gh-compare](https://github.com/uetchy/gh-compare) を作りました。この小さなツールを使って、導入を検討しているライブラリ群の比較表をコマンド1つで作ることが出来ます。
|
||||
|
||||
ライブラリのリポジトリが GitHub にあることが前提になりますが、プロジェクトの勢いからサイズまで俯瞰することが出来ます。
|
||||
|
||||
最高と最悪の値はそれぞれ緑色と赤色に着色されるので、違いが一目瞭然でわかります。
|
||||
|
||||
## インストール
|
||||
|
||||
`gh-compare`モジュールは`npm`からインストール出来ます。
|
||||
|
||||
```bash
|
||||
npm install --global gh-compare
|
||||
```
|
||||
|
||||
## 使い方
|
||||
|
||||
`gh-compare`の後にスペース区切りで比較したいリポジトリを書きます。
|
||||
|
||||
```bash
|
||||
gh-compare facebook/react vuejs/vue riot/riot angular/angular
|
||||
```
|
||||
|
||||
もし変な挙動を見つけたら、プロジェクトの [Issues](https://github.com/uetchy/gh-compare/issues/new) に是非書いてください。
|
54
source/_posts/2017/2017-06-16-x11forward.md
Normal file
54
source/_posts/2017/2017-06-16-x11forward.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: Forward X11 window over SSH
|
||||
date: 2017-06-16 00:00:00 +09:00
|
||||
redirect_from: "/blog/2017/06/16/x11forward"
|
||||
---
|
||||
|
||||

|
||||
|
||||
## Ubuntu 16.04
|
||||
|
||||
Make sure you have installed SSH, X11 and xAuth on a remote server.
|
||||
|
||||
```
|
||||
sudo apt install -y xorg xauth openssh
|
||||
sudo sed -i '/ForwardX11/s/.*/ForwardX11 yes/' /etc/ssh/sshd_config
|
||||
sudo service ssh restart
|
||||
```
|
||||
|
||||
## macOS Sierra
|
||||
|
||||
You also need to have X11 on your local machine.
|
||||
|
||||
```
|
||||
brew cask install xquartz # install X11
|
||||
ssh -X <remote>
|
||||
$ xeyes # verify you have X11
|
||||
```
|
||||
|
||||
You might want to restart macOS if `$DISPLAY` have empty value.
|
||||
|
||||
# Plot with matplotlib
|
||||
|
||||
Plot a simple graph remotely on Ubuntu 16.04:
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
plt.plot([1, 2, 3])
|
||||
plt.show()
|
||||
```
|
||||
|
||||
If you can't see any window, add **backend** settings to `~/.config/matplotlib/matplotlibrc`.
|
||||
|
||||
```ini
|
||||
backend: TkAgg
|
||||
```
|
||||
|
||||
or just add few lines to change the backend explicitly:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
import matplotlib.pyplot as plt
|
||||
...
|
||||
```
|
29
source/_posts/2017/2017-12-27-oss-for-designers.markdown
Normal file
29
source/_posts/2017/2017-12-27-oss-for-designers.markdown
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: デザイナーとしてOSSに貢献できること
|
||||
date: 2017-12-26T15:24:00.000+00:00
|
||||
redirect_from: "/blog/2017/12/27/oss-for-designers"
|
||||
|
||||
---
|
||||
GitHub で公開されている OSS にちょっとした Pull-request を送るのが私の趣味です。
|
||||
そのような Pull-request の中にはコードだけでは無く、時にロゴデザインが含まれていることもあります。
|
||||
|
||||
## textlint
|
||||
|
||||
文章校正ツールである[textlint](https://textlint.github.io/)プロジェクトの例では、作者の azu 氏が[ロゴの募集をされている Issue](https://github.com/textlint/textlint/issues/56)を見かけ、[ちょっとしたアイディア](https://github.com/textlint/textlint/issues/56#issuecomment-160050653)をコメントしたことから始まりました。
|
||||
|
||||
その後、[より詳細な検討](https://github.com/textlint/media/pull/1)を重ねた結果、私がデザインした textlint のロゴは無事プロジェクトに受け入れられました。
|
||||
|
||||
このようにプロジェクトの作者が Issue 等でロゴを募集することは一般的であり、WebAssembly のロゴも[公募のコンペティション](https://github.com/WebAssembly/design/issues/112)で決まっています。
|
||||
|
||||
一方で自らロゴの提案をすることもあります。
|
||||
|
||||
## ⌘ 英かな
|
||||
|
||||
macOS のキーバインドを変更するアプリである[⌘ 英かな](https://ei-kana.appspot.com/)の例では、アイコンの Enhancement を思いつき、[Pull-request](https://github.com/iMasanari/cmd-eikana/pull/5)を送ったところ、本当にすぐにマージしてくれました。
|
||||
|
||||
他の方の例では、[Annict](https://github.com/annict/annict/issues/120)などがあります。
|
||||
|
||||
## 結論
|
||||
|
||||
以上のように、OSS コミュニティではコードだけでなくデザインワークに対してもオープンにコミットすることが出来ます。
|
||||
デザイナーの皆さんが OSS への貢献に関わる機会がますます増えることを楽しみにしています(そして OSS 開発者の多くは、クールなロゴが提案されることを心から待ち望んでいます!)
|
40
source/_posts/2018/2018-03-24-earin-m2-first-look.markdown
Normal file
40
source/_posts/2018/2018-03-24-earin-m2-first-look.markdown
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: EARIN M-2 所見
|
||||
date: 2018-03-24 12:56:00 +09:00
|
||||
redirect_from: "/blog/2018/03/24/earin-m2-first-look"
|
||||
---
|
||||
|
||||
EARIN M-2 は全体的に見て EARIN の正統進化系と言って良い。
|
||||
タッチ操作による再生コントロールや通話中のアクティブノイズリダクション、イヤホンの左右を区別しないインターフェースは洗練されており使いやすい。
|
||||
|
||||
一方で欠点が無いわけでは無い。EARIN M-2 は初代同様いくつかの点においてストイックな使い方をユーザーに要求する。
|
||||
|
||||
特にペアリングと、ペアリング後の内部挙動を理解することがスムーズな操作のために必要になってくる。そこで、バグ報告のついでに EARIN 社から聞いた情報を書き留めておく。
|
||||
|
||||
# EARIN M-2 の接続フロー
|
||||
|
||||
EARIN M-2 の接続フローは以下の通りである。
|
||||
|
||||
1. ケースから EARIN(単体)が取り出されると電源が入り、デバイスを探して接続する
|
||||
2. デバイスとの接続が完了すると、デバイスに他の EARIN が既に接続されているかを確認する
|
||||
3. 既に他の EARIN が接続されていた場合、自身の接続を解除し、既に接続されている EARIN に NFMI(近距離磁界誘導)で接続し直し、以後クライアントとして振る舞う
|
||||
4. 他の EARIN が接続されていなかった場合、マスターとして振る舞う。デバイスから送られてくる音声信号を、(もしクライアントが存在する場合)クライアントに NFMI 経由でリレーする
|
||||
|
||||
以上のフローを最初に実行するため、ケースから取り出したイヤホンを素早く両耳に装着した際に、最初片耳からしか音楽が聞こえないのは仕様である。NFMI 接続が確立すると両耳から流れるようになる。
|
||||
|
||||
ちなみに左右のイヤホンのどちらがマスターか知りたければ、音楽を再生しながら片方のイヤホンを耳から外すことでわかる。もし、まだつけている方のイヤホンの音楽が止まれば外した方がマスターであり、音楽が鳴り続けていたら耳につけている方がマスターである。
|
||||
|
||||
# イヤーチップ
|
||||
|
||||
EARIN M-2 付属のイヤーチップが耳に合わず、遮音性が低かったため替わりのチップを探した。
|
||||
内筒の直径を測ると 5mm だったので、同じ内径の Comply Ts-500 を装着したところ、遮音性もフィット感も最高になった。
|
||||
|
||||
# バッテリー
|
||||
|
||||
電力消費量が左右非対称なので、マスターのバッテリーが先に無くなる。その結果音楽が途切れるが、今までクライアントだったもう片方のイヤホンがすぐさまマスターとして振る舞うようになるので、片耳で音楽を聞き続ける猶予が少しだけある。
|
||||
|
||||
# ノイズ
|
||||
|
||||
現行品の不具合で、クライアント側に微細なホワイトノイズが乗っていることがある。
|
||||
今週末に Android 向けのファームウェアアップデートが出るらしい。iOS 向けは 2 週間後になるようだ。
|
||||
アップデートでこの問題が修正されるかわからないが、もし問題が続く場合、本社に送れば修理してくれるそうなので気になっている人はサポートに連絡を取ろう。
|
139
source/_posts/2018/2018-03-29-products-guide.markdown
Normal file
139
source/_posts/2018/2018-03-29-products-guide.markdown
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: 普段使いしているもの
|
||||
date: 2018-03-29 22:33:00 +09:00
|
||||
redirect_from: "/blog/2018/03/29/products-guide"
|
||||
updated: 2018-08-03 09:00:00 +09:00
|
||||
---
|
||||
|
||||
普段使いしているプロダクトを紹介する。
|
||||
「20XX 年に買ってよかったもの」を毎年書くのではなく、この記事を定期的に更新しようと思う。
|
||||
|
||||
# ハードウェア
|
||||
|
||||
## [MacBook 12"](http://www.apple.com/jp/shop/buy-mac/macbook/%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%89-512gb)
|
||||
|
||||
スペックを犠牲にして持ち運びに極振りした超コンパクトな MacBook。
|
||||
|
||||
## [EARIN M-2](https://earin.com)
|
||||
|
||||
EARIN M-1 から買い替えた。
|
||||
コンパクトさに極振りした完全無線イヤホン。万人受けしないプロダクトではあるが、その特性を理解して使えば手放せないギアになる。
|
||||
[レビュー記事](https://uechi.io/blog/2018/03/24/earin-m2-first-look)
|
||||
|
||||
## [Bose QuietControl 30](https://www.bose.co.jp/ja_jp/products/headphones/earphones/quietcontrol-30.html)
|
||||
|
||||
ノイズキャンセラーイヤホン QuietComfort 20 の後継機種。ワイヤレス化して、取り回しがよくなった。QuietControl の名の通り、ノイズキャンセリングの度合いを調整するボタンが搭載されている。しかし、実際のところ最大と最小しか使わないので、ボタンを押す手間がかえって不便に感じる。
|
||||
ノイズ除去能は随一なので、旅行には必ず持っていく。
|
||||
|
||||
## [Apple Watch series 2 Nike+](http://www.apple.com/jp/shop/buy-watch/apple-watch-nike/%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%82%B0%E3%83%AC%E3%82%A4-%E3%82%A2%E3%83%AB%E3%83%9F%E3%83%8B%E3%82%A6%E3%83%A0-%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF-%E3%83%9C%E3%83%AB%E3%83%88-%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84%E3%83%90%E3%83%B3%E3%83%89?preSelect=false&product=MP0J2J/A&step=detail#)
|
||||
|
||||
最終的に以下の機能しか使わなくなった。
|
||||
|
||||
- 時計
|
||||
- タイマー
|
||||
- 運動中の心拍数や歩数の計測
|
||||
- Suica
|
||||
- メッセージの閲覧・返信
|
||||
|
||||
## [M-Audio Keystation 88](http://m-audio.com/products/view/keystation-88)
|
||||
|
||||
88 鍵 MIDI キーボード。Oxygen 88 が壊れたので同じメーカーの別製品に買い替えた。Oxygen 88 の重さ(21kg)に懲り、持ち運びが容易な鍵盤を選んだ。
|
||||
|
||||
## [BALMUDA The Pot](https://www.balmuda.com/jp/pot/)
|
||||
|
||||
トースターで有名な BALMUDA が 11 月に出した電気ケトル。お茶やコーヒーを飲むときしか使わないので 0.6L でも十分だと感じた。注ぎ口の切れが良く、気に入っている。
|
||||
|
||||
最近は Stagg EKG のような温度調整機能付きケトルが気になっている。
|
||||
|
||||
## [Nature Remo](https://nature.global/)
|
||||
|
||||
スマートな赤外線リモコン。
|
||||
Google Home や Alexa、IFTTT と連携して使っている。
|
||||
|
||||
## [Knirps Big Duomatic Safety](http://www.knirps.jp/product.html)
|
||||
|
||||
知りうる中で最も大きなサイズの自動開閉折りたたみ傘。コンビニで売っている傘よりも大きいので安心感が違う。
|
||||
|
||||
## [Shure MOTIV MV88](https://www.shure.co.jp/go/motiv-mic/jp/mv88/)
|
||||
|
||||
非常にコンパクトなコンデンサーマイク。Lightning 端子を備えており、iPhone/iPad に繋いで録音ができる。
|
||||
|
||||
## [LEZYNE CNC Floor Drive ABS2](http://www.wiggle.jp/lezyne-cnc-floor-drive-abs2-%E3%83%95%E3%83%AD%E3%82%A2%E3%83%9D%E3%83%B3%E3%83%97/)
|
||||
|
||||
デザインと機能性が両立した自転車の空気入れ。仏式と米式バルブに対応している。回転するねじ込みノズルが特徴的で、BROMPTON のような小口径タイヤを持つ自転車でも問題なく使える。
|
||||
|
||||
## [iPad Pro 10.5 インチ](http://www.apple.com/jp/ipad-pro/)
|
||||
|
||||
[Apple Pencil](http://www.apple.com/jp/shop/product/MK0C2J/A/ipad-pro%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEapple-pencil)との組み合わせがとても良い。ノートを書いたり、絵を描くのに使っている。
|
||||
|
||||
スタンドは、Twelve South の[Compass 2](http://www.apple.com/jp/shop/product/HF022ZM/B/twelve-south-compass-2-stand-for-ipad)を使っている。折りたたむと Apple Pencil2 本分くらいに小さくなる。
|
||||
|
||||
# サブスクリプションサービス
|
||||
|
||||
## G Suite
|
||||
|
||||
月 540 円。
|
||||
好きなドメインで Google サービスを利用出来るので使っている。Gmail にも y@uechi.io でログイン出来る。
|
||||
|
||||
## Apple Music
|
||||
|
||||
学割で月 480 円。普段の音楽ソースはこれに統一している。
|
||||
|
||||
## iTunes Match
|
||||
|
||||
CD からインポートした曲をクラウド同期するために有効化。
|
||||
|
||||
## iCloud Drive
|
||||
|
||||
写真やクラウド同期のために容量を購入した。
|
||||
|
||||
## Dropbox Pro
|
||||
|
||||
あらゆる作業データを保存しているため容量を増やした。
|
||||
|
||||
## Amazon Student
|
||||
|
||||
Prime の学割版。年間 1400 円。
|
||||
|
||||
## Sketch
|
||||
|
||||
コンピューター 1 台ごとに課金されるため非常に割高。やめたい。
|
||||
|
||||
## Adobe Creative Cloud
|
||||
|
||||
学割で月 3000 円。
|
||||
|
||||
## Apple Developer Program
|
||||
|
||||
税金。
|
||||
|
||||
## MoneyForward
|
||||
|
||||
オンライン家計簿。電子決済縛りプレイと相性が良い。
|
||||
|
||||
## [Namecheap](https://www.namecheap.com/)
|
||||
|
||||
ドメインレジストラ。お名前.com から iwantmyname、そして Namecheap へと移行してきた。この手のサービスにしては良くデザインされており、使いやすい。
|
||||
|
||||
一度転送でトラブルがあり、カスタマーサポートのお世話になったことがあったが、しっかりとした仕事をしてくれた。
|
||||
|
||||
## [Netflix](https://www.netflix.com/jp/)
|
||||
|
||||
既存コンテンツの配信だけに留まらず、オリジナル作品の制作にも意欲的に取り組んでいる。
|
||||
|
||||
観たい作品が無くなったら購読をキャンセルし、必要に応じて再購読している。
|
||||
|
||||
## 珈琲きゃろっと
|
||||
|
||||
珈琲豆の定期宅配サービス。配送日の直前に焙煎をするため豆が新鮮なのが特徴。他にも土井珈琲が同様のサービスを提供しているので比べてみて自分に合った方を選ぼう。
|
||||
|
||||
## TastyTable
|
||||
|
||||
使い切りの食材とレシピを定期的に、または都度注文で宅配してくれるサービス。
|
||||
普段なら絶対に作らないような献立が提案されてくるので、週末に普段とは一風変わった食事を楽しみたい人にオススメのサービス。
|
||||
|
||||
## TENTAL
|
||||
|
||||
テントや焚き火グッズのようなキャンプ用品をレンタル出来るサービス。
|
||||
テントは高価な上にほとんど買い換えないタイプの製品なので、このようなサービスを通じて様々な種類のテントを借りて実地で試して、眼を肥やしてから購入した方が良いと感じた。
|
||||
3 シーズン用を買い揃えて、やる頻度の低い冬用の装備だけレンタルするという戦術もある。
|
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Building TensorFlow from Source
|
||||
date: 2018-04-10 09:41:00 +09:00
|
||||
redirect_from: "/blog/2018/04/10/building-tensorflow-from-source"
|
||||
---
|
||||
|
||||
As you may notice lines of snippet showed on [dockerfile-machinelearning](https://github.com/uetchy/dockerfile-machinelearning/blob/ffc2cadaf192b19509df0f4b87bc9d427aa30966/Dockerfile#L54-L86), TensorFlow can be non-interactively installed from source.
|
||||
|
||||
The code here are hugely depend on [PatWie's gist](https://gist.github.com/PatWie/0c915d5be59a518f934392219ca65c3d). I just added some build options for a newer version of TensorFlow and remove options that affect nothing.
|
||||
|
||||
```
|
||||
PYTHON_BIN_PATH=$(which python) \
|
||||
CUDA_TOOLKIT_PATH=/usr/local/cuda \
|
||||
CUDNN_INSTALL_PATH=/usr/local/cuda \
|
||||
PYTHON_LIB_PATH="$($PYTHON_BIN_PATH -c 'import site; print(site.getsitepackages()[0])')" \
|
||||
TF_NEED_GCP=0 \
|
||||
TF_NEED_CUDA=1 \
|
||||
TF_CUDA_VERSION="$($CUDA_TOOLKIT_PATH/bin/nvcc --version | sed -n 's/^.*release \(.*\),.*/\1/p')" \
|
||||
TF_CUDA_COMPUTE_CAPABILITIES=6.1,5.2,3.5 \
|
||||
TF_NEED_HDFS=0 \
|
||||
TF_NEED_OPENCL=0 \
|
||||
TF_NEED_JEMALLOC=1 \
|
||||
TF_ENABLE_XLA=0 \
|
||||
TF_NEED_VERBS=0 \
|
||||
TF_CUDA_CLANG=0 \
|
||||
TF_CUDNN_VERSION="$(sed -n 's/^#define CUDNN_MAJOR\s*\(.*\).*/\1/p' $CUDNN_INSTALL_PATH/include/cudnn.h)" \
|
||||
TF_NEED_MKL=0 \
|
||||
TF_DOWNLOAD_MKL=0 \
|
||||
TF_NEED_MPI=0 \
|
||||
TF_NEED_OPENCL_SYCL=0 \
|
||||
TF_NEED_S3=0 \
|
||||
TF_NEED_KAFKA=0 \
|
||||
TF_NEED_TENSORRT=0 \
|
||||
TF_NEED_GDR=0 \
|
||||
TF_SET_ANDROID_WORKSPACE=0 \
|
||||
GCC_HOST_COMPILER_PATH=$(which gcc) \
|
||||
CC_OPT_FLAGS="-march=native" ./configure
|
||||
bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package && \
|
||||
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg && \
|
||||
pip install /tmp/tensorflow_pkg/tensorflow-1.7.0-cp36-cp36m-linux_x86_64.whl
|
||||
```
|
51
source/_posts/2018/2018-04-13-camping.markdown
Normal file
51
source/_posts/2018/2018-04-13-camping.markdown
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: 初キャンプに必要な機材
|
||||
date: 2018-04-13 14:26:00 +09:00
|
||||
redirect_from:
|
||||
- "/blog/2018/04/13/camping"
|
||||
---
|
||||
|
||||
先月、大洗で初めてのキャンプ泊をした。
|
||||
|
||||
初めてのテント泊を経験した上で得た反省点、ポイントをいくつか残しておく。
|
||||
|
||||
# 道具のレンタル
|
||||
|
||||
キャンプ道具を一度に買い揃えるのが難しかったため、テントと椅子と焚き火グリルを TENTAL でレンタルした。
|
||||
6 万円以上するテントを購入前に実地で試用できるという点で、キャンプ初心者はむしろレンタルから始めることで銭失いの後悔を最小化できそうだ。
|
||||
逆に、1 万円を切る道具は熟慮した上で購入した方が良い。
|
||||
|
||||
# 焚き火とバーベキュー
|
||||
|
||||
キャンプをするからにはアウトドアでしか出来ないことをするべきである。そこで焚き火とバーベキューのどちらもこなせるピコグリル 398 を持って行った。
|
||||
ピコグリル 398 は重さが 400g 程度であり、厚さ 5mm 程に折りたたむことが出来る。このサイズ感で焚き火とバーベキュー両方をこなせるギアは他に無い。
|
||||
|
||||
バーベキュー用の炭として、ヤシガラ炭に着火剤を混ぜ込んだ形成炭を使用した。備長炭と違って簡単に火が付くため、重い着火用の風防や追加の着火剤を持って行かずに済む。
|
||||
2 人で 1-2 時間程度のバーベキューであれば形成炭 4 個で十分足りた。
|
||||
着火剤込みと言えどマッチで火をつけるのは難しかったので、コンパクトトーチを持って行くべきである。
|
||||
|
||||
また、グリルには厚手のアルミホイルを 2 枚ほど敷いておくと、バーベキューの最中に網から垂れた油を洗う手間が省ける。
|
||||
ただし、焚き火を始める前にアルミホイルを取り除くべきである。そのまま焚き火を始めると、アルミホイルが溶け出し洗い物がかえって困難になる。
|
||||
|
||||
焚き火を熾す際は、バーベキューで使った炭を着火剤として用いると薪に自然に火がついてくれる。
|
||||
干草を着火剤にする場合は薪の下に敷くべきである。着火した干草は火の粉となり周囲に広く拡散する。
|
||||
|
||||
# 風呂
|
||||
|
||||
キャンプ場のコインシャワーが壊れていた。さらに銭湯が遠く離れていたため、結局帰宅するまでお風呂に入ることが出来なかった。
|
||||
次回以降はそのような状況にも備える必要がある。そこでいくつか最低限の清潔さを保つための方策を考えた。
|
||||
|
||||
コンパクトな折りたたみバケットに水を半分張り、沸かしたお湯を注いでぬるま湯を作る。これで洗顔が出来る。さらにドライシャンプーで髪の油脂を取り除き、ぬるま湯で洗い流す。
|
||||
|
||||
身体は、デオドラントシャワーシートで汚れを拭き取る。歯の汚れは歯磨きシートで拭き取る。これで最低限の身嗜みを整えることが出来るはずだ。
|
||||
|
||||
# 就寝時の防音
|
||||
|
||||
キャンプをしている人々は皆素晴らしい人なのだが、規範意識の薄い人は一定の割合で必ず存在すると考えたほうが自然である。
|
||||
モルデックスのような遮音性が非常に高い耳栓を一つ持っていくと良い。
|
||||
|
||||
# 就寝時の防寒
|
||||
|
||||
当日の最低気温は 3 度と予報されたが、快適下限が 3 度のダウンシュラフでは到底太刀打ち出来ないほど凍えた。
|
||||
緊急の対策としてヒートテック、靴下、ネックウォーマーを装着し、さらに貼るカイロ x4 を身体中の血管が集中している場所に配置することでなんとか耐え凌いだ。
|
||||
寒すぎて困ることはあれど、暖かすぎて困ることは無い。シュラフにはお金をかけるべきである。
|
21
source/_posts/2018/2018-08-03-hermitian-conjugate.md
Normal file
21
source/_posts/2018/2018-08-03-hermitian-conjugate.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: 随伴行列あるいはエルミート共軛
|
||||
date: 2018-08-03 00:00:00 +09:00
|
||||
redirect_from: "/blog/2018/08/03/hermitian-conjugate"
|
||||
---
|
||||
|
||||
$m\times n$の複素行列の転置を取り、複素共軛をとった$n\times m$行列を随伴行列$A^\*$あるいはエルミート共軛という。
|
||||
|
||||
$$
|
||||
\begin{align}
|
||||
A &=\begin{pmatrix} 1 & -1-i \\ 1+i & i \end{pmatrix} \\
|
||||
A^{\_} &=\begin{pmatrix} 1 & 1-i \\ -1+i & -i \end{pmatrix} \\
|
||||
A^{\_} &= \bar{A}^T
|
||||
\end{align}
|
||||
$$
|
||||
|
||||
表記には方言があり$A^\*, A^H, A^\dagger$などのバリエーションがある。
|
||||
|
||||
# エルミート行列
|
||||
|
||||
複素数を成分に持つ正方行列$A$があったとして、その行列 A の随伴行列$A^\*$が$A$と等しい場合、行列$A$をエルミート行列という。
|
83
source/_posts/2018/2018-08-05-life-automation.md
Normal file
83
source/_posts/2018/2018-08-05-life-automation.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: 生活の自動化
|
||||
date: 2018-08-05 00:00:00 +09:00
|
||||
redirect_from: "/blog/2018/08/05/life-automation"
|
||||
---
|
||||
|
||||
生活にオートメーションを上手く取り入れ、本当にやりたいことや、やるべきことに集中できる環境をつくろう。
|
||||
|
||||
# 洗濯の自動化
|
||||
|
||||
Panasonic のドラム洗濯乾燥機を使っている。威力を最大限に享受するため、タンブラー乾燥向けの普段着を揃えておくことも重要だ。
|
||||
洗剤は粉と液体とが一体化したジェルボール洗剤が便利。ドラムの底にひとつ置くだけでよく、計量する必要がない。
|
||||
|
||||
# 食器洗いの自動化
|
||||
|
||||
Panasonic NC-TCR2 という一人暮らし用のコンパクト食洗乾燥機が便利。
|
||||
洗濯機と同じく食洗機専用のジェルボール洗剤を使えば計量する手間を省ける。
|
||||
|
||||
# 照明の自動化
|
||||
|
||||
Hue はインターネット経由で明るさや色相をコントロールすることができる電球である。
|
||||
|
||||
- 「家から離れたら消灯」
|
||||
- 「家に近付いたら点灯」
|
||||
- 「日が暮れたら暖色系に切り替える」
|
||||
- 「23 時になったら消灯」
|
||||
|
||||
など多様なルールを作ることができる。
|
||||
家では外の明るさに合わせて照明の明るさを調整して、概日リズムが崩れにくいようにルールを決めている。
|
||||
|
||||
# 空調の自動化
|
||||
|
||||
Nature Remo でエアコンの操作を自動化した。
|
||||
|
||||
- 「湿度が高ければドライに変更」
|
||||
- 「家から離れたら電源オフ」
|
||||
- 「朝になったら冷房へ切り替え」
|
||||
|
||||
など多様なルールを作ることができる。
|
||||
|
||||
Nature Remo 自体はエアコン専用ではなく、赤外線で操作出来るデバイスであればなんでも操作できる。家ではテレビもこれで操作している。
|
||||
|
||||
ちなみに[Nature Remo を NodeJS で操作することができるライブラリ](https://github.com/uetchy/nature-remo)を作ったので、是非使ってみて欲しい。ライブラリ経由で温度・湿度・明度のセンサー値を取得したり、指定したモードにエアコンを切り替えることができる。
|
||||
|
||||
# 自動施錠・自動開錠
|
||||
|
||||
Qrio Lock をドアに取り付けることでオートロックとオートアンロックができるようになった。
|
||||
|
||||
# 睡眠記録の自動化
|
||||
|
||||
Withings 改め Nokia の Sleep を使っている。
|
||||
睡眠を計測する際、身体にウェアラブルデバイスを身につける必要がないという点で、Nokia Sleep は Apple Watch や Fitbit よりも優れている。
|
||||
|
||||
機能としては、入眠・起床検知、心拍数記録、睡眠深度解析、いびき検出、IFTTT 連携がある。
|
||||
|
||||
# 体重記録の自動化
|
||||
|
||||
Withings の Wi-Fi Scale を使っている。体重と体脂肪率、心拍数、BMI を Wi-Fi 経由でクラウドに自動記録し、Apple Health などで推移を確認できる。
|
||||
|
||||
Wi-Fi Scale には CO2 センサーもついており、部屋の二酸化炭素濃度を記録してくれる。
|
||||
|
||||
# コーヒー豆のサブスクリプション
|
||||
|
||||
珈琲きゃろっとのサブスクリプションを利用している。
|
||||
|
||||
# オンラインスーパー
|
||||
|
||||
イトーヨーカドーのオンラインスーパーを使っている。お気に入りリストへ牛乳、オレンジ、ベーコン、卵など毎回買うものを登録しておくことで、慣れれば 5 分程度で注文が完了する。あとは指定した時間に家へ商品を届けてくれる。
|
||||
|
||||
# 自動家計簿
|
||||
|
||||
MoneyForward を使っている。支出を自動で食費、趣味、日用品などに仕分けてくれる。
|
||||
無現金縛りプレイと相性が良い。
|
||||
|
||||
# 自炊の効率化
|
||||
|
||||
最近 COMP で食事を置き換え始めた。まだ評価は出来ないが少なくとも味は悪くなく(薄いきな粉のような味)、不足しがちなビタミンや鉄分を補える点では良い製品だと思う。
|
||||
|
||||
# 気になる製品
|
||||
|
||||
## ルンバ
|
||||
|
||||
ルンバは気になるが、絨毯を取り除くわけにもいかないので二の足を踏んでいる。ルンバについては[KainokiKaede's diary](http://kainokikaede.hatenablog.com/entry/2018/07/24/185452)の素晴らしい記事を読んで欲しい。
|
21
source/_posts/2018/2018-09-02-know-your-deps.markdown
Normal file
21
source/_posts/2018/2018-09-02-know-your-deps.markdown
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Know your deps on package.json in seconds
|
||||
date: 2018-09-02 03:23:00 +09:00
|
||||
---
|
||||
|
||||
How do you know what packages that project/library depend on and what exactly are that packages doing for?
|
||||
You'll want to quickly survey on them. So [npm-deps-list](https://github.com/uetchy/npm-deps-list) is here for.
|
||||
|
||||

|
||||
|
||||
You can install them using `npm` or `yarn`.
|
||||
|
||||
```bash
|
||||
npm install -g npm-deps-list
|
||||
```
|
||||
|
||||
Running `ndl`, you will get a detailed list of dependencies for the package on the current directory.
|
||||
|
||||
If you are using iTerm2, you can also `Command + Click` on a package name to jump to their homepage.
|
||||
|
||||
If you have any idea on it, please consider submitting an issue or a pull request!
|
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Comparing OSS on GitHub
|
||||
date: 2018-09-23 03:21:00 +09:00
|
||||
---
|
||||
|
||||
You are making a decision on which open source project you would adopt for your newly developing application.
|
||||
|
||||
This time it is a little bit difficult for you because the candidates are seemingly almost the same in a functional perspective.
|
||||
|
||||
So let's delve into this from a different perspective: contributors and users activities.
|
||||
|
||||
- More stars, forks, and watchers are the good vital sign of a vibrant project, which indicates many users getting involved with the project.
|
||||
- More issues stand for both good and bad sign but basically it indicates their activeness.
|
||||
- Organization owned projects are, in most cases, more stable and robust than user owned projects.
|
||||
- Size of the repository have complexed meanings but in practice, simpler code is better than the massive one if both are trying to achieve the same goal.
|
||||
|
||||
I made a simple tool to get you covered with the above guidelines.
|
||||
|
||||
# gh-compare
|
||||
|
||||

|
||||
|
||||
[gh-compare](https://github.com/uetchy/gh-compare) is a simple terminal app to explore your candidates and aggregate a result into a nice-looking report.
|
||||
|
||||
```bash
|
||||
npm install -g gh-compare
|
||||
gh-compare facebook/react vuejs/vue riot/riot
|
||||
```
|
||||
|
||||

|
||||
|
||||
You will see the GitHub activities for each candidate at once.
|
||||
It could help you to decide which library you would adopt!
|
||||
|
||||
Warmly welcome to any comments/ideas to improve `gh-compare`!
|
47
source/_posts/2018/2018-10-23-math-api.markdown
Normal file
47
source/_posts/2018/2018-10-23-math-api.markdown
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: 'Math API: LaTeX Math as SVG image'
|
||||
date: 2018-10-23 03:19:00 +09:00
|
||||
---
|
||||
|
||||
I've always wanted to put LaTeX Math equations on a web page where MathJax is not allowed to run inside it.
|
||||
|
||||
Spending some time, I made [Math API](https://math.now.sh), that renders LaTeX Math markup into an SVG image.
|
||||
|
||||
So you can place your equation on almost everywhere on which you could put `<img>` or Markdown (`![]()`), such as GitHub, Jupyter Notebook or dev.to (here!).
|
||||
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
# Inline image
|
||||
|
||||

|
||||

|
||||
|
||||
It is possible to generate an inline equation by changing the query from `from` to `inline`.
|
||||
|
||||
```markdown
|
||||
<img src="https://math.now.sh?inline=\\LaTeX" />
|
||||
```
|
||||
|
||||
# Online Editor
|
||||
|
||||
Also, there is the online editor available at https://math.now.sh.
|
||||
|
||||

|
||||
|
||||
# Conclusion
|
||||
|
||||
The source code is available on [GitHub](https://github.com/uetchy/math-api).
|
||||
Give it a try and leave a comment/idea for a new feature.
|
52
source/_posts/2018/data-recovery.md
Normal file
52
source/_posts/2018/data-recovery.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Guide to recover data from damaged HDD
|
||||
date: 2018-02-15 12:45:00 +09:00
|
||||
redirect_from: "/blog/2018/02/15/data-recovery"
|
||||
---
|
||||
|
||||
This is a complete guide describes how to rescue your data from old and wrecked HDD.
|
||||
|
||||
Suppose you are using macOS and your endangered disk is formatted with HFS+.
|
||||
|
||||
# Beforehand
|
||||
|
||||
## Inspect
|
||||
|
||||
Use `diskutil list` to verify that which drive is damaged.
|
||||
|
||||
This article assumes that `disk2` is the damaged AND a partition `disk2s2` is what you expected to be rescued. You don't want to save `disk2s1` that is usually EFI partition.
|
||||
|
||||
## Damage Control
|
||||
|
||||
To prevent extra load, unmount the damaged disk: `diskutil unmountDisk disk2`.
|
||||
|
||||
# Rescue
|
||||
|
||||
If you never been `ddrescue`, `brew install ddrescue` to install them on your machine.
|
||||
|
||||
```bash
|
||||
cd /Volumes/AnotherDriveLargerThanDamagedDrive
|
||||
sudo ddrescue -n -v /dev/disk2s2 ./hdimage.dmg ./mapfile
|
||||
```
|
||||
|
||||
So this command will start rescuing your data from `/dev/disk2s2` partition to `hdimage.dmg` while writing log to `mapfile`.
|
||||
|
||||
You might want to rescue data as fast as possible. option `-n` is here for. This will skip scraping phase that causes aggressive disk access.
|
||||
|
||||
Option `-v` stand for verbose logging.
|
||||
|
||||
```bash
|
||||
sudo ddrescue -r5 -v /dev/rdisk2s2 ./hdimage.dmg ./mapfile
|
||||
```
|
||||
|
||||
When the first command completed, do it again with different parameters to aggressively scrape bad area failed to access the first time.
|
||||
|
||||
Option `-r5` means ddrescue will try rescuing damaged area for 5 times.
|
||||
|
||||
And `/dev/disk2s2` become `/dev/rdisk2s2` this time. `r` stand for raw so this will access the disk more direct way.
|
||||
|
||||
> Beware: You MUST use same `hdimage.dmg` and `mapfile` between two commands. `mapfile` remains information of which blocks were rescued.
|
||||
|
||||
# Aftercare
|
||||
|
||||
Mount `hdimage.dmg` and copy files and directories to a new drive. If the image is broken, you can recover it using `testdisk`.
|
@@ -0,0 +1,36 @@
|
||||
---
|
||||
date: 2019-10-25 19:49:01 +0900
|
||||
title: Bose Noise Cancelling Headphones 700レビュー
|
||||
---
|
||||
Bose Noise Cancelling Headphones 700を使い始めて一ヶ月が経ったので、現時点での印象をまとめる。
|
||||
|
||||
## Pros
|
||||
|
||||
* ノイズキャンセリング性能の高さ
|
||||
* デザイン
|
||||
* 8台までのマルチペアリング
|
||||
* 2台までのマルチポイント
|
||||
* タッチコントロール
|
||||
* 3段階ノイズキャンセリングレベルコントロール
|
||||
* 10段階の内3つをあらかじめ選んでおき、ボタンを押してローテーションできる
|
||||
* QC30は1段階ずつしか変更出来ずボタンを連打させられる仕様だったので、大きな改善
|
||||
* バッテリーの持ちの良さ
|
||||
* 15時間くらいは動く
|
||||
* 有線対応
|
||||
* 有線時もANCが働く
|
||||
* USB-C充電対応
|
||||
|
||||
## Cons
|
||||
|
||||
* マルチポイント時の混線ノイズ
|
||||
* 音楽再生中にもう一方のデバイスで何か通知音が鳴るとストリームに対して「プツプツ」ノイズが入る
|
||||
* システムサウンドが大きすぎる(変更不可)
|
||||
* 消耗部品の多さ
|
||||
* ヒンジ部分はケースに仕舞う度に動かなさいといけないため消耗が心配
|
||||
* 可動部が多いほど故障率は上がる
|
||||
* 本体側での接続先選択が不可能
|
||||
* QC30では出来ていた本体側のボタンで接続先を選択できる機能が無くなっていた
|
||||
* ボタン配置のミス
|
||||
* ボタンが手に触れやすい位置にあるため、ヘッドホンを外す度に間違って押してしまう
|
||||
* ストリーム元とボタンの送信先が異なるバグ
|
||||
* マルチポイント接続で一方のデバイスで音楽を流している際に、再生ボタンの信号が音楽を流していない方のデバイスに送信されてしまうバグがある
|
459
source/_posts/2019/english-note.md
Normal file
459
source/_posts/2019/english-note.md
Normal file
@@ -0,0 +1,459 @@
|
||||
---
|
||||
title: 英語メモ
|
||||
date: 2019-01-17T10:31:00.000+00:00
|
||||
redirect_from: "/blog/2019/01/17/english-note"
|
||||
---
|
||||
|
||||
雑多なメモです。
|
||||
|
||||
- spin up - 立ち上げる
|
||||
- woe - 悲しみ
|
||||
- a little too - 少し〜すぎる
|
||||
- all that much - それほど(否定形で)
|
||||
- family doesn't mean all that much to you.
|
||||
- articulate - 考えをはっきり述べられる
|
||||
- concordant - 調和した
|
||||
- ergo - それ故に
|
||||
- かたい ergo - thus - therefore - so やわらかい
|
||||
- endeavor - 努力
|
||||
- I myself struggle with the endeavor of mastering the English language
|
||||
- vis-à-vis - 〜と向かい合って、〜と比較して
|
||||
- takeaway - 要点
|
||||
- thoroughly - 徹底的に
|
||||
- have little to do with ほとんど関係がない
|
||||
- As well as I recall, - 記憶している限りでは、
|
||||
- He is more of a researcher - どちらかというと研究者だ
|
||||
- It is more a matter of feelings. - どちらかというと気持ちの問題だ
|
||||
- more of a curse than a blessing - メリットよりデメリットが多い
|
||||
- manifold — 多数の
|
||||
- three-fold — 三倍
|
||||
- evade — 避ける = avoid
|
||||
- a word that evades definition — 定義しにくい言葉
|
||||
- don't be fooled by A — A に惑わされるな
|
||||
- thrice — とても
|
||||
- Circuit Judge Joseph Bulone called 49-year-old Michael Drejka a “wanna-be” law enforcement officer and a self-appointed “handicapped parking space monitor.”
|
||||
- encapsulate — 包容している
|
||||
- atm — at this moment
|
||||
- so far — これまで
|
||||
- SMDH — Shaking My Damn Head
|
||||
- micro stutter — プログラム上の細微な遅延
|
||||
- When characters are missing from fonts, it's nice to be able to communicate to the user that this happened. — フォントに文字が欠けている場合、それをユーザーに伝えることができると便利です。
|
||||
- for the sake of A — A の名のもとに
|
||||
- Firefox has abandoned subpixel-AA for the sake of simplicity — Firefox はシンプルさの名のもとにサブピクセル AA を棄てました。
|
||||
- The entire idea behind subpixel-AA is that you are abusing how the pixels are laid out in a display. — サブピクセルアンチエイリアスは、ディスプレイにピクセルがどのように配置されているかという知識を基に成り立っています。
|
||||
- a reasonable balance — 適度なバランス
|
||||
- That said, — とはいえ、
|
||||
- A with B on it — B が乗っている A
|
||||
- can play a bit fast and loose with A — A を大雑把に扱える
|
||||
- current iteration of A — 現行の A
|
||||
- A doesn't play nice with B — B がため A が上手く動かない
|
||||
- our current iteration of search doesn't play nice with CJK characters
|
||||
- Tried out and see what happens — 試して成り行きを見てみた
|
||||
- Losing your shit — the state of being pushed over the edge of sanity and having a complete and utter freak out or mental/emotional breakdown ≒ お前は完全にイッちまうぜ
|
||||
|
||||
> And this is a Tech Forum, AND it's supposed to be a safe space. — そしてここは技術フォーラムであり、*かつ*心理的安全性が確保されているべき場所だ。
|
||||
> If you don't want to answer questions for "n00b", then don't answer. — "初心者"の質問に答えたくないなら、ただ口をつぐんでくれ
|
||||
|
||||
> Have you thought of what you’ll do after you retire? — 引退したらやりたいことについて考えたことある?
|
||||
|
||||
- any of those — これらどれでも (all of, every と交換可能 | 肯定文)
|
||||
|
||||
- there aren't any apples on the floor (否定の場合は any の後に複数形)
|
||||
|
||||
- you will likely do A — あなたは A することだろう
|
||||
|
||||
- 99% of the time this is what you want to use — 99%これを使えば良い
|
||||
|
||||
- The one catch is that — 例外は、
|
||||
|
||||
- I ended up settling for this which looks incredibly anti-pattern-y but was the only option that wouldn’t explode on me — 最終的にこれに落ち着いた。アンチパターンっぽいけど僕にとっては一番安定している
|
||||
|
||||
- Why was that even created? — まずなぜこれが作られたの?
|
||||
|
||||
- Putting the main code in another function serves two purposes:
|
||||
|
||||
- one week cannot and should not define any team
|
||||
|
||||
- it go to show that A — A ということの証明となる
|
||||
|
||||
- A is to not have B — 「A」とは、B を持たないことである
|
||||
|
||||
> wireless charging is kinda funny because it really goes to show that the only way to get the tech industry to agree on a unified connector is to not have a connector
|
||||
|
||||
> me: it’s not that I mind freelancing, I love it. It’s just that the social interaction is pretty minimal and extremely uneven day-to-day and sometimes I wonder how that will affect me long term, you know?
|
||||
> barista: ok are you going to order
|
||||
|
||||
- constitute, make up
|
||||
|
||||
> glad you’re happily situated elsewhere now. — あなたが他の場所で活躍しているようで嬉しい
|
||||
|
||||
- My dA account turned 10yo. In fact, I had spent 99% of the time as a lurker and six months ago finally started drawing and posting art.
|
||||
- A conditional request is one that triggers if something happens, like: "If you don't quit talking, I am gonna have to ask you to leave." In this case, you can't really say, "If you don't quit talking, I have to ask you to leave." So even though it's not really conditional, using a conditional form is more polite because it's less direct.
|
||||
- come to pass
|
||||
- come across
|
||||
|
||||
> I would also half-expect the following sentences to contain further information on this particular group of students, like this:
|
||||
|
||||
> It uses the definite article before "majority of the students", as if referring to a known group.
|
||||
|
||||
> This sentence uses the indefinite article before the "majority of the students". This has the effect of introducing this group of students to the reader or the listener.
|
||||
|
||||
> It may give a hint that the exact number of the students that will vote is uncertain: it could be 51%, but then it could be 88%.
|
||||
|
||||
> Design is not just a visual thing, it's a thought process. it's a skill.
|
||||
|
||||
- at will — 意思次第で
|
||||
- for asking — 望むなら
|
||||
- fuck A up — A をボコボコにする
|
||||
- friendly reminder - a euphemism for "this is the last warning"
|
||||
- I feel attached
|
||||
- I feel called out
|
||||
|
||||
> Lots of bittersweet feelings over this
|
||||
|
||||
- LRT: My favorite part of this is the upload on Youtube that's titled "Iwata vs Reggie (full fight)" like it was stitched together from multiple episodes of Naruto.
|
||||
- get around to — 先延ばしにしていたことにやっと取り掛かる
|
||||
- Finally got around to writing something on @ThePracticalDev, which was a really great experience!
|
||||
- wordy, lengthy — 言葉の多い、冗長な
|
||||
- A teenager not old to buy a six-pack — ビールも買えない年頃の子供
|
||||
- It is likely that 未来形 — 〜になるだろう
|
||||
- It's likely that the affair will come to nothing — どうやら無事に治まりそうだ
|
||||
- We will most likely do A — 我々は必ず A をするでしょう
|
||||
- chirring - 虫が鳴く; bugs chirring
|
||||
- what are you waiting for
|
||||
- with a grain of salt — 割り引いて(考えて)
|
||||
|
||||
> learning foreign languages is for me lifelong hobby. knowledge likely to requires much time to acquiring but it never decays.
|
||||
|
||||
> _sees client, whistles loudly_
|
||||
|
||||
> weston comes out of nowhere running on all fours like a gorilla towards client
|
||||
|
||||
> I don't even understand how there can be HOURS of planned downtime for a service like this.
|
||||
|
||||
> And what could go wrong, in depending on the internet to keep the child warm
|
||||
|
||||
> the developer advocate in question understands the language barrier, it would seem; he’s not a native English speaker. regardless, his stance puts many who haven’t had a strong English education at a disadvantage. it prioritizes “getting things done” over people...
|
||||
|
||||
> save my dying cactus. what's wrong. cactus should have been easy stuff since they barely need water.
|
||||
|
||||
> higher form of something
|
||||
|
||||
> i hope it will inspire Americans to pursue a second language
|
||||
|
||||
> I love the fact that
|
||||
|
||||
> let's see if the result is the same (spoiler alert: it wasn't)
|
||||
|
||||
> Feature engineering is when we use existing features to create new features to determine if they provide new signals to predict our outcome.
|
||||
|
||||
> The happiest moment of my life was when I passed the entrance test.
|
||||
|
||||
> Controversial opinion: Every single opinion is controversial.
|
||||
|
||||
- Actually, my younger brother is a bit of a chav. — 弟はちょっとヤンキーなんだよ。
|
||||
- take leap of faith 確証が持てないことを信じること(盲信とは違う)
|
||||
- icky — 古めかしい
|
||||
- adherence — 執着 one's adherence to A
|
||||
- belief — 信念
|
||||
- on principle — 道徳的見地から
|
||||
- in set terms — 決まり文句で
|
||||
- (Evening|Cold weather) has set in — (夜に|寒く)なった
|
||||
|
||||
> i feel like i'm most productive when i'm avoiding some other kind of responsibility
|
||||
|
||||
- be more of A — どちらかといえば A である; He is more of a researcher.
|
||||
- be more of A thant B — B というよりむしろ A だ
|
||||
- see less pain but also less joy — 痛みを感じることも少ないが喜びも少ない
|
||||
- in term of A — A の観点から
|
||||
|
||||
## Go
|
||||
|
||||
- go into 何かを始める;状態に入る;費やされる
|
||||
- go down 降りる;落ちる;低下する; go down on all fours — 四つん這いになる
|
||||
- go easy on fellow insiders 身内に甘い;身内に手加減する
|
||||
- go easy with her 彼女に優しくしろよ
|
||||
|
||||
## Get
|
||||
|
||||
- get over it (障害を)乗り越えろ
|
||||
- get out 出て行く
|
||||
- get down on A for B — B したことに大して A を批判し続ける
|
||||
- get down to [verb.] — やっと始める。
|
||||
- get in — 乗り込む
|
||||
- too much to take - 手に負えない
|
||||
- de rigueur - 慣習上必要不可欠
|
||||
- utterly - 完全に
|
||||
|
||||
> make sure you know what the author expects you to know.
|
||||
|
||||
- The doom-laden feeling that this creates in us is then intensified by our inability to remember the past;
|
||||
- smoke-laden 煙が立ち込めた
|
||||
- doom-laden 厭世観で満ちた
|
||||
|
||||
> Thanks to his help, we managed to finish the work in time. 彼のおかげでなんとか時間内に仕事を終えることできた
|
||||
|
||||
> Thanks to the development of medicine, people have been able to live longer.
|
||||
|
||||
> Owing to the rise in oil prices, people are forced to use public transportation.
|
||||
|
||||
> The balloon is likely to burst at any time その風船は今にも爆発しそうだ
|
||||
|
||||
> It is because the air was polluted that the experiment was a failure.
|
||||
> The experiment was a failure because the air was polluted.
|
||||
|
||||
> Thesis. Remote companies have less of an echo chamber since they are distributed. Thoughts?
|
||||
|
||||
> Obviously they should A, and B when C. Not D forever.
|
||||
|
||||
- Still - there is no A, just B.
|
||||
|
||||
> I think people are angry because Slack A, B and is C. No D, no E.
|
||||
|
||||
> Because he's the kind of person who likes helping others and is always gentle and kind as you described
|
||||
|
||||
> it was more difficult to get it wrong than guess it right!
|
||||
> XD
|
||||
|
||||
> I'm pretty sure there was a lot of uproar about the Equifax thing
|
||||
|
||||
## Idioms
|
||||
|
||||
- Don’t make me blush XD — 恥ずかしい XD
|
||||
- Think before you speak next time — 次からは考えてから話せ
|
||||
- just a citation of the law they're overcompensating for — 彼らは濫用している法律の引用ただそれだけしか示してない
|
||||
- repeal — 撤回する
|
||||
- no respect for their users — ユーザーに対する敬意がない
|
||||
- be now going the A route — 今度は A 作戦ときた
|
||||
- in a blunt fashion — 露骨なやり方で
|
||||
- "DM us, we'll take a look!" faux-friendly route — 偽りの友情作戦「DM で詳しく話を聞かせて!」
|
||||
- reinstate — (アカウントを)復活させる
|
||||
- shut the whole thing down — 全てを終わらせる
|
||||
- as if, as though — 後者は話者の疑いが現れている. 仮定法過去を取る. It's as if I were a movie star.
|
||||
- predominatly — 大抵は. Your costs are predominantly human labor.
|
||||
- a myriad of A — 無数の A
|
||||
- funnel toward 狭いところを前へと通る
|
||||
- in a verifiable manner — 検証可能な方法で
|
||||
- in a frigid manner — 冷たい態度で
|
||||
- are expressed as — 〜として表せる
|
||||
- a cup of tea — 好きなこと、得意なこと (It's not my cup of tea)
|
||||
- I have a lot on my plate — やることが沢山ある
|
||||
- It's a piece of cake — 朝飯前、超簡単
|
||||
- can enforce fine-grained control over — 何かをきめ細かく制御することができる
|
||||
- C’est la vie! — それが人生
|
||||
- What’s done is done — 終わったものは仕方ない
|
||||
- If you've got it, flaunt it — 良いものは隠さないで
|
||||
- clench my teeth — 歯を食いしばる(って耐える)
|
||||
|
||||
> Hello, I just came across this wonderful library and was really intrigued by it :)
|
||||
|
||||
> When teaching, be careful not to mix up "" and "".
|
||||
|
||||
- life saver under this condition
|
||||
- It turned to be such great experience, I couldn’t miss opportunity to share it
|
||||
- I like Makefiles, they are simple and yet very powerful.
|
||||
- To my surprise — 驚くべきことに
|
||||
- I did it out of curiosity — 興味本位でやった
|
||||
- If you're of the belt-and-suspenders mindset, consider setting UsePAM to 'no' as well. — 心配性な性格のこと
|
||||
- you can cancel it as long as it has not been matched — 〜されていない限りいつでも
|
||||
- By definition — 定義によると
|
||||
- A found B C — A は B が C だと思った
|
||||
- in that — という点において
|
||||
- Iconoclast — 因襲打破主義者
|
||||
|
||||
> Researchers spend a great deal of time doing something — 研究者は多くの時間を〜するのに割いています。
|
||||
|
||||
- ~ upon demand for ~ — ~の要請に応じて~
|
||||
- Granularity — 粒度
|
||||
- in a manner — いわば、ある意味
|
||||
- periodic – 定期的 <=> sporadic – 不定期的
|
||||
- abuse — 名詞は(a)bjú:s 動詞は(a)bjú:z
|
||||
- eavesdrop — 盗み聞きする
|
||||
- hypernym – 上位概念 <=> hyponym – 下位概念
|
||||
- in this case — 今回の場合
|
||||
- imply, represent, mean, stand for, refer to — 意味する
|
||||
- redundant — 余剰であり過剰であり不必要なもの
|
||||
- appropriate, proper, reasonable — 妥当な
|
||||
- barely — かろうじて、ほとんど〜ない
|
||||
|
||||
> The iPad already has external keyboard support and an external trackpad support would go a long way to making the iPad a Mac replacement.
|
||||
|
||||
> Countless wrong inferences could be drawn from those observation.
|
||||
|
||||
- it drives me crazy [nuts] — イライラさせられる
|
||||
- describes the steps that are involved in ~ — ~に関する手順について説明する
|
||||
- 前置詞 in は特徴の違いを、of は程度の違いを表す
|
||||
- A is in proportion to B — A は B に比例している
|
||||
- A is out of proportion to B — A は B に反比例している
|
||||
- 受動態は不自然に手を加えられて発生した結果に付随する、能動態は自然に発生した場合に付随する — our profits were increased は不正があったかのような表現、our profits increased が正しい
|
||||
- be collectively known as A — A と総称されている
|
||||
- Any links to this, as to be honest nobody is providing evidence, just lip-service relying on the ignorance of most readers
|
||||
- in a great hurry - 大急ぎで
|
||||
- gross 名詞 — 明らかな〜, a gross oversimplification - 明らかに過度な簡略化
|
||||
- among — 〜の間で — in, through で代替可能
|
||||
- throw A away — A を捨てる、A を無駄にする
|
||||
- throw A up — 急にやめる
|
||||
- be quick to — すぐ〜する。(People are quick to alienate outsiders 人々はすぐよそ者を阻害する)
|
||||
- incredulous at — 〜を容易に信じない
|
||||
- lack of standards for — 〜に対するけじめの無さ
|
||||
- ludicrous, ridiculous — 馬鹿げた
|
||||
- derogatory — 差別的な
|
||||
- A that it was B — A だったので、B , 便利な接続詞
|
||||
- After (p.p.), He (p.) — 〜の後、彼は〜した
|
||||
- vicious — 凶悪な
|
||||
- relentless, ruthless — しつこく、in の時は徹底的な
|
||||
- mercilessly — 無慈悲に
|
||||
- reckless — 無謀な
|
||||
- profound — 心理的影響が重大な、深刻な(物理的には deep が適切)
|
||||
|
||||
> I felt like a coward hiding this from people — それを隠すことで自分が臆病者に思えた
|
||||
|
||||
> While training for the marathon, she was relentless in following the same schedule — マラソンの練習の間、彼女は同じスケジュールをしつこいほど守った。
|
||||
|
||||
- His history of A led to B — 彼が A を繰り返したせいで B を招いた。
|
||||
- hatred — 憎悪
|
||||
- coarse — 粗い
|
||||
- B with A everywhere — A がいたるところに散乱している B
|
||||
- people, all, the crowd — 人々
|
||||
|
||||
> A was quick to spot the potential of the Internet — A はインターネットの可能性をいち早く見出した
|
||||
|
||||
- a man who's nice to be around — そばに居てくれると助かる親切な人
|
||||
- His generosity knows no bounds — 彼の寛大さには限りが無い
|
||||
- borad-minded — 心が広い
|
||||
- in one way or the other — どのみち、ある意味 e.g. This inspired you in one way or the other これはある意味あなたをインスピレートした
|
||||
- to some extent — ある程度は、e.g. Travelling only helps to some extent 旅行はある程度それを助ける
|
||||
- close-knit — 密接に関係している
|
||||
- hot take — 走り書き
|
||||
- cost an arm and a leg — 大変な金がかかる
|
||||
- person with a forgiving nature — 寛大な心の持ち主
|
||||
- we are on the same page — これで我々の認識が一致しましたね
|
||||
- in that — という点で。 Man differ from animals in that they can think and speak.
|
||||
- That said, — とは言え。ですから。
|
||||
|
||||
p.p. the present progressive form, 現在進行系
|
||||
|
||||
- There have long been allegations that という噂がある
|
||||
- The antisocial behaviour you are naturing あなたが心に抱いている反社会的行動
|
||||
- have a lot to do with ~によるところが大きい
|
||||
|
||||
一般に前置詞+ who(m)は既知の情報を確認する際に, who +前置詞は新しい情報を求める際に好まれる
|
||||
|
||||
> This is sure to satisfy those who are into computers. これはコンピュータにはまっている人をきっと満足させるだろう
|
||||
|
||||
> I've always wanted to study abroad someday but I haven't been able to yet.
|
||||
|
||||
## 複文と分詞構文
|
||||
|
||||
- A typhoon hit the city, causing big destruction.
|
||||
- While skiing in Hakuba, I twisted my ankle.
|
||||
- Not knowing what to say, she kept silent.
|
||||
- Seeing me, the man ran away. ←→ As the man saw me, he ran away.
|
||||
- Written in simple English, this book is easy to understand. ←→ Since this book is written in simple English, it is easy to understand.
|
||||
- Walking along the beach, I found a beautiful shell. ←→ When I was walking along the beach, I found a beautiful shell.
|
||||
- and そうすれば or 然もなくば but けれども so だから、それで for というのも nor 〜もまた、〜ではない
|
||||
- She is not a politician, nor is she a diplomat.
|
||||
|
||||
## when
|
||||
|
||||
1. 未来の条件を表す場合は現在形を使う When I arrive at the station, I'll call you.
|
||||
2. 過去の時を表す場合は過去形 When I was a child, I used to like soccer.
|
||||
3. 未来の可能性を話す場合は未来形 I don't know when he will come.
|
||||
|
||||
- happened to — たまたま、偶然、もしかして
|
||||
- Do you happen to know if she has a boyfriend? — あの子に彼氏いるのかな?
|
||||
|
||||
不定詞は名詞・形容詞・副詞的働きをする動詞ベースの詞のこと
|
||||
|
||||
to 不定詞が unrealized(未実現)、-ing が realized(実現)
|
||||
|
||||
- I want (to eat an apple)← 名詞的
|
||||
- Thank you for playing the game
|
||||
|
||||
1. She is studying English hard to study abroad.
|
||||
2. She study English hard to study abroad.
|
||||
|
||||
違いは?
|
||||
|
||||
- only to A — 思わぬ悲観的な事実を説明する clause
|
||||
- He returned after the war only to be told that his wife had left him.
|
||||
- I tore open the box, only to discover that some of the parts were missing.
|
||||
- I arrived only to find that the others had already left.
|
||||
|
||||
## 倒置法
|
||||
|
||||
- So do I — 私も!(I like apple に対して)
|
||||
- So am I — 私も!(I'm twenty years old に対して)
|
||||
- Here comes bus — もうバス来たよ
|
||||
- Here we go — ほら行こう
|
||||
- In you go — 中にお入り
|
||||
- What a shitty day — なんて日だ
|
||||
- How beautiful (that is) — なんて綺麗なの
|
||||
- "I'm fine", said he — 大丈夫だと彼は言った
|
||||
- Dark as(though) it was, I found the footprints. — 暗かったが、なんとか足跡を見つけた
|
||||
- Hard though she tried, she couldn't make the deadline. — 頑張ったが間に合わなかった
|
||||
- Do what you will, I won't give up — 何をされようとも諦めない
|
||||
- Walk as he would, he couldn't get to the station. — どんなに歩いても駅にたどり着けなかった
|
||||
|
||||
> "We live in a world of churn, but we do not have to accept high churn rates as the only reality." from "Subscription Marketing: Strategies for Nurturing Customers in a World of Churn (English Edition)" by Anne Janzer
|
||||
> 45 Ways To Avoid Using The Word 'Very' - Writers Write
|
||||
|
||||
> I still hate that "atheist" now is code for "bigoted asshole."
|
||||
|
||||
> Life only comes around once. So do whatever makes you happy and be with whoever makes you smile!๑╹◡╹)ノ…
|
||||
|
||||
> This is exactly what I thought was gonna happen when I saw those tweets, thank you…
|
||||
|
||||
> @Nodejs and @the_jsf have merged to form the #OpenJSFoundation! The OpenJS Foundation is to become the central place to support collaborative development of #JavaScript and web technologies.
|
||||
|
||||
> I love critical thinking and I admire skepticism, but only within a framework that respects the evidence.
|
||||
|
||||
> In earlier versions of TypeScript, we generalized mapped types to operate differently on array-like types. This meant that a mapped type like Boxify could work on arrays and tuples alike.
|
||||
|
||||
> a cool thing about the last few years is that the U.S. became the leading exporter of the intellectual machinery of western fascism and one of the leading domestic debates about it is whether undergrads are treating the people behind it politely enough
|
||||
|
||||
> Perhaps it would be less of a debate if they were more circumspect in who/what they call fascism. The main criticism seems to be that they have a lot of false positives in their "fascist-test" and treat anyone who points this out as fascist fellow travellers
|
||||
|
||||
> Universities are filled with people who feel like they are competing against their colleagues. When you do this, you end up constantly looking in front of you, feeling bitter. Or looking behind you, becoming arrogant. Run your own race.
|
||||
> — Marc Lamont Hill
|
||||
> https://twitter.com/marclamonthill/status/1109500482500939776?s=12
|
||||
|
||||
> Much discussion about bias in ML due to the training dataset - this has been an active area of study for a long time in population genetics, and is still not fully resolved
|
||||
> — Miriam Huntley
|
||||
> https://twitter.com/iam_mir_iam/status/1108819635959418881?s=12
|
||||
|
||||
> Welcome to the FGO NA Twitter. If you look to your left, you'll see the salty people club that are currently sulling about not pulling Okita. If you look to your right, you'll see the angry weeb club still screeching about Emiya Alter. Please enjoy your stay.…
|
||||
> — ℭ𝔦𝔫𝔡𝔢𝔯 𝔉𝔞𝔩𝔩
|
||||
> https://twitter.com/zettainverse/status/1109231751019278337?s=12
|
||||
|
||||
> Probably one of the most auto-bookmarkable post I've seen in a while, regardless of skill level with git:
|
||||
> — Ben Halpern 🤗
|
||||
> https://twitter.com/bendhalpern/status/1135319291568562176?s=12
|
||||
|
||||
> Now announcing tsconfig-api 🎉 An experimental microservice for retrieving @typescript compiler option details 🔎 100% open source and hosted by @zeithq Now
|
||||
> — Matterhorn
|
||||
> https://twitter.com/matterhorndev/status/1138610398159147008?s=12
|
||||
|
||||
> Amid all of the chaos, an answer could be found.
|
||||
> There’s a special kind of joy in UI libraries when you see small primitives working. Like maybe it’s a two rectangle demo. But you’ve already learned that thanks to composition, if it worked for two rectangles, you can make it work for a whole FB/Twitter-level app.
|
||||
> — Dan Abramov
|
||||
> https://twitter.com/dan_abramov/status/1143911059717263360?s=12
|
||||
|
||||
> Yes, assuming something will work like literally every other software that has ever been created will work is subjective.
|
||||
> Super annoying that these people are so insecure about themselves that they have to do that kind of thing.…
|
||||
> — Kent C. Dodds
|
||||
> https://twitter.com/kentcdodds/status/1147142716280602629?s=12
|
||||
|
||||
> Honest question: how does banning people from an opportunity to build a professional presence and potentially escape an oppressive regime advance human rights?…
|
||||
> — Dan Abramov
|
||||
> https://twitter.com/dan_abramov/status/1154871232459956224?s=12
|
||||
|
||||
> The national flag of Japan is a rectangular white banner bearing a crimson-red disc at its center. This flag is officially called Nisshōki (日章旗, the "sun-mark flag"), but is more commonly known in Japan as Hinomaru (日の丸, the "circle of the sun"). It embodies the country's sobriquet: Land of the Rising Sun.
|
||||
> reading this tweet is weird because at first you're like "hahaha they're not used to how gacha works" then you realize you've just been conditioned into being ok with predatory game models
|
||||
> You're offering subjective value assessments, not facts.…
|
||||
> — Levi Roach
|
||||
> https://twitter.com/DrLRoach/status/1172907254892421120?s=17
|
||||
|
||||
> My takeaway is that I'm starting a support group for design systems engineers across the world. 😛 We're all going through different versions of the same challenges at each of our companies and it's always encouraging to share information about where we are in this journey.
|
||||
> — Maja Wichrowska
|
||||
> https://twitter.com/majapw/status/1187891828189589504?s=17
|
59
source/_posts/2019/give-your-app-slick-name.md
Normal file
59
source/_posts/2019/give-your-app-slick-name.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: Give Your App Slick Name with namae.dev
|
||||
date: 2019-08-29 03:12:00 +09:00
|
||||
---
|
||||
|
||||
Have you ever struggled with naming your new OSS project or web app? While hoping no one claimed your desired one in GitHub, npm, Homebrew, PyPI, Domains, etcetera, choosing the best name is weary work.
|
||||
|
||||
That's why I created [namae](https://namae.dev).
|
||||
|
||||
# namae
|
||||
|
||||

|
||||
[namae](https://namae.dev) is an inter-platform name availability checker for developers and entrepreneurs.
|
||||
|
||||
Once you fill out a form with a name you want to use, namae will check through various registries and check if the name is already in use or not.
|
||||
|
||||

|
||||
|
||||
# Supported Platforms
|
||||
|
||||
namae supports 15 package registries and web platforms, and it's growing.
|
||||
|
||||
- Domains
|
||||
- GitHub Organization
|
||||
- npm / npm Organization
|
||||
- PyPI
|
||||
- RubyGems
|
||||
- Rust (crates.io)
|
||||
- Homebrew / Homebrew Cask
|
||||
- Linux (Launchpad & APT)
|
||||
- Twitter
|
||||
- Spectrum
|
||||
- Slack
|
||||
- Heroku
|
||||
- ZEIT Now
|
||||
- AWS S3
|
||||
- js.org
|
||||
|
||||
Additionally, the search result comes with a list of projects which has a similar name on **GitHub** and **App Store**.
|
||||
|
||||
# Name Suggestion
|
||||
|
||||
namae also has a unique feature called __Name Suggestion__. It suggests auto-generated names made up of common prefix/suffix and synonyms. Take look at some examples.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Clicking the suggestion, namae completes the form with it and start searching around the registries.
|
||||
|
||||
# Open Source
|
||||
|
||||
namae is completely open-sourced and the entire source code is available at [GitHub](https://github.com/uetchy/namae). It consists of Node.js Lambda for APIs and React app for the web frontend, and is running on [ZEIT Now](https://now.sh).
|
||||
|
||||
# Conclusion
|
||||
|
||||
namae saves your time searching for a universally available name around a set of hosting providers and package registries.
|
||||
|
||||
Go to [namae.dev](https://namae.dev/) and grab a report for the availability of your future product name. If you have any suggestion, poke me on Twitter ([@uechz](https://twitter.com/uechz)).
|
34
source/_posts/2019/padsize.md
Normal file
34
source/_posts/2019/padsize.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: padStartにおけるpadSizeの求め方
|
||||
date: 2019-01-14 00:00:00 +09:00
|
||||
redirect_from: "/blog/2019/01/14/padsize"
|
||||
---
|
||||
|
||||
padStart における padSize の求め方です。
|
||||
|
||||
$$
|
||||
\textrm{padSize} = \lceil \log_{10}(\mathbf{arraySize} + 1) \rceil
|
||||
$$
|
||||
|
||||
```js
|
||||
const padSize = Math.ceil(Math.log10(arr.length + 1));
|
||||
|
||||
arr.forEach((item, index) => {
|
||||
console.log(`${index.padStart(padSize, "0")}: ${item}`);
|
||||
});
|
||||
```
|
||||
|
||||
結果は以下のようになる。
|
||||
|
||||
```
|
||||
01: item1
|
||||
02: item2
|
||||
03: item3
|
||||
04: item4
|
||||
05: item5
|
||||
06: item6
|
||||
07: item7
|
||||
08: item8
|
||||
09: item9
|
||||
10: item10
|
||||
```
|
187
source/_posts/2019/sign-and-notarize-electron-app.md
Normal file
187
source/_posts/2019/sign-and-notarize-electron-app.md
Normal file
@@ -0,0 +1,187 @@
|
||||
---
|
||||
title: Electronアプリをコード署名してApple 公証 (Notary) を通過させる方法
|
||||
date: 2019-06-05 00:00:00 +09:00
|
||||
redirect_from: "/blog/2019/06/05/sign-and-notarize-electron-app"
|
||||
---
|
||||
|
||||
electron-builder を利用して macOS 向け Electron アプリをコード署名し、公証を通過させます。
|
||||
|
||||
> **tl;dr**: コード署名と公証に対応した macOS アプリ Juno のリポジトリを[GitHub で公開](https://github.com/uetchy/juno)しています
|
||||
|
||||
# Code Sign
|
||||
|
||||
アプリのコード署名は`electron-builder`によって自動で行われます。内部的には[electron-osx-sign](https://github.com/electron-userland/electron-osx-sign)が使用されます。
|
||||
|
||||
リリース用のアプリにコード署名をするには、Keychain に有効な Developer ID Certificate が格納されている必要があります。macOS Developer Certificate は開発用のコード署名のみ可能なので、リリース用としては不十分です。
|
||||
|
||||
まだ証明書を発行していない場合は、[Apple Developer](https://developer.apple.com/account/resources/certificates/list)で証明書の追加ウィザードに進み、**Developer ID Application**を選択して証明書を発行してください。
|
||||
|
||||
# Notarize
|
||||
|
||||
コード署名済みのアプリを[electron-notarize](https://github.com/electron-userland/electron-notarize)を使用して Apple Notary Service に提出します。
|
||||
|
||||
```js
|
||||
const { notarize } = require("electron-notarize");
|
||||
notarize({
|
||||
appBundleId,
|
||||
appPath,
|
||||
appleId,
|
||||
appleIdPassword,
|
||||
ascProvider,
|
||||
});
|
||||
```
|
||||
|
||||
- **appBundleId**: アプリの Bundle ID です。`package.json`の`build.appId`と同じものを使います。
|
||||
- **appPath**: `.app`の絶対パスを指定します。
|
||||
- **appleId**: Apple Developer として登録している Apple ID を指定します。
|
||||
- **appleIdPassword**: Apple ID のパスワードです。2 要素認証を必要としないパスワードが必要なので、[Apple ID](https://appleid.apple.com/#!&page=signin)にアクセスして**App-specific Password**を発行してください。
|
||||
- **ascProvider**: Apple Developer の Membership に記載されている**Team ID**を指定します。
|
||||
|
||||
## electron-builder の afterSign フック
|
||||
|
||||
electron-builder の afterSign フックを使用して、コード署名が済んだアプリを自動で Notary に提出します。
|
||||
|
||||
フックスクリプトを`./scripts/after-sign-mac.js`に置きます。
|
||||
|
||||
```js
|
||||
const path = require("path");
|
||||
const { notarize } = require("electron-notarize");
|
||||
|
||||
const appleId = process.env.APPLE_ID;
|
||||
const appleIdPassword = process.env.APPLE_PASSWORD;
|
||||
const ascProvider = process.env.ASC_PROVIDER;
|
||||
|
||||
const configPath = path.resolve(__dirname, "../package.json");
|
||||
const appPath = path.resolve(__dirname, "../dist/mac/App.app");
|
||||
const config = require(configPath);
|
||||
const appBundleId = config.build.appId;
|
||||
|
||||
async function notarizeApp() {
|
||||
console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`);
|
||||
await notarize({
|
||||
appBundleId,
|
||||
appPath,
|
||||
appleId,
|
||||
appleIdPassword,
|
||||
ascProvider,
|
||||
});
|
||||
console.log("afterSign: Notarized");
|
||||
}
|
||||
|
||||
exports.default = async () => {
|
||||
await notarizeApp();
|
||||
};
|
||||
```
|
||||
|
||||
`package.json`の`build`に`afterSign`を追加してコード署名が終わった後にスクリプトが実行されるようにします。
|
||||
|
||||
```json
|
||||
"build": {
|
||||
"afterSign": "./scripts/after-sign-mac.js"
|
||||
}
|
||||
```
|
||||
|
||||
## Hardened Runtime and Entitlements
|
||||
|
||||
このままでは公証に失敗します。デフォルトで書き出されるバイナリでは、セキュリティの強化された[Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime_entitlements)が有効になっていないためです。以下のようなエラーメッセージを貰います。
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "Invalid",
|
||||
"statusSummary": "Archive contains critical validation errors",
|
||||
"statusCode": 4000,
|
||||
"issues": [
|
||||
{
|
||||
"severity": "error",
|
||||
"code": null,
|
||||
"path": "App.zip/App.app/Contents/MacOS/App",
|
||||
"message": "The executable does not have the hardened runtime enabled.",
|
||||
"docUrl": null,
|
||||
"architecture": "x86_64"
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`package.json`の`build.mac.hardenedRuntime`を`true`にして Hardened Runtime を有効にします。
|
||||
|
||||
```json
|
||||
"build": {
|
||||
"mac": {
|
||||
"hardenedRuntime": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Hardened Runtime 下では、必要に応じて Entitlement を指定しなくてはなりません。Electron の実行には`allow-unsigned-executable-memory`という Entitlement が必要なので、`entitlement.plist`ファイルを`build`フォルダに作成し、以下のような plist を記述します。
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
`package.json`の`entitlements`及び`entitlementsInherit`に Entitlment が記述された plist のファイルパスを指定します。
|
||||
|
||||
```json
|
||||
"build": {
|
||||
"mac": {
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "./src/build/entitlement.plist",
|
||||
"entitlementsInherit": "./src/build/entitlement.plist"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Hardened Runtime で Electron を実行することができるようになったので、Notary を通過できる状態になりました。
|
||||
|
||||
実際に`electron-builder`を実行してすべてのプロセスが上手く動作することを確かめてください。
|
||||
|
||||
# Verify Notary Status
|
||||
|
||||
ただしく公証を得られたかどうかは`altool`で調べることができます。
|
||||
|
||||
公証通過後に送られてくるメールに`Request Identifier`が記載されているのでメモします。
|
||||
|
||||
```
|
||||
Dear Yasuaki,
|
||||
|
||||
Your Mac software has been notarized. You can now export this software and distribute it directly to users.
|
||||
|
||||
Bundle Identifier: <Bundle ID>
|
||||
Request Identifier: <UUID>
|
||||
|
||||
For details on exporting a notarized app, visit Xcode Help or the notarization guide.
|
||||
Best Regards,
|
||||
Apple Developer Relations
|
||||
```
|
||||
|
||||
`xcrun altool --notarization-info`コマンドに UUID と Apple ID、パスワードを指定して公証ステータスを確認します。
|
||||
|
||||
```
|
||||
xcrun altool --notarization-info <UUID> -u $APPLE_ID -p $APPLE_PASSWORD
|
||||
```
|
||||
|
||||
正しく公証が得られている場合は以下のようなメッセージが表示されます。おめでとうございます!
|
||||
|
||||
```
|
||||
2019-06-05 13:51:18.236 altool[5944:261201] No errors getting notarization info.
|
||||
|
||||
RequestUUID: <UUID>
|
||||
Date: 2019-06-05 04:45:54 +0000
|
||||
Status: success
|
||||
LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/<Log file identifier>
|
||||
Status Code: 0
|
||||
Status Message: Package Approved
|
||||
```
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [Resolving Common Notarization Issues](https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/resolving_common_notarization_issues)
|
||||
- [Notarizing your Electron application](https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/)
|
||||
- [Feature request: Enable hardened runtime for macOS #3383](https://github.com/electron-userland/electron-builder/issues/3383)
|
207
source/_posts/2019/welch-t-test.md
Normal file
207
source/_posts/2019/welch-t-test.md
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
title: プログラムの速度改善が誤差かどうかを統計的に調べる
|
||||
date: 2019-10-03 17:21:00 +09:00
|
||||
---
|
||||
|
||||
**Welch の t 検定**を用いて 2 つのベンチマークの分布の平均が等しい(速度差は誤差の範疇)か、あるいは異なる(=有意な速度改善が成されている)かどうかを判定します。
|
||||
|
||||
ベンチマーク用の TypeScript プログラムを用意します。
|
||||
|
||||
```ts a.ts
|
||||
function a() {
|
||||
const noise = Math.random() - 0.5;
|
||||
const offset = 1.0;
|
||||
const t = noise * 2 + offset;
|
||||
setTimeout(() => console.log(t), t * 1000);
|
||||
}
|
||||
a();
|
||||
```
|
||||
|
||||
```ts b.ts
|
||||
function b() {
|
||||
const noise = Math.random() - 0.5;
|
||||
const offset = 2.0;
|
||||
const t = noise * 2 + offset;
|
||||
setTimeout(() => console.log(t), t * 1000);
|
||||
}
|
||||
b();
|
||||
```
|
||||
|
||||
まず[hyperfine](https://github.com/sharkdp/hyperfine)で 2 つの プログラムのベンチマークを取り、`result.json`に保存します。
|
||||
|
||||
```shell
|
||||
hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
||||
```
|
||||
|
||||
`result.json`の中身は以下のようになります。
|
||||
|
||||
```json result.json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"command": "ts-node a.ts",
|
||||
"mean": 1.9369869248950002,
|
||||
"stddev": 0.6074252496423262,
|
||||
"median": 2.005230080295,
|
||||
"user": 1.549546345,
|
||||
"system": 0.08031985000000001,
|
||||
"min": 0.8807363742950001,
|
||||
"max": 2.830435366295,
|
||||
"times": [
|
||||
1.4010462692949999,
|
||||
2.830435366295,
|
||||
1.010024359295,
|
||||
1.159667609295,
|
||||
1.8311979602950001,
|
||||
...
|
||||
]
|
||||
},
|
||||
{
|
||||
"command": "ts-node b.ts",
|
||||
"mean": 2.833931665055,
|
||||
"stddev": 0.6505564501747996,
|
||||
"median": 2.7373719187950005,
|
||||
"user": 1.5474132649999999,
|
||||
"system": 0.07978893000000001,
|
||||
"min": 1.938184970295,
|
||||
"max": 3.946562622295,
|
||||
"times": [
|
||||
2.2806011012950003,
|
||||
2.0140897212950004,
|
||||
2.1835023382950003,
|
||||
2.304886362295,
|
||||
3.8122057912950003,
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> t 検定はサンプルが正規分布に従っているという仮定を置いているので、大数の法則から本当はもっと試行回数を増やした方が良いです。
|
||||
|
||||
この`result.json`の`times`配列を受け取り、2 つの分布間に有意差があるかどうかを判定します。
|
||||
|
||||
```ts
|
||||
import fs from "fs";
|
||||
import { jStat } from "jstat";
|
||||
|
||||
const log = console.log;
|
||||
|
||||
const sum = (x: number[]) => x.reduce((a: number, b: number) => a + b); // 総和
|
||||
const sqsum = (x: number[], mu: number) =>
|
||||
x.reduce((a: number, b: number) => a + (b - mu) ** 2); // 自乗誤差の総和
|
||||
|
||||
function ttest(X: number[], Y: number[]) {
|
||||
const Xn = X.length; // サンプル数
|
||||
const Yn = Y.length;
|
||||
log(`Xn = ${Xn}`);
|
||||
log(`Yn = ${Yn}`);
|
||||
|
||||
const X_mu = sum(X) / Xn; // 平均
|
||||
const Y_mu = sum(Y) / Yn;
|
||||
log(`X_mu = ${X_mu}`);
|
||||
log(`Y_mu = ${Y_mu}`);
|
||||
|
||||
const X_sigma = sqsum(X, X_mu) / (Xn - 1); // 不偏分散
|
||||
const Y_sigma = sqsum(Y, Y_mu) / (Yn - 1);
|
||||
log(`X_sigma = ${X_sigma}`);
|
||||
log(`Y_sigma = ${Y_sigma}`);
|
||||
const t = (X_mu - Y_mu) / Math.sqrt(X_sigma / Xn + Y_sigma / Yn); // t値
|
||||
log(`t = ${t}`);
|
||||
const df =
|
||||
(X_sigma + Y_sigma) ** 2 /
|
||||
(X_sigma ** 2 / (Xn - 1) + Y_sigma ** 2 / (Yn - 1)); // 自由度
|
||||
log(`df = ${df}`);
|
||||
return jStat.studentt.cdf(-Math.abs(t), df) * 2.0; // p値
|
||||
}
|
||||
|
||||
const filename = process.argv.slice(2)[0];
|
||||
const result = JSON.parse(fs.readFileSync(filename).toString());
|
||||
const X = result.results[0].times;
|
||||
const Y = result.results[1].times;
|
||||
const p = ttest(X, Y);
|
||||
log(`p = ${p}`);
|
||||
log(`p < 0.05 = ${p < 0.05}`);
|
||||
log(p < 0.05 ? "Possibly some difference there" : "No difference");
|
||||
```
|
||||
|
||||
ここで`X_mu`は分布 X の平均、`X_sigma`は分布 X の不偏分散です。
|
||||
|
||||
$$
|
||||
\begin{eqnarray}
|
||||
\mu_X &=& \frac{1}{n_X} \sum^{n_X}_i X_i\\
|
||||
\sigma_X &=& \frac{1}{n_X-1}\sum^{n_X}_i (X_i - \mu_X)^2
|
||||
\end{eqnarray}
|
||||
$$
|
||||
|
||||
これを X と Y 両方に対して求めます。さらに以下のようにして t を求めます。
|
||||
|
||||
$$
|
||||
t = \frac{\mu_X - \mu_Y}{\sqrt{\frac{\sigma_X}{n_X} + \frac{\sigma_Y}{n_Y}}}
|
||||
$$
|
||||
|
||||
t 分布の累積密度関数 (Cumlative Distribution Function; CDF) を定義します。面倒すぎたので[jstat](https://github.com/jstat/jstat)の`studentt.cdf`を使ってます。コードを見ると、分子の積分は[シンプソンの公式](https://ja.wikipedia.org/wiki/シンプソンの公式)を使って近似していました。
|
||||
|
||||
$$
|
||||
\text{CDF} =\frac{\int_0^{\frac{v}{t^2+v}}\frac{r^{\frac{v}{2}-1}}{\sqrt{1-r}}dr{}}{\text{exp}(\ln(\Gamma(\frac{v}{2}))+\ln(\Gamma(0.5))+\ln(\Gamma(\frac{v}{2}+0.5)))}
|
||||
$$
|
||||
|
||||
CDF を用いて p 値を求めます。両側検定をするので 2 を掛けます。t 分布の自由度 (degree of freedom; df) は$n-1$なので、両分布の自由度を$n_X+n_Y-2$で与えます。本当は
|
||||
|
||||
$$
|
||||
\text{df} = \frac{(\sigma_X + \sigma_Y)^2}{
|
||||
\frac{\sigma_X^2}{n_X - 1} + \frac{\sigma_Y^2}{n_Y - 1}}
|
||||
$$
|
||||
|
||||
で求める必要がありますが、さぼって近似しました。
|
||||
|
||||
$$
|
||||
p = \text{CDF}(-|t|, n_X+n_Y-2) \times2
|
||||
$$
|
||||
|
||||
## 結果
|
||||
|
||||
異なる実行時間を示すプログラム`a`,`b`を比較すると、2 つの分布の平均が異なることが示唆されました。
|
||||
|
||||
```
|
||||
❯ ts-node test.ts ab.json
|
||||
Xn = 10
|
||||
Yn = 10
|
||||
X_mu = 1.8022945422950003
|
||||
Y_mu = 2.9619571628950006
|
||||
X_sigma = 0.6067285795623545
|
||||
Y_sigma = 0.6593856215802901
|
||||
t = -3.2590814831310353
|
||||
df = 17.968919419652778
|
||||
-0.0001571394779906754
|
||||
p = 0.004364964634417297
|
||||
p < 0.05 = true
|
||||
Possibly some difference there
|
||||
```
|
||||
|
||||
p 値が 0.05 未満となり、帰無仮説「2つの分布は等しい」が棄却されたので「2つの分布は等しくない」ことがわかりました。同じプログラム同士でベンチマークを取るとどうなるでしょうか。
|
||||
|
||||
```
|
||||
❯ ts-node test.ts aa.json
|
||||
Xn = 10
|
||||
Yn = 10
|
||||
X_mu = 1.7561671737900002
|
||||
Y_mu = 1.9892996860899999
|
||||
X_sigma = 0.5127362786380443
|
||||
Y_sigma = 0.442053230382934
|
||||
t = -0.754482245774979
|
||||
df = 17.901889803947558
|
||||
-27359.526584574112
|
||||
p = 0.4603702896905685
|
||||
p < 0.05 = false
|
||||
No difference
|
||||
```
|
||||
|
||||
p 値が 0.05 未満ではないので、帰無仮説は棄却されず、つまり「2つの分布は等しい」ことがわかりました。
|
||||
|
||||
ウェルチの t 検定はスチューデントの t 検定と違って等分散性(2つの分布の分散が等しいこと)を仮定しないので、とても取り扱いやすい検定です。もちろん等分散性のある分布でも使用できるので、基本的にはウェルチの方法を使う方針で良さそうです。
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [Welch's t-test - Rosetta Code](https://rosettacode.org/wiki/Welch%27s_t-test)
|
22
source/_posts/2020/secure-dev-server.md
Normal file
22
source/_posts/2020/secure-dev-server.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: Securing Local Dev Server
|
||||
date: 2020-02-07 00:00:00 +0900
|
||||
---
|
||||
|
||||
Sometimes you want to interact with a local webserver with https support because of some browser APIs that are only available in an https environment.
|
||||
|
||||
You can easily create a self-signed TLS cert for development purposes with [`mkcert`](https://github.com/FiloSottile/mkcert).
|
||||
|
||||
```bash
|
||||
brew install mkcert
|
||||
mkcert -install # Install the local CA in the OS keychain
|
||||
```
|
||||
|
||||
After installing `mkcert` and generating system-wide local CA cert, you can create a certificate for each project.
|
||||
|
||||
```bash
|
||||
cd awesome-website
|
||||
mkcert localhost # this will generate ./localhost.pem and ./localhost-key.pem
|
||||
npm install -g serve
|
||||
serve --ssl-cert ./localhost.pem --ssl-key ./localhost-key.pem
|
||||
```
|
600
source/_posts/2021/arch-linux-setup-guide.md
Normal file
600
source/_posts/2021/arch-linux-setup-guide.md
Normal file
@@ -0,0 +1,600 @@
|
||||
---
|
||||
title: Arch Linux Setup Guide
|
||||
date: 2021-02-12
|
||||
---
|
||||
|
||||
This note includes all commands I typed when I setup Arch Linux on my new baremetal server.
|
||||
|
||||
# Why I choose Arch Linux
|
||||
|
||||
- Simple as it should be
|
||||
- Outstanding community efforts to maintaining package registry
|
||||
- Well organized wiki resources
|
||||
|
||||
# Useful links
|
||||
|
||||
- [General recommendations](https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups)
|
||||
- [System maintenance](https://wiki.archlinux.org/index.php/System_maintenance)
|
||||
- [Improving performance](https://wiki.archlinux.org/index.php/Improving_performance#Know_your_system)
|
||||
- [Benchmarking - ArchWiki](https://wiki.archlinux.org/index.php/Benchmarking)
|
||||
|
||||
# Provisioning
|
||||
|
||||
## wipe whole disk
|
||||
|
||||
```bash
|
||||
wipefs -a /dev/sda
|
||||
```
|
||||
|
||||
## create parition
|
||||
|
||||
```bash
|
||||
parted
|
||||
|
||||
select /dev/sda
|
||||
mktable gpt
|
||||
mkpart EFI fat32 0 512MB # EFI
|
||||
mkpart Arch ext4 512MB 100% # Arch
|
||||
set 1 esp on # flag part1 as ESP
|
||||
quit
|
||||
```
|
||||
|
||||
## install file-system
|
||||
|
||||
```bash
|
||||
mkfs.vfat -F 32 /dev/sda1 # EFI
|
||||
mkfs.ext4 /dev/sda2 # Arch
|
||||
```
|
||||
|
||||
## mount disk
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/sda2 /mnt
|
||||
mount /dev/sda1 /mnt/boot
|
||||
```
|
||||
|
||||
## install base & linux kernel
|
||||
|
||||
```bash
|
||||
reflector -f 10 --latest 30 --protocol https --sort rate --save /etc/pacman.d/mirrorlist # optimize mirror list
|
||||
|
||||
pacstrap /mnt base linux linux-firmware vim man-db man-pages git informant
|
||||
# base-devel need to be included as well?
|
||||
genfstab -U /mnt >> /mnt/etc/fstab
|
||||
arch-chroot /mnt
|
||||
```
|
||||
|
||||
```bash
|
||||
pacman -Syu # upgrade
|
||||
pacman -Qe # list explicitly installed pkgs
|
||||
pacman -Rs # remove pkg and its deps
|
||||
pacman -Qtd # list orphans
|
||||
```
|
||||
|
||||
## bootloader
|
||||
|
||||
```bash
|
||||
pacman -S \
|
||||
grub \
|
||||
efibootmgr \
|
||||
amd-ucode # AMD microcode
|
||||
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
```
|
||||
|
||||
## ntp
|
||||
|
||||
```bash
|
||||
sed -i -e 's/#NTP=/NTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org/' -e 's/#Fall/Fall/' /etc/systemd/timesyncd.conf
|
||||
systemctl enable --now systemd-timesyncd
|
||||
```
|
||||
|
||||
## locale
|
||||
|
||||
```bash
|
||||
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
|
||||
hwclock --systohc
|
||||
vim /etc/locale.gen & locale-gen
|
||||
echo "LANG=en_US.UTF-8" > /etc/locale.conf
|
||||
```
|
||||
|
||||
## network
|
||||
|
||||
```bash
|
||||
hostnamectl set-hostname polka
|
||||
hostnamectl set-chassis server
|
||||
|
||||
vim /etc/hosts
|
||||
# 127.0.0.1 localhost
|
||||
# ::1 localhost
|
||||
# 127.0.0.1 polka
|
||||
```
|
||||
|
||||
See https://systemd.network/systemd.network.html.
|
||||
|
||||
```ini
|
||||
# /etc/systemd/network/wired.network
|
||||
[Match]
|
||||
Name=enp5s0
|
||||
|
||||
[Network]
|
||||
#DHCP=yes
|
||||
Address=10.0.1.2/24
|
||||
Gateway=10.0.1.1
|
||||
DNS=10.0.1.100 # self-hosted DNS resolver
|
||||
DNS=1.1.1.1 # Cloudflare for the fallback DNS server
|
||||
MACVLAN=dns-shim # to handle local dns lookup to 10.0.1.100 which is managed by Docker macvlan driver
|
||||
```
|
||||
|
||||
```ini
|
||||
# /etc/systemd/network/dns-shim.netdev
|
||||
# to handle local dns lookup to 10.0.1.100
|
||||
[NetDev]
|
||||
Name=dns-shim
|
||||
Kind=macvlan
|
||||
|
||||
[MACVLAN]
|
||||
Mode=bridge
|
||||
```
|
||||
|
||||
```ini
|
||||
# /etc/systemd/network/dns-shim.network
|
||||
# to handle local dns lookup to 10.0.1.100
|
||||
[Match]
|
||||
Name=dns-shim
|
||||
|
||||
[Network]
|
||||
IPForward=yes
|
||||
|
||||
[Address]
|
||||
Address=10.0.1.103/32
|
||||
Scope=link
|
||||
|
||||
[Route]
|
||||
Destination=10.0.1.100/30
|
||||
```
|
||||
|
||||
`ip` equivalent to the above settings:
|
||||
|
||||
```bash
|
||||
ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim
|
||||
ip a add 10.0.1.103/32 dev dns-shim # assign host ip to shim defined in docker-compose.yml
|
||||
ip link set dns-shim up # enable interface
|
||||
ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet to shim interface
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl enable --now systemd-networkd
|
||||
networkctl status
|
||||
|
||||
# for self-hosted dns resolver
|
||||
sed -r -i -e 's/#?DNSStubListener=yes/DNSStubListener=no/g' -e 's/#DNS=/DNS=10.0.1.100/g' /etc/systemd/resolved.conf
|
||||
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||
|
||||
systemctl enable --now systemd-resolved
|
||||
resolvectl status
|
||||
resolvectl query ddg.gg
|
||||
drill @10.0.1.100 ddg.gg
|
||||
|
||||
# FIXME
|
||||
pacman -S wpa_supplicant
|
||||
vim /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
# ctrl_interface=/run/wpa_supplicant
|
||||
# update_config=1
|
||||
wpa_supplicant -B -i wlp8s0 -c /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
wpa_cli # default control socket -> /var/run/wpa_supplicant
|
||||
modinfo iwlwifi
|
||||
```
|
||||
|
||||
If `networkctl` keep showing `enp5s0` as `degraded`, then run `ip addr add 10.0.1.2/24 dev enp5s0 ` to manually assign static IP address for the workaround.
|
||||
|
||||
## firewall
|
||||
|
||||
```bash
|
||||
pacman -S firewalld
|
||||
# TODO
|
||||
```
|
||||
|
||||
See also [Introduction to Netfilter – To Linux and beyond !](https://home.regit.org/netfilter-en/netfilter/)
|
||||
|
||||
## shell
|
||||
|
||||
```bash
|
||||
pacman -S zsh
|
||||
chsh -s /bin/zsh
|
||||
```
|
||||
|
||||
## user
|
||||
|
||||
```bash
|
||||
passwd # change root passwd
|
||||
|
||||
useradd -m -s /bin/zsh uetchy # add local user
|
||||
passwd uetchy # change local user password
|
||||
|
||||
userdbctl # verify users
|
||||
|
||||
pacman -S sudo
|
||||
echo "%sudo ALL=(ALL) NOPASSWD:/usr/bin/pacman" > /etc/sudoers.d/pacman # allow pacman without password
|
||||
usermod -aG sudo uetchy # add local user to sudo group
|
||||
```
|
||||
|
||||
## ssh
|
||||
|
||||
```bash
|
||||
pacman -S openssh
|
||||
vim /etc/ssh/sshd_config
|
||||
systemctl enable --now sshd
|
||||
```
|
||||
|
||||
on the host machine:
|
||||
|
||||
```bash
|
||||
ssh-copy-id uetchy@10.0.1.2
|
||||
```
|
||||
|
||||
## AUR
|
||||
|
||||
```bash
|
||||
git clone https://aur.archlinux.org/yay.git
|
||||
cd yay
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
## finalize
|
||||
|
||||
```bash
|
||||
exit # leave chroot
|
||||
umount -R /mnt
|
||||
reboot
|
||||
```
|
||||
|
||||
# Additional setup
|
||||
|
||||
## gpgpu
|
||||
|
||||
```bash
|
||||
pacman -S nvidia
|
||||
cat /var/lib/modprobe.d/nvidia.conf # ensure having 'blacklist nouveau'
|
||||
|
||||
yay -S cuda-10.2 cudnn7-cuda10.2 # match the version number
|
||||
|
||||
nvidia-smi # test runtime
|
||||
```
|
||||
|
||||
## docker
|
||||
|
||||
```bash
|
||||
pacman -S docker docker-compose
|
||||
yay -S nvidia-container-runtime-bin
|
||||
vim /etc/docker/daemon.json
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"log-driver": "journald",
|
||||
"log-opts": {
|
||||
"tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"
|
||||
},
|
||||
"exec-opts": ["native.cgroupdriver=systemd"], // for kubernetes
|
||||
"runtimes": {
|
||||
// for docker-compose
|
||||
"nvidia": {
|
||||
"path": "/usr/bin/nvidia-container-runtime",
|
||||
"runtimeArgs": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl enable --now docker
|
||||
|
||||
groupadd docker
|
||||
usermod -aG docker user
|
||||
|
||||
docker run --rm -it --gpus all nvidia/cuda:10.2-cudnn7-runtime
|
||||
```
|
||||
|
||||
## telegraf
|
||||
|
||||
```bash
|
||||
yay -S telegraf
|
||||
vim /etc/telegraf/telegraf.conf
|
||||
```
|
||||
|
||||
```ini
|
||||
# File: /etc/sudoers.d/telegraf
|
||||
Cmnd_Alias FAIL2BAN = /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *
|
||||
telegraf ALL=(root) NOEXEC: NOPASSWD: FAIL2BAN
|
||||
Defaults!FAIL2BAN !logfile, !syslog, !pam_session
|
||||
```
|
||||
|
||||
## fail2ban
|
||||
|
||||
```
|
||||
pacman -S fail2ban
|
||||
systemctl enable --now fail2ban
|
||||
```
|
||||
|
||||
```ini
|
||||
# File: /etc/fail2ban/jail.local
|
||||
[DEFAULT]
|
||||
bantime = 60m
|
||||
ignoreip = 127.0.0.1/8 10.0.1.0/24
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = 22,10122
|
||||
|
||||
[mailu]
|
||||
enabled = true
|
||||
backend = systemd
|
||||
journalmatch = CONTAINER_NAME=mailu_front_1
|
||||
port = smtp,submission
|
||||
chain = DOCKER-USER
|
||||
filter = mailu
|
||||
findtime = 600
|
||||
maxretry = 1
|
||||
bantime = 1d
|
||||
```
|
||||
|
||||
```ini
|
||||
# File: /etc/fail2ban/filter.d/mailu.conf
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
failregex = ^%(__prefix_line)s\d+\/\d+\/\d+ \d+:\d+:\d+ \[info\] \d+#\d+: \*\d+ client login failed: "Authentication credentials invalid" while in http auth state, client: <HOST>, server: \S+, login: "<F-USER>\S+</F-USER>"$
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
```
|
||||
fail2ban-client reload
|
||||
fail2ban-client status mailu
|
||||
```
|
||||
|
||||
## sendmail
|
||||
|
||||
```bash
|
||||
yay -S sendmail
|
||||
```
|
||||
|
||||
## cfddns
|
||||
|
||||
Dynamic DNS for Cloudflare.
|
||||
|
||||
```
|
||||
yay -S cfddns
|
||||
```
|
||||
|
||||
```yml
|
||||
# File: /etc/cfddns/cfddns.yml
|
||||
token: <token>
|
||||
```
|
||||
|
||||
```ini
|
||||
# File: /etc/cfddns/domains
|
||||
uechi.io
|
||||
datastore.uechi.io
|
||||
```
|
||||
|
||||
```
|
||||
systemctl enable --now cfddns
|
||||
```
|
||||
|
||||
## smart
|
||||
|
||||
```bash
|
||||
pacman -S smartmontools
|
||||
systemctl enable --now smartd
|
||||
```
|
||||
|
||||
## backup
|
||||
|
||||
```ini
|
||||
# File: /etc/backups/borg.service
|
||||
[Unit]
|
||||
Description=Borg Daily Backup Service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Nice=19
|
||||
IOSchedulingClass=2
|
||||
IOSchedulingPriority=7
|
||||
ExecStart=/etc/backups/run.sh
|
||||
```
|
||||
|
||||
```ini
|
||||
# File: /etc/backups/borg.timer
|
||||
[Unit]
|
||||
Description=Borg Daily Backup Timer
|
||||
|
||||
[Timer]
|
||||
WakeSystem=false
|
||||
OnCalendar=*-*-* 03:00
|
||||
RandomizedDelaySec=10min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
```bash
|
||||
# File: /etc/backups/run.sh
|
||||
sleep 5
|
||||
|
||||
#
|
||||
# Script configuration
|
||||
#
|
||||
export BORG_PASSPHRASE="<PASSPHRASE>"
|
||||
MOUNTPOINT=/mnt/backup
|
||||
TARGET=$MOUNTPOINT/borg
|
||||
|
||||
# Archive name schema
|
||||
DATE=$(date --iso-8601)
|
||||
|
||||
# Options for borg create
|
||||
BORG_OPTS="--stats --compression lz4 --checkpoint-interval 86400"
|
||||
|
||||
# No one can answer if Borg asks these questions, it is better to just fail quickly
|
||||
# instead of hanging.
|
||||
export BORG_RELOCATED_REPO_ACCESS_IS_OK=no
|
||||
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no
|
||||
|
||||
# Log Borg version
|
||||
borg --version
|
||||
|
||||
echo "Starting backup for $DATE"
|
||||
|
||||
echo "# system"
|
||||
borg create $BORG_OPTS \
|
||||
--exclude /root/.cache \
|
||||
--exclude /var/cache \
|
||||
--exclude /var/lib/docker/devicemapper \
|
||||
--exclude /home \
|
||||
--one-file-system \
|
||||
$TARGET::'{hostname}-system-{now}' \
|
||||
/ /boot
|
||||
|
||||
echo "# home"
|
||||
borg create $BORG_OPTS \
|
||||
--exclude 'sh:/home/*/.cache' \
|
||||
--exclude 'sh:/home/*/.cargo' \
|
||||
$TARGET::'{hostname}-home-{now}' \
|
||||
/home/
|
||||
|
||||
echo "# data"
|
||||
borg create $BORG_OPTS \
|
||||
$TARGET::'{hostname}-data-{now}' \
|
||||
/mnt/data
|
||||
|
||||
echo "Start pruning"
|
||||
BORG_PRUNE_OPTS="--list --stats --keep-daily 7 --keep-weekly 4 --keep-monthly 3"
|
||||
borg prune $BORG_PRUNE_OPTS --prefix '{hostname}-home-' $TARGET
|
||||
borg prune $BORG_PRUNE_OPTS --prefix '{hostname}-system-' $TARGET
|
||||
borg prune $BORG_PRUNE_OPTS --prefix '{hostname}-data-' $TARGET
|
||||
|
||||
echo "Completed backup for $DATE"
|
||||
|
||||
# Just to be completely paranoid
|
||||
sync
|
||||
```
|
||||
|
||||
```bash
|
||||
ln -sf /etc/backups/borg.* /etc/systemd/system/
|
||||
systemctl enable --now borg
|
||||
```
|
||||
|
||||
## kubernetes
|
||||
|
||||
```bash
|
||||
pacman -S kubeadm kubelet kubectl
|
||||
systemctl enable --now kubelet
|
||||
kubeadm init --pod-network-cidr='10.244.0.0/16'
|
||||
cp /etc/kubernetes/admin.conf ~/.kube/config
|
||||
|
||||
kubectl taint nodes --all node-role.kubernetes.io/master- # to allow allocating pods to the master node
|
||||
|
||||
# setup flannel network manager
|
||||
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
|
||||
|
||||
# setup nginx ingress controller
|
||||
# TODO
|
||||
|
||||
kubectl cluster-info
|
||||
kubectl get nodes
|
||||
kubectl get pods -A
|
||||
kubectl get cm -n kube-system kubeadm-config -o yaml
|
||||
```
|
||||
|
||||
[Kubernetes - ArchWiki](https://wiki.archlinux.org/index.php/Kubernetes)
|
||||
|
||||
[Kubernetes Ingress Controller with NGINX Reverse Proxy and Wildcard SSL from Let's Encrypt - Shogan.tech](https://www.shogan.co.uk/kubernetes/kubernetes-ingress-controller-with-nginx-reverse-proxy-and-wildcard-ssl-from-lets-encrypt/)
|
||||
|
||||
## certs
|
||||
|
||||
```bash
|
||||
pacman -S certbot certbot-dns-cloudflare
|
||||
echo "dns_cloudflare_api_token = <token>" > ~/.secrets/certbot/cloudflare.ini
|
||||
chmod 600 ~/.secrets/certbot/cloudflare.ini
|
||||
certbot certonly \
|
||||
--email y@uechi.io \
|
||||
--agree-tos \
|
||||
--dns-cloudflare \
|
||||
--dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
|
||||
-d "*.uechi.io"
|
||||
openssl x509 -in /etc/letsencrypt/live/uechi.io/fullchain.pem -text
|
||||
certbot certificates
|
||||
|
||||
cat <<EOD > /etc/systemd/system/certbot.service
|
||||
[Unit]
|
||||
Description=Let's Encrypt renewal
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook "docker exec nginx-proxy-le /app/signal_le_service"
|
||||
EOD
|
||||
|
||||
cat <<EOD > /etc/systemd/system/certbot.timer
|
||||
[Unit]
|
||||
Description=Twice daily renewal of Let's Encrypt's certificates
|
||||
|
||||
[Timer]
|
||||
OnCalendar=0/12:00:00
|
||||
RandomizedDelaySec=1h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOD
|
||||
```
|
||||
|
||||
- [Certbot - ArchWiki](https://wiki.archlinux.org/index.php/Certbot)
|
||||
- [Welcome to certbot-dns-cloudflare’s documentation! — certbot-dns-cloudflare 0 documentation](https://certbot-dns-cloudflare.readthedocs.io/en/stable/)
|
||||
- [docker-letsencrypt-nginx-proxy-companion/Standalone-certificates.md at master · nginx-proxy/docker-letsencrypt-nginx-proxy-companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Standalone-certificates.md)
|
||||
|
||||
## audio
|
||||
|
||||
```bash
|
||||
pacman -S alsa-utils # maybe requires reboot
|
||||
arecord -L # list devices
|
||||
|
||||
cat <<EOD > /etc/asound.conf
|
||||
pcm.m96k {
|
||||
type hw
|
||||
card M96k
|
||||
rate 44100
|
||||
format S32_LE
|
||||
}
|
||||
|
||||
pcm.!default {
|
||||
type plug
|
||||
slave.pcm "m96k"
|
||||
}
|
||||
EOD
|
||||
|
||||
arecord -vv /dev/null # test mic
|
||||
```
|
||||
|
||||
```
|
||||
alsamixer # gui mixer
|
||||
```
|
||||
|
||||
- [SoundcardTesting - AlsaProject](https://www.alsa-project.org/main/index.php/SoundcardTesting)
|
||||
- [Advanced Linux Sound Architecture/Troubleshooting - ArchWiki](https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture/Troubleshooting#Microphone)
|
||||
- [ALSA project - the C library reference: PCM (digital audio) plugins](https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html)
|
||||
|
||||
# Maintenance
|
||||
|
||||
```bash
|
||||
systemctl --failed
|
||||
free -h
|
||||
htop
|
||||
lsblk -f
|
||||
nvidia-smi
|
||||
iotop
|
||||
sensors
|
||||
journalctl -p err
|
||||
networkctl status
|
||||
```
|
18
source/_posts/2021/braille.md
Normal file
18
source/_posts/2021/braille.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 点字の表現力
|
||||
date: 2021-02-13
|
||||
---
|
||||
|
||||
「n 種類の文字を表現できる点字を作らないといけなくなったらどうしよう」
|
||||
|
||||
例としてドット が 3 つの点字を用意した。
|
||||
|
||||
- 組み合わせ数は 3P3 + 3P2 + 3P1
|
||||
- $f(N,K) = \sum_{i=K → 0} N P K$
|
||||
- 2 の n 乗っぽい
|
||||
- べき集合の濃度?
|
||||
- 2 進数のブール配列と考えるとわかりやすくなった
|
||||
- ということは X 個の表現をするために必要なブール配列の長さは $\lceil\log_2 (X)\rceil$
|
||||
- 例えばアルファベットなら 6 ドットの点字で表現できる
|
||||
- だから英語の点字は 6 つの点
|
||||
- 点字を 18 ドットに拡張すれば Unicode 13.0 の文字すべてを表現できる
|
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: OAuth 2.0 と JWT 関連 RFC
|
||||
date: 2021-02-11
|
||||
---
|
||||
|
||||
個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べています。
|
||||
|
||||
## [RFC6749](https://tools.ietf.org/html/rfc6749) — The OAuth 2.0 Authorization Framework
|
||||
|
||||
2012 年 10 月
|
||||
|
||||
OAuth 1.0a に代わる新たな認証基盤 OAuth 2.0 のコアを規定しており、特筆すべき点がいくつかある。
|
||||
|
||||
- `access_token` の内容は規定されておらず、ベンダーに委ねられている
|
||||
- JWS でもなんでもいい
|
||||
- リソースサーバーに `access_token` を渡す方法は規定されていない(同月発行の RFC6750 で規定された)
|
||||
|
||||
### Authorization Grant
|
||||
|
||||
トークンエンドポイントで`access_token`を発行してもらう際に使用できる Grant (許可証)は、提案中の拡張仕様を含めて 5 つある。
|
||||
|
||||
1. Authorization Code Grant: [RFC6749 – Section 1.3.1](https://tools.ietf.org/html/rfc6749#section-1.3.1)
|
||||
1. `grant_type=authorization_code`
|
||||
2. Authorization Code Grant with PKCE
|
||||
2. Implicit Flow: [RFC6749 – Section 1.3.2](https://tools.ietf.org/html/rfc6749#section-1.3.2)
|
||||
1. もともと CORS (Cross Origin Resource Sharing) が登場する以前の SPA で、POST リクエストを回避しつつ Access Token を得る"妥協案"として策定された
|
||||
2. CSRF 耐性が無い ([RFC6819 - Section 4.4.2.5](https://tools.ietf.org/html/rfc6819#section-4.4.2.5))ため、使うべきではない
|
||||
3. Resource Owner Password Credentials Grant: [RFC6749 – Section 1.3.3](https://tools.ietf.org/html/rfc6749#section-1.3.3)
|
||||
1. 直接パスワードで認証する形式
|
||||
4. Client Credentials Grant: [RFC6749 – Section 1.3.4](https://tools.ietf.org/html/rfc6749#section-1.3.4)
|
||||
1. クライアントシークレットでトークンを取得する形式。
|
||||
5. Device Grant: [RFC Draft — OAuth 2.0 Device Authorization Grant](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15)
|
||||
1. 入力機器が無い場合もある組み込みデバイス向けの認証フロー
|
||||
|
||||
## [RFC6750](https://tools.ietf.org/html/rfc6750) — The OAuth 2.0 Authorization Framework: Bearer Token Usage
|
||||
|
||||
2012 年 10 月
|
||||
|
||||
OAuth 2.0 において、`access_token`をリソースサーバーに渡す手法を規定する。OAuth 2.0 JWT Bearer Token Flow**ではない**。
|
||||
|
||||
手法として 3 つが挙げられている。
|
||||
|
||||
1. Bearer Token (**SHOULD**)
|
||||
2. Form Encoded Parameters (SHOULD NOT)
|
||||
3. URI Query Parameters (SHOULD NOT)
|
||||
|
||||
## [OICD](https://openid.net/specs/openid-connect-core-1_0.html) — OpenID Connect Core 1.0
|
||||
|
||||
2014 年 11 月
|
||||
|
||||
OAuth 2.0 の上にいくつか仕様を足したサブセット。
|
||||
|
||||
## [RFC7515](https://tools.ietf.org/html/rfc7515) — JSON Web Signature (JWS)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JSON ベースの署名プロトコル。
|
||||
|
||||
## [RFC7516](https://tools.ietf.org/html/rfc7516) — JSON Web Encryption (JWE)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JSON ベースの暗号化プロトコル。
|
||||
|
||||
## [RFC7517](https://tools.ietf.org/html/rfc7517) — JSON Web Key (JWK)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWT の署名チェックに用いる公開鍵を配信するためのプロトコル。
|
||||
|
||||
## [RFC7518](https://tools.ietf.org/html/rfc7518) — JSON Web Algorithms (JWA)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWS、JWE、JWK で利用されるアルゴリズム (alg)やその他プロパティを規定する。
|
||||
|
||||
## [RFC7519](https://tools.ietf.org/html/rfc7519) — JSON Web Token (JWT)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWT は JSON を利用して Assertion を生成するための仕様。
|
||||
|
||||
## [RFC7521](https://tools.ietf.org/html/rfc7521) — Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
任意の Assertion を OAuth 2.0 Client Authentication の Client Credentials として使ったり、あるいは Authorization Grant として Access Token と交換するための仕様。
|
||||
|
||||
トークンエンドポイントに強化されたクライアント認証を付与する。続く RFC で、それぞれ SAML と JWT を使用したパターンを規定している。
|
||||
|
||||
**OAuth 2.0 JWT Bearer Token Flow**とも呼ばれている。
|
||||
|
||||
- [RFC7522](https://tools.ietf.org/html/rfc7522) — Security Assertion Markup Language (**SAML**) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||
- [RFC7523](https://tools.ietf.org/html/rfc7523) — JSON Web Token (**JWT**) Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||
|
||||
2015 年 5 月 https://tools.ietf.org/html/rfc7523
|
||||
|
||||
## [RFC Draft](https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-02) — JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
|
||||
|
||||
2019 年 7 月
|
||||
|
||||
リソースサーバーに渡す Access Token に JWT を使用することを定めている。
|
148
source/_posts/2021/split-bill.md
Normal file
148
source/_posts/2021/split-bill.md
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: 最小送金回数で精算する割り勘アルゴリズム
|
||||
date: 2021-02-14
|
||||
---
|
||||
|
||||
大人数でキャンプを楽しんだあとに待っているのは耐え難き送金処理です。
|
||||
次回から楽をするために、送金回数を最小化する制約で精算表を作る方法を考えてみます。
|
||||
|
||||
# tl;dr
|
||||
|
||||
アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」です。
|
||||
|
||||
1. 全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)
|
||||
2. 降順でソート(出費過多が先頭)
|
||||
3. リストの最後(最大債務者, 出費=L)がリストの最初(最大債権者, F)に $\min(F, |L|)$ を支払ってバランスを再計算
|
||||
4. 全員のバランスが 0 になるまで 2-3 を繰り返す
|
||||
|
||||
# 実験
|
||||
|
||||
実際にコードを書いて本当に望んでいる結果が得られるのかを検証します。
|
||||
|
||||
```5js
|
||||
const history = [
|
||||
{
|
||||
amount: 121,
|
||||
payer: "A",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 98,
|
||||
payer: "B",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 10,
|
||||
payer: "C",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 10,
|
||||
payer: "C",
|
||||
involves: ["A", "B"],
|
||||
},
|
||||
{
|
||||
amount: 50,
|
||||
payer: "C",
|
||||
involves: ["A"], // meaning C lent A 50
|
||||
},
|
||||
];
|
||||
|
||||
// calculate balance sheet
|
||||
const init = { balance: 0, consumption: 0 };
|
||||
Map.prototype.fetch = function (id) {
|
||||
return (
|
||||
this.get(id) || this.set(id, Object.assign({ name: id }, init)).get(id)
|
||||
);
|
||||
};
|
||||
|
||||
const data = new Map();
|
||||
|
||||
for (const { payer, amount, involves } of history) {
|
||||
const record = data.fetch(payer);
|
||||
record.balance += amount;
|
||||
const dept = Math.ceil(amount / involves.length);
|
||||
// actual payer should not owe extra dept coming from rounded up numbers
|
||||
const payerDept = amount - dept * (involves.length - 1);
|
||||
for (const deptor of involves.map((i) => data.fetch(i))) {
|
||||
const cost = Math.round(amount / involves.length);
|
||||
deptor.balance -= cost;
|
||||
deptor.consumption += cost;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
|
||||
// calculate transaction table
|
||||
const transaction = [];
|
||||
let paidTooMuch, paidLess;
|
||||
while (true) {
|
||||
for (const [_, tbl] of data) {
|
||||
if (tbl.balance >= (paidTooMuch?.balance || 0)) {
|
||||
paidTooMuch = tbl;
|
||||
}
|
||||
if (tbl.balance <= (paidLess?.balance || 0)) {
|
||||
paidLess = tbl;
|
||||
}
|
||||
}
|
||||
|
||||
if (paidLess.balance == 0 || paidTooMuch.balance == 0) break;
|
||||
|
||||
const amount = Math.min(paidTooMuch.balance, Math.abs(paidLess.balance));
|
||||
|
||||
transaction.push({
|
||||
sender: paidLess.name,
|
||||
receiver: paidTooMuch.name,
|
||||
amount,
|
||||
});
|
||||
|
||||
paidTooMuch.balance -= amount;
|
||||
paidLess.balance += amount;
|
||||
}
|
||||
|
||||
console.log("Settled");
|
||||
|
||||
console.log("\n# Transaction table");
|
||||
for (const ev of transaction) {
|
||||
console.log(`${ev.sender} owes ${ev.receiver} ¥${ev.amount}`);
|
||||
}
|
||||
|
||||
console.log("\n# History");
|
||||
for (const { payer, amount, involves } of history) {
|
||||
if (involves.length === 1) {
|
||||
console.log(`${payer} lent ¥${amount} to ${involves[0]}`);
|
||||
} else {
|
||||
console.log(`${payer} paid ¥${amount} for ${involves.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n# Expenses");
|
||||
for (const [_, { name, consumption }] of data) {
|
||||
console.log(`${name} virtually paid ¥${consumption} in total`);
|
||||
}
|
||||
```
|
||||
|
||||
`history`に支払い履歴を書き込んでから実行すると、「送金表」「履歴」「実質支払総額」が得られます。
|
||||
|
||||
```md
|
||||
# Transaction table
|
||||
|
||||
A owes B ¥10
|
||||
C owes B ¥6
|
||||
|
||||
# History
|
||||
|
||||
A paid ¥121 for A, B, C
|
||||
B paid ¥98 for A, B, C
|
||||
C paid ¥10 for A, B, C
|
||||
C paid ¥10 for A, B
|
||||
C lent ¥50 to A
|
||||
|
||||
# Expenses
|
||||
|
||||
A virtually paid ¥131 in total
|
||||
B virtually paid ¥81 in total
|
||||
C virtually paid ¥76 in total
|
||||
```
|
||||
|
||||
プログラムに落とし込めたら、あとはアプリを作るなりスプレッドシートのマクロにするなり自由です。面倒なことは全部コンピューターにやらせよう!
|
Reference in New Issue
Block a user