OmniAICreator/Qiita-1.07M huggingface dataset:
AWS IAM

# AWS Identity and Access Management について
まずはじめに用語整理

* リソース
    * IAM に保存されているユーザー、グループ、ロール、ポリシー、および ID プロバイダー。AWS サービスと同様に、IAM のリソースを追加、編集、削除することができます。
* ID
    * 識別し、グループ化するために使用される IAM リソースオブジェクト。IAM ユーザーにポリシーをアタッチすることができます。ユーザー、グループ、およびロールなどがあります。
* エンティティ
    * AWS によって認証に使用される IAM リソースオブジェクト。たとえば、IAM ユーザー、フェデレーションユーザー、引き受ける IAM ロールです。
* プリンシパル
    * AWS にサインインし、リクエストを作成するために AWS アカウントのルートユーザー、IAM ユーザー、または IAM ロールを使用する人またはアプリケーション。

> AWSユーザーに対して AWSのリソースへのアクセスできる範囲やアクセス方法を安全に制御するためのウェブサービスです。IAM により、どのユーザーが AWS リソースを使用できるか（認証）、また、それらのユーザーがどのリソースをどのような方法で使用できるか（認可）を制御できます。

##IAM のベストプラクティス
* AWS アカウントのルートユーザー アクセスキーをロックする
    * MFAを設定すること
* 個々の IAM ユーザーの作成
* IAM ユーザーへのアクセス許可を割り当てるためにグループを使用する
* 最小権限を付与する
    * IAM ポリシーを作成する場合、最小限のアクセス権を付与するという標準的なセキュリティアドバイスに従うか、タスクの実行に必要なアクセス許可のみ付与
* AWS 管理ポリシーを使用したアクセス許可の使用開始
* インラインポリシーではなくカスタマー管理ポリシーを使用する
* ユーザーの強力なパスワードポリシーを設定
* MFA の有効化
* Amazon EC2 インスタンスで実行するアプリケーションに対し、ロールを使用する
* ロールを使用したアクセス許可の委任
    * アカウント間でセキュリティ認証情報を共有しない
* アクセスキーを共有しない
* 認証情報を定期的にローテーションする
* 不要な認証情報を削除する
* 追加セキュリティに対するポリシー条件を使用する
* AWS アカウントのアクティビティの監視
    * Cloudfront
    * CloudWatch
    * CloudTrail
    * Config
    * S3


##IAM Access Analyzer とは
> IAM Access Analyzer は、アカウント内のどのリソースを外部プリンシパルと共有しているかを知らせます

### サポートされているリソースタイプ
* Amazon Simple Storage Service バケット
* AWS Identity and Access Management ロール
* AWS Key Management Service キー
* AWS Lambda の関数とレイヤー
* Amazon Simple Queue Service キュー

##Amazon EventBridge による AWS IAM Access Analyzer のモニタリング
>Access Analyzer は、各結果の生成時、既存の結果の状態の変更時、および結果の削除時に EventBridge にイベントに送信します。結果および結果に関する通知を受信するには、Amazon EventBridge でイベントルールを作成する必要があります。イベントルールを作成するときに、ルールに基づいてトリガーするターゲットアクションを指定することもできます。たとえば、新しい結果のイベントが Access Analyzer から返されたときに Amazon SNS トピックをトリガーするイベントルールを作成できます。

[EventBridgeについて](https://qiita.com/fjisdahgaiuerua/items/b822131ca41dadd50abd)

#参考文献
* AWS再入門 AWS IAM (Identity and Access Management) 編
    * https://dev.classmethod.jp/articles/cm-advent-calendar-2015-getting-started-again-aws-iam/
*
虫の頭でcoffeescriptを理解しようとしてみる。クラスの継承とメソッド書き換え

虫クラスの中で妙にカマキリが多いので、クラスを継承して新しくカマキリクラスを作る

```coffeescript:musi.coffee
class 虫
  
  名前:"捕まえた虫の名前"
  
  constructor:(名前)->
    if 名前?
      @名前=名前
  
 特徴:(文章,数)->
     console.log("特徴:#{文章}#{@名前}#{数}匹捕まえた")
```

クラスの継承は親クラスをextendsで行う

```coffeescript:musi.coffee

class カマキリ extends 虫
```

メソッドの書き換えは同じメソッド名でまたメソッドを書くと自動的にできる

```coffeescript:musi.coffee

  特徴:(文章,数)->
    console.log("特徴:#{文章}カマキリ:#{@名前}#{数}匹捕まえた")
    
虫1=new カマキリ("オオカマキリ")
虫1.特徴("体が大きい",2) 
#特徴:体が大きいカマキリ:オオカマキリ2匹捕まえた

```
【httpclient】でのリクエストからcontrollerまでの流れについて確認とリファクタリング

#はじめに
以前、JQueryのautocomplete、ajax、そしてhttpclientを使いオートコンプリートを実装したが、内容についてぼんやりとしか把握できていなかった。リファクタリングを行いつつ、内容を確認していく。

まず、外部APIにアクセスしている部分は、クラスに切り出し、libディレクトリに入れる。
lib/api_suggest.rb

```ruby
require 'httpclient'
require 'json'

class ApiSuggest
  API_KEY = Rails.application.credentials.api[:API_KEY]
  API_URI = Rails.application.credentials.api[:API_URI]

  def self.suggest(keyword, max_num)
    uri = API_URI
    headers = {
      Authorization: "Bearer #{API_KEY}",
    }
    params = {
      keyword: keyword,
      max_num: max_num,
    }

    client = HTTPClient.new
    req = client.get(uri, body: params, header: headers)
    req
  end
end
```
リファクタリング前は、

```ruby
    client = HTTPClient.new
    req = client.get(uri, body: params, header: headers)
    res = JSON.parse(req.body)
    res
```
と、`JSON.parse(req.body)`を行っていたが、
リファクタリング後は、

```ruby
req = client.get(uri, body: params, header: headers)
```
client.getした結果をである`req`部分をそのままコントローラーに返し、

コントローラー側では、
app/controllers/suggests_controller.rb

```ruby
require 'api_suggest'
class SuggestsController < ApplicationController
  SUGGEST_MAX_COUNT = 5
  def search
    @suggests = ApiSuggest.suggest(params[:keyword], SUGGEST_MAX_COUNT)

    render body: @suggests.body, status: @suggests.code
  end
end
```
7行目の、renderで、

```ruby
render body: @suggests.body, status: @suggests.code
```
各パラメータに入れる事で`JSON.parse`する必要がなくなった。

そして、そのパラメータが、
app/assets/javascripts/suggest.js

```js
$("#form").autocomplete ({
  source: function (req, res) {
    $.ajax({
      url: '/suggest',
      type: 'GET',
      cache: false,
      dataType: "json",
      data: { keyword: req.term },
  n    success: function (data) {
        res(data);
      },
      error: function (xhr, ts, err) {
 n       res(xhr, ts, err);
      }
    });
  }
});
```
ajaxのsuccess以下に返されるという流れになっている。

##全体の流れを確認
ajaxのオプションで指定している
`url: '/suggest'`にリクエストが送られ、
ルーティングで

```ruby
get 'suggest',    to: 'suggests#search'
```

`app/controllers/suggests_controller.rb`のsearchメソッドが呼ばれ、

```ruby
  def search
    @suggests = ApiSuggest.suggest(params[:keyword], SUGGEST_MAX_NUM)
    render body: @suggests.body, status: @suggests.code
  end
```
`ApiSuggest.suggest`によりhttpclientでの外部APIリクエストを介した結果、

`render body: @suggests.body, status: @suggests.code`
が返されて、

`app/assets/javascripts/suggest.js`のajax

```
success: function (res) {
  resp(res);
},
error: function (xhr, ts, err) {
  resp(xhr, ts, err);
}
```
成功、失敗それぞれのケースに返される。
という流れ。

##ajax部分について詳しく
render bodyのオプションが、戻り値の本体を返していて、
statusがステータスコード(200, 404, 500など)の外部APIの結果が返される。

ajax側でそれを受け取ると、
ajaxの中では、そのstatus codeを参照して、200系、300系を正常として判定して、success側を実行。

それ以外のstatus codeがきたらerror側を実行、
という処理を行っている。

以上。

#終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
amazon-ssm-agentのバージョン確認方法

AmazonLinux2であれば、以下コマンドで確認できます。

```
$ sudo yum info amazon-ssm-agent
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
インストール済みパッケージ
名前                : amazon-ssm-agent
アーキテクチャー    : x86_64
バージョン          : 2.3.662.0
リリース            : 1.amzn2
容量                : 61 M
リポジトリー        : installed
要約                : Manage EC2 Instances using SSM APIs
URL                 : http://docs.aws.amazon.com/ssm/latest/APIReference/Welcome.html
ライセンス          : ASL 2.0
説明                : This package provides Amazon SSM Agent for managing EC2 Instances using SSM APIs

利用可能なパッケージ
名前                : amazon-ssm-agent
アーキテクチャー    : x86_64
バージョン          : 2.3.714.0
リリース            : 1.amzn2
容量                : 15 M
リポジトリー        : amzn2-core/2/x86_64
要約                : Manage EC2 Instances using SSM APIs
URL                 : http://docs.aws.amazon.com/ssm/latest/APIReference/Welcome.html
ライセンス          : ASL 2.0
説明                : This package provides Amazon SSM Agent for managing EC2 Instances using SSM APIs
```
Unityでゲームつくりてえ。：Dpad（十字キー）をなんとかしてえ。

※書きかけの記事だよ★

ゲームパッドの十字キーの取り扱いが非常に難儀と聞き、やってみたら難儀でした。
のちのち調べて表埋めしたい。
以下まとめ。


# 経緯
- ゲームパッドは厄介、Dpadは特に厄介、という話は聞いていた
- unity1week の影響で、WebGLでビルドすることを意識しはじめた
  - Mac勢は多い、ということにいまさら気付いた
  - エディタ内テストで期待通りに操作できてたのに、WebGLにビルドすると違う動作をする！
- ちゃんと調べて対応しないと「うごかないよお」て人が思ったより増えるのでは


# 環境別対応表
|検証済み|ビルド先|OS|ゲームパッド|横軸（Horizontal）|縦軸（Vertical）|
| ---- | ---- | ---- | ---- | ---- | ---- |
|○|エディタ内|Win|PS4|7軸|8軸|
|-|エディタ内|Win|XBox|6軸|7軸|
|-|エディタ内|Win|PC|?|?|
|-|エディタ内|Mac|PS4|8ボタン、7ボタン|5ボタン、6ボタン|
|-|エディタ内|Mac|XBox|?|?|
|-|エディタ内|Mac|PC|?|?|
|○|WebGL|Win|PS4|6軸|7軸|


# ひとりごと
- そのゲームパッドが「なに経由で動いているか」みたいな話なのかなー（XInputとかそのへん）。
- GamepadAPIというものがあることを知った。


# 参考記事
https://ch.nicovideo.jp/tenoji/blomaga/ar1646706
https://qiita.com/o_s_t/items/c18edeeee869d42c6eb9
https://developer.mozilla.org/ja/docs/Games/Techniques/Controls_Gamepad_API
TSLintとPrettierのVSCodeへのインストールと使用方法

Angularでの開発時に便利なプラグインの「TSLint」と「Prettier」について説明します

・TSLintとはTypescript用の静的コード解析ツール
・Prettierとはコードフォーマッター

#VSCode拡張機能でのインストール
　1.「ファイル」>「ユーザ設定」>「拡張機能」を選択します
　　![拡張機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/49ed5998-cb93-b9ea-636d-38496b1416cd.png)

　2.検索欄にTSLintと入力します（Prettierも同様です)
　　![検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/ce7e0010-0e48-5a89-e5d1-c5cc4d553b20.png)

