OmniAICreator/Qiita-1.07M huggingface dataset:
cronとrsyncでDBdumpファイルを自動バックアップ

DBバックアップをとるためにcronでmysqldumpを回したりしますが、
そもそもサーバーが落ちるとバックアップの甲斐がないわけです。
そこで、別のサーバーに転送しておこうというお話。

◆ **スクリプト**

```
#!/bin/sh

# バックアップファイルを何日分残しておくか
period=7
# バックアップファイルを保存するディレクトリ
dirpath='/home/hoge/backup/'
# バックアップ用別サーバー情報（開発環境）
remotehost='fugafuga'
remotedir='fuga_backup/'
remoteuser='fugauser'
remotepass='fugapass'

# ファイル名を定義(※ファイル名で日付がわかるようにしておきます)
filename=`date +%y%m%d`

# mysqldump実行
mysqldump --opt --password=hogepass hogedb > $dirpath/$filename.sql

# パーミッション変更
chmod 700 $dirpath/$filename.sql

# 古いバックアップファイルを削除
oldfile=`date --date "$period days ago" +%y%m%d`
rm -f $dirpath/$oldfile.sql

# 別サーバーに同期
expect -c "
set timeout 3600
spawn rsync -av -e ssh --delete $dirpath $remoteuser@$remotehost:$remotedir
expect {
        \"Are you sure you want to continue connecting (yes/no)?\" {
                send \"yes\r\"
                expect {
                        -re \".*password:.*\" {
                                send \"$remotepass\r\"
                        }
                }
        }
        -re \".*password:.*\" {
            send \"$remotepass\r\"
        }
}
expect {
  \"denied\" { exit 1 }
  eof { exit 0 }
}
interact
"
```
パスワードをベタで書いているのは微妙ですが…

◆ 参考
[rsyncで自動バックアップ（Linux）](http://aimix.jp/wordpress/linux/546/)
Qiita:Teamを移行するかもしれない件について


# 移行作業のために調べたこと

## APIキー利用の準備

ここからAPIを利用するためのキーを作成します。

```
https://qiita.com/settings/applications
```

## 次に準備したもの

以下のコマンドを使います。

```
brew install jq curl
```

pythonを今後使っていくつもりなので、pythonも最新版にすると良いのですが、本日の記事では割愛します。

## 取得するためにはどうするか

まずはそもそもどうやってデータを取得するか、という点に絞っていくと、以下のようにAPIを叩けば全て取得できるようです。

```
curl -sSH "Authorization: Bearer xxxx" https://yyyy.qiita.com/api/v2/items?per_page=100 | jq -C .
```

この状態ですと、素のmarkdownではなく、html入りのjsonデータが落ちてきますので、そのままでは流用できません。

## 素のmarkdownが欲しい

以下のように取得したjsonからURLの末尾に.mdで加えてアクセスすれば、素のmarkdownがダウンロード可能です。

```
https://yyyy.qiita.com/{username | shared}/{適当な英数字}.md
```

## 画像を取得したい

ファイルの中から特定キーワードで画像を取得するように処理を書いてあげる

```
curl -sSH "Authorization: Bearer xxxx" https://yyyy.qiita.com/files/yyyyy.{png | jpg}
```

## 悩ましいところ

最終的にはgitlabに放り込むことを想定しています。
他に良いプランへ移行できるならそのままポイっと放り投げてうまく変換してくれるならそれも良しかな、というところです。
ただmdのファイル名をtitleにし、画像ファイル名はそのままでfilesディレクトリに保存するのがほとんど修正要らずでいい感じなのですが、ディレクトリをどういう風に分けるのかが難しい…。
月単位でいいのかなぁなどとぼんやり考えてみてます。
全部同じディレクトリに放り込むと現実的じゃないし、画像もごちゃまぜになるので探しにくく、辛いです。

とりあえずCLIで年月に分けるならcreated_atに対して、

```
cut -d"-" -f 1,2
```

ってやればサクッと年と月が取れるんですよね。
ファイル数も人によってはしれたものなので、可搬性が良いように、年月で取るのが良さそうかなぁ…。

ということで、仕様を明らかにしましたので後日、のんびり作ろうかと思います。
Cognos Analytics 上でTM1 Cubeデータを結合する

#概要
Cognos BIでCognos TM1をデータソースに使用した時に、TM1 Cubeを結合しようとして、結合できない仕様という事がわかり、困った方も多いかと思います。
Framework Managerで複数のTM1 Cubeの取り込みまではできるのですが、リレーションの作成ができない仕様なんですよね。

今回は、Cognos Analyticsの新機能である「データ・セット」と「データ・モジュール」の機能を用いて、若干無理やりにTM1 Cube間データの結合を実施してみた投稿です。

#内容
TM1のPlanning Sampleの、plan_BudgetPlanキューブとplan_BudgetPlanLineItemキューブを結合しようと思います。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c7ff09d2-4171-cfbb-7a0b-da9d55cbff98.png)

とりあえずFramework Managerに両キューブを取り込みますが、ここで「関係」を作成しようとしてもできません。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/1d33f956-eea1-0bc5-a7ae-9f00c8b78fad.png)

とりあえずパッケージとして発行して、パッケージのメニューから「データ・セットの作成」を選択します。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/13b7d837-3b79-87cf-c256-1423bfeaaa05.png)

1個目のplan_BudgetPlanキューブの各ディメンションの階層と、2004の数値アイテムを配置し、DS_PlanBPというデータ・セットを作成します。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/1f117d0f-50cf-62f5-be74-ec153c7dd5cb.png)

同様に、2個目のplan_BudgetPlanLineItemからDS_PlanBPLIデータ・セットを作成します。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/91088cd1-2bed-682a-bc4c-a555eb2cfe99.png)

データ・モジュールを新規作成し、先に作成した2個のデータ・セットを配置し、関係を作成します。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c61c9e94-c2e8-aab4-bdac-3ff75f5dd7cb.png)

結合は、以下の通りで、各キューブにユニークなもの以外は結合対象としています。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/a2af2eda-a07d-c765-13ca-52337067b77b.png)

このデータ・モジュールで、レポートを作成したところ、図のように2個のキューブからデータアイテムを取得しているリストが作成できました。
※結合のカーディナリティとか余りちゃんと考えてないので、データが正確かは不明ですが、TM1キューブデータ間の結合自体は可能なことがわかりました。
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/fb22d36d-dfe6-c02a-b0b1-0535aef1a1ca.png)

という感じです。
手順としてはやや大変ですが、Cognos BI時代には100%できなかった事が、この様にできるようになり、Cognos Analyticsにしてちょっとうれしいネタでした。
Javaでスクレイピングをしよう！！


#開発環境
- Spring Tool Suite

#スクレイピングとは
Webサイト上のHTMLから特定の画像やタイトルなどのデータを抜き出す処理を指します！


##スクレイピングに必要なライブラリ
スクレイピングをするには **「jsoup」** というライブラリを使用します！

jsoupとはHTMLを解析するためのライブラリで、解析するための様々なクラスが使えるようになります！


では、pom.xmlに以下の記述をしましょう。


```Java[]{}:
<dependencies>

// 省略

    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
    </dependency>
</dependencies>
```
<br>

##スクレイピングを行う手順
① WebサイトからHTML情報を取得する
② HTML情報から指定のタグ要素の情報を検索する
③ HTML情報からテキスト、属性値を抜き出そう




###① WebサイトからHTML情報を取得する
HTML情報を扱うには **「Documentクラス」** を使用します。
Documenntクラスの変数を作成し、その変数に取得したHTML情報を代入します。以下の記述です！

```Java[]{}:
Document document = Jsoup.connect("url").get();
```

connectメソッドの引数にURLの文字列を指定することで、そのURLのWebサイトのHTMLを取得できます。
その情報をDocumentクラスの変数に代入します。

<br>

###② HTML情報から指定のタグ要素の情報を検索する
取得したタグ情報を取得するには **「selectメソッド」** を使用します。

```Java[1]{2}:
Document document = Jsoup.connect("url").get();
Elements elements = document.select("h3");
```

