OmniAICreator/Qiita-1.07M huggingface dataset:
return new Promise()とreturn Promise.resolve()使い分け

## 伝えたいこと

javascriptを触っていて嫌でも触らないといけないPromiseオブジェクトの返し方で`return new Promise()`と`return Promise.resolve()`の使い分け方法。
結論から言うと再帰関数を使用する際に明確な違いが生まれる。
以下コードと少し解説です。

### return Promise.resolve()

```javascript
const correct = 1

const generateRand = (digit) => {
  return Math.floor(Math.random() * digit)
}

const getCorrect = () => {
  return new Promise(resolve => {
    const delayTime = generateRand(1000)
    console.log(`delayTime: ${delayTime}ms`)
    setTimeout(() => {
      return resolve(correct)
    }, delayTime)
  })
}

const findCorrect = (findVal, counter) => {
  return getCorrect().then(correct => {
    if (findVal !== correct) {
      return findCorrect(generateRand(10), counter + 1)
    }
    return Promise.resolve({correct: findVal, counter: counter})
  })
}

findCorrect(generateRand(10), 0).then(correctItem => {
  console.log(correctItem.correct)
  console.log(`${correctItem.counter + 1}回処理されました。`)
})
```

```:result
delayTime: 66ms
delayTime: 176ms
delayTime: 998ms
delayTime: 283ms
delayTime: 816ms
delayTime: 735ms
delayTime: 397ms
delayTime: 501ms
delayTime: 908ms
delayTime: 549ms
delayTime: 12ms
delayTime: 833ms
delayTime: 698ms
delayTime: 378ms
delayTime: 616ms
delayTime: 935ms
1
16回処理されました。
```

コードの説明をすると正解の数字1があり、ランダム生成した値と一致するまで再帰処理を行うというプログラムです。(catch、rejectはコード省略化のため書いていません)

`getCorrect`関数が正解の数字を返してくれます。が、非同期処理です。
はいはいPromisePromise。
`getCorrect`関数がPromiseオブジェクトを返すということに伴って`findCorrect`関数も必然的にPromiseを返さないといけません。
処理的には`findCorrect`関数が正解の数字と一致するまで再帰呼び出しを行うのみですね。
無事resultでも正解の数字と何回再帰処理が行われたのかが出力されていますね。

ところが・・・

### return new Promise()

```javascript
const correct = 1

const generateRand = (digit) => {
  return Math.floor(Math.random() * digit)
}

const getCorrect = () => {
  return new Promise(resolve => {
    const delayTime = generateRand(1000)
    console.log(`delayTime: ${delayTime}ms`)
    setTimeout(() => {
      return resolve(correct)
    }, delayTime)
  })
}

const findCorrect = (findVal, counter) => {
  return new Promise(resolve => {
    return getCorrect().then(correct => {
      if (findVal !== correct) {
        return findCorrect(generateRand(10), counter + 1)
      }
      return resolve({correct: findVal, counter: counter})
    })
  })
}

findCorrect(generateRand(10), 0).then(correctItem => {
  console.log(correctItem.correct)
  console.log(`${correctItem.counter + 1}回処理されました。`)
})
```
```:result
delayTime: 148ms
delayTime: 788ms
delayTime: 563ms
delayTime: 908ms
delayTime: 962ms
delayTime: 429ms
delayTime: 934ms
delayTime: 306ms
delayTime: 178ms
delayTime: 555ms
delayTime: 978ms
delayTime: 572ms
delayTime: 822ms
delayTime: 429ms
delayTime: 16ms
delayTime: 291ms
delayTime: 20ms
delayTime: 272ms
```

`return Promise.resolve()`との違いは`findCorrect`関数の戻り値が`return new Promise()`になっていることですね。
`return new Promise()`の場合、遅延時間のみが出力されて`resolve()`の値が返る前に処理が終了しています。
再帰呼び出しの際に毎回新しいPromiseオブジェクトを作成しているから当たり前といえば当たり前なのですが、今まで意識せずに`return new Promise()`で書いていたため、ハマってしまいました。

## 教訓

