OmniAICreator/Qiita-1.07M huggingface dataset:
ALB+LambdaでHello WorldなWebアプリ

Lambda関数作成
-

1. コンソールを開く → https://ap-northeast-1.console.aws.amazon.com/console/home?region=ap-northeast-1
2. 「サービスを検索する」で「lambda」を検索して移動 → https://ap-northeast-3.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/begin
4. 「関数の作成」を押下
5. 以下を入力して「関数の作成」を押下
    1. 一から作成：デフォルト(チェック)
    2. 関数名：helloworld
    3. ランタイム：デフォルト(Node.js 10.x) ★実案件ではJavaとしたい
    4. 実行ロール：デフォルト(基本的なLambdaアクセス権限で新しいロールを作成)
6. 表示されているコードを以下の内容に変更して画面上部の「保存」を押下

```
exports.handler = async(event) => {
    return {
        statusCode: 200,
        headers: {
            'Content-Type': 'text/html'
        },
        body: 'Hello World'
    };
};
```

Application Load Balancer(ALB)作成
-

1. コンソールを開く → https://ap-northeast-1.console.aws.amazon.com/console/home?region=ap-northeast-1
2. 「サービスを検索する」で「EC2」を検索して移動 → https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Home:
3. 左メニューから「ロードバランサー」を探して移動 → https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#LoadBalancers:sort=loadBalancerName
4. 「ロードバランサーの作成」を押下 → https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#SelectCreateELBWizard:
5. 「Application Load Balancer」の「作成」を押下
6. 以下を入力して「次の手順：セキュリティ設定の構成」を押下
    1. 名前：helloworld-alb
    2. スキーム：デフォルト(インターネット向け)
    3. IPアドレスタイプ：デフォルト(ipv4)
    4. ロードバランサーのプロトコル：デフォルト(HTTP、80)
    5. VPN：デフォルト
    6. アベイラビリティーゾーン：2つチェック
    7. タグ：デフォルト(なし)
7. 「次の手順：セキュリティグループの設定」を押下
8. 以下を入力して「次の手順：ルーティングの設定」を押下
    1. セキュリティグループの割り当て：新しいセキュリティグループを作成する
    2. その他：すべてデフォルト
9. 以下を入力して「次の手順：ターゲットの登録」を押下
    1. ターゲットグループ：デフォルト(新しいターゲットグループ)
    2. 名前：helloworld-targetgroup
    3. ターゲットの種類：Lambda 関数
    1. ヘルスチェック パス：デフォルト(/)
    1. ヘルスチェックの詳細設定：すべてデフォルト
10. 以下を入力して「次の手順：確認」を押下
    1. Lambda 関数 - リストから Lambda 関数を選択するか、関数を作成します：チェック
    1. 関数リスト：helloworld
    1. バージョン：チェック
    1. バージョンリスト：デフォルト($LATEST)
11. 「作成」を押下
12. 「閉じる」を押下
13. 状態が「provisioning」の間、何度か右上の更新アイコンを押して「active」に変わるのを待つ (2～3分)
14. 説明タブの「DNS名」をコピー (右端のアイコンでコピー可能)

動作確認
-

ブラウザで http://＜コピーしたDNS名＞/ にアクセス
テストデータ作成ツール試行

1.ゴール

2.課題


3.アクション


4.アクション(実績)
　全般的に、クエリをたくさんつくって、手続き言語でつなげるイメージをしている。
　・対象者抽出と履歴抽出のクエリをそれぞれ作った。
　・対象者にはIDを振った。
　・対象者として認められたIDに限って、履歴抽出のクエリに割り当てた。
　・あとは対象者データとカラムを合わせてUNION ALLしてテストデータとするつもり
　→この方法が思いつかない。対象者抽出条件としてヒットする歴とそうでない歴を分けないとかな。
包含したクラスのコンストラクタに引数を渡す


C++勉強中のメモ。あとqiitaに記事を上げる練習

# 結論
クラスにクラスを包含するときに、包含したクラスのコンストラクタに引数を渡したい場合は、初期化の際にコンストラクタを呼ぶ。

# クラスのメンバ変数にクラスを持たせる
クラスのメンバ変数としてクラスを持たせた場合、なにもしなくてもデフォルトコンストラクタが呼ばれる。

```C++:test1.cpp
#include <iostream>
class Test1{
    public:
        Test1();
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
```

```:実行結果
Constructor:Test1
Constructor:Test
```

また、コンストラクタは包含したクラスから呼ばれていることもわかる。
# 引数を持つクラスを包含する
先程のTest1クラスのコンストラクタに引数を設定してみる。
とりあえずなにも考えずこう書くとコンパイルはエラーを吐かなくなった。

```C++:test2.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1(int a);
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
```

が、実行してみるとこうなる。Test1のコンストラクタが呼ばれていない。

```:実行結果
Constructor:Test
```

~~冷静に考えると引数に渡しているaには実体がないので、これでTest1のコンストラクタが呼ばれても困る。
(コンパイラに怒って欲しかった。)~~

## 追記
コンパイルが通るのも当然で、ここで宣言しているのはコンストラクタではなくただのメンバ関数だった。
ちなみにこのように書くと、Test1クラスにはデフォルトコンストラクタがないぞとIDEも怒ってくれるしコンパイルは通らない。

```C++:test2.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
```




# コンストラクタでクラスを初期化する
メンバとしてクラスなどのオブジェクトを持たせた場合でも、普通の変数と同様にコンストラクタで初期化ができる。

```C++:test3.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(int a){
    std::cout << "Constructor:Test1" << " argument:" << a << std::endl;
}

Test::Test():
    test1(1)//初期化でコンストラクタを呼ぶ
{
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
```

```:実行結果
Constructor:Test1 argument:1
Constructor:Test
```

コンストラクタが呼ばれた。引数を渡すこともできている。
GCPの無料枠でWordPressを起動して運用するまでの備忘録 4

### 背景
前回 独自ドメインを設定しました。

- [GCPの無料枠でWordPressを起動して運用するまでの備忘録 3][1]
[1]:https://qiita.com/pooh_ichi/items/0b986e3f6bd766f4a6cf
今回はプラグインを設定し、データを復元。運用を再開させます。
### Akismet Anti-Spam を有効化
![plug_in01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/d7ac18ad-038a-5096-2b24-097eb15d896e.jpeg)
### Jetpack,WP Multibyte Patch を有効化
![plug_in09.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/d7390a6a-70f8-e9e0-a3b9-9f5a4eb3152e.jpeg)
### UpdraftPlus WordPress Backup Plugin をインストール

- [まだBackWPup使ってるの？復元までこなすWordPressのバックアップおすすめプラグイン UpdraftPlus][2]
[2]:https://growup43.com/120/
こちら ↑ を参考にしました。

「プラグインを追加」で UpdraftPlus WordPress Backup Plugin を「今すぐインストール」→「有効化」
![plug_in02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/75e15cc5-df86-e49e-c126-3fd70bece412.jpeg)
「設定」タブで保存先を「Google Drive」に設定
![plug_in10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/35ba522f-db2a-7fd8-8eac-3c8a21981b27.jpeg)
![plug_in03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/8a4827c9-a7cf-0f0b-1abf-bc275ef2eeed.jpeg)
「Backup/Restore」タブで「今すぐバックアップ」
![plug_in11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/3b9ea904-6b91-c0fc-423b-26673bcdd23f.jpeg)
復元する場合は、「バックアップ済み」のファイルから復元。
![plug_in05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236301/a7d6637f-6b16-9bb6-a784-cdf0900a5e52.jpeg)
あっと云う間に復元できてしまいました。
以前は、BackWPup で phpMyAdmin でデータを戻していましたが、それに比べると格段に楽して復元できました。
### まとめ
これで WordPress が再開できました。
DCGANを使って上白石萌歌さんらしきものを生成した話