2行目記述の右辺にselectメソッドを使用していますね。引数に文字列でh3を記述しているので、指定したURLのWebサイトから h3要素の情報 を取得し、Elementsクラスの変数に代入します。
Elementsクラスとは、Elementクラスをリストのような形で保持しているクラスで、Elementクラスは、HTMLの要素を表すクラスです。

<br>

###③ HTML情報からテキスト、属性値を抜き出そう
HTMLのテキストを取得する際には、 **「textメソッド」** を使用し、属性の値を取得したい場合は **「attrメソッド」** を使用します。

```Java[]{}:
Document document = Jsoup.connect("url").get();
Elements elements = document.select("h3");

for (Element element : elements) {
    System.out.println(element.text());
}
```

selectメソッドで取得した"h3"要素の情報からテキストを取り出し、コンソールに表示させます！
<br>

```Java[]{}:
Document document = Jsoup.connect("url").get();
Elements elements = document.select("h3 a");

for (Element element : elements) {
    System.out.println(element.attr("href"));
}
```

selectメソッドで取得した"h3 a"要素の情報からhref属性を取り出し、コンソールに表示させます！
[TouchDesigner] RGB(またはHSV)をチャンネルごとに抜き出す

![td_final.png](https://qiita-image-store.s3.amazonaws.com/0/127402/c5d52d6d-f823-f672-4cf0-6e3386f4af5a.png)
# はじめに
![bandicam-2017-09-11-15-28-47-9221.gif](https://qiita-image-store.s3.amazonaws.com/0/127402/5af58095-4781-ba0d-19f2-afc3f7479abd.gif)

TouchDesignerでは、RGBAチャンネルをそれぞれ抜き出すノードがありません(見つけきれてないだけかも...)。
ので、GLSLで対処してみます。

# サンプル
サンプルはこちら([GitHub](https://github.com/kodai100/TouchDesignerUtilities/blob/master/ChannelSeparator.toe))に置いています。

# 解説
## 色空間の変換
RGB値を抜き取りたい場合はこの工程を無視して頂いて結構です。
![2017-09-11_170014.png](https://qiita-image-store.s3.amazonaws.com/0/127402/db97bb53-708e-7816-5f4a-893415c0befe.png)
読み込んだファイルをHSV色空間に変換しています。
ややこしいですが、HSV値はそれぞれRGBに格納されます。
そのため、輝度を取り出したい場合はBチャンネルの値を抜き出せばよいことになります。

## チャンネルごとに値を取り出す
![2017-09-11_170755.png](https://qiita-image-store.s3.amazonaws.com/0/127402/21602c43-c97b-9097-6261-0015d265b427.png)
GLSL TOPを用いて、指定したチャンネルのピクセル値を取り出します。
GLSLでは、ベクトル値のアクセスにxyz, rgb, [index]の形でアクセスすることができますから、
今回は[index]の形で取り出しています。

```c:Decomposition.glsl
uniform int channel;

out vec4 fragColor;
void main() {
    vec4 tex = texture(sTD2DInputs[0], vUV.st);
    vec4 color = vec4(vec3(tex[channel]), tex.a);    // <- 
    fragColor = color;
}
```

![2017-09-11_165929.png](https://qiita-image-store.s3.amazonaws.com/0/127402/cf0a70f7-3c61-ac24-6856-94949c2fb341.png)
取り出すチャンネルはスライダーで設定できるようにしてみました。
![2017-09-11_170939.png](https://qiita-image-store.s3.amazonaws.com/0/127402/5c58209a-951f-c057-a630-1e61d0394561.png)
スライダーの値は0-1の範囲で動きますので、Math CHOPで3倍にしておき、0-3で動くようにしておきます。

# 結果
![2017-09-11_171313.png](https://qiita-image-store.s3.amazonaws.com/0/127402/5bf114ab-6a94-d565-e4fd-ecb76f79c7c1.png)
色相

![2017-09-11_171330.png](https://qiita-image-store.s3.amazonaws.com/0/127402/1e9d65aa-d4b5-bfff-6d42-b25d1c0886fe.png)
彩度

![2017-09-11_171354.png](https://qiita-image-store.s3.amazonaws.com/0/127402/33616d50-71e5-2d5a-8a6d-21afd1959e55.png)
明度

と、それぞれのRGBチャンネルを抜き出すことができました。
[Survey] Kaggle - Quora 4位解法まとめ

Kaggle - Quora Question Pairs[^1]の4位解法[^2]の調査記事です．

Title: [4位] Overview of 4th-Place Solution
Author: HouJP
Discussion URL: https://www.kaggle.com/c/quora-question-pairs/discussion/34349
Code: https://github.com/HouJP/kaggle-quora-question-pairs



## 流れ

1. [前処理](https://github.com/HouJP/kaggle-quora-question-pairs/blob/master/bin/preprocessor.py)
2. 特徴抽出
3. モデル構築
4. [後処理](https://github.com/HouJP/kaggle-quora-question-pairs/blob/master/bin/postprocessor.py)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/12294d68-87de-7db8-fecf-ec6fff0c3d34.png)
HouJP/kaggle-quora-question-pairs[^4]より引用

## 前処理

- Text-cleaning: 誤字脱字の修正， 記号の処理, 頭字語の復元など
- Word-stemming: SnowballStemmer[^3],など
- Shared-word-removing: 両方に共通して出現する単語の除去など

## 特徴抽出

- 1400以上の特徴量
- 統計: 共通する単語の比率，文章の長さ，単語の数など．
- 自然言語処理: 構文木の解析，ネガティブな単語の数など
- グラフ構造: PageRank, hits, 最短経路, クリークの大きさなど

## モデル構築

- ニューラルネット，XGBoost, LightGBM, LogisticRegression(単一モデルだとLB=0.122〜0.124が最良)
- 140モデルのModel Stacking(LB上で0.007改善)


## 後処理

- 訓練データとテストデータでデータの傾向が異なっていたので，重みを調整する必要があった．
- クリークの大きさでデータを分割して重みを調整(この操作でLB上が0.001改善)

## References

[^1]: Kaggle, [Quora Question Pairs](https://www.kaggle.com/c/quora-question-pairs), 2017.
[^2]: Turkewitz, [Overview of 4th-Place Solution](https://www.kaggle.com/c/quora-question-pairs/discussion/34349), 2017.
[^3]: shibukawa, [Snowball stemming library collection for Python](https://github.com/shibukawa/snowball_py), 2013.
[^4]: HouJP, [kaggle-quora-question-pairs](https://github.com/HouJP/kaggle-quora-question-pairs), 2017.
HHKBでMacをスリープさせるショートカット

###```ESC``` + ```Fn``` + ```alt``` + ```cmd```
　　

```ESC``` + ```Fn``` が電源ボタンのようです
公式サイト[Macintosh Q3より](https://www.pfu.fujitsu.com/hhkeyboard/hhkb_support/faq_bt-us.html)


自分が探した時なかなか見つからなかったのでメモとして。
TypeScriptで不動点コンビネータに型をつける

# 不動点コンビネータ

多くのプログラミング言語では、再帰関数を書くことができます。例えば、 JavaScript では `fact` 関数の定義の中で、自身の名前である `fact` を参照できます：

```js
function fact(n) {
    return n === 0 ? 1 : n * fact(n - 1);
}
console.log(fact(5));
```

一方で、ある種のプログラミング言語（または計算体系）では、関数を定義する際に自身の名前を参照できません。（型無し）ラムダ計算がその代表例です。

しかし、型無しラムダ計算では不動点コンビネータと呼ばれるものを書くことができ、それを使うと再帰関数を書けます。不動点コンビネータの例としては、（名前呼びの体系で使える）Yコンビネータがあります：

```
Y = λf. (λx. f (x x)) (λx. f (x x))

fact = Y (λf. λn. if n == 0 then 1 else n * f (n - 1))
```

このYコンビネータは値呼びの体系では使えないので、値呼びの体系では別の形の不動点コンビネータ[^1]を使います：

```
Z = λf. (λx. f (λy. x x y)) (λx. f (λy. x x y))

fact = Z (λf. λn. if n == 0 then 1 else n * f (n - 1))
```

[^1]: Wikipediaの[不動点コンビネータの記事](https://ja.wikipedia.org/wiki/%E4%B8%8D%E5%8B%95%E7%82%B9%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF#Z.E3.82.B3.E3.83.B3.E3.83.93.E3.83.8D.E3.83.BC.E3.82.BF)ではZコンビネータと呼ばれています。

このZコンビネータをJavaScriptで書くとすれば、次のようになります：

```js
function fix(f) {
    return (x => f(y => x(x)(y)))(x => f(y => x(x)(y))); // 関数定義の中で fix という名前を使っていない！
}

let fact = fix(f => n => n == 0 ? 1 : n * f(n-1)); // 関数定義の中で fact という名前を使っていない！
console.log(fact(5));

let diverge = fix(f => x => f(x)); // 停止しない関数
diverge();
```

# 不動点コンビネータと型

型無しラムダ計算では不動点コンビネータを記述することができましたが、型がつくとそうでもなくなってきます。特に、単純型付きラムダ計算や System F では不動点コンビネータを記述できません。このような体系で再帰関数を書けるようにするには、言語組み込みの不動点コンビネータ、またはそれに相当するもの（let rec など）を用意しなければなりません。

しかし、**再帰型**があると、上記のZコンビネータに適切な型を与える（つまり、不動点コンビネータを体系内で記述する）ことができます。

特に、 TypeScript には再帰型があるので、さっき定義した fix 関数に型をつけることが可能です。

```typescript
function fix<S,T>(f: (_:(_:S) => T) => (_:S) => T) {
    type U = (_:U) => (_:S) => T;
    return ((x:U) => f((y:S) => x(x)(y)))((x:U) => f((y: S) => x(x)(y)));
}

let fact = fix<number,number>((f: (_:number) => number) => (n: number) => n === 0 ? 1 : n * f(n-1));
console.log(fact(5));

let diverge = fix<any,never>((f: (_:any) => never) => (x:any) => f(x));
diverge(0);
```

上の例では、 fix 関数の中で定義している `U` という型が `U = (_: U) => (_: S) => T` を満たす再帰型です。定義の中で `U` 自身を参照しているのがポイントです。（このような型はどの言語でも書けるわけではありません）

なお、 TypeScript では関数の引数の型をある程度省略できるので、次のように書くこともできます：

```typescript
function fix<S,T>(f: (_:(_:S) => T) => (_:S) => T) {
    type U = (_:U) => (_:S) => T;
    return ((x:U) => f(y => x(x)(y)))(x => f(y => x(x)(y)));
}

let fact = fix<number,number>(f => n => n === 0 ? 1 : n * f(n-1));
console.log(fact(5));

let diverge = fix<any,never>(f => x => f(x));
diverge(0);
```

ちなみに、再帰型を使わないやり方として、参照（変更可能な変数）を使ったものが「型システム入門」で紹介されています。

# まとめ

TypeScript には再帰型があるのでヤバい

# 参考文献

「型システム入門 プログラミング言語と型の理論」：

- 第5章「型無しラムダ計算」 5.2「ラムダ計算でのプログラミング」
- 第11章「単純な拡張」 11.11「一般的再帰」
- 第13章「参照」 13.5「安全性」演習13.5.8
- 第20章「再帰型」 20.1「例」
vimで複数行に同じ文字列を書き込む

Ctrl-vでvisualモードに入り、jを連打して、文字列を書き込みたい複数の行の先頭を選択する。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/87725/b299f4ef-8042-6b86-f49d-ed393e821d51.png)

このあとShift-iで書き込みたい文字列(例として"- ")を入力後、escapeキーを押すと、選ばれた行全ての先頭に、入力した文字列が挿入される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/87725/6d05f13b-f887-adf4-fe15-280b53e9aa5c.png)
iOS 11 UITableViewでcontentOffsetを使ったスクロールが上手くいかない


## 問題

いままではこのように固定の高さのCellとrow indexから計算して指定した位置へスクロールしていました。

```swift
let index: Int = 26
let rowHeight: CGFloat = 60
let offset = CGPoint(x: 0, y: rowHeight * CGFloat(index))
tableView.setContentOffset(offset, animated: true)
```

しかし、iOS 11からスクロール先がおかしな位置に移動するようになりました。

## 解決方法

原因はiOS 11で`UITableView`のプロパティ**`estimatedRowHeight`のデフォルト値が`UITableViewAutomaticDimension`となった**影響でした。

そこで、セルの固定高さでスクロールを調整したい場合の解決策は`estimatedRowHeight`を明記する。(`0`を指定すると自動調整を無効という意味になります。)

```swift
tableView.estimatedRowHeight = 60
```

もしくは、`UITableViewDelegate`のメソッドで高さを明記します。

```swift
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60
}
```

以上、`estimatedRowHeight`の指定忘れが原因で起こるiOS 11の問題でした。
s3 syncでリージョンの異なるバケットにデータをコピーする


リージョンが異なるバケットにデータをコピーしようと`s3 sync`したら以下のエラーが出力され、コピーされなかった。

```
A client error (PermanentRedirect) occurred when calling the ListObjects operation: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint: <コピー先バケット>
You can fix this issue by explicitly providing the correct region location using the --region argument, the AWS_DEFAULT_REGION environment variable, or the region variable in the AWS CLI configuration file.  You can get the bucket's location by running "aws s3api get-bucket-location --bucket BUCKET".
Completed 1 part(s) with ... file(s) remaining
Build step 'Execute shell' marked build as failure
Finished: FAILURE
```

ちなみに使用したコマンドは次の通り

```
aws s3 sync s3://${SRC_BUCKET}/assets s3://${DST_BUCKET}/assets --delete 
```

どうやらコピー元とコピー先の両方のリージョンを指定する必要があるらしい。
というわけで次のように`--source_region`にコピー元を指定して`--region`にコピー先のリージョンを指定して実行したところ、うまくコピーできました。

```
aws s3 sync s3://${SRC_BUCKET}/assets s3://${DST_BUCKET}/assets --delete --source-region=${SRC_REGION} --region=${DST_REGION}
```

まぁ例によって[ドキュメント](http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)にはちゃんとかいてあるんですけどね。
prop()

```
prop()

```
下記などのプロパティを操作する。

```
checked
```

```
disabled
```
```
selected
```
```
checked
```
の場合

```
$('input[type="checkbox"]').prop('checked');
```
返り値

チェックあり =>true
チェックなし =>false

checkedが付いていたらtrue、なければfalseが返されます。
UIAlertControllerのcompletionにnilを渡すと起きること

UIAlertControllerを使う時にdismissの部分でハマッたのでメモ

## 概要
アラート表示に使うUIAlertControllerを消去・画面遷移する場合に、completionにnilを渡し直列に画面遷移処理を記述すると、dismissが正常に行われず次の画面に残ってしまい影響が出る時がある。

## 対応方法
アラート消去完了まで待ってあげてから画面遷移を行う

## ポイント
UIAlertController dismissの第二引数はnilを渡すのではなく、completion処理を記述する。

## サンプル （不具合版）

```AlertDisappear_before.m
- (void)shouldTransition
{
    /* dismissの動作が保証されない記述 */
    /* completionの引数がnil指定
    [_alertController dismissViewControllerAnimated:YES completion:nil]; // 第二引数にnilを渡す場合

    
    NextViewController *nextViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"NextViewController"];
    [self.navigationController pushViewController:nextViewController animated:YES];
}

- (IBAction)tappedAutoDisappear:(id)sender
{
    /* アラート表示を表示する */
    _alertController = [UIAlertController alertControllerWithTitle:@"Discription" message:@"Disappear an alert after transition." preferredStyle:UIAlertControllerStyleAlert];
    [self.navigationController presentViewController:_alertController  animated:YES completion:nil];

    /* アラートを消去し画面遷移する */
    [self performSelector:@selector(shouldTransition) withObject:self afterDelay:3.0f];
}

```

## サンプル（対応版）
```AlertDisappear_after.m
- (void)shouldTransition
{
    [_alertController dismissViewControllerAnimated:YES completion: ^{
        // 第二引数にcompletion処理を渡す場合
        NextViewController *nextViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"NextViewController"];
        [self.navigationController pushViewController:nextViewController animated:YES];
    }];
}

- (IBAction)tappedAutoDisappear:(id)sender
{
    /* アラート表示を表示する */
    _alertController = [UIAlertController alertControllerWithTitle:@"Discription" message:@"Disappear an alert after transition." preferredStyle:UIAlertControllerStyleAlert];
    [self.navigationController presentViewController:_alertController  animated:YES completion:nil];

    /* 3秒後にアラートを消去し画面遷移する */
    [self performSelector:@selector(shouldTransition) withObject:self afterDelay:3.0f];
}

```

## 備考
アラート表示途中にアプリをバックグラウンドへ、プッシュ通知から起動したら遷移先でアラートの残骸が出たので対応した。
既存のtfディレクトリをWorkspaces管理に移行する

## TL;DR
Terraform 0.10から、Workspacesという機能が追加されました。
https://www.terraform.io/docs/state/workspaces.html

0.9で追加された State: Environmentsが名称変更されたものです。

1つのディレクトリで、任意の複数の環境(e.g dev, stg, prod)を切り替えられるようにするものです。

下記を適用する下準備として、既存のtfディレクトリをWorkspaces管理に移行する際にはまったことのメモです。
[Terraform Best Practices in 2017](http://qiita.com/shogomuranushi/items/e2f3ff3cfdcacdd17f99#state-environments%E3%81%AE%E6%B4%BB%E7%94%A8%E6%96%B9%E6%B3%95)

## 既存のtfディレクトリをWorkspaces管理に移行する。

### 1. 既存のstateファイルからworkspaceを作る(とincompatible state lineageエラーが出る)
```
terraform workspace new -state=./terraform.tfstate [workspace名]
```

```
$ terraform workspace new -state=terraform.tfstate example
Created and switched to workspace "example"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
incompatible state lineage; given 3d2aa9e3-198b-400c-a1aa-0a8e15ac44b4 but want 768adb25-938d-45cc-9195-fae815470dd3
$
```

詳細は確認していませんが、newした時点で作成されるtfstateファイルにはlineageが発行されているのですが、
-stateで指定した既存のtfstateで上書きする際に、既存のtfstateファイルでまるごと上書きしてしまい、lineageが一致しなくなることが問題のようです。


### 2. stateファイルをs3などのremoteで管理している場合は、stateファイルをremoteとsyncした上で手動マージする

remoteの最新stateファイルをpullし、workspace:example用のtfstateファイルを置き換える

```
terraform state pull > ./terraform.tfstate.d/example/terraform.tfstate
```

"modules"を既存のもので差し替え、pushする

```
terraform state push ./terraform.tfstate.d/example/terraform.tfstate
```

### 3. 既存のtfstateファイルを引き継げているかをplanの結果を見て確認する

```
terraform plan -var-file=./tfvars/example.tfvars -out=path_to_plan.plan
```

問題なく移行できていれば、planの実行結果に新規作成されるリソースは存在しないはず。
PHPで「含む」かどうかを書く場合（文字列、配列）

いざ書こうと思ってついグーグル先生に聞いてしまうので、メモ。

## 文字列
**strpos**

```
if(strpos($str,'hoge') !== false){
  //'hoge'が含まれている場合
}

if(strpos($str,'fuga') === false){
  //'fuga'が含まれていない場合
}
```

出現する位置を返すため、型比較する必要がある（===,!==）

（参考）
http://qiita.com/kazu56/items/2c72d187438de07c2503
http://php.net/manual/ja/function.strpos.php

## 配列
**in_array**

```
if(in_array('hoge',$arr,true)){
  //'hoge'が含まれている場合
}

if (in_array(array('hoge', 'fuga'), $arr,true)) {
  //配列'hoge','fuga'がある場合
}
```

（参考）
http://www.t-net.ne.jp/~cyfis/php/judge/in_array.html
http://php.net/manual/ja/function.in-array.php

【追記】
in_array()は第3引数を指定しないと型比較を行わないので、
その場合、思わぬところでハマる可能性があります。。。
（コメント参照）
DjangoでHeroku（無料枠）のスリープを阻止する

# Herokuのサーバーはスリープします

Herokuの無料枠では30分サーバーにアクセスがないとサーバーがスリープしてしまいます。
これを阻止する方法はいくつかあります。

1. Herokuに課金する
2. アドオンを追加する
3. Google apps scriptなどで定期的にアクセスする。

今回はDjango側でスリープを阻止する方法を紹介します

## 仕組み
今回の方法は、サーバーのスタート時に別スレッドで定期的に自サーバーにアクセスするというものです。

`wsgi.py`に別スレッドで定期処理を実行するようにコードを書きます。[参考](https://www.slideshare.net/tokibito/django-52696489)

## 実装
```wsgi.py
import os
import threading
import requests
import time

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hoge.settings")

application = get_wsgi_application()

def awake():
    while True:
        try:
            print("Start Awaking")
            requests.get("http://hogefuga.herokuapp.com/")
            print("End")
        except:
            print("error")
        time.sleep(300)

t = threading.Thread(target=awake)
t.start()
```

このコードでは300秒(5分)間隔で自サーバーにアクセスしています。
これでサーバーのスリープを阻止できます。
rspec実行時に結果をOSXの通知センターに通知したい


# やりたかった事

* テストが重く、意図した場所だけ実行する事が多いのでrspecをguardからの自動実行ではなく手動実行したい
* テスト実行後、時間がかかることが多いので、終了時に結果を通知センターに通知したい
* JenkinsサーバはLinuxなので自端末のみに影響をとどめたい

# 既に似たような事をやっているケース

* [Guardで実行する場合に通知する方法](http://b0npu.hatenablog.com/entry/2016/04/17/155457) Guardなので今回は対象外で
* [twe4ked/rspec-nc](https://github.com/twe4ked/rspec-nc) 導入して、フォーマットを指定すると通知センターに出してくれます。今回やったことはこのgemのほぼコピーです

# 実際にやったこと

~/.rspec_files/terminal_notifier_formatter.rb にフォーマット用のファイルを用意して、
~/.rspec でrequire とformatを指定することで独自に用意したフォーマットを指定しました。

やってること自体は、ほぼ、[ここのまま](https://github.com/twe4ked/rspec-nc/blob/master/lib/nc.rb)なのですが、既存の出力もする様にするため、Progressを継承してみました。

```ruby:~/.rspec_files/terminal_notifier_formatter.rb
require 'rspec/core/formatters/base_formatter'
require 'terminal-notifier'

class TerminalNotifierFormatter < RSpec::Core::Formatters::ProgressFormatter
  SUCCESS_EMOJI = "\u2705"
  FAILURE_EMOJI = "\u26D4"
  
  RSpec::Core::Formatters.register self, :dump_summary
  
  def dump_summary(notification)
    body = "Finished in #{notification.formatted_duration}\n#{notification.totals_line}"
    title = if notification.failure_count > 0
      "#{FAILURE_EMOJI} #{directory_name}: #{notification.failure_count} failed example#{notification.failure_count == 1 ? nil : 's'}"
    else
      "#{SUCCESS_EMOJI} #{directory_name}: Success"
    end
    notify title, body
  end
  
  private
  
  def directory_name
    File.basename File.expand_path '.'
  end
  
  def notify(title, body)
    TerminalNotifier.notify body, title: title
  end
end
```

```~/.rspec
--require ~/.rspec_files/terminal_notifier_formatter
--format TerminalNotifierFormatter
```

# 結果

rspecを実行して5分後などの忘れたころに通知が来る様になり、テスト終了タイミングを知るためにコンソールを開き続けて置く必要がなくなりました。
また、プロジェクトソースを変更する必要がないので、そのまま横に流用できます。

# 疑問点

* ~/.rspec_files ってどうなん……？（そもそも.rspecで別のファイルを置くこと自体が想定されてないぽいですが）
zshでDocker コンテナに入るのを楽にする TIPS

## やること
今まで以下のようにログインしてましたが、長々しくて面倒なのでzshのaliasで解決しようと思います。

```
$ docker exec -it <コンテナ名> bash
```


## やったこと
### 1. Aliasの設定
~/.zshrc に以下のように書きました。

```
alias docker-login='(){ docker exec -it $1 bash -lc "su - $2" }'
```

### 2. Dockerコンテナに入る

[rootで入る場合]
```
$ docker-login <コンテナ名>
```

[ユーザ指定して入る場合]
```
$ docker-login <コンテナ名> <ユーザ名>
```

楽になりました。
WebEngineViewサンプル

#WebEngineViewのサンプル
##テスト用QML
```qml
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtWebEngine 1.0
import QtMultimedia 5.9

ApplicationWindow {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("WebEngineViewサンプル")
    onHeightChanged: adjustWebViewSize()

    Audio { id: clickSound; source: "Sounds/btn01.mp3" }

    Column {
        id: column
        Row {
            width: root.width

            // URL入力用TextInput定義
            Rectangle {
                width: root.width - buttonGo.width
                height: textUrl.height
                border.width: 1

                TextInput {
                    id: textUrl
                    width: root.contentItem.width - buttonGo.width
                }
            }

            // ブラウズ開始ボタン定義
            Button {
                id: buttonGo
                text: "Go"
                onClicked: { clickSound.play(); webView.url = textUrl.text }
            }
        }

        Row {
            width: root.width

            // 戻るボタン定義
            Button {
                id: buttonBack
                text: "Back"
                onClicked: { clickSound.play(); webView.goBack() }
            }

            // 進むボタン定義
            Button {
                id: buttonForward
                text: "Forward"
                onClicked: { clickSound.play(); webView.goForward() }
            }
        }

        // WebEngineView定義
        WebEngineView {
            id: webView
            width: root.width
            height: root.contentItem.height - buttonGo.height - buttonBack.height
            onCanGoBackChanged: buttonBack.enabled = canGoBack
            onCanGoForwardChanged: buttonForward.enabled = canGoForward
            onLoadingChanged: {
                switch (loadRequest.status) {
                case WebEngineLoadRequest.LoadStartedStatus:    // ページ読み込み開始したのでプログレスバーを表示する
                    loadProgressBar.visible = true
                    adjustWebViewSize()
                    break

                default:                                        // それ以外はプログレスバーを消去する
                    loadProgressBar.visible = false
                    adjustWebViewSize()
                    break
                }
            }
            onLoadProgressChanged: loadProgressBar.value = loadProgress // プログレスバー更新処理
        }

        // ページ読み込み進捗表示用プログレスバー定義
        ProgressBar {
            id: loadProgressBar
            width: root.width
            from: 0
            to: 100
            value: 0
            visible: false
        }
    }

    // WebEngineViewのリサイズ処理
    function adjustWebViewSize() {
        webView.height = loadProgressBar.visible
                ? root.contentItem.height - buttonGo.height - buttonBack.height - loadProgressBar.height
                : root.contentItem.height - buttonGo.height - buttonBack.height
    }
}
```
う〜ん…もうちょっとリサイズ処理なんとかならないかな？^^;
##実行結果
[![SignalTransitionサンプル動画](http://img.youtube.com/vi/6CPg9wj8914/0.jpg)](http://www.youtube.com/watch?v=6CPg9wj8914)
※Linux Mint 18.2 & Qt 5.9.1使用
ど素人がつまづいた、シェルスクリプトの自動起動設定

#ことの発端
上司「ぼく君さぁ・・・EC2のインスタンスを平日の営業時間だけ立ち上がってる状態にしてくれない？」

ぼく「！ｗ」

上司「8:30に自動的に立ち上がって、18:30に自動停止させたらいいから。簡単でしょ？」

ぼく「？ｗｗｗ！？ｗ！？！ｗｗｗｗｗ」

上司「じゃ、まかせたね～」

ぼく「・・・ｗ」
#概要
・EC2インスタンスを8:30に立ち上げ、18:30に停止させる
・インスタンス立ち上げた際にwebアプリケーション立ち上げのシェルスクリプトを実行する

#実装に必要なこと
- Lambdaでインスタンスの自動起動と停止を行うための処理をそれぞれ用意する
 - 丸パクリ⇒　http://dev.classmethod.jp/cloud/aws/lambda_cloudwatch-events_ec2-star-stop-python/

- CloudWatchに8:30と18:30のそれぞれLamda関数を呼び出す処理を用意
 - 参考⇒　http://qiita.com/tiwu_official/items/76b01a9a42070ffb6f68#cloudwatch

- インスタンスの起動とともにアプリケーション起動シェルの自動起動を設定

#ど素人がハマったこと

まず、やることはすごく単調で調べればそれらしい内容はいくらでも出てきたので、AWS上ではそこまで問題らしい問題は起こりませんでした。
（CloudWatchの時間設定方法がUTCなため、平日起動時間をミスって設定してしまい、インスタンスを土曜も立ち上がらせたくらい。）

ではどこでハマったかというと、
>インスタンス立ち上げた際にwebアプリケーション立ち上げのシェルスクリプトを実行する

こいつ。

##失敗1
###[ /etc/rc.localに起動させたいシェルを書き込む ]
「自動起動 シェルスクリプト」
これで検索した時に一番初めにでてきたものがrc.localへの記述だったため、すぐ採用。
####・結果
おっしゃ動いたやんけ！！！はい余裕～

ぼく「上司さん！できましたわ！」
上司「お、いいね！早いしちゃんと起動して・・・ん？シェル実行された時に生成されるディレクトリ諸々の権限違うくない？」
ぼく「えっ、」
⇒やりなおし
####・原因
⇒/etc/rc.localはrootで実行される
***

##失敗2
###[ root権限で実行されるならスクリプト内にsuコマンド付け足してec2-userに変えたろ！！ ]

```sudo -u ec2-user bash << EOF
~~~~~~
EOF
```
####・結果
⇒そもそも/etc/rc.localの記述スクリプトを読んでいない。
####・原因
⇒不明。
***

##失敗3
###[ ユーザーを変更し、起動したいシェルを呼び出すためのスクリプトを作成、/etc/rc.localに記述 ]

####・結果
⇒用意したシェルも/etc/rc.localからは呼び出されず。

####・原因
⇒不明。このあたりから、suコマンドを用いたシェルは/etc/rc.localで使用できないのではないかと思い始める。泣きそう。
***

#解決
上記の失敗1～3までの検証を行っている間に気がつけばAWS上の実装とは別に1人日消費しておりました。
この辺で思うように実装できないことよりも、意味の分からないタスクを寄こした上司を恨むように。

再度「自動起動 シェルスクリプト」で検索。

##方法
###[ crontab内にOSの起動時、自動起動させるためのコマンド@rebootを記述 ]
```@reboot /bin/sh /home/ec2-user/bin/shell.sh```
この一行を追加するだけ！！！だけ！！！！返してぼくの1人日！！！！！！

参考⇒ http://nort-wmli.blogspot.jp/2016/02/cron-osreboot-shellsh.html

#まとめ
インスタンスの起動時、自動起動させたいシェルスクリプトの実行権限はrootで良い？
YES ⇒　/etc/rc.localに実行シェルを
NO　⇒　crontabの@rebootを使用する。
***
実装する時は策を2つ以上用意しとかないとこういうことになるんですね。
どっと疲れた。。。

ちなみに/etc/rc.localにsuを含んだシェルスクリプトを記述して実行されない理由は分かりませんでした。もしかしたら実行権限がないとか、そういった部分なのかも。
S3にAWS:SDKを使わずpresigned_urlで画像をアップロードする。しかもブラウザじゃないJSスクリプトで。

大抵はこういう処理はブラウザで画像をアップするものである。
そうでなくとも、AWS:SDKを使ってやるものである。
しかし、今回の案件ではS3などのキーは手元になく、APIを叩きpresigned_urlを取得し、画像をS3にアップロードをどうしてもしたかった。（画面を作りたくなかった）

## 最終的なコード
```js
  fetch(/* presigned_urlを発行するAPIリクエスト */)
  .then((presigned_url) => {
      const data = fs.readFileSync(path);
      const base64data = new Buffer(data, 'base64');
      return fetch(presigned_url, {
          method: "PUT",
          body: base64data,
          headers: {
              "Content-Encoding": "base64",
              "Content-Type": "image/jpeg",
              "Content-Length": base64data.byteLength
          }
      })
  })
```

### 苦労したところ
最終的なコードにしてみると大したことがないのだが、画像の読み込み方とリクエストに突っ込み、S３に納得してもらえるヘッダーの形になるまで非常に苦労した。
  
#### fs.createReadStreamで実装しようとすると
「Transfer-Encoding: chunk」に対応してないと言われて怒られる。
S3が対応していないようだ。
**new Buffer**をそのままの形で送ろうとしても同じように駄目。

### Content-Lengthをきちんと付け、Chunk形式じゃないよとすることでなんとかアップロードに成功しました。
とりあえず最低限上記のヘッダーつけたらいけた。
UnityでGear VRのビルドができなくなった時の対処法

UnityでGear VR用apkのビルドができなくなっていた。Unable to merge android manifest Errorとかいうエラーが出る。Build SystemをInternalからGradleに変えてみたりもしたけど、エラーメッセージがちょっと変わるだけで状況は変わらず。

どうやらGear VR用のプラグイン(OVRPlugin)の中で定義されているAndroidManifest.xmlとUnityが生成するAndroidManifest.xmlの値が競合しているようです。具体的には、Gear VR用プラグインでは`<application android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">`を指定している一方でUnityは`<application android:theme="@style/UnityThemeSelector">`を指定しています。そこで、Unity側の設定で強制的に`android:theme`の値を上書きするようにしてみたら症状が改善してビルドできるようになりました。

修正した箇所は一行のみで、Unityのインストールディレクトリ以下にある*Editor/Data/PlaybackEngines/AndroidPlayer/Apk/AndroidManifest.xml*のファイルの`<application>`要素に`tools:replace="theme"`という属性を追加しました。

```xml:UnityInstalledDirectory/Editor/Data/PlaybackEngines/AndroidPlayer/Apk/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="1.0">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>

    <application
        tools:replace="theme"
        android:theme="@style/UnityThemeSelector"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>
```

Windowsの場合、Unityのインストールディレクトリはデフォルトで*C:\Program Files\Unity*です。この中のファイルには管理者権限がないと書き込みできませんので注意してください。
S2Dを構成してみた。

##S2Dの構築はここを参考にしました。
https://docs.microsoft.com/ja-jp/windows-server/storage/storage-spaces/hyper-converged-solution-using-storage-spaces-direct
https://mhiroblog.wordpress.com/2016/12/29/s2d-storage-space-direct-%E3%81%AE%E6%A7%8B%E6%88%90/
http://tricra.doorblog.jp/archives/70251641.html

##クラスタ構成後のクラウド監視はここを参考にしました。
http://tricra.doorblog.jp/archives/70115019.html

##構成
- ディスク構成
SanDisk SDSSDA240G　4本
キャッシュなし

オールフラッシュの最小構成ですね。

- ネットワーク
QLogic FastLinQ QL45212H 25GbE Adapter　2ポート

`Get-SmbClientNetworkInterface
Get-SmbServerNetworkInterface`
どっちもRDMA CapableはTrueです。


"C:\ClusterStorage\Volume1"のフォルダに対してまずは手軽なCrystalDiskMark5.2.2をとってみました。

- サイズ8GB、キュー32、スレッド1 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/dbedc883-3515-0584-761b-133e391a5a39.png)

- サイズ8GB、キュー32、スレッド4
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/869cb586-04fb-44b6-eee9-b33e2b834610.png)

- サイズ8GB、キュー32、スレッド16
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/ef0b9297-cd4f-a680-a8e7-8bc3d04239cb.png)
iopsにするとリード8万とライト5千くらいです。

スレッド数を上下させるとシーケンシャルリードとランダムリードだけトレードオフでした。
ランダムライトがSSDに4並行でアクセスできるのに想像以上に遅いのが気になりました。
それ以外の数字はなかなか優秀だと思います。

パフォーマンスモニターでRDMAを確認してみましょう。
CPUはほとんど使われていないこと、2ポートできれいに負荷分散されていることが確認できますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/15b4d445-9756-6b06-10ed-32cb49ade0de.png)

##おまけ
###ここを参考にCSVキャッシュを有効にするとどうなるでしょうか。
https://blogs.msdn.microsoft.com/clustering/2013/07/19/how-to-enable-csv-cache/

`(Get-Cluster). BlockCacheSize = 8192
Get-ClusterSharedVolume | Set-ClusterParameter enableblockcache 1
Get-ClusterSharedVolume|Stop-ClusterResource|Start-ClusterResource`
今回はテストサイズが8GBなのでキャッシュサイズも8GBにしました。
結果、こうなりました。スレッド16です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/87c7daf1-c25d-56e1-872b-21f59193ef80.png)

メモリから繰り返し読みだしているからシーケンシャルリードが劇的に速くなる！15GB/sですよ。
読み出し中心の配信系ファイルサーバーやBIやバッチ処理なら使ってもよさそうです。
けど仮想化でより重要なランダムI/Oにはほとんど影響がありませんでした。
参考までに。

次回はいよいよSANsymphonyと同一ハードウェアで直接対決させてみます。勝てるといいなあ。

その次はHCIでより重要になる、仮想マシン上からベンチマークをかけつつ、仮想マシン数の変化させた時のクラスター全体（2台しかないけど）のトータル性能の推移を見てみます。
仮想ディスクは分けたほうがいいのか単一の方がいいのか、ホスト2台に同時に書き込んでも性能は維持できるのか。興味は尽きません。
Cognos Analytics 11.0.7 でログが色々と変わった話

#概要
Cognos BI～Cognos Analytics 11.0.6まで、Cognosで何かあったら「cogserver.log」を見る、というのが万人の共通理解だったと思いますが、Cognos Analytics 11.0.7で突如として「cogserver.log」というものは存在しなくなりました。

まあ、それに変わる「cogaudit.log」はあるのですが。

というあたりの、Cognos Analytics 11.0.7でのログ出力の話をまとめました。

#内容
こちらは手持ちのCognos Analytics 11.0.7環境で、セットアップ以降12日間経過後のlogsフォルダです。
cogserver.logじゃなくて、cognosserver.logとか、それが毎日.gzされているファイルとか、気がつかれると思います。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/1fcd53e0-0f7c-fc3b-e3f9-13c70868cc0a.png)

とりあえず「cogserver.log」が「cogaudit.log」になった、という話ですが、Cognos Configurationにもこの通りcogaudit.logで、デフォルト指定されています。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/3e734e12-7391-03e0-237c-10ba49f46ca8.png)

cogaudit.logの中身です。
cogserver.logそのもので、基本的にこれまで通り、このファイルを見れば問題ありません。
また、監査に関する情報も全てcogaudit.logには出力されるそうです。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/09bf054b-8678-6132-6a25-bf5da1e5cbf3.png)

では、cognosserver.logの出力です。
DispatcherのJVMの稼動状態を出力するログとの事です。
また、後述する「診断ログ記録」を有効化すると、その内容もこのログに出力されます。

こちらはスクロール・バーを左端においている状態です。
ERROR という、メッセージタイプを表示する列が、2列目に組み込まれていますので、これまでcogserver.logで、ログファイルメッセージ監視は難しかったですが、このファイルであれば容易に監視できると思います。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/ef62c1cc-ad02-c972-7ce8-9c7067f6d5c2.png)

スクロールを右に動かした状態です。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/d9e63a9a-700b-6648-f0fe-e9e4c92a947d.png)

「診断ログ記録」に関しては、「管理」メニューの「構成」から指定ができます。
出力内容を指定したい場合は、「診断ログ記録」を選択します。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/01532665-0f07-2815-e124-078454f39e17.png)

組み込みトピックタブで、Cognos組み込みのログ出力内容が選択できます。
「トピックのダウンロード」という機能で、ログ出力指定内容がjson形式でダウンロードできます。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/85341f28-0143-862f-d89e-15ff6d189ba7.png)

試しに「AAA」の内容をダウンロードしたものです。
![010.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/f942f5a4-8410-4432-ef83-63f31eb3ea4d.png)

このjsonファイルをカスタマイズし、カスタム・トピックのタブでアップロードすると、新規にトピックを追加する事ができます。
![011.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/7857ab0e-cc6a-bd3c-1999-bfdd56599295.png)

また、「構成」から「システム」を選択し「診断ログ記録」タブで、ファイルのサイズやバックアップ数を指定する事もできます。
![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/8f44ecc0-800f-d707-246b-b2c2e6f2d394.png)

その他のlogsフォルダ上のログファイルは、以下のように説明されています。
**cbs_*.log – no change**
Bootstrap files, tells you about startup, running and shutdown state of the application

**p2pd_messages.log – no change**
information about the dispatcher JVM regarding startup, run and shut down state

**dq_messages.log - ??**
information about Dynamic Query JVM regarding startup, run and shut down state

以上です。
とりあえず、11.0.7で大きく変わったという事を認識頂ければ、何も知らずに11.0.6→11.0.7にバージョンアップして、運用が崩壊するという事は避けられると思いますので、ご認識頂ければと思います。

#参考資料
**How to use Logging in #Cognos Analytics 11.0.7**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/how-to-use-logging-in-cognos-analytics-11-0-7/
CUDA 7.5 の nvcc にはコンパイラのバグがある

CUDA のプログラムを書いていたら, Ubuntu 16.04 apt で入る CUDA 7.5 の nvcc で以下のような LLVM レイヤーでのコンパイラ側のエラーに遭遇しました.

```
Both operands to a binary operator are not of the same type!
%15 = fmul float %12, %struct.float2 undef, !dbg !327
```

そこそこ複雑なカーネルコードなので, どこが原因なのかこのメッセージだけでは不明です.

プログラムの書き方で治すのは諦めて CUDA 8.0 にしたところ, エラーが出なくなりましたので, そこそこ複雑なカーネルを記述する場合, 8.0 以降利用を推奨します.

# まとめ

* CUDA みたいな, 特定の GPU で動かすにはコンパイラの選択肢が限られるような条件では, コンパイラにバグがあると詰んでしまうのでつらい.
Macで .pem や .ppk の変換方法

# Macで .pem を .ppk に変換する方法

## 内容
- Macで .pem や .ppk の変換方法を記載しています

## 詳細

### PuTTY インストール
#### Homebrewでインストール
```
$ brew install putty
```

### 鍵の変換

#### .pem から .ppk への変換
```
$ puttygen test.pem -O private -o test.ppk
```

#### .ppk から .pem への変換
```
$ puttygen test.ppk -O private-openssh -o test.pem
```
よく使うETL系シェルコマンドメモ

ETLの簡単なデータクレンジングなどはシェルで結構いける。
よく使うけど油断すると忘れるコマンドをメモ


#[1] 基本系

##YYYYMMDD形式で翌日(前日）
```sh
date +'%Y%m%d' -d "${date} 1 days (ago)"
```

##ファイル名取得

```sh
filename=${filepath##*/}
```

例）/home/user/file.txt　⇒　file.txt

##ファイル格納ディレクトリパス取得
```sh
directorypath=${filepath%/*}
```
例）/home/user/file.txt　⇒　/home/user

##変数の指定文字抽出
```sh
${var:オフセット:長さ}
```
例 ${file:0:4}

#[2]ETLシェル芸の種

##文字コードおよび改行コードをLinux系（utf-8 + LF）に変換
```sh 
前処理 | xargs nkf --overwrite -Luw 
```

##文字置換
```sh 
cat ファイル | sed -e 's/置換前文字/置換後文字/g' 
```


##csvの各行の2カラム目と4カラム目のみを抽出
```sh 
cat ファイル.csv | cut -d ',' -f2,4 
```

##csvの2カラム目の先頭8文字をカットし、その他はそのまま出力
```sh 
cat ファイル.csv | awk -F',' -v OFS=, '{$2=substr($2,1,8); print}' 
```

##gzファイルの元ファイルを残したまま処理
```sh 
gunzip -c ファイル.csv | 処理 | gzip > 別ファイル 
```

##先頭3行のみ
```sh 
cat ファイル.csv  | head -n 3 
```
or

```sh 
cat ファイル.csv  | sed -n '1,3p' 
```

##最後の３行のみ
```sh 
cat ファイル.csv  | tail -n 3 
```

##header行スキップ
```sh 
cat ファイル.csv   | tail -n +2 
```

##奇数行
```sh 
cat ファイル.csv  | sed -n '1~2p' 
```

##特定カラム抽出
``` sh
cat ファイル.csv | cut -d ',' -f1,4 
# cut
# -d ' ' : delimiter
# -f[num] : 対象カラムnum (複数の場合は , 区切り) 
```

or

```sh
cat ファイル.csv  | awk -F',' -v OFS=, '{print $1,$4}' 
# awk
# -F' ' : delimiter (input)
# -v : 変数オプション ※-v OFS=でセット
# OFS= : delimiter (output) : Output File Separator
```

##ソート
```sh
cat ファイル.csv | sort -r -n -k 8,8 -k 5,5 -t ',' 
# sort
# -n ：数字
# -k　：カラム指定。開始カラム,終了カラムで指定。
# -t　：区切り文字指定
# -r ：　降順
# 複数カラムの場合は、-k [num] -k [num] で列挙。左から優先。
```
##特定カラムのdistinct
```sh
cat ファイル.csv  | cut -d ',' -f2 | sort -u 
```
##特定カラムをhash化
```sh
cat ファイル.csv  | awk -F',' '{print $3}' | md5sum | awk '{print $1}'
```

##パイプで渡す際に受け取る変数の位置指定

```sh
cat ファイル | xargs -I{} python xxx.py {} arg2 | ・・・ 
```
-Iで指定した任意文字（この場合は{}）で、位置を指定できる。
たとえば引数が２つ必要なxxx.pyに、第一引数としてパイプの入力を渡したい時、上記のようにすればよい。

##特定文字列(正規表現)を含む項目を抽出

```sh
cat xxx | grep -o yyy[a-zA-Z0-9_=]*
```
前方一致で yyy の例

##tar

圧縮：　`tar cfvz　[アーカイブ名].tar.gz [ディレクトリ]`
解凍：　`tar xfvz [アーカイブ名].tar.gz`



#[3]処理制御

##ファイルを1行ずつ読み込んで処理（その１）
```sh
cat ファイル | while read line
do
　処理
done
```

##ファイルを1行ずつ読み込んで処理（その２）
※処理内容が複雑になると、その１のcatのパイプではただしく全処理ループできない場合がある。その際はfor分で。

```sh
#リストファイル読み込み
. ./list.txt

#１行ずつ処理
for line in "${LIST[@]}"
do
　処理
done
```

この時の list.txt

```sh

LIST=(
xxxxx
yyyyy
zzzzz
)
```

##tar.gzファイルのgzファイルを１つずつ処理して１つのgzファイルにまとめる
```sh
for gz in ${tar tf ファイル}
do
　tar xOf ファイル $gz | gunzip | 処理
done | gzip > 出力ファイル
```

##桁数を揃えて連番

```
for i in `seq -f %02g 1 10`
do
　echo $i
done
```
01　02　・・・　10　となる

%03g にすれば
001　002　・・・　003 となる

#[4]エラー処理

##対象行の処理がエラー時にステータスコード1で終了
```sh 
処理 || { exit 1;} 
```


##パイプ処理（途中も含む）がエラー時にステータスコード1で終了
```sh
for i in "${PIPESTATUS[@]}"
do
  if [ ${i} != 0 ]; then
     exit 1;
  fi
done
```


#[5]運用系

##ディスク容量確認
```sh
df -h
du -sh [パス]
```

##起動しているpythonプロセスの確認
```sh 
ps aux | grep python 
```
Linker command failed with exit code 1でハマりまくったお話

#Linker command failed with exit code 1

現在C++をベースにした ` openFrameworks ` というライブラリを用いて開発していますが、たまにこのエラーに遭遇します。
また、このエラー自体は ` swift ` や ` Objective-C ` を使った開発でも見かけたことがありますので、Xcodeのエラーだと思われます（ちなみに筆者のXcodeは ` 8.3.3 ` です）。

このエラーの辛いところ、それは”何がダメなのかよくわからないところ”です。

![スクリーンショット 2017-09-10 15.09.30.png](https://qiita-image-store.s3.amazonaws.com/0/179036/bbc6a34e-3441-8af2-a9ca-624bc0d1c352.png)

というわけで、このエラーが出ると一気にやる気が失せてしまうわけですね。
エラー発生の理由がよくわからないので、何を修正したら良いのかもよくわからない。
どこの何行目がダメ、とか書かれていなくて、すごく困ったものです。

しかし、ようやくこのエラーとの向き合い方がわかった気がするので、今回備忘録として書いておくことにしました。


#発生原因は別のところで見れる
さすがに上のようなメッセージだけでは何を直せばいいの？となり、途方にくれましたので、エラーが出た過程を見れないものかと試してみました。

![スクリーンショット 2017-09-10 15.14.15.png](https://qiita-image-store.s3.amazonaws.com/0/179036/fc70c5f9-bfa8-7dd9-95c3-c5801ce664d8.png)


 ` Linker command ` の部分を右クリックで画像のようなポップアップ画面を出します。
そして、この中の ` Reveal in Log `をクリックすると、下のようにエラー原因を見ることができます。


![スクリーンショット 2017-09-10 15.19.27.png](https://qiita-image-store.s3.amazonaws.com/0/179036/766becda-2f03-cbb5-0ca8-32f20a4d96dd.png)


筆者の場合、上記のようなメッセージと、`duplicate symbol` というメッセージを発見。
このとき、筆者のプログラムではcppファイルで別クラスをincludeし、そのまま変数をcppで定義していました。
これを複数のクラスで行なっていたため、このようなエラーが出たということがわかりました。
なので、これらをhファイルで宣言することでエラーを解消できました。
`duplicate`は訳すと「複写」という意味を持つらしく、定義が重複している時などに現れる模様です。
このように、`Reveral in Log`でエラーの詳細を見れば`Linker command`の原因も特定しやすくなります。

ちなみに、hファイルで定義したメソッドをcppファイルで記述していない時などにも`Linker command`のエラーが出ます。
このとき、ログで表示されたメッセージは`referenced from`でした。

#Linker commandで困ったら Reveal in Log を

まずはエラーの原因を特定するところから！ですね。
これができればエラー解消も楽になるのではないでしょうか。
Git便利コマンドまとめ

## コミットが属するブランチを取得
`git branch --contains <commit>`
`git name-rev <commit>`

## コミットが属するタグを取得
`git tag -l --contains <commit>`
フィルターする場合
`git tag -l --contians <commit> 'v4.0.*'`

## ログをツリー形式で表示
`git log --graph --oneline --decorate=full`
[Tableau] Error(8725,24): element 'tuple' is not allowed for content model '(value)' (id: hogehoge.twb)

```
Error(8725,24): element 'tuple' is not allowed for content model '(value)' (id: hogehoge.twb)
```
とでて、ファイルが開けなくなり・・・前日の仕事がパーになったかと思ったのですが・・・
調べてみると下記のようなIssueが

http://kb.tableau.com/articles/issue/error-element-tuple-is-not-allowed-for-content-model-value-when-opening-a-workbook-in-tableau-desktop

バージョンアップしたらエラーが出なくなり、開くことができました。
Chef v13でtimezone-iiを使う（なるべく使わない方が良い）

前任者から引き継いだ開発環境（Vagrant + Chef）が起動できなかったのでメモ。
今更感がすごい気がしますが。。

## 実施環境

* OS: macOS Sierra (10.12.6)
* Vagrant: 1.9.8
* Virtualbox: 5.1.26 r117224
* Chef Client: 13.3.42
* Ruby: 2.4.1p111
* Box: ubuntu/trusty64

## エラー

```bash
NoMethodError
-------------
undefined method `tz=' for #<Chef::Node...>
```

## 原因

timezone-iiがハッシュでドット記法を使っているため。

## 対応

#### 1. timezone-iiを使わない（推奨）
プロジェクト自体が死んでいるようなので、そもそも使わない方が良い。
PRはたくさん出ているが全くマージされていない（後述の修正を含むPRも[出ている](https://github.com/L2G/timezone-ii/pull/42/files)）。

#### 2. ドット記法を修正する
こんな感じでcookbookを編集する。

```rb:attributes/default.rb
// 修正前
default.tz = value_for_platform_family(
  〜中略〜
)

// 修正後
default['tz'] = value_for_platform_family(
  〜中略〜
)
```

一括置換
Atomとか: ([a-zA-Z])\.([a-zA-Z_]+) を \$1['$2'] 
Vim: %s/\(\a\)\.\([a-zA-Z_]\+\)/\1['\2']/g
Djangoで２枚の画像を合成する

概要：
Djangoでアップロードした画像と固定で決めた画像を合成をする処理。

処理：

```
import json
import numpy as np

import cv2
import os

def upload(request):
    try:
        req_file = request.FILES['image']

        file_path = '/tmp/'

        tmp_dir = file_path
        if not os.path.isdir(tmp_dir):
            os.makedirs(tmp_dir)


        path = os.path.join(tmp_dir, req_file.name)
        destination = open(path, 'wb')

        if req_file.size > １０４８５７６:
            image_data = {
                'status': 400,
                'data': {
                    'message': '容量がオーバしています。',
                }
            }
            return JsonResponse(image_data)

        #アップした画像を書き込む
        for chunk in req_file.chunks():
            destination.write(chunk)

        image = cv2.imread(path)
        width, height = image.shape[:2]


        #上部の画像と合成をする処理
        size = width / 10 if width > height else height / 10
        size = int(size)
        margin = size / 5
        margin = int(margin)
        watermark = cv2.imread("上部の画像のフルパス", cv2.IMREAD_UNCHANGED)
        watermark = cv2.resize(watermark, (size, size))
        watermark_width, watermark_height = watermark.shape[:2]

        # 画像のアルファチャンネルだけ取り出す
        mask_ = watermark[:,:,3]
        # アルファチャンネルの値をBGRに格納したndarrayを作る
        mask = np.ones((watermark_width, watermark_height, 3))
        for i in range(len(mask)):
            for j in range(len(mask[0])):
                mask[i][j] = np.ones(3) * mask_[i][j]
        # 0~1になるように規格化
        mask = mask / 255.0
        # 値をfloatにキャストしておく。
        image = image.astype('float64')
        # アルファチャンネルはもういらないのでそれ以外を取り出す
        watermark = watermark[:,:,:3]
        # 指定の位置に画像を貼り込んで返す
        image[width - watermark_width -margin:width -margin, height - watermark_height -margin:height -margin] *= 1 - mask
        image[width - watermark_width -margin:width -margin, height - watermark_height -margin:height -margin] += mask * watermark


        root, ext = os.path.splitext(req_file.name)
        file_name = "test" + ext

        #合成した画像を書き込む
        cv2.imwrite(tmp_dir + '/' + file_name , image)

        image_data = {
            'status': 200,
            'data': {
                'name': req_file.name,
                'image_url': file_path + "/" + file_name,
                'size': req_file.size
            }
        }
        return JsonResponse(image_data)
    except:
        # 例外が発生したら、404を返す
        traceback.format_exc()
        return Http404("message")

```
Nginx Unit　＋　PHP5.4　構築メモ


環境
--
AWS t2-micro
ap-southeast-1a
unit  0.1-1.el7.ngx
CentOS 7 (x86_64) - with Updates HVM
注意
(Precompiled binaries for Unit are available for CentOS 7.0 and Ubuntu 16.04 LTS.)
php5.4 (default)

※セキュリティグループの設定等割愛



Nginx Unitインストール
--

1.リポジトリの設定

/etc/yum.repos.d/unit.repo を作成

```
[unit]
name=unit repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
```
2.インストール

```
yum install unit
```

3.nginx unit のコンフィグの作成

```
{
        "applications": {
                "php": {
                        "type": "php",
                        "user": "nobody",
                        "workers": 2,
                        "root": "/path/to", #任意のパス設定
                        "index": "index.php"
                },

        },

        "listeners": {
                "*:80": {
                        "application": "php"
                }
        }
}
```


PHP設定
--

phpの設置(実行権限はつける。実行権限がないと500Error）

任意のパスにindex.phpファイルの作成(とりあえずinfo出すだけの処理)

```php
<?php
phpinfo();
?>
```

実行
--
```
service unitd start
service unitd restoreconfig /path/to/configファイル
```


以上でブラウザからアクセス可能

参考
--
http://unit.nginx.org/docs-installation.html#system-requirements