　3.インストールボタンを押下してインストールします
   ![インストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/4aeea301-6dd4-1d3a-3992-2539635d89af.png)

　これでインストールは完了しました。

#設定
　デフォルトでは１行あたりの文字数がTSLintでは140文字、Prettierでは80文字となっており、一致していない上に80文字ではソースが見づらくなってしまう(私の個人的趣味かもしれないが)ので設定を変更します

　・TSLintでの設定
　　プロジェクト下にtslint.jsonというファイルができているので、そのファイルを開き"max-line-length"の値を修正します。
　　自分は150文字にしました。

```
  "max-classes-per-file": false,
    "max-line-length": [true, 150],
    "member-ordering": [
      true,
      {
        "order": ["static-field", "instance-field", "static-method", "instance-method"]
      }
    ],
```

　　それ以外の設定については、https://palantir.github.io/tslint/rules/ を参照

　・Prettierでの設定
　　プロジェクト下に.prettierrcを作成し、そこに値を設定します

```
{
  "printWidth": 150
}
```

　　それ以外の設定については、https://prettier.io/docs/en/options.html を参照

#使い方
　・Prettierは保存時(Ctrl+S)に自動整形してしてくれます
　・TSLintは編集領域や問題タブに指摘内容が出ますのでそれの合わせて修正してください
　　![問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377078/bd091c3f-dfb7-739a-a4ee-21df2bdb4720.png)
[rails]開発中に使うコマンド一覧

## 【Git】

<details><summary>コマンド一覧</summary><div>

### マージリクエスト作成

```
$ git status
$ git add -u
$ git commit -m "#[イシュー番号] コミットメッセージ"
$ git push origin ブランチ名
```

### ブランチの新規作成

```
$ git checkout -b <ブランチ名>

名前の付け方は以下を参照
　・バグ修正 →    (hotfix/{issue番号}_{fix_機能説明})
　・新規機能追加 → (feature/{issue番号}_{feature_機能説明})
```

### ブランチの移動

```
$ git checkout main
$ git checkout ブランチ名
```

### ブランチの管理

```
# ブランチ一覧
$ git branch

# リモートブランチの最新化
$ git pull

# ローカルブランチの削除
$ git branch -D ブランチ名

# リモートブランチの削除
$ git push --delete origin ブランチ名

# 前回のコミットまで戻す
$ git reset --hard HEAD
```


### 書いた内容の避難(コミットする前にブランチを変更したい時など)

```
# 書いた内容を一時避難
$ git stash

# 一時避難した内容を戻す
$ git stash apply
```

### コンフリクトが起きた場合の対処
mainを最新化し、その差分を作業中のブランチに反映させる

```
$ git checkout main
$ git pull
$ git checkout ブランチ名
$ git merge master
```
</div></details>

## 【Docker】

<details>
<summary>コマンド一覧</summary>
<div>

### よく使うコマンド

```
# コンテナ内へ入る
$ docker exec -it コンテナ名 bash

# コンテナの再起動
$ docker-compose restart

# コンテナの削除
$ sudo docker ps -a
$ docker rm [コンテナID]
```

### Dockerのコンテナが起動しない場合

```
# エラー内容を確認
$ docker-compose logs

# 確認したエラーが「A server is already running.」の場合
$ rm tmp/pids/server.pid
```
</div></details>

## 【DB操作】 

<details>
<summary>コマンド一覧</summary>
<div>

:::note warn
※railsコンソール上での操作になります
:::

```:
# データの全削除
$ モデル.destroy_all

# データの上書き
$ モデル.find(ID).update_attribute(:カラム, "上書きする内容")
例：→ $ User.find(10).update_attribute(:name, "たろう")
```
</div></details>

## 【マイグレーションファイルの操作】

<details>
<summary>コマンド一覧</summary>
<div>

```

# マイグレーションの設定(必要あればseedも流す)
$ rails db:migrate
$ rake db:seed

# マイグレーションの確認
rails db:migrate:status

# 1つ前へルールバック
$ rails db:rollback

# バージョンを指定してロールバック
$ rails db:migrate:down VERSION=●●●●

# マイグレーション内容をリセット
$ rails db:reset

```
</div></details>

## 【Jem】

<details>
<summary>コマンド一覧</summary>
<div>

```
# インストール
$ bundle install

# 削除
$ bundle exec gem uninstall
```
</div></details>
JavaはExcelを画像、html、XPS、XML、CSV、PostScript、PCLに変換します

Excel文書の日常の運用では、さまざまな作業場面のニーズを満たすために、文書の形式を変換する必要があることがよくあります。この記事では、Javaプログラムでコードを使用してExcelを画像、html、XPS、XML、CSVに変換する方法を示します。

**使用ツール：** Free Spire.XLS for Java（無料版）

