OmniAICreator/Qiita-1.07M huggingface dataset:
OpenPoseのHand Estimationを動かしてみた。

#目次
[1.OpenPoseを動かしてみた。](http://qiita.com/nnn112358/items/a4490d85dac5827db53b)
[2.OpenPoseチュートリアルのソースコードを読む。](http://qiita.com/nnn112358/items/ccd6330bed1e253d5ef9)
[3.WindowsでOpenPoseを動かしてみた。](http://qiita.com/nnn112358/items/121dc36c3c1752a00276)
[4.OpenPoseのFace Estimationを動かしてみた。](http://qiita.com/nnn112358/items/398765b5a4e5158b9ba2)
[5.OpenPoseのHand Estimationを動かしてみた。](http://qiita.com/nnn112358/items/713b4b8de25318fb1afc)


##目的
OpenPose 1.0.0(Jul 2017)が公開され、遂にHand Estimationが実装された。
[github OpenPose](https://github.com/CMU-Perceptual-Computing-Lab/openpose)


##動作例
![out.png](https://qiita-image-store.s3.amazonaws.com/0/73020/309ad102-db7e-ea4f-d41b-009a24209348.png)
フリー素材アイドルmika☆rika様の素材画像を使用しました。 http://mika-rika-free.jp/

##動作環境
>Description:	Ubuntu 14.04.5(x64) LTS trusty
CUDA Version 8.0.61
NVIDIA-SMI 375.66 / Driver Version: 375.66  / GeForce GTX 1050 
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
OpenPose v1.0.0

###OpenPoseに必要なライブラリのインストール
[OpenPoseを動かしてみた。](http://qiita.com/nnn112358/items/a4490d85dac5827db53b)を参照。
---[CUDA v8.0のインストール](http://qiita.com/nnn112358/items/a4490d85dac5827db53b#cuda%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
---[cuDNN v5.1のインストール](http://qiita.com/nnn112358/items/a4490d85dac5827db53b#cudnn%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
---[OpenCV/Atlasのインストール](http://qiita.com/drafts/713b4b8de25318fb1afc/edit)

###OpenPoseのダウンロード・インストール

```
$ mkdir ~/openpose_dev
$ cd ~/openpose_dev
$ git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git
$ cd openpose/
$ ./ubuntu/install_caffe_and_openpose_if_cuda8.sh
```


###コードの修正

>./example/openpose/openpose.cpp

　 Check failed: error == cudaSuccess (2 vs. 0)  out of memory
　out of memoryとなる場合、GPUのメモリを飽和している。
　net_resolution・face_net_resolution・hand_net_resolutionを調整して、GPUのメモリの使用量を小さくする。


>DEFINE_string(net_resolution, "320x160",)
>DEFINE_string(face_net_resolution,"256x256",);
>DEFINE_string(hand_net_resolution,"256x256",);


###デモを実行する。

1. WebカメラでPose Estimation動かしてみる
>./build/examples/openpose/openpose.bin

2. WebカメラでPose Estimation+Face Estimation動かしてみる
>./build/examples/openpose/openpose.bin --face

3. WebカメラでPose Estimation+Face Estimation+Hand Estimation動かしてみる
>./build/examples/openpose/openpose.bin --hand --face

---

###所感
openposeの正式版かリリースされ、全機能が使えるようになった。
handとfaseを同時に使うにはそれなりに上位のgpuが必要そうである。GPUメモリ2Gではでは片方しか動かせなかった。
bindActionCreators expected a function actionCreator for key '<ActionCreatorのキー名>', instead received type 'undefined

React & Reduxのコーディングで上のようなjsエラーが出て頭を捻ることが2回あったので、3度目がないようにメモ。

# とりあえず解決法
Container ComponentからActionCreatorをインポートする箇所を修正。

```js:container.js(before)
import hoge from 'action.js'
```

```js:container.js(after)
import { hoge } from 'action.js'
```

# エラーが出ていた原因

ActionCreatorは1つのjsに複数書いており、 `export default` していないため。

```js:action.js
export const hoge = () => ({
    type: 'HOGE',
})

export const fuga = () => ({
    type: 'FUGA',
})
```

# あとがき
React, Reduxやそのビルド環境で詰まり、昨今のフロントエンド界隈ハードすぎと思いきや、JSやES6が分かっていなかっただけ、ということがとても多いので勉強し直したいと思いました。
JWT/OpenID Connect に対する疑問

# JWT を localStorage に保存して大丈夫？

```html
<script src="//外部のCDN/jquery.js"></script><!-- 1 -->
<script src="トークンを扱う.js"></script><!-- 2 -->
```

ってすると取れそう？って思ったけど、[ブラウザ内部に保存されるデータへのアクセスは、オリジンによって権限が分かれている](https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy#Cross-origin_data_storage_access)。<strike>クロージャでスコープ切ってる限りは大丈夫そう。</strike>

追記：オリジンはHTMLのオリジン。悪いスクリプトを読み込んじゃうとダメ。ちゃんと調査した後に、意図しない改変を防ぐために [Subresource Integrity](https://developer.mozilla.org/ja/docs/Web/Security/Subresource_Integrity) を使う。 `integrity` 属性でハッシュを付けて検証されるようにしよう。

さらに追記： `integrity` 属性でも限界あるよねという話。 ([Please Stop Using Local Storage](https://www.rdegges.com/2018/please-stop-using-local-storage/)) 適切な属性で Cookie に乗せよう。あとそもそも OpenID Connect の流れでは `localStorage` に置く流れにはならないはず。

> And while we’re at it: subresource integrity (while cool) is also not a global solution to this issue. For most marketing tools, ad networks, etc. (which are by far the most commonly used types of third party JavaScript), subresource integrity is almost never used as the providers of those scripts want to change them frequently so they can silently update functionality for their users.

# RS256 ってどれぐらい強いの？

[RFC 7518](https://tools.ietf.org/html/rfc7518#section-7.1.2) によると、 RSASSA-PKCS1-v1_5 using SHA-256 。 [いろんな機関の基準](https://www.keylength.com/en/4/) をながめると、2048 bit の鍵を 1, 2 年に 1 回ぐらい鍵を更新しとけば 2030 年ぐらいまでは戦えるかも。適当に作ったシステムが意外と長く使われるのはよくある話なので、余裕を持ってより強い鍵を使っておいた方がたぶん良い。

# 鍵ってどうやって更新するの？

鍵を変更すると2種類の鍵で作られたトークンが世の中に存在することになる。検証時にキーを特定するには、["kid" (Key ID) Header Parameter](https://tools.ietf.org/html/rfc7515#section-4.1.4)を使ってキーを探す。古い鍵はしばらく検証のみに（非対称なら秘密鍵を失効）して、 "exp" クレームに設定した最後の期間を過ぎたら検証側も失効する。

# Revoke ってどうしたら良い？

`jti` で区別して [ブラックリストに入れる](https://auth0.com/blog/blacklist-json-web-token-api-keys/)。

DB へのアクセスが必要なくなるのがメリットの一つではあるが、マルチテナントを導入した時点で普通はキーをテナントごとに持つので、すでに考慮しなくても良いという主張。キャッシュを導入したり、非同期で配布して IO を追い出したりして最適化する。 `exp` を考慮すれば、貯まり続けるのも防げる。

特殊な状況でも無い限り、（ブラックリスト）⊂（全体のトークン）にはなるはずなので、セッションID方式に比べてまだメリットはあるかなと思う。

# OpenID Connect トークンが二種類あるのはなぜ？

[ジャストな回答](http://blog.openid.or.jp/post/12874061176/openid-connect-tale-of-two-tokens)。

ID Token は JWT ですが、 Access Token に関しては IdP が独自に決められることが特に重要そう。
「RP が IdP を利用して End-User が本人か確認する」ことと、「RP が End-User の認可の下で IdP のリソースにアクセスできる」というのは、必ずしも一致しないという事情があるようです。認証を継続しつつ権限を変更とかが可能になりそう。

# ID Token があれば UserInfo Endpoint いらなくない？

[実装して理解するLINE LoginとOpenID Connect入門](https://www.slideshare.net/naohiro.fujie/line-loginopenid-connect) より、

> ID TokenにもID情報を含められるがトークンのサイズの巨大化の問題や認証時以外の情報取得に対応するためUserInfoを使用
ブラウザログをターミナルに流してデバッグ情報を一元管理する


chrome extension作った

[console reporter](https://chrome.google.com/webstore/detail/console-reporter/mnojelhkkdbklbncbemblmpbnkpncpfe)

READMEを見たほうがよくわかるかもしれない

[console reporter - GitHub](https://github.com/KeitaMoromizato/console-reporter)

## 何をするのか

仕事でnode.js/Reactのアプリケーションを作っている。サーバーログ、eslint/flowの結果をひとつのコンソール上で流しており、問題があればすぐに気づけるのだけれど、ブラウザコンソールだけは画面スペースの問題で表示していないことがある。

それだと細かいwarningとかを見逃してしまったりするので、いっそブラウザログもターミナルで一元化して見れたらいいなと作ったのがこちら。

![capture.gif](https://qiita-image-store.s3.amazonaws.com/0/52054/c124de4f-6694-1f1f-0102-5aa1b09f431d.gif)

仕組みはそれほど難しくなく、chrome extensionでブラウザのconsole.xxを上書きして、terminalで待ち受けているサーバーにPOSTしているだけ。

ログレベルを指定して送信することも可能。redux-loggerのlogが邪魔であればOFFにしておく、といった使い方ができる。ブラウザには通常通りログはでるので、必要なときにだけそれを見ると良い。

![Screenshot from 2017-07-09 20-58-30.png](https://qiita-image-store.s3.amazonaws.com/0/52054/28535de0-3ded-793d-fce4-cdce80608bdc.png)



サーバー側は[Docke Imageとして公開](https://hub.docker.com/r/moromii/console-reporter/)しているため、nodeアプリでもrailsアプリでも何にでも組み込みやすい。docker-composeを使っているのなら、servicesに4行追加するだけで使えるようになっている。

```yml:docker-compose.yml
services:
  browser:
    image: moromii/console-reporter
    ports:
      - 3333:3333
```

npmとしても公開したほうがいいなとは思っているけど、Dockerもっと流行れと思っているので皆この機会にdockerを使おう。docker for macのマウント遅い問題もCE 17.06がリリースされてcacheオプションがサポートされたことで問題ない速さになった（※個人の感想です）


[開発環境をDockerに乗せる方法とメリットを3ステップで学ぶチュートリアル
](http://qiita.com/KeitaMoromizato/items/ae1a57fc62b41b942d71)


## 残Issue

- chrome extensionが読み込まれるタイミングの問題？で、ページロード時のJSログには対応できていない
IE11で「新しいAzure Portal」アクセス時に"HTML5 Storage disabled"

# 概要

Windows 10のInternet Explorer 11でAzureの「新しいポータル」にアクセスすると"HTML5 Storage disabled"とのエラーが表示される。ここでは、IEの詳細設定で「DOMストレージを有効にする」が無効化されている可能性と、Sysprepで展開されたWindows 8/8.1/10環境で特定ディレクトリへの権限付与が必要な可能性の2つを挙げる。

# 詳細

## 現象

Windows 10のInternet Explorer 11でAzureの「新しいポータル」にアクセスすると"HTML5 Storage disabled"とのエラーが表示される。ここから「Azure Classical Portal」にアクセスした場合、こちらは表示される。

## 「詳細設定 > セキュリティ > DOMストレージを有効にする」の確認

「[Azure Portal thinks HTML5 Storage is disabled on IE11 / Win 8.1 desktop](https://social.msdn.microsoft.com/Forums/security/ja-JP/f62a9580-f787-4e85-b728-15b7cbf3d6e8/azure-portal-thinks-html5-storage-is-disabled-on-ie11-win-81-desktop)」の以下を確認する。

> You can enable local storage (aka DOM storage) in IE11 by going to Tools > Options > Advanced > Security > Enable DOM storage.

日本語環境では「詳細設定 > セキュリティ > DOMストレージを有効にする」。私の環境では、チェックが入っていた。

## Sysprepで展開されたWindows 7/8.1/10のアクセス権修正

「[Windows 8 / Windows 8.1 / Windows 10 環境において、展開後の一部フォルダーに Low Mandatory Level アクセス権が付与されない | Ask CORE](https://blogs.technet.microsoft.com/askcorejp/2016/01/24/windows-8-windows-8-1-low-mandatory-level-1/)」にそって、以下を実行する。なお、これを実行したのは、私の環境が該当OS版数で、Sysprepで展開されたものと思われたため。

1. コマンドプロンプトと「管理者で実行」で開く。
2. 以下の3行をそれぞれ実行する

    icacls "%userprofile%\appdata\locallow\microsoft\Internet Explorer" /setintegritylevel (OI)(CI)L
    icacls %userprofile%\appdata\locallow\microsoft /setintegritylevel (OI)(CI)L
    icacls "%userprofile%\appdata\locallow\microsoft\Internet Explorer" /setintegritylevel (OI)(CI)L

私の環境では、これを実行した後に「新しいAzure Portal」を開いていたタブをリロードしたところ、エラー表示が解消された。

# 参考

以下の情報を参考にした。

* [Azure Portal thinks HTML5 Storage is disabled on IE11 / Win 8.1 desktop](https://social.msdn.microsoft.com/Forums/security/ja-JP/f62a9580-f787-4e85-b728-15b7cbf3d6e8/azure-portal-thinks-html5-storage-is-disabled-on-ie11-win-81-desktop)
* [Windows 8 / Windows 8.1 / Windows 10 環境において、展開後の一部フォルダーに Low Mandatory Level アクセス権が付与されない | Ask CORE](https://blogs.technet.microsoft.com/askcorejp/2016/01/24/windows-8-windows-8-1-low-mandatory-level-1/)

後者は、以下のページで見つけた。

* [IE11でLocalStorageが使えない時の対処法 - Qiita](http://qiita.com/hida/items/5570e390781b6f118a4f)

----

本ページ内容は作成者の個人的なメモです。内容を保証するものではありません。また作成者の所属組織等とは一切かかわりがありません。
mysqlが起動出来ないとき

# 概要

MacにMySQLを入れたとき、下記のエラーが出ました。

```
ERROR! The server quit without updating PID file
```

かなりありがちなエラーなため検索するとすぐに引っかかるのですが、自分の場合は検索して得られた情報だけでは解決出来なかったので、記事を書きました。

# 原因

このエラーが出る前、自分は下記のエラーに遭遇しました。

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
```

そこで、 `/tmp.mysql.sock` が存在しないのかーと思った自分は、下記コマンドで `/tmp/mysql.sock` を生成しました。

```
# touch /tmp/mysql.sock
```

結果的にこれがまずく、上記コマンドで生成されたファイルの所有者はユーザ自身になってしまうのです。
(本来は `_mysql` になるべき)

```
# ls -la
-rw-r--r--   1 root         wheel      0  7  9 20:30 mysql.sock
```

# 解決策

下記コマンドで、ファイルの所有者を正しく戻します。

```
# chown -R _mysql:wheel /tmp/mysql.sock
```

これでもまだ起動出来ない方は、下記リンクも参考にしてみてください。

- [mysql起動で「The server quit without updating PID file」](http://qiita.com/mogetarou/items/e34ca51d3756d55d7800)
- [MySQLが起動しないエラー（The server quit without updating PID file）](http://easyramble.com/mysql-server-pid-file-error.html)
【Python】指定間隔を5分区切りにする【datetime】

# 指定間隔の時間を5分区切りにする

```py3

from datetime import datetime, timedelta

def split_span_by_5min(start_time, end_time):
    """
    start_time, end_time 間を5分毎に区切ったリストにして返す
    (end_timeは含まない)
    param start_time: datetime.datetime
    param end_time:   datetime.datetime
    return list = [datetime.datetime,..]
    """
    span_list = list()
    handle_time = start_time
    while(True):
        span_list.append(handle_time)
        next_time = handle_time + timedelta(minutes=5)
        if next_time < end_time:
            handle_time = next_time
        else:
            break
    
    return span_list
```
pythonで時刻文字列をパースする３つの方法【備忘録】


# やりたい事
テキストで書かれた時刻をpythonのdatetime型にパースする際の方法について備忘録を作っておきたい。

# 環境
- Windows10 pro
- anaconda navigator 1.6.2
- Jupyter Notebook 5.0.0
- python 3.6.1
- Intel Core i7 4770 16GB
 
#経緯
１．[OpenWeatherMap](https://openweathermap.org)のXML内に登場する日時が見たことない形式(自分だけ)かつ時刻がGMT(UTC)だった。
２．9時間足してあげる処理をしないと時差で日付が違う状態になってしまう事態に対応するのが大変。
３．あらかじめ用意されている型に入れて時差を追加で計算してあげるのが一番と考えた。

ちなみにXMLの中で登場する日付はこんな感じ。

```text
2017-07-08T19:33:11
```
パースの方法を調べたらたくさんあったのでコードをまとめておく。

```py3
import time
from datetime import datetime
from dateutil.parser import parse

start = time.time()
date="2017-07-08T19:33:11" #パース対象の文字列
for i in range(100000): #parse()で10万回パースするループ
    dt1 = parse(date)
elapsed_time_for_parse = time.time() - start #parse()でパースした場合の経過時間を格納

start = time.time()
for i in range(100000): #strptime()で10万回パースするループ
    dt2 = datetime.strptime(date, '%Y-%m-%dT%H:%M:%S')
elapsed_time_for_strptime = time.time() - start #strptime()でパースした場合の経過時間を格納

start = time.time()   
for i in range(100000): #文字列切出で10万回パースするループ
    dt3 = datetime(
        year=int(date[0:4]),month=int(date[5:7]),day=int(date[8:10]),
        hour=int(date[11:13]),minute=int(date[14:16]),second=int(date[17:20])
    )
elapsed_time_for_cutparse = time.time() - start #文字列切出でパースした場合の経過時間を格納

print('parse()       takes {:.4f}sec, dt1:{}'.format(elapsed_time_for_parse,dt1))
print('strptime()    takes {:.4f}sec, dt2:{}'.format(elapsed_time_for_strptime,dt2))
print('cut and parse takes {:.4f}sec, dt3:{}'.format(elapsed_time_for_cutparse,dt3))
```

#結果
| 方法      |所要時間|
|:----------|-------:|
| parse()   | 5.8433 |
| strptime()| 1.0622 |
| 文字列切出| 0.2875 |
※所要時間は筆者の上記環境で10万回ループを実行した時間

#まとめ
parse()が一発で楽だけど遅い
文字列切出が手間多いが速い。

#参考にさせていただいたサイト

[OpenWeatherMap](http://openweathermap.org/forecast5)
[コード７区 日時の文字列を python でパース。年月や時分を取りだす](http://ailaby.com/parse_date/)
[miyalog Python の datetime.strptime がすんごく遅い件](http://miyalog.hatenablog.jp/entry/python_strptime)

#jupyter notebookの結果画面

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104578/0e1cc4cc-9cb4-861f-6f42-2496bb51f1d9.png)
gem open の先にMacのEmacsの find-file 相当で飛ぶ方法

まず `emacsclient` のラッパーを作っておきます。この時点で、プロセスを共有する程度ではなく、元のEmacs自体で開くようにしておきます。また裏でこっそり開いている場合があるので AppleScript で Emacs にフォーカスを持っていくようにします。

```bash:~/bin/e
#!/bin/sh
emacsclient -e "(find-file \"$1\")"
osascript -e 'tell application "Emacs" to activate'
```

次にそれをデフォルトのエディタとして反応するようにしておきます。

```zsh:~/.zshenv 
export EDITOR=e
```

これで、次のようにすると、すぐに `/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activemodel-5.1.2` に飛べたりします。

```shell-session
$ gem open activemodel
```

このあと、本来なら emacsclient を抜けなければ上のターミナルに戻れなかったりするのですが、`find-file` で飛んだ効果で、
「あとで emacsclient を抜ける」ことを考えなくてよくなります。

# 参考

https://ja.stackoverflow.com/questions/20456/terminal%E3%81%8B%E3%82%89-emacsclient-%E3%82%92%E9%96%8B%E3%81%84%E3%81%9F%E6%99%82%E3%81%AB-waiting-for-emacs-%E3%81%A7%E5%BE%85%E6%A9%9F%E3%81%97%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B

# 2017-09-11 追記
emacsclient を抜けたあとで続けて何かをするようなスクリプトもあるため、この方法を導入するといろいろおかしくなることに気づきました。もし参考にしていただいた方いましたら(いないと思いますが)切腹します。
PHP Manual 読書会(10回目)(クラスとオブジェクト1)

PHPに慣れる為に週1ぐらいで更新していきます。PHP Manualを読んで実験して行きます。

前回:[PHP Manual 読書会(9回目)(関数)](http://qiita.com/amesho/items/ba2e05c0efa98c3f0a25)

## クラスの基礎

```php
<?php

class Sample
{
    public $name = 'hello';

    public function displayName() {
        echo $this->name;
    }
}

$obj = new Sample();

$obj->displayName();
```

> PHP 5.4.0 以降では、新しく作成したオブジェクトのメンバーに、作成したその式の中でもアクセスできるようになりました。

つまり以下のような真似ができるようです。

```php
echo (new DateTime())->format('Y');
```

> クラスのプロパティとメソッドは、それぞれ別の "名前空間" に存在するので、 同じ名前のプロパティとメソッドを共存させることもできます。

名前の衝突はあっても問題ないが、

> プロパティに 無名関数 を代入した場合に、その関数は直接呼び出せないということです。 その場合は、たとえば事前にプロパティを変数に代入しておく必要があります。 PHP 7.0.0 からは、括弧で囲むことでプロパティを直接呼び出せるようになりました。

その作用として、無名関数を入れると直接呼び出せなくなるようだ。

継承をする場合は`extends`を使用。`parent`を使用して継承元のメソッドやプロパティへアクセスできる。

```php
<?php

class Sample
{
    public $name = 'hello';

    public function displayName() {
        echo $this->name . "\n";
    }
}

class ExSample extends Sample
{
    public function displayName() {
        parent::displayName();
        echo "Ex hello\n";
    }
}

$obj = new ExSample();

$obj->displayName();
```

`::class`を使用するとクラス名を取得できる。`namespace`を使用したときに便利に使えるようだ。

```php
<?php

namespace Hoge {
    class Sample
    {
        public function displayClassName() {
            echo Sample::class . "\n";
        }
    }
    $obj = new Sample();
    $obj->displayClassName();
}
```
自分の記事で読み返すことがありそうなやつのまとめ（daijinload）

自分の記事が多くなってきたので、整理してみました。
自分でも見返す記事を中心に持ってきているので、全部リストしているわけではないです。。

追記：2020/03/24 ファーストビューで、コメント欄が見えなくなっているので、タグで検索できるよというコメントを頂いたので、こちらにも書いておきます。

### Gitタグの検索
---

https://qiita.com/search?q=user%3Adaijinload+tag%3AGit&sort=created

### Git関連
---

- [Githubの作業をSSHで行う](http://qiita.com/daijinload/items/d4a336656a8b046a5f33)
- [Github上で消したブランチが見える場合](http://qiita.com/daijinload/items/8c6ae0088c992aa2b52b)
- [Gitでcloneしたリポジトリ全てに個人的なファイルのignoreを設定する方法](http://qiita.com/daijinload/items/6467d90b087390750e00)
- [Gitでコミットするアカウントを間違えた際に対象アカウントのみ一括置換する方法](http://qiita.com/daijinload/items/0e8e088730ea8100fbc0)
- [Gitで説明する機会が多かったのでまとめてみた](http://qiita.com/daijinload/items/00993075e0049c8131de)
- [Gitのブランチ名をコンソールに表示する方法](http://qiita.com/daijinload/items/2bb0031a706ce347aca6)
- [git clone時に.gitファイルを除く方法](http://qiita.com/daijinload/items/e501e670e36e915c614a)
- [rebase以外でmasterの修正を取り込んでいて、不要なコンフリクトが多発する場合の回避方法](http://qiita.com/daijinload/items/0989080a4dbd524890a8)
- []()
- []()
 
### Windows関連
---

- [Windows10でhash値を確認する方法](http://qiita.com/daijinload/items/f45f60767f8e48012288)
- [Windowsでgit cloneすると変更していないのに差分が出る](http://qiita.com/daijinload/items/7bcd2a466bfe9cc36d69)
- [Windowsでフォルダにあるファイルに一括で拡張子を付けるワンライナー](http://qiita.com/daijinload/items/351206b972bf4ce52e22)
- [windowsでmysql5.7をzipインストールする](http://qiita.com/daijinload/items/cf3e2e548f5008973140)
- [SSDをSecureEraseしてみた](http://qiita.com/daijinload/items/8f8142ef08aea6bc976a)
- []()
- []()

### Linux関連
---

- [unzipコマンドで日本語が文字化けした際の文字コード指定](http://qiita.com/daijinload/items/c2e5d3c7c62c3866ae07)
- []()
- []()
- []()

### 設計関連
---

- [ドメイン駆動設計（DDD）について書きます](http://qiita.com/daijinload/items/5b34190e202cd59703f4)
- [マネージドサービスとか出てきていますが、システム設計について整理しました](http://qiita.com/daijinload/items/f18cf5715873039e28d1)
- [技術選定の時に気を付けること](http://qiita.com/daijinload/items/cab3ed862c08da4c06e8)
- [擬似コードではなく、模擬コード（造語）のススメ](http://qiita.com/daijinload/items/dcdb45c9d6b4eeef2df0)
- [普段マネジメントしている人から、Webアプリケーションの作成方法を聞かれた話](http://qiita.com/daijinload/items/e25c2f41e67c901b0d98)
- [なぜ炎上する開発案件があるのか？考えてみた](http://qiita.com/daijinload/items/06807bb2b1fe7ac66099)
- [Googleのアカウント登録時のバリデート処理を調べてみた](http://qiita.com/daijinload/items/d817bbddc02825ae3c60)


### 未分類
---

- [超細粒度タスクでポモドーロ・テクニックする](http://qiita.com/daijinload/items/78ef912f9cfec9ff7b84)
- [集中できる開発スタイルを目指して](http://qiita.com/daijinload/items/a37364970f6d6f699bbc)
- [新卒の子にどこまで勉強すれば良いですかね？と聞かれた件](http://qiita.com/daijinload/items/0ee132950087da9366df)
- [プレゼン資料作成について](http://qiita.com/daijinload/items/6ff346e615262e2876d1)
- [PHPをNetbeansで開発するときのセットアップ手順](http://qiita.com/daijinload/items/2df0ab3d4f7f5ed726bf)
- []()
- []()
- []()
- []()
- []()
SEO対策一覧

SEO対策用の作業をまとめてみた。

１、HTMLタグを正しく書く。
２、metaタグを記入（description,ogpなど）
3、Google analyticsを設置
[参考リンク](https://liginc.co.jp/web/seo/107784)
4、Search Console連携
[参考リンク](https://liginc.co.jp/290591)
5、sitemap.xmlをgoogleに送信
[参考リンク](https://ferret-plus.com/1352)
6.googleマイビジネス登録
[参考](https://www.google.co.jp/business/)
[参考](https://maps.multisoup.co.jp/blog/958/)
(map表示、レビュー、プレビュー写真を登録)


その他：cssをminifyする。
C# で Thread.Sleep はあきまへん

ちいさな Tips。サンプルでよく使いますが、しばらく止まって欲しいときってありますよね。そのケースに、Thread.Sleep とかよく使うようです。ただ、これは、あまり使わないほうが良さげですね。

例えば次のようなサンプルを書いてみました。

```CSharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AwaitSample
{

    class Program
    {
        async Task<string> getMessageAsync(string message)
        {
            Console.WriteLine("getMessage!");
            System.Threading.Thread.Sleep(3000);
            Console.WriteLine("finished!");
            return "message:" + message;
        }
        async void executeAsync()
        {
            Console.WriteLine("step 1");
            var result = await getMessageAsync("hello");
            Console.WriteLine(result);
            Console.WriteLine("step 2");
        }
        static void Main(string[] args)
        {
            var program = new Program();
            program.executeAsync();
            Console.WriteLine("step 3");
            Console.ReadLine();
        }
    }
}
```
結果は step 1, 2, 3 が順に実行されてしまいます。私の想定では、step 1, getMessage! の後は、executeAsync() は非同期なので、先に step 3 が表示されると思っていました。

```
step 1
getMessage!
finished!
message:hello
step 2
step 3
```

理由は簡単で、[Thread.Sleep Method](https://msdn.microsoft.com/en-us/library/system.threading.thread.sleep(v=vs.110).aspx) は、スレッドを止めるメソッドだから、スレッドがブロックされます。だから、この非同期処理が、メインと同じスレッドを使っているとしたら、メイン側のスレッドも停止します。

この場合は、`TaskDelay()` メソッドを使ってみます。[Task.Delay Method (TimeSpan, CancellationToken)](https://msdn.microsoft.com/en-us/library/hh194845(v=vs.110).aspx) こちらは特定の時間の後、Taskの実行が終了しますので、スレッドをブロックしません。

```CSharp
            // System.Threading.Thread.Sleep(3000);
            await Task.Delay(3000);
```


```
step 1
getMessage!
step 3
finished!
message:hello
step 2
```

めでたしめでたし。
CTF問題解説


### RingZero
---
#### コーディング
[Hash me if you can](http://qiita.com/stu-sec-teams/items/ab93959ef1245464b9da)

#### フォレンジック
[I made add of Agent Smith usb key](http://qiita.com/stu-sec-teams/items/ab757f5a0440163b26b3)
rails4でBootstrapとBootswatchを使う

#目的
railsのビューには必須の[Bootstrap3](http://getbootstrap.com/)
更にテーマとして[Bootswatch](https://bootswatch.com/)を使う
ついでに[Font Awesome](http://fontawesome.io/icons/)も使えるようにする。

#環境
Rails4.3.9

#Bootstrap系のgem

#1) twitter-bootstrap-rails
bootstrap系では一番ヒットするgem。
このgemはlessで使用するんだけど、
BootswatchのGemである
twitter-bootswatch-railsと併用する場合
glyphiconが表示されなくなり、あきらめた。

#2) bootstrap-sass + bootswatch-rails
結局sass(scss)を使用するこっちに落ち着いた。

```:Gemfile
gem 'sass-rails', '~> 5.0'
gem 'autoprefixer-rails'
gem 'bootstrap-sass'
gem 'bootswatch-rails'
# FontAwesomeを使用する場合
gem "font-awesome-rails"
```
上記を追加し、bundle install

app/assets/stylesheets/application.cssをapplication.css.scssに変更し、
以下を記述する。
(例はbootswatchの"superhero"というテーマにしたい場合。
他のテーマに変えたい場合は"superhero"を"readable"とか"lumen"に適宜変更）

```scss:application.css.scss
@import "bootstrap-sprockets"; // これは一番上にしないとglyphiconが表示されない
@import "bootswatch/superhero/variables";
@import "bootstrap";
@import "bootswatch/superhero/bootswatch";
@import "font-awesome"; //FontAwesomeを使用する
```

app/assets/stylesheets/application.jsに「//= require bootstrap-sprockets」を追記する

```js:application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
//= require bootstrap-sprockets
```
これをしないとbootstrapのdropdownとかできないので注意

##他のテーマを適用させたい
例えば公式にあるテーマ[solar](https://bootswatch.com/solar/)はbootswatch-railsのgemでインストールされない。

この場合は
１）app/assets/stylesheetsにbootswatch/テーマ名（この場合はsolar)フォルダを作成。
２）その中に「_bootswatch.scss」「_variables.scss」の２つのファイルをbootswatchサイトからダウンロードし、置いておく。

あとは他のテーマと同様にapplication.css.scssにsolarの設定を書く。

```scss:application.css.scss
@import "bootstrap-sprockets"; // これは一番上にしないとglyphiconが表示されない
@import "bootswatch/solar/variables"; //solarの設定
@import "bootstrap";
@import "bootswatch/solar/bootswatch"; //solarの設定
@import "font-awesome"; //Font Awesomeを使用する
```
無料でR言語を勉強できる本 R Programming For Data Science

# この記事について

[Job Trendから見るデータ分析言語の記事](http://qiita.com/gigiwu/items/8657f1f6cc34f07c6a2d)を書いたあと、けっきょくどっちにしても損はないのを判明したので、まずは先輩たちが使ってる R を早速勉強し始めた。
Amazonで”R プログラミング”を検索したら、本だけで378件の検索結果でした。
私が読んだ本は [R Programming For Data Science](https://leanpub.com/rprogramming)
とてもおすすめなのでその理由を記事にしたいと思います。

# この本にした理由
表紙は謎なペンギン、オライリーみたいなすごそうなデザインでもない、他に似たようなタイトルもいっぱいありそうけど、この本にした理由は以下の３つ：

- 先輩に勧められたし、適当に"data science book"でググって出てきた上位の[Quoraの答え](https://www.quora.com/What-are-the-best-books-about-data-science)もこの本を勧めている
- LeanPub なので**無料**で Kindle 用のフォーマットもある
- 平易な言葉で長くない（ペーパーバックで194ページ）。これなら、読み切れる！　（←英語で読んでるから大事）

# 実際読んだ感想
実際読んだら、まだ途中ですけど、とても読みやすくてすごくいい本と思います。作者は R を学びながら、他の人に教えてたから（当時Rはまだ若くてcoolな言語だぞ）、今でも授業やりながらこの本をアップデートしてるみたい。**たくさんのトライアンドエラーの後の、最適化された教え方じゃないかなと思います。**

# 結論
ということで、今からRを勉強したい人には、その初歩として[R Programming For Data Science](https://leanpub.com/rprogramming)をおすすめしたいと思います。
Cocoaの機能を使ってメニューバーアプリケーションの使用をきっかけに動作するAppleScriptアプリケーションサンプル



* スクリプトエディタで下のコードを保存
	* ファイルフォーマット：アプリケーション
	* オプション：「ハンドラの実行後に終了しない」にチェック
* 通常のアプリケーションとして実行
	* 起動後は何も動作しないように見える
	* 通常のアプリケーションと同様、`command + Q`などで終了
* メニューバーアプリケーションを使用すると`notify`ハンドラが実行される
	* アプリケーションが起動している間は何回でも繰り返し実行される
* `notify`ハンドラ内で動作内容を決める
	* `if`から始まる行の`"com.google.musicmanager"`を、動作のきっかけとなる別のメニューバーアプリケーションのバンドルIDに変更
	* `delay 3`の行からが動作内容のメイン部分



```applescript:triggeredByUsingMenuBarApplication.app
use scripting additions
use framework "AppKit"
use framework "Foundation"

on run
	--NSDistributedNotificationCenterに"com.apple.HIToolbox.beginMenuTrackingNotification"という通知があったとき、このAppleScript内の"notify:"ハンドラを実行するobserverを追加
	current application's NSDistributedNotificationCenter's defaultCenter()'s addObserver:me selector:"notify:" |name|:"com.apple.HIToolbox.beginMenuTrackingNotification" object:(missing value)
end run

on quit
	--アプリケーション終了時、runハンドラでNSDistributedNotificationCenterに追加したobserverを削除
	current application's NSDistributedNotificationCenter's defaultCenter()'s removeObserver:me
	continue quit
end quit

on notify:notification
	--メニューバーアプリケーションのバンドルIDが"com.google.musicmanager"かどうかチェック
	set notifiedApplication to current application's NSRunningApplication's runningApplicationWithProcessIdentifier:(notification's userInfo's ToolboxMessageEventData)
	if (notifiedApplication's bundleIdentifier's isEqual:"com.google.musicmanager") as boolean then
		
		--3秒待ってダイアログ表示
		delay 3
		activate
		display dialog (notifiedApplication's localizedName as text) & " is being used" buttons {"OK"} default button 1
		
	end if
end notify:
```


## 更新履歴

* 2016-10-07: FoundationフレームワークのNSDistributedNotificationCenterクラスを使って作成
PyCharmのIdeaVimで日本語検索

PyCharmにIdeaVimプラグインをインストールして使用して特に不満もなかったんですが、最近ソースコード中の日本語を検索することが多い仕事がありました。

「意外と普通にプログラム組んでるときって日本語検索しないもんなんだな」と気づかされました。

ショーカットキー「/」でVimと同様に検索できますが、日本語書くと文字化けします。

![2017-07-09_18h53_06.png](https://qiita-image-store.s3.amazonaws.com/0/13183/b4c9b62b-a6d5-fa02-0c33-65ee5ec87d16.png)

もう諦めてCtrl+Shift+fでPyCharmの検索ウインドウ出してます。
F3で次を検索です。「n」とか打っても無駄です。

![2017-07-09_18h53_44.png](https://qiita-image-store.s3.amazonaws.com/0/13183/fc57fd31-5833-f0e1-d0ed-0a09f1fe7977.png)

PyCharmは「インストールしてそのまま使える」が一番良いところだと思うので、正直、調べる気にもなりません・・・
情報求む！
[iOS10] 煩わしいカーネルログを非表示にする

# 概要
iOS10からカーネルのログが出力されているため、XcodeのDevicesウィンドウからのログ解析が大変しんどくなっております。
そこで/Application/Utilities/Consoleアプリを使えば、不要なカーネルログの出力を非表示にすることが出来ることがわかったため、以下にやり方を記載します。

# やり方
１. 接続しているデバイスを選択する  
![Screen Shot 2017-07-09 at 16.52.17.png](https://qiita-image-store.s3.amazonaws.com/0/70065/24f62b9b-cf75-f828-af27-e8950384348d.png "Screen Shot 2017-07-09 at 16.52.17.png")

こちらでも何もしなければ、カーネルのログが出力され続けます。

２. Searchテキストボックスに以下を入力してエンターする。

使用している言語が、英語の場合

```
Library:libSwift(Enter)
```

使用している言語が、日本語の場合

```
ライブラリー:libSwift(Enter)
```

以下のようにカプセル化して入力されます
![Screen Shot 2017-07-09 at 18.28.55.png](https://qiita-image-store.s3.amazonaws.com/0/70065/9b8da69e-b380-fa39-c163-30216f4b50df.png "Screen Shot 2017-07-09 at 18.28.55.png")


３. クリアした後、ログ取りを開始する
以下メッセージ欄にNSLogの出力が表示しています。
![Screen Shot 2017-07-09 at 18.26.46.png](https://qiita-image-store.s3.amazonaws.com/0/70065/b00e6591-c4dc-5921-ff11-48c022c8d8f0.png "Screen Shot 2017-07-09 at 18.26.46.png")
RaspberryPiからBlueToothでGPSロガーに接続する(10Hz対応)

今回はGPSモジュールではなく、別体のGPSロガー(BlueTooth対応)から位置情報を取得する方法を書きます。
遮蔽物があってGPS衛星がつかめないけれどロガーを外に設置してBlueToothで接続することはできる、という超限定的な環境で意味があるかもしれない記事です。

まずBlueTooth関連の設定をしていきます。

必要なソフトのインストール。

```bash:
$ sudo apt-get install bluez
$ sudo apt-get install bluetooth blueman bluez-tool
```
2行に分ける必要があるかわかりませんが、参照したサイトがそうなっていたのでそれに倣って書いています。

下記のコマンドでbluetoothctlのプロンプト(#)に入ります。以下コマンドの後の#表記はroot権限ではありませんのでご注意下さい。

```bash:
$ sudo bluetoothctl -a
```

ペアリング対象のアドレスを確認します。

```bash:
# scan on
```

確認したらscanを終了します。

```bash:
# scan off
```

ペアリングします。

```bash:
# pair <ペアリング対象のアドレス>
```

ペアリング対象の自動接続に登録します。(任意)

```bash:
# trust <ペアリング対象のアドレス>
```

bluetoothctlから出ます。

```bash:
# exit
```

/etc/systemd/system/dbus-org.bluez.service
の以下の部分を変更します。
ExecStartは既にあると思うので書き換え。ExecStartPostを追記します。

```text:/etc/systemd/system/dbus-org.bluez.service
ExecStart=/usr/lib/bluetooth/bluetotthd --compat
ExecStartPost=/usr/bin/sdptool add SP
```

リブートします。デーモンの再起動では設定が反映されないようです。

```bash:
# reboot
```

たぶん「var/run/sdp」ができているので、権限を変更します。
できていなかったらmkdirすればok？
とりあえず777で動きますが、セキュリティ的なことは考えていないので、そのへんが重要な時は適宜対策して下さい。

```bash:
$ sudo chmod 777 /var/run/sdp
```

状態確認。

```bash:
$ sdptool browse local
```

Serial Port serviceがないので追加。channelは任意で。listen側にする時以外関係なさそう？

```bash:
$ sudo sdptool add --channel=22 SP
```

GPSロガーに接続します。

```bash:
$ sudo rfcomm connect hci0 <ペアリング対象のアドレス> &
```

あとは

```bash:
$ cat /dev/rfcomm0
```

でGPSデータが流れるはずです。

コマンドを流す時はいつもどおり、

```bash:
$ echo -e "\$PMTK220,100*2F\r\n" > /dev/rfcomm0
$ echo -e "\$PMTK300,100,0,0,0,0*2C\r\n" > /dev/rfcomm0
```

などとすれば良いハズです。
10Hz化について詳しくは[こちら](http://qiita.com/snz/items/624544d508867e6473c2)をご覧ください。
BlueTooth接続の場合は通信速度の変更は不要かもしれません。(詳細未調査。PMTK、sttyコマンドで変更できるのかも未調査。必要になったら調べます…。)

ここで新たに発見した注意点。
PMTK220コマンドとPMTK314コマンドは、両方共に報告周期をパラメータに持ちます。
それ故にどちらかのコマンドを入力すると、どちらかが反映されない事があるようです。
両方のコマンドを入力していて、後から入れたコマンドが反映されない時はこの辺を疑うと良いかもしれません。
これがチップ依存なのかロガー依存なのか仕様なのか判っていませんが、現状そのような動きになっているようです。

もしかしたら正式な仕様は決まっていないのかもしれません。
また、チップやロガーメーカーの資料も限定的であることが多いので、試してみるしか無いのかもしれませんね。
scoptって何？

https://github.com/scopt/scopt

## scoptとは
"scopt is a little command line options parsing library."

パーサーライブラリらしいです。

## パーサーって？
http://e-words.jp/w/%E3%83%91%E3%83%BC%E3%82%B5.html

"一定の文法に従って記述された複雑な構造のテキスト文書を解析し、プログラムで扱えるようなデータ構造の集合体に変換するプログラムのこと"

( ,,`･ω･´)ﾝﾝﾝ？
最初これ読んでよくわかんなかったんで、コード書いて理解してみました。

## コード

参考というかそのまま
http://qiita.com/yoheihonda/items/7d6bdedfe0df36d11da8

githubにサンプルコード作りました。
https://github.com/kazuogawa/samplescopt
intellijのsbtでプロジェクト作成

```build.sbt
name := "samplescopt"

version := "1.0"

scalaVersion := "2.12.1"

libraryDependencies ++= Seq(
  "com.github.scopt" %% "scopt" % "3.6.0",
  "joda-time" % "joda-time" % "2.9.9"

)
```

```samplescopt.scala
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat

object samplescopt {
  case class CommandLineArgs(
    //引数が設定されていなかった場合は現在時間の1日前を入れるみたいです
    from: DateTime = DateTime.now.minusDays(1),
    to: DateTime = DateTime.now.minusDays(1))
  def main(args: Array[String]): Unit = {
    //scopt.OptionParserにcase classの型を入れるみたいです。そのあとにパーサーの名前を入れるみたいです
    val parser = new scopt.OptionParser[CommandLineArgs]("your program name") {
      //--helpしたときに表示されるやつ？
      head("scopt", "3.6.0")

      val dtf = DateTimeFormat.forPattern("yyyyMMdd")
      //引数で設定する「-ほげほげ 値」またはの部分を作っているみたいですね
      //値の部分はcase classで設定した値を指定すればいいみたいですね
      //xには値が、cにはcase classに設定した型にパースされた値が入っているみたいです
      opt[String]('f', "from") action { (x, c) =>
        //println("x = "+ x)
        //println("c = "+ c)
        c.copy(from = DateTime.parse(x, dtf))
        //--helpを使った場合のメッセージが書かれるみたいです
      } text ("from is date")

      //上と同じようにしましょう
      opt[String]('t', "to") action { (x, c) =>
        c.copy(to = DateTime.parse(x, dtf))
      } text ("to is date")

      //--helpを出す場合に書くみたいですね
      help("help") text("print this usage text.")
    }
    println(parser.parse(args, CommandLineArgs()))
  }
}
```

sbtを実行

```
>sbt "run-main samplescopt -f 20170509 -t 20170709"
Some(CommandLineArgs(2017-05-09T00:00:00.000+09:00,2017-07-09T00:00:00.000+09:00))

>sbt "run-main samplescopt --from 20170509 --to 20170709"
Some(CommandLineArgs(2017-05-09T00:00:00.000+09:00,2017-07-09T00:00:00.000+09:00))

>sbt "run-main samplescopt --help"
scopt 3.6.0
Usage: your program name [options]

  -f, --from <value>  from is date
  -t, --to <value>    to is date
  --help              print this usage text.
```

## 要するに
case class で扱いやすいように渡された値をごにょごにょしてくれるものですね。

他に参考：
http://d.hatena.ne.jp/Kazuhira/20140115/1389801398
https://stackoverflow.com/questions/2315912/best-way-to-parse-command-line-parameters
Webpackで is not an absolute path! エラーの回避

### 問題

webpackで新しい環境を構築しているとき、以下のエラーが発生して困った

```
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.output.path: The provided value "./dist" is not an absolute path!
```

`./dist` 『それ絶対パスじゃないよ！』
そう言われても、絶対パス書いちゃうとあとで不便するし…

### 解決策

webpack.config.js 内で、現在パスを表す `${__dirname}` を記載するとなんとかなるかも

```js:webpack.config.js
module.exports = {
  output: {
    filename: '[name].js',
    path: `${__dirname}/dist` // バッククォート（ ` ）で囲ってね
  },
```

以上、ご報告でした。
ubuntuのLDAPでssh鍵を一括管理する時に詰まったこと

Ubuntuでsshの認証しようとした時、結構詰まったのでそのメモ書き

参考
OSバージョン：ubuntu16.04LTS
sshに使うやつ：ssh-ldap-pubkey

# とりあえずやりたかったこと

- 踏み台サーバーからクライアントに対してsshをかける
- 認証の際にLDAPサーバーの公開鍵を参照してログイン
- クライアント側には秘密鍵も公開鍵も置かない状態になっていること

# やり方

### クライアントサーバーに必要なものを一括インストール

サーバー

```
apt　install slapd libnss-ldap libpam-ldap nslcd
```

クライアント

```
apt　install libnss-ldap libpam-ldap nslcd
```

パスワードとかは任意のものを使用。

ldap://はLDAPサーバーのIPを入れてます（基本はドメインだと思う）

ついでに初期設定で聞かれるLDAPのドメインとかはそのサーバーのドメインをdc=ドメイン名で設定
例：）
xxx.example.comの場合
dc=example,dc=com見たな感じ

adminの設定もdcはさっき入力したやつを入力

あとはデフォルト値にしたがってはいはいと進めていきます。

### sshスキーマを作成してデータベースに入れる

CentOSだとデフォルトでスキーマとか入っているらしいのですが、Ubuntuはその辺適当みたいで、むしろ自分で作れって言われました。

デフォルトだとsshのObjactClassがないみたいなのでldifファイルを作成して食べさせます。

このソースをviでコピペして作成する。
↓これ
[openssh-lpk.schema](https://github.com/jirutka/ssh-ldap-pubkey/blob/master/etc/openssh-lpk.schema)

```
vi openssh-lpk.ldif
```

そんで管理者権限でさっき作ったやつをしれっと入れます。

```
ldapadd -x -W -D cn=admin,dc=example,dc=com -H ldap:/// -f openssh-lpk.ldif
```

これでスキーマがスコンと入れは成功

### ssh-ldap-pubkeyのインストール


あとは最近ssh-ldap-pubkeyなるものが使えるようになったみたいなのでそれをクライアントとサーバー両方にインストール

Pythonで書かれているらしくpipをあらかじめインストールしてから使ってください。

```
sudo pip install ssh-ldap-pubkey
```

あと、ライブラリが足りないみたいなのでこれも追加してインストール

```
sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev
```

これでssh-ldap-pubkeyが使えるのでログインしたいLDAPユーザーのホームディレクトリに公開鍵と秘密鍵があることを確認したらLDAPデータベースに公開鍵を以下のコマンドで入れます。

```
ssh-ldap-pubkey add ~/.ssh/id_rsa.pub
```

admin権限で入れろよと怒られた場合はadminをバインドして入れましょう

```
ssh-ldap-pubkey add -D cn=admin,dc=example,dc=com -u demouser ~/.ssh/id_rsa.pub
```

### クライアント側のsshdの設定の変更

このままだとクライアント側が普通のsshの認証しかしないので/etc/ssh/sshd_configの設定をviで編集。

```
vi /etc/ssh.sshd_config
```

認証する際にssh-ldap-pubkeyを使うように追記します。

その際にはパスワード認証はオフにしておくといいかも

```
AuthorizedKeysCommand /usr/bin/local/ssh-ldap-pubkey-wrapper
AuthorizedKeysCommandUser nobody
```

最後にsshdの再起動して反映させれば完了です。

```
systemctl restart sshd.service
```

あとはLDAPに公開鍵を登録したユーザーでsshできれば完成

参考URL
[ubuntu OpenLDAP](https://help.ubuntu.com/lts/serverguide/openldap-server.html)
[jirutka/ssh-ldap-pubkey](https://github.com/jirutka/ssh-ldap-pubkey)
[Server world LDAPサーバーの設定](https://www.server-world.info/query?os=Ubuntu_16.04&p=openldap)
Goでのアルゴリズムクイックリファレンス第2版(二分探索木)

Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。[アルゴリズムクイックリファレンス 第2版](https://www.amazon.co.jp/gp/product/4873117852/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4873117852&linkCode=as2&tag=amesho-22&linkId=b7688201ae37a6234596fa96dfd3ccdd)を読んで各種アルゴリズムをGoで実装して行きます。

前回: [Goでのアルゴリズムクイックリファレンス第2版(ブルームフィルタ)](http://qiita.com/amesho/items/03904b2d984ed8750dd1)

今回は[二分探索木](https://ja.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2%E6%9C%A8)

> 二分探索木（にぶんたんさくぎ、英: binary search tree）は、コンピュータプログラムにおいて、「左の子孫の値 ≤ 親の値 ≤ 右の子孫の値」という制約を持つ二分木である。探索木のうちで最も基本的な木構造である。

```go
package main

import "fmt"

type BinaryNode struct {
	Value int
	Left  *BinaryNode
	Right *BinaryNode
}

type BinaryTree struct {
	Root *BinaryNode
}

func NewBinaryNode(val int) *BinaryNode {
	return &BinaryNode{val, new(BinaryNode), new(BinaryNode)}
}

func (n *BinaryTree) Add(val int) {
	if n.Root == nil {
		n.Root = NewBinaryNode(val)
	} else {
		n.Root.Add(val)
	}
}

func (n *BinaryNode) Add(val int) {
	if val <= n.Value {
		if n.Left != nil {
			n.Left.Add(val)
		} else {
			n.Left = NewBinaryNode(val)
		}
	} else {
		if n.Right != nil {
			n.Right.Add(val)
		} else {
			n.Right = NewBinaryNode(val)
		}
	}
}

func (n *BinaryTree) Contains(target int) bool {
	node := n.Root
	for node != nil {
		if target < node.Value {
			node = node.Left
		} else if target > node.Value {
			node = node.Right
		} else {
			return true
		}
	}
	return false
}

func main() {
	bn := new(BinaryTree)
	bn.Add(1)
	bn.Add(2)
	bn.Add(3)
	bn.Add(100)

	if bn.Contains(4) == false {
		fmt.Println("not found")
	}

	if bn.Contains(100) {
		fmt.Println("found")
	}
}
```

次回は深さ優先探索です。
Laravelの論理削除と愉快なトラップたち


Laravelは簡単に論理削除を実装できるのですが、意外と落とし穴が多くハマったところがあったので、列挙していきます。
よりスマートな回避方法があれば、突っ込んでください。

## 論理削除したのにuniqueのバリデーションが通らない
論理削除の場合、以下のようなバリデーションは削除済を含めて一意であることをバリデーションします。

```php
    public function rules()
    {
        return [
            'name' => 'required|unique:countries'
        ];
    }
```

### 対策
#### 1. uniqueのルールをカスタマイズする

```php
    public function rules()
    {
        return [
            'name' => [
                'required',
                Rule::unique('countries')->whereNull('deleted_at')
            ]
        ];
    }
```

#### 2. カスタムバリデーションでEloquent ORMを使う
[Laravel5でカスタムバリデーション](http://qiita.com/zaburo/items/e584641cb720febd0d1c)を参考にするとできる。今はめんどくさいけど、[Laravel 5.5. Custom Validator Rules](https://laravel-news.com/laravel-5-5-custom-validator-rules)によると、5.5で楽になりそう

また、`exists`についても同じように、「削除したのにバリデーションが通ってしまう」現象が起きるので、同様の処置が必要です。

## `->delete()`メソッドを使うと孫が消えてくれない
論理削除のときにDelete on Cascade的なことをやりたいときの話
Country < User < Postのリレーションを例に使います。

まず、Userのdeletingイベントはこんな感じで書けると思います。

```php
    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($user) {
           $user->posts()->delete();
        });
    }
```

Countryのdeletingイベントをこう書くとCountry削除時にPostは消えません。あら悲しい。

```php
    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($country) {
           $country->users()->delete();
        });
    }
```

### 対策
#### 1. さくっとぐるぐる削除
一番てっとり早いものの、できれば採用したくないやり方。
Userをひとつひとつ削除するので、Userモデルに書いたdeletingが発火してくれる。

```php
    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($country) {
            $users = $country->users;
            
            foreach($users as $user) {
                $user->delete();
            }
            
        });
    
    }

```

#### 2. 削除するモデルを列挙
数が少ないならいいけど、リレーションしまっくてると書き出すのがめんどくさい

```php
    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($country) {
            $user_ids = $country->users->pluck('id')->toArray();
            
            Post::whereIn('user_id', $user_ids)->delete();
            User::destroy($user_ids);
        });
    }

```


## 検証用につくったリポジトリ
https://github.com/sawadashota/softdelete-traps
Tera Termマクロで自動ログイン


## 概要
デスクトップ上のファイルをダブルクリックすれば、目的のホストにSSHログインできるようにする。

頻繁にログインするホストがあったとき、毎回IPアドレスを入れて、秘密鍵のパスを入れて…とやっていると面倒だから。

## 方針
Tera Termマクロを使い、スクリプトを書く。
そのファイルをデスクトップに置き、Tera Termのマクロ実行エンジン「ttpmacro.exe」と関連付ける。

## 手順
Tera Termはインストールされている前提。

 * 下記の内容で、デスクトップにファイルを作成する。

```
username = 'ログインユーザ名'
hostname = 'ログイン先のIPアドレス(例：192.168.0.1)'
keyfile = 'ローカルに保存された秘密鍵のパス(例：C:\Users\foo\path\to\secret_key)'

msg = hostname
strconcat msg ':22 /ssh /auth=publickey /user='
strconcat msg username
strconcat msg ' /keyfile='
strconcat msg keyfile
connect msg
```

 * このファイルと"ttpmacro.exe"を関連付ける
    * Windows10ならば、ファイルを右クリックして、プロパティ->プログラムから選択する。
    * ttpmacro.exeは、Tera Termと同じディレクトリにインストールされているはず

### 秘密鍵のパスをファイルに書いてしまうのはちょっと…
 * 秘密鍵にパスワードをつけて、マクロ実行時にパスワードを聞かれるようにすることができる
 * こちらのサイトを参考に
    * https://mag.osdn.jp/10/01/08/0825239

### 鍵認証ではなくてパスワード認証にしたいんだけど…
 * 同じく、こちらのサイトを参考に
    * https://mag.osdn.jp/10/01/08/0825239
Windows10に開発環境

##ローカルでやるのが楽ちん
現在、Windows10で開発を行っているのだが今まではWEB(主にCodeCamp)でのエディタを使ってコードを書いていた。Mac寄りのエディタだったのですんごく使い辛いと思ってローカルに色々入れてみようと思い、開発環境を整えることにした。覚書としても記事に起こしておきたいからね。
###まずはApache2.4から
XAMPPに頼るのもいいんだろうけど、手動で入れてみたかったのでそれぞれ個別にダウンロード。Apacheは随分昔にローカルへ入れたことがあったのだが、CGIが流行りだした頃の話なので随分違うｗ

四苦八苦するほどではなかったけど少し悩んだ。1つ1つ何かを達成して行くのは楽しいし、面白い。勉強にもなるから一石何鳥にもなる。参考サイトをただただコピーするのではなく、1つ1つの設定が何をしてるのか理解しながら進めるのも面白い。

###次にPHP7.0系
非常に解りやすい参考サイトだったので凄く簡単に入れることが出来た。ベアメタルから構築することが今後、あると思うのでこういった環境構築は知っておかなければならないだろう。PHPでの開発が主になると思うので今後の為にも触っておいて損はないはず。

###PHPとMySQLはセット
MySQLも手動インストール。同じ参考サイトからのインストールなので非常に解りやすかった。特につまずくこともなくすんなり。

###phpMyAdminも入れとこう
コマンドラインでのSQLは正直、不慣れなのでphpMyAdminのインストールもやりました。コマンドラインでSQLが打てるようになったらSQL文を書くのが凄く早くなりそうだけど、ここはインターフェイスがあるのでそれに頼ろうかとｗ

###テキストエディタはAtom
開発環境を整えようと思う前からインストールはしていたので今後はAtomでコードを書いていこうと思います。あまり触れてなかったけど実際にAtom使ってみるとWEBのエディタより数百倍使いやすいことが解った。

参考サイト：[ウェブデザインラボ](http://www.webdlab.com/guide/local-apache-9/)
TrendMicroCTF 2017 writesup

時間がたっていますがTrendMicroCTF 2017を会社の人と参加したのでWritesUp
を投稿しておきます

#OSINT 100
以下のサイトに誘導されていると記載があるのでアクセスしてみる
http://ctf.superpopularonlineshop.com.definitelynotaphishingsite.com/

ページソースを見ても特にヒントとなりそうな箇所がない。
よって、次にこのドメインが誰によって取得されているかを確認する
whois definitelynotaphishingsite.com
怪しいユーザ名　osint isfunで登録されているのでこのユーザが他のドメインを取得していないか
を確認する
以下のサイトで、登録ユーザ名で検索可能
http://viewdns.info/reversewhois/
他にt3m4.comを取得しているのでアクセスする
![iot100-3.png](https://qiita-image-store.s3.amazonaws.com/0/156890/fcf46e32-1670-6d04-32c6-14be9318f3d5.png)
アクセスするとこのユーザが皆からT3-M4Haxorと呼ばれていると書かれている
![iot100-4.png](https://qiita-image-store.s3.amazonaws.com/0/156890/73b87e91-581c-c2e8-b6ce-280bd8194dcd.png)
上記のユーザ名で検索かけるとtwitterのユーザ名が出てくる
![iot100-5.png](https://qiita-image-store.s3.amazonaws.com/0/156890/0efea0d4-b915-fd4c-17b4-58484a5c14a2.png)
twittwerのアカウント名で検索をかけると過去に登録した本名が出てくる
![iot100-6.png](https://qiita-image-store.s3.amazonaws.com/0/156890/81bc1db3-3209-d7ee-0a5a-f8fabb2c4798.png)
本名での検索をかけるとLinkedinに登録されたプロフィール内にフラグが記載されている
![iot100-7.png](https://qiita-image-store.s3.amazonaws.com/0/156890/0cab39d0-b6e4-94d5-e2d6-b668a543e1e9.png)
フラグがROT13でデコードしフラグが出てくる
_TMCTF{FTR0SINT101}_

#Reverse 100
出てきたファイルがzipなので解凍
更に出てきたファイルがrarなので解凍
片方がパスワード付きzipファイルなので、もう片方の実行ファイルを実行すると
すぐに終了してしまうのでIDAPROでデバックする

ブレークポイントを仕掛けて実行すると、mから始まるお菓子の名前を探せと表示される。
![reverse100.png](https://qiita-image-store.s3.amazonaws.com/0/156890/b5d87d86-358a-1c13-1284-39f44caabe8c.png)

そのまま、Exceptionが発生する所まで実行するとメモリ内にお菓子の名前が展開されているので
それをパスワード付きzipファイルに代入
![reverse100-2.png](https://qiita-image-store.s3.amazonaws.com/0/156890/dc405e49-18c6-0221-4fef-c94ee947651c.png)

更に3つのファイルが生成される。それぞれテキスト、画像、実行ファイルになる
テキスト内に、画像ファイルと実行ファイル内にフラグがあると記載されているので調査する

画像ファイルは、一番最後にzipファイルが添付されているのでその部分のみ保存し、解凍するとフラグの一部、creamが出てくる

実行ファイルはIDAPROでデバックすると中でループをカウントする変数があるのでちょうど終了する所で、レジスタを確認するともう一つのフラグであるchouxが出てくる。
![reverse100-3.png](https://qiita-image-store.s3.amazonaws.com/0/156890/3a669dc5-c6be-22c9-c5fc-01287abc4be4.png)

_TMCTF{choux_cream}_
ちなみにテキストファイル通りに入力してもフラグにはならなかった・・・
#反省点
今回は100点の問題のみに時間をかけすぎてしまい、上位の問題にトライする時間があまりとれなかったので今後は時間をかけずに回答できるようにしていきたい
［Windows 64bit環境］Apache Sparkのインストールについて

Sparkの環境をWindows上で構築したくて
インストールしていたが、どうしてもバッチ起動でエラーになってしまったので、
対処方法をメモします。

# ̻■環境
Windows10 64bit

# ̻■インストール手順
○Apache Spark をインストールする
http://spark.apache.org/downloads.html
※バージョンは最新を取得（spark-2.1.1-bin-hadoop2.7）
　tgzが解凍できるソフトで任意のディレクトリに解凍しとく

○winutils.exeのダウンロード
https://github.com/steveloughran/winutils/blob/master/hadoop-2.7.1/bin/winutils.exe
※WindowsでSparkを実行するために、Hadoopの依存関係を解決するためのexe
別のバージョンのHadoopや32bit OSを利用する場合は、当該するバージョンのwinutilsのダウンロードが必要らしい。。
今回は2.7なのでこちら。
ダウンロードがすんだら、解凍した
Apache Sparkのbin直下に配置します。

# ̻■環境変数
○HADOOP_HOME
ApacheSparkを解凍したディレクトリ
D:\tools\spark-2.1.1-bin-hadoop2.7\

○path追加
%HADOOP_HOME%\bin

# ̻■実行
今回はScalaを起動します。
Windowの32bitだと
このまま下記ファイルを管理者権限で実行すればいいみたいなんですが、
D:\tools\spark-2.1.1-bin-hadoop2.7\bin
spark-shell.cmd

※管理者として起動しないとアクセスエラーが出ます。。

64bitだとパスで怒られてなんだかうまくいかない現象が発生しました。。
調べると、javaを実行する際にパス指定がよくないことがわかったので、
下記ファイルを修正。。
D:\tools\spark-2.1.1-bin-hadoop2.7\bin
spark-class2.cmd

```bat:spark-class2.cmd
rem Figure out where java is.
set RUNNER=java
if not "x%JAVA_HOME%"=="x" (
  set RUNNER=%JAVA_HOME%\bin\java :★ココのパスから""を除外してあげる
) else (
  where /q "%RUNNER%"
  if ERRORLEVEL 1 (
    echo Java not found and JAVA_HOME environment variable is not set.
    echo Install Java and set JAVA_HOME to point to the Java installation directory.
    exit /b 1
  )
)

```

そうすると無事起動完了！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/108839/0a8af57a-c538-0940-565e-8f2b0a2c5fca.png)


これでsparkいじれる～。

参考になれば幸いです。
Herokuをsleepさせない最も簡単な方法(Google Apps Script)

現在(2017.7.9)Herokuのフリープランでは30分間アクセスがないとsleepしてしまいます。
sleepさせたいために色々な方法がありますが、おそらく一番簡単にできる方法はGoogle Apps Scriptを使い30分おきにアクセスさせることだと思うので紹介します。

## Google app scriptの設定
まずGoogle Drive上で右クリックをし、"その他>アプリの追加"からGoogle Apps Scriptを追加します。
追加出来たら右クリックでその他からGoogle Apps Scriptを開くことができます。
そして以下のコードを入力  

<!-- jsではないけれど見やすいため -->
```js
function myFunction() {
  var url = "http://hogehoge.com/";    // 監視対象URL
  UrlFetchApp.fetch(url, { muteHttpExceptions:true });
}
```  
これでスクリプトは完成です。ここまでできたら一度ファイル名を付けて保存してください。
## トリガーの設定
アイコンバーの時計のようなアイコンをクリックすると、「トリガーが設定されていません。今すぐ追加するにはここをクリックしてください。」  と表示されると思うのでそちらをクリック。  
”時タイマー”を”分タイマー”にし”30分ごと”を選択して保存をクリックします。   
これで設定したurlに30分おきにアクセスされるのでHerokuがsleepすることがなくなります。ですがHerokuフリープランでは月の稼働時間は1000時間となっていますのでお気をつけてください。
  
---
  
意外とこの方法が書かれているページがなかったので紹介してみました！
Google Apps Scriptを知らなくても簡単に設定ができますね！素晴らしい！
Zabbix2.4でトラップの文字化け回避(zabbix_trap_receiver.pl版)

# やりたいこと
日本語版vCenterからのSNMPTRAP文字化けを直す。
こんな感じ・・・

### 対応前(16進数＋スペースの羅列)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/5d0d1b8b-b44e-7573-6b66-6046ae84a605.png)

### 対応後(日本語に!!)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/adc7ff9f-5bef-710c-a300-c2b26d1e6578.png)

# 制約事項

UTF8以外(シフトJIS等のマルチバイト)は対応できていません。

# 環境
SNMPTRAPの経由方法として「zabbix_trap_receiver.pl」を使用している環境

# 対処方法
### 既存プログラム「zabbix_trap_receiver.pl」をちょっぴり変更

元はZabbixソースコード2.4.8の「zabbix_trap_receiver.pl」を以下のように変更。
いつもながら適当ですが動くと思いますw。
PERLの正規表現のスマートな記述方法がわからず、ごちゃごちゃですいません。

```shell-session:zabbix_trap_receiver.pl
[localhost]# diff  zabbix-2.4.8/misc/snmptrap/zabbix_trap_receiver.pl /usr/local/bin/zabbix_trap_receiver.pl 
97c97,103
< 		printf OUTPUT_FILE "  %-30s type=%-2d value=%s\n", $x->[0], $x->[2], $x->[1];
---
> 		my $value = $x->[1];
> 		if( $value =~ s/^Hex-STRING: //) {
> 			$value =~ s/(\n|\r|\r\n)//g;
> 			$value =~ s/(..) /chr(hex($1))/ge;
> 			$value = "Hex-STRING: " . $value;
> 		}
> 		printf OUTPUT_FILE "  %-30s type=%-2d value=%s\n", $x->[0], $x->[2], $value;
```
変更箇所は、TRAP情報の型が"Hex-STRING"の時、文字列16進数をバイナリに置換するだけ。

# 最後に

- SNMPTTを利用している場合の文字化け対応は、[こっち](http://qiita.com/mishikawan/items/13b7d43959e703d04f54)を参照してください。

文字化けとは関係ないですが、
SNMPTRAPの鳴り分け処理する場合は、SNMPTTがとても便利だなと思います。
[Unity](初心者向け)Sceneビューに表示されるカメラアイコンやCanvasを機能を残したまま非表示にする方法

<h1>こんな感じ</h1>
このように、SceneビューではCanvasやカメラアイコンが表示されるのだが、作業を進めていくとだんだん邪魔に思えてくるわけです。

<img width="732" alt="スクリーンショット 2017-07-09 16.12.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/179803/023311ae-c224-5000-5454-67cdaf1ec330.png">


<h1>方法</h1>
上の画像を見てください。「Gizmos」ってところをクリックすると、色々出てきます。
<img width="563" alt="スクリーンショット 2017-07-09 16.13.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/179803/b07cb43d-20fc-31aa-b0c9-e0b279342218.png">

任意のものをここで非表示にできます。
試しにCanvasのチェックボックスをoffにしてみましょう。
<img width="731" alt="スクリーンショット 2017-07-09 16.18.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/179803/640e7b4b-e608-1f8d-6ee5-8091b6a5070f.png">

あら不思議、消えました。

このように、カメラやAudioのアイコンも機能を残したまま非表示にできます。

お疲れま様でした。