OmniAICreator/Qiita-1.07M huggingface dataset:
絶対パスでモジュールをimportする

jsを書いているとき、importで相対パスを利用していると階層が深くなるにつれて汚くなってしまいます。

```js
import Header from '../../../../components/Header'
```

すごい気になるので、絶対パスで書きたいが、npmモジュールにするのはめんどくさいよとなったので、
その時のTIPSです。

## package.jsonを利用する方法

プロジェクトルートからの絶対パスとしたいときは単純に
package.jsonのnameを指定すれば、そこから絶対パスで利用できます。

```js
// package.json
{
  "name": "utoniq",
  //...
}

// index.js
import Header from 'utoniq/app/components/Header'
```

## babel-module-resolverを利用する方法

私のプロジェクトでは、git submoduleでルートフォルダ直下に
共通コンポーネントの置き場所を作っています。

今後npmモジュールとしてまとめて管理したいので、lernaでinitしてmonorepo構成にしています。

```sh
# ex)
- utoniq-base
    - packages
        - components
        - models

```

この構成の場合、プロジェクトルートの絶対パスを利用しても、あまりきれいにならないので、
[babel-module-resolver](https://github.com/tleunen/babel-plugin-module-resolver)を利用します。

```js
//.babelrc

{
  "presets": ["react-native"],
  "plugins": [
    ["module-resolver", {
      "alias": {
        "@utoniq": "./utoniq-base/packages"
      }
    }]
  ]
}

```

このようにすると、きれいにimportすることができます。

```js

import { Header } from '@utoniq/components'

```

相対パス嫌だなあと思ったらぜひ利用してみてください！

## PS. パスが上手く解決できない

```react-native run-ios```で実行してもパスが上手く解決できないとき、
```react-native start --reset-cache```などを実行すると参照をうまく解決できます。

## PS.2 コードの補完を有効にする
webstormなど、intelliJでは上記の方法での補完は現在サポートされていないようです。
Visual Studio Codeではjsconfigを利用すれば解決できます。

```js
//jsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@utoniq/*": ["./utoniq-base/packages/*"]
    }
  }
}

```
Firefoxアドオンを自分で公開（self hosted）する方法

＜2018年一人なんでもアドベントカレンダー1日目＞
#はじめに
Firefoxの拡張機能を公開したい場合、ストアに申請して公開するのが通常の方法ですが、公開条件を満たす必要があります。
例えば、社内用アプリケーションを使って社員のみが使うような拡張機能の場合、用途と利用者が限定すぎるためにリジェクトされたりします。
そのときに「自分で公開（self hosted）」という方法があります。

#updates.jsonを用意
まずはアップデート情報を記述する`updates.json`を用意します。
あとで説明しますが、拡張機能の`manifest.json`内にこの`updates.json`ファイルのURLを記述することで、拡張機能は更新の有無を知ることができるようになります。

```json:updates.json
{
  "addons": {
    "<拡張機能のUUID>": {
      "updates": [
        {
          "version": "1.0.0.0",
          "update_link": "https://server.com/myextension.xpi"
        },
        {
          "version": "1.0.1.0",
          "update_link": "https://server.com/myextension.xpi"
        }
      ]
    }
  }
}
```

`version`に拡張機能のバージョン番号を、`update_link`にあとで置くことになるxpiファイルのURLを指定しておきます。
ここでは仮に`https://server.com/myextension.xpi`に置いたとします。

#manifest.jsonをサーバーに置く
ブラウザからhttpsでアクセスできればどこでも良いです。
ここでは仮に`https://server.com/updates.json`に置いたとしましょう。

#manifest.jsonにupdates.jsonのURLを追記


```json:manifest.json
抜粋
　"applications": {
    "gecko": {
      "id": "<拡張機能のUUID>",
      "update_url":"https://server.com/updates.json",
      "strict_min_version": "42.0"
    }
  },
```

`applications`プロパティの中に`update_url`プロパティを追加し、先程のupdates.jsonファイルのURLを`https://`から記述します。

#開発者センターで拡張機能に署名
公開するには拡張機能に署名を施す必要があります。
開発者センターにログインし、「新しいアドオンを登録」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/92ef48a5-d073-a86e-4dd3-1e33209672c0.png" title="" alt="image.png" width="60%" height="" >

配布手段に「自分自身で。」を選択して「続ける」をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/e9befe66-b45c-f56e-17d8-b9091c46305b.png" title="" alt="image.png" width="60%" height="" >

拡張機能の.xpiファイルをアップロードして「アドオンを署名」をクリックします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/8e61307b-31e5-62ce-2927-786ce23ee2c8.png" title="" alt="image.png" width="60%" height="" >


ここは「いいえ」を選択して「続ける」をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245438/358953d1-a6f7-7137-716e-cdc27c43f62f.png)

これで署名が完了しました。
ダウンロードボタンを押してxpiファイルをダウンロードします。

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/8fc0d233-6b53-52f0-0ea1-3a472011a874.png" title="" alt="lkasdfjalskdfja.png" width="60%" height="" >


#xpiファイルをサーバーに置く

それを`updates.json`に記述したxpiファイルのURLと同じ場所に置きます。
ここでは`https://server.com/myextension.xpi`ですね。

これで公開されました。

#初回インストール
xpiファイルのURLにアクセスすればインストールされます。


#拡張機能の更新
拡張機能を更新するときは、プログラム的な変更を行った後に以下の作業を行います。

1. manifest.jsonのバージョンを変更
2. updates.jsonに新しいバージョンの情報を追加する
3. 開発者センターで拡張機能に署名
4. xpiファイルとupdates.jsonをサーバーに置く

2のバージョン情報の追加は以下のようにします。
例えば新しいバージョン`1.0.1.1`を追加します。

```json:updates.json
{
  "addons": {
    "<拡張機能のUUID>": {
      "updates": [
        {
          "version": "1.0.0.0",
          "update_link": "https://server.com/myextension.xpi"
        },
        {
          "version": "1.0.1.0",
          "update_link": "https://server.com/myextension.xpi"
        },
        {
          "version": "1.0.1.1",
          "update_link": "https://server.com/myextension.xpi"
        }
      ]
    }
  }
}
```
CocoaTouchFramework上でImageLiteralを使用する方法

SwiftでCocoaTouchFrameworkを開発していて、特に不便だなと思うのは、 ImageLiteralが使用出来ないということです。

これは、ImageLiteralが、mainのBudleからリソース取得しようとするため、使用すると、mainのBundleで画像が無いとクラッシュしてしまうためです。

しかし、Xcodeの機能上、Frameworkのプロジェクト上でもImageLiteralは使えますし、コンパイルも通るので、使えないのはなんとももどかしいところです。

なので、今回は、そこをなんとかハックして、CocoaTouchFramework上でImageLiteralを使用する方法を見つけたので、紹介します。

#_ExpressibleByImageLiteral
**_ExpressibleByImageLiteral**というProtocolを利用すれば、Framework上でImageLiteralを使用することができます。

ただし、このProtocolはXcodeの予測変換で出てこないので、実際に打ち込む必要があるので気をつけましょう。

とりあえず簡単に実装してみると以下のようになります。

```swift
// _ExpressibleByImageLiteralは予測変換で出てこないImageLiteralのProtocol
struct FrameworkImageLiteral: _ExpressibleByImageLiteral {
    
    let image: UIImage
    
    // pathにはImageLiteralで指定したImageの名前が入ってくる
    init(imageLiteralResourceName path: String) {
        // 通常のImageLiteralの動作と同じように初期化できなかったらアプリを落とすために!にする
        self.image = UIImage(named: path, in: Bundle.current, compatibleWith: nil)!
    }
}
```

**Bundle.current**に関しては、以前に以下の記事を書いたので、それを参考にしてください。