**JARファイルのインポート方法**
**方法1：** [Free Spire.XLS for Java](https://www.e-iceblue.com/Download/xls-for-java-free.html)パッケージをダウンロードして解凍し、Spire.Xls.jarパッケージをlibフォルダーからJavaアプリケーションにインポートします。
**方法2：** mavenを使用している場合は、pom.xmlファイルに次の依存関係を追加する必要があります。

```java
<repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
			<url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls.free</artifactId>
        <version>2.2.0</version>
	</dependency>
</dependencies>
```

**Javaコード例：**

```java
import com.spire.xls.*;

public class ExcelToImg {
    public static void main(String[] args) {
        //Excelワークシートを読み込む
        Workbook wb = new Workbook();
        wb.loadFromFile("input.xlsx");

        //ワークシートを取得
        Worksheet sheet = wb.getWorksheets().get(0);

        //画像としてExcelワークシートを保存
        sheet.saveToImage("ToImg.png");
        //Excelで指定したセルのデータ範囲を画像として保存する
        //sheet.saveToImage("ToImg2.png",8,1,30,7);

        //ExcelをHTMLとして保存
        sheet.saveToHtml("ToHtml.html");

        //ExcelをXPSとして保存
        sheet.saveToFile("ToXPS.xps", String.valueOf(FileFormat.XPS));

        //ExcelをCSVとして保存
        sheet.saveToFile("ToCSV.csv", String.valueOf(FileFormat.CSV));

        //ExcelをXMLとして保存
        sheet.saveToFile("ToXML.xml", String.valueOf(FileFormat.XML));

        //ExcelをPostScriptとして保存
        sheet.saveToFile("ToPostScript.postscript", String.valueOf(FileFormat.PostScript));

        //ExcelをPCLとして保存
        sheet.saveToFile("ToPCL.pcl", String.valueOf(FileFormat.PCL));

    }
 }
```

**ドキュメントの変換結果：**
![convert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/6d6e503b-60d0-a2b7-3b49-a933b182373b.png)
Blender 2.8 以降における寸法(メートルなど)表示法

Blender 初心者です。
色々調べていると、Blender 2.7 の情報がヒットして、Blender 2.8 と UI が大幅に異なっているようで、混乱したためメモとして残します。

# Units の単位設定

`Properties` (Shift+F7) > `Scene Properties` (液体っぽいアイコン) > `Units`

から、`Unit System` を `Metric` にし、距離をメートルに設定。

また、自分の設定したい単位に合わせ、2つのパラメータを変更する。

- センチ単位の場合: `Length` を `Centimeters` / `Unit Scale` を `0.01` に設定
- ミリメートル単位の場合: `Length` を `Millimeters` / `Unit Scale` を `0.001` に設定


# 寸法の表示

`3D Viewport` (Shift+F5) から `Edit Mode`(Tab) へ入り、`Viewport Overlay`(○と●がちょっと重なってるアイコン) の ▽ を押し、割と下のほうにある `Measurement` から、以下の寸法にチェックを入れることで、表示を切り替えられる。

- Edge Length
- Edge Angle
- Face Area
- Face Angle

![コメント 2020-05-18 110457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208566/3d0a5606-1101-ed68-0d93-1889ef76d5e4.png)


以上


# 参考資料

- Blender 2.8 - Edge info and Face info: https://stackoverflow.com/questions/55093872/blender-2-8-edge-info-and-face-info
SAP試験振り返り

#第一回　５５７
* 十分な知識を有する分野
    * なし
* 再学習の必要あり
    * 組織の複雑さに対する設計
    * 新しいソリューションの設計
    * 移行の計画
    * コスト管理
    * 既存のソリューションの継続的な改善

#第二回　６３２
* 十分な知識を有する分野
    * 組織の複雑さに対する設計
* 再学習の必要あり
    * 新しいソリューションの設計
    * 移行の計画
    * コスト管理
    * 既存のソリューションの継続的な改善

#第三回　670
* 十分な知識を有する分野
    * 組織の複雑さに対する設計
* 再学習の必要あり
    * 新しいソリューションの設計
    * 移行の計画
    * コスト管理
    * 既存のソリューションの継続的な改善

精度は上がったがまだまだという印象。
iOS13以降のUIActivityViewControllerでUIImageのプレビューをなんとかしたい

#UIActivityViewControllerでUIImageのプレビューをなんとかしたい
##動機
自作アプリでUIActivityViewControllerを使ってみたけど、サムネイルがアプリアイコンになってしまう。
「メモ」アプリみたいに、シェアする画像をサムネイルに使いたい。

https://qiita.com/ezura/items/6036c6e100599b601482

を読んでも、コードがよく分からなかったので、

https://stackoverflow.com/questions/57850483/ios13-share-sheet-how-to-set-preview-thumbnail-when-sharing-uiimage

を参考にしてやってみた。

#やり方

## LinkPresentation frameworkをインポート
`import LinkPresentation`

## UIViewControllerに変数を宣言する
`var shareImage: UIImage? //シェアするイメージ`

## UIActivityViewControllerの呼び出し
[shareImage, self]をactivityItemsにセットする
selfをセットするのは、ViewControllerにUIActivityItemSourceを実装してあげるといいらしいので.
<code> shareImage = シェアするイメージ
let share = UIActivityViewController(activityItems: [shareImage, self], applicationActivities: nil)
present(share, animated: true, completion: nil)
</code>

## UIViewControllerに、UIActivityItemSourceのメソッドを実装してあげる
<code>extension viewController : UIActivityItemSource {
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
    return ""
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
    return nil
}
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
    let imageProvider = NSItemProvider(object: shareImage!)
    let metadata = LPLinkMetadata()
    metadata.imageProvider = imageProvider
    return metadata
}
}</code>

これで、サムネイルがうまく表示される。
UIActivityItemSourceを扱うclassを作れるとさらに良さげ。
ベーシック認証(社内はIP認証でスキップする)の設定

固定IP(社内)からのアクセスは、認証をスキップする
それ以外からのアクセスの場合は、通常通りBasic認証を行う設定。

```
# Basic認証orIP認証
Satisfy Any
# Basic認証
AuthUserFile (.htpasswdの場所)
AuthGroupFile /dev/null
AuthName "Protected Area"
AuthType Basic
<Limit GET POST>
require valid-user
</Limit>
# 特定のIPアドレスを除外する記述
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
```

#Wordpress用

```
# Basic認証orIP認証
Satisfy Any

# Basic認証
AuthUserFile "(.htpasswdの場所).htpasswd"
AuthName "Protected Area"
AuthType Basic
require valid-user

<Files "xmlrpc.php">
Satisfy any
order allow,deny
allow from all
</Files>

# 特定のIPアドレスを除外する記述
order deny,allow
deny from all

#許可するIP
allow from xxx.xxx.xxx.xxx
```
CraftCMSのプラグイン設定画面で.envの値をサジェストする

CraftCMSで独自プラグインやモジュールを開発する際に、外部サービスのAPIキーやメールアドレスなどを設定することがあります。この設定に.envの値を利用することができますが、設定じに、サジェストしてユーザが選択しやすいようにすることができます。

### サジェスト機能付きテキストフィールド設定

```twig:templates/settings.twig
{% import "_includes/forms" as forms %}

{{ forms.autosuggestField({
    label: "Secret Key"|t('plugin-handle'),
    id: 'secret-key',
    name: 'secretKey',
    value: settings.secretKey,
    suggestAliases: true,
    suggestEnvVars: true
}) }}
```

` forms.autosuggestField ` を使うことで、サジェスト機能付きのテキストフィールドを出力できます。これに `suggestEnvVars: true` をオプションに追加すると、テキストフィールドで先頭に$を入力すると.envの値を参照してサジェストしてくれます。設定値がファイルパスやURLなどの場合は` suggestAliases: true` もオプションに追加します。

<img width="1195" alt="Screen Shot 2020-05-18 at 10.27.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9882/0b1ec8d9-9b2d-2508-c124-9eb8a5bac387.png">

\*\*\*_PASSWORDや\*\*\*_KEY、\*\*\*_SECRETなどは自動でマスクしてくれる模様。サジェストされた環境変数を選択して保存すると、`$SOME__KEY` 、つまり**環境変数名** が保存されます。

### 環境変数名から値を取得する
上記の通り、保存された設定内容は **環境変数名** になります。このままだと、.envの値を利用できません。環境変数名から.envの値を取得するには、getenv()を使うのではなく、以下のように記述します。

```php
Craft::parseEnv(MyPlugin::getInstance()->settings->secretKey);
```

`Craft::parseEnv()`を利用すると、$からスタートする値は.envの値、それ以外はその値そのものを返します。
Ruby 正規表現

#正規表現とは

・文字列の一部分を置換
・文字列の一部分を抽出
・文字列が制約を満たしているか調べる

　などの操作を行うための技術が正規表現です。

　正規表現のほとんどの記述はどの言語間でも共有可能です。


#メソッドと使用例

###subメソッド

<font color="Red">文字列の指定した部分を別の文字列に置き換える</font>

```irb
irb(main):001:0> str = "リンゴを食べる"
=> "リンゴを食べる"

irb(main):002:0> str.sub(/リンゴ/,"オレンジ")
=> "オレンジを食べる"
```

変数strに文字列 "リンゴを食べる" が代入されています。

次にstrに対し、subメソッドを使用し、第一引数にリンゴ、第二引数にオレンジを指定しています。

出力すると、リンゴを食べる　→　オレンジを食べるになっています。

このように**第一引数に置き換えたい文字列を「 / (スラッシュ)」囲み、第２引数に変換後の文字列を指定します。**

###matchメソッド

<font color="Red">文字列がメソッドの左の文字列に含まれているか否かをチェックする</font>

```irb

irb(main):001:0> str = "Hello, World"
=> "Hello, World"

irb(main):002:0> str.match(/Hello/)
=> #<MatchData "Hello">

irb(main):003:0> str.match(/Good/)
=> nil
```

変数strに文字列 "Hello, World" が代入されています

次にstrに対し、matchメソッドを使用し、引数にHelloを指定しています

"Hello, world" には指定した "Hello" という文字列は含まれているので、MatchDataオブジェクトの返り値として指定した文字列 "Hello" が得られます。

"Good" は含まれていないので、返り値はnilになります。

matchメソッドもsubメソッドと同じように**引数を「 / (スラッシュ)」で囲みます。**

###gsubメソッド

<font color="Red">文字列の指定した部分を全て別の文字列に置き換える</font>

