OmniAICreator/Qiita-1.07M huggingface dataset:
TerminalからDashを開く

Dashとは

> Dash for macOS - API Documentation Browser, Snippet Manager - Kapeli : https://kapeli.com/dash

TerminalからDashを開くコマンドは

```
$ open dash://keyword
```

例えば、python3のprint関数を参照するには以下を実行する

```
$ open dash://python3:print
```

`open dash://` をいちいち入力するのは面倒なので関数を定義して実行できるようにする

bashの場合

```~/.bash_profile
dash () {
    open dash://$1
}
```

zshの場合

```~/.zshenv
alias dash='(){ open dash://$1 }'
```

以下の様に使える

```
$ dash python3:print
```
Raspberry Pi 2にGHCとStackをインストールした時のメモ

[Rasberry Pi3 (ARMv7)にhaskell-stackをインストールする][raspi3stack]を参考にさせていただきました.

# 環境
Raspberry Pi 2 Model B (ARMv7, 1GB RAM)
OS: Raspbian Jessie

# 手順
1. いずれかの方法でstack(1.1.2)をインストールする.
    - Debianのリポジトリからインストール
        1. [Rasberry Pi3 (ARMv7)にhaskell-stackをインストールする][raspi3stack]を参考にDebianの`stretch`リポジトリを追加.
        2. aptからhaskell-stackをインストール.

            ```bash
            $ sudo apt install haskell-stack
            ```
    - バイナリパッケージ版のインストール
        1. [github][stack1.2.2]からARM向けビルドをダウンロード.
        2. バイナリをパスの通ったディレクトリに配置する.
    
3. [バイナリパッケージ版のGHC7.10.3][ghc7.10.3bindist]をインストールする.

    ```bash
    $ ./configure --prefix=/home/pi/.dist
    $ make install
    ```
4. `/tmp`をRAMディスクに置いている場合は, 通常のディスクへと戻す.


`/tmp`がRAMディスクに置いてあると
`hPutBuf: resource exhausted (No space left on device)`
や
`LLVM ERROR: IO failure on output stream.`
といったエラーがずらずらと出てきます. (但し, Hello worldぐらいならコンパイルできる模様)

# 何故かダメだったもの
[DebianパッケージのGHC 7.10.3][ghc-deb]の場合は, 次のようなエラーメッセージを吐いてビルドできませんでした。

```
/tmp/ghc50d2_0/ghc_6.s: Assembler messages:

/tmp/ghc50d2_0/ghc_6.s:105:0:
     Error: selected processor does not support `movw r3,:lower16:stg_bh_upd_frame_info' in ARM mode
...
```

# 参考リンク
[Cross-compile for ARM processors support · Issue #1332 · commercialhaskell/stack](https://github.com/commercialhaskell/stack/issues/1332)
[Filling /tmp results in a crash · Issue #623 · commercialhaskell/stack](https://github.com/commercialhaskell/stack/issues/623)

[raspi3stack]:http://qiita.com/aiya000/items/fe45952da33ddc99d4be
[ghc7.10.3bindist]:https://www.haskell.org/ghc/download_ghc_7_10_3#linux_armv7
[ghc-deb]:https://packages.debian.org/stretch/ghc
[stack1.2.2]:https://github.com/commercialhaskell/stack/releases/tag/v1.1.2
スマホで横画面にしたときだけアラートを出す

##概要
スマホサイトで、縦画面で使ってほしいときのために、画面が回転して横になったらアラートをだすスクリプトを書きました。

##コード

```js
$(document).ready(function(){
    var noMoreAlert = false;
    $(window).bind("load orientationchange",function(){
        setTimeout(checkOrientation,100);
    });
  
    function checkOrientation(){
        var w = $(window).width();
        var h = $(window).height();
        console.log("w:"+w+" h:"+h);
        if(h<w){
            if(noMoreAlert===false){
                if(confirm("本サイトは、縦向きでの利用を推奨しています。\nこれ以上このメッセージを表示しない場合は「OK」を選択して下さい。")){
                    noMoreAlert = true;
                }
            }
        }
    }
});

```

動作サンプル
http://jsdo.it/tsunet111/yfKwQ


###メモ
- 古いAndroid も対応する場合は、```resize``` イベントもいれておいたほうがよいです。ただし、新しい機種だと、アラート２回発動します。
- 実務上は、OS判別をして、タブレット以上のサイズ（あるいはPCのみ）では動作しないようにしたほうがよいかと思います。
ipython + jupyter + plotly (matplotlib) 設定 & 使い方メモ

自分用便利設定たち

# Environment & Requirement

- OS X
- anaconda3

    - python3
    - ipython
    - matplotlib
    - plotly
    - jupyter

# 設定

`~/.ipython/default_profile` 一式を作る。

```
$ ipython create profile
```

- `~/.ipython/profile_default/ipython_config.py`

```
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
```

- `~/.ipython/profile_default/ipython_kernel_config.py`

```
c.InteractiveShellApp.matplotlib = 'inline'
```

- `~/.ipython/default_profile/startup/00-first.py`

```
import numpy as np
import matplotlib.pyplot as plt
import plotly.offline as py
py.init_notebook_mode()
def plotly(f, *largs, **dargs):
    fig = plt.figure()
    f(*largs, **dargs)
    iplot_mpl(fig)
```

# Sample

```
x = np.random.randn(10)
y = x+np.random.randn(10)*0.1
plotly(plt.plot,x,y,'bo')
```

plotlyの使い方をちゃんと覚える気にならなかったのでplotlyでmatplotlibのラッパーを作りたかったが
高階関数使う意外簡単にできる方法思いつかなかった。。。
少しでも複雑なことしようとすれば使えないので
これを見た強い人、他に何かいい方法があれば教えてください。
（plotlyの使い方覚えろというのは正論。。）

plotlyのサンプルにしたがってpyをエイリアスにしたけどそれ使うのは強気すぎる気が。。。w
CentOS7 + Nginx + PHP-FPM でPHPを実行する環境を整える

# はじめに
PHPをインストールしてNginxの設定でCGIを実行できるようにすれば簡単にできると思っていましたが、実際にやってみると意外とハマったのでメモとして残しておきます。

# PHPのインストール
以下のコマンドを実行します。

```bash
$ sudo yum -y install php
```

インストールできたかどうかを確認します。

```bash
$ php --version
```

📝 最新版のPHPをインストールしたい場合、あるいはプロジェクトごとに異なるバージョンのPHPを簡単に管理したい場合は、phpenvをおすすめします。phpenv利用したPHPのインストール手順については「[phpenvで最新版のPHPをインストールしてWebサイトで使用する](https://ja.developers.noraworld.blog/how-to-install-latest-version-of-php-with-phpenv)」を参考にしてください。

# PHP-FPMのインストール
以下のコマンドを実行します。

```bash
$ sudo yum -y install php-fpm
```

# Nginxのインストール
こちらの記事を参照してください。

[CentOS 7 (5, 6) で "安定版 (最新版)" のNginxをインストールする方法](https://ja.developers.noraworld.blog/how-to-install-latest-or-stable-version-of-nginx)

# PHP-FPMの設定を変更
Apacheを使用する場合は特に変更することはありませんが、Nginxを使用する場合は設定ファイルの変更が必要です。`/etc/php-fpm.d/www.conf`内の`user`と`group`を`nginx`に変更します。

```diff:/etc/php-fpm.d/www.conf
- user = apache
- group = apache
+ user = nginx
+ group = nginx
```

設定したら、PHP-FPMを起動(再起動)します

```bash
$ sudo systemctl restart php-fpm
```

# Nginxの設定を変更
Nginxの設定を変更してPHPを実行できるようにします。`/etc/nginx/conf.d/default.conf` を編集します。今回はホームディレクトリ以下に `www` というディレクトリを作り、その中にある `index.php` を実行できるようにします。

⚠️ 初期設定に戻せるように設定のバックアップを取りたい人はこのファイルを直接編集せずに、コピーして編集してください。コピー先ファイルは `default.conf` と同じディレクトリ、ファイル名は任意ですが、拡張子は `.conf` としてください。なお、今回は `default.conf` を直接編集することを前提として説明します。

```diff:/etc/nginx/conf.d/default.conf
- location / {
-     root   /usr/share/nginx/html;
-     index  index.html index.htm;
- }
+ location / {
+     root   /home/ユーザ名/www;
+     index  index.html index.htm index.php;
+ }