**[SwiftのフレームワークでBundleを取得する方法](https://qiita.com/PKPK-Carnage/items/bb2c6d07bee702ca396c)**

##実際に使ってみるとこんな感じ
```swift
let image = (#imageLiteral(resourceName: "image_name") as FrameworkImageLiteral).image
```
これでFramework上のBundleからImageLiteralを使用して画像を取得できます。

###なんかイケてなくね？
```swift
(#imageLiteral(resourceName: "image_name") as FrameworkImageLiteral) 
```
しかし、キャストするのが少し鬱陶しいので、もう少しいい感じにする方法を考えてみました。

###いい感じにしてみた。
まずは最初の_ExpressibleByImageLiteralを実装した構造体でUIImageを生成せずに、Pathだけ保持するように変更します。

```swift
struct FrameworkImageLiteral: _ExpressibleByImageLiteral {
    
    let path: String
    
    init(imageLiteralResourceName path: String) {
        // ここでImageを生成せずにpathだけ保持しておく
        self.path = path
    }
}
```

次にUIImageのextensionで、Frameworkimageliteralを引数にして、先ほどFrameworkImageLiteralで行なっていたUIImageの初期化をこちらで行います。

```swift
extension UIImage {
    
    convenience init!(literal: FrameworkImageLiteral) {
        self.init(named: literal.path, in: Bundle.current, compatibleWith: nil)!
    }
}
```

それで実際に使用するとこんな感じになります。

```swift
let image = UIImage(literal: #imageLiteral(resourceName: "image_name"))
```

変にキャストが挟まらないので、いい感じになりました。
MCプロトコルのチートシート

# アドベントカレンダー
夏休みの宿題を直前にやるタイプとバレてしまいました。。

# 送信と受信について
過去の記事でも書きましたが、TCPを使ったソケット通信です。
設定その他は、<a href="https://qiita.com/Tatsuya-8888/items/28cc12dd637c0866fd1c">こちらの記事</a>を参照下さい。

ここでは、送信・受信したいコマンド例文を上げていきます。
また、フォーマットは3Eフレームとします。

# メモリ-レジスタの種類
メモリやレジスタ（変数）の事をPLCではデバイスと言っています
PLCをプログラムするときのデバイスを一通り説明します。

以下()カッコ内はデバイスの説明
[]カッコ内はコマンドのコード値です。

- Xレジスタ (PLCへの入力端子) [X*]
- Yレジスタ (PLCからの出力端子) [Y*]
- 内部リレー (PLCでビット値として使用できる) [M*]
- ラッチリレー (停電時にも状態保持されるビット) [L*]
- アナンシェータ (警報用特殊リレー) [F*]
- エッジリレー (入力の立ち上がり時のみON、その後自動OFF) [V*]
- リンクリレー (GOTなどの外部デバイスと相互同期している) [B*]
- データレジスタ (16bit分のデータ保存レジスタ) [D*]
- リンクレジスタ (リレーと同じく外部デバイス同期 16bit) [W*]
- タイマー (左から順に入力-出力-現在値) [TS][TC][TN]
- 積算タイマー (左から順に入力-出力-現在値) [SS][SC][SN]
- カウンタ (左から順に入力-出力-現在値) [CS][CC][CN]
- インデックスレジスタ (数値オフセット用の特殊レジスタ) [Z*]
- ファイルレジスタ (データ保存用の記憶領域) [ZR*][R*]

PLCをいじっている人なら、わかるかもしれませんが、
特殊レジスタ以外は変更・取得することが出来ます。
この為、制御中のPLCにも介入して実行できる為、
セキュリティには十分気をつける必要があります。

### PLCのデータ変更タイミング
良く知られた話ですが、PLCは計算の都度レジスタ値を変更しません。
プログラマの慣習としては首をかしげますが、
1行毎に計算結果を保留とし、最後に一斉に反映・変更が行われます。
以下イメージ。(左：一般的なプログラム　右：PLC)
![scan2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178507/2ac17d53-fc69-fe06-4e22-57f8a50f98a8.png)

### PLCとの通信タイミング
1スキャンが完了し、データ更新が完了した後のタイミングで行われます。

※コマンドについてはすべてスペースなしです。
　ここでは見やすくスペースを入れることとします。

### ヘッダフレームの指定
##### 4Eフレームの場合
`` 5400 1234 0000 ``
5400 : 4Eフレーム送信であることを定義
1234 : 任意シリアル番号 PLC返答分に盛り込まれて、どのPLCかわかります。
0000 : 空き 0固定

##### 3Eフレームの場合
`` 5000 ``
5000 : 3Eフレームを定義

### アクセス範囲指定
##### 4Eと3Eフレームの場合
`` 00 FF 03FF 00 ``
00 : ネットワーク番号
FF : PC番号
03FF : 要求先 I/O番号
00 : 要求先ユニット番号

PLCにEtherポートが1つの場合、上記にてOK
複数ポートにて他のPLCと繋がっている場合、
PLCの設定と同じく指定する。

### 送信データ長
このコマンド以降のデータ長さ(文字数)を16進で伝える

`` 5000 00FF 03FF 00 0018 0020 1401 0000 D*00 0000 0001 ``
上記なら 
**0020 0401 0000 D*00 0000 0001**
24文字 = 0018


### 監視タイマー
命令文実行完了までのウォッチドッグ。
250msec =0.25sec単位で指定
16進数

> 0020 = 0.25 x 32 = 8sec

### コマンド
ここの数値で書き込みか、読み込みか、連続か個別かを指定します。
前半が読み書きコマンド、
後半がサブコマンド

0401 0000 : ワード単位 16bit 一括読み出し(連続範囲指定)
0401 0001 : ビット単位 一括読み出し(連続範囲指定)

1401 0000 : ワード単位 16bit 一括書き込み(連続範囲指定)
1401 0001 : ビット単位 一括書き込み(連続範囲指定)

0403 0000 : ワード単位 読み出し ランダムアドレス指定
0403 0002 : ダブルワード単位 読み出し ランダムアドレス指定

0406 0000 : ブロック単位の読み出し ランダムアドレス指定
1406 0000 : ブロック単位の書き込み ランダムアドレス指定

ここからはコマンドに応じたコードになる。
例えば、
0401 0000 D*00 0001 0001 = D001から1ワード分を読み出し
1401 0000 ZR00 0001 0001 00c3 = ZR01に1ワード"00c3"を書き込み

0403 0000 0002 0000 D*00 0050 D*00 0076 = ランダムワード読み出し D050とD076 ダブルワードなし

### 受信データ

一例

`` D000 00 FF 03FF 00 000C 0000 1234 5678 ``

D000 : 固定文
00 : ネットワーク番号
FF : PC番号
03FF : 要求先ユニットI/O番号
00 : 要求先ユニット 局番
000c : 以降のデータ長 "0000 1234 5678" = 12
0000 : 終了コード エラーの場合は C051となる
1234 5678 : 2ワード分のデータ 
　※1ワードかもしれないし、1ダブルワードかもしれない
　　要求した本人だけがわかる。

# 最後に
ざっくりとした説明になってしまったが、
個人的には少量なら関数を作成し、
1ワードずつ読み書きしたほうがややこしくならないと感じます。

読み出し数が多い場合、PLC側で使用していない領域 D3000~D7000などに
コピー情報を並べておき、一括で読み出すことでオーバーヘッドの少ない通信になると考えます。

重要なのは現状の処理を邪魔しないことなので、
テスト環境で負荷試験を行うことをおすすめします。
Implicit Invocation (暗示的な呼び出し) について (Actions on Google/Google Assistant)

#Implicit Invocation とは
Implicit Invocation とは、「ユーザーの暗示的な呼び出しに、アクションを反応させる」ことです。

例（スクリーンショット）：
![Screenshot_20181201-111643_Google.jpg](https://qiita-image-store.s3.amazonaws.com/0/40524/14e5f7f3-9915-da3f-2414-b06bba3f89a8.jpeg)

# Google Assistant のアクションのユーザー数を増やす際の問題
Google Assistant 用にアクションを作成した際の問題の 1 つが、「どうやってアプリを知ってもらうか（Discoverability）」です。
アプリの名前を知ってもらっていないと使われないため、「アプリ名を知ってもらう工夫」が必要、という問題があります。

Implicit Invocation (暗示的な呼び出し) は、その問題の 1 つの解決策です。
一言で言うと、「ユーザーの暗示的な呼び出しに、アクションを反応させる」ことです。

本記事では Implicit Invocation を、「満月博士」というアクションの例で説明します。
「満月博士」は、次の満月の日や、今日が満月かどうかを答えられる Google Home/Google Assistant 用のアクションです。

#コンテンツ：
- Implicit Invocation とは
- 設定方法
- 実際の成果
- 感想

#Implicit Invocation とは
再掲ですが、Implicit Invocation とは、「ユーザーの暗示的な呼び出しに、アクションを反応させる」ことです。

例（スクリーンショット）：
![Screenshot_20181201-111643_Google.jpg](https://qiita-image-store.s3.amazonaws.com/0/40524/14e5f7f3-9915-da3f-2414-b06bba3f89a8.jpeg)

例　（満月博士の場合）：
ユーザーが Google Home/Google Assistant に「次の満月はいつ？」や「今日は満月？」というようなクエリを投げかけたとき、 Google 自体に答えさせるのではなく、「満月博士」に回答を促すように設定できます。

詳細：https://developers.google.com/actions/discovery/implicit

これを行う事により、ユーザーが「満月博士」を知らなくてもアクションが呼び出されるようになります。

#設定方法
詳細は [Implicit/Explicit Invocation ~ Actions on Gogoleの呼び出し方を考える AoGを一発で呼び出すために ~] (https://qiita.com/soundTricker/items/1d9d6bbe52caba5302af) が詳しいです。

対象のインテントを、 Implicit Invocation として使う設定をします。
Dialogflow 側及び Actions on Google 側両方で設定が必要なのでどちらも対応ください。

#成果
11 月の呼び出し数です。11/23 は満月だったため、呼び出しが増えたことがわかります。
<img width="986" alt="スクリーンショット 2018-12-01 11.33.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/40524/14cddae2-adbf-b306-ec52-216e5718a49d.png">

特に、「次の満月はいつ」というキーワードによく反応していることがわかります。
<img width="1025" alt="スクリーンショット 2018-12-01 11.38.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/40524/3d75a3f3-e894-74c6-73cf-81328ef4c08c.png">

#感想
こちらを利用することで、ユーザーがニーズを欲した瞬間「マイクロモーメント」を確実にアクションで満たすことができます。
Google Assistant の良さの 1 つである「すぐに、簡単に」情報を得られる、という部分を有効活用できるかと思います。


ぜひ使ってみてください！

#追記
（20181203 追記）Entity を利用する場合は、 Entity と日本語の間に半角スペースを入れる必要があります。
https://developers-jp.googleblog.com/2018/03/exp-imp-invocations.html
（ご指摘ありがとうございます！）
｢新宿ダンジョン｣の下水道版を作りたい

##現実世界を探検するアプリが欲しい
数年前に、｢新宿ダンジョン｣という新宿駅を探検して宝探しをするアプリで遊びました。
アプリとしての完成度もさることながら、新宿駅の構造が勉強できて、とても役に立ちました。
その記憶から、他にも現実世界をモチーフにした探検アプリがあれば、勉強になって面白いんじゃないかなーと思っていました。
##東京の地下迷宮地図があった
他の地下街の探検アプリ作っても良いのですが、せっかくなら地下鉄とかダンジョン感のあるモチーフが良いなーと思っていました。
そんなとき縁あって、SEMISという東京の下水道地図サイトの存在を知りました。
これ、都内に張り巡らされている下水管が全部地図になっているので、このマップを探検アプリにしたら、相当大きなものができそうです。
##スマホだけでandroidアプリを作りたい
立派なPCとか持ってないので、スマホでできる範囲でやります。
最終的には、東京中の地下を縦横無尽に探検できる3Dゲームが理想ですが、まあ趣味の範囲でできるところまでやってみます。
##さて何からやるか
アプリなんか作ったことないので、ざっくり調べてみたところ、こんな記事見つけました。
https://allabout.co.jp/gm/gc/431890/

まずはここに書かれてるAIDEというアプリをスマホに入れて、最低限のアプリを作ってみたいと思います。
ランダムフォレストの概要（自分用）

#　ランダムフォレスト

##　ランダムフォレストとは

・少しずつ異なる決定木をたくさん集めたもの。決定木は訓練データに対して過剰適合してしまう問題に対応するための方法。
過剰適合した決定木をたくさん作り、その結果の平均を取ることで過剰適合の度合いを減らすことができ、予測性能を維持したまま過剰適合を解決できる。
異なるターゲットをそこそこの値を予測できている決定木をたくさん作るのだが、その際に決定木が被らないよう乱数で調整しているため"ランダムフォレスト"と呼ばれている。

ランダムフォレストに乱数を導入する方法は以下の２通りある
・データポイントを選択する方法
・分岐テストに用いる特徴を選択する方法

##長所、短所、パラメータ
###長所
・非常に高い予測値を出すことができる。
・パラメータチューニング、データのスケール変換をせずに使える。
・大きいデータセットに対しても有効。

###短所
・決定木の詳細な解釈ができない。（なぜ高い予測をだせたかなどの説明をするのが難しい）
・本質的にランダムの為、乱数のシード(random_state)を変更するとモデルが大きく変わる可能性がある。
・テキストデータなどの、高次元で疎なデータに対して機能しない時がある。

###重要なパラメータ
###n_estimators（決定木の数）
多くの決定木の平均をとると、過剰適合が低減されアンサンブルが頑健になるため、このパラメータは大きければ大きいほうがいい。
ただし、増やすとメモリの量も訓練時間も増大するので注意。

###max_features（決定木を作る際に使用する特徴量の数）
この値を大きくすると、ランダムフォレストの中の決定木が似たようなものになり、識別性の高い特徴量を使うため、訓練データに容易に適合できる。
小さくするとランダムフォレストの中の決定木は大幅に異なるものになるが、決定木の深さを大きくしないと、データに適合えきない。

###max_depth（決定木の深さ）
値を大きくすると予測性能が高くなるがデータが複雑になり、過剰適合する恐れがある。
値を小さくすると単純にはなるが、そもそもデータに適合できない可能性がある。

一般にはデフォルト値を使うといいとされている。
1,2,3. 1,2,3. 1,2,3.

# 1,2,3
1,2,3. といえば、PlayStation。
11月発売のSEGA SATURN の購入を見送り、12月にPlayStation本体とRidge Racerを買ってきた当時が懐かしいです。 
本日発売されたのは、[PlayStation Classic](https://www.youtube.com/watch?v=eU2SSXzH9dc)。
1994年12月3日に[初代PlayStation](https://www.youtube.com/watch?v=pOwNcOWmR6g)が発売されてから、ちょうど24年が経ちました。もう、あれから2回も戌年が巡ってきてしまったと。
当時は[ネットやろうぜ!](https://ja.m.wikipedia.org/wiki/ネットやろうぜ!)も購入し、遊んだなー。[開発機](https://twitter.com/playstation_jp/status/350523971789279232)が黒く表面もザラザラに加工されててカッコよかった。

# 1
Oneといえば、[JavaOne](https://ja.m.wikipedia.org/wiki/JavaOne)。
1999年に参加した時は、会場で[Palm V](https://ja.m.wikipedia.org/wiki/Palm_V)を購入しましたっけ。KVMで遊びました。Numentaバンザイ。
Wikipediaはマトモに更新されてませんが、まだなんとか、続いてるみたいですね。

# 2
2といえば、J2EE。
現在は、2が抜けて、JavaEE。エンプラなJava屋さんがつかう、アレです、アレ。

# 3
3といえば、Java3D。あ、もう絶滅してますね。。
ではなく、3といえば、もちろん、Scala 3です。
[Dotty](http://dotty.epfl.ch/)という完全新番のコンパイラを採用する、新たなScalaのバージョンです。
まだ、Javaを使ってる人は時流に追いつく絶好のチャンスです。ぜひ、Scala3のキャッチアップをこれから始めましょう！
Scala3の正式版は2020年にリリースされる予定ですので、来年は準備期間として有意義に使いましょう。
試したい方は[コチラ](http://dotty.epfl.ch/docs/contributing/getting-started.html)を参考にどうぞ。
gem  install 'pg'でエラーになった場合の対処　 [備忘録]　

<h1>目的</h1>
オリジナルをアプリをHerokuへデプロイする時、
データベースは「PostgreSQL」を使わないといけないらしいが、
インストール時に'pg'についてエラーが発生したため、対処法を書き残す。

<h1>エラー内容</h1>

gemfileを追記して、ターミナルでインストールしようとしたところエラー画面に遭遇した。:frowning2:


・gemfileに以下を記載

```ruby:Gemfile
group :production do
gem 'pg'
end
```

・ターミナルのエラー内容
![スクリーンショット 2018-12-01 11.15.50.png](https://qiita-image-store.s3.amazonaws.com/0/321039/886e23fc-3895-284f-1e99-ba1f9cd46878.png)


上記のターミナルエラーの少し上を遡ると、以下画像３行目の通り「Can't find the 'libpq-fe.h header」と
記載されており、どうやら「libpq-fe.h」が見つからないらしい。


![スクリーンショット 2018-12-01 11.20.42.png](https://qiita-image-store.s3.amazonaws.com/0/321039/5f99e444-0efd-0a31-134b-b3af5057de3f.png)


<h1>対処法</h1>

ターミナルで「brew install postgresql」を実行すると解決する。



```ruby:tarminal
brew install postgresql
```
pipenv+pylint利用時のunable to importへの対応

vscode+pylint+pipenvt利用時に遭遇したのでメモ。

下記のように.envファイルでpythonのパスを変更すればよい。

```.env
PYTHONPATH=./backend
```

仮想環境内にpylintが入っていなければpylintも追加する必要がある。

参考
https://github.com/Microsoft/vscode-python/issues/1990
LambdaでサーバーレスにhtmlをPDFに変換しよう

ヴァル研究所アドベントカレンダー2018の2日目です。

PDF帳票が必要な場合、どんな方法で作成していますか？

html・cssで書いてそれをPDFに変換できると便利ですよね。html・cssでのレイアウトにはみんな慣れていますし、テーブルや文字のセンタリング等も簡単です。cssでは長さの単位に `mm` や `cm` も使えるので、物理的なサイズをそのまま指定できます。

[html-pdf](https://github.com/marcbachmann/node-html-pdf)というNode.jsライブラリ・CLIツールを使うとhtmlをPDFに変換できます。内部ではPhantomJSを使っているので、htmlのレンダリングにも安心感があります。

```console
$ npm install -g html-pdf
$ html-pdf test/businesscard.html businesscard.pdf
```

当方ではサーバーレスで開発していたので、この変換をLambdaで行いたいと考えました。そうなるとネックになるのが**Lambdaのデフォルト環境には日本語フォントが入っていないという問題**。結局そこは、**フォントをzipパッケージに含めて、実行時に `font-cache` を実行することで PhantomJSから使えるようにする**方法で解決しました（`fonts.conf` の中で `cachedir` を指定しているのが何気にキモです）。`fontconfig` 自体はLambda環境にデフォルトで入っているのでインストール不要です。
　
`font-cache` に3秒程度かかってしまいますが、許容範囲かと思います。
API Gatewayと組み合わせて、「htmlをリクエストボディとしてPOSTするとPDF化してS3に保存してそのURLを返す」というAPIの形にして利用しました。

その[Lambdaのzipパッケージをこちらにアップロード](https://github.com/aoyama-val/lambda-html2pdf/releases)してあるので、すぐにお使いいただけます。

# 備考
[HTMLページをPDFファイルへ変換するPDFShiftというWebサービス](https://qiita.com/rubytomato@github/items/a3ea1635b801ea068b24)もあるようです。

実行時に `font-cache` を実行する方法は、LambdaでPhantomJSを使ってWebページのスクリーンショットを取る場合にももちろん使えます。
BCM/mipsでもmruby

[BCM/mips](https://qiita.com/yamori813/items/9cd9188b8b416de812f9)でもmrubyが動くようにしてみました。

![写真（2018-12-01 11.58） #2.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/f1b840d7-509d-d6a3-8354-d86335e1f7d7.jpeg)

[蟹さん](https://qiita.com/yamori813/items/c1d8111a3f45c5a74655)の時と同じで[newlibを用意](https://qiita.com/yamori813/items/3f87fe35acae2b4e442c)します。

とりあえずlibcとlibmrubyをリンクして実行すると固まります。デバッグしたところsetjmpの問題な事がわかり修正しました。mrubyをデバッグしてsetjmpにたどり着いたのですが、結構骨で、setjmp/longjmpはアーキテクチャや環境によって問題起こしやすいので、事前にテストしておいた方が良いです。

https://github.com/yamori813/bcmbm-mruby

```
CFE> boot -elf 10.10.10.3:main.elf
Loader:elf Filesys:tftp Dev:eth0 File:10.10.10.3:main.elf Options:(null)
Loading: 0x80010000/256952 0x8004ebb8/76 Entry at 0x80010000
Closing network.
et0: link down (interface down)
Starting program at 0x80010000
index:0
index:1
index:2
index:3
index:4
index:5
index:6
index:7
index:8
index:9
index:10
```

いろいろはまって一週間くらいかかりました。

蟹さんはBigEndianですがBCM/mipsはLittleEndianです。また蟹さんは正式にはMIPSではない(Lexra）のですがBCM/mipsはほんまもんのMIPSです。

BCM/mipsなターゲットはメモリが8Mや16Mのものが多いのですが、OSをのせるには窮屈ですが、mrubyにとっては十分な大きなのではないでしょうか。
PHP 比較系演算子の話

PHPにはいろんな演算子がありますよね。
例えば文字列結合の「.=」や三項演算子「?」などなど

今回は自分も最近知った、Null合体演算子、エルビス演算子を紹介したいと思います。

# Null合体演算子「？？」
PHP7から導入されました。
この演算子は未定義変数初期化に大いに役立ちます。

例えば下記コードのようにissetメソッド用いて変数を初期化したいことは多々あると思います

```
<?php
if (isset($hoge)) {
    $output = $hoge;
} else {
    $output = 'not_hoge';
}
echo $output;  //not_hoge
```

ここで上記のコードをNull合体演算子を使って表現してみます。

```
<?php
$output = $hoge ?? 'not_hoge';
echo $output; //not_hoge
```

このように初期化をNull合体演算子を使うと、
余計なif,elseを使わずに表現できます！
ちなみに名前に騙されそうですが、is_nullではなく、issetで判定してるみたいです。

# エルビス演算子「?:」
これはPHP5.3から導入されている演算子です。
こちらも変数初期化のときに役に立ちます。

```
<?php
$hoge = 'hoge';  //この行を消すと「Notice: Undefined variable: hoge」
if ($hoge) {
    $output = $hoge;
} else {
    $output = 'not_hoge';
}
echo $output; // hoge
```

上記のように変数で判定している場合がありますね。
これをエルビス演算子を使って再現すると下記のようになります。

```
<?php
$hoge = 'hoge';   // この行を消すと上記と同様に「Notice: Undefined variable: hoge」
$output = $hoge ?: 'not_hoge';
echo $output; // hoge
```
Null合体演算子のissetなし版という感じですね。


この演算子の注意点は、未定義判定は行わないことです。
初期化してない変数に使用するとNotice出てきます

ちなみにこの演算子の名前の由来はエルビス・プレスリーらしいです。（下記にリンクあります）

### 参考
- [Null合体演算子](https://ja.wikipedia.org/wiki/Null%E5%90%88%E4%BD%93%E6%BC%94%E7%AE%97%E5%AD%90)
- [【PHPなど】エルビス演算子 ?: 本当にエルビス・プレスリーだった【画像あり】](https://qiita.com/ito_gen/items/7650454fbb27baefc1f7)
YouTubeのAV1のテスト配信を試す

新しいビデオコーデックであるAV1を使ったYouTubeのテスト配信を見る方法を紹介します。
基本的にはこのページに書いてある通り。

[AV1 Beta Launch Playlist](https://www.youtube.com/playlist?list=PLyqf6gJt7KuHBmeVzZteZUlNUQAVLwrZS)

簡単なので、興味のある人はぜひ試してみてください。

# ブラウザの設定

まずはAV1を再生できるブラウザを準備します。

## Chrome

Version 70 以降ならばデフォルトでAV1は有効になっています。
普通に現在の安定版のChromeをインストールすれば、特に設定は必要ありません。

## Firefox

URLに `about:config`　を入力します。
`av1` を検索すると、`media.av1.enabled` という項目が見つかるので、それを`true` にします。

![Screenshot from 2018-11-29 10-49-28.png](https://qiita-image-store.s3.amazonaws.com/0/13271/a9c6fe98-638c-387c-b0ff-508677677717.png)

# YouTubeアカウントの設定

AV1を再生できるブラウザで以下のサイトにブラウザでアクセスします。

https://www.youtube.com/testtube

AV1に関する設定項目があるので、「常にAV1を使う」を選択します。

![Screenshot from 2018-11-29 10-45-45.png](https://qiita-image-store.s3.amazonaws.com/0/13271/e1680a87-666b-5192-f065-8e30ed45b301.png)

# AV1のテスト配信を見る

[AV1 Beta Launch Playlist](https://www.youtube.com/playlist?list=PLyqf6gJt7KuHBmeVzZteZUlNUQAVLwrZS)

このプレイリストから動画を選んで再生します。

# CODECの確認

本当にAV1の再生をしているのかどうか確認します。
YouTubeの再生画面で右クリックすると以下のメニューが表示されます。

![Screenshot from 2018-11-29 10-43-48.png](https://qiita-image-store.s3.amazonaws.com/0/13271/c26cceae-98e9-4dfe-69eb-c9bcacbe124c.png)

ここで`詳細統計情報`を選択します。
![Screenshot from 2018-11-29 10-44-03.png](https://qiita-image-store.s3.amazonaws.com/0/13271/89053720-6a21-7d7f-565e-9b396531be37.png)

Codecsの項目が `av01` で始まっていることを確認してください。

# どんな感じか

MacやLinux, Windowsなどいくつかの環境で試してみました。
今年購入したような新しい機種では、1080p 30fps は問題なく再生できました。
すこし古い機種では1080p がすこしカクカクしましたが、720p なら問題無いという感じでした。

現状のChrome, Firefox のAV1のデコーダはリファレンス実装であるlibaomを使用していると思いますが、デコードに関しては通常の視聴であればいけそうです。
今後チューニングされたAV1のデコーダも出てくると思いますが、そうなると解像度を4Kにあげたり、フレームレートを60fpsに上げたりといったことが期待されます。

自分でAV1で配信してみたくなった方はこちらを。
[新しいビデオコーデックのAV1を使って無理やり HLSでストリーミングしてみた](https://qiita.com/tetsu_koba/items/44a2c4026c4cee8ab8f6)
【解決方法】Amazon EKSクラスターのkubeconfigが取得できない

# 問題

Amazon EKSクラスターの**kubeconfig**が取得できない

```shell-session
# クラスターの kubeconfig を作成または更新
$ aws eks update-kubeconfig --name <cluster_name>

Could not connect to the endpoint URL: "https://eks.ap-northeast-1.amazonaws.com/clusters/<cluster_name>"
```

> 補足：`<cluster_name>`は事前に作成したEKSクラスター名


# 調査

AWS CLIの設定を確認

```shell-session
$ aws configure
AWS Access Key ID [****************WVJA]:
AWS Secret Access Key [****************LD/m]:
Default region name [ap-northeast-1]: 
Default output format [None]:
```

# 原因

AWS CLIで設定しているリージョンとEKSクラスターを作成したリージョンが不一致だった。

- AWS CLIで設定しているリージョン：ap-northeast-1
- EKSクラスターを作成したリージョン：us-west-2

> 補足
> ap-northeast-1：アジアパシフィック (東京)
> us-west-2：オレゴン

# 対処

EKSクラスターを作成したリージョンをAWS CLIで設定する

```
aws configure
AWS Access Key ID [****************WVJA]:
AWS Secret Access Key [****************LD/m]:
Default region name [ap-northeast-1]: us-west-2
Default output format [None]:
```

Amazon EKSクラスターの**kubeconfig**が取得できるようになったことを確認

```
$ aws eks update-kubeconfig --name <cluster_name>
Added new context arn:aws:eks:us-west-2:xxxxx:cluster/<cluster_name> to /Users/<username>/.kube/config
```
Slackのログ（JSON形式）をCSVに変換させた

# Slackのログ（JSON形式）をCSVに変換した
## やりたいこと
- Slackの活動数やユーザー間のつながりを分析したい
    - 発言数、リアクション数、リアクション・被リアクション関係、メンション関係など
- データはJSONの階層形式なので、分析しやすいようにCSVに変換する

## DLできるデータ
- 詳しくは [Slack からエクスポートしたデータの読み方](https://get.slack.help/hc/ja/articles/220556107-Slack-%E3%81%8B%E3%82%89%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%E3%81%97%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9) 参照
- Slackのログはパブリックチャンネルであれば全期間出せる
    - 設定と権限＞データのインポート／エクスポート　でいける
- ログ
    - channnel.json：チャンネル一覧
    - users.json：ユーザー一覧
    - チャンネル名フォルダ下にログが存在する日付ごとのファイルがある
        - 2018-01-01.json
        - 2018-01-02.json

## やりたいことをもとに見たいデータの形を考える
- 今回は汎用的に分析できるように、RDBライクなデータにする
    - チャンネル一覧
    - ユーザー一覧
    - メッセージ一覧
    - リアクション一覧：リアクションされたユーザー、リアクションしたユーザー、絵文字
    - メンション一覧：メンションしたユーザー、メンション先ユーザー
- リアクション、メンションはメッセージと1:N関係

## 出力するとこんな感じ

### メッセージ
|channel_id|talk_id|talk_user|text|
|:--|:--|:--|:--|
|C5XXXXXXX|XX1|U9XXXXXXX|`<@U8YYYYYYY>`こんにちは|
|C5XXXXXXX|XX2|U8YYYYYYY|帰りたい|
|C5XXXXXXX|XX3|U9XXXXXXX|しごおわ|

### リアクション
|channel_id|talk_id|talk_user|reaction_user|emoji|
|:--|:--|:--|:--|:--|
|C5XXXXXXX|XX1|U9XXXXXXX|U8YYYYYYY|ok_woman|
|C5XXXXXXX|XX1|U9XXXXXXX|U7ZZZZZZZ|iine|
|C5XXXXXXX|XX2|U8YYYYYYY|U9XXXXXXX|wakaru|
|C5XXXXXXX|XX2|U9XXXXXXX|U7ZZZZZZZ|otukare|

### メンション
|channel_id|talk_id|talk_user|mention_user|
|:--|:--|:--|:--|
|C5XXXXXXX|XX1|U9XXXXXXX|U8YYYYYYY|

こうしておくことで人気絵文字とかリアクション・被リアクション関係、メンション・被メンション関係などを分析しやすくなる！

## ソースコード
Pythonで作ったぞい
https://github.com/yakipudding/slack-analytics
jsdoでchip8　その9

#概要

jsdoでchip8やってみた。
開発環境を整備してみた。
アセンブラとディスアセンブラとエミュを合体した。


#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/797dbc75-3c95-f3f6-0c0c-9a3b282c1bfa.png)

#成果物

http://jsdo.it/ohisama1/8yvv

以上。
Excelが勝手に起動する（メモ）

#Excelが勝手に起動する場合のチェックポイント３

```
C:\Users\(user name)\AppData\Roaming\Microsoft\Excel
C:\Users\(user name)\AppData\Local\Temp
C:\Users\(user name)\AppData\Local\Microsoft\Office\UnsavedFiles
```

このフォルダになにかあったら削除してください。
３つめのUnsavedFilesは、正しく保存できなかった場合にあるのですが、
正しく保存しなおしても残ってる場合があります。なぜかわかりませんが。
Kaggle Tokyo Meetup #5 資料まとめ


2018年12月1日(土)に開催された[Kaggle Tokyo Meetup #5](https://connpass.com/event/105298/)のスライド一覧のリンクをまとめます。

# Time Table
## Avito 9th Place Solution & 中国Kaggle事情
- [スライド](https://www.slideshare.net/JinZhan/kaggle-avito-demand-prediction-challenge-9th-place-solution-124500050)


## Home Credit 2nd place solutions ~ お通夜から始まったドラマ ~
- [スライド](https://speakerdeck.com/hoxomaxwell/home-credit-default-risk-2nd-place-solutions)
- [記事](http://ireko8.hatenablog.com/entry/2018/11/30/221030)

## Santander Value Prediction Challenge 17th Solution
- [スライド](https://www.slideshare.net/KeiYagi/santander-value-prediction-challenge-17th-solution/KeiYagi/santander-value-prediction-challenge-17th-solution)

## Santander 8th Solution~気合いでとったソロゴールド~
- [スライド](https://www.dropbox.com/s/bjju15vkb9ewsj5/20181201_santander.pdf?dl=0)

## PFDet: 2nd Place Solution to Open Images Competition
- [スライド](https://www.slideshare.net/shotarosano5/pfdet-2nd-place-solutions-to-open-images-competition)

## LightGBMを少し改造してみた
- [スライド](https://www.slideshare.net/RyuichiKanoh/lightgbm-124545133)

## 日本初の競技機械学習大会"Cpaw AI Competition"の運営
- [スライド](https://speakerdeck.com/shunk031/about-cpaw-ai-competition-in-kaggle-meetup-tokyo)

## kaggler-ja driven learning
- [スライド](https://speakerdeck.com/upura/kaggler-ja-driven-learning-kaggle-tokyo-meetup-number-5)

## RSNA Pneumonia Detection Challenge 6th Place Solution
- [スライド](https://www.slideshare.net/pfi/rsna-th-place-solution-pfneumonia)

## TGS Salt Identification Challenge 12th place solution
- [スライド](https://speakerdeck.com/catla/tgs-salt-identification-challenge-12th-place-solution)


## あとがき
現状ある情報のみで構成しています。
追加・訂正等が必要があるものはこちらで修正しますので
編集リクエストかコメントで教えて頂けると幸いです。
Rails Tutorial 初心者視点のつまづきポイント

プロゲートを終えたぐらいのレベルの視点から書き綴ってみます。
たくさんあると思うけど、自分がつまずいたポイントと解決できた方法を書いておきます。


##1.前置きがなげぇ


いきなりでアレですが３回は寝落ちしたと思いますw。寝る前に横になってタブレットで読み進めるのはやめておいたほうがいいです。**というか、チュートリアルなので自分で手を動かしながら進めないと無意味です。**時間を費やせば血肉になるというのは幻想です。
それと、若干本題とはそれますが**『活字にどれだけ免疫をつけられるか』**というのもプログラミングを学習する上で重要なポイントかなと思いました。



**解決：pcでやろう**



##2.日本語でok##
そう思ったのならRailsチュートリアルはまだ来るべきところではありません。わからなければググるのが基本ですが、その頻度があまりに多いなら学習効率が悪すぎます。検索バーにプロゲートと入力し、理解できたらリベンジするスタイルのほうが懸命です。



**解決：背伸びしすぎない**



##3.Cloud9##
チュートリアル内では個人の実行環境の差を吸収するためにClooud9というクラウド開発環境を利用します。Cloud9はいつの間にかAWSに吸収されて利用にはAWSアカウントが必要なのですが、**クレジットカードの登録が必要です。**一応一年間は無料で利用できるようですが、**無料枠には条件があります。**あんまりハシャぐとあとで痛い目を見るかもしれません。**[こんな事例もありますし。](https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694)**

チュートリアル内での解説がザックリしてる(ちょっと古い?)のもあって今回導入するにあたって[こちらの記事](https://www.sejuku.net/blog/385)が丁寧でわかりやすかったです。
最近大分炎上されてましたが少なくともこの記事は参考になりました。



**解決：疑問はググる**



##４．どこでコマンドを打つのか##
第一章ではRailsだけではなくてコマンド、GitHub、Bitbucket、SSH公開鍵の作成などにも触れます。特に公開鍵の作成方法は**記事がリンク先になっているので文脈が飛びます**。そうなると作成した鍵はどこに入れるべきなのか。そもそも公開機鍵とはなんなのか。悩みます。



また、**git init** という初期化コマンドも階層が違えば結果も変わります。だってツリーに表示されないんだもの。
なんか特別な場所にあるんだろう(﹡´◡`﹡ )ﾆｯｺﾘ ぐらいに捉えていたら**あとで全消しすることになります**(なった)。



チュートリアルでははじめのうちこそ $ cd ~/environment/hello_app/  のように階層を明記してくれますがそれも途中からありません。ひつじ師匠ほど優しくはないのです。
ということで、最低限 cd , ls, pwd　ぐらいは覚えましょう。そして構造を意識することが大切だと理解しました。



**解決：公開鍵はCloud9コンソールから ~/.ssh**



##5.　ブランチの概念##
おそらく文章だけで説明されてもかなりわかりにくいのではないかと思います。
「コピーを作る」と説明されてますが普段よく見るツリー構造に慣れていると、そのコピーしたファイルどこにあるの？となると思います。Git関連は解説してるサイトも豊富ですし**別コンテンツで学習してから進めるほうが効率的**だと感じました。



**解決：Gitは入門サイトが豊富なので先にそっちで概要を掴むのがおすすめ**



##6.　Herokuにログインできない##


チュートリアルにはさくっと　heroku login　とありますが...

**heroku: waiting for login... が終わりませんでした。**

でも**ググればすぐに解決しました。**細かいことはわかりませんがとにかく動いたので良しとします。細部にこだわりすぎて目的を見失っても本末転倒です。



**解決：heroku login --interactive にする**
***




以上自分がつまずいた所と、それにどういった対処をしたかを書き綴ってみました。
もっと言えば細かいところで立ち止まってますし、完全に理解しきれていない部分もあるかと思います。
ですが『ググれば５分でわかる』ぐらいには理解できたと思います。

危険なのは**実践もせずに読んだだけでわかった気になること、何が問題となっているのかを認識できていないこと**、なのかと思います。そこがわかってしまえばあとは手を動かす量の問題かもしれません。





**解決：ググらざるものプログラムべからず**

初投稿でした。
AWS Lambda(python)からRESTコールする ～ 試しにdocomo自然対話APIに！

## はじめに
長らく慣れ親しんだdocomo雑談対話APIが2018年10月末でサービス終了となりました。
サービス開始当時は、LINEの後ろに仕込んでLINE BOT作って遊んでいました。

その後継サービスとして、docomo自然対話APIがあるようです。
https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4_usage_scenario#tag01

せっかくなので、AWS Lambda (python3.6)からAPIコールしてみたいと思います。

## 手順
初回は(1)及び(2)が必要で、ちょっと面倒です。

#### (1) docomo developer supportに登録
https://dev.smt.docomo.ne.jp/

#### (2) API登録
API経由でユーザー登録をして、アプリケーションIDを取得する必要があります。
この手順は、少しコーディングが必要です。

lambdaに以下のコードを入れて、ハンドラ情報をlambda_function.registrationに設定して、動かすと、アプリケーションIDを取得することができます。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/271244/d23530bc-a49f-eab4-6750-136ecf7976f3.png)


そしたら、アプリケーションIDとアプリケーションキーをLambdaの環境変数に設定しましょう。


![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/271244/78c38471-4492-b8b2-6fda-c62189f27dc0.png)

#### (3) 利用
会話時はハンドラをlambda_function.mainにして使ってみてください。

環境変数のメッセージに話しかけたい内容（「こんにちは」など）を書いてテストボタンを押すと・・・

![キャプチャ4.PNG](https://qiita-image-store.s3.amazonaws.com/0/271244/4c56df08-e5b5-f151-a75c-633e07606cbd.png)

メッセージが返ってきます。

いろいろ、話しかけてみましょう！

## コード

```python:lambda_function.py
import requests
import json
import os

docom_app_id = os.environ['APP_ID']
docomo_api_key = os.environ['API_KEY']
docomo_endpoint_registration = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY='+docomo_api_key
docomo_endpoint_dialog = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY='+docomo_api_key

headers = {
    'Content-type': 'application/json;charset=UTF-8'
}

def registration(event, context):
    payload = {
        "botId": "Chatting",
        "appKind": "Smart Phone"
    }
    response = requests.post(
        docomo_endpoint_registration, 
        data=json.dumps(payload), 
        headers=headers
    )
    data = response.json()
    print(json.dumps(data))
    return {'statusCode': 200}
    
def main(event, context):
    payload = {
        "language": "ja-JP",
        "botId": "Chatting",
        "appId": docom_app_id,
        "voiceText": os.environ['MESSAGE'],
        "appRecvTime": "2017-10-28 00:25:00",
        "appSendTime": "2017-10-28 00:25:00"
        
    }
    response = requests.post(
        docomo_endpoint_dialog, 
        data=json.dumps(payload), 
        headers=headers
    )
    data = response.json()
    return data['systemText']['expression']

```

## 参考
https://www.yamamanx.com/docomo-developer-support-api/
アセンブリ言語でのゲームボーイ開発(画面更新)

今回は、画面を動かした。ソースコードは[こちら](https://github.com/toh4649/gb-asm/tree/master/vsync)。

![vsync.gif](https://qiita-image-store.s3.amazonaws.com/0/57535/2a931c3f-08aa-6ef3-0281-6f20cf6b87be.gif)


#いつ画面更新するか

GBは、1/60秒ごとにVRAMの内容を画面に表示する。その処理は、1/60秒間ずっと続いているわけではなく、実際は少し短い。そのため、画面表示の処理をしていない、「すきま時間」が存在している。プログラムは、その「すきま時間」に、VRAMを書き換えるような画面更新処理を実行する必要がある。

この「すきま時間」は、ブラウン管テレビの用語の名残で「垂直帰線区間」や「VBlank」等と呼ばれるようである。本記事でも「VBlank」と呼ぶことにする。

#VBlankとの同期

画面を更新するためには、VBlankの間にVRAMを書き換えたい。だが、VBlankがいつ発生するかを知る方法が必要である。

GBでは、VBlankが開始したタイミングで割り込み発生するので、それをハンドルすればよい。具体的には、VBlankが発生すると$0040番地に処理が飛ぶので、そこに画面更新のルーチンを記載すればよい。ただし、そこには8バイトしかプログラムが書けないので、画面更新のルーチンにジャンプする命令を書くことになるだろう。

#メインループの書き方

[gpspec.txt](http://www.devrs.com/gb/files/gbspec.txt)では、以下のような構成のメインループが提案されていたので、そうした。[プロの方が書いた記事](http://fawlabo.com/2016/10/07/post-121/)でも、そのような構成は現場で使われていたとある。

VBlank割り込みハンドラ:
1. VBlankフラグをセット

メイン処理：
1. VBlankフラグがセットされるまでループ
2. VBlankフラグをクリア
3. ゲームの処理

```ini:vsync.asm
;VBlank割込みハンドラ
draw:
    ld      a,1
    ld      [VBlankFlg],a
    reti

;メインループ
mainloop:
    halt   ;何らかの割り込みが発生するまで、CPU(?)を止める。電池節約のために良いとされる。
    nop    ;halt命令で処理が止まる前に,次の命令が実行されてしまうので、ダミーの1命令を挟む

    ;Vblankを含め、何らかの割り込みがあった場合、ここに来る
    ld  a,[VBlankFlg]   ;VBlank割り込みハンドラがフラグを立てたかチェック
    or  a
    jr  z,mainloop      ;(つまり、今回の割り込みがVBlank割り込みであれば次に進む)

    xor a               ;a=0
    ld  [VBlankFlg],a   ;VBlank判定用のフラグをクリア
    
    ;[メインの処理]

    jp  mainloop
```


割り込みハンドラにあまり多くの処理を書くのはよくないのかもしれない。
人の激少ないスタートアップで機械学習チームをつくる術


## カヤック時代
カヤックではデニールと呼ばれておりました。
2014年に中途で入社し3年間iOA,Androidのエンジニアとして働いており、
今は[TRUNK](https://trunk.company/)という教育と採用の会社を創業しCTOとして開発から経営までわちゃわちゃしてます。

## なぜ機械学習チームが必要になったか
結論から言うと、物凄く必要というわけではありませんでした。
個人的に去年から今年の頭にかけて、東大の社会人向けのデータサイエンティスト講座を修了し、自社に活かそうとしていました。
機械学習を何に使えるか決まってないけど、スモールスタートでとにかくやってみようという感じでヌルっとはじめました。

参考: [東京大学グローバル消費インテリジェンス寄付講座](https://gci.t.u-tokyo.ac.jp/)


## チーム集め
まずはチームです。そもそも弊社はフルタイムエンジニアが私含め2人なので、フルタイム社員はまず無理です。
そこで、インターンです。TRUNKは大学生向けのWEBとリアルの学習+採用サービスということもあり、自社サービスから探しました。(採用サービスやっててよかった。)
ということで集まったのが、情報系の学部で機械学習も少しやったことがある通称イトゥーとデータサイエンティストとしてインターンしてる通称ナゴヤボーイの2人を招集しました。
イトゥーはこの為に採用し、ナゴヤボーイは元からいたインターンです。

PM: わたし
エンジニア: イトゥー、ナゴヤボーイ

## タイトルの自動生成プロジェクトはリリースまでいけず
まず最初に目をつけたのが、トレーニングタイトルの自動生成です。
現在TRUNKでは学生が集まりそうなタイトルを人間が圧倒的な感覚で決めてます。
参考: [トレーニング一覧](https://trunk.fm/trainings)

これを機械が勝手に決めてくれたら社内の全員助かる！ということでこれに決めました。

### 技術的な話
#### サマリー
- マルコフ連鎖 
- LSTMで文字の自動生成

ここらへんの技術に近いです。
[【エヴァンゲリオン】アスカっぽいセリフをDeepLearningで自動生成してみる - Qiita](https://qiita.com/S346/items/24e875e3c5ac58f55810#rnn%E3%81%A8%E3%81%AF)


### マルコフ連鎖

#### データセット
TRUNKの過去のトレーニングタイトル: 700件(重複をのぞく)

#### 生成結果サンプル
```
- 今も現役バリバリ䛾おっさんエンジニア、デザイナー志望䛾学生向け
- ゴール䛾設定䛾しかたを勉強して体験！春休みにユーチューバーデビューしよう！
- フォトショップでトレーニング画像を使うと面白くなりそうなも䛾
```
### LSTM
#### データセット
TRUNKの過去のトレーニングタイトル: 700件(重複をのぞく)
compassの過去のイベントタイトル: 5900件


#### 生成結果サンプル
```
- lpを使ったスキル開発ツールを用い
- PyLadiesTokyoMeetup
- インターネットLTエンジニア社よ
```

### 精度が上がらず中止
ご覧の通り、結果としてできた文章は、実用レベルには達しませんでした。
このプロジェクトはここで終わりとしました。

詳しくはイトゥのスライドをどうぞ
[kobachi presentation - Speaker Deck](https://speakerdeck.com/andmohiko/kobachi-presentation)



## 学生のレコメンドモデルがリリースまでいけそう
次に目をつけたのが、レコメンドのモデルです。
TRUNKは企業の人事が学生のレジュメを見てスカウトを打ちます。
そこで、機械学習をつかったレコメンドモデルをつくり、よりスカウトを打ってもらおうというプロジェクトです。

### 技術的な話
過去にスカウトを打ったユーザーのレジュメにあるキャッチコピーを解析し、似たキャッチコピーのユーザーをレコメンドしようというものです。

#### サマリー
- Doc2Vec
- MeCab

### Doc2Vec
Doc2Vecは任意の長さの文章をベクトル化する技術です。
学生のキャッチコピー、自己紹介を学習データにベクトルにし、類似度を出そうというものです。

### Mecab
MeCabは日本語の形態素解析に使われるライブラリでキャッチコピーから動詞と名詞を取り出すのに使っています。

詳しくはイトゥのスライドをどうぞ
[project yamcha phase 1 - Speaker Deck](https://speakerdeck.com/andmohiko/project-yamcha-phase-1)


### キャッチコピーに対する類似度の結果
結果の一部をご覧ください。
※ 文章右側の数字は1.0が類似度MAX(同一文章)で、数字が1.0に近いほど類似度が高いです

#### ユーザーAのキャッチコピー: "人が少しでもポジティブに働ける社会創りに貢献する"

```
使命を全うする！!	0.337063
インド、ベトナムでエンジニア修行！泥臭さなら誰にも負けません!	0.301001
keep on	0.298875
```


#### ユーザBのキャッチコピー: "生きてるだけで丸儲け"
```
フットワーク	0.300182
好奇心旺盛のマイペース	0.296664
何でもやってみたい	0.274297
```

#### ユーザCのキャッチコピー: "誰とでもすぐ仲良くなれる怖いものなし大阪出身のたこやき娘"
```
食うか食われるかの人生送るサバンナ系女子大生	0.303465
星が出るエンジニア^_−☆	0.287842
忍耐強いにっこりスマイル0円	0.285037
```

どうでしょうか、**なんとなくわかる~** という感想だと思います。
ユーザーCの例に関しては**たこやき娘**と**サバンナ系女子大生**という絶妙なチョイスに驚きです。
アルゴリズムにはない良い味だしてます。

## プロダクトに導入への道
このモデルはまだムラがあるので、この機械学習のモデルとルールベースのアルゴリズムを組み合わせてレコメンドするよう現在開発中です。

## 気をつけた事=厳密なルールを決めた
- 私は絶対にコードを書かない  
- 期日を設けて、その日のモデルの出来で次のステップに行くか判断し、それ以外では判断しない
- インターンには問題を2人で努力しながら解決してもらう為、書籍はケチらない




## まとめ
- 適切な難易度の課題を見つけることが重要
- アプリケーションのコードと違って正解があるようでないのでフィードバックしにくい
- 前処理前と前処理後でデータの数が激減する
- スタートアップでも実験ベースの開発をやろうと思えばできる
- プラットフォームつくるの楽しい
【Unity】画像トラッキング でエラーとなった場合の対処方法


最初、トラッキングする画像のサイズが310pxの場合、以下のエラーが出ました。

ARUnityChanTraking[1548:71129] [Session] Session (0x105f53280): did fail with error: Error Domain=com.apple.arkit.error Code=300 "Invalid reference image." UserInfo={NSLocalizedFailureReason=One or more reference images have an invalid size: Fish, NSLocalizedRecoverySuggestion=Make sure that all reference images are greater than 100 pixels and have a positive physical size in meters., 


 <font color="Magenta">幅と高さは、少なくとも480ピクセルにしないといけないらしい。</font>

実装内容はこちらに記述してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2018/12/01/094346)
30歳でプログラミングを始めて2年半くらい経った

この記事は[nana music Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nana-music)の1日目の記事です。

タイトルのとおりですが、僕は30歳でプログラミング未経験の状態から学習を開始し、曲がりなりにもソフトウェアエンジニアとして給料をもらって生活をすることができている。
「プログラマー35年定年説」というのは今となっては過去の遺物となっていて、30代からプログラミングを学習し、ソフトウェアエンジニアに転身しようとする人も増えているらしいので、具体的にどういう感じでやってきたかを自分自身の振り返りとともに書きたいと思う。

## 前提
もともとの僕のスペックだけど、、コーディング等は全くしないユーザー系SIerで働いており、Linuxの基礎知識やDBの知識があったり、SQLを多少書けたり、という感じ。

##とにかくアウトプットする 
ある意味、これが全てだと言ってもいいかもしれない。

日々、コードを書いたりしていると、何かしらの気づきや発見がある。
また、コードレビューを通じて、新たな知見を得たり、他人が書いたコードを読むことによって「こういう書き方があるのか」「このフレームワークにはこういう仕組みがあるのか」というのを知ることができると思う。
もちろん、技術書を読んだり、ウェブでチュートリアルをやってみたりとか。

そのように何かしらの形でインプットが発生していると思うんだけれど、僕の場合はそういったインプットと同時にアウトプットも必ずやるようにしている。
ただ、アウトプットと言っても別にブログに書いたり、Qiitaで書いたり、みたいな外部への公開を前提としたアウトプットはそんなに頻繁にはしていなくてEvernoteにひたすら書いている。
まあ、いまさらEvernoteかよ感はあるけれど、ずっと使い続けていたので惰性でそこにアウトプットしているだけ。
最近なら[Scrapbox](https://scrapbox.io)でざざっと書いていけばいいんじゃないかなと思うし、そっちに移行しようかなーとも思っている。

アウトプットをすることの利点は今更特に説明する必要がないと思うけど、知識の定着を促進したり、インプットを自分の言葉で翻訳することで理解を進めやすい、というのが個人的に最も大きな効果なんじゃないかなー、と思ってる。
もちろん「あれ、これどういうふうに書くんだっけ」という時にアウトプット先を探せば良いという点もある。

## 最初の半年はカネと時間をかける
今では無料のプログラミング学習サイトがあったりするし、数千円払えば初心者向きの技術書を購入し、学習することができるけれど、やっぱりある程度カネをかけてスクールに通ったほうがいいと思います。
とはいえ、スクールのほうが学習カリキュラムが優れているとか、別にそういうことではなく、単純にカネをかけたほうが「やらないと」感が出て、自分のケツをひっぱたくことができるから。
あとは、そういうスクールだと誰かしらメンターがついてくれることが多いため、躓いた時に助かる。
オンラインのスクールとかもあったりするけれど、個人的には対面でコミュニケーションが取れるところのほうがいいんじゃないかなー、と思う。

それからコードを書く時間をがんばって増やす。
別に趣味でプログラミングをやるだけ、というのならば別にいいのだけれど、ソフトウェアエンジニアとして食っていく、というのならば、スタートが遅いんだから、時間をかけないと話にならない。
僕の場合、ちょうどプログラミングを始めた時期が、親会社に出向していてちょうど時間が取りやすかったため、始めて半年くらいは週に30時間程度はスクールのカリキュラムをやったり、写経したり、自分でツイッターのクローンアプリを作るなどをして、コードを書くことに費やしていた。

## とりあえず現場に飛び込む
実際に得た知識を現場で使うことが、自身の技量を高める最も効率の良い方法だと僕は思ったので、多少、不安があったものの転職をしてなんとかコードを書く仕事を得ることができた。(現職じゃないよ)
当然ながら未熟なので迷惑をかけることもあるし、実際迷惑をかけたと思うが(というか今も迷惑をかけていると思う)、そこらへんは多少開き直るというか、なんというか。
そういったことをごちゃごちゃと気にするよりも実際の生きているコードを読んだり、書くことのほうが自分にとって大きなプラスになるんじゃないかなー、と思う。

## 卑屈にならない
これは多少精神論よりっぽいけれど、重要なんじゃないかなー、と思う。
30歳でプログラミングを始める、っていうと大抵は同僚よりずいぶんとプログラミング歴に差がある。
自分の年下よりも当然ながら歴が浅かったりする。
だけど、そこで他人と比較して卑屈になったりしてもあんまり意味はなくて、とにかく自分で書ける限りよいコードを書くことのみにフォーカスをするって感じかなあ。

## 謙虚である
これも非常に重要で、わからないことがあったら素直に周りの人に聞く。
もちろん、"教えて君"になるのではなくある程度、自分で調べて、それでもわからなかったら聞くって感じかな。
あとは、コードレビューしてるときとか、他人のコードを読んでいる時に、なんでこういう書き方しているんすか、こういう書き方だと何が良いんすか、とかを聞くとかね。
ただ、そのためには周りの人に聞ける環境に身を置く、ということがすげー重要だと思うし、その環境を探すのにも大変だったりはするんだけど。

## こんな感じです
やっていきます。

次回は@_kobackyが書きますので、お楽しみに。
Swiftはnull安全だけどCocoaはそうじゃない話



swiftはnull安全な言語なので、nullの変数にアクセスしてしまって落ちる・・・ということがないはずなのですがCocoaの内部でnullアクセスしてアプリが落ちることがあります・・・
その罠のひとつを紹介したいと思います。

例えば何かのビューの上にマウスカーソルを持ってきた時、すぐさまポップアップを表示するのではなく少し遅延させて表示したい場合があると思います。（以下の例では１秒遅延）
その場合にダメな例と良い例のサンプルが以下。

```swift:sample.swift
class sampleView: NSView
{
    let popover = NSPopover()

    //ダメな例
    func showPopover_NG() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
            guard let _self = self else { return }
            _self.popover.show(relativeTo: NSRect.zero, of: _self, preferredEdge: .minX)
        }
    }

    //良い例
    func showPopover_OK() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
            guard let _self = self, _self.window != nil else { return }
            _self.popover.show(relativeTo: NSRect.zero, of: _self, preferredEdge: .minX)
        }
    }
}
```

ダメな例がなぜダメか、というと
popover.showが実行されるその瞬間にsampleViewのwindowがnullになっていることがあるからです。
sampleViewのwindowがnullになっていると、popover.showした途端にアプリが落ちます。popover.showは内部的にsampleViewのwindowにアクセスしているようです。

本来的には「sampleViewのwindowがnullであるならshowは無視される」というcocoaフレームワークの挙動になっていれば良いのですがそうはしてくれないのがApple。

ですので、showの前にwindowのnullチェックが必要になります。このnullチェック、何のためにやっているのかあとからソースを見た人がわからなくなるのでやりたくないんですが・・・
【Unity】UnityARImageAnchor 画像トラッキング [ARKit1.5]

<font color="Magenta">２枚の手書き絵の画像をトラッキングしてUnity Chanを表示する。</font>
環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1
⭐️Xcode10.1
⭐️iPhone7(IOS 12.1)

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1068659956012859396

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【Unity ARkit】2枚の手書き絵の画像をトラッキングしてキャラクターを表示する。を勉強したよぉ<br>💕(≧∇≦)💕<br>動作環境<br>Xcode10.1<br>iPhone （iOS12.1）<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Unity3D?src=hash&amp;ref_src=twsrc%5Etfw">#Unity3D</a> <a href="https://twitter.com/hashtag/ARkit?src=hash&amp;ref_src=twsrc%5Etfw">#ARkit</a> <a href="https://twitter.com/hashtag/UnityARImageAnchor?src=hash&amp;ref_src=twsrc%5Etfw">#UnityARImageAnchor</a> <a href="https://t.co/fvvPAhZqPf">pic.twitter.com/fvvPAhZqPf</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1068659956012859396?ref_src=twsrc%5Etfw">2018年12月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

続きは、こちらに記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2018/12/01/094346)
コード内で現在ユニットテスト中か否かを判定する。

# はじめに

現在、アプリとして動いているか、あるいはテスト中かを判定したい事があると思います。ただ、iOSにはそれ用のメソッドが準備されていません。これはマクロを定義する必要があるのか？と嘆く必要ありません。それなりにエレガントな解決方法があります。

# 実際のコード

以下のようにXCTestCaseが存在するか否かを調べる事で判定することができます。

```
   Class testSuite = NSClassFromString(@"XCTestCase");
   return testSuite != nil;
```
ユニットテスト時に専用のAppDelegateクラスにすげ替える。

# はじめに

iOSのユニットテストを行う際、テストターゲットアプリを指定した方が便利です。ただ、プロダクトコードのAppDelegateには大概色々のもの(UI、プッシュ、行動解析ライブラリの初期化やら。。。)がごちゃごちゃ乗っていてユニットテストの阻害要因になりやすいす。

# 解決策

ユニットテスト用のAppDelegateを作って、ユニットテストを実行する際はそれにすげ替えましょう！

# 実際のコード

こんな感じになります。なお、TestableAppDelegateはテストターゲットのみに含めます。

```objc:main.m

int main(int argc, char * argv[])
{
   @autoreleasepool {

        Class appDelegateClass = NSClassFromString(@"TestableAppDelegate");
        if (!appDelegateClass) {
            appDelegateClass = [AppDelegate class];
        }
        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass(appDelegateClass));
    }
}

```

テスト用のAppDelegateはこんな感じですっからかんにします。

```objc:TestableAppDelegate.m

@implementation TestableAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = [UIViewController new];
    [self.window makeKeyAndVisible];
        
    [UIView setAnimationsEnabled:NO];
    
    return YES;
}

@end

```
Dataloaderバッチモード用の暗号化パスワードの生成方法

# 昔のお作法
* encrypt.batを-g でサクっと暗号化できちゃいました

> cd C:\Program Files (x86)\salesforce.com\Data Loader\bin
> encrypt.bat -g hogehogepassword

# 今のお作法
1. 暗号鍵ファイルを吐き出して
2. 鍵を使ってパスワードを暗号化する
っちゅーお作法に変わったようです

> cd C:\Program Files (x86)\salesforce.com\Data Loader\bin
> encrypt.bat -k c:\temp\dataloader.key
> encrypt.bat -e hogehogepassword c:\temp\dataloader.key

# リンク
[英語版ヘルプページ](https://help.salesforce.com/articleView?id=command_line_create_enc_password.htm&type=0)
テスト用の画像をネットワークから読み出さないようにする。

# はじめに

[組織にテストを書く文化を根付かせる戦略と戦術](https://www.slideshare.net/t_wada/test-strategy-and-tactics)にある通り、ユニットテストは最低限、再現性と繰り返し性を追求する必要があります。

サーバー(=ネットワーク)につなぐ処理はそれを阻害する要因なので、スタブやモックを使って断ち切る必要があります。

Rest APIをスタブする方法が色々出回っているのでここで述べません。

一方、テスト画像をスタブするにはどうすれば良いでしょうか？　わざわざスタブを書く？　いえ、画像キャッシュライブラリの機能を使えば書かなくて済みます！

# 実際のコード例

実際のコードはこんな感じになります。SDWebImage限定です。XCTestCaseクラスのSetUpメソッド辺りで呼びましょう。

```swift:

   let cache = SDImageCache.shared()
        cache?.maxCacheSize = 50 * 1024 * 1024
        for name in ["item_1", "item_2", "item_3", "item_4", "item_5", "item_6"] {
            let url = Bundle(for: type(of: self)).url(forResource: name, withExtension: "png")
            let data = try! Data(contentsOf:url!)
            cache?.removeImage(forKey:  "https://hogehoge.com/" + name)
            cache?.store(UIImage(data: data), forKey:  "https://hogehoge.com/" + name)
        }

```
CloudWatchイベントのGlue関連対応

## クローラーとジョブが対応

これで最低限捉えたいGlueの状態は拾えるかと思います。

(2019/01/11)ころ？アップデートがあり、"Glue Data Catalog Database State Change"と"Glue Data Catalog Table State Change"が追加されました。

<img width="725" alt="スクリーンショット 0031-01-27 16.50.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/ad10cbe5-1805-a06f-fbf1-45fabe7a2cad.png">

#### Glue Crawler State Change

Glue クローラーが、StartingやStopping,Readyは拾えなく、Failed，Started,Succeededと確定したステータスのようです。

公式には以下のステータスはこの種類あるようです(20181201現在)
CWイベントのとちょっと違いますね^^;

>State - UTF-8 文字列 (有効な値: READY | RUNNING | STOPPING)。
>クローラが実行中かどうか、または実行が保留中かどうかを示します

https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-api-crawler-crawling.html#aws-glue-api-crawler-crawling-StartCrawler

<img width="725" alt="スクリーンショット 0030-12-01 9.07.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/26d8843d-2de6-1e18-9f75-a6eefb011723.png">

#### Glue Job Run Status

現在のジョブ実行の状態。こちらは進行形のステータスがとれるようです。
RUNNING,STARTING,STOPPING

公式には以下のステータスはこの種類あるようです(20181201現在)
>JobRunState - UTF-8 文字列 (有効な値: STARTING | RUNNING | STOPPING | >STOPPED | SUCCEEDED | FAILED | TIMEOUT)。

https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-api-jobs-runs.html

<img width="742" alt="スクリーンショット 0030-12-01 9.07.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/4881add7-62c4-a9a9-2d52-566f7ae81c56.png">

#### Glue Job State Change

"detail-type"： "Glue Job State Change"のイベントは、SUCCEEDED、FAILED、TIMEOUT、およびSTOPPEDに対して生成されます。

#### Glue Data Catalog Database State Change

"detail-type"： "Glue Data Catalog Database State Change"のイベントは、CreateDatabase、DeleteDatabase、CreateTable、DeleteTable、およびBatchDeleteTableに対して生成されます。

#### Glue Data Catalog Table State Change

"detail-type"："Glue Data Catalog Table State Change"のイベントは、UpdateTable, CreatePartition, BatchCreatePartition, DeletePartition and BatchDeletePartitionに対して生成されます

## 参考
Glue with CloudWatch Events
https://docs.aws.amazon.com/glue/latest/dg/automating-awsglue-with-cloudwatch-events.html

Glueの使い方まとめ
https://qiita.com/pioho07/items/32f76a16cbf49f9f712f
CircleCIで別のPrivate RepositoryをCloneしようとするとAre you sure you want to continue connecting yes/no?

## 何が起こったのか?

CircleCIで別のPrivate RepositoryをCloneしようとすると `Are you sure you want to continue connecting yes/no?` とでて実行がストップしてしまっていました.

## どうやって解決したのか?
- [Git clone fails in Circle 2.0](https://discuss.circleci.com/t/git-clone-fails-in-circle-2-0/15211/10)

上記のForumにある `mkdir ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config` を実行し、SSHの初回ログインの警告を出さないようにしたら解決しました.

## 他に試したこと
- [Are you sure you want to continue connecting yes/no?](https://support.circleci.com/hc/en-us/articles/115015628247-Are-you-sure-you-want-to-continue-connecting-yes-no-)

CircleCIのヘルプページには `add_ssh_keys` を使えと書いてあるのですが,私の環境では `add_ssh_keys`でフィンガープリントを指定してもうまく動きませんでした.
非同期通知が来ない事を確認するテストを行う

# はじめに

iOSのユニットテストフレームワークには通知、KVOといった非同期処理のテストを書くメソッドが準備されています。
ただ、非同期のトリガーそのものが発火しない事を確認するためのテストを書きたい事があるかと思います。

その時は以下のコードを書く事で実現することができます。

# 実際のコード例

```swift:

        let expectation = XCTNSNotificationExpectation(name:HogehogeNotification)
        
        テストコード
        ...
        
        // 通知が来ない事をテストにするはisInvertedをtrueにセットする。
        expectation.isInverted = true
        // タイムアウトすればテストが成功
        wait(for: [expectation], timeout: 0.01)

```
FBSnapshotTestCaseとKIFを共存させて、UI操作→画面の表示のユニットテストを実現する。

# はじめに

UIのユニットテスト（≠UIテスト)でテストコードを書く場合、以下のフローで書きたいでしょう。

UI操作→表示された画面の検証

で調べてた所、単体でうまくやってくれるやり方、ライブラリがわかりませんでした。

この問題はKIFとFBSnapshotTestCaseを共存させる事によって解決することができます。

# 実際のコード例

以下の関数を定義します(出典：https://blog.karumi.com/ui-testing-for-ios/)。

```swift:

func tester(file: String = #file, _ line: Int = #line) -> KIFUITestActor {
    return KIFUITestActor(inFile: file, atLine: line, delegate: nil)
}

```

FBSnapshotTestCaseのサブクラスで以下のように呼び出すことができます。

```swift:

   // UI操作
   tester().tapView(withAccessibilityIdentifier:"閉じるボタン")

   ...

   // 画面の検証
   FBSnapshotVerifyView(view)

```