```irb
irb(main):001:0> tel = '080-1234-5678'
=> "080-1234-5678"

irb(main):002:0> tel.sub(/-/,'')
=> "0801234-5678"

irb(main):003:0> tel.gsub(/-/,'')
=> "08012345678"
```
変数telには電話番号が代入されています。

次にsubメソッドでハイフンを空の文字列に置き換えることで取り除こうとしますが、最初のハイフンだけが置き換えられています。

指定した初めの文字列だけを置き換えるならsub,全て置き換えるならgsubを使います。

#正規表現のメタ文字

メタ文字は、特殊な意味・機能を持った文字で、これを使用することで様々な制約が可能になります。

種類が多いので、パスワードの制約を例に挙げる中でいくつか紹介します。

```irb
irb(main):001:0> pw = 'Abcd1234'
=> "Abcd1234"

irb(main):002:0> pw.match(/[a-z\d]{8,10}/i)
=> #<MatchData "Abcd1234">
```

上記は、

・aからzの英字、数字のいずれかの文字
・８文字以上10文字以内
・文字は大小どちらでも可

という制約をかけています。

引数の中身を分解し、それぞれの文字の意味を説明していきます


<font color="Red">/[a-z\d]{8,10}/i</font>

↓　            

/[a-z\d]{8,10}/　　　　　　<font color="Red">i</font>（スッラッシュの中身の文字列は大文字小文字どちらでも可）

↓

[a-z\d]　　　　　　　　    <font color="Red">{8,10}</font>（直前の文字が8から10文字出現するものにマッチ）

↓

[a-z]　　　　　　　　     　<font color="Red">\d</font>　(数字にマッチ）

↓

<font color="Red">[a-z]</font> (aからzまでの文字いずれかにマッチ）

※今回はa-zに加え、数字も角括弧に囲まれているため、英数字いずれかにマッチする）


#まとめ

|種類            |  意味                  |    
|:--------------|---------------------------------------------:|
|      [  ]     |  囲まれたいずれか1つの文字にマッチ                  |     
|    \d         |  数字にマッチ                                   |      
| {a,b}         | 直前の文字がa回以上b回以下出現するものにマッチ                    |      
| i　(オプション）|             大文字・小文字を区別しない                         | 


基本的に紹介した2つのメソッドと正規表現のパターンを組み合わせることで様々な制約が実装できます。

パターンに関してはここに記したのは一例です。他にも正規表現を用いてできることはたくさんあります。
transfer.shというサービスが便利だった

scpが使えない環境等で、サーバー上のファイルをローカルにダウンロードしたいときに困った。
具体的には、heroku上で作成された一時ファイルを取得したかったが、scp接続できない（設定はあるのかもしれないが調べてない）ので困っていた。サクッとファイル転送できないもんかなと思ってたらあった。

[transfer.sh](https://transfer.sh/)

## 使い方

下記のコマンドを実行する

```sh
$ curl --upload-file ./{対象のファイル名} https://transfer.sh/{対象のファイル名}
```

するとURLが返ってくる
ファイル共有の一時URLです

```
https://transfer.sh/{ハッシュ}/{対象のファイル名}
```

アクセスするとダウンロード可能なページになっているのでそこからファイルを落とせる

## 便利な点

- アカウント不要なので即実行できる
- 実行環境への設定も不要(curlのみ)

以上です。
虫の頭でcoffeescriptを理解しようとしてみる。コンストラクタ

クラス虫を使って虫さんの情報を出力したい

コンストラクタを使って、クラスに捕まえた虫さんを入れた時と同時に名前を出力できるようにする

```coffeescript:musi.coffee

class 虫
  
  名前:"捕まえた虫の名前"
  
  constructor:(名前)->
    if 名前?
      @名前=名前

```

これでnew 虫する時に引数で虫さんの名前が入れられる
他のメソッドで引用できるように、名前がnullじゃなかったらthis名前(this=@)というのに入れる(あまりよくわかってない)

さらにそれを利用して名前や虫の特徴を出力したい

```coffeescript:musi.coffee
  
  特徴:(文章,数)->
    console.log("特徴:#{文章}#{@名前}#{数}匹捕まえた")

```

特徴メソッドを作って引数に特徴と捕まえた数を入れられるようにした。文章と数は特徴メソッドを参照。
名前は特徴メソッドとは違うメソッドであるコンストラクタから引用できるようにしてある

これで出力できる

```coffeescript:musi.coffee
    
虫1=new 虫("オオカマキリ") 
虫2=new 虫("オビロカマキリ")
​
虫1.特徴("体が大きい",3)
#特徴:体が大きいオオカマキリ3匹捕まえた
虫2.特徴("尾が広い",1) 
#特徴:尾が広いオビロカマキリ1匹捕まえた

```
FontAwesomeの導入と使い方解説

今回はFontAwesomeの導入方法から表示させるまでについてを解説していきます。

#FontAwesomeの導入

1.Gemfileに以下の記述を追記

```ruby

gem "font-awesome-sass"
```

```
$ bundle install
```

2.application.scssに以下を記述。

```ruby

@import "font-awesome-sprockets";
@import "font-awesome";
```

これで導入は完了です。


#ビューで表示
iconヘルパーメソッドを使っていきます。
使い方の模範はこんな感じです。

```ruby
icon('接頭辞名', 'アイコン名')
```

実際に使うとこんな感じです。

```ruby
= icon('fab', 'facebook-square') #例
```
###参考資料

接頭辞名とアイコン名については以下のサイトで調べて使いましょう！
https://fontawesome.com/
[iOS]アップルの審査で落ちた。Guideline 2.3.3 - Performance - Accurate Metadata We noticed that your screenshots do not sufficiently reflect your app in use.

# アップルにアプリを申請したら却下
却下されたためメモしておきます

エラーは下記

```
Guideline 2.3.3 - Performance - Accurate Metadata We noticed that your screenshots do not sufficiently reflect your app in use.
```

今まではアップルに送るキャプチャは5.5インチのみでよかったが今は
キャプチャを5.5,6.5と二つになった模様。しかし二つとも貼り付けましたが、却下されました。
6.5インチでキャプチャを撮ったものをそのまま流用したのが原因かもしれません。

参考
https://growthhackjournal.com/article/news/aso-screenshot-size-renewal-2/
localhost:8080で表示されるログイン画面

<h1>原因の正体はSpringSecurity</h1>

<p>SpringBootを使ってWEBアプリケーションを開発するとき、localhost:8080で実際に画面を表示したりする。そのとき、想定していたhtmlファイルに遷移せずに謎のログインページに飛ばされた。</p>
<p>調べてみると、どうやらSpringSecurityを使用する場合に出てくるものみたい。</p>
<h1>対応策</h1>
<p>デフォルト設定であればユーザー名は`"user"`、SpringBoot起動時にコンソールに表示されるパスワードを入力してあげるとログインして、目的のページにたどり着くみたい。</p>
<p>※もしSpringSecurityを使わないのであれば、依存関係を削除すればOK！</p>
<p>参考：<a href="https://stackoverflow.com/questions/46265775/spring-boot-project-shows-the-login-page">Spring Boot project shows the login page</a></p>
FFFTPの転送モードではまった（改行コードに気を付けよう）

FFFTPの転送モードが自動判別に設定していたので、意図しない動作になったよ
というお話

FFFTPはWindowsではド定番かつシンプル高機能で使いやすいFTP転送ができるソフトです。

私はこれまでは、Windowsでもバーチャルマシン上のLinuxマシンからそのままFTPしたり、cygwinイントール環境が整っていたので端末からFTPしたり、そもそも開発環境がLinuxだったりしたので、FFFTPを開発で使用することは多くありませんでした。

今回は開発用PCが別途与えられたので、せっかくWindowsだったら定番のものでやってみよう
と軽い気持ちで始めたのが、半日潰す要因になってしまいました。。。

# 結論
転送モードが自動判定モードで、デフォルトの条件でAsciiモードリストに入っていたため、自動で終端（今回はLF ⇒ CRLF）が変換されてしまっていました。

ファイルの拡張子が「.sh」だったことに依存します。

転送モードを**バイナリモード**にしたらうまくいきました。

# 環境
・ローカル（FTP送信）
OS:Windows
エディタ：MS VS code

・ホスト（FTP受信）
Linux (今回は組み込み用)

# 何にはまったか
バイナリデータやWEBソースを特に意識せずに、すでにやり取りをしていて問題は起きていませんでした。
だいぶ環境が固まってきてフォルダ構成も決まり、web一式は圧縮してこのフォルダに置き起動時に解凍してあげよう、
と起動スクリプトを作成しFTPで転送したのですが何度やってもうまくいかない。


この時のスクリプト実行エラーが

```
./start.sh: line 45 syntax error: unexpected end of file (expecting "then")
```

うん、何か間違っている。
構文エラーだ。


## moreしてスクリプトを確認

```
xxx@xxx: more ./start.sh
```

先頭に記述が必要な、忘れがち&タイプミス多め（私だけ？）のおまじない

```start.sh
#!/bin/sh
    :
```

問題なし。

その他、念入りにタイプミスのチェック・・・
：
：
：
あっていそう

シンプルにスクリプトを修正。
ifなんて使わない！
(fiで閉じってなに。いつ見てもこれがタイプミスに見えてしまうよ

いざ実行！

```
// xxxはいろいろ省略
:  not found: xxx 
:  not found: xxx 
     :
: No such file or directory xxx
     :
mv can't rename 'xxx' : No such file or directory
cp can't stat 'xxx' : No such file or directory
```

いやいや、ファイルもディレクトリもあるし！
ヘンテコエラーすぎて頭の中もエラーに。

しかも厄介なことにシンプルにしすぎると、

```
-sh: ./start.sh: not found
```

ファイルは確かにあるのに、not found
カーネルを壊したかと思ってしまいます。

```構文エラーやnot foundエラー```
単純にそうであれば、一番何ともないエラーなんだけど
違う要因でこのようになっていた場合、何が本質かわからなくなり
一番迷子になってしまうことが多いです。
```やっとここで初めて、そもそもを疑い始めました。```
もしかしたらWindowsでスクリプト編集しているから、改行コードがおかしい？

うん、ここでは問題なさそう。

## ホスト環境（Linux側）でviするしかない。
vi 難しいから避けたい（むしろこの気持ちが一番の悪だったのかもしれない

**いた**
**^M "それは"見てはいけないやつ**

```
^M
```

シェルスクリプトを実行するには改行コードはLFのみでなければならない
これがいるってことは、Windowsの日本語文字コードであるShift-JISかつ改行コードがCR+LFになっていることがわかりました。

シェルスクリプトをWindowsで作業することが間違いだった。
エディタの設定が違っているに違いないと推測。

## エディタはおなじみVS Code
画面右下のプロパティを確認
``` 行1、列1　スペース:4　UTF-8　LF　Shell Script```
うーん、あっていそう。
.shをシェルスクリプトとも認識しているし。素晴らしい。
MSさんも心が広くなった。（拡張機能なのかな？

なんだか改行コードあっていそう。
でも保存するとおかしくなるのか？
会社が秀丸さんにお布施をしているので、秀丸さんで保存したファイルを開く。

[ファイル]メニュー　⇒　[エンコードの種類]
```・Unicode(UTF-8)```
```・改行=LF```

ここでも問題なさそうだ。

ますます分からない。

## 最終手段、バーチャルマシンでLinux起動。
ここまで来たら純なemacsしかない。
共有フォルダへ起動スクリプトをコピー。
emacsで開く。
やっぱりあっている。

**もしかしてだけど**
**もしかしてだけど**
**FTPするときにファイルが勝手にかわっているんじゃないのぉ**

問題はスクリプトファイルをFTPしたら発生しました。
そうでした。
見事にはまりました。

## FFFTP
確かにプラットフォームが変わるときに、ASCIIモードに設定しておけば自動で変わると楽かもしれない。
でもやっぱり自分で意図せずファイルの中身が変わるのは気持ちが悪い。。。
今後は必ずバイナリモードにして、改行コードもファイル単位できちんと管理しようと心に決めました。
Gitlab-CIでTex文書を自動でPDF化

# Gitlab-CIでTex文書を自動でPDF化

gitlabのアカウントを持っていることを前提で話します。

持っていない人は作ってください。↓↓↓
https://gitlab.com/

## 新規プロジェクト作成
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/63402bbd-ef8a-ff7f-235b-6432e1ec23d7.png)

## プロジェクトの設定
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/1513b578-1c7d-0b7c-1727-3b82a8710506.png)

## CI/CD の設定
### その1
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/efa7a960-c977-5a3b-c64e-186b8d2f5223.png)

##その2
下記のもの(.gitlab-ci.yml)をコピー

``` yml:.gitlab-ci.yml
# This file is a template, and might need editing before it works on your project.
# use docker image with latex preinstalled
# since there is no official latex image, use https://github.com/blang/latex-docker
# possible alternative: https://github.com/natlownes/docker-latex
image: whywaita/docker-latex-jlisting:latest

stages:
  - build

before_script:
  - pwd
  - echo "start compile"
  
build:
  stage: build
  script:
    - for i in `ls *.tex | sed 's/\.[^\.]*$//'`; do echo "$i.tex -> $i.pdf"; platex $i; dvipdfmx $i; done
    - echo finished
  artifacts:
    paths:
        - "*.pdf"
```

## その3
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/136c37c9-11b2-159e-7830-c98f39a78891.png)

## Texファイルのアップロード方法

### プロジェクトの概要に戻る
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/2e9ff723-ec88-0038-a821-d5a58e02ef86.png)