- #location ~ \.php$ {
- #    root           html;
- #    fastcgi_pass   127.0.0.1:9000;
- #    fastcgi_index  index.php;
- #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
- #    include        fastcgi_params;
- #}
+ location ~ \.php$ {
+     root           /home/ユーザ名/www;
+     fastcgi_pass   127.0.0.1:9000;
+     fastcgi_index  index.php;
+     fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+     include        fastcgi_params;
+ }
```

`ユーザ名`のところに自分のユーザ名を入力してください。注意すべき点は、`location ~ \.php$` ブロック内の `root` を `location /` の `root` と同じにすること、`fastcgi_param` のパスを上記のように変更することの2点です。

また、`location /`ブロックの`index`に`index.php`を追加することを忘れずにしてください。なお、ここでいう`index.php`はファイルを省略した場合に参照するファイルなので、たとえば`info.php`というファイルにアクセスしたい場合でもNginx設定ファイル内の`index.php`の部分は変更する必要はありません。

上記を設定に変更したらNginxを起動(再起動)します。

```bash
$ sudo systemctl restart nginx
```

# PHPファイルを作成
PHPのファイルを作成します。ホームディレクトリに`www`ディレクトリを作り、その中に`index.php`を作成します。

```
$ mkdir ~/www
$ vi ~/www/index.php
```

`index.php`に以下を追加します。

```php:index.php
<?php
  phpinfo();
?>
```

# 確認
ブラウザで`http://ドメイン名/index.php`にアクセスして、PHPに関する情報が表示されたら成功です。お疲れさまでした。

# 403 Forbidden と表示されたとき
ホームディレクトリのパーミッションが正しいか確認してください。パーミッションを正しく設定するには以下を実行します。

```bash
$ chmod 755 /home/ユーザ名/
```
Fullscreen API をさわったのでメモ

`document.querySelector('img').requestFullScreen()`とかすると画像が全画面表示されるやつ。画面ロード直後にいきなり全画面表示とかはできないようになってるのでclickイベント内とかで行う。

詳しくは以下

- [フルスクリーンモードを使用する - Web developer guide | MDN](https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Using_full_screen_mode)


画像ギャラリー的なUIでの利用を想定してみる。画像をクリックしたら最大化表示されるやつ。

```html
<style>
img{
  width: 300px;
  height: 233px;
  border: solid 4px #aaa;
  border-radius: 16px;
}
img:hover{
  border-color: #00aaff;
  cursor: pointer;
}
</style>
</head>
<body>
<h1>FullScreen Demo for Chrome/Safari</h1>
<img src="https://lh5.googleusercontent.com/-7cggVHG-i74/U5M05ee0DAI/AAAAAAAAHWA/iM3hb0gONVc/s800/IMG_1727.png"/>
<img src="https://lh4.googleusercontent.com/-E-GSa8wymBs/U5MzX0_5G7I/AAAAAAAAHVM/S2igEXSg8nU/s800/IMG_1778.png"/>
<script>
var images = document.querySelectorAll('img');
Array.prototype.forEach.call(images, function (image, index, nodeList) {
  image.addEventListener('click', function(){
    if(image.webkitRequestFullScreen) {
      image.webkitRequestFullScreen();
    }
  });
});
```

<img width="722" alt="gallery.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/f689b95c-8863-ac05-0ad5-a0f33fb21a04.png">


## 最大化されない

Firefoxの場合、styleのサイズ指定が無視されでっかく表示されるけど、Chrome/Safariの場合は小さいままになってしまう。

### Firefox

<img width="1680" alt="firefox_full.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/dcc963b4-968d-047e-c20f-f83172986387.png">

### Chrome/Safari

<img width="969" alt="chrome_full.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/4e92253e-3d63-2db6-6d79-0b664a4a3130.png">


MDNによると以下でFirefoxと同じ挙動になるとのこと。

```css
img:-webkit-full-screen {
  width: 100%;
  height: 100%;
}
```

なんか長細くて変ｗ

<img width="1680" alt="chrome_full2.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/6d094442-0a57-8e02-a6a0-c1d68a264573.png">

FullScreen化された時だけ、サムネイル時のstyleを解除するといい感じに動くみたい。

```html
<style>
.noFullScreen img{
  width: 300px;
  height: 233px;
  border: solid 4px #aaa;
  border-radius: 16px;
  display: inline-block;
}
.noFullScreen img:hover{
  border-color: #00aaff;
  cursor: pointer;
}
</style>
<script>
document.addEventListener('webkitfullscreenchange', function(){
  var image = document.webkitFullscreenElement;
  if(image){
    document.body.classList.remove('noFullScreen');
  }
  else{
    document.body.classList.add('noFullScreen');
  }
}, false);
</script>
```

<img width="1680" alt="chrome_full3.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/356ff9de-f930-8986-d4c6-dd5633d44c40.png">


## Chromeの場合のみ最大化解除後、段積みになっちゃう

Chromeの場合のみ以下みたいになってしまう。バグかな。

<img width="697" alt="gallery_chrome.png" src="https://qiita-image-store.s3.amazonaws.com/0/15637/50e7ddfb-1ca1-7f85-49d1-db1d3a2f9c8d.png">

これについては`inline-block`を指定すれば解決するっぽい。

```css
.noFullScreen img{
  width: 300px;
  height: 233px;
  border: solid 4px #aaa;
  border-radius: 16px;
  display: inline-block; /* 追加 */
}
```