今回は[前回](https://qiita.com/I_Love_idachi/items/fe93d5c2f18ac9451052)の続きとして。DCGANを用いて上白石萌歌さんらしきものを生成してみました。

とりあえず、DCGANの簡単な説明をしていきます。

## DCGANとは
参考にしたサイトは以下
[はじめてのGAN](https://elix-tech.github.io/ja/2017/02/06/gan.html)

一文でまとめると、CNNを用いたGAN。
![dcgan_generator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423403/80304739-0659-a7d8-6ea6-a80146233c29.png)


CNNといってもプーリングはしないで、その代わりストライド2の畳み込みをする。

最後の方で全結合をしないで、Global average poolingを用いる。これを用いることで過学習を防いでくれる。(パラメータがなくなるから)
![global_average_pooling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423403/d7f426a9-27fd-8bc8-5056-9c451d39d3d6.png)


Batch Normalizationを用いて学習をはやくしたり、過学習を防ぐ。

GeneratorではReLUとTanhを用いるが、DiscriminatorではLeaky ReLUを用いる。

## データセットの用意
スクレイピングとOpenCV2を使いました。詳しくは[こちら](https://qiita.com/I_Love_idachi/items/4ebed2cfb778f8cb2136)

## 実装してみる
以下を参考にしました(というかほぼコピペ....)
[５ステップでできるPyTorch - DCGAN](https://qiita.com/hokuto_HIRANO/items/7381095aaee668513487)
Colabで動かした結果は[こちら](https://colab.research.google.com/drive/1QBIspDo0qNoO_1nLvQ36fynZfOi8oi0h)

このコードは画像サイズが$64\times64$しか許されていないが、他のサイズを用いたいなら、頑張って畳み込みの部分を逆算するとよい。ちなみにDiscriminatorではサイズは辺の長さが半分ずつになっている。

gifの作り方を覚えたので載せておく。
Colavでconvertを使うのには、事前に以下のコマンドを実行することが必要。

```
!apt-get update && apt-get install imagemagick
```

以下でgifが作れる。

```
!convert -layers optimize -loop 0 -delay 10 ./Generated_Image/*.jpg animation.gif
```

## 結果
GANの時よりは色合いもろもろを含めてまあ良くなったかなぁという感じ。
![](https://media.giphy.com/media/cPkz1oNc7WKWgGWqY3/giphy-downsized-large.gif)
ただ、まだまだ求めてるものとは程遠い。

(gifを貼る際に参考にしたサイト)
[Qiitaにgifアニメを投稿する僕が考える一番簡単な方法【GIPHY CAPTURE】](https://qiita.com/hirothings/items/7ed040d017bda13e261a)

前回の結果
![GAN_kamisiraisi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423403/65d93245-2946-75bf-efdc-d9eda6e61bc1.png)


今回の結果
![4900.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423403/62cd1179-0318-678a-6f98-f8cb91992799.jpeg)


うーん、なんか下手な油絵みたいだなぁ。

まだまだ、俺の理想には遠いようだ。

チューニングをしたら良い感じのものができあがるのかなぁ。そもそもデータセットの質が悪いのかなぁ。まだGANの理解があまり足りていないので、もう少し理論の方を見ていきたい。

次回やることは未定ですが、ちょっとデータセットを改善したりGANの勉強をして、リベンジしたい。
Swift：MIDIのBluetooth構成ウィンドウを開く

# 概要

MacとMIDI機器を接続する時に開くウィンドウ↓ をプログラムのコードから呼び出したかった。

![ble.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/1d39e9c3-4034-8dff-72b1-e4250f69973b.png)


# 方法

`CoreAudioKit`の`CABTLEMIDIWindowController`を使えば良いようです。

```swift
func open() {
    // すでに開いていた場合は新規にはインスタンスを作らないように注意
    if let window = NSApp.windows.first(where: { $0.title.contains("Bluetooth") }) {
        window.orderFrontRegardless()
        return
    }
    NSApp.activate(ignoringOtherApps: true)
    let wc = CABTLEMIDIWindowController()
    wc.window?.hidesOnDeactivate = false // ここが重要ポイント
    wc.showWindow(nil)
}
```

注意点として，`hidesOnDeactivate = false`をしないとスクリーン上からはウィンドウが消えているのに、windowのインスタンスが残っておりクラッシュするということがあり得ます。また、CABTLEMIDIWindowController()をどこかで保持するのはやめた方が良さそうです。MIDI機器との接続が意図せず切れた時に、AppDelegateにて`Thread 1: EXC_BAD_ACCESS`で原因不明死することがあったりします。
anyenv / nodenv 使用時に Node.js のバージョンを上げる方法

今は anyenv を使って \*\*env 系を管理している。例えば anyenv を使って nodenv をインストールし、nodenv を使って Node.js のバージョン管理をしている。この環境の場合、次の流れで Node.js のバージョンを上げる。

1. **anyenv に anyenv-update プラグインをインストールする（初回のみ）**
1. **nodenv を最新にする**
1. **Node.js の新しいバージョンをインストールする**
1. **Node.js を新しいバージョンに切り替える**

詳細は下記

## anyenv に anyenv-update プラグインをインストールする（初回のみ）

anyenv で管理している \*\*env を最新にアップデートするには anyenv-update プラグインが必要らしい。
[GitHub - znz/anyenv-update: anyenv plugin that provides `anyenv update` command to update all **env and all plugins](https://github.com/znz/anyenv-update)

GitHub の README に書かれているように、次のコマンドでインストールできる。

```
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
```

## nodenv を最新にする

```
$ anyenv update
```

## Node.js の新しいバージョンをインストールする

nodenv を最新にすれば、最新バージョンの Node.js もインストールできるようになっているはず。

```
$ nodenv install -l
```

例えば 12.1.0 をインストールする場合は

```
$ nodenv install 12.1.0
```

## Node.js を新しいバージョンに切り替える

~~忘れがち~~

グローバルで変えてよければ次のようにする:

```
$ nodenv global 12.1.0
```
パイプしたときの終了ステータスの取得方法

コマンドの実行でエラーが起こってないか監視ツールで監視したいため、
コマンドの実行が成功したか失敗するか取得する方法を調べました。

## 正常 or エラー
Linux(Unix)では、すべてのコマンドは`終了コード（exit code）`を返します。
`0`が成功、`1以上の値`はエラーです。
エラー時の終了ステータスは以下のように予約されています。
`128+n`のエラー内容はコマンドやソフトウェアの実装によって異なります。

| 終了ステータス | 意味 |
|:--|:--|
| 1 | 一般的なエラー |
| 2 | ビルトインコマンドの誤用 |
| 126 | コマンドを実行できなかった（実行権限がなかった） |
| 127 | コマンドが見つからなかった |
| 128 | exit に不正な値を渡した（例えば浮動小数点数） |
| 128+n | シグナル n で終了 |
| 255 | 範囲外の終了ステータス |

引用:
https://ja.wikipedia.org/wiki/%E7%B5%82%E4%BA%86%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9#bash

## 特殊変数 $?

直前に実行したコマンドの終了コードは`$?`という特殊変数に格納されています。
`echo $?`というコマンドを実行することで直前の終了コードを表示できます。
`echo`は引数の文字列や変数を表示するコマンドです。

## パイプの終了ステータス

```
# exit 2 | exit 1 | exit 0
```
こういうケース。
３つのコマンドをパイプで繋いでいます。
１つめと２つめはエラーを返すようになっています。

上記のコマンドの実行後に`echo $?`とすると、`0（正常終了）`が返ってしまいました。

パイプ元でエラーが発生していても正常終了扱いになってしまうので注意が必要です。
（たぶん、`最後に終了したコマンド`の終了コードが帰ってきます。)

簡単な解決策は２つあります。
ただし、Bash,Zsh以外のシェルでも使えるか不明なので注意すること。

### PIPESTATUS

```
# exit 2 | exit 1 | exit 0
# echo  ${PIPESTATUS[@]}
2 1 0
```
PIPESTATUSという配列変数で取得できます。

### set -o pipefail

pipefailを有効にすると、Pipeでエラーが有ったときそのエラーコードを返してくれます。

```
# set -o pipefail
# exit 2 | exit 1 | exit 0
# echo $?
2
```

## 関連：リダイレクトの終了ステータス

リダイレクト元かリダイレクト先のどちらかが終了ステータスを返したら
その終了ステータスを返します。

```
# echo aaa > .
# echo $?
1

#  cat . > file.txt
# echo $?
1
```
※`.`はディレクトリなので、書き込めずエラーになります。
UWPアプリをテスト用に配布する方法

UWPで作成したアプリケーションを、テスト用に自分のマシンにインストールしたり
テスターに配布する方法を記述します。

### ポイント

サイドローディング
証明書

### 前提
この記事の前提として、UWPをインストールするPCには
**Windows 10 Anniversary Update (Windows 10, version 1607)**
のアップデートが済んでいるものとします。

## はじめに

UWPは本来Windows10用アプリケーションなのでWindows Storeからインストールする必要がありますが、
Windows Storeで公開せずに自身のPCにインストールしたり、ほかのPCにインストールして動作検証したいケースがありますよね。
そのほか、UWPでつくった社内の基幹業務アプリ(LOB)をStoreで公開せずに社内のみで使いたいといったケースも考えられます。
上記の様なケースで、UWPで作成したアプリをStoreに公開せずにインストール・配布する方法を以下に記します。


## PCの設定を変更しよう
※UWPアプリをインストールするPC全てで行ってください。

Contanaで「開発」と打ち込んで、予測で出てきた「開発者向け設定」を選択してください。
![contana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77473/f1389a8f-d0d2-f16e-41d8-653a6f92b89d.png)

開発者向け設定画面で「アプリのサイドローディング」にチェックをつけます。
![開発者向け.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77473/2b83fcf9-c426-28b1-5609-d3a9aa4d7e55.png)

[ポイント]であげた「サイドローディング」が出てきましたね。
サイドローディングとは正規のストアの認証を受けていないアプリケーションをインストールする方法のことです。
ここでいう正規のストアはWindows Storeですね。
今回はStoreに公開せずにアプリを使いたいので、「アプリのサイドローディング」にチェックをつけました。

## UWPのアプリをパッケージングする
では次にアプリを配布する準備をしていきましょう。

１．UWPのソリューションを右クリック＞ストア＞アプリパッケージの作成
２．「いいえ」を選択
３．配布するパッケージの構成を設定します。
![パッケージの選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77473/9a3c85c0-f68f-eb24-2877-7826b6007455.png)

　出力場所：（デフォルト）アプリを作成したパス配下
　バージョン：自動的に増加
　アーキテクチャ：アプリを配布したいPCや組み込み機器のOSバージョンに合わせる

作成ボタンを押したら、出力場所に指定した場所にフォルダが作成されます。
![フォルダ一覧.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77473/99fe3b87-d348-cb8e-ae88-de9d9bdb9631.png)


AppPackageフォルダの中にはアプリを配布するのに必要なものが格納されたフォルダが作成されています。
このフォルダは、バージョンごとに作成されます。


## 必要なモジュールをインストールする
UWPアプリを動かすために、Dependenciesの中身をインストールしましょう。
※UWPアプリはexeファイルを実行しても動きません。


## 証明書をインストール
AppPackageフォルダ直下拡張子が「.cer」のファイルをダブルクリックします。
UWPアプリは証明書で署名する必要がありますが、サイドローディングの場合はパッケージングを行った際に発行された証明書をユーザーのデバイスにインストールすればOKです。
証明書の保存先をローカルコンピューターにして、「信頼されたルート証明機関」にインストールしてください。

## appxbundleをインストールします。
証明書のインストールが終わったら、appxbundleファイルをダブルクリックしてください。
アプリのインストールが始まりますので、終わりましたらContanaでアプリ名を入力してみてください。
インストールが無事終わっていればアプリがヒットしますので、
アプリを起動させてみてください。
無事動作することを確認して終了です！
Swiftにおけるreduceの使い方

#使いどころ

配列内の要素の合計値を求めるときなどに使います(実際のプロジェクトでreduceを見かけるのはほとんどこのパターンな気がします)。

では**要素内の合計値の求め方**を例にreduceの処理の流れを見ていきます。

```Swift:reduce.swift
let array = [1, 2, 3, 4, 5]
let result = array.reduce(0) { $0 + $1 }
print(result) // 15
```

reduceでは`{ }`の中身の処理が要素の数だけ繰り返されます。

###1周目
まず1周目ですが、`$0`にはreduce呼び出しの第一引数で指定した`0`が代入されます。一方、`$1`には配列の要素が順番に代入されていくので、この1周目では`1`が代入されます。したがって、`{ }`の中では`0 + 1`の結果である`1`が得られます。

###2周目
1周目の結果として得られた`1`が、2周目の`$0`に代入されます。つまり2周目以降は、前回の周で得られた結果が`$0`に代入されることになります。そして、`$1`は配列の要素が順番に代入されるので、今回は配列の2つ目の要素である`2`が代入されます。よって、`1 + 2`の計算が行われ、`3`が得られます。

###3周目
あとはこれの繰り返しになります。2周目の結果として得られた`3`が3周目の`$0`に、そして配列の要素の3番目である`3`が`$1`に代入されます。`3 + 3`で`6`が結果として得られます。

###4周目
`6 + 4`で`10`になります。

###5周目
`10 + 5`で`15`になります。そして、これで配列にあるすべての要素の処理が終わったので、resultには`15`が代入されます。

##最後に
今回は例として`{ }`の中で足し算の処理をしましたが、他には掛け算、あるいは文字列の結合などにも使えます。いずれにしても上記の処理の流れがわかっていれば応用が効く思うのでいろいろ試してみてください。

##ちなみに
僕は新しく知ったことを実際にコードで確かめたい時には[paiza.io](https://paiza.io/ja/projects/new)をよく使っています。ちょっとしたアウトプットをするときなどに重宝しています。
AnimationでDurationのデフォルト値について(Swift・Obj-C)

## はじめに

短い内容ですが、ググってもすぐに出てこなかったので記事にします。

## 知りたいこと

`UIPageViewController.setViewControllers` メソッドで `duration` のデフォルト値が知りたかったのですが、対象メソッドの公式ドキュメントには書かれていませんでした。
https://developer.apple.com/documentation/uikit/uipageviewcontroller/1614087-setviewcontrollers

## 結論

`setAnimationDuration(_:)` メソッドの公式ドキュメントに明記されていました。
https://developer.apple.com/documentation/uikit/uiview/1622617-setanimationduration

> The default value is 0.2 seconds.

AnimationのDurationは __0.2秒がデフォルト値__ です。

## おわりに

`setAnimationDuration(_:)` というメソッドがあるのを知らなかったので勉強になりました。

Twitterで教えていただいたので、感謝です:bow:
Rubyで音(wav)を書き出してみた

小ネタです。
Rubyで音声ファイルって作れないのかなと思ったら、こんな感じでやるとできそうです。

```bash
gem install numo-narray
gem install wavefile
```

サイン波っぽいの

```ruby
require "wavefile"
require "numo/narray"

include WaveFile

frequency = 440.0    # 生成するサイン波の周波数
seconds   = 1.0      # 生成する音の秒数
rate      = 44100    # 出力するwavファイルのサンプリング周波数

a = Numo::SFloat.linspace(0, 2 * Math::PI * frequency, rate) # 本当はrate+1として1個削るべき?
b = Numo::NMath.sin(a)
wave = b.to_a

buffer = Buffer.new(b.to_a, Format.new(:mono, :float, rate))

Writer.new("sin.wav", Format.new(:mono, :pcm_16, rate)) do |writer|
  writer.write(buffer)
end
```

三角波はこんな感じかな？

```ruby
require "wavefile"
include WaveFile
rate      = 44100

triangle = Array.new(100){|i|
  i < 50 ? i : 100 - i
}.map{|i| i / 50.0 - 0.5}

buffer = Buffer.new(triangle, Format.new(:mono, :float, rate))

Writer.new("triangle.wav", Format.new(:mono, :pcm_16, rate)) do |writer|
  441.times{writer.write(buffer)}
end
```

矩形波はこんな感じ？

```ruby
require "wavefile"

include WaveFile

rate      = 44100
kukei = Array.new(50, -0.5).concat(Array.new(50, 0.5))

buffer = Buffer.new(kukei, Format.new(:mono, :float, rate))

Writer.new("kukei.wav", Format.new(:mono, :pcm_16, rate)) do |writer|
  441.times{writer.write(buffer)}
end
```

FlammarionでGUI化してみると面白そうだ。

## 参考資料
[Python で音楽を作って楽しもう](https://qiita.com/yura/items/e5c6e9527215e0e0524a)
psexecの使い方備忘録

#psexecの使い方備忘録

###1.ポートの開放
・TCP 135番（RPCエンドポイント・マッパー）
・TCP 445番（ダイレクト・ホスティングSMB）
・TCP 1025～65535番（RPC動的ポート）
※RPC動的ポート は「%SystemRoot%\system32\services.exe」に対して許可します。

※https://www.projectgroup.info/tips/Windows/comm_0043.html を参考

リモート・コンピュータでユーザー・アカウント制御（UAC）が有効な場合、psexec実行時にアクセス拒否エラーが発生することがあった。その場合はUACを無効化する必要がある。
※https://www.atmarkit.co.jp/ait/articles/1205/11/news147.html  を参考
※僕は特にエラーは発生しなかった

###2.PsExec でコマンドの実行

```
psexec -u [ユーザー名] -p [パスワード] \\175.164.〇.〇〇 ipconfig
```

###3.気づいたこと

```
psexec -u [ユーザー名] -p [パスワード] \\175.164.〇.〇〇 cmd
```

でリモート・コンピュータ上でコマンド・プロンプトを起動するとき
Tabキーの補完機能は使用できないみたい

※https://4sysops.com/archives/psexec-vs-the-powershell-remoting-cmdlets-invoke-command-and-enter-pssession/
※https://www.howtogeek.com/school/sysinternals-pro/lesson8/
Laravel Mix + Vue.jsで CSS Modules を使えるようにする

# はじめに

[Atomic Design ～堅牢で使いやすいUIを効率良く設計する](https://www.amazon.co.jp/dp/B07CJ5TLK2) 、この本があまりに素晴らしくて、写経をしたいんだけど、実践で利用するのは Vue.js なので、読み替えて写経する必要がありました。

で、 https://github.com/katsuhiko/laravel-mix-template こちらで、 Docker + Laravel Mix で気軽に始めたんだけれども、コンポーネント内に CSS を閉じこめるところでつまづきました。

Vue.js には、 [スコープ付き CSS](https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html) があるんですが、 slot を使った時や、子コンポーネントの扱いでイマイチな気がして、 [CSS Modules](https://vue-loader-v14.vuejs.org/ja/features/css-modules.html) を使うことにしたんですが、少し手間がかかったので、記録として残します。


# webpack.mix.js の編集

CSS Modules を有効にするためには、 webpack.config.js の設定を追加する必要があります。

[Quick webpack configuration](https://laravel-mix.com/docs/4.0/quick-webpack-configuration) の「2.」 の方法、mix.webpackConfig() を利用する方法を今回は使います。

```javascript
const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    // CSS Modules を有効にするために以下を追加
    .webpackConfig({
      module: {
        rules: [
          {
            test: /\.css$/,
            loaders: [
              {
                loader: 'css-loader',
                options: {
                  modules: true,
                  localIdentName: '[local]_[hash:base64:8]',
                },
              },
            ],
          },
        ],
      },
    });
```


# component の作り方

設定が終われば、 CSS Modules を使ったコンポーネントの作り方は簡単です。

style タグで module 属性を指定し、CSSクラスを指定するときに $style オブジェクト経由で bind するのみです。

```vuejs
<template>
  <span :class="$style.balloon"><slot></slot></span>
</template>

<style module>
.balloon {
  background-color: #1a1a1a;
  border-radius: 2px;
  color: white;
  display: inline-block;
  font-size: 0.8rem;
  padding: 0.4rem 0.5rem;
  position: relative;
}

.balloon::after {
  border-color: #1a1a1a transparent transparent transparent;
  border-style: solid;
  border-width: 3px 3px 0 3px;
  bottom: 0;
  content: "";
  display: block;
  height: 0;
  left: 50%;
  position: absolute;
  transform: translate(-50%, 100%);
  width: 0;
}
</style>

<script>
export default {
}
</script>
```

上記コンポーネントを利用するために、テンプレートとして以下のように記述すると

```html
<balloon-el>次へ</balloon-el>
```

HTML として出力されるときには以下のようになっています。

```html
<span class="balloon_3tlcaaYA">次へ</span>
```

CSS Modules になっています！


# さいごに

Laravel Mix はビルドの動きを知らなくても気軽に使える利点はあるのですが、一歩先に進もうとすると、やはり動きを知る必要が出てきます。

導入系記事は多いんですが、カスタマイズになると情報・記事が少ない気もします。案外、一歩先に進む人は、自前で Webpack を整備するのかな。それとも Vue cli かな。

しばらくは、Laravel Mix を使おうと思うのですが、Storybook との兼ね合いでも、一手間かかりそうな気がしています。

Rails の Assets Pipeline は、自分には合わない感じだったので、もうちょっと Vue.js のことが理解できるようになったら、 Laravel Mix も合わなく感じでしまうかもしれないなーっと、CSS Modules を調べていて思いました。


# 参考

- https://github.com/JeffreyWay/laravel-mix/issues/1930
【VisualStudio 2019 for Mac】【C#】Mac用アプリ：ボタンを置く(追加)

#手順追記
storyboardとC#の処理の実装はファイルが分離しているのでVisualStudioでも個別に作業を進めることができる。
storyboardを変更してもdesigner.csを変更しても変更が有効になるようなのでルールは決めるべきなのか
※WARNINGに記載されている

##storyboard(XCode)
<img width="1111" alt="スクリーンショット 2019-05-26 22.25.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423985/99975db0-9822-a0b0-12ae-f02dd527d212.png">


##C#のコード(VisualStudio)
<img width="948" alt="スクリーンショット 2019-05-26 22.25.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423985/ed59aba4-9c3b-0750-1053-0c33a660d554.png">
create-react-app が Node.js 12.0.0 で動かない

## 問題

次のように create-react-app を動かそうとした（環境は Mac）：

```
$ npx create-react-app hello-react --typescript
$ cd hello-react
$ yarn start
```

しかしエラー：

```
#
# Fatal error in , line 0
# Check failed: U_SUCCESS(status).
#
#
#
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```

## 原因

ググったところ[同様の問題を扱った issue](https://github.com/facebook/create-react-app/issues/6908) を見つけ、そのなかで[次のコメント](https://github.com/facebook/create-react-app/issues/6908#issuecomment-487842410)を見つけた：

>If anyone is using Node.js 12.0.0, try to upgrade to 12.1.0. For me it is now working.

ちょうど [12.0.0 をインストールしていた](https://qiita.com/silmisilon/items/a2cc637eb7e59fa13f2c#nodejs-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)ので、12.1.0 にアップグレードすることにした。

## 解決

1. まず、Node.js 12.1.0 をインストールして、バージョンを 12.1.0 に切り替える（[ここの詳細は別の記事に書きました](https://qiita.com/silmisilon/items/be41110fa786fc514b9a)）
1. yarn をグローバルにインストールし直す（`npm install -g yarn`）
1. プロジェクトルート（`hello-react`）に移動し、`node_modules` を削除して、`yarn install` し直す（一応）
1. `yarn start` し直す

これで無事アプリが起動！

![スクリーンショット 2019-05-26 22.32.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155820/129468fa-6699-8d7f-55f4-6e0ed6b69d81.png)
sshポートフォワーディングで詰まったら確認すること

特定の許可されているサーバーからだけアクセスできるDBやwebページに接続する場合、sshでポートフォワーディングして、踏み台(特定のアクセス許可されているサーバー)経由で接続しに行く場合があると思います。うまく接続できない時のチェックポイント書きました。


## やりたいこと
EC2サーバー経由(3.113.xx.xx)でIPアドレスが表示される`https://www.cman.jp/network/support/go_access.cgi`に接続する。

## 文法の確認
`ssh -N 踏み台ホスト -L ローカルポート:リモートホスト:リモートポート`

実際に発行するコマンド:

```bash
ssh -N ec2-user@3.113.xx.xx -L 3333:www.cman.jp:80`
```

- `ローカルポート`を-Lオプションで接続先のポートにバインドします。
上記例ではローカルの`3333`経由でアクセスするように指定しています。このポート番号は他のアプリと被らなければ適当で問題ないと思います。

- `リモートホスト`はアクセス先のホスト名を指定しています。パス（network/support/go_access.cgi）は指定しなくてもドメイン以下はフォワーディングしてくれるようでした。
- `リモートポート`はhttp接続したいので80番を指定します。


ローカルのブラウザーから`127.0.0.1:3333//network/support/go_access.cgi`
に接続すると`www.cman.jp/network/support/go_access.cgi`のページが表示されIPアドレスがEC2サーバーのものになっているのがわかります。

![スクリーンショット 2019-05-26 22.18.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162167/5fc4afe4-42c7-99da-9cd0-2acc859eeaee.png)

## エラーが発生する場合

```bash

channel 2: open failed: administratively prohibited: open failed
```
- リモートサーバーで`/etc/ssh/sshd_config`に`AllowTcpForwarding`が許可されているか確認する。コメントアウトされていたらコメント外してyesにします。

```configuration

# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
AllowTcpForwarding yes
#       PermitTTY no

```

- リモートサーバーから当該のウェブページにアクセスできるか確認する

```bash

[ec2-user@ip ~]$ wget www.cman.jp
--2019-05-26 12:38:42--  http://www.cman.jp/
www.cman.jp (www.cman.jp) をDNSに問いあわせています... 157.65.27.7
www.cman.jp (www.cman.jp)|157.65.27.7|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/html]
`index.html' に保存中

    [ <=>                                             ] 9,865       --.-K/s 時間 0s

2019-05-26 12:38:42 (137 MB/s) - `index.html' へ保存終了 [9865]
```
できなければ名前解決ができているか、firewalldやiptablesなどでアクセスを遮断していないか確認します。
iptablesで設定するファイヤーウォールで、ポート番号を範囲指定する

## はじめに

今までiptablesでポート番号の口を空ける際に、1ポートづつスクリプトで空けてたため凄く設定に時間がかかっていました。
目に余ったのでググったら普通にやり方があったので覚書

## ポートの範囲は:で指定

通常のこんな風にdportにポート番号を1つ指定する代わりに、

```
iptables -A INPUT -p udp --dport 2085 -j ACCEPT
```

:でくくった範囲指定をします。

```
#i=2085, ..., 2900に設定するのと同じ働き
iptables -A INPUT -p udp --dport 2085:2900 -j ACCEPT
```

## 参考

[Turbolinux 11 Server: ユーザーガイド > 第 22章パケットフィルタリングと NAT	> 22.2. iptables のコマンド書式](https://www.turbolinux.co.jp/products/server/11s/user_guide/iptablescmd.html)
BigScreenで他画面環境構築

## BigScreen

VR環境でPCのディスプレイを表示させることができる。

主に動画やゲームをするときなど、疑似プロジェクタに使用できる。

また、ルームを作って他者と共有できるので疑似的なミーティングなども可能だ。

## 他画面環境

当然ながら、画面を複数作る場合、複数のディスプレイが必要である。

BigScreenは、例えば２枚の実機ディスプレイを持っている場合、２枚出すことができる。

しかし、ディスプレイポートが余っている場合、例えば３枚目を出すことができないだろうか？  
そのためには実機ディスプレイを買う必要があるのだろうか？

### ディスプレイエミュレータ

ということで、世の中にはそういう事を考える人がいるわけで、ディスプレイポートに指すことでパソコンに「ディスプレイが刺されている」と誤解させるための機器を作っている人がいる。しかも、３個で２千円もしないなど、とてもお手軽に他画面が構築できる。

> でも、実機がなければ見れないんじゃないの？

確かに、実機がなければ見れない。ただし、PCの中にはそのディスプレイ環境が作られている。ならば、複数のディスプレイのある環境からアクセスできるならどうだろう？

[![Image from Gyazo](https://i.gyazo.com/c2fc2a65f0793b94c9ae3da424195f79.jpg)](https://gyazo.com/c2fc2a65f0793b94c9ae3da424195f79)

この機器の本来の目的は、リモートディスプレイで充実した機器環境から簡素な環境にアクセスするために簡素な方でも他画面ディスプレイを構築するためのものである。

同様の論理が、BigScreenでも実現できた。

### 実際に他画面にしてみた。

通常、私は２画面のディスプレイをもっている。そこに対して、ディスプレイエミュレータを指してみた。

以下の画像のとおり、３枚目の機器が見事に表示できた。

[![Image from Gyazo](https://i.gyazo.com/6ab64eac95866288f5a2c12dc8f78979.png)](https://gyazo.com/6ab64eac95866288f5a2c12dc8f78979)

本当は、４枚、５枚と表示させたいところだが、それはPCの性能によることになる。私がつけているグラボでは、４画面まで表示できる。そのうち、１つはHTC Viveで表示させているので、最大３画面ということになる。

これを増やしたい場合は、グラフィックボードを買い足すか、USBディスプレイポートで増設するなど考えられるだろう。
【Nodejs】pm2で--expose-gcオプションをつける方法

## 【Nodejs】pm2で--expose-gcオプションをつける方法
このよう`--node-args`に指定します。
`pm2 start index.js --node-args="--expose-gc"`

pm２の公式クイックスタートドキュメントはこちら。
http://pm2.keymetrics.io/docs/usage/quick-start/

この記事が参考になれば幸いです。それでは。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
AWS Sysops 試験に失敗した話(2019年5月)

あまりにも悲しかったのでみなさまへの共有も含め、初投稿します。

著者の知識レベル
Linucレベル3持ってます。
AWSソリューションアーキテクト持ってます。

# 今回AWS Sysopsの受験を通して感じたこと

AWSソリューションアーキテクトを9割以上取れる知識があってもそれようの対策を講じなければ落ちるということ

その反省点を是非色々な方に生かしてほしいのでこの記事を書きます。


# その1 AWSソリューションアーキテクトの知識があれば余裕というのは運が良く受かっただけの意見(本当に頑張った方はすみません)

試験を受けての感想は、これは全くの別試験だと思われます。

そもそも前提がソリューションアーキテクトの知識がしっかりあれば大丈夫という噂を耳にし、試験に軽い気持ちで挑戦しました。

旧試験のころとは出題範囲全然違うので気をつけてください。

#その2 調べれば調べるほどジャンルの違うテスト

ソリューションアーキテクトはそれぞれのサービスの役目を全体的に俯瞰して覚えて、組み合わせてベストプラクティスに沿った構成にできているかを問う試験です。

Sysopsは運用者の視点に立った資格なので、セキュリティレポートの作成や診断の仕方、CloudFormationを用いた自動化の方法、S3をとことん掘り下げる問題。Trusted Advisorを用いた運用、などなど分野が完全に違います。


# 上記を踏まえこれから学習する方へのアドバイス

実際に運用経験が長期間ある方は別ですが短期間で努力し独学で臨む方も多いと思います。
その方達にまず伝えたいのは、しっかりSysopsの分野に特化した準備をすることです！ソリューションアーキテクトの知識がいくらあってもこの試験は受かりません！！


というわけでこの資格をこれから取る方に向けアドバイスとして学習した方が良い分野を送れたらと思います。

## <学習が特に必要な分野>
・AWS Trusted Advisorの深い知識
・CloudFormationの深い知識
・セキュリティレポートの作成方法
・AWS Artifactとはなにか
・タグによるリソースの管理
・S3の深い理解(バージョニング時の削除方法など)
・CostExplorerなど請求周りの理解
・脆弱性チェックの深い理解
・CloudWatchの理解
・IAMの組織アカウントに関する深い理解
・CLIのコマンド実行時のエラーへの対処方法(InsufficientErrorなど)


この辺が特にマストになると思います。

Sysopsの情報は非常に少ないので、これから学習される方の少しでも助けになれたらと思います。

思っていたより、多くの方にお読みいただけているので下記を加筆しました。
もしよければ、お読みください:relaxed:

------------------------------------------ 〜それから2週間後〜 --------------------------------------------------


なんと2週間で資格取得することに成功しました！

今回は前回の反省を生かして合格するために何をしたかを書いていきたいと思います。

#前回の振り返り

一言言えることはSysopsの試験をナメていました。

ソリューションアーキテクト余裕だったからと、この感じで勉強していれば受かるとの噂を聞き、余裕で大丈夫と思い込んでいたのです。

それで受かれるのはおそらく、問題の改訂がある前に受かった人だけでしょう。

改定後にもしそれで受かったのなら運が良かったと思うべきだと思います。

＜前回やっていた学習＞
AWS WEB問題集で学習しようを三周
ホワイトペーパーを読む
ソリューションアーキテクト極める
（2週間）

結果として前回は合格できませんでした。


#今回の取り組み

まず前回の反省をしました。
それを生かして、やらなければならないことはSysops用の対策でした。

受験時の記憶を頼りに必要な情報や学習をPickupし、それに絞り2週間学習に取り組みました。

＜学習内容(読んだ資料)＞
・下記のサービスのBlackBeltを読み込んだ
s3
Trusted Advisor
Organizations
Powershell
IAM
IAM2
guard duty
cost explorer
cloudformation
cloudwatch
config
cloudtrail
service catalog
AWS support
AWS shield
devicefarm ※これは出ないのでおまけです。


<この中でも特に理解が必要なのが>
TrustedAdvisor
IAM ※特に重要
costexplorer
Cloudformation ※特に重要
cloudwatchの他サービスとの連携
config
cloudtrail
service catalog
WAF

だと思います。

この辺を深く理解していないと全く太刀打ちできない試験になっています。
逆に本番環境でしっかりと、運用側の経験が数年ある方は割と簡単に感じるのかもしれません。


＜学習内容(問題集)＞
別にディスっているわけではないですが、個人的にはAWS Web問題集では受かる気がしませんでした。

※これは個人的な意見です。


## 補足：特にお勧めなサイト


Whizlabsという英語の問題集です。

https://www.whizlabs.com/

こちらをSysopsとDeveloperの学習に使用しました。

英語が苦手という方はGoogle翻訳のWebアプリを使用して、翻訳すれば本番と似たような感じで練習ができるのでかなり使えます。

似たような問題も10問くらいはあったので他のサイトよりはかなり本番に近い演習ができると思います。

ちなみに私は全演習を9割以上取れるまで繰り返しといて復習をして、ブラックベルトで知識の補填をすることでスムーズに合格できた気がします。

本番はかなり難しかったですが、太刀打ちするには良い学習法なのかなと思っています。


いかがでしたでしょうか。
資格試験に取り組むのもなかなか大変ですが、自分のキャリアのために挑戦することは大切だと思います。

この記事が皆様の学習の一助になれば幸いですし、受験に懸命に取り組む方を応援しています！

お読みいただきありがとうございました。
Django REST frameworkチュートリアル その４.２

# Associating Snippets with Users

前回の記事「[Django REST frameworkチュートリアル その４.1](https://qiita.com/John_sugai/items/77cf379bcc99f1b8b324)」の続きです。
[チュートリアルその4](https://qiita.com/John_sugai/items/16220349ab16f98de0b6)の記事で以下のTODOがありました。

> スニペットを登録するときに自動でリクエストを送った人が`owner`となるように登録したいです。

この機能を実装してみましょう。


## views.py

この実装はかなり簡単です。`SnippetList`クラスの`perform_create()`メソッドをオーバーライドするだけです。

``` snippets/views.py
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from snippets.permissions import IsOwnerOrReadOnly
from django.contrib.auth.models import User
from rest_framework import generics, permissions


class SnippetList(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [IsOwnerOrReadOnly]
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer


class UserList(generics.ListCreateAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetails(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [IsOwnerOrReadOnly]
    queryset = User.objects.all()
    serializer_class = UserSerializer
```

[公式ドキュメント](https://www.django-rest-framework.org/api-guide/generic-views/)を参照すると、

> `perform_create(self, serializer)` - Called by `CreateModelMixin` when saving a new object instance.

とあります。`perform_create`は`CreateModelMixin`から呼び出されて、新しいオブジェクトインスタンスを保存するときに呼び出されるメソッドのようですね。


## テスト

スニペットを新規作成するリクエストを送ってみましょう。

``` bash
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer <your access token>' -d '{"title":"hoge","code":"fuga"}' http://localhost:8000/snippets/
```

`owner`が自動で登録されるのが確認できたでしょうか。

以上でオーナーの自動登録は完了です。
ローカルマシンの仮想環境でXdebugを使うときの注意点

ローカルマシンの開発環境において、
ポートフォワードを使った構成のときに、
ホストOSのVSCode(Visual Studio Code)とゲストOSのXdebugが接続できなかったのでメモ。

## 結論
ポーフォフォワードでHTTPサーバにアクセスしてる場合は、
`remote_connect_back`を無効にする。
## 構成

Vagrant x Apache x PHP(XDEBUG）

```
ホストOSのブラウザ
↑↓
↑↓（ホストの8080ポートにゲストOSの80ポートをマッピング）
↑↓
ゲストOSのHTTPサーバ（ポート８０）
```

やりたいこと

```
ホストOSのVSCode
↑↓
ゲストOSのXDEBUG
```

## 設定内容

`/etc/httpd/conf/httpd.conf`

```
php_value session.auto_start 0
php_value xdebug.remote_autostart 1
php_value xdebug.remote_enable 1
php_value xdebug.remote_host XX.XX.XX.XX
php_value xdebug.remote_connect_back 1
 ```

## 問題点
 
`remote_host`でホストOSのIPを指定しているが、
`remote_connect_back`を有効にしてしまっていました。

`remote_connect_back`は、HTTPリクエストの送信元IPに対して、Xdebugが接続を行う設定です。
`remote_connect_back`は`remote_host XX.XX.XX.XX`より優先されます。

ホストOSはポートフォワードで、ゲストマシンの８０ポートにアクセスしてるため、
Xdebugは、`localhost`に接続を試みます。
Xdebugにとっての`localhost`はゲストOSのことなので、ホストOSのVSCodeとゲストマシンのXdebugは疎通できませんでした。

ポートフォワードを使ってWebサイトを表示している場合は、`remote_host XX.XX.XX.XX`を使って
ゲストOSから接続可能なホストOSのIPを指定してやりましょう。
heroku+railsでs3にsitemapを置く

# 目的

herokuだとsitemapを置けないためs3に置き、そこから読み込みをgoogleにさせる。

# 仕様概要

* sitemapgeneratorでsitemapを作成
* aws-sdkでs3に保存
* sitemap専用のルーティングを作ってそれをsearchconsoleに送信
* robots.txtにもsitemapの場所を記載

# aws-sdkでs3に保存

## sitemap.rbにsitemapの置き場所を記載

```sitemap.rb
SitemapGenerator::Sitemap.default_host = ""
SitemapGenerator::Sitemap.sitemaps_host = "https://s3-ap-northeast-1.amazonaws.com/#{ENV['S3_BUCKET_NAME']}"
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
  ENV['S3_BUCKET_NAME'],
  aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
  aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  aws_region: 'ap-northeast-1'
)
SitemapGenerator::Sitemap.create do
  # '/articles/:id' を追加する
  Post.find_each do |post|
    add post_path(post), :lastmod => post.updated_at
  end
end
```

default_hostでwebsiteのURLを登録。sitemaps_hostでsitemapのURLを登録する。

## herokuに環境変数登録

```
$ heroku config:add S3_BUCKET_NAME=bucket_name
$ heroku config:add AWS_ACCESS_KEY_ID=xxxxxxxxxxxxx
$ heroku config:add AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxx
```
## localはdotenvで環境変数登録

gemのdotenvを入れて環境変数の登録

# sitemap専用のルーティングを作る

```
get '/sitemap' => redirect('https://s3-ap-northeast-1.amazonaws.com/sitename/sitemap.xml.gz')
```

# robots.txtにsitemapの場所を記述

```robots.txt
Sitemap: https://sitename/sitemap
```
【論文紹介】 自動運転車両の動作計画の安全を確保するためのオンラインフェールセーフ検証

# 紹介する論文

[Christian Pek and Matthias Althoff. "Ensuring Motion Safety of Autonomous Vehicles through Online Fail-Safe Verification," In Robotics: Science and Systems - Pioneers Workshop, 2019.](http://mediatum.ub.tum.de/doc/1485322/593962292129.pdf)



# 論文の要約

- 自動運転のための安全を確保した動作計画（経路選択）法を提案する
- 周囲の障害物（他車など）が最も走行しそうな経路に加え，物理的に走行可能な領域まで計算する
- 自車が走行すべき経路に加え，周囲の障害物が走行可能な領域を外した地点にフェールセーフ経路を計画しておく
- 周囲障害物が交通ルールを無視するなどして衝突しそうな危険が発生した場合には，フェールセーフ経路に舵を切ることで安全を確保する



# はじめに

自律移動ロボットや自動車のための経路・動作計画は，非常にポピュラーな研究トピックの1つであり，これまでにも多くの研究が行われています．しかしながら「その安全性をどのように保証するか？」という問いに対する答えは，未だに未解決であるように思います（個人的に）．本論文では，オンラインの経路計画に加え，フェールセーフ経路計画まで行い，もし周囲の障害物と衝突の可能性がある場合には，フェールセーフ経路に舵を切ることで安全を確保する方法を提案しています．

なお本論文はワークショップの論文なので，詳細な数式やアルゴリズムが記載されていません．



# 手法の概要

大きく分けて2段階で構成されます．

### 到達可能領域の解析（reachability analysis）

まず周囲の障害物（他車など）が最も走行する可能性が高い経路（most likely trajectory）を計算します．これに加え，障害物が物理的に行うことが可能な行動（feasible behavior）や計測の不確かさやになども考慮して，到達可能な領域を計算します．「物理的に行うことが可能な行動」を考慮しているので，交通ルールに従わないような行動までも考慮されています．

### フェールセーフ経路の計算

フェールセーフ経路は，自車の目標経路から枝分かれした経路です．このフェールセーフ経路は，周囲の障害物が到着可能な経路までを考慮したものなので，**衝突しない安全な経路である**といえます．下図（論文中図1）に，フェールセーフ経路の例が示されています．

![fail-safe_trajectory_planning.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329950/74d273e8-9a62-c9ce-9cf5-adc27d116d1e.png)

もし障害物と衝突しそうな場合には，(1)フェールセーフ経路に従い走行する，(2)新たな目標経路とフェールセーフ経路の組を探索する，2つの戦略を取ることで，衝突回避を実現し，安全を確保します．



# シミュレーションによる検証

下図（論文中図2）に，シミュレーションの結果が示されています．3台の他車（$b1$，$b2$，$b3$）が存在する中で，それぞれの物理的に到達できる経路を計算しています．なおこの状況では，直進する自車が優先となっています．しかし実験では，$b2$が自車を見落としたと仮定し，T字路を自車より先に左折しようとします．ここで自車はフェールセーフ経路を計算しているので，衝突を回避することができています．なお自車は，6秒先の衝突までを予測しているとのことです．

![simulation_experiments.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329950/b555c267-a5b2-13d9-02aa-5fe7ec8f5341.png)



# 感想

経路・動作計画のほとんどの問題は，コスト関数などの最適化などで定式化されます．そのため，どのようにコスト関数を設計するかが，手法の性能を左右します．その中で，「安全を保証するコスト関数」と言われると，中々定義が難しくなりますが，それとは別に明示的にフェールセーフ経路を計算しておく，とすると，シンプルですが確かに効果的であるなと思いました．
Googleハングアウト等の、特定のポート番号を利用するサービスに関するまとめ

## はじめに

自宅のネットワークに対して自分でファイヤーウォールを設定していると、必要ないポートは基本全部塞ぐってスタンスの人も多いと思います。
その際に「よく使うサービス・機能が使えなくなった」ってことが結構あると思うので、このサービスではこれが必要だったってのをメモっておこうと思います。

## well-knownポートについて

well-knownポート、一般的なプロトコル用に用途が決まっているポートです。
こちらはWikipedia様の一覧を見れば事足りますのでリンクを貼っておきます。
[TCPやUDPにおけるポート番号の一覧](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)

一応自分が家のルーターに設定しているものを抜粋。

|機能|通信プロトコル|デフォルトポート番号|備考|
|:---|:---|:---|:---|
|DHCP|UDP|67, 68|ローカルネットワークのIP払い出し|
|DNS|UDP/TCP|53|名前解決|
|HTTP|TCP|80|各種HTTP通信|
|HTTPS|TCP|443|各種HTTPS通信|
|NTP|UDP|123|時刻同期用のプロトコル|
|SMTP|TCP|25|メール|
|SMTPS|TCP|465|メール、over TLS protocol|
|POP3|TCP|110|メールサーバーの設定による|
|POP3S|TCP|995|メールサーバーの設定による|

SSHについてはポートを変えているので未記載。
Linux環境化のSSHサーバーだったら、例えば以下のようにすれば設定からポート番号を引っ張ってきて穴あけを行うことが出来ます。

```shell:
#sshd_configのに設定されたポート番号を検索して、LOGINに代入
LOGIN=`cat /etc/ssh/sshd_config | grep '^#\?Port ' | tail -n 1 | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/'`
#取得したポート番号に対してACCEPT設定
iptables -A INPUT -p tcp -i ${LANIF} --dport $LOGIN -j ACCEPT
```

## その他サービスを利用する際に必要なポート番号

Youtube, Twitter, slackチャット, Qiita等、Webサービス全般は大抵HTTP/HTTPSのポート(+DNS等の外に出るためのポート)が空いていればOKでした。
ただ、一部サービスは+αのポートを利用する為設定追加が必要です。自分が出くわしたもの、使いそうなものを記載。なんか出くわしたら追記していきます。

- Googleハングアウト/ハングアウトMeet
    - UDPの19302-19309
        - ポートをふさいだ状態でもテスト通話は聞こえるが、通話すると画面が真っ暗なままになる。実際通話してみないと気付きませんでした。
- Line
    - 無料通話・ビデオ通話​: UDPの389, 443, 554, 9400-9420, 10000-60000
        - ポートをふさいだ状態だと、呼び出しはなるけど通話できず、そのうちエラーで切れます。
    - LINE Out: UDPの10000-60000
- Slackコール
    - UDPの22466、*.slack-core.comのホワイトリスト登録
- ニコニコ生放送
    - TCPの80、81～86、88～92、99、443、843、1935、2805～2899
        - ポートをふさいだ状態だと、枠だけ開くけど配信者の画面が真っ暗に映ります。

※各種サービスのホームページを調べれば大抵情報は乗っています。ただスマホゲームで情報がないものがあったりするのが難点。

## 参考

一般的な番号 Wikipediaより:
[TCPやUDPにおけるポート番号の一覧](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)

Googleハングアウト公式:
[G Suite 管理者ヘルプ - 1. ネットワーク接続の要件](https://support.google.com/a/answer/7582935?hl=ja)

Line設定(公式が無かったので、公式問い合わせをされた方のブログ):
[LINEで遊ぶ - 利用ポート一覧 -](https://www.gachatsuku.com/entry/2018/12/05/230000)

Slack公式:
[Slack コールのトラブルシューティング](https://get.slack.help/hc/ja/articles/115003538426-Slack-%E3%82%B3%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)

ニコニコ生放送公式:
[niconicoの動作環境](https://qa.nicovideo.jp/faq/show/1112?site_domain=default)
Django REST frameworkチュートリアル その４.１

# Object level permissions

前回の記事「[Django REST frameworkチュートリアル その４](https://qiita.com/John_sugai/items/16220349ab16f98de0b6)」の続きです。
前回の記事では認証処理を実装しましたが、その課題として以下のものがありました。

> トークンを持っていれば他の人のユーザー情報やスニペットの中身を書き換えることができてしまいます。変更や削除などのリクエストを送った人がそのデータのオーナーなのかをチェックしたいです。

はい。ということで、リクエストを送った人が編集したいデータのオーナーであるかのチェックをしたいと思います。


## permissions.py

自分でカスタムのパーミッションを作成する際には、`BasePermission`を継承して`has_object_permission()`メソッドをオーバーライドします。

新規で`permissions.py`を作成して、カスタムパーミッションを実装してみましょう。

``` snippets/permissions.py
from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """
    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the owner of the snippet.
        return obj.owner == request.user
```

コメントにある通り、`GET`、`HEAD`、`OPTIONS`メソッドなどの安全なリクエストは誰でも取得できますが、他のメソッドについては、リクエストを送った人とオブジェクトのオーナーが同じでないと認証が通りません。


## views.py

あとは`views.py`の`permission_classes`に上で作ったクラスを設定してあげるだけです。

``` snippets/views.py
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from snippets.permissions import IsOwnerOrReadOnly
from django.contrib.auth.models import User
from rest_framework import generics, permissions


class SnippetList(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [IsOwnerOrReadOnly]
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer


class UserList(generics.ListCreateAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetails(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [IsOwnerOrReadOnly]
    queryset = User.objects.all()
    serializer_class = UserSerializer
```


## テスト

あらかじめユーザーを2名以上作成しておきましょう。
以下のコードでそれぞれのユーザーでアクセストークンを取得します。

``` bash
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/oauth2/token/
```

そしてあるスニペットに対して2人のアクセストークンでそれぞれリクエストを送ってみてください。

``` bash
curl -X PATCH -H 'Content-Type:application/json' -H "Authorization: Bearer <your_access_token>" -d '{"code":"This is modified."}' http://localhost:8000/snippets/1/
```

そうするとスニペットのオーナーに対してはリクエストが通るのに対して、オーナーでないユーザーに対してはリクエストが拒否されるのが確認できるかと思います。

以上でオーナーのチェックは完了です。
EC2上で起動しているJupyter Notebookに、WindowsPCからアクセスする方法

## 前提
・Puttyを使って、秘密鍵を用いたEC2へのSSH接続ができる。
・EC2上にはすでにJupyter Notebookが入っている。


## ①EC2上でJupyter Notebookを起動する

```bash.
ec2-user$jupyter notebook
```

起動すると、下記のような形で、URLとトークンが表示される。

```bash.

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=<your token>
```

この＜your token＞をあとで使う。

## ②Puttyからトンネル接続
今開いているものとは別にPuttyを起動し、通常通りサーバにSSH接続する設定をする。
その上で
connnection→SSH→Tunnelsの画面に行き、下記画面のように設定をする。
![デスクトップ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167185/532289f2-c0f9-8176-7250-9840ee8f68f5.png)
以下の２つの欄を埋め、「add」を押す。
・Source port
　自分のローカルWinマシンからアクセスするポート番号を指定。
　開いているポートであればなんでもOK。
・Destination
　「localhost:8888」と入力。
※他はデフォルトでOK。

上記の設定をしたプロファイルで、もう一度Jupyter Notebookが起動しているサーバにSSH接続をする。

## ③ローカルマシンのブラウザからJupyterに接続
ブラウザを起動し、下記のフォーマットのURLへ移動する。
＜your port＞には上記で指定したSorce portを記載する。例えば画像の例では、「ttp://localhost:8157/login」となる。
```URL.
http://localhost:<your port>/login
```
上記URLを訪れると、下記のような画面が表示される。
![デスクトップ５５.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167185/73d4ab23-0669-007d-2101-7dc469a060fd.png)

一番上部にある「Password or token:」の右隣の空欄に、先程の＜your token＞を入力する。
そうすると、ログインに成功して、いつものJupyter Notebookの画面に移動できる。
![デスクトップ３３３.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167185/f65b3bb4-b0f8-f942-c41b-37a99de9c97b.png)
LaravelでクエリビルダのJoinを使って検索機能を作ろうとしたらハマった

当方、Laravel初心者です。

`Eloquentモデル`をクエリビルダの`join()`を使って関係するテーブルのカラムを使って絞り込んだら、
検索対象じゃないモデルのインスタンスが返ってきて小一時間悩みました。

## まとめ
`Eloquentモデル`をクエリビルダの`join()`を使ってインスタンスを取得したら、
`id`というカラムが複数存在したため、
想定外のインスタンスが返ってきた。
↓
同じカラム名はLaravel内の処理で上書きされる。
`Select()`で取得するカラムを絞ろう!

## 詳細
たとえばこんなコード。

```php
$searched_posts = Post::join('comments', 'posts.id', '=', 'comments.posts_id')
  ->where('comments.text', 'like', '%あいうえお%')->get();
```

`posts`テーブルにも`comments`テーブルにも「`id`」というカラムがある前提です。

上記のコードをSQLに変換されると多分こんな感じになります。

```sql
select * from posts 
  inner join comments on posts.id = comments.post_id 
  where comments.text LIKE '%あいうえお%';
```

仮にSQLの実行結果が以下のような感じだったとします。


| id|post_content|id|text|
|:--|:--|:--|:--|:--|
| 1|あああ|2|あいうえお|
| 3|ううう|3|あいうえお|
| 5|おおお|4|あいうえお|

これで`Post`モデルのインスタンスが３つ取れて、
`post_content`はそれぞれ`「あああ」「ううう」「おおお」`となるんだろうな　とおもったら
なぜか全然違うPostが返ってきました。

そうです。
`id`カラムが重複して存在するため、
`posts.id`を`comments.id`が上書きしてしまい、
`id`が`2`,`3`,`4`である`Post`がモデルインスタンスとして取得されてしまいました。

## 解決策

selectで取ってくるカラムを絞る。

```php
$searched_posts = Post::select('posts.*')->join('comments', 'posts.id', '=', 'comments.posts_id')
  ->where('comments.text
', 'like', '%あいうえお%')->get();
```
`select('posts.*')`のように、取得するカラムを絞り込むことで、`id`というカラムが重複しないようにしましょう。

こういうハマりポイントは知っていればすぐ解決できるのに、知らないと結構はまってしまいますよね。
Laravelを覚えるにあたって先にハマりポイントを押さえておこうと思いました:frowning2:

そもそもクエリビルダのJoinを使って検索をするっていうのがイケてないっぽいので
よりよい方法があれば教えていただきたく思います。

`whereHas()`を使うといいのかな？

```php
Post::whereHas('Comment', function($comment){
    $comment->where('text', 'like', '%あいうえお%');
```

以上、お役に立てれば幸いです

## 参考
[laravelのクエリビルダでJOINしたら、同名カラムの値が上書きされるという事案発生](https://qiita.com/pipiox/items/395bef543e16c93a1fa6 )
[Laravel Eloquent でハマらないために知っておきたいこと](https://qiita.com/ttaka/items/ab7cb9e4022756ad8206)
JavaScript配列の空文字を削除

`filter()`メソッドを使って配列の空文字、`null`、`undefined`を削除する

## filter(Boolean)
```js
var arr = ["hoge", "", "123", " ", "0", 123, 0, null, undefined];

arr.filter(Boolean); //["hoge", "123", " ", "0", 123]

// アロー関数式
arr.filter(n => n); //["hoge", "123", " ", "0", 123]
```

### 説明
上の使い方をテスト関数を作成して、引数で渡す方式で書くとこうなる

```js
function isTrue(value) {
  return Boolean(value);
}

var arr = ["hoge", "", "123", " ", "0", 123, 0, null, undefined];
arr.filter(isTrue); //["hoge", "123", " ", "0", 123]
```

`filter()`はテスト関数が`false`を返す要素は取り除かれる。

この場合は各要素を`Boolean`に変換すると空文字、`null`などは`false`になるので、取り除かれる。

### 注意すること
+ `Number`の「0」も消えちゃうこと
+ 空白(スペース)は消えないこと

## 参考
+ MDN web docs
    + [filter()] (https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
    + [Boolean] (https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean)
JavaScriptの非同期処理はasync/await/Promise

#JavaScriptの非同期処理についてまとめた
今週からモダンなJavaScriptを使った開発案件にjoinすることになりました。
JavaScriptなら専門学校でも勉強したしいける！と思っていましたが、最近のJavaScriptは色々と複雑なうえに、そもそも入門レベル（苦笑）しか無かったので改めて勉強しようとおもいました。

今回は同期処理と非同期処理の違い、そして非同期処理の取り扱い方について書いていきます。

#同期処理と非同期処理

- 同期処理（sync）・・・コードを順番に処理していき、ひとつの処理が終わるまで次の処理をしない
- 非同期処理（async）・・・処理が終わるのを待たずに次の処理をする

#同期処理
```javascript:test.js
const a = () => console.log("a");
const b = () => console.log("b");
const c = () => console.log("c");

a()
b()
c()
```
```:実行結果
a
b
c
```
普通に書くと上から順番に実行されます。これが**同期処理**です。a→b→cの順番で書いてあるわけですから、実行結果がその順番になるのは当然です。
#非同期処理
```javascript:test2.js

const a = () => console.log("a");
const b = () => {
  setTimeout(() => {
    console.log("b")
  }, 1000);
}
const c = () => console.log("c");

a()
b()
c()
```
```:実行結果
a
c
b
```
次にbの処理を書き換え、**実行されて1秒待ってからbを表示**するようにしました。
>
setTimeout関数は、第一引数に関数、第二引数に時間（ミリ秒）をとります。そして第二引数の時間経過後に第一引数を実行します。上のように第一引数の中に関数をぶち込んでもいいし、別で定義しても構いません。

結果a→b→cの順番で呼び出したのに、コンソール上の結果はa→c→bの順番になってしまいました。何が起きたのかというと、bの中にあるsetTimeout関数の結果を待たずに次のcが実行されたのです。
setTimeout関数のように、実行結果を待たずに次の処理が実行されてしまうものを**非同期処理**といいます。書いた順番と違った順番で処理される可能性があるわけですね。

それでも「俺はこの順番に実行したいんじゃー」という時があるとおもいます。例えばあるデータを外部から取ってきて計算したい場合、データが返ってくる前に計算は不可能ですよね。時間がかる処理があっても決まった順番に処理したい場合は以下のような対策があります。

#Promise
```javascript:test3.js
const a = () => console.log("a");
const b = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("b")
      resolve();
    }, 1000);
  });
}
const c = () => console.log("c");

a()
b().then(c)
```
```:実行結果
a
b
c
```
これで無事解決です。

ポイントは`Promise`インスタンスを生成して返却する点です。
Promiseは関数を引数にとりますが、その関数の第一引数に`resolve`、第二引数に`reject`（省略可）の2つのコールバック関数をとります。この2つの名前は適当でもいいです。そして処理の成功時はresolveメソッドを実行してあげます。

あとは実行時に`then`メソッドを実行し、引数に次に実行したい関数を入れれば完成です。

```javascript:test4.js
//実行部分
a()
b().then(c).catch(d)
```
もし「外部にデータを取りに行ったけど、データが取ってこれませんでした」という時には、resolveメソッドではなくrejectメソッドを実行してあげてください。データが取れたかどうかで条件分岐すると良いですね。そしてthenメソッドの次に`catch`メソッドを書き加えればOKです。

上の例は成功すればc、失敗ならdを実行します。

#async/await

```javascript:test5.js
const abc = async() => {
  const a = () => console.log("a");
  const b = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("b")
        resolve();
      }, 1000);
    });
  }
  const c = () => console.log("c");

  a()
  await b()
  c()
}

abc();
```
```:実行結果
a
b
c
```
1行目ですが、今までの処理を関数abcでまとめて、`async`を付けました。
asyncを付けた関数は必ずPromiseインスタンスを返します。そしてasync関数内では`await` を使えます。こうすることでawaitが付けられた関数の処理を待ってから次の処理を行います。thenをつなげて書くよりも、見た目が同期処理っぽく書けるのが良い点です。

#まとめ
JavaScriptの非同期処理は**async/await/Promise♪**（タイトル回収）

#参考
js-prime　非同期処理　https://jsprimer.net/basic/async/