### 自分のファイルをアップロード
サンプルでHello.texを使います。(内容は下に載せています。)
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/3d013fcd-9537-5b7c-0cc3-6a9f9ca47363.png)

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/2effa8d5-a67c-5f0b-6a25-b02db211f140.png)

![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/67cb95e1-c181-577a-095b-43574ac69b02.png)

``` HelloTex.tex
\documentclass{jsarticle}
\usepackage[b5j]{geometry}
\begin{document}
Hello\TeX!
\end{document}
```

## 出来上がったPDFのダウンロード
再びプロジェクトの概要に戻る
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/f149a558-86a1-95eb-4bb1-78dd3f0246a1.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/4f40e57c-7de9-b7cd-2300-d62a8163d0f6.png)

#おまけ
##　共同編集の方法
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639578/6ff4ca6a-5af0-5dca-e009-f71b387b41d9.png)

共同編集者を招待したらプロジェクトを共同で編集したりできます。
[Angular] 公式ドキュメントのバージョン変更

意外と気づかなかったりするので。

## 過去バージョンへの変え方
下記の形式でアクセスするだけ。
※[N]には2以上の数字が入る
`https://v[N].angular.io/docs/`

例えば、バージョン7のドキュメントを参照するには
https://v7.angular.io/docs
にアクセスすれば良い。

## 最新バージョン

最新のドキュメントは常これ。
https://angular.io/docs

現在の最新は9だが
https://v9.angular.io/docs
にアクセスすると
https://angular.io/docs
にリダイレクトされる。

## 時期バージョン
ここにアクセスする。
https://next.angular.io/docs

## WEBからも変更できる
サイドバーの一番下からもバージョンを変更できる。
<img width="264" alt="スクリーンショット 2020-05-18 10.15.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528526/6e1d1840-0258-45ff-963a-b090cd490fa8.png">
Typescript + node-configで「プロパティ 'hogehoge' は型 'IConfig' に存在しません。」問題に対処する

```ts
import * as config from 'config'

console.log(config.hogehoge)
```

と書くと、

```ts
TS2339: Property 'hogehoge' does not exist on type 'IConfig'
```

とエラーが出てしまう。コンパイルはできるけどエラー表示は消したい。
config.get()を使うと

```ts
TS1259: Module '"D:\\node_modules\\@types\\config\\index"' can only be default-imported using the 'esModuleInterop' flag
```

と別のエラーになってしまう。
ひとまずの対処で

```ts
import * as config from 'config'

const myConfig: any = config

console.log(myConfig.hogehoge)
```

ｳｰﾝ、代入しなおすしかないのか...
【Alamofire】Module 'Alamofire' has no member named 'request' というエラーが出る

```Swift
Alamofire.request(route).responseJSONDecodable { response in }
```
これを書いて普通にAlamofireを使おうと思ったら

```
Module 'Alamofire' has no member named 'request'
```
そんなん無いよと怒られました。

### Alamofireは5系からの変更に注意
Alamofireは5系からメソッドの命名とかが結構変わっています。
こういう変更は勘弁してもらいたい。

基本的に「Alamofire」と記述していた部分は「AF」に変わったみたいです。
上記の例だと

```Swift
AF.request(route).responseJSONDecodable { response in }
```

こうすれば動くようになります。
MATLABで日の出日の入り

照度計のグラフに日の出と南中と日の入りの線を描いているのだが、当初ハードコードしていたものをプログラムで算出すことにしてみた。