- [Demo for Chrome/Safari](https://cyokosaturn.github.io/cyokodog_net_demo/screen_api/fullscreen/demo01.html)
- [Demo for Firefox](https://cyokosaturn.github.io/cyokodog_net_demo/screen_api/fullscreen/demo02.html)
Zabbixのアクションが突然全停止したときは

Zabbixは、監視元の条件から「トリガー」を発生させ、
「トリガー」について「アクション」という形でコマンドなどを実行可能です。

しかし、急激に大量のアクションが発生すると、アクションの実行が全停止してしまうことがあります。
全停止したことを示すようなZabbixサーバのログは特に出力されず、またこうなってしまうと時間経過では直りません。
Zabbixのプロセスを再起動したところ、無事アクションが実行されるようになりました。
大量に発生したアクションは再起動後そのまま実行されます。

### 参考URL
https://support.zabbix.com/browse/ZBX-10161
atomでterminalを使う

# 要件
ATOMでterminalを使いたい。

# 使用したプラグイン

1. [term2]()　
term2をinsthttps://atom.io/packages/term2allする過程でpty.jsやterm.jsが必要でatomのsetting->packageから上手くDLできず諦める

2. [terminal-plus](https://atom.io/packages/terminal-plus)　
setting->packageから検索して普通にinstallするところまで行けたが、terminalを起動すると何故か、何もコマンドが打てないという不具合が発生し、諦める

3. [platformio-ide-terminal](https://atom.io/packages/platformio-ide-terminal)　
terminal-plusをforkしているらしく、teminal-plusの要領で動作する。
[こちらのブログ](http://labs.spiffield.net/archives/508)を参考にさせて頂きました。
正常に動作してterminalをatom上で起動させることができたので良かったかなと。
Docker 1.12で--log-optの指定を間違えるとプロセスが残ってしまう

## 経緯

[Amazon ECS](https://aws.amazon.com/jp/ecs/)をインフラに利用したNode.js+expressのWEBアプリケーションを開発している過程でECSタスクが頻繁に強制停止されては再起動する事象に遭遇。

原因を調べるとコンテナインスンスタンス（Dockerホスト機）のメモリ不足でログ書き込みに失敗していた。

しかし、ECSタスクに割り当てているメモリは512MB程度でコンテナインスタンスの搭載メモリ上限には達していいないのになぜ…？

コンテナインスタンス上で動作しているプロセス一覧を確認するとNode.jsのプロセスが40個近く動作しており、それらがコンテナインスタンスのメモリを食いつぶしていた。

## 疑問

`docker ps`の結果からみて起動しっぱなしのコンテナは存在しない。
`docker ps -a`を実行するとSTATUS=Createdなコンテナがたくさん残っていた。
これは何？

Dockerはコンテナが停止されればプロセスも停止されるはずなのだが…

## 仮説

１週間ほど前にTaskDefinitionのLogging設定に記述ミスがあり、ECS Serviceにより何度も「タスクを起動しようとする」→「失敗」→「タスクを起動しようとする」…を繰り返していた。

その時のプロセスが残り続けているに違いない！
そして、コンテナが停止してもプロセスが残ることがあるに違いない！

## 検証

おそらくnode.jsとか関係ない。nginxコンテナを使って単純に再現するかを試す。

```shell-session:ロググループ名を間違えてnginxコンテナを実行
$ docker run  --log-driver=awslogs --log-opt awslogs-group=unknown nginx
docker: Error response from daemon: Failed to initialize logging driver: Cannot determine region for awslogs driver.
```

一見logging driverのエラーでコンテナの起動に失敗した風。

```shell-session:コンテナの状態を確認
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
8befc665980a        nginx               "nginx -g 'daemon off"   2 minutes ago       Created                                 hungry_heyrovsky
```

Created状態のコンテナの存在を確認。

```shell-session:実行中プロセスを確認
$ ps auxf
root     14295  0.0  0.0 208832  5528 ?        Sl   20:18   0:00      \_ docker-containerd-shim 8befc665980aae3e099a71863f9ca54b97b8
root     14312  0.0  0.0  31732  5080 ?        Ss   20:18   0:00          \_ nginx: master process nginx -g daemon off;
syslog   14331  0.0  0.0  32124  2816 ?        S    20:18   0:00              \_ nginx: worker process
```

`docker-containerd-shim 8befc665980aae3e099a71863f9ca54b97b8`を親としたnginxプロセスの存在を確認。

再現した！

## 対処

プロセスをkill。最も単純なのはコンテナインスタンスの再起動。
Twitter 電話番号を登録できませんでした。再度お試しください。

ソフトウェア開発に長い間従事していると、問題が発生した時に、手がかり（エビデンス、ログ、事象を見た人の報告 etc...）から、問題に対しまず仮説を立て、事象を再現させたり仮説を裏打ちさせる証拠（ログ、モジュール差分、バグリポート、取り調べ etc...)を見つける事で問題の解決を図るまでのプロセスの質とスピードが研磨されていく。
プログラマーやSEは刑事や探偵に向いてるんじゃないかとよく思う。

仮説は、時に99.9%、時に1%(はまっている時）という確信度を要素に従えており、そのうち、だいたい1%〜80%くらいというレンジの広いそれで表現されるのが

「キャッシュかな？」

である。

修正したはずの画面やJSの挙動が反映されなかったりした時にとりあえず「キャッシュかな」と言えばいいと思っている。

キャッシュは僕の中で何年経っても動きがよく分からないもので、また、たいがい問題が発生した時くらいしか認識する場面がない。

昔、HTTPでXMLを取りに行って、XMLの中身の情報を軸として処理する日次バッチをリリースした。
XMLはあるサービスの有効期間を管理しており、新しいサービスが変わる2、3か月くらいに1度の頻度で更新される、そのバッチに取っては非常に重要なXMLだ。
新しいXMLに変わって2、3日は新しいXMLが取得出来てたが、ある日1日、というかバッチの中で2、3回呼ぶ（その作りもバカだがw)内の1回だけ古いXMLを取得してしまい、後続処理に影響が出てしまった事があった。
その時も僕は「キャッシュですかね？」とひとまずみんなを煙に巻くように、決してプログラムのせいでは無いことをほのかに主張しつつ、解析はインフラ担当に任せた。
結果、プロキシか、XMLを保持するサーバかは分からないが、そこがキャッシュを返す設定になってたらしいので、キャッシュを返さない設定にしたという事をそれとなく聞いた。結局1日2回、日中にHTTPで取得し、ローカルに保存したXMLを実際に処理する際に見に行くというよく分からない修正をさせられた。（古いXMLが取れてしまった場合に対処すべきなのだが、そんな仕掛けにも運用にもしていないw）
リリース前に、バグが出るならXMLだろうなとは思っていたのでそれはそれでハンター冥利に尽きる。

話がそれた。
とまあそれくらいキャッシュはよく分からない謎の動きをする。それに慣れてくると、

「キャッシュが効いてて修正が全然反映されねえじゃねえかクソが」

といいつつ、全く別の場所の資材を修正していたというのは誰しも経験があるのではないだろうか。二重管理はダサいし、何でもキャッシュのせいにしてはダメだということである。



こんなに長々と書くつもりがなかったのだが、以下が本題。

TwitterAPIを使用しようとする場合は、アカウントに電話番号を紐付けなければならないのだが、Twitterの設定画面で、携帯に送られてきた認証番号を入力して設定しようとした際に、

`電話番号を登録できませんでした。再度お試しください。`

と謎エラーが出てしまい、困惑してググってたら「画面を更新すると良い」とあったので、「おいおいまさか、、、そんな、、、バカなっ、、、」と思いつつ半信半疑で`Ctrl + R`で画面更新後、設定したら見事に出来てしまったので、きっとキャッシュが効いていたんだろーなーと思いつつ、結局のところよく分からない自分も認識している。

よく分からないけど直った。たまにこういう経験をする事で、人は不完全である事を認識するのである。
The Ultimate Question of Programming, Refactoring, and Everything

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/141625/b69af0d4-7b21-588e-5beb-239ae55b02f6.png)

Yes, you've guessed correctly - the answer is "42". In this article you will find 42 recommendations about coding in C++ that can help a programmer avoid a lot of errors, save time and effort. The author is Andrey Karpov - technical director of "Program Verification Systems", a team of developers, working on PVS-Studio static code analyzer. Having checked a large number of open source projects, we have seen a large variety of ways to shoot yourself in the foot; there is definitely much to share with the readers. Every recommendation is given with a practical example, which proves the currentness of this question. These tips are intended for C/C++ programmers, but usually they are universal, and may be of interest for developers using other languages.

Full EBook: http://www.viva64.com/en/b/0391/

I hope you enjoyed this collection of tips. Of course, it is impossible to write about all the ways to write a program incorrectly, and there is probably no point in doing this. My aim was to warn a programmer, and to develop a sense of danger. Perhaps, next time when a programmer encounters something odd, he will remember my tips and won't haste. Sometimes several minutes of studying the documentation or writing simple/clear code can help to avoid a hidden error that would make the life of your colleagues and users miserable for several years.
[Ruby] JSONをメソッドチェーンできるようにメタプログラミング

# はじめに

こんなJSONをかえすAPIを想定しています

```json:こんなJSONでレスポンスがきたら
[
    {"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
    {"name": "random",  "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
]
```

---

# したいこと

APIからJSONでデータを取得した時に、メソッドチェーンでアクセスしできたらいいなー
こんなかんじでアクセスできたら楽だろうなーと思って作ってみました

---

```rb:コンソール
client = Api::Client.new(url)

# チャンネルのレスポンス
client.result.channels # => [
                       #      {"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
                       #      {"name": "random",  "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
                       #     ]


# チャンネルに登録しているメンバーID
client.result.channels.first.members # => ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]
```

---

# 現状はこんなかんじ

RubyでAPIを使う時の一般的な例

```rb:APIを叩くスクリプト
response_json = open(url).read
response_hash = JSON.parse(res)
response_hash.first["members"] # => ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]
```

---

```rb:したいこと
# これがしたい
response_hash.first.members    # => エラー
```

JSON.parseはHashを返すので、メソッドチェーンできずに失敗します

---

# 実装

```rb:api.rb
require 'open-uri'
require 'json'

class Hash
  # ここが実装のきもです。
  # Api::Client.new(url).resultはHashインスタンスを返しますが、
  # Hashインスタンスに対して`name`などのHashのkeyを呼んだ時に
  # self[:name]を返します
  def method_missing(name)
    return self[name].extend Hash if key? name
    self.each { |k, v| return v if k.to_s.to_sym == name }
    super.method_missing(name)
  end
end

module Api

  class Client
    attr_accessor :result
    def initialize(url)
      response = request(url)
      @result = parse(response)
    end

    private

    def request(url)
      open(url).read
    rescue SocketError => e
      puts "URLがちがうZE"
    end

    def parse(res)
      JSON.parse(res)
    rescue JSON::ParserError => e
      puts 'JSONじゃないZE'
      {}
    end

  end
end
```

---

# できました

SlackAPIを叩いて、`random`チャネルに登録しているユーザIDを取得してみます

---

```rb:コンソール
# このURLにアクセスしたい。今回はslackAPI
token = ENV['SLACK_TOKEN']
url = 'https://slack.com/api/channels.list?token=#{token}&pretty=1'

require '上記のファイルパス'

client = Api::Client.new(url)

# チャンネルのレスポンス
puts client.result.channels

# チャンネルに登録しているメンバーID
puts client.result.channels.first.members
```

---

```ruby:実行結果
# チャンネルのレスポンス
[
    {"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
    {"name": "random",  "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
]

# チャンネルに登録しているメンバーID
D29GZBJBQ
D29RJ3PBG
D29RJ3PCG
```

---

# まとめ

SlackとかGithubのAPIで面白いもの作れそうですね！
vimで書いたコードをQiitaのエディタにコピペするときにインデントが大きくなる問題の対処法

#困ったこと
vimで書いたコードをQiitaのエディタにコピペすると
インデントがvimで書いていたよりも大きくなった．

#原因
vimにおけるインデントがタブによるものであったが，
tabstop=2と設定していたため小さく見えた．
これをQiitaのエディタに貼り付けたときに普通のタブに戻った．

#解決法
vimの設定ファイル`_vimrc`に`set expandtab`を追加する．
そうするとタブが複数の空白に置き換えられるため，
コピペをしても(tabstop=2のとき)空白2つ分の幅が保たれる．

#参考にしたページ
[SublimeTextのインデントをタブからスペースに変更した](http://chuckwebtips.hatenablog.com/entry/2015/09/11/000000)
[Vim のカスタマイズ 〜 タブ/インデントの設定 〜](http://vimblog.hatenablog.com/entry/vimrc_set_tab_indent_options)
<ol>タグをcssで装飾する

`<ol>`タグ（番号付きリスト）をcssで装飾する方法。

## 仕組み

基本はこれ。

```scss:scss
ol {
  counter-reset: counter-name;

  li { //元のスタイルをリセットする
    margin: 0; 
    list-style: none;
  }

  li:before {
    counter-increment: counter-name;
    content: counter(counter-name);
  }
}
```

`counter-name` のところは、自分で好きな名前をつけてください。

1. `counter-increment:` で指定したカウンターの数を1増やして、
2. `content: coounter()` でその数を表示して、
3. `counter-reset:` でカウンターをリセットする

というようなことが可能らしいです。

上記cssを適用した`<ol>`は、だいたいこんな表示。

```
1あああああ
2いいいいい
3うううううう
```

## デザインする

```scss:scss
ol {
  counter-reset: counter-name;

  li {
    margin: 0; 
    list-style: none;
    position: relative;
    padding-left: 20px;
  }

  li:before {
    counter-increment: counter-name;
    content: counter(counter-name) ".";
    color: #269fdb;
    position: absolute;
    left: 0;
 }
}
```

↓↓

![スクリーンショット 2016-09-21 20.06.14.png](https://qiita-image-store.s3.amazonaws.com/0/45187/348d3ac3-c7ab-2427-b155-1dee8273d878.png)

ちなみに、数字の後ろや前に文字を追加したい場合、
```content:  "第" counter(counter-name) "位";```
これで ```第3位 ``` と表示されます。

### もっとデザインする

border-radiusなども組み合わせていけば、色んなデザインがcssで作れます。
ホバーエフェクトなども気軽に使えるので（olで使うタイミングがあるか謎ですが）覚えておきたいです。

![スクリーンショット 2016-09-21 20.19.22.png](https://qiita-image-store.s3.amazonaws.com/0/45187/cf9a410d-5037-914a-1fca-83167defffd4.png)
（コードは間違えて消しました）

`content`には他にも諸々あるようなので、後日調査したいところですね。
リバースプロキシ下のServletアプリのsendRedirectをいい具合にする

リダイレクトするときにクライアントとwebサーバーが対話する際に使ったプロトコルが無視される問題についてのお話。

## いきさつ

* jenkinsをnginxの下に立てようとした
* httpsで受けてhttpでjenkins.warを動かしたjettyに流すようにした
* ログイン/アウト時にhttpにリダイレクトされる
* httpsしかファイアウォールで許可してなかったので怒られる

そんな感じ。

色々調べてみたところ、jenkinsのリダイレクトは`req.sendRedirect("/hoge")`とかでやっていることが分かった。

だとすると、それを受けたservletの方でhttpにしてるのでは？という疑惑が芽生えた。

## tomcatの場合

### 初動検証

apache-tomcat-9.0.0.M10.tar.gzをダウンロードし、以下のようなファイルをビルドしたものを組み込んで検証すると、無事httpsからhttpにリダイレクトされた。

```Risa.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Risa extends HttpServlet{
  public void doGet(HttpServletRequest req,
                      HttpServletResponse res) 
                      throws ServletException, IOException {
    System.out.println(req.getContextPath());
    res.sendRedirect(req.getContextPath());
  }
}
```

### 直す

conf/server.xmlに以下の一行を足すだけ。

```server.xml
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="x-forwarded-proto"/>
```

これでX-Forward-Protoで得たプロトコルを利用できるようになったので、nginxに`proxy_set_header X-Forwarded-Proto $scheme;`と入れてproxy_passすればhttpsでリダイレクトされるようになる。


## jettyの場合

### 初動検証

tomcatの時と同じものをwebappsフォルダの下に置いて`java -jar start.jar`で実行すると、やはりhttpにリダイレクトされた。


### 直す

jettyの9.3系だとアーカイブの中にjetty-http-forwarded.xmlファイルなるものが存在しており、それを喰わせればいい。これもX-Forwarded-Protoを見るようになるので、nginxの設定を足せばいい。

```run.sh
#!/bin/sh
cd `dirname $0`
/usr/bin/java -jar start.jar ./etc/jetty-http-forwarded.xml
```


## 愚痴

さらっと書いたけど、普通の人は「httpをhttpsにリダイレクトする設定を入れればいいじゃん」って感じになるのか、軽く動かすにしてもなかなか同じトラブルシューティングが見つからなくてめっちゃ困った。

ここ最近アプリの動作確認取る上で同じ問題にしばしばハマってて、rundeckだとprofileファイルに`-Drundeck.jetty.connector.forwarded=true`と書き足して、gitbucket(jetty)の場合だとGUI中のbaseUrlにhttpsのURLを書いたりしてた。

アプリごとにそれぞれ個別設定入れて対策取らないといけないのかなりカロリー使うしどうにかならないんだろうか……。
Mattermostの新規チャンネル追加を通知するbotを作った

最近社内でMattermostを使うようになり、全てのチャンネルを閲覧するようにしているが、新規にチャンネルが増えても分からない。少し調べてみたがチャンネル追加を通知するような設定は無いようだった。
そこで、チャンネルが新規に追加されたら適当なチャンネルにその情報を投稿するbotを作ってみた。
Mattermostの公式HPにはJavaScript、Go用のドライバはあるが、Javaしか書けないマンなのでJavaで書いた。  

作成したbot
------
https://github.com/tsyki/mattermost-channel-add-checker

cronで定期的に動かし、その時点のチャンネル一覧と、前回実行時に書き出しておいたチャンネルIDの一覧を比べて差異があったものの情報を投稿する。


利用したAPI
------

* ログイン
    * URL：/api/v3/users/login
    * リクエストメソッド：POST
    * POSTするデータ
        * login_id
        * password
    * レスポンスヘッダのTokenから認証用トークンを取得できる。  
    以後リクエストヘッダに「Authorization: Bearer {{トークン}}」を追加して通信することで認証された状態となる
* チームの取得
    * URL：/api/v3/teams/all
    * リクエストメソッド：GET
    * チーム名、チームIDが取得できる。ここで取得したIDを使ってチャンネル情報を取得する
* 参加しているチャンネル一覧の取得
    * URL：/api/v3/teams/{{チームID}}/channels/
    * リクエストメソッド：GET
    * ダイレクトメッセージや非公開グループも取れてしまうので、typeの値を見て判断する。
        * O:公開チャンネル
        * P:非公開チャンネル
        * D:ダイレクトメッセージ
* 参加していないチャンネル一覧の取得
    * URL：/api/v3/teams/{{チームID}}/channels/more
    * リクエストメソッド：GET
* Incoming Webhookでの投稿  
    * URL：Incoming Webhookの作成時に表示されるURL
    * リクエストメソッド：POST
    * POSTするデータ
        * text
        * channel
        * username
        * icon_url
    * Incoming Webhookを使わずAPIのみでも投稿できるが、Incoming Webhookを使うとBOTと投稿時にマークがつくので分かり易い

参考
----

* JavaでJSONをPOSTする方法  
[[Java] HttpClient の POST で JSON を送信する件． | hirooka.pro](https://hirooka.pro/?p=2692)
* Mattermost APIのtopページ  
[Web Service API — Mattermost 3.0 documentation](https://docs.mattermost.com/developer/web-service.html)
* JavaScript版のドライバ(client.jsx)  
[mattermost/mattermost-driver-javascript: Javascript library for interacting with the Mattermost API](https://github.com/mattermost/mattermost-driver-javascript)  
※最近APIのリファレンスページが出来たようなので今なら[そっち](https://api.mattermost.com/)を見たほうがよさそう  
* Incoming Webhookの使い方  
[Incoming Webhooks — Mattermost 3.4 documentation](https://docs.mattermost.com/developer/webhooks-incoming.html)
Spring Bootでwarファイル作成＆jarのサービス化

## spring boot
- spring-bootの詳しい説明は以下が参考になります
- [spring-boot公式](http://projects.spring.io/spring-boot/)
- [Spring Boot 使い方メモ](http://qiita.com/opengl-8080/items/05d9490d6f0544e2351a)  
簡単に説明すると設定ファイルがほとんど必要なく、起動もとても簡単なフレームワークという感じでしょうか。  
javaでよく耳にするspringとは別のフレームワークです。  
Mavenビルドするとjarファイルが出来上がり、tomcatなどがjarファイルに組み込み済みなので、そのjarファイル１つで起動することができます。

## jarファイル作成
デフォルトではMavenビルドするとjarファイルが作成されるかと思います。

```shell-session
java -jar xxx.jar
```
というコマンドを打てば、そのjarファイルが起動すると思います。
ただ、jarファイルではなくwarファイルで「作成してtomcatに配置したい」や「サービス化したい」などというときもあるかと思います。
その方法を調べたので、メモしておきます。

## warファイル作成
Spring Boot 1.3.0.RELEASE(2016年9月現在最新版は1.4.1)からMavenビルドで
Fully Executable Warとして実行できるようになりました。
今回はそちらを利用します。
`pom.xml`に以下を追記します。ポイントは`executable`を`true`にするところです。

```java:pom.xml
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<executable>true</executable>
				</configuration>
			</plugin>
		</plugins>
	</build>
```


そして`pom.xml`の上部記載してあるはずの`packaging`を`war`に変更します

```java:pom.xml
    <groupId>com.agetech</groupId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
```

この状態でMavenビルドして成功するとwarファイルが作成されていると思います。
(作成されない場合は`Maven Update`などしてみて下さい)

## jarのサービス化
方法はとても簡単です。

```shell-session
#シンボリックリンクを設定
ln -s /home/ec2-user/jarファイル名.jar /etc/init.d/jarファイル名

##スタート
service jarファイル名 start

##ストップ
service jarファイル名 stop
```

## 参考記事
- [Spring BootのFully Executable Warを試す](http://qiita.com/yoshidan/items/696cfa68f3dbbad8140c)  
今回参考記事とかなり似ている内容になりましたが、要所要所違うため誰かの参考になればと思いQiitaに残しました。
桁数に応じてテキスト幅が変化するステータスの作り方

#概要
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/32aefe16-903e-968c-fb57-1fc602bf6dd6.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/46c7bebc-8853-d315-7c03-51acd90f69ff.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/5d560eae-f609-5657-25a2-3c224a7e2c31.png)

ゲームを作ってるとよく出てくるスラッシュの左が現在の値。右側が最大値というステータス表現。
最大値と現在値を変数で持たせてプログラム上で文字列結合し、一つのテキストオブジェクトに入れて表示するという表現の仕方もできますが、別々の値を毎回結合させる方法に違和感を感じたので別々のテキストオブジェクトで管理する方法を作成しました。

#ヒエラルキー
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/6461cb74-b15a-6244-9d1f-ecda13fb2529.png)


#インスペクター
- StatusValueParts  
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/ad296ef3-61e6-f61e-ce1d-da73aa47a895.png)  
  　
- RightValueText
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/1a5321ef-9b88-d4b3-ceae-d82a59c8e401.png)
  　

- MiddleValueText
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/0b6f744e-af32-2804-33ca-9e8900eb2f6e.png)
  　

- LeftValueText
![image](https://qiita-image-store.s3.amazonaws.com/0/93944/4e03c2ac-ffae-0fac-5213-8604c1bddaf2.png)

#完成イメージ
現在値や最大値が変化すると全体のテキスト幅が変化し、右詰めのキレイなレイアウトになります。
CakePHP Sequence plugin でレコードの順番を管理



# 公式

https://github.com/ADmad/cakephp-sequence


# 概要

レコードの順番を管理するシンプルなプラグインです。


# インストール

composerでインストール後、`config/bootstrap.php`に 追加。

```composer
composer require admad/cakephp-sequence
```


```config/bootstrap.php
Plugin::load('ADmad/Sequence');
```


# 使い方

以下をBehaviorの設定に追加。

```Table.php
$this->addBehavior('ADmad/Sequence.Sequence', [
    'order' => 'position',   // 順番を保存するカラム名。デフォルト： "position".
    'scope' => ['group_id'], // グルーピングに使うカラムの配列。 デフォルト [].
    'start' => 1,            // 順番の初期値。デフォルト 1.
]);
```


新しいレコードを保存する度に、'position' カラムに 1->2->3 と自動で順番が保存されます。

また、クエリのorder()が未指定の場合は、自動でorder('position asc')が追加されます。



# 保存、更新、削除時の動作

新規追加だけでなく、挿入や削除にも対応しています。
挿入や更新の場合は、`position`に挿入、更新したい位置をセットしてsave()すれば、他のレコードの`position`も更新されます。
このため、大量のレコードがあるものには向かないのではないかと思われます。
docker execをより使いやすいため便利なツールを作ってみた


デバッグのため、Dockerホストにログインし、`docker ps`で実行中のコンテナーを調べて、対象となるコンテナーのIDを取得し、最後に`docker exec -it $cid bash`などでコンテナーの中に入り、デバッグなどをします。

例えば（例１）：

```
$ docker ps | grep post
d448ca916642        postgres            "/docker-entrypoint.s"   About an hour ago   Up About an hour    5432/tcp            cocky_kare

$ docker exec d448 hostname
d448ca916642
```

こんな頻繁な操作であれば、もっと簡単にすべきだと思って、便利なツールを作りました。


ソースは [GitHub](https://github.com/liubin/scripts/blob/master/dexec) にあげています。

使い方法：

```
$ dexec search-string [arg1, arg2, arg3]
```

`search-string` は必須で、 `arg1` などはコンテナーに実行するコマンド、もしコマンドを指定されていなければ、 `bash` が渡されます。


`dexec` を使えば、例１は下記のように一つのコマンドができます：

```
$ dexec post hostname
```


もし `post` に該当するコンテナーが多数があれば、どのコンテナーまたはすべてのコンテナーを選択することもできます。

例えば、すべての `busybox` コンテナーのIPを調べたいとしたら：

```
$ dexec busy ip addr show eth0
the is more than one containers found:

1 630f17f03600        busybox             "tail -f /dev/null"      About an hour ago   Up About an hour                        goofy_kilby
2 699872b3712c        busybox             "tail -f /dev/null"      About an hour ago   Up About an hour                        clever_euler


please select one [1-2](ENTER for run in all containers):
Running commands in conatiner 630f17f03600 
26: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link 
       valid_lft forever preferred_lft forever
Running commands in conatiner 699872b3712c 
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.4/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:4/64 scope link 
       valid_lft forever preferred_lft forever
``` 

上記のよう、 `busybox` のコンテナーが２つありまして、どのコンテナーに実行するか聞かれます。上からコンテナーの順番を指定すると、そのコンテナーにコマンドが実行されます。 何も指定しなくて `Enter` を押すと、すべてのコンテナーに実行されます。やめるには `Ctrl＋C` でOKです。


下記のビデオもご覧ください。

[![asciicast](https://asciinema.org/a/b9bxcyf4iamfnoc8wzu3udm3i.png)](https://asciinema.org/a/b9bxcyf4iamfnoc8wzu3udm3i)
R > 比較 > == > sample(x,3,rep=T)==c("zun","zun","doko")

```txt:動作環境
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

参考 Rで学ぶデータ・プログラミング入門 by 石田基広さん

ズンドコの前準備。

```R
> x<-c("zun","doko")
> sample(x,3,rep=T)==c("zun","zun","doko")
[1]  TRUE  TRUE FALSE
> sample(x,3,rep=T)==c("zun","zun","doko")
[1] TRUE TRUE TRUE
> sample(x,3,rep=T)==c("zun","zun","doko")
[1] TRUE TRUE TRUE
> sample(x,3,rep=T)==c("zun","zun","doko")
[1] TRUE TRUE TRUE
> sample(x,3,rep=T)==c("zun","zun","doko")
[1] FALSE FALSE FALSE
```

3回取出したものを`==`でチェックする。
R > 文字列操作 > 結合? > paste(x, collapse="") > strsplit()の場合はunlistしておく必要がある

```txt:動作確認
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

参考 Rで学ぶデータ・プログラミング入門 by 石田基広さん

paste()で分割した文字列をつけることができるようだ。

```R
> x<-c("a","b","c")
> x
[1] "a" "b" "c"
> paste(x, collapse="")
[1] "abc"
```

ただし、以下は意図通り(`zunzundoko`)にならなかった。

```R
> x<-strsplit("zunzundoko", "")
> x
[[1]]
 [1] "z" "u" "n" "z" "u" "n" "d" "o" "k" "o"

> paste(x, collapse = "")
[1] "c(\"z\", \"u\", \"n\", \"z\", \"u\", \"n\", \"d\", \"o\", \"k\", \"o\")"
```

### 教えていただいた事項

@r-de-r さんの[コメント](https://qiita.com/7of9/items/7030320fbc22dd3a2a4a/#comment-53d8a919d078414b760f)にてstrsplitとunlistを組合わせた方法を教えていただきました。

情報感謝です。
Git CUIとうまく付き合うための便利コマンド一覧 ～設定・確認編～

[株式会社オズビジョン](http://www.oz-vision.co.jp/)の@terra_yuccoです。
2016年度、[enPiTプログラム履修生](http://enpit.aiit.ac.jp/)として、
7月～ 品川シーサイドの産業技術大学院大学にて学んでいます。

職場ではGit/GitHubはTortoiseGitで操作していますが、
講義内ではCUI操作なので、自分のための覚書も兼ねてまとめています。
今回は、初期設定、およびよく使いそうな状態確認周りをまとめました。

# 環境確認・設定
PCを変えたり再インストールしたりするたびに必要になりそうな設定。
その他GitHubを利用するならssh用鍵の登録も必要。

- バージョン確認
    - GitHubインターフェースのhubコマンドを入れていると、hub側のバージョンも出ます
    - ここで躓いたら[Git - Gitのインストール](https://git-scm.com/book/ja/v1/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)辺りを参照してインストールから。

```bash
$ git --version
git version 1.9.1
hub version 2.2.3
```

- グローバル設定
    - push.default simple については、[git の push.default 設定を理解する](http://qiita.com/misopeso/items/ede49b661cc7ad30528a)が良さそうです。

```bash
$ # ユーザ名
$ git config --global user.name terra-yucco
$ # メールアドレス
$ git config --global user.email aaa@bbb.ccc
$ # CUI上の色付け設定
$ git config --global color.ui auto
$ # エディタの設定
$ git config --global core.editor vim
$ # Pushのデフォルト設定付け
$ git config --global push.default simple
```

- グローバル設定確認

```bash
$ git config -l
color.ui=auto
push.default=simple
core.editor=vim
core.autocrl=input
user.email=aaa@bbb.ccc
user.name=terra-yucco
```


# 状態確認
## 現在のワークスペースの状況確認 (git status)
今自分がどのブランチにいるか、ブランチの状態がどうなっているのかを確認できる。

- 作成したての新規ブランチ

```bash
$ git status
On branch new
nothing to commit, working directory clean
```

- 新規作成したファイルがあってステージング前

```bash
$ touch tutorial.txt
$ git status
On branch new
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        tutorial.txt

nothing added to commit but untracked files present (use "git add" to track)
```

- ステージング後、コミット前

```bash
$ git add .
$ git status
On branch new
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   tutorial.txt
```

- コミット後 (最初に戻る)

```bash
$ git commit -m 'test commit'
[new a907804] test commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 tutorial.txt
$ git status
On branch new
nothing to commit, working directory clean
```

- git show
- git log
- git branch -vva

# 参考リンク
- [Gitチートシート](https://services.github.com/kit/downloads/ja/github-git-cheat-sheet.pdf)
- [サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](http://www.backlog.jp/git-guide/)
- [Gitチュートリアルとトレーニング|Atlassian](https://www.atlassian.com/ja/git/tutorial)

# まだWIP
- git show
- git log
- git branch -vva

このあたりの詳細は次の版で自分用に書きます！

おしまい。

----
# Git CUIとうまく付き合うシリーズ
- [設定・確認](http://qiita.com/terra_yucco/items/3e21319d2f75e19a0c65)
- [リカバリ・Tips](http://qiita.com/terra_yucco/items/ff31c9423836c0ba5517)
R > 文字列操作 > 分割 > strsplit(x, "") > [1] "z" "u" "n" "z" "u" "n" "d" "o" "k" "o"

```txt:動作確認
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

参考 Rで学ぶデータ・プログラミング入門 by 石田基広さん

```R
> x<-"zunzundoko"
> strsplit(x, "")
[[1]]
 [1] "z" "u" "n" "z" "u" "n" "d" "o" "k" "o"
```
R > typeof() > オブジェクトのタイプを表示

```txt:動作確認
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

参考 Rで学ぶデータ・プログラミング入門 by 石田基広さん

typeof()の使い方を練習してみた。

```R
> x<-c("zun","zun","doko")
> y<-3.141592
> z<-6.022+1.023i
> typeof(x)
[1] "character"
> typeof(y)
[1] "double"
> typeof(z)
[1] "complex"
```
R > Conj() > 複素共役を得る

```txt:動作環境
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

複素数を扱えるということは複素共役を得る関数があるはず。
タブ補間で見つけた。

```R
> z<-1+2i
> Conj(z)
[1] 1-2i
```
R > table() + barplot() > diceの出目をbarplot表示

```txt:動作確認
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

参考 Rで学ぶデータ・プログラミング入門 by 石田基広さん

3までのdiceを考えて実装してみた。

```R
> dice<-sample(1:3, 100, rep=T, prob=c(1/6,1/6,1/6))
> table(dice)
dice
 1  2  3 
33 33 34 
> z<-table(dice)
> barplot(z)
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b6651b5f-bb7f-0937-e674-e587420aea41.png)

確率は1/6でなく1/3が実は正しい。
VPC Peering + AWS LambdaはPrivate IP

タイトル見て「何を当たり前のことを、、、」と思われることでしょうが、気づかずはまってしまったのでメモ。

# やりたいこと
AWS Lambdaから別アカウントで構築しているEC2サーバにアクセスしたかった

# やったこと
1. VPC Peeringの設定
2. 相互のVPCにPeeringを行ったVPCのルートテーブル紐づけ設定
3. LambdaにVPCを設定する（IAMのRoleにAWSLambdaVPCAccessExecutionRoleを付けて）
4. EC2サーバのセキュリティグループに、Lambdaが利用しているサブネットからのアクセス許可設定
5. タイムアウトしてアレー？となる

参考：http://dev.classmethod.jp/cloud/vpc-peering-restricts-and-considerations/

# 原因
もう冒頭に書いていますが、AWS Lambdaの内部に記載していたアクセス先のホスト名がDNSで、VPC内アクセスなのでここにはPrivate IPを記載しなければなりませんでした。

# Tips
テスト用のLambda Functionを作って、

```python
import commands

def lambda_handler(event, context):
    print(commands.getoutput("curl -v http://hoge/api"))
```

と実行してみてようやく気づいた次第。そうだよね。


# Tipsその2

もともと、VPC Peringは「NAT立てるの面倒！」と思って試してみたのですが、

> インターネットアクセス - 特定のファンクションに対してこの機能を有効にすると、そのファンクションは標準ではインターネットへアクセスできなくなります。

http://aws.typepad.com/aws_japan/2016/02/access-resources-in-a-vpc-from-your-lambda-functions.html

という注意点をよく読まずにやってしまいました。何たる。
システム的にはインターネットアクセス無しで回避する方策があったので事なきを得ましたが、もし類似したことをやろうとしている方はご注意を！
STIのtypeを変える

# はじめに
STIでtypeを変える方法。


# 動機
本来は禁じ手だが、STIのtypeを変えたい時がある。
STIのオブジェクトが他のモデルから関連付けられている場合などにおいて、削除->追加 をすると、アソシエーションの管理が面倒になる。


# 構成
- 『番号フォーマット』はある番号を生成するフォーマットであり、内容は複数の仕様のフォーマットで構成される。
	- Time: strftimeのフォーマット (e.g. '%Y%m%d')
	- Sequential: sprintfのフォーマット (e.g. '%04d')
- 『番号フォーマット』は、複数の『部分』から構成される
- 『部分』クラスは自分の仕様に従って文字列を生成する (日付、連番、etc..)

例) '%Y%m_Number%03d'  # '201612_Number003' のように生成される

![download.png](https://qiita-image-store.s3.amazonaws.com/0/78099/bcb597d5-536a-a621-efa5-3f211656571f.png)

### クラス
- NumberFormat
ユーザへの公開クラス
NumberPartのリストを持つ。build()で各NumberPartのbuild()を呼び出し連携つする

- NumberPart
STIの親。

- DatePart
STIの子。
build()で、登録されたフォーマットに従い文字列を生成する。フォーマットはstrftimeに準じる。

- SequentialPart
STIの子。
build()で、登録されたフォーマットに従い文字列を生成する。フォーマットはsprintfに準じる。
連番を生成するため、オブジェクトは『現在の値』を管理する。


# STIのtypeを変える

モデル。
STIでは各々の子クラスに必要なすべてのカラムを同一レコードで持つため、typeを変更したときに前のクラスのアトリビュートが残る。
つまり、type変更に伴って自分に必要なカラム・不要なカラムを適切に初期化する必要がある。

```ruby
class NumberFormat < ActiveRecord::Base
  has_many :number_parts
  ...
  def build
    number_parts.map{|np| np.build()}.inject(&:+)
  end


class NumberPart < ActiveRecord::Base
  #  id               :integer
  #  type             :string   # STI
  #  format           :string   # 番号フォーマット
  #  current_number   :integer  # NumberPartが使う『現在の値』
  ...
  belongs_to :number_format
  after_save :reset

  def build
    ''
  end

  private
    # 親クラスで全てのSTIの子に特異なアトリビュートをリセット
    def reset
      update_column(:current_number, nil)
    end


class DatePart < NumberPart
  def build
    Time.zone.now.strftime format
  end


class SequentialPart < NumberPart
  # STIのtype変更時にパラメータをリセットする必要のある必要な子クラスは
  # 初期化をオーバーライドする。
  after_save :reset

  def build
    num = format % current_number
    increment! :current_number
    num
  end

  def reset
    update_column(:current_number, 0) unless self.current
  end
```

変更するコード

```ruby
class HogeHogeController
  ...
  def transform_parts_type(number_part, new_type_name)
    # まずtypeのみDBレコード直で書き換える
    number_part.update_column(:type, new_type_name)

    # becomes!でクラスを変更する
    type_updated = number_part.becomes!(new_type_name.constantize)

    # モデルのsaveコールバックを発生させ、タイプ変更時の初期化を行う
    type_updated.save
  end
```

# 図作成
https://www.jgraph.com/
R > sample() > 数値を取り出す > replace=True/False > リスト要素の再利用する/しない

```txt:動作環境
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

sample()を使って値を取り出す。

```R
> x<-1:5
> sample(x,10,rep=FALSE)
Error in sample.int(length(x), size, replace, prob) : 
  cannot take a sample larger than the population when 'replace = FALSE'
> sample(x,10,rep=TRUE)
 [1] 1 3 3 1 1 1 5 2 5 1
```

rep=FALSEだと5個のリストは5回しか取出せない。
rep=TRUEの場合はリスト要素を再利用するので6回以上取出せる。
WebアプリライクにWebviewを見せるために設定したcssの備忘録

WebアプリライクにWebviewを見せるために設定したcssの備忘録です。

# タップ時のハイライトカラーを透明化する
`-webkit-tap-highlight-color:rgba(0, 0, 0, 0);`

半透明のハイライトカラーが表示されることを防ぎます

# buttonやsubmitなどのタップ時に出る枠を非表示にする
 `outline: none;`

上記ハイライトカラーのみでは消えない枠が出た場合、こちらを設定します

# 長押し時のポップアップを無効にする
`-webkit-user-select: none;
user-select: none;
-webkit-touch-callout: none; /*iOS用*/`

コピペ用のポップアップなどが表示されることを防ぎます
swift3でswift2.3で動いていたC構造体メンバ（Char配列）を読み込むコードが動かなかった件について

下記のようなC構造体を、bridge経由でswiftから操作するとき、

```c:cstruct.h
 #define MEM01_SIZE 255
 struct cstruct {
    char cstr01[MEM01_SIZE];
  } 
```

swift2では下記のようなコードで出来ていたが、swift3ではコンパイラエラーになっていた。

```swift:swift2.2.swift
var size: Int32 = 0
var cstruct = GetCStruct(&size)
let cstr01_str = withUnsafePointer(&cstruct.memory.cstr01)
{
 return String.fromCString(UnsafePointer($0))!
}
```

swift3では下記のようにすれば通った。

```swift:swift3.swift
var cstr01_str_tuple = cstruct?.pointee.cstr01
let cstr01_str = withUnsafePointer(to: &cstr01_str_tuple)
{
  return String(cString: UnsafeRawPointer($0).assumingMemoryBound(to: CChar.self))
}
```

なんでこれで動くのかよく分かってなくて、解説はまだ書けないけど、とりあえず動いたのでメモ。
R > 関数名だけ > 関数の内容が表示される

```txt:動作環境
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

```R
> rep
function (x, ...)  .Primitive("rep")
```

```R
> sample
function (x, size, replace = FALSE, prob = NULL) 
{
    if (length(x) == 1L && is.numeric(x) && x >= 1) {
        if (missing(size)) 
            size <- x
        sample.int(x, size, replace, prob)
    }
    else {
        if (missing(size)) 
            size <- length(x)
        x[sample.int(length(x), size, replace, prob)]
    }
}
<bytecode: 0x0eead5c0>
<environment: namespace:base>
> 
```

どう使うかは未消化。
Rubyことはじめ

# 対象読者

* 何らかのプログラミング言語を使って開発経験のある方
* Rubyの文法をさっと流し読みしたい方

# ゴール

* Rubyの文法をさらっと俯瞰する

# 環境

* Ruby2.2

## 構成管理

* rbenv + bundler

### インストール

gemではbundlerのみインストールして、それぞれのプロジェクトごとのライブラリをbundlerで管理する。

```shell-session
$ gem install bundler
$ vim Gemfile
```

インストールしたいファイルをgemfileに記述していく。

```ruby
# frozen_string_literal: true
source "https://rubygems.org"

# gem "rails"
gem "ruby-debug-ide"
gem "debase"
gem "rubocop"
gem "ruby-lint"
gem "rcodetools"
...
```

インストール

```shell-session
$ bundle install
```

# 文法

## Hello World

* 幾つか書き方があります。

```ruby
msg = 'hello world'
puts msg
printf("%s", msg)
p msg
```

## 書式付き表示

```
msg = 'hello world'
user = 'Yamada'
p "%s -> %s" % [msg, user]
```

## 分岐

if~then~elseですね

```ruby
pattern = 'a'
if pattern == 'a' then
    p "yes"
else
    p "no"
end
```

## 繰り返し

いくつか書き方があります。

```ruby
# forループ
sum = 0
for i in 1..10 do
    sum += i
end
puts sum

# eachで同様の処理
sum = 0
(1..10).each do |i|
    sum += i
end
puts sum

# foreach
colors = ["red", "blue", "yellow"]
for color in colors do
    puts color
end
```

## メッソドとクラス

rubyはなんでも、修飾子とendがセットになるようです。

```ruby
# classは class修飾子をつける
class Person
    # @@をつけるとクラス変数
    @@language = 'ja'

    # 
    def initialize(name = 'unknown', age = nil) 
        # @をつけるとインスタンス変数
        @name = name
        @age = age
    end

    def putName()
        puts @name
    end    
end

# class名 + new で インスタンス生成
anonimus = Person.new()
tanaka = Person.new('tanaka', 20)
# 引数がない場合は、かっこを省略できる
anonimus.putName
tanaka.putName()
```

## 例外

C#やJavaをメインにしていたので、単語が違うので少々とまどいました。

```ruby
class ExceptionTest
  def cause_error
    begin
        # 0除算例外
        1 / 0
    rescue ZeroDivisionError => ex        
        # 〜なんらかの例外処理〜
        puts ex.class
        # raiseで上に投げる
        raise        
    rescue StandardError => ex
        puts ex.class
    ensure
        # finally相当
    end
  end
end

# 例外を出す
obj = ExceptionTest.new
obj.cause_error
```

## コメント

```ruby
# 一行コメント

=begin
複数行の
コメントは
beginとendで囲む
=end
```

# UnitTest

いくつもtest framworkがあるが、Ruby2.2に組み込まれているminitestを使ってみます。
有名所ではRSpec等でしょうか。

## インストール

不要。組み込まれています。以下で確認可能。

```shell-session
$ gem list
```
## かんたんなテストサンプル

```ruby
# for Minitest 5

# autorunを読み込むと、ファイルを実行したときにテストを実行してくれる
# example : $ ruby test.rb
require 'minitest/autorun'

# テスト対象クラス
class MyMath
    def add(a, b)
        return a + b
    end
end

# テストクラス。Minitest::Testを継承する
class MyMathTest < Minitest::Test
    # テストメソッドはtest_ではじめる
    def test_add
        assert_equal 5, MyMath.new.add(2, 3)
    end
end
```
CocoaPodsに登録したライブラリの更新

#はじめに#
CocoaPodsに登録したライブラリがあるときに、そのバーションアップをCocoaPods側に反映させる手順についてメモします。

#前提#
仮に、"SwiftyPickerPopover"という名前のライブラリについて、version 1.0.0から1.1.0へのアップデートをしたい場合を考えてみます。

#手順#
1. podspecの`s.version = "1.0.0"`を`1.1.0`に書き換えます。コミットを作ります。

2. `s.source = { :git => "https://github.com/hsylife/SwiftyPickerPopover.git", :tag => s.version }` のようにしておき、対象コミットに`1.1.0`のタグに打ちます。

3. ターミナルを開きます。リポジトリのディレクトリまで移動して、`pod spec lint`を実行します。バリデージョンをパスできると、SwiftyPickerPopover.podspec passed validation.の結果が表示されます。

4. `pod trunk push`を実行します。これにより、CocoaPods側にpodspecの内容を反映させます。

5. 正常に反映できているかを確認するために`pod trunk info SwiftyPickerPopover`を実行します。`- 1.1.0`のVersionが表示されていれば成功です。

#ミスした場合のキャンセル#
`pod trunk push`を実行した後でキャンセルしたい場合は、最後のバージョンを削除する。`pod trunk delete SwiftyPickerPopover 2.3.0`のようにコマンドを実行することで、任意のバージョンを削除できる。ライブラリ名 削除したいバージョンの順に記述する。

#おまけ#
タグをつけると、GitHubのreleasesにバージョンごとの記録も残るので便利です。

#関連#
[CocoaPodsにライブラリを登録する](http://qiita.com/key/items/663b0757f57434701fdb)
[SwiftyPickerPopover](https://github.com/hsylife/SwiftyPickerPopover)
C#のプロパティを動的にアクセスする

#動的にプロパティへアクセスする方法
クラスのプロパティへ値を設定したり読んだりする時に、プロパティ名が規則的なルールを持っていたりデータ側が持っている文字列から作成できる時があります。
switch文などを使って分岐してアクセスするのは馬鹿らしいですよね。
そういった場合には、一手間掛けてアクセスするとプログラムの見通しがグッと良くなります。

##リフレクションを使ってアクセスする
最も単純な解決方法は、言語のリフレクション機能を使ってアクセスする方法です。
ただし、通常アクセスできないメソッドにアクセスできてしまうため無制限に行うものではありません。
プロパティアクセスに限定して抑制的に利用しましょう。
実行速度が非常に遅いため繰り返し呼ばれるルーチンなどでは利用しない方が良いです。

```:ReflectionUtility.cs
public class ReflectionUtility
{
        /// <summary>
        /// プロパティ情報の取得
        /// </summary>
        /// <param name="type">型</param>
        /// <param name="name">プロパティ名</param>
        /// <returns>プロパティ情報</returns>
        public static PropertyInfo GetPropertyInfo(Type type, string name)
        {
            var property = type.GetProperty(name);

            return property;
        }
}
```

```:Test.cs
var property = ReflectionUtility.GetPropertyInfo(this.GetType(), "UserData" + string.Format("{0:00}", index));

property.GetMethod.Invoke(this, new object[1] { 0, });
```

##アクセッサーを使ってアクセスする
リフレクションの動作速度が遅いというデメリットを解決する方法がアクセッサーです。
アクセッサーは、プロパティのデリゲートだけを持ったオブジェクトです。
デリゲート経由でプロパティにアクセスするため実行速度は高速でです。
(※プロパティ構文のアクセッサー宣言とは違うものです)

```:IAccessor.cs
public interface IAccessor
{
        /// <summary>
        /// 読み取り属性
        /// </summary>
        bool CanRead { get; }

        /// <summary>
        /// 書き込み属性
        /// </summary>
        bool CanWrite { get; }

        /// <summary>
        /// 値の取得
        /// </summary>
        /// <param name="target">インスタンス</param>
        /// <returns>値</returns>
        object GetValue(object target);

        /// <summary>
        /// 値の設定
        /// </summary>
        /// <param name="target">インスタンス</param>
        /// <param name="value">値</param>
        void SetValue(object target, object value);
}
```

```:PropertyExtension.cs
public static class PropertyExtension
{
        public static IAccessor ToAccessor(this PropertyInfo pi)
        {
            Type getterDelegateType = typeof(Func<,>).MakeGenericType(pi.DeclaringType, pi.PropertyType);
            Delegate getter = Delegate.CreateDelegate(getterDelegateType, pi.GetGetMethod());

            Type setterDelegateType = typeof(Action<,>).MakeGenericType(pi.DeclaringType, pi.PropertyType);
            Delegate setter = Delegate.CreateDelegate(setterDelegateType, pi.GetSetMethod());

            Type accessorType = typeof(Accessor<,>).MakeGenericType(pi.DeclaringType, pi.PropertyType);
            IAccessor accessor = (IAccessor)Activator.CreateInstance(accessorType, getter, setter);

            return accessor;
        }
}
```

```:Test.cs
var property = ReflectionUtility.GetPropertyInfo(this.GetType(), "UserData" + string.Format("{0:00}", index));
var accessor = property.ToAccessor();

accessor.SetValue(this, data);
```
R > help.search() > 関数やデータセットの表示 > help.search("Titanic") / help.search("datasets")

```txt:動作環境
RStudio 0.99.903 on Windows 7 pro
R version 3.3.1 
```

help.search()というもので関数のヘルプが表示できるとのこと。

```R
> help.search("Titanic")
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5063e6e9-f86d-4caf-acc2-e8e3ededa6ea.png)

```R
> help.search("datasets")
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/1ea9d514-a790-e768-3675-05cdbb6ab250.png)

datasetsで検索すると色々なサンプルデータが見つかった。

```R
> head(boot::bigcity)
    u   x
1 138 143
2  93 104
3  61  69
4 179 260
5  48  75
6  37  63
```
Visual Studio 2015 と Windows 10 SDK のインストールで エラー「2147287038(0x80030002) 」が出る

Visual Studio 2015 Update3 をインストールするときに Windows 10 SDK(10.0.14393.33) を一緒にインストールしようとすると、エラー「-2147287038(0x80030002) 」が出る。

以下はインストールが出来た手順です:

1. Visual Studio 2015 Update3 のアンインストール
1. Windows 10 SDK(10.0.10586.212) と Visual C++ 2015 用の共通ツール にチェックを入れて、Visual Studio 2015 Update3をインストール
1. Windows 10 SDK(10.0.14393.33) と Visual C++ 2015 用の共通ツール にチェックを入れて、変更インストール
（なぜか、Visual C++ 2015 用の共通ツールのチェックが無かったため再度チェック）
Django で、URL ( path_info ) から名前空間つきビュー名を求めるには

Django で、URLのパス (例: /admin/auth/user/1/change/ ) から、名前空間 (namespace) のついたビュー名を求める場合。

ついでに解析された引数も表示する。

```python3
from django.core.urlresolvers import get_resolver

path_info = '/admin/auth/user/1/change/'

resolver = get_resolver(None)  # 最近の Django は引数無くても良い

resolver_match = resolver.resolve(path_info)
print('view_name:', resolver_match.view_name)

callback, callback_args, callback_kwargs = resolver_match
print('args:', callback_args, ', kwargs:', callback_kwargs)
```

結果

```
view_name: admin:auth_user_change
args: ('1',) , kwargs: {}
```