Promiseオブジェクトを用いた処理で再起呼び出しを行う場合は`Promise.resolve()`、`Promise.reject()`を使うこと。
Qiitaの記事をバックアップしてみたい(C#)

#きっかけ
Qiitaは便利だから色々投稿してるけど、これが消えたらショックだよなぁ...というのがきっかけ。
「QiitaAPI」を使えば、最低限自分のローカルに記事をバックアップしておくことはできそうだったので、
色々他の方の記事も参考にしながらツールを作ってみることにした（C#）。

#アクセストークンを使った認証
アクセストークンをAuthorizationリクエストヘッダに含めることで、認証を行うことができる。
[Qiita API v2ドキュメント「認証認可」](https://qiita.com/api/v2/docs#%E8%AA%8D%E8%A8%BC%E8%AA%8D%E5%8F%AF)
アクセストークンは、自分のアカウントの設定画面から発行できる。

#使用するAPI
##自分の記事一覧を取得する
[Qiita API v2ドキュメント「/api/v2/authenticated_user/items」](https://qiita.com/api/v2/docs#get-apiv2authenticated_useritems)

##記事を取得するコード
JSON形式でレスポンスが返ってくる。

```ruby:コード
public static List<QiitaArticleModel> Execute()
{
    var wc = new WebClient();
    wc.QueryString = new NameValueCollection
    {
        ["page"] = "1",
        ["per_page"] = "20",
    };
    wc.Headers.Add("Authorization", "Bearer " + Constants.QIITA_TOKEN);
    var result = wc.DownloadString(Constants.QIITA_REQUEST_URL_AUTHENTICATED_USER_ITEMS);

    var articleList = JsonConvert.DeserializeObject<List<QiitaArticleModel>>(result);
    return articleList;
}

```

##JSON形式のレスポンスをデシリアライズする
###モデルクラスを作成
とりあえずTitleとBodyがあればいいかな、と。

```ruby:QiitaArticleModel.cs
    public class QiitaArticleModel
    {
        [JsonProperty("title")]
        public string Title { get; set; }
        [JsonProperty("rendered_body")]
        public string RenderedBody { get; set; }
    }
```

JsonProperty属性を使えば、プロパティ名と異なるキー名をつけることができる。
（レスポンスに含まれるキー名と異なるプロパティ名にしたいことは多々あるから）

###実際にデシリアライズ

```ruby:デシリアライズ処理
var articleList = JsonConvert.DeserializeObject<List<QiitaArticleModel>>(result);
```

##取得した記事をファイル出力
デシリアライズで生成したモデルクラスのリストを、1件ずつ処理してHTMLファイルに出力。
ファイル名に「記事タイトル」、中身はもちろん記事の内容（HTML）。

```ruby:ファイル出力処理
public static void FileExport(QiitaArticleModel article)
{
    var outputFileName = string.Format("{0}.html", article.Title);
    var encoding = Encoding.GetEncoding("utf-8");
    using (var writer = new StreamWriter(Constants.FILE_OUTPUT_DIRECTORY + outputFileName, true, encoding))
    {
        writer.WriteLine(article.RenderedBody);
        writer.Close();
    }
}
```

#参考
[C#でJSONの読み書き～Json.NETを使ってみる～](http://sourcechord.hatenablog.com/entry/2015/06/08/173805)
[C#でJSONを扱うライブラリ「Json.NET」を使ってみました](https://qiita.com/ta-yamaoka/items/a7ff1d9651310ade4e76)

#開発状況
2018/4/11：
とりあえず「自分の記事を全部取得する」ところまで。
次はファイルに保存する処理を追加する。
2018/4/21：
JSONで返ってきたレスポンスを、デシリアライズするところを作ってみた。
「HTML形式の本文」を取得しているため、今度はHTMLファイルに出力するところを作ってみる。
2018/4/25：
いったんQiitaに投稿した記事を取得して、ファイル出力するまでの処理はできた。
今後改良したい箇所としては、「HttpClient」を使った実装にしてみるところか...
でもやっぱりfor文は使っていいと思うよ

親記事：[なぜfor文は禁止なのか？ポエム版 \- Qiita](https://qiita.com/miyabisun/items/8e52b7ba6ef38028f1c4)

だって遅いんだもん

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/fda5a730-7c07-da10-5a6f-e8760edd2e8a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/ba53d79a-221e-08ae-f718-2bc0259e1569.png)

http://jsben.ch/BimhK

もしくは https://jsbench.me/
TVBoxにArmbian

少し前に購入したAndroidのTVBoxにArmbianをインストール

1. TVBox　

　インストールしたのはMXQ Pro 4KというTVBox
![MXQ.jpg](https://qiita-image-store.s3.amazonaws.com/0/249443/5707c67a-92a8-580b-c7ad-326723822325.jpeg)
スペックはAmlogic S905W（Cortex-A53 1.5GHz）,RAM1GB,　HDMI,　USBx4
ただし、同じ機種名でもandroidのバージョンが違う、CPUが違う、Wifiチップが違うなどのバリエーションがあるようで、正確にどんなものが来るのか定かでは無いもよう。
＊セール価格なので普段はこれほど安くない


2.インストール手順

　機種は違うが、大筋は[ここ](https://blog.pyyoshi.com/2017/02/22/x96-tv-boxniarmbiannaubuntu-16-04woru-reru/)に説明されている通り。
より詳細には[開発元のサイト](https://forum.armbian.com/topic/2419-armbian-for-amlogic-s905-and-s905x/)を参照のこと。

イメージは「Armbian_5.41_S9xxx_Ubuntu_xenial_3.14.29_mate_20180307」を使った。
dtb.imgは「gxl_p231_1g.dtb」だったと思う。

3.問題点
　フォーラムで良く出てくる話がWLANなのだが、やっぱりWLANが動作しない。それ以外は有線LANを含めて問題無い。WLANチップはSV6051Pで、ドライバー、ファームウェアは入っているみたいだが、WLANのポートのアクセス時にエラーとなっている。ひととおり用意されているdtb.imgは試したので、適切なdtb.imgがまだないと思われる。

4.おすすめ?
 ラズパイなどとの大きな差はGPIOが無いという点。GPIOを使わない用途ならばコスパは最高クラス。
ラズパイで使用済みSDカードをMacでフォーマットする

MacのターミナルからコマンドでSDカードをフォーマットします

# 前提
- 今回のSDカードは16GB
- 前のラズパイデータが残っている
- MacにSDカードを指した状態

# SDカードを確認する

以下コマンドでディスクの一覧が出てくる

```
$ diskutil list
```

/dev/disk0とdisk1はNAMEが`Macintosh HD`とあるので消しちゃダメ
（これはMacが使用しているdiskなので触ってはいけない）

/dev/disk2がsdカードですね

```
/dev/disk0 (internal):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                         500.3 GB   disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:          Apple_CoreStorage Macintosh HD            499.3 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3

/dev/disk1 (internal, virtual):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           +499.0 GB   disk1
                                 Logical Volume on disk0s2
                                 285B76A3-2DE8-4866-AAC1-DE638EF94BA0
                                 Unlocked Encrypted

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.6 GB    disk2
   1:               Windows_NTFS RECOVERY                1.5 GB     disk2s1
   2:                      Linux                         33.6 MB    disk2s5
   3:               Windows_NTFS boot                    72.4 MB    disk2s6
   4:                      Linux                         14.0 GB    disk2s7
```

# フォーマットする (FAT32 - MS-DOSの場合)

### コマンド

```
$ diskutil eraseDisk MS-DOS RPI disk2
```

`diskutil eraseDisk` フォーマット形式 削除後のパーティション名 フォーマット対象ディスク

### ログ

```
tarted erase on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s2 as MS-DOS (FAT) with name RPI
512 bytes per physical sector
/dev/rdisk2s2: 29932976 sectors in 1870811 FAT32 clusters (8192 bytes/cluster)
bps=512 spc=16 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=29962240 bspf=14616 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2
```

Finished とあるので完了したようです。

ディスクユーティリティで確認すると無事にフォーマットできてました。

<img width="932" alt="スクリーンショット 2018-04-11 17.15.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/5b37c8fe-ef60-ff04-add9-bb4caacb11e3.png">

# オマケ - 64GBのSDカードをフォーマットする (exFAT)
フォーマット形式が MS-DOS だと64GB以上の容量を扱えません

参考：Mac の SD および SDXC カードスロットについて
https://support.apple.com/ja-jp/HT204384

SDカードが64G以上の場合、フォーマット形式を`exFAT`に指定する必要があります。

コマンドは以下です。

```
diskutil eraseDisk exFAT RPI /dev/disk2
```

MS-DOS を exFAT に置き換えるだけですね。

これで空きが64GBと認識されるようになります。
システム開発における生産性ってなんだ？





初めての投稿が愚痴っぽくなってしまいました。
でも我慢できなかったので


### 生産性について考えた理由
---
昨今の働き方改革の推進により、自分の所属する企業で生産性の計測が始まったが、その方法に疑問を持った為、調べてみました。


### 結論から言うと・・・。
---
自分の調査ではシステム開発における生産性の適切な評価方法を見つけることができませんでした。
皆様のお知恵を拝借させていただきたいです。

### 私の会社の生産性の計測方法
---
一時間でアウトプットできた成果物の量を計測してるようです。
一週間ごとに集計し、前週と比較して「先週よりも下がってるぞ！」
とお叱りを受けます

ここでいう成果物とは

1. 設計書等のドキュメント
1. プログラムのステップ数

になります。

例を書くほどでもないと思いますが

* Aさん→1時間に100ステップを書きました
* Bさん→1時間に200ステップを書きました

つまりこの計測の評価ではBさんはAさんの2倍仕事をしたということになります。

**本当にそうでしょうか？**

私が疑問に思ったのは以下の2点です。

1. 大量のコードを書くこと＝生産性が高い？
1. 機能の難易度が考慮されていない

という点です。

### 1.大量のコードを書くこと＝生産性が高い？
---
私の会社の計測の仕方では一時間当たりに書くコードの量が多ければ多いほど、生産性が高いという評価になります。

沢山コードが書けるというのは評価すべきだと思いますが、
少ないステップ数で同じ処理を実装した場合評価が低くなってしまいます。

沢山コードが書けることと同じぐらい、最低限の処理数でコードが書けること[^1]も重要であると個人的には思っております。
[^1]: 可読性を低めない範囲で



また極端な話になってしまいますが、バグが存在しているようなダメなコードを大量にコーディングした場合でも、生産性は高くなってしまいますよね。

### 2.機能の難易度が考慮されていない
---
ステップ数だけで評価しようとすると、
同じ100ステップの機能でも実装難易度が違うのに、同じ評価になってしまいますよね。

このように、ステップ数や成果物の量だけで生産性を計測しようとするのは平等とは思えないのです。

### ではなにで生産性を評価するのがいいのか？
これだ！というものを見つけることができませんでした。
ここまで読んでくださったかた申し訳ございません。


### 大事なのは計測の仕方ではなくその理由
---
生産性を計測する目的をはっきりさせることが重要だと感じました。

生産性を上げて、一つのプロジェクトの開始から完了までの期間を短くするという目的ならば、

日々の成果物で生産性を計測するのではなく、テスト作業やデプロイ作業の自動化を推進するほうが効果が計測しやすいのでは？という結論に至りました。
PDFの技術書をKindleで快適に読む

#はじめに
オンラインで入手した技術書や論文のPDFをKindleで読みたいということがあると思います。
その際、PDFファイルをそのままKindleで開くと、PDFファイルに対してKindleのスクリーンが小さく拡大やフレームの移動などが大変で諦めてしまった人もいる様です。

[公式サイト]
(https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201974220)に書かれている通りですが、躓きやすい点や気づきにくい点がありましたので、共有します。

#PDFファイルをKindleで快適に読むための方法

- [コンテンツと端末管理](https://www.amazon.co.jp/mn/dcw/myx.html#/home/content/booksAll/dateDsc/)
にアクセス
- 設定タブをクリックし、パーソナル・ドキュメント設定の項目まで下にスクロールし、パーソナル・ドキュメント設定を開く
- Send-to-Kindle Eメール設定の下に、Kindle端末のEメールアドレスが表示されるので、このアドレスに、Kindleで読みたいPDFファイルを添付し**Eメールの件名に「変換」**を入力し送信する。
- しばらくすると、Kindleでダウンロードできる様になる

ポイントは、Eメールの件名に「変換」と入力することです。これにより、PDFファイルをKindleに適したファイルに変換してくれます。文字の拡大などまさにKindle本同様スムーズで、PDFファイルをそのまま読むときの煩わしさから解放されます!!

#送信時の注意点
Send-to-Kindle Eメールアドレスの設定の下の承認済みEメールアドレス一覧に表示されていないアドレスからは送っても、Kindle端末で受信できません。特にポップアップなども表示されないので注意してください。承認済みEメールアドレスは自由に追加することができます。

#その他

技術書や論文のpdfファイル容量が大きいと、そもそもメールに添付できなかったり、送信に時間がかかります。
pdf圧縮ソフトを利用すると良いと思います。
オンラインの圧縮サービスなどは時間がかかるので、ダウンロードして使うタイプがおすすめです。
https://pdf.wondershare.jp/

快適なKindleライフをお送りください!!
Redux で複数の非同期通信を捌く方法

SPA を作っていると複数の API に同時に接続して、通信を待って何かをする、というケースが頻繁にあります。そういった場合、Redux ではどうするのか考えてみました。

こういった場合、ミドルウェアには [redux-saga](https://github.com/redux-saga) を使うのが定石かもしれませんが、あの独特の記法がどうも好きになれないのと、処理が分散してコードが追いにくくて苦手なので、今回は [redux-thunk](https://github.com/gaearon/redux-thunk) の利用で検討してみます。

サンプルのソースはこちら。
https://github.com/ANTON072/redux-multiple-ajax-sample

デモ
https://anton072.github.io/redux-multiple-ajax-sample/

View と Reducer は特に変わったことはやっていません。
https://github.com/ANTON072/redux-multiple-ajax-sample/blob/master/src/App.js

https://github.com/ANTON072/redux-multiple-ajax-sample/blob/master/src/index.js#L18

```js
const github = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.FETCH_EXAMPLE_REQUEST:
      return { ...state, loading: true };
    case ActionTypes.FETCH_EXAMPLE_FAILURE:
      return { ...state, loading: false };
    case ActionTypes.FETCH_EXAMPLE_SUCCESS:
      return { ...state, ...action.payload, loading: false };
    default:
      return state;
  }
};
```

工夫のポイントは Action Creator です。

まず Action ですが、通信まわりは REQUEST / FAILURE / SUCCESS とステータスに応じて suffix を付けておきます。今回のネタには直接関係ないですが、suffix に定型句を付けておくと、ミドルウェアでの加工も簡単にできるので何かと便利です。視認性もいい。

```js
export const FETCH_EXAMPLE_REQUEST = 'FETCH_EXAMPLE_REQUEST';
export const FETCH_EXAMPLE_FAILURE = 'FETCH_EXAMPLE_FAILURE';
export const FETCH_EXAMPLE_SUCCESS = 'FETCH_EXAMPLE_SUCCESS';

const AJAX_A_REQUEST = 'AJAX_A_REQUEST';
const AJAX_A_FAILURE = 'AJAX_A_FAILURE';
const AJAX_A_SUCCESS = 'AJAX_A_SUCCESS';

const AJAX_B_REQUEST = 'AJAX_B_REQUEST';
const AJAX_B_FAILURE = 'AJAX_B_FAILURE';
const AJAX_B_SUCCESS = 'AJAX_B_SUCCESS';
```

各 API を叩く Action Creator を定義します。redux-thunk を使っているので、Promise で返すことができます。

```js
export function ajaxA() {
  return function(dispatch) {
    dispatch({ type: AJAX_A_REQUEST });
    return fetch('https://api.github.com/')
      .then(response => response.json())
      .then(
        json => dispatch({ type: AJAX_A_SUCCESS, payload: json }),
        err => dispatch({ type: AJAX_A_FAILURE, payload: err })
      );
  };
}

export function ajaxB() {
  return function(dispatch) {
    dispatch({ type: AJAX_B_REQUEST });
    return fetch('https://api.github.com/users/anton072')
      .then(response => response.json())
      .then(
        json => dispatch({ type: AJAX_B_SUCCESS, payload: json }),
        err => dispatch({ type: AJAX_B_FAILURE, payload: err })
      );
  };
}
```

ajaxA と ajaxB をバンドルする Action Creator を定義します。

```js
export function exampleAjax() {
  return function(dispatch) {
    dispatch({ type: FETCH_EXAMPLE_REQUEST });
    return Promise.all([dispatch(ajaxA()), dispatch(ajaxB())])
      .then(responces => {
        dispatch({
          type: FETCH_EXAMPLE_SUCCESS,
          payload: {
            apis: responces[0].payload,
            user: responces[1].payload
          }
        });
      })
      .catch(err => {
        dispatch({
          type: FETCH_EXAMPLE_FAILURE,
          payload: err
        });
      });
  };
}
```

View からはこのバンドルされた関数を実行すれば、複数の非同期通信をまとめて実行することができます。

async / await を使うともうちょいオシャレな書き方もできるんですかね。
git commit時にhint: Waiting for your editor to close the file... mvim -f: mvim: command not found

git commitを行った際に下記エラーが発生。

```
hint: Waiting for your editor to close the file... mvim -f: mvim: command not found
error: There was a problem with the editor 'mvim -f'.
Please supply the message using either -m or -F option.
```

Gitがエディターを使おうとして`mvim`なんてコマンドないっすと言われている。

# 解決方法
.gitconfigの設定を修正することで解決。

## 手順
```
# .gitconfigの内容を確認
$ less ~/.gitconfig
[core]
	excludesfile = /hogehoge/.gitignore_global
	editor = mvim ←こんな設定があるはず
	autocrlf = input
〜以下略〜

# 設定変更
$ git config --global core.editor vi

# .gitconfigが変更されていることを確認
$ less ~/.gitconfig 
```
ServiceNowのテストフレームワークでSeleniumのような画面のテストの自動化をする

# Automated Test Framework

画面を開く、値を設定する、サブミットするという一連の動作を実施し、その画面キャプチャーをを自動で取得する一連の流れを１つのテストケースとして作成することが可能。

## テスト作成

テストの作成はStudioではなく通常のServiceNowブラウザーから行う。
Navigatorメニューの、「Automated Test Framework」の「Tests」を選択する。

![testslist.png](https://qiita-image-store.s3.amazonaws.com/0/197947/21688fd1-b833-06c6-7a37-227c764c3e2a.png)

「New」をクリックし、新しいテストケースを作成する。

![settingtestcase.png](https://qiita-image-store.s3.amazonaws.com/0/197947/956c2049-3739-4e29-b4a7-2ff0bea2262e.png)

Nameにテストケース名
Descriptionにテストの説明を入力する。

## テストステップの追加

「Add Test Step」によりこのテストケースで実施する動作、検証を追加していく。
今回は下記を追加する。
1.「NeedItのフォームを開く」（NeedItテーブルのデフォルトビューを開く）
2.フォームのRequested for Email、Other（値=TEST0001)、WhenNeededを入力する。
3.フォームをサブミットする。
4.NeedItテーブルを検索し、Other=test0001の検索結果があることを検証する。


![1.OpenNewForm.png](https://qiita-image-store.s3.amazonaws.com/0/197947/3b70342d-9ad5-5073-a149-0bd309565adc.png)

![2.SetFieldValue.png](https://qiita-image-store.s3.amazonaws.com/0/197947/21c4b7a2-a19b-aa47-64b2-bfa8d7c65d42.png)

![3.SubmitForm.png](https://qiita-image-store.s3.amazonaws.com/0/197947/de4b4c0a-aa51-ad7a-8eaf-fab058e71605.png)

![4.ValidateQuery.png](https://qiita-image-store.s3.amazonaws.com/0/197947/2ab9e6c8-4c86-014c-10d9-e4abc9e3635e.png)

それぞれタイトルの「Open a new Form」などをAdd Test Stepクリッック後に表示される画面のFormカテゴリ、Serverカテゴリーなどから見つけて選択して作成する。

## 実行

設定が出来れば、テスト設定画面の「Run Test」をクリックする。
テストを起動すると別ブラウザーまたは別タブでテストが実行されている様子がわかる。
画面上に自動的にフォームが起動されて入力される様子が表示される。

![runningtest.png](https://qiita-image-store.s3.amazonaws.com/0/197947/8228a84e-9ca1-0cf7-66a7-f9ac9fa5e731.png)


テストが完了したら、元のテスト設定画面の上に下記の画面が表示されているので、
「Go to Result」でテスト結果の画面を表示させる。

![testResutlConfirm.png](https://qiita-image-store.s3.amazonaws.com/0/197947/b6c3a1e0-df54-ccf1-e34e-1f3a780a42e5.png)


テスト結果画面の上部にはそれぞれのステップで取得した画面キャプチャーが添付されている。下部のStep Resultにはステップごとの成功、失敗が表示されている。

![testresult_head.png](https://qiita-image-store.s3.amazonaws.com/0/197947/c962c803-f7f2-f049-6bda-64a362f044c2.png)

Test Results画面の下の方で確認すると。

![testresult_step.png](https://qiita-image-store.s3.amazonaws.com/0/197947/cdd6344f-e1e1-6ca4-bd41-7fef7884ada7.png)


# 最後に

submit時に入力エラーが発生することの確認は、Submit a formのAsseertion Typeの設定によりテスト可能だが、その時に画面に表示されるエラーメッセージの確認は自動的には出来ないようだ。自動取得されている画面キャプチャーを見て確認ということになるだろう。

また、今回はテストケースを１つ作成したが複数のテストケースをまとめてテストスイーツとしえて１連のテストを一括で流す方法もあるようだ。
GMOクラウドVPSに他社管理のドメインを割り当てる

# 手順
手順というほどのものではありませんが、一応。
1. ドメイン管理システムからDNSサーバーの設定を行う
2. 必要であれば各レコードの設定を行う

## 1. DNSサーバーの設定を行う
DNSサーバーの設定はドメイン管理側のシステム（お名前.comなど）で行う必要があります。
GMOクラウドの場合、DNSサーバー名は下記の通りですので
ドメイン管理システムのログイン画面から割り当てたいドメインの設定画面を開き、ネームサーバーを下記のように設定します。

|DNSサーバー名(GMOクラウド)||
|:--|:--|
| プライマリDNSサーバー | ns.namedserver.net |
| セカンダリDNSサーバー | ns2.namedserver.net |

写真はお名前.comの設定画面です。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/108017/ed063c04-e49f-f194-6d96-c785b396c6ad.png)

## 2. 必要であればDNSの設定を行う
もし、サブドメインを作成するなど、各種レコードの設定が必要であれば、
ドメイン管理システムの画面からレコードの設定を行います。
IntelliJ: ScalaプロジェクトをインポートするとResolve Errorが発生



# 環境
* IntelliJ IDEA 2018.1
* Scala 2.12



# 問題
GitからクローンしたScalaプロジェクト（`.idea`フォルダはない）をIntelliJで開くと、Resolve Errorが発生しました。

![IntellJIDEA_ResolveError.PNG](https://qiita-image-store.s3.amazonaws.com/0/37903/495693a5-94c6-71b0-b82a-753e32199065.png)

>java.lang.NullPointerException at scala.collection.mutable.ArrayOps$....

# 解決
JREのパスを正しい値に変更したら、解決しました。

Import Project from sbt → Grobal sb settings領域 → JVM領域 → JREテキストボックス

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/6702548f-f9e2-d204-d5d0-48b746b6da16.png)
独自証明書のインストールが許可されていないAndroid端末で、アプリデバッグ時にCharlesによるHTTPSトラフィック解析をする方法


# アプリのデバッグ時にCharlesでHTTPSトラフィックを解析したいけど証明書が入れられない問題

Androidアプリを作る上で、[Charles](https://www.charlesproxy.com/)によるHTTPSのトラフィック解析には大いに助けられていると思います。

さて、CharlesでHTTPSトラフィックを解析するためにはCharlesが発行した独自証明書をAndroidの証明書ストアに登録する必要がありますが、一部のAndroid端末（たとえば一部のAndroidTVなど）では証明書ストアへの独自証明書のインストールを許可していないものもあります。

Android 7.0以降限定の手法とはなりますが、そのようなAndroid端末でもアプリデバッグ時にCharlesでHTTPSを解析できるようにする方法を見つけたので記します。


# 手法の概要

[Android 7.0からネットワークセキュリティーの仕様が変わり、マニフェストで明示的にトラストストアを指定するようになりました。](https://developer.android.com/training/articles/security-config.html?hl=ja)

この機能を活用して、『デバッグ版アプリ内にRAWリソースとして埋め込んだCharlesが発行した独自証明書を信頼する』という設定を入れることで、デバッグ時だけCharlesでHTTPSトラフィックを閲覧できます。


# 具体的な手法

## (1) Charlesの証明書をデバッグ時にだけアプリに埋め込む

まず、Build Variantsを利用し、デバッグビルド版アプリのリソース内にだけCharlesの証明書を埋め込みます。

Charlesを立ち上げ、メニューから[Help]>[SSL Proxying]>[Save Charles Root Certificate]と選び、Charlesの証明書(PEM形式)を任意の場所に保存しておきます。

次に、Android Studio内の次のようなパスにそのPEMファイルを設置することで、RawリソースとしてDebugビルドにのみ埋め込みます。
*※Rawリソースにはファイル名の制限があるので、先の手順で保存したPEMファイルの拡張子などを取っ払って「charles_ca_pem」という名前にし、rawディレクトリ内に移動するだけです。*

debug/res/raw/charles_ca_pem
![charles_embeded_cert.png](https://qiita-image-store.s3.amazonaws.com/0/10682/a2c57fd3-d69e-39e3-87fb-7a5a01fe2828.png)



## (2) 埋め込んだ証明書をデバッグ時に参照し信頼する設定を入れる

`<network-security-config>`の[`<debug-overrides>`](https://developer.android.com/training/articles/security-config.html?hl=ja#TrustingDebugCa)を利用することで、デバッグ時のみ埋め込んだ独自証明書を参照＆信頼するという設定が行えます。
この設定はデバッグ時のみ有効で、かつ、Playストアにはデバッグ可能なアプリは公開できないので、本番リリース版アプリで意図せずCharlesでHTTPSトラフィックが覗けてしまうという事態を防ぐことができます。

debugなBuild Variantsで次のように書くと、RAWリソース内の証明書を参照しそれを信頼する証明書としてトラストアンカーに追加することができます。

debug/res/xml/network_security_config.xml:

```xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/charles_ca_pem"/>
        </trust-anchors>
    </debug-overrides>
</network-security-config>
```

ストア公開版のmainバリアントの方のnetwork_security_configはとりあえず空で作っておきます。
main/res/xml/network_security_config.xml:

```xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
</network-security-config>
```

あとは、これらnetwork_security_config.xmlをAndroidManifest.xmlから参照することで、証明書信頼設定がこのアプリで有効になります。

```xml
<application
    android:name=".MyApp"
    android:networkSecurityConfig="@xml/network_security_config"
    >
    ...
</application>

```

アプリ側での準備はこれだけです。

あとはAndroidのプロキシ設定画面でCharlesを利用するようにすれば、CharlesでアプリのHTTPSトラフィックが見えるようになっていると思います。
2点見積もりと作業バッファの計算方法「SRSS法」のイメージ

タスクの工数を見積もる際に、タスク自体が確定していないから、見積もりにくいことがあります。

こういう時、その不確定さも含めて見積もってしまい、作業バッファとして積むという技があります。(勝手に2点見積もりと呼んでいます)
少しまとめておきます。

> ちなみに、見積もりの単位はストーリーポイントでも人日でも関係なく使える話です。

## 平均時間と最悪時間

勘でタスクごとに2つの見積もり数字を出します。

1. 「平均的に終わらせるとしたら」の時間
2. 「ハマったりして時間がかかったとしたら」の時間


なお、(2)は「明日、地球に隕石が落下して世界が滅びたらどうしよう」みたいな、常識的に考えると起こり得ないことまでは考慮しません。想定できる範囲で、「悪いことが重なったらどうしよう」と考えてください。

イメージとして、50%と90%を念頭においてください。

1. 50% ぐらい、もしかしたらオーバーするかも
2. 90% まあ確実に終わるだろう



## 作業バッファを積みすぎる問題

不確実なので、作業バッファを考えなければいけません。

ここで、タスクは複数あり、並列ではなく直列にやっていくものとします。
例えば作業者が1人しかいないとか、タスクに依存関係があって前のタスクが終わらないと次のタスクが出来ない、みたいなイメージです。

単純なのは、(2)の90%見積もりを全部足してしまうことですが…

最悪5のタスクが3つで合計15。これは妥当でしょうか？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1126/c2c4b27d-af44-c8cb-2424-56ac7bb0064e.png)


仮に、50% - 90%の見積もりが正しいとしましょう。(正しいと信じて勘で出しているはずです)
そうすると、確率的に50%見積もりの通りに終わるタスクもきっとあるでしょう。その分のバッファは必要ないはずです。

15は悲観的すぎな気がしますね。

そこで妥当なバッファを計算するやり方に、SRSS法というものがあります。

## SRSS法 (対角線の長さを使う)

`Square Root of Sum of Squares`、直訳すると `二乗和平方根`で、計算方法をそのまま書いた名前です。個人的にはイメージを覚えるために勝手に **対角線法** というあだ名を付けています。

それぞれのタスクで出した最悪と平均の差を、2乗して足し合わせ、最後に正の平方根を取ります。これが妥当なバッファ期間とします。単位的に細かくなくていいなら、小数点は切り上げると良いでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1126/c61364af-dccd-2574-1060-dc91295e3651.png)

最悪時間を足しただけの `15` よりも、少しアグレッシブに `13` になりました。
これでも多分、大丈夫なはずです。

## なんで対角線？？

SRSS法は長方形や立方体の対角線の長さの計算方法と同じ公式です。なのでイメージが付きやすくて勝手に対角線法と呼んでいます。(他に呼んでる人に会ったことがないので世間的には通じません)

例えばタスクが2つで(最悪 - 平均)が3と4だったら、バッファは $\sqrt{3^2 + 4^2 }$ で5になりますが、これは3x4の長方形の対角線の長さを出してるのと同じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1126/a689fac2-ede5-734e-fb28-bab859f489bb.png)


同じイメージで、(最悪 - 平均)の差分が1のタスクが3つあったとしたら、バッファは $\sqrt{1^2 + 1^2 + 1^2}$ で`1.73205...`ですが、これも1x1x1の立方体の対角線の計算式と同じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/1126/c48ab6f0-ad57-2086-802e-d062a16e8f6d.png)


タスク4つだと4次元になってしまうので超直方体とかになってイメージできなくなりますが。。。まあ、イメージの話なので気にしないでください。


## 対角線の長さはバッファ期間として妥当なの？

いきなり計算方法を示されても妥当かどうか掴めないと思うので、感覚的な説明をしましょう。

タスクが2つの時、バッファはタスクの不確実さを隣り合う2辺にして、長方形を描いたときの対角線の長さです。

三角形の性質でもありますが、対角線は **それぞれのタスクの不確実さより必ず長くなります** 。
例えば1個、すごく不安で100ぐらい50%と90%で差のあるタスクがあったとして、計算されるバッファは100以上になります。

$\sqrt{100^2 + n^2} >= 100$

これは重要な性質ですね。

また、50%と90%で差がない場合、つまり **タスクの不確実さがゼロの場合は、そのタスクはバッファに影響を与えません。**
例えば不安なタスクが1個しかないなら、そのタスクの最悪時間までだけバッファとして積んでおけばよいのです。

$\sqrt{0^2 + n^2} = \sqrt{n^2} = n$


不確実さ1の **タスクが増えると、じわじわとバッファも増えていきます** 。

$\sqrt{1^2 + 1^2} < \sqrt{1^2 + 1^2 + 1^2} < \sqrt{1^2 + 1^2 + 1^2 + 1^2} < \sqrt{1^2 + 1^2 + 1^2 + 1^2 + 1^2}$

切り上げ方式だと、不確実さ1のタスクが増えるごとにこんな感じですね。

* 1個 → バッファ1
* 2個 → バッファ2
* 3個 → バッファ2
* 4個 → バッファ2 
* 5個 → バッファ3

この増え方も何となく、直感的な気がしますがどうでしょうか。


## まとめ

勘ベースの手法ですが、そんなに手間がかからないので、作業バッファの決め方としてオススメです。
もちろん、もっと雑にx1.5とかでバッファを見積もってもいいのですが、それっぽい計算方法が欲しい方は参考にしてみてください。

## 参考文献

- [アジャイルな見積りと計画づくり](https://www.amazon.co.jp/dp/B00IR1HYGW/)
RestTemplateのCould not extract response: no suitable HttpMessageConverter found for response typeの対策

# 環境
```xml
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
```

# 状況
あるREST APIが場合によってContent-Typeが```application/json```になったり```application/octet-stream```するが、JSONが返ってくることには変わりはない状況に出くわした。このとき、レスポンスのJavaオブジェクトへのマッピングが```application/octet-stream```の場合は以下のようにエラーとなる。

```
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class asdf.springsample.SampleController$MyResponse] and content type [application/octet-stream]
```

# 対策
デフォルトではspringのConverterが```application/json```の場合にマッピングするようになっているので、これに```application/octet-stream```も追加する。参考：[Could not extract response: no suitable HttpMessageConverter found for response type](http://www.technicalkeeda.com/spring-tutorials/could-not-extract-response-no-suitable-httpmessageconverter-found-for-response-type)

```java
RestTemplate r = new RestTemplate();

MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM));
r.getMessageConverters().add(mappingJackson2HttpMessageConverter);

RequestEntity<String> request = RequestEntity.post(new URI("http://localhost:8080/a2")).accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM).body("");
ResponseEntity<MyResponse> response = r.exchange(request, MyResponse.class);
```

もしくは、参考URLによると、Apache HttpComponents HttpClientをクラスパスに入れてこっちを使う場合は以下のようなやり方でもOKらしい（こっちは実際に試してない）。

```java
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
RestTemplate restTemplate = new RestTemplate(requestFactory);
```
Osaka Mix Leap Study #4 - Reactの振り返り

株式会社Gemcookでエンジニアしている西野です。

今年の1月に「Osaka Mix Leap Study #4 - React」で発表した資料を共有します。

## さぁ！Reactを始めよう！

https://speakerdeck.com/gcfuji/2018-dot-01-dot-11-osaka-mix-leap-study-number-4-react-saa-reactwoshi-meyou

Reactに入門する為の基礎知識や考え方のほか、Facebookの思想という内容です。

## Reactで状態管理とUIを作ってみよう！

https://speakerdeck.com/sr1994lu/reactdezhuang-tai-guan-li-touiwozuo-tutemiyou

Reactの状態管理とReduxの必要性のほか、便利なUIライブラリを紹介しました。

## Reactを実案件で使って思った''成功''と''反省''

https://speakerdeck.com/keisukemaeda/mix-leap-reactwoshi-an-jian-teshi-tutesi-tuta-cheng-gong-to-fan-sheng

弊社で実際開発しているReact案件から得た「成功」と「反省」についてまとめた内容です。（たった3ヶ月で、今ではずいぶんと構成が変わりました...）


## 最後に

勉強会に参加するだけでも色々な知見や話を聞くことができるのでオススメです。
今年の5月にヤフー株式会社様のグランフロント大阪オフィスにてReactのハンズオンを開催させて頂きます。
React初めての人でもReactを触れるようになっていけたらいいなと思っています。
Logasterで数分間でオンラインでロゴを作成する方法

ロゴは、あらゆるビジネス（小規模または大規模なもの）にとって非常に重要です。 以来、それはあなたの会社の商標を示し、あなたの会社はあなたのロゴの助けを借りて市場で特定されます。

しかし、あなたがロゴデザイナーを雇うときは、あなたの会社やウェブサイトのロゴをデザインするのにほとんど料金がかかりません。 したがって、ビジネスの始まりやウェブサイトの所有者にとって、ロゴデザイナーを雇うことは、その費用のために可能ではありません。 そのような人々はいくつかのオンラインサービスを利用することができます。

すばらしいロゴを無料で無料で作成したい場合は、[Logaster](https://www.777logos.com/logo-creation/) をご覧ください。
![Selection_018.png](https://qiita-image-store.s3.amazonaws.com/0/249438/ef8a33e9-107b-5d05-c169-2b919aa2d61e.png)

##Logasterのしくみ
 
最初のステップでは、ロゴに使用するテキストを入力する必要があります。
![Selection_023.png](https://qiita-image-store.s3.amazonaws.com/0/249438/39aa3f98-9fef-fcc7-28e3-83f8dad5b1eb.png)

その後、「続行」をクリックすると、Logasterはもう一度考えます。 このプロセスの最後には、さまざまな提案のページを埋めるリストが表示されます。 好きなロゴをすばやく見つけることができます.
![Selection_019.png](https://qiita-image-store.s3.amazonaws.com/0/249438/3c088c1f-7a58-a143-a681-d9f3397c094e.png)

下書きを決定すると、それがエディタに表示され、そこで作業することができます。

アイコン、フォント、色の要素を変更したり、スローガンを追加または削除したり、変更せずに保存することができます。
![Selection_020.png](https://qiita-image-store.s3.amazonaws.com/0/249438/ba5d1292-6b4e-5c6c-7256-8484c77e97f2.png)

編集後、アカウントを作成してロゴを保存する必要があります。 その後、小さなロゴを無料でダウンロードしたり、高解像度のロゴを購入することができます。
![Selection_021.png](https://qiita-image-store.s3.amazonaws.com/0/249438/c57166bc-0aa1-cb6d-8fee-52895285c6b8.png)

##Logaster：完全なビジネス文書のための合理的な価格
こうすることで、ブランディング全体を作成することができます。 あなたがそれらを支払った場合、あなたはベクトルとラスタ形式であなたのデザインを得るでしょう。 それにもかかわらず、彼らがプロセスの終わりにしたオファーは公平以上のものでした。 あなたは、ロゴ、名刺、封筒、レターヘッド、ファビコンのために$ 30を支払う必要があります。

あなたが缶詰のビジネス文書のものであるかどうかにかかわらず、あるいはあなたが探しているものすべてがインスピレーションのビットである場合でも、[Logaster](https://www.777logos.com/corporate-identity/) は見て分かる価値があります。
【UWP】UWPアプリでインターネット上のPDFファイルを表示する

# はじめに
こんにちは！

UWPアプリでネット上のPDFファイルを参照する方法の紹介です。（日本語文献が少なすぎる、、、）
iOSから少しそれてしまいますが、Xamarinにも少し関係するためありかと・・・。

# UWPでPDFを表示

まずは全体のソースです。

```C#

// HTTPクライアントを生成
using (var client = new HttpClient())
{
    using (var uploadResponse = await client.GetAsync(pdfUrl))
    {
        // URL先からストリームを取得
        var temp = await uploadResponse.Content.ReadAsStreamAsync();

        if (temp.AsRandomAccessStream().Size == 0)
        {
            var err = new TextBlock();
            err.Text = "PDFファイルを読み込めませんでした。";
            this.listView.Items.Add(err);
            return;
        }

        // 一時ファイルストリームをPDFドキュメントとしてパース
        pdfDoc = await PdfDocument.LoadFromStreamAsync(temp.AsRandomAccessStream());

        // PDFを1ページずつ画像に変換し、リストビューに挿入
        for (uint i = 0; i < pdfDoc.PageCount; i++)
        {
            PdfPage page = pdfDoc.GetPage(i);

            var stream = new InMemoryRandomAccessStream();
            await page.RenderToStreamAsync(stream);

            var image = new BitmapImage();
            await image.SetSourceAsync(stream);
            var img = new Image();
            img.Source = image;

            this.listView.Items.Add(img);
        }
    }
}
```

コメントを適宜記入していますが、分割して説明していきます。

```C#
// HTTPクライアントを生成
using (var client = new HttpClient())
{
    using (var uploadResponse = await client.GetAsync(pdfUrl))
    {
        // URL先からストリームを取得
        var temp = await uploadResponse.Content.ReadAsStreamAsync();
                            ・
                            ・
                            ・
    }
}
```

`await client.GetAsync(pdfUrl)`でHttpClientのレスポンスを取得します。
その取得したレスポンスを`await uploadResponse.Content.ReadAsStreamAsync()`でStreamとして読み出します。

```C#
        // 一時ファイルストリームをPDFドキュメントとしてパース
        pdfDoc = await PdfDocument.LoadFromStreamAsync(temp.AsRandomAccessStream());
    }
}
```

次に、`temp.AsRandomAccessStream()`で取得したStreamをRandomAccessStream型として抽出し、PdfDocumentクラスでPDFファイルとしてパースします。

```C#
        // PDFを1ページずつ画像に変換し、リストビューに挿入
        for (uint i = 0; i < pdfDoc.PageCount; i++)
        {
            PdfPage page = pdfDoc.GetPage(i);

            var stream = new InMemoryRandomAccessStream();
            await page.RenderToStreamAsync(stream);

            var image = new BitmapImage();
            await image.SetSourceAsync(stream);
            var img = new Image();
            img.Source = image;

            this.listView.Items.Add(img);
        }
    }
}
```

解析したPDFファイルのページ数分ループさせます。

`pdfDoc.GetPage(i)`でPdfPageオブジェクトを取得し、
それをInMemoryRandomAccessStreamオブジェクトに書き込みます。

UWPではPDFをそのまま表示できないため、BitmapImageに変換して出力します。
書き込んだStreamを`await image.SetSourceAsync(stream)`でBitmapImageに変換し、
ImageタグのSourceにBitmapImageを登録して完了です。


# さいごに

この実装にはかなり手こずりました。。。
何より参考文献が全くと言っていいほどありません。
この記事が誰かの役に立てば幸いです！

ではでは。
【GPS】GPSを使った何かを作りたい

# はじめに
こんにちは！

現在少しずつではありますが、作成中のiOSアプリでGPSデータを使ってみたいと思ったので自分なりに調べてみました。

今回はその調査結果を自分自身の備忘録として書き記していこうかと思います。

# GPSって？
GPSは「Global positioning system(グローバル・ポジショニング・システム)」の略で、
日本語でお固く言うと全地球測位システムだそうです。

もともとはアメリカが軍事用に打ち上げた衛星を非軍事用途で使えるようになったのが始まりみたいですね！

つい最近の話だと、日本版GPS衛星「みちびき」の打ち上げに成功し、2018年度から利用可能となるようです。

この衛星を利用すると即位誤差がcm級にまで縮まるそうですｗ
~~恐ろしい~~

今後この即位誤差の縮小によって、自動運転や農業、漁業などのIoTにも影響がありそうですね！

# Swiftで扱うGPS

ようやくここからGPSの取得についてです。

SwiftでGPSのデータを利用するには「CoreLocationフレームワーク」をimportする必要があります。

また、GPSの利用はユーザーの承諾が必要であるため、Info.plistに承諾を促す文を追加します。

Key: Location When In Use Usage Description
Value: このアプリでは位置情報を取得します。（的な）

許可が得られない場合、どういった機能が使えなくなるのか書いていると親切な設計なのかなと思います。

もしくはアプリ起動時ではなく、権限許可が必要な機能を使用しようとした場合に許可を求めれば説明いらないですね！
（よく考えるとそんなアプリが最近増えているような・・・？）

次にCoreLocationフレームワークに含まれている、CLLocationManagerを生成して一瞬の緯度経度や、
取得間隔から移動距離、速度も計算して算出できるようですね。

# さいごに

今回は調査ということで実際にコーディングは行いませんでしたが、
こうして記事に書き記すことで自分自身の理解が深まったように感じます。
多分誰得かって言われたら自分しか得しませんがｗ
こういったアウトプットもいいのかなと思いました！

次回は実際にコーディングしてみて、移動速度の表示までやってみようかなと思っています。

なんかこんな記事書いているとウェアラブル端末が欲しくなりました。。。

AppleWatchほしい何か作りたい。。。
ServiceNowでiTunesのRestAPIを使用する(下編）

# 概要

今回は、[中編](https://qiita.com/sukkyxp/items/788c0310e29a56c06802)で作成した下記の画面のソースの解説を行う。

![iTunessearch.png](https://qiita-image-store.s3.amazonaws.com/0/197947/a6e45fc6-65d4-d6da-43a0-8b20b3f9436b.png)


## BootStrapのスタイルを使用する

```html
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"></link>
```

Bootstrapのスタイルシートを使って少しだけ見た目を良くする。
HTML中のclass指定は全てBootstrapで定義されているスタイルシートを指定。

## 入力値のサーバースクリプトへの送信とサーバー側スクリプトの設定値に受け取り
```html
<input type="text" class="form-control" name="searchWord" placeholder="検索ワード" value="${searchWord}"></input>
```
リクエストパラメーターにキー名 = "searchWord"で入力値をサーバーに送信。

```html
value="${searchWord}"
```

の${searchWorld}は、サーバーで設定した値を受け取るためのプレースフォルダーだ。
これがないと、検索ボタンを押下して画面を再描画したら、検索キーワードが消える。
サーバー側のProcessing Scriptで

```javascript
var searchWord = searchWord;
```
左辺の変数はサーバー側の変数である。これをクライアントで受け取るのがHTMLの${searchWord}だ。
右辺はクライアントから送信されたリクエストパラメーターからキーがsearchWordの値を取得している。

## REST Messageの呼び出し

```javascript
var r = new sn_ws.RESTMessageV2('x_58872_needit.iTunesSearch', 'Default GET');
```

このコードはRest MessageのHTTP Method設定画面の「Preview Script Usage」のリンクをクリックする事により表示されるコードをコピーしたものだ。
rはREST Messageを送信するためのオブジェクトのインスタンスだ。
これにリクエストパラメーターを設定して、execute()によりRest APIを実行する。

```javascript
r.setStringParameterNoEscape('term', searchWord);
```

Rest Message のtermパラメーターにsearchWordを設定している。

## REST APIの戻り値のJSONを解析

```javascript
 var parser = new global.JSON();
 var parsed = parser.decode(responseBody);
```

parsedにJSONメッセージ変換されたオブジェクトが格納される。

## 検索結果の表示

検索結果の表示部分は下記の通り。

```html
<j:forEach items="${parsed.results}" var="jvar_item" indexVar="i">
                <g:evaluate jelly="true" object="true">
                    var trackName = jelly.jvar_item.trackName;
                    var jacketUrl = jelly.jvar_item.artworkUrl60;
                    var idx = jelly.i + 1 + '';
                </g:evaluate>
                 <tr>
                     <td>${idx}</td>
                     <td><img src="${jacketUrl}" /></td>
                     <td>${trackName}</td>
                 </tr>
             </j:forEach>
```

iTunes Search APIの戻り値のJSONメッセージのresultsには、検索結果が配列で格納されている。配列の１つ１つの値は連想配列になっており。
trackNameや、artworkUrl60は連想配列のキーだ。

```html
<j:forEach items="${parsed.results}" var="jvar_item" indexVar="i">
```

は、jellyの文法で、${parsed.result}で受け取った配列から値を順に取り出し処理するループ分になる。取り出した値は、jvar_itemに格納される。
indexVarは必須ではないが、ループ内で行番号を出力するために使用している。

```javascript
var trackName = jelly.jvar_item.trackName;
```

jvar_itemに検索結果１行分が連想配列で格納されているので、キー名で値を取り出している。

```javascript
var idx = jelly.i + 1 + '';
```

インデックスとして使っているiは、０から始まるので、行番号とするために１足してから、文字列に変換のため、’’を足している。
文字列に変換しないで、そのまま出力すると、行番号に「1.0」が出力される。

# 最後に
始めてまだ１週間程度なので、余計な遠回りをしていたり、間違った解説をしている事も考えられる。
気づいた点があれば、指摘をお願いしたい。
今後は、今回のiTunes検索画面をAjaxで実施したり、ServiceNowのその他の画面のデザインの雰囲気を合わせていく方法を調べて投稿していく予定としている。
また、ページネーションを自力で実装するよりも、検索結果を一時トランザクションテーブルに登録して、検索結果をServiceNowのFormにより表示することによりページネーションをServiceNowのForm機能に任せる方法も調べていく予定にしている。
Kubeadm + Helm Charts使ってGitLab CIを試したい ① ~ Vagrant で２つのマシンを一括起動する ~ 

会社だとプロキシ様がいろいろあれなので家でもKubernetesを触ってみたい :)
ついでにGitLab CIを使いたい．Helm入れてやってみるのだ．

ホストはWindows10使用なのでVagrant+VirtualBoxを使います．

## こんな感じで作る予定
Vagrant 2.0.2 + VirtualBox 5.2.8
kubeadm 1.8系

|IP             |OS          |Role        |
|:--------------|:-----------|:-----------|
|192.168.33.10  |CentOS 7.3  |Master node | 
|192.168.33.101 |CentOS 7.3  |Node 1      |

## 実際の作業

今回はマシンの立ち上げだけです．なぜならVagrantすらよくわかっていないから・・・・
Vagrantで2台のVMを一括で立ち上げます．

Vagrantfileを下記のように書く（boxとってくるとかは他記事にあるので割愛）

```
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "create 3 VMs"
  
  config.vm.define "master" do |master|
    master.vm.box = "bento/centos-7.3"
    master.vm.synced_folder ".", "/vagrant", disabled: true
    master.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2222
    master.vm.network "private_network", ip: "192.168.33.10", virtualbox__intnet: "intra"
  end

  config.vm.define "node01" do |node01|
    node01.vm.box = "bento/centos-7.3"
    node01.vm.hostname = "node01.atomichost"
    node01.vm.synced_folder ".", "/vagrant", disabled: true
    node01.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2223
    node01.vm.network "private_network", ip: "192.168.33.101", virtualbox__intnet: "intra"
  end
end
```
VM同士が互いに通信できるようになっているようにネットワーク設定を書きました．
そして起動する．

```
$ vagrant up
```

終わり．
Vagrantの使い方まだいまいちわかってないけど習うより慣れろということで．

注）Virtual Box 5.1系を使ってたらエラーが出たので，アンインストールして最新版を入れました．
ホストだけバージョン上げると，ゲストOSとバージョンがあわなくて死亡してエラーが出ました．
[こちら](https://qiita.com/satokourov/items/e632df854be6048adf7b)を参考に解決．
ちなみに指定のマシンだけ起動したいときは下記のようにすればOK

```
$ vagrant up node01
```


## 参考
[【Qiita】 Vagrant+Virtualboxを使いWindows10上にCentOS7.3+php7+MySQL5.7の環境を構築する](https://qiita.com/yasushi00/items/0926b65ab0abd8f20e21)
[【Qiita】Vagrantで複数の仮想マシンを立ち上げる　マルチマシン(Malti-Machine)設定](https://qiita.com/zum/items/03da94291ffbc9af2244)
[【Qiita】vagrant up するとGuestAdditions エラーが発生](https://qiita.com/satokourov/items/e632df854be6048adf7b)
[【Qiita】【まとめ】Vagrant コマンド一覧](https://qiita.com/oreo3@github/items/4054a4120ccc249676d9)
windowがあればwindow.parentがある。

### 空のhtmlでもwindowがあればwindow.parentがある。
ブラウザ無を考慮するなら、windowの有無だけをチェックしてpostMessageすればよい。

```html
<script>window.onmessage=function(ev){console.log('from child',ev)};</script>
<iframe srcdoc='<body onload="window.parent.postMessage(`xyz`,`*`)"></body>'></iframe>
```
Windows 7 で Microsoft Update の Web サイトに遷移できない。

## 概要

Windows 7 で Windows Update の

> その他のマイクロソフト製品の更新プログラムを入手します。
> **詳細情報の表示**

をクリックしても,

> [スタート] メニューを使用して、更新プログラムを確認してください

と表示されてしまう。

## 原因

Internet Explorer (IE) が 11 にアップデートされたため。

Microsoft Update のページは古い IE 向けの構造になっているため, 新しい IE では表示できない。

## 対策

1. IE の **ツール** - **互換表示設定** をクリックする。
   - ツールバーが表示されない場合, Alt キーを押下する。
1. *追加する Web サイト* 欄に `microsoft.com` と入力し, **追加** ボタンを押下する。
1. *互換表示に追加した Web サイト* 欄に *microsoft.com* が追加されたことを確認し, **閉じる** ボタンを押下する。
1. ページがリロードされ, Microsoft Update のページが表示される。

## 参考文献
- [その他のマイクロソフト製品の更新プログラムの入手が利用できない。 - マイクロソフト コミュニティ](https://answers.microsoft.com/ja-jp/windows/forum/all/%e3%81%9d%e3%81%ae%e4%bb%96%e3%81%ae%e3%83%9e/11129b64-8eea-4e3d-afb3-22fcda227ab9)

どっとはらい。
2018年4月頃に行うELECTRON/VSCodeのデバッグでenv.APPDATAが通らない



# こうすると
```launch.json
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "プログラムの起動",
            "program": "${workspaceFolder}\\index.js",
            "cwd": "${workspaceRoot}",
            "preLaunchTask": null,
            "windows": {
                "runtimeExecutable": "${env.AppData}\\npm\\node_modules\\electron\\dist\\electron.exe"
            },
            "console": "integratedTerminal",
            "sourceMaps": false,
        }
    ]
```

# こうなるよエラー
```
PATH 上で '${env.AppData}\npm\node_modules\electron\dist\electron.exe' のランタイムが見つかりません。
'${env.AppData}\npm\node_modules\electron\dist\electron.exe' がインストールされていることを確認してください。
```

# こうすると通る
```launch.json
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "プログラムの起動",
            "program": "${workspaceFolder}\\index.js",
            "cwd": "${workspaceRoot}",
            "preLaunchTask": null,
            "windows": {
                "runtimeExecutable": "${env:AppData}\\npm\\node_modules\\electron\\dist\\electron.exe"
            },
            "console": "integratedTerminal",
            "sourceMaps": false,
        }
    ]
```


# なにがいけなかったのか
大体の記述が`${env.AppData}`だった。
いまどきは`${env:AppData}`らしい。
Angular用にExpressサーバを作る

# はじめに
Angularだけはやったことあるんですが、
サーバ側を全くやったことが無いのでExpressを勉強しようと思い最低限動かすとこまでまとめます。

# 前提条件
Nodeはインストール済み & OSはMacです。   

# インストール
[公式？サイト](http://expressjs.com/ja/starter/installing.html)を参考にコマンドを叩いていきます。

```shell
# サーバ用のフォルダ作成
mkdir server
cd server

# package.json作成
# 色々聞かれるけど、初期設定で良いのでEnter連打
npm init

# Expressをインストール
# 一応 --saveを付けておく
npm install express --save
```

これで、インストールは問題ないはず。

# とりあえず動かしてみる
引き続きサイトを参考に`index.js`を作っていきます。

```javascript
// 今のところ意味あるかわからないが一応付けとく
'use strict';

// expressインポート
import express from "express";

const app = express();

// '/'来た時返す
app.get('/', (req,res) => {
    res.send('Hello World!');
});

// ポート3000で待受
app.listen(3000, () => {
    console.log('listen on Port 3000');
});
```

最低限はこれでOKのハズ。。。
`node index.js`で起動。

```
import express from "express";
^^^^^^

SyntaxError: Unexpected token import
```

だめじゃん！
調べてみたらNodeはES6で書けないっぽい。
仕方ないのでimportはrequireに修正。
下記の様にしました。

```javascript
'use strict';
const express = require('express');
const app = express();

app.get('/', (req,res) => {
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('listen on Port 3000');
});
```

もう一度実行すると`listen on Port 3000`とちゃんと出てきた。
'http://localhost:3000'にアクセスするとHello Worldって出てた。
これでとりあえずOKっぽい。

# アプリ置いてみる
さて、一番やりたかったWebサーバとして設定しようと思います。
公式サイト見てもわからなかったので、色々参考にして下記の様になりました。

```javascript
'use strict';
const express = require('express');
const app = express();

// 変更箇所
app.use(express.static('./app/'));

app.get('/', (req,res) => {
    // 文字返してもしかたないのでconsole.logにしとく
    console.log('Hello World!');
});

app.listen(3000, () => {
    console.log('listen on Port 3000');
});
```

ちなみに置いているアプリは[これ](https://github.com/Tetsuya-Minase/trpgApp)。
アプリについては割愛趣味で作ってたものを置いてあります。
`ng build`で出てきた内容を`index.js`と同じ階層の'app'ディレクトリにおいてあります。

アプリを置いたので、先程のアドレスにアクセス。
無事アプリを表示出来ました！！
出来ましたが、getを消しても動くのでよくわからないです。。。
その内調べたいですが、一旦動いてるので良しとします。

```javascript
'use strict';
const express = require('express');
const app = express();

// 変更箇所
app.use(express.static('./app/'));

//app.get('/', (req,res) => {
    // 文字返してもしかたないのでconsole.logにしとく
    //console.log('Hello World!');
//});

app.listen(3000, () => {
    console.log('listen on Port 3000');
});
```
FlutterでのiOS API呼び出し

Flutter７日目。
## iOS連携
iOS側の機能を呼び出す際には Dart と Objective-C もしくは Swift と連携をする必要がある。
Flutterではチャンネルのキーワードを決めることで必要な連絡を取れるようになっている。

今回はその中でも Dart から連絡を入れる場合。
とはいえ結局は[６日目](http://blog.xhift.com/2018-04-11/flutter-day6/)にあげたリンク
[Writing custom platform-specific code with platform channels](https://flutter.io/platform-channels/)
の実際どうするの？話に尽きる。

## チャンネルとは？
要は文字列。
### Dart では

```dart
const MethodChannel('samples.flutter.io/battery');
```

と書いてあるもの。
### Objective-C では

```objective_c
methodChannelWithName:@"samples.flutter.io/battery"
```

文字列が同じ。

## 関数の呼び出し方
つまりは Dart 側。

```dart
MethodChannel methodChannel;
final int result = await methodChannel.invokeMethod('getBatteryLevel', ['Hello', 'World']);
```

これで引数が渡せる。

## 引数の取り方
### Objective-C の場合
引数無しは上記リンクで。
引数有りの場合

```objective_c
NSArray* arguments = call.arguments;
NSString* word = arguments[0];
```

ってやると引数に渡した文字列が取れる。
int を渡したなら int で受け取りましょう。

### Swift の場合

```swift
let arguments = call.arguments as! Array<Any>;
let word = arguments[0] as! String;
```

で受け取りましょう。
Swiftでargumentsの定義にとんでも id がどうこうと見えるだけで結局どうしたらよいかわからんかった。

## おまけ
id とは？
Objective-C にある型で、C でいう void* のようなものっぽい。
Swiftではこれが Any となるっぽい。as! や as? に関しては Swift のキャストについて調べてみてね。


この内容は
[個人ブログ](http://blog.xhift.com) でも投稿されております。

---
お仕事募集しております
[株式会社xhift](http://xhift.com/)

北千住でコワーキングスペースも運営しておりました。再開したい！
[Bono Prince(ぼのプリ)](http://xhift.com/bonopri/)

---
__init__.pyをエイリアスっぽく使う

```
lib
 ┗__init__.py
main.py
```
こんなディレクトリ構造があったときに

```python:main.py

import lib

lib.foo()
```
みたいに呼びたいときは、通常、次のようにlib/_____init_____.pyにこんな感じで関数を付け足す。

```python:__init__.py
def foo():
  print('called foo')
```
でも、_____init_____.pyはあまり汚したくない。そういった場合は別のモジュールを用意してimportすれば、main.pyから同じように呼び出せる。


```
lib
 ┗__init__.py
 ┗funcs.py
main.py
```

```python:__init__.py
from .funcs import foo
```

```python:funcs.py
def foo():
  print('called foo')
```

気づいてしまえば何のことはない、すごく簡単。
【Raspberry Pi 3 Model B】男ひとり酒を飲みながらラズパイと会話したい（第３回）

##概要
docomoのAPIや、Open JTalk等を組み合わせれば、ラズパイと会話ができそうなので作ってみました。
第３回はdocomoAPIを使用しての雑談対話です。

##参考にしたサイト

- [とりあえずdocomo雑談対話APIを使ってみる](https://qiita.com/ponkio-o/items/df0d64677dcb4b7e8eb3)

##前提条件

- モデル : Raspberry Pi 3 Model B
- OS : Raspbian Stretch
- マイク（USB）
- スピーカー（アナログ）

```Bash:
$ uname -a
Linux raspberrypi 4.14.30-v7+ #1102 SMP Mon Mar 26 16:45:49 BST 2018 armv7l GNU/Linux
```

##雑談対話動作確認
第２回で取得したAPIKEYを使ってとりあえずの動作確認です。

```Pyton:
$ python
>>> import requests
>>> import json
>>>
>>> url = "https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY={}".format("メモったAPIKEY")
>>>
>>> utt_content = 'こんにちは'
>>> payload = {'utt' : utt_content, 'context': ''}
>>> headers = {'Content-type': 'application/json'}
>>> r = requests.post(url, data=json.dumps(payload), headers=headers)
>>> response = r.json()['utt']
>>> print "response: %s" %(response)
response: やぁ
>>>
>>> exit()
```
’こんにちは’に対して何かしらのレスポンスがあれば成功です！

##雑談対話でチャット
[雑談対話｜docomo](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=dialogue&p_name=api_usage_scenario#tag01)のページにも記載がありますが、同一のコンテキストID(context)を用いた場合、対話履歴は会話が途切れるまで記憶されるようです。
ということで、[参考サイト](https://qiita.com/ponkio-o/items/df0d64677dcb4b7e8eb3)そのままなので省略。

##まとめ
テキスト→音声、音声→テキスト、テキストでの会話ができたので、次回は音声での会話に挑戦します。

##記事

[【Raspberry Pi 3 Model B】男ひとり酒を飲みながらラズパイと会話したい（第１回）]
(https://qiita.com/sunaga70/items/acbfa107ae9221529115)
[【Raspberry Pi 3 Model B】男ひとり酒を飲みながらラズパイと会話したい（第２回）]
(https://qiita.com/sunaga70/items/aed3da33fb6ba453c422)
[【Raspberry Pi 3 Model B】男ひとり酒を飲みながらラズパイと会話したい（第３回）]
(https://qiita.com/sunaga70/items/f83dac93ac2b9ef217dd)
[【Raspberry Pi 3 Model B】男ひとり酒を飲みながらラズパイと会話したい（第４回）]
(https://qiita.com/sunaga70/items/f636edc396a7b5100a7a)
ActionCableを使うときはEventEmitterと組み合わせてSingletonで使うと捗るかもしれないという話

# まえがき
最近、Rails5でActionCable + Vue[^1]を使ってSlackっぽい感じのチャット画面を作っているのですが…

[^1]: 執筆時点での使用歴はActionCable,Vue共に1ヶ月程度です。

- 「所属ルーム(Slackのチャンネルに相当)」と「ルーム内のメッセージ」を2ペインで表示する
- 「所属ルーム」と「メッセージ」のコンポーネントはそれぞれ独立したVueファイルに記述されている

という状況で

- 新規チャットメッセージが配信されたときに各コンポーネントでそれぞれ独立した処理を行いたい
    - 例えば…
        - 「メッセージ」ペインでは配信されたメッセージを末尾に追加する
        - 「所属ルーム」ペインではLINEみたいに新規メッセージが来たルームを一番上に持っていく
        - etc...

上記を実現する必要がありました。[^2]
[^2]: 通常であればこういう時にVuexが役に立つのだと思います。しかし、ここで作成しているプロダクトは機能が限られており、要求に対してオーバーだと感じたためVuexの導入はしていません。

そんな時にタイトルの件を行ったら良い感じに出来たと思いましたので共有します。

# おことわり
- 各コンポーネント間のイベントの動作順序は問わない前提です
    - 例えば「メッセージペインで行う処理が所属ルームペインで行う処理より後でなければいけない」場合は想定していません
- 他にも意外なところでマズいかもしれないのでご利用は自己責任でお願いします
- 筆者はActionCable,Vue共々始めて日が浅い[^1]ので他に良い手法をご存知の方はコメントいただけると幸いです

# 書いたもの

まず、この様なJSファイルを用意しました。

```js:chat-event.js
import ActionCable from 'actioncable'

const EventEmitter = require('events').EventEmitter

class ChatEventEmitter extends EventEmitter {
  constructor() {
    super()
    const _this = this
    this.cable = ActionCable.createConsumer('/cable')
    this.channel = this.cable.subscriptions.create({channel: "ChatChannel"}, {
      connected: function(){
        _this.emit('connected')
      },
      disconnected: function(){
        _this.emit('disconnected')
      },
      received: function(data){
        _this.emit('received', data)
      }
    })
  }
}

const instance = new ChatEventEmitter()
Object.freeze(instance)

export default instance
```

そして、各Vueファイルで使うときはこの様になります。

```vue:example.vue
<template>
  <!-- 略 -->
</template>

<script>
import ChatEvent from 'chat-event.js'

// 略

export default {
  // 略
}

ChatEvent.on('received', (data) => {  // 配信されたときに呼び出される
  console.log(data) // => コンソールに配信された内容が表示される
  // 以下、行いたい処理
})
// ちなみにChatChannelのアクションを呼び出したいときは以下の様になる
// ChatEvent.channel.perform(...)
</script>
```

これで期待した動作が実現できました。
コンポーネントの分離性を損なわず、ActionCableのコールバックを利用したい際に使えるので今のところ気に入っています。

# あとがき
数種類のチャンネルを貼りたいときは各チャンネルで同様のクラスを作ると良いと思います。
~~誰かが既にやっててもおかしくないのに誰もやってなさそうなあたりベストプラクティスではない気もする。~~

# 参考にしたページ

[[Javascript] イベント駆動型の設計ができるEventEmitterに入門](https://www.yoheim.net/blog.php?q=20170103)
[JavaScript/ES6の基本文法とSingletonパターン | 酒と涙とRubyとRailsと](http://morizyun.github.io/javascript/design-pattern-singleton.html)