[SunCalc](https://github.com/mourner/suncalc)というJavascriptのコードを移植してみた。

```MATLAB
dayMs = 1000 * 60 * 60 * 24;
J1970 = 2440588;
J2000 = 2451545;

rad  = pi / 180;

toJulian = @(date) date / dayMs - 0.5 + J1970;
fromJulian = @(j) (j + 0.5 - J1970) * dayMs;
toDays = @(date) toJulian(date) - J2000;

e = rad * 23.4397;
declination = @(l, b) asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l));

J0 = 0.0009;

julianCycle = @(d, lw) round(d - J0 - lw / (2 * pi));
approxTransit = @(Ht, lw, n) J0 + (Ht + lw) / (2 * pi) + n;
hourAngle = @(h, phi, d) acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d)));
observerAngle = @(height) -2.076 * sqrt(height) / 60;

solarMeanAnomaly = @(d) rad * (357.5291 + 0.98560028 * d);
solarTransitJ = @(ds, M, L) J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L);
eclipticLongitude = @(M) M + (rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M))) + (rad * 102.9372) + pi;


getSetJ = @(h, lw, phi, dec, n, M, L) solarTransitJ(approxTransit(hourAngle(h, phi, dec), lw, n), M, L);

lat = 35.6581;
lng = 139.7414;
height = 0;
now = datetime('now', 'TimeZone', 'UTC');
date = posixtime(now) * 1000;

lw = rad * -lng;
phi = rad * lat;
dh = observerAngle(height);
%d = toDays(date);
d = juliandate(now) - J2000;
n = julianCycle(d, lw);
ds = approxTransit(0, lw, n);
M = solarMeanAnomaly(ds);
L = eclipticLongitude(M);
dec = declination(L, 0);

Jnoon = solarTransitJ(ds, M, L);

solarNoon = fromJulian(Jnoon);
nadir = fromJulian(Jnoon - 0.5);

nan = datetime(solarNoon/1000,'ConvertFrom','posixtime','TimeZone','Asia/Tokyo');

time0 = -0.833;

h0 = (time0 + dh) * rad;

Jset = getSetJ(h0, lw, phi, dec, n, M, L);
Jrise = Jnoon - (Jset - Jnoon);

srise = fromJulian(Jrise);
sset = fromJulian(Jset);

sr = datetime(srise/1000,'ConvertFrom','posixtime', 'TimeZone','Asia/Tokyo');
ss = datetime(sset/1000,'ConvertFrom','posixtime', 'TimeZone','Asia/Tokyo');

disp(sr);
disp(nan);
disp(ss);
```

functionはThingSpeakのMATLABでは使えないようだったので、無名関数で実装しました。

元のコードは薄明の計算もありますが、このコードは日の出日の入りだけを計算しています。

ユリウス日の計算はMATLABの関数(juliandate)を使ってみました。

緯度経度がThingSpeakのデータに入っている場合はそれを使うのが良いです。

実行してみるとこうなります。

```
   18-May-2020 04:35:18

   18-May-2020 11:38:52

   18-May-2020 18:42:26
```

[国立天文台のデータ](https://eco.mtk.nao.ac.jp/koyomi/dni/2020/s1305.html)と1分程度はずれがあるが大丈夫そうです。

![スクリーンショット 2020-05-18 18.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d7ac347a-4b33-729f-8f13-62d123561b21.png)
Mac の VSCode などで指定するフォント名を確認したい

> <strong>Visual Studio Code でフォントを変更したいが<font color=darkorange>指定するフォント名がわかりません</font></strong>のです。
>
> ... "Font Book.app" の、どの項目だったっけ？

[「mac VSCode フォント名 確認」でググって](https://www.google.com/search?q=mac+VSCode+%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E5%90%8D+%E7%A2%BA%E8%AA%8D)も、ピンポイントでフォント名を確認する<ruby>だけ<rt>・・</rt></ruby>の記事がなかったので、自分のググラビリティとして。

## TL; DR

- `Font Book` アプリのフォント情報の `PostScript名` を使う

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/34e6a59f-56b6-eefc-61e9-f7d8604b54d2.png' with=100%>

## TS; DR

1. “`Font Book`” アプリを開き、対象フォントを選ぶ。
2. 表示の「ⓘ フォント情報を表示」（もしくは `⌘I`）した際に表示される詳細情報の「`PostScript名`」を控える
3. VSCode のメニューから設定を開く
  - [`Code`] - [基本設定] - [設定] or `⌘,`
4. VSCode のフォント設定を開き、控えたフォント名を入力
  - [テキストエディター] - [フォント] - [`Editor: Font Family`]
  - VSCode のターミナルや拡張機能など、他の設定も確認・変更したい場合
      - 設定を開いている状態で「設定の検索」窓で "`font`" と検索

## 動作確認

- macOS Mojave (OSX 10.14.6)
- Visual Studio Code 1.45.1
- Homebrew 2.2.16-69-g9fcaa46
- `brew cask info font-hackgen` 1.4.0

## 参考文献

- [Mac OSXのフォント名（システム用表記名）の確認方法](https://blog.keinos.com/20170623_2604) @ KEINOS Blog
- [【文字幅 半角3:全角5 も追加】Ricty を神フォントだと崇める僕が、フリーライセンスのプログラミングフォント「白源」を作った話](https://qiita.com/tawara_/items/374f3ca0a386fab8b305) @ Qiita
- [macOS で Visual Studio Code を使うためのアレコレ (2020/03/09)](https://qiita.com/satokaz/items/6a6a0d9b6489ec2d1803) @ Qiita
C#で確実にファイル名を変更する

C#でファイル名を変更するには`File.Move(元ファイルパス,後ファイルパス)`を使うのが一番ラクですが、実はこのメソッドには2つ落とし穴があるので、それを回避する方法を説明します。

# フォルダ（ディレクトリ）では使えない
`File`なので当たり前といえばそうですが、フォルダかどうかは気にせずファイル名を変更したいですね。
フォルダの場合は代わりに`Directory.Move()`を使用します。
そして、指定されたパスがフォルダかどうかは`FileInfo.Attributes`から調べます。

```csharp
public static void Rename(string sourceFilePath, string outputFilePath)
{
    var fileInfo = new FileInfo(sourceFilePath);

    if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
    {     
        Directory.Move(fileInfo.FullName, outputFilePath);
    }
    else
    {
        fileInfo.MoveTo(outputFilePath);
    }
}
```

# フォルダ（ディレクトリ）は大文字小文字だけの変更はできない
たとえば、`C:\abc`→`C:\ABC`といった変更は直接できません。ですので一度別のファイル名に変更してから再変更します。

```csharp
public static void RenameDirectory(string sourceFilePath, string outputFilePath)
{
    if ((String.Compare(sourceFilePath, outputFilePath, true) == 0))
    {
        var tempPath = GetSafeTempName(outputFilePath);
        Directory.Move(sourceFilePath, tempPath);
        Directory.Move(tempPath, outputFilePath);
    }
    else
    {
        Directory.Move(sourceFilePath, outputFilePath);
    }
}

private static string GetSafeTempName(string outputFilePath)
{
    outputFilePath += "_";
    while (File.Exists(outputFilePath))
    {
        outputFilePath += "_";
    }
    return outputFilePath;
}
```

なお、この問題は`File.Move()`では発生しません。謎い。

# まとめ
以上２つの解決策をまとめると、以下のようになります。
他にもこんな落とし穴がある、とかあったら教えてください。

```csharp
/// <summary>
/// 確実にファイル／ディレクトリの名前を変更する
/// </summary>
/// <param name="sourceFilePath">変更元ファイルパス</param>
/// <param name="outputFilePath">変更後ファイルパス</param>
public static void Rename(string sourceFilePath, string outputFilePath)
{
    var fileInfo = new FileInfo(sourceFilePath);

    if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
    {
        RenameDirectory(sourceFilePath, outputFilePath);
    }
    else
    {
        fileInfo.MoveTo(outputFilePath);
    }
}

/// <summary>
/// 確実にディレクトリの名前を変更する
/// </summary>
/// <param name="sourceFilePath">変更元ファイルパス</param>
/// <param name="outputFilePath">変更後ファイルパス</param>
public static void RenameDirectory(string sourceFilePath, string outputFilePath)
{
    //Directory.Moveはなぜか、大文字小文字だけの変更だとエラーする
    //なので、大文字小文字だけの変更の場合は一度別のファイル名に変更する
    if ((String.Compare(sourceFilePath, outputFilePath, true) == 0))
    {
        var tempPath = GetSafeTempName(outputFilePath);

        Directory.Move(sourceFilePath, tempPath);
        Directory.Move(tempPath, outputFilePath);
    }
    else
    {
        Directory.Move(sourceFilePath, outputFilePath);
    }
}

/// <summary>
/// 指定したファイルパスが他のファイルパスとかぶらなくなるまで"_"を足して返す
/// </summary>
private static string GetSafeTempName(string outputFilePath)
{
    outputFilePath += "_";
    while (File.Exists(outputFilePath))
    {
        outputFilePath += "_";
    }
    return outputFilePath;
}
```

# 参考
https://dobon.net/vb/dotnet/file/filecopy.html

# 環境
VisualStudio2019
.NET Core 3.1
C#8
PythonでABC168Dを解く

### はじめに
昨日のABCで解けなくて、悔しくて夜も眠れなかったので復習します。

### [ .. (Double Dots)](https://atcoder.jp/contests/abc168/tasks/abc168_d)

**考えたこと**
制約より、どの部屋間も複数の道を使えば移動可能なので与えられるグラフは連結しています。連結しているグラフなら、必ず構築かのうになります。print('No')で提出すると0ACです。
解法は、道標は1から同じ深さごとに探索して自分よりも深い部屋に到達したら、自分の部屋への道標を置いていけば解けます。これは、BFSで簡単に実装できます。

verはver[i]から1回で到達できる部屋のリスト

```python
from collections import deque
n, m = map(int,input().split())
ab = [list(map(int,input().split())) for _ in range(m)]

q = deque([])
path = [-1] * n
ver = [[] for _ in range(n)]
for i in range(m):
    ab[i].sort()
    if ab[i][0] == 1:
        q.append([ab[i][0]-1,ab[i][1]-1])
        #path[ab[i][1]-1] = 1
    ver[ab[i][0]-1].append(ab[i][1]-1)
    ver[ab[i][1]-1].append(ab[i][0]-1)

def bfs(q, visited_list):
    while len(q) > 0:
        now = q.popleft()
        go = now[1]
        if visited_list[go] == -1:
            visited_list[go] = now[0]+1
            for i in range(len(ver[go])):
                q.append([go,ver[go][i]])
    return visited_list
ans = bfs(q,path)
print('Yes')
for i in range(1,n):
    print(ans[i])
```
計算量は$O(N+M)$
### まとめ
非常に基礎的な問題でした。昨日は、空回りしてた感があったので次のAGCで1完目指してがんばります。ではまた。

### 余談
グラフの問題は[これ](https://hello-world-494ec.firebaseapp.com/)を使うと考えやすいです。
[JavaScript] RxJSを使わずにRxJSを理解する

# はじめに

この記事は、RxJSの使い方を解説する記事です。
けど、RxJSは出てきません。
（えっ

よくわからないままにRxJSを使い始めて悩んでいるひと（←自分）のための再入門記事です。

2つのテーマについて書いています。

- `subscribe`しないと動かないのはなぜか
- 何度も`subscribe`すると、何度も動くのはなぜか


# この記事の登場人物

## プロデューサー

![tv_producer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/9366cba8-0777-6645-6571-a5038c28a588.png)

プロデューサーは、依頼を受けて何か仕事をしてくれます。
仕事がいつできあがるかはわかりません。
できあがり次第教えてくれることになっています。




## オブザーバー

![shinbun_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/ace85339-a41d-e6b0-4884-96aa44489053.png)

オブザーバーは、仕事の結果を受け取ります。

場合によって、3つの役目を受け持ちます。
正常結果を受け取る役目、失敗結果（エラー）を受け取る役目、仕事が全て終わったことを受け取る役目です。



## オブザーバブル

![job_shinbunhaitatsu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/a0fe30bf-41cd-cd15-b9bc-4af031d19231.png)

オブザーバブルは、プロデューサーとオブザーバーの仲介役です。
オブザーバーから注文を受けると、プロデューサーを働かせて仕事結果をオブザーバーへ渡させます。

`subscribe`メソッドを持ちます。
今回のキモです。


# 実装

RxJSを理解するために、それぞれを簡単に実装してみます。

まずキモであるオブザーバブルです。

## オブザーバブルの実装

オブザーバブルは、オブザーバーからの注文を`subscribe`というメソッドで受け付けます。

仕事の内容は、コンストラクタ引数で受け取ったプロデューサー任せです。

`subscribe`メソッドの中身はまた後で実装します。


```js
class オブザーバブル {
    constructor(プロデューサー) {
        this._プロデューサー = プロデューサー;
    }

    subscribe(オブザーバー) {
      // 後で
    }
}
```

## オブザーバーの実装

オブザーバーは`next` `error` `complete`の3つのメソッドを持つオブジェクトです。
それぞれ、正常結果、失敗結果（エラー）、仕事の完了を受け取るためのものです。


```js
const オブザーバー = {
    next: function(結果) {},
    error: function(エラー) {},
    complete: function() {},
};
```

## プロデューサーの実装

プロデューサーはただの関数にしました。
オブザーバーを引数に取り、自分の仕事結果を渡します。
仕事がすべて正常に終われば`complete`を呼び出し、途中で何か問題があれば`error`を呼び出します。

実際の開発現場では、フレームワーク等があらかじめ用意しているプロデューサーを使うことになると思います。


```js
function プロデューサー(オブザーバー) {
    try {
        オブザーバー.next(仕事1());
        オブザーバー.next(仕事2());
        オブザーバー.next(仕事3());
        オブザーバー.complete();
    } catch (e) {
        オブザーバー.error(e);
    }
}
```

# 使い方

上記で実装したプログラムを使うシーンはこうなります。

オブザーバブルオブジェクトを作って、`subscribe`メソッドにオブザーバーを渡します。

```js
const observable = new オブザーバブル(プロデューサー);

observable.subscribe(オブザーバー);
```

# subscribeメソッドの実装

後回しにしたオブザーバブルの`subuscibe`メソッドの実装です。
ここが今回のテーマのキモです。
キモですが、内容はごく単純です。プロデューサーを呼んでいるだけです。


```js
class オブザーバブル {
    constructor(プロデューサー) {
        this._プロデューサー = プロデューサー;
    }

    subscribe(オブザーバー) {
        this._プロデューサー(オブザーバー);
    }
}
```

# まとめ

`subscribe`しないと、プロデューサーは呼ばれないことがわかりました。

`subscribe`する度に、プロデューサーが呼ばれることがわかりました。


# 次は……!?

- subscribeしなくても動くプロデューサーがあるんだってよ
- プロデューサー一回の働きを、複数箇所でsubscribeするやりかたがあるんだってよ

# 参考リンク

- [ReactiveX 公式ドキュメント](http://reactivex.io/documentation/observable.html)
- [RxJS 公式ドキュメント](https://rxjs-dev.firebaseapp.com/guide/observable)
- [inDepth.dev](https://indepth.dev/angular/)
- [Angular in Depth](https://medium.com/angular-in-depth)
- [いらすとや](https://www.irasutoya.com/)
js.erbで簡単に非同期通信画像削除

#はじめ
FontAweSomeで削除アイコンを導入

```ruby:qiita.rb
  
<head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
```

```xxx.html.erb
  <i class="fa fa-trash-o fa-lg" aria-hidden="true"></i>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634461/f03ddae3-2aed-16ea-ce4b-ee1fff696458.png)


#Destroy一例
```photos_controller.rb
  def destroy
    @photo = Photo.find(params[:id])
    room = @photo.room

    @photo.destroy
    @photos = Photo.where(room_id: room.id)

    respond_to :js
```

#respond_to :jsのファイル
```photos/destroy.js.erb
$('#photos').html("<%= j render 'photos_list' %>")
```
普段Macを使っている人が Boot Camp で Window10を入れてから設定したこと

# マウスのぐりぐりをナチュラルにする

## いろいろな方法があるのだろうけど、僕はレジストリを書き換える

https://blog.dreamhive.co.jp/yama/13622.html

ここの記事を引用させていただきます。

> 実際の手順
> 
> レジストリの書き換え手順は次の通りです。
> 
> 1. Cortanaや「ファイル名をして実行」から「regedit」でレジストリエディターを起動する
> 2. 「HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\VID_???\VID_???\Device Parameters」キーを開く
> 3. 「FlipFlopWheel」値を「1」に変更
> 4. Windowsを再起動する

## Bluetooth マウスが切れる

Bluetooth のマウス使っているのだけれども、
どんなタイミングだったかわすれが、接続が切れて二度と繋がらなくなることがあったんンゴねぇ。

https://yuko-life.com/married-life/diary/bootcamp-magicmouse-keyboard-problem/

ここの記事を引用させていただきます。

> 1. 設定＞Bluetoothとその他のデバイス＞デバイスとプリンター
> 2. Magic Mouse 2をダブルクリック
> 3. 上のタブ「ハードウェア」をクリックし、「Apple Wireless Mouse」を選択
> 4. 「プロパティ」＞新しく立ち上がったウィンドウで「設定の変更」
> 5. 上のタブの「電源の管理」をクリック
> 6. 「電力の節約のために、コンピューターでこのデバイスの電源をオフにできるようにする」のチェックを外す

これで解決した。
ンでも、Windowsアップデートが走ると振り出しに戻るような気がする。クッソ。

# 「英数」と「かな」キーで文字を変換できるようにする

## 参考にした記事

* https://blog.dreamhive.co.jp/yama/13622.html
* https://dailymochi.com/boot-camp-eisuu-kana
GitLab Runner（GitLab-CI）でユニットテスト用の外部コンテナを起動する

`services`を使う。
外部のミドルウェアに依存する機能のユニットテストに便利。

参考（公式ドキュメント）

- [GitLab CI/CD Pipeline Configuration Reference | GitLab](https://docs.gitlab.com/ee/ci/yaml/#services)
- [Using Docker images | GitLab](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#available-settings-for-services) <- オプションの使用方法について一番詳しい
- [GitLab CI services examples | GitLab](https://docs.gitlab.com/ee/ci/services/README.html)

指定イメージがデフォルトでリッスンするポート番号を利用できる。

```yaml:.gitlab-ci.yml
image: busybox  # script を実行するコンテナ

# 別途立ち上げるコンテナ(この例では4つ)
services:
  - mysql:latest
  - postgres:11.6
  - name: redis:latest
    alias: redis1
  - name: redis:latest
    alias: redis2
```

~~ポート番号をバインディングする方法が謎~~。
`entrypoint`, `command`を書き換えるっぽい。

`name`または`alias`で指定したホスト名で名前解決してパイプラインから使用できるようになる。
上記の例`.gitlab-ci.yml`だと

- mysql
- postgres
- redis1
- redis2

といった具合。
Xplentyのテンプレートを使って手軽にデータ連携: Taboola > データウェアハウス編

[Taboola](https://www.taboola.com/ja)や[Appsflyer](https://www.appsflyer.com/jp/)、[Yotpo](https://www.yotpo.com/)、[Similarweb](https://www.similarweb.com/ja)など、日本でもだいぶおなじみになってきた製品のデータについても、Xplentyを使うことによりすでにお使いのDWHやデータベース、ストレージなどに簡単に統合することが可能です。

今回はXplentyを使用してTaboolaのデータを別のデータベースに格納する手順を紹介します。

#Taboolaについて
Xplentyの[統合ページ](https://www.xplenty.com/integrations/taboola/)でTaboola の紹介を見ると、

Taboola is a discovery-driven content marketing service for both advertisers and publishers that is designed to offer visitors highly personalized external content while they engage with a publisher’s website. Taboola accomplishes this level of personalization through a predictive analysis engine that looks at a wide range of data points, including demographic data, browsing history, purchase history, etc. Then, it chooses and displays the discovery links that are most likely to engage those visitors, thereby increasing the likelihood of conversion.

となっています。

Taboolaは広告主とPublisherの双方に対してディスカバリードリブンのコンテンツマーケティングサービスを提供している会社です。様々なデータを通して、デジタルコンテンツ表示のパーソナライゼーションを実現しています。

今回はデータ連携の観点から、Taboolaをお使いの広告主(Advertiser)にとって重要なキャンペーンデータをRedshiftデータベースへどのように連携できるかを紹介します。（もちろん、それ以外のデータベース、データウェアハウス、さらにはストレージサービスとも連携可能です。）

Taboolaのキャンペーンデータは、Facebook AdsやGoogle Adsといったポピュラーな広告プラットフォームのパフォーマンスデータと同じようにAPIでデータを取得することができます。また、データ連携に、Xplentyが持つTaboolaデータ統合のために用意されているテンプレートを使うことで、広告主は、簡単にTaboolaのキャンペーンデータを抽出し、別のDWHやDBへ連携することができます。

それでは、どれくらい簡単にそれが実現できるかについて、見ていきましょう。

#Xplenty テンプレート： Taboola > Redshift
Xplentyのパッケージ作成画面でテンプレート一覧に「Taboola」と入力すると、「Taboola Analytics Reports to Redshift」というテンプレートが見つかりますので、それを選択し、パッケージを作成します。

もし、Redshiftでなく別のデータベースやストレージサービスがいいという場合は、保存先のコンポーネント入れ替えるだけで、保存先を別のものに変更することも簡単にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/74b9c5ad-f7f6-0016-8282-49bcb772db2c.png)

パッケージの編集画面を見てみましょう。テンプレートなので、データ取得、加工、ロードといった必要となる一連の処理がすでに出来ているのが分かります。処理内容を変更する必要がなければ、あとは、Noteに記載のある指示に従って、API連携に必要なクレデンシャル情報と保存先のRedshiftの接続に必要な情報を入力するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/697f475d-b824-4a58-bad9-c9f6345ae13b.png)

これだけで完成です。

どういったデータが取得できるかは、接続先のドメインを変更するだけです。キャンペーンの場合は以下の項目が取得されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/54e9cf7d-84ed-55e1-b13e-2303b340bae6.png)

キャンペーンアイテムを取得した場合は、以下のようなデータを取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/9a056fae-1f9f-b3ac-84e0-edbe688f779c.png)

#最後に
Xplentyを使えば、簡単にパイプラインを作成し、TaboolaのCampaignデータをクラウド上にあるDB、DWH,さらにはストレージへ連携することが可能です。またTaboola以外にもAppsflyerなども同様にテンプレートを利用し、パインプラインを作成することが可能です。

XplentyはG2 Crowdにて2020年SpringのETLツールカテゴリにおいて「Leader」に選ばれています。（G2 Crowdのレビューページでは、ユーザーの声がビデオで紹介されており、変換の多様性、すぐに使えるコネクタの豊富さ、サポートのレスポンスの良さ、学習が容易といった点を評価していただいてます。）

[Xplentyのデモ紹介に登録して、無料でプラットフォームを試してみよう!](https://calendly.com/xplenty-etl-pipelines/trial-setup/?action=schedule&controller=help&month=2020-05&utm_source=xp&utm_medium=blog&utm_campaign=content)（予約サイトは英語ですが、日本語でデモします）
スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版、ハマったところcheckboxの再描画編~~

#はじめに
Vueに対応していこう～。ということで始めたわけですが、
checkboxの再描画にもハマりましたんで残しておきます。
[Vue版、ハマったところinputの再描画編~~]
(https://qiita.com/yamamow/items/ad967a1dbfda6f9e4aa8)の対応もあったのですが、checkboxなりのことがあったのでここに投稿します。

#結論
ここを見ている方は、たぶん、同じ症状の方だと思うのでとっとと結論書きます。
checkboxは配列にする！これに尽きるのではないかと思われました。
そうです、初期値から配列です！空っぽでも、空の配列です！
あとkeyも設定してみましたので、チェックボックス一覧のデータは連想配列にしておきました。


#なぜ配列だとうまくいくのか
逆に、配列にしないとtrue、falseが返ってくるだけなので、データの保存しようがないです。

#配列は２つ用意
チェックボックスはラジオボタンと違って、複数チェックを可能にするために用いると思います。
そのため、
チェックボックス一覧の配列と
データの配列（初期表示でチェックをつけていないといけないデータ）の
２つに必要です
※checkbox自体も２つ以上ある場合があると思うので、「:id」「:name」にする箇所も一意にするために配列にする必要があるかと、、、
Aの中で選択とBの中で選択みたいな感じですね。


ソースはこんな感じです。

```javascript
          <div v-for="(items,idx) in チェックボックス一覧の配列">
                <input :id="うまく一意となるように設定" 
                       :name="うまく一意となるように設定" 
                       :key="items.id" 
                       type=checkbox
                       v-model="データの配列"
                       v-bind:value="items.item"
                       :checked="データの配列.indexOf(items.item) > -1" />{{ items.item }}<br>
                       <!-- 初期のチェックがないらないので、v-modelとv-bind:valueを併記する -->
          </div>
```

#ちょっと説明
前途の通り、「:id」「:name」を設定し、
「チェックボックス一覧の配列」をv-forで回すのですが、この配列が連想配列になっているので
「:key」には、itemsのidを指定しています。
「type」は「checkbox」でいいですね。
「v-model」には、初期でチェック表示したいデータがVueのvmのrefits[4]を指定します。
この配列の中に、更にデータが配列で入っているイメージです。
「v-bind:value」には、v-forで回っているitemsの連想配列のitemを指定します。
そして初期のチェックをつけるために「:checked」には、
「refits[4].indexOf(items.item) > -1」左記の判定式を入れました。

v-modelは、v-bind:valueとv-bind:onを包括的に、、、みたいな記事もありましたが、
とりあえず、上記で私の試した感じだとうまくいっております。
v-modelとv-bind:valueに違うものを設定しているので、上記の記事と異なるのはわかりますが、なぜ動くのはいまいちよくわかっておりません。
理解できた方教えてください。

#感想
表示のされ方が分かればデータを作成するだけなので、
ゴリゴリ書くより断然楽になりますね。


[ハマったところinputの再描画編~~](https://qiita.com/yamamow/items/ad967a1dbfda6f9e4aa8)

全体の記事はこちら↓
[スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版 その１～～](https://qiita.com/yamamow/items/6be4fa99cd3cb45ecffa)

[スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版 その２～～](https://qiita.com/yamamow/items/38ad08c3cf85ec9df0e7)
CodeBuildのVPC構成でハマった点をメモ

# 適当に設定してみたらダメだった
- CodeBuildプロジェクトを作成
- パブリックサブネットしかない状態でVPC設定しようとしたら、「プライベートサブネットに配置するべし」とエラーが出る。※CodeBuildの「VPC設定の確認」ボタン押下時
- プライベートサブネットを作成して再チャレンジしたら「0.0.0.0/0へのルートがない」みたいなエラーになった
- 困った・・・

# Lambdaの時を思い出した
- LambdaをVPCにのせた時も似たような話があったことを思い出す。
- `[こちらのサイト](https://qiita.com/kojiisd/items/a15c1807c5c6bb08add0)が物凄く役に立ちました。ありがとうございます。a lot of 感謝。

# 結論からいうと以下の要件が必要です。
- CodeBuildからCodeCommitを見るためにはインターネット接続が必須。
- 接続構成にはPublic SubnetとPrivate Subnetの二つのSubnetが必要。
- VPCにはInternet-GWがアタッチされていること
- Public SubnetのルートテーブルにInternet-GWが設定されていること。
- CodeBuildを実行するSubnetはPrivate Subnetに配置する必要がある。
- 当該Private SubnetにはNAT GWが接続されている必要がある。
- ★当該NAT GWは、★★Public Subnet側★★に配置しなければならない。

# 適当にNAT-GWをPrivate Subnetに作成していたのが原因
- 適当に作業してはいけない事をひどく反省しました。
- 多くの時間を浪費した事も反省しました。