OmniAICreator/Qiita-1.07M huggingface dataset:
AWS 認定 Alexa スキルビルダー取得にむけて、全然わからんので用語を整理してみる

# はじめに
AWS認定資格としてAWS 認定 Alexa スキルビルダーが気がつけば追加されていた。
Amazon Lexならともかく、AlexaってAWSの仲間なの？ 的な疑問はさておき、AWSなのにBlackbeltに説明もなく仕様も良くわからん。というのが正直なところ。
資格取得はまあ置いといて、とりあえずカスタムスキルの概略まで頑張って理解した時のメモ。

## アカウント管理

AWSな人たちが触れる最初の壁。
Alexa開発視点でまとめると、こうなる？

- AWS 開発者コンソール(Amazon Developer)
  - 2019.11現在「Alexa Skills Kit(ASK)」「Alexa Voice Service(AVS)」の開発に対応。
  - ASKがAlexaスキルの設定の要となるもの。
  - AVSは今回は省略。
- AWSアカウント
  - (AWS使いには)おなじみアカウント
  - Alexaスキルのバックエンドのリソースを構築・設定するところ。
     - 基本はAWS Lambda、EC2/Fargate等でいい感じに処理すればOK。
     - AlexaとJSONの受け渡しが出来れば、ぶっちゃけHerokuとかでもOK。
         - ~~もういよいよAWSじゃないじゃん~~

## Alexaスキル

Alexaのスキルは大きく分けて、下記の3つが代表的。

- スマートホームスキル
  - **対応機器を操作する**為のAlexaスキル
    - 要は、声でのリモコン操作
  - スキル名(呼び出し名)を言わなくても使える
    - 例：テレビつけて、今日の天気は？
- フラッシュブリーフィングスキル
  - **在りもののコンテンツを読み上げ/再生**する為のAlexaスキル
    - RSSをAlexaに読み上げさせたり、音声を再生したり？
- カスタムスキル
  - バックエンドにAWS LambdaやWEBサーバなどの処理部分を開発者が用意し、**柔軟な動作をする**Alexaスキル。
    - Alexaスキルを作りこみたい時は、コレ！
    - Alexa スキルビルダー対策としてはこの辺の知識が必要なのかな。

## カスタムスキルの利用例

カスタムスキル周りでは用語がたくさん出てくるが、用語の示す概念を理解するのが難しい。
実例に即して理解を試みたい。結果としてごちゃついたが……

- ユーザーが「**アレクサ**、**俺の寿司予約くん**を**起動して**、**マグロづくしセット**を**注文して。**」とAlexa対応デバイス(Echo)に話しかける
  - アレクサ = **ウェイクワード**
      - **Alexa**を起動させるためのワード。いわゆる「鏡よ鏡」。
  - 起動して = **起動フレーズ**
      - **Alexaスキル**を起動させるためのワード。後述するスロットや注文フレーズが決まってなくても、起動フレーズさえあればとりあえずAlexaスキルは動く。
- Echoがデバイス内のAlexaに音声を渡す。
  - Alexaは文脈を解析し、**呼び出し名**、**呼び出しフレーズ**と**スロット**を抽出する。
      - 俺の寿司予約くん = **呼び出し名**
         - Alexaスキルを呼び出す際の名前。スキル名とは別の概念なので、呼び出し名とスキル名は同じでも別でもいい。
         - この例でもわかる通り、家族・来客等の前で呼べる名前にしましょう。
      - 注文して。 = 呼び出しフレーズ
      - マグロづくしセット = スロット
  - **呼び出し名**に対応する**カスタムスキル**が以下を行う。
      - 呼び出しフレーズに対応するインテント(発話意図)にスロットを渡す。
          - インテントは例えば**MySushiReserver-Intent**と定義する。
      - (インテントの)呼び出しフレーズ：例えば**予約するんだ**、**注文して**と定義する。
         - この設定の場合、呼び出しフレーズ外の内容を言ってもインテントは呼び出されない
             - OK例：「マグロづくしセットを**予約するんだ**」「マグロづくしセットを**注文して**」
             - NG例：「マグロづくしセットを**注文するんだ**」「マグロづくしセットを**頼んで**」
  - インテントのインテントスキーマ(対話シナリオの定義のようなもの)に、以下を設定する。
      - 標準ビルトインインテント
         - ストップ、キャンセル、ヘルプなどの一般的なアクション。
         - スロットは一部()を除いて非対応。
             - 一部=AMAZON.SelectIntent等。スロットの変更は不可。
      - カスタムインテント
         - スロットを引数として、バックエンドプログラムの関数(dialogue関数？)を呼び出すアクション。
             - スロットは名前、タイプ(型)を指定する。
             - 定義するのが面倒ならカスタムスロット設定することで、定義していない言葉をいい感じにスロット化する。
             - ただ、カスタムスロットはファジーな作りなのでAmazon的には非推奨っぽい？オウム返しスキルとか有名ですが…
- カスタムインテントではAlexaから受け取ったJSONを、Lambda等のバックエンドが処理。レスポンスをAlexaへJSONで渡す。
  - バックエンドの詳細は割愛。

- インテントスキーマに沿ってAlexaが発話する。

ざっくりこんな感じ、カスタムスキルは絵で描かないと大変ね。

## おまけ

- 個人的に用語が混在しやすいと感じた箇所にも簡単に触れる。
  - **スキル名**と**呼び出し名**
      - 前者はスキルの名前。カスタムスキルを公開する時に、この名前で公開される。
      - 後者はスキルを呼び出す時の名称。
  - **インテント**周り
     - インテントのインテントスキーマには標準ビルドインインテントやダイアログインテントを設定する。と書いて一発でわかる人は大丈夫。
      - 英語苦手な人には正直ハードル高いと思う。
- ちなみに公式はBlackbeltではなく、[こちら](https://developer.amazon.com/ja/docs/ask-overviews/build-skills-with-the-alexa-skills-kit.html)や[こちら](https://developer.amazon.com/ja/designing-for-voice/)なので、私もあなたも、お互いしっかり読みましょう。
Pegmatiteが素晴らしいツールなので自分好み(GitHub Enterprise Serverで使えるよう)にしてみた

# 〜[Pegmatite](https://chrome.google.com/webstore/detail/pegmatite/jegkfbnfbfnohncpcfcimepibmhlkldo) が素晴らしいツールなので自分好み(GitHub Enterprise Serverで使えるよう)にしてみた〜道のりとその先へ・・・

## ~~拝啓~~背景
- 願望として
    - ドキュメント(管理)をどうにかしたい
    - GitHub Enterpriseがあるので有効活用したい
    - [PlantUML](http://plantuml.com/ja/) を使うとテキストベースで図が描けるので利用したい
        - PlantUMLはMarkdownに埋め込める
            - GitHub Flavored [Markdown](https://github.github.com/gfm/) でもモチロンOK
            - [Asciidoc](http://asciidoc.org/) にも埋め込める
                - [Githubでレンダリングされる軽量マークアップ言語](https://github.com/github/markup) のうち、割と人気っぽくてMarkdownに記法が近く(※個人的感想)、Markdownに足りないテーブルの結合が書けるので併用したい
    - Githubだとサイズの小さいCSVやTSVがテーブル表示されるので利用したい
        - ローカルは [Visual Studio Code](https://code.visualstudio.com/) のプラグインでプレビュー可(Markdown, Asciidoc, PlantUMLもそれぞれ在る)
    - Github( Enterprise)側でも図が見たい
        - 埋め込めるが図自体のバージョン管理/差分比較がし難くなるため、ブラウザの拡張機能で実現したい
            - 良さそうな拡張機能があった
                - GitHub Enterprise(コーポレートドメイン)では使えない
                    - デベロッパーモードで改造するしかない
                        - ソース等を良く見てみると機能改修もできる？
                            - とりあえずローカル環境で弄ってみる

## 環境
- macOS High Sierra
    - バージョン 10.13.6
- MacBook Pro (Retina, 13-inch, Early 2015)
- (社内認証)プロキシ サーバー 有
    - Cntlm利用

※Windows(10)環境でもOK(だと思います)

- Pegmatite 1.5.1

## 結果(※都合によりGitHub環境)
Asciidoc -> Markdown の順
![github.plantuml.sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116864/a64af016-f103-6771-6d3c-0d66c42d838b.gif)

## やった(will contribute if accepted)こと
1. [GitHub](https://github.com/dai0304/pegmatite) からFork
2. `develop` ブランチから `feature` ブランチを作成
3. 自分好みへ
4. ~~`feature` ブランチを `develop` へrebase~~
    - READMEではこのように記載されているが、実際は下記の運用となっている
5. `feature` ブランチを `develop` へpull request <= イマココ

### 3. 自分好みへ(詳細)
- Asciidoc対応が `gitlab.com` のみだったので、`github.com` にも対応させる
    - 合わせてAsciidocの場合と同様Markdownでもコードブロック背景が画像描画の際には親背景となるように変更
- GithubがSPA？pjax利用？のため、ページ遷移してもスクリプトが起動しない
    - [Issuse](https://github.com/dai0304/pegmatite/issues/21) に挙がっているが、別アプローチ
        - ソースコードはベストではなくベターな感じです・・・

#### その他PR予定なもの
- ドキュメント(Markdown)のtypo修正
- オプション(options.html)のcss記述typo修正
- rawdeflate.jsのバージョンアップ
    - [コチラ](https://qiita.com/take_3/items/ae3254a172c67369244c) によると現バージョンの方が広まっているようだが・・・
- 上記「結果」で利用したサンプル追加

### 本当の自分好み対応はローカルのみ(PR対象外)
- 社内で利用しているGitHub Enterprise Server(コーポレートドメイン)も対応させた
    - Google Chrome 機能拡張をデベロッパー モードにし、上記のディレクトリを読み込んだ

※別途、ローカル環境にDockerで [PlantUML Server](https://hub.docker.com/r/plantuml/plantuml-server/) を起動させ、オプションでローカル環境を指定した(セキュリティ面で)

## 感想
本投稿時点ではpull request前のため「自分好み」と表現していますが、(PRが受け入れられたら)世の中に貢献できる内容だと思っています。
Google Chrome ExtensionsはJavaScriptをゴリゴリ書ける人が開発した方が良いとは思いますが、ゼロベースでなければOSSらしく参加するのもアリではないでしょうか。

PlantUMLは素晴らしい！
もっと広まって欲しいです。

ただ、ローカルのPlantUML Serverは重いので、社内で強いサーバを建ててもらえるよう活動していきたいと思っています。
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'presentingViewController must be set.' のエラー解決方法【GoogleSignIn for iOS】


SwiftでFirebaseを使ってGoogleログインするときにでたエラーの解決方法です。

#原因

出たエラーはこちら

```
Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'presentingViewController must be set.'
```

ボタンをクリックしたときグーグル認証されるというもの。
ボタンをタップしたときに上記のエラーが起こる。

```googleLogin.py
    @IBAction func loginGoogleButton(_ sender: Any) {
         GIDSignIn.sharedInstance()?.signIn()
    }
```

#解決方法

これを

```
GIDSignIn.sharedInstance()?.uidelegate = self
```

こう変える

```
GIDSignIn.sharedInstance()?.presentingViewController = self
```

Google Sign inがバージョン5.0.0になったことで色々仕様が変わったようですね。
以下引用
公式ドキュメント
https://developers.google.com/identity/sign-in/ios/release
github
https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues/1370
HamlをRuby on Railsアプリケーションに導入する方法

##Hamlとは

Hamlとは、HTMLを簡潔かつ簡単に記述できるマークアップ言語。

##Railsで使用する場合の手順

###1. Hamlを導入
Gemfileの一番下にコードを記述すると、すべての環境でhamlが使用できる。
記述後は、**bundle installを忘れずに** 。

```ruby:Gemfile
gem 'haml-rails'
```

###2. erbファイルをHamlに変換
rails newにより、erbファイルがすでに作成されているので
拡張子がerbのファイルをhamlに変換する。

####一括変換する方法
ターミナルから以下のコマンドを実行。

```
$ rails haml:erb2haml
```
ここで、

```
Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n)
```
と聞かれたら、状況に応じてy/nを選択する。

**元のerbファイルを削除して構わなければ** yを選択しよう。
【RPA】ロボットの稼働方法 (ヒトロボ協働型・ロボ自律型)別ライセンス提供/ツール別比較

RPAにおけるロボットの動作には2種類の方式があるのをご存じですか？1つは人間のユーザーが使っているパソコン上で一緒に稼働する方式 (**Attended**/ヒトロボ協働型) 、もう1つはRPA専用マシン上でサーバーからの指示で自律して稼働するタイプ (**Unattended**/ロボ自律型) です。人間と一緒に動作するAttendedタイプは、人間のPC作業を直接支援したり、ロボットを仲介して複数の人間ユーザーと共同作業したりといったことが想定されます。一方、専用マシンで自律して稼働するUnattendedタイプはひとまとまりの切り離された作業をただひたすら実行する想定です。

これらのタイプの違いは稼働時間の違いやライセンス費用の違いにも表れてくることがあります。Attendedタイプは人間が稼働している間、つまり1日最大8時間の稼働となる一方、Unattendedタイプは24時間の稼働が可能です。そのためUnattendedはAttendedの3倍以上の仕事効率があるとも考えることができます。Attended/Unattended用のライセンスが分かれている場合は、Attendedの値付けはUnattendedの数分の1となっています。

ということで、ロボットの稼働方法別ライセンス提供について主要5大RPAソフトウェア (WinActor、BizRobo!、UiPath、Automation Anywhere、Blue Prism)の比較をしてみたいと思います。

# ロボットの稼働方法別ライセンス提供 - ずばり比較！

**凡例**
👍: 対応するライセンスがある。
❌: 対応なし。

|RPAソフトウェア|Attended|Unattended|説明|
|:--|:--:|:--:|:--|
|WinActor|👍|❌|RDAであるため、基本はユーザーのデスクトップPCで動作することが想定されています。ライセンスタイプの違いはありません。|
|BizRobo!|👍<br/>(mini)|👍<br/>(Basic)|ライセンスタイプの違いはありませんが、製品の違い Bizrobo! miniとBizrobo! Basicはそれぞれデスクトップ型のRDA、サーバー型のRPAなので、この違いがAttended/Unattendedの違いと考えることもできます。|
|UiPath|👍|👍|Attended、Unattendedの2種類のライセンスがあります。|
|Automation Anywhere|👍|👍|Attended、Unattendedの2種類のライセンスがあります。|
|Blue Prism|❌|👍|"本番環境" の最大同時実行ロボット数のみ課金対象というのが特徴です。課金は専用マシンでの実行 (=ロボ自律型) のみ想定しており1種類です。|

# 参考記事

* [UiPath - Attended ロボットと Unattended ロボットの両方を適材適所で活用](https://www.uipath.com/ja/product/robots)
* [BizRobo! mini の紹介](https://rpa-technologies.com/lp/bizrobomini/)
* [Automation Anywhere - Attended や Unattended RPA に最適なプラットフォーム](https://www.automationanywhere.com/jp/solutions/attended-vs-unattended-rpa)
* [Blue Prism の特長 (日本語資料) ](https://www.blueprism.com/japan/resources/white-papers/blue-prism-competitiveness/)

# 関連記事

* [【RPA】ロボット実行環境のOS対応状況/ツール別比較](https://qiita.com/Okura_/items/8975d6cd7ba0ff2ff61b)
* [【RPA】基本用語/ツール別比較](https://qiita.com/Okura_/items/2cb0dd2ce17356bb50ea)
* [【RPA】どのランタイム環境上で作られているか/ツール別比較](https://qiita.com/Okura_/items/a3f9393267e655e7300d)
* [【RPA】メールの送受信/ツール別比較](https://qiita.com/Okura_/items/369d95a938a05e836417)
* [【RPA】自動化に対する思想/ツール別比較](https://qiita.com/Okura_/items/1c8b29d40d98f2e5ce63)
* [【RPA】サーバー管理の仕組み/ツール別比較](https://qiita.com/Okura_/items/dfc380ec50df6b289391)
* [【RPA】トリガー・スケジュール機能/ツール別比較](https://qiita.com/Okura_/items/7d5e617260378fd2947f)
* [【RPA】オブジェクト指向のロボット作成/ツール別比較](https://qiita.com/Okura_/items/923706e8f4c8e3628522)
* [【RPA】シンクライアント操作への対応/ツール別比較](https://qiita.com/Okura_/items/13de777603cd9912992b)
* [【RPA】SAP対応/ツール別比較](https://qiita.com/Okura_/items/b265ca3f083b92471b58)
* [【RPA】対応ブラウザー/ツール別比較](https://qiita.com/Okura_/items/8501117954139300f427)
* [【RPA】コーディング知識の必要度/ツール別比較](https://qiita.com/Okura_/items/71a577e2141591c88a33)
* [【RPA】UI Automation 対応状況/ツール別比較](https://qiita.com/Okura_/items/95a78c46454ae0dac036)
* [【RPA】ログイン情報の保管方法/ツール別比較](https://qiita.com/Okura_/items/12cdcc743670c6d9c7c7)
Windows form テーブルの配置

#テーブルの作成
ツールボックスのTableLayoutPanelを配置
列と行を増やす
プロパティのCellとRowを好きな数に設定

#結合
ツールボックスからLabelをテーブル内に配置
![スクショ３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/0bf163d8-6741-ab2e-7a13-a3c0a695b467.jpeg)
配置したLabelを選択
プロパティにCellSpanとRowSpanがあるので今回は行を結合するので、RowSpanを２に変更
DockプロパティをFillに変える
TextAlignもCenterに変える
![スクショ２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/76969b2a-226f-768f-3a98-8dbcacaab770.jpeg)
余計なmarginがはいっているので0,0,0,0に変える

完成
![スクショ１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/bc1d467b-4121-2214-2b72-929b67a215ce.jpeg)

#１つのセル内に複数の要素を配置する
ツールボックスからpanelをセルに配置する
marginを0,0,0,0に設定
![スクショ４.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/57941195-a971-3329-03c6-0cfacb8fca21.jpeg)
あとは好きにpanelの上にドラッグして配置できる
![スクショ５.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/e8558045-aa47-e77a-3aa0-c494663c1902.jpeg)
OpenDataをつかった戦い方

## 注意
- 別に著者は今特になにかやってないです…(ごめん)
- 過去やっていたことをベースにはなすよ
- 地元に貢献している（したい）ローカルエンジニア交流会で発表しようかまよったけど作るのが間に合わなかったスライドです
- そのうちしたいけどいったん供養がてらにここにおいておきます

---  

##  貢献のカタチ

- 地域企業で働く
- 地域コミュニティ

--- 
##### けどボッチには
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77203/9fe4e2cc-71f8-99c5-88d5-e80dfd085ab6.png)
※ 素材: http://enjoynet.co.jp/ip_policy

--- 

## 個人でできる貢献はないんだろうか?

---

## そこでOpen Dataという戦い方
- OpenSorceSoftwareのデータ版
- 総務省「地方公共団体のオープンデータの推進」
- 行政が持っている貴重なデータ
    - 必要な人に届いていないという現状
 
---
## 2017年 当時学生

--- 

## 2017 当時学生
- ちょうど横浜市がOpen Yokohama構想
- アイディアソン/ハッカソンを弊学で実施
- 「面白そうだしやるかぁ」

--- 

### しかし
- データの形はバラバラ
- データの質が微妙
- エンジニアライクではない

--- 
### それでも

- 無駄な手続きを必要せずに行政データが使える
- 普段さわることのない領域
- 必要な人にわかりやすく情報を伝える
- エンジニアでも触れる形のデータにする

---- 
### OpenDataを選ぶきっかけになれば幸いです
Mask R CNN をAnacondaを使って RTX-2070Super上で動かしてみた

#　目的
噂に聞いたMask R CNN をデスクトップＰＣに入れてみたところ、GPUかなりが比較的新しいせいか、はまってしまったので、自分のメモがてらシェアします

# 　環境
Windwos10
CPU Corei7 9700 
RAM 16GB
GPU RXT-2070 Super 8GB

#　やったこと
Anaconda上に新しい環境を作成
Git Hubから
https://github.com/matterport/Mask_RCNN
をダウンロードして、
pip install -r requirements.txt
で環境のインストール
途中Shapelyでエラーがでたので、いろいろ調べた挙句
https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely
Shapely-1.6.4.post2-cp37-cp37m-win_amd64.whl
をpip install でインストール
https://github.com/cocodataset/cocoapi
をダウンロードして
その中のPythonAPIの中で
python setup.py build_ext install
を実行
https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5
をダウンロードして、MASK_RCNNフォルダに移動
ここまでは順調だったのですが、いざsamplesの中のdemo.ipynb
を実行しようとjupyter notebookを立ち上げると画面が真っ白で動かない
ここは
https://qiita.com/TaroNakasendo/items/b03216c0e2b611f1823e
を参考にさせていただきなんとか凌ぎました
それでも、実行中にKernelが落ちてしまい結局は解決していませんでした
その後はトライアンドエラーを繰り返しましたが、なかなかデモをうごかせませんでした

#解決方法
Anaconda上で新しく仮想環境をつくった際に先に、Tensorflow1.14.0,Tensorflow-gpu.14.0,Keras,Keras-gpuを入れてCuda toolkit 10.0(.130),cudnn7.6.0が入っていることを確認し、その後上記の一連の手順を実施してようやく動くようになりました
色々と試しましたが結局は何が悪いのかは不明でした

#
初心者によるプログラミング学習ログ 172日目

# 100日チャレンジの172日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

172日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>171日目<br><br>webサイトコーディングの課題<br>短い縦線の区切り線追加とか<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1200143422914347008?ref_src=twsrc%5Etfw">November 28, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

ツイートは171日目ですが、172日目です。
【Github Actions】FlutterのビルドをApp Distributionに自動デプロイする


##はじめに
Pull Requestがマージされた際に、最新のマージされたバージョンをFirebase App Distributionにデプロイする作業をGithub Actionsで自動化したものです。 Github Actionsの基本的な動かし方については[こちらの記事](https://qiita.com/1915keke/items/8b18097d2981e88eca93)でわかりやすく説明されているので参考にしてみてください。
##Workflow全体

```yaml:.github/workflows/deploy_after_merge.yml
name: deploy_after_merge

on:
  push:
    branches:
    - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - uses: subosito/flutter-action@v1
        with:
          channel: 'stable'
      - name: build and download apk
        run: flutter build apk --release
      - name: upload artifact to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1.1.1
        with:
          appId: ${{secrets.FIREBASE_APP_ID}}
          token: ${{secrets.FIREBASE_TOKEN}}
          groups: ANDROID_TEST
          file: build/app/outputs/apk/release/app-release.apk
```
##使用するオープンソースのActions
flutterのコマンドを打つための Action です。
[![subosito/flutter-action - GitHub](https://gh-card.dev/repos/subosito/flutter-action.svg)](https://github.com/subosito/flutter-action)
App Distribution にデプロイするための Action です。
[![wzieba/Firebase-Distribution-Github-Action - GitHub](https://gh-card.dev/repos/wzieba/Firebase-Distribution-Github-Action.svg)](https://github.com/wzieba/Firebase-Distribution-Github-Action)


##`secrets`の設定
```yaml:.github/workflows/deploy_after_merge.yml
with:
  appId: ${{secrets.FIREBASE_APP_ID}}
  token: ${{secrets.FIREBASE_TOKEN}}
  groups: DEPLOY_TEST
  file: build/app/outputs/apk/release/app-release.apk

```
`FIREBASE_APP_ID`と、`FIREBASE_TOKEN`という名前の Secret を Github 上に作る必要があります。Secret の作り方は[Githubのヘルプ](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)を参考にしてみてください。

- `FIREBASE_APP_ID`の設定
<img width="984" alt="スクリーンショット 2019-11-28 20.28.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488239/70bdb09a-f680-280f-ecfa-1567d4234baa.png">
Firebase console で「プロジェクトの設定」という画面を開くとアプリIDがあります。`FIREBASE_APP_ID`という名前で、ちょうど上の画像で赤線で隠されている値をGithubのSecretsに追加します。


- `FIREBASE_TOKEN`の設定
[Firebaseのリファレンス](https://firebase.google.com/docs/cli?hl=ja#cli-ci-systems)を参考にトークンを取得した後、`FIREBASE_TOKEN`という名前でSecretsに追加します。

##参考
- [Github Actionsが使えるようになったので使ってみる](https://qiita.com/1915keke/items/8b18097d2981e88eca93)
- [Github ヘルプ Creating and using encrypted secrets](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
- [Firebase リファレンス](https://firebase.google.com/docs/cli?hl=ja#cli-ci-systems)
- [CI/CD for Flutter Apps Using GitHub Actions](https://medium.com/better-programming/ci-cd-for-flutter-apps-using-github-actions-b833f8f7aac)
- [Custom Github Action for Firebase App Distribution](https://www.tooploox.com/blog/custom-github-action-for-firebase-app-distribution)
Fork（Gitクライアントツール）

# 無料アプリではない
Forkは無料のアプリではなく、長期間の利用は有料でライセンスの購入が必要なアプリでした。
https://git-fork.com/license

自分の調査不足で勘違いさせてしまう情報を公開してしまい、申し訳ありません。
@DogFortuneさん ご指摘いただきありがとうございました。

---

# 概要
Gitクライアントツールとして、有名なツール [SourceTree](https://www.sourcetreeapp.com/) は利用する際にAtlassianのアカウント認証が必要。

Bitbucket を使うならいいが、今の業務では [GitLab](https://gitlab.com/) を使ってソース管理をしているため、
ツール使うためだけにアカウント作るのは面倒だった。

~~SourceTreeと似たようなことができるツールないかな（無料で）と探していた時にたどり着いたツールの紹介。~~
長期間の利用は有料でライセンスの購入が必要なツールでした。

# Fork
https://git-fork.com/

使える機能の説明などは上記のページに詳しく書かれています。
各ブランチごとのコミット履歴の確認やファイル差分の表示など、
自分がGitクライアントツールを使って確認したい内容は満たされていたので、使おうと思いました。

# インストール方法
以下のリンク先からインストーラーをダウンロードできるので、実行してインストールするだけ。
Windows・Macともに対応しています。
　https://git-fork.com/

# 感想
使っていて不便に感じることがほとんどないため、かなり気に入っています。
~~SourceTreeを使おうと思ったけど、アカウント作るのが面倒と思ったときはぜひ使ってみてください。~~
正規表現まとめ　学習記録

#メタ文字
. 改行を除く任意の文字列
\ メタ文字のエスケープ

#文字種
\d 0-9
\D \d以外

\w a-z,A-Z,0-9,_
\W \w以外

\s スペース、タブ、改行
\S \s以外

#量指定子
{n} n個
{min,max}　min以上 max以下
{min,}　min以上

? {0,1}
+ {1,}
* {0,}

01-2345-6789
0123456789
TEL01-2345-6789
T0123456789

上記の全部の検索に引っ掛けたい時の例
\w*\d{2}-?\d{4}-?\d{4}

1番短い文字列にマッチさせる
"apple","orange","grape"
".+"だと全てを1つの文字列として選択してしまうので
".+?"のように量指定子の後に？を追加すると短い文字列にマッチさせる

#アンカー　位置を指定する
\A 始まりを指定
\z 終わりを指定
^ 行の先頭を指定する
$ 行の末尾を指定する
\b 単語の境界を指定する

#選択子
| →　or

example.com
example.net
を両方検索で引っ掛けたい時
example.com|netだと後者はnetしか引っ掛からないので、
example.com|example.net または　example\.(net|com)とする

#文字クラス
[]を使う
[abc]　a,b,cのどれか1文字という意味になる

##文字クラス内のメタ文字
^
[^c]とすると否定の意味になり、c以外の文字という意味になる　[]の直後のみ

-
[A-F]　ABCDEFといった範囲指定の意味
※ただし、文字コードには順番があり、遡っての指定はできない

#改行とタブ
\t タブ
\r\n 改行　Windows
\r v9までのMacOS
\n 改行　v10以降のMacOS、Unix
全てを選択したい場合は
\r\n|\r|\n

#キャプチャ
() 
 $1,$2,....　()に保存した文字を取り出して置換で使うことができる

google,https://google.com　
という文字列があった場合
(.+),\s?(.+)で検索し、
```<a href="$2">$1</a>```で置換することによって
```<a href="https://google.com">google</a>```になる

#後方参照
3,7,3,3,4,5,5,6,9,8
で連続した数字の時だけ検索したい場合
(\d),\1としてキャプチャしたものを\1などして使う
FuelPHPのEmailパッケージのドライバを追加してSendGridでメールを送信する

FuelPHP の Email パッケージから呼び出して使えるドライバを実装しました。今回は SendGrid のドライバを実装しましたが、他にも応用できると思います。

# やりたいこと
* Email パッケージを使用して `mail()` 関数でメールを送信している処理を SendGrid に置き換えたい。
* 既存の Email パッケージの関数を呼び出している処理をできるだけ流用したい。
* できるだけきれいに拡張したい。

# 環境
* FuelPHP 1.8.2

# Email ドライバクラスの作成
`fuel/app/classes/email/driver` ディレクトリ以下に `Email\Email_Driver` クラスを継承する `Email_Driver_<ドライバ名>` クラスを作成します。
Email パッケージのソースコードを参考にして、他のドライバと同様の命名規則となるディレクトリ構成とクラス名にします。

```php:fuel/app/classes/email/driver/sendgrid.php
<?php
class Email_Driver_Sendgrid extends Email\Email_Driver
{

}
```

Email パッケージの設定ファイルで、新たに作成したドライバを指定します。Mailgun ドライバに倣って、API キー等のドライバ固有の設定も併せて記載します。

```php:fuel/app/config/email.php
<?php
return [
    'defaults' => [
        'driver' => 'sendgrid',
        'key' => '<YOUR API KEY>',
    ],
];
```

これで新たに作成したドライバが呼び出されるようになりました。あとは必要な関数を実装していきます。継承元クラスのうち、必要な public 関数を読み進めて、適宜オーバーライドします。

```php:fuel/app/classes/email/driver/sendgrid.php
<?php
class Email_Driver_Sendgrid extends Email\Email_Driver
{
    protected function _send()
    {
        // Email\Email_Driver::_send() をオーバーライドする

        // メールの送信処理を実装する

        // ドライバがメール送信に失敗した際に投げるための例外が用意されているので、
        // 失敗したら投げる 
        throw new EmailSendingFailedException;
    }

    public function cc()
    {
        // ドライバで対応しない関数が呼び出されたら例外を投げるなどする
        throw new LogicException;
    }
}
```

# 参照
* [FuelPHP Documentation](https://fuelphp.com/docs/)
* [GitHub - fuel/email](https://github.com/fuel/email)
git パスワードを毎回聞かれる問題をHTTPSでも解決

GitHubに``git push``するときに毎回ユーザ名とパスワードが聞かれますね．

ググるとSSHを使うページが多いですが，**GitHubの推奨はHTTPSです．**
HTTPSでも聞かれなくする方法を紹介します．

## 結論
HTTPSでCloneしたリポジトリで，

```
git config credential.helper store
```

**を実行して，ユーザ名，パスワードをキャッシュさせる．**

これで，最初に一度ユーザ名，パスワードを入力すればそれ以降は聞かれなくなります．

ただ，これだと平文でパスワードが保存されるので，嫌な場合は後の項目を参照ください．

## 解説
基本的には，[公式のページ](
https://help.github.com/en/github/using-git/which-remote-url-should-i-use)に全部書いてあります．

HTTPSのほうが「ファイアウォールやプロキシ下でも使いやすい」のもあって推奨していてます．
その下のTipsの欄に，「パスワードを覚えさせるには[credential helperを使うといいよ](https://help.github.com/en/github/using-git/caching-your-github-password-in-git)」って書いてあります．

GitHubとしては，メモリにキャッシュとして記憶するオプション (``git config  credential.helper cache``) を紹介しています．
デフォルトは15分でキャッシュが切れます．

``git config credential.helper store``とすると，ファイル (~/.git-credentials) に``https://myusername:mypassword@github.com``のような形で，**平文で**保存されます．

## 平文テキストは怖いんだが...

[GitHubの解説ページ](https://help.github.com/en/github/using-git/caching-your-github-password-in-git)によると，Macではosxkeychain helper，Windowsではwincredが使えます．また，設定すればLinux (Ubuntu) ではgnome-keyringなどが使えます．


以下，MacとWindowsは動作未検証です．

### Macの場合
(1) osxkeychain helperがインストールされているか確認

```
$ git credential-osxkeychain
> Usage: git credential-osxkeychain <get|store|erase>
```
↑インストールされていなければ，``requesting install``と言ってインストールのプロンプトが出ます．

(2) osxkeychain helperをGitで使うように設定

```
$ git config --global credential.helper osxkeychain
```

### Windowsの場合
下記だけでwincredというhelperを使うように設定できます．

```
git config --global credential.helper wincred
```

### Linuxの場合
[このページ](https://blog.scottlowe.org/2016/11/21/gnome-keyring-git-credential-helper/) を参考に設定します．

(1) gnome-keyringのmakeに必要なライブラリを入れる．

```
sudo apt install libgnome-keyring-dev
```

(2) makeする

```
cd /usr/share/doc/git/contrib/credential/gnome-keyring
sudo make
```

(3) gitにcredential-helperを設定

```
git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring
```

## まとめ

credential.helperを設定しておけば，快適にGitが使えますね．
(ただ，当然ですがcredentialの情報が変わったときに再設定が必要なのでご注意．)
[UE4]カスタムMipmapの作り方

##自分好みのMipmapが作りたいなぁ
UE4にはテクスチャをインポートすると自動でMipmapを作成してくれる便利な機能があります。
![mip.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/6640ad03-e907-23f4-a1ad-b495344e0e7f.gif)
しかし、あくまで自動ですので、
状況によっては望んだMipmapを得られない事があります。
そんな時はMipGenSettingsを変更して、より良いMipmapを得られるように調整するのですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/f62cdd7e-6313-d83c-46a2-d3f40beb2e9e.png)
それでもやはり高Mipで形状が崩れてしまい、自分でMipmapを作成できないものか……と思うことがあると思います。
そこでUE4はカスタムでMipmapをインポートする事ができます。




##DDSファイルを作ろう
カスタムでMipmapを作成する為には、DDSファイルを作成する必要があります。
今回はNVIDIAが提供しているPhotoshopのプラグインを使用します。
（CS6までとなっていますが、手元ではPhotoshop CC 2019でも動きました。）
https://developer.nvidia.com/nvidia-texture-tools-adobe-photoshop
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/79230b2a-ff6a-5ca1-c03e-020f1092c8f1.png)

上記のプラグインをインストールするとPhotoshopでDDSファイルを作成することが可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/63ee54ed-c543-1bc5-a8e1-21424d62c67e.png)

Mipmapを自分で作りたい画像をDDS形式で、「Generate MIP Maps」のチェックを入れて保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/7c6eec62-4968-1c6f-1257-a57fb789fc33.png)

保存したDDS画像を、「Load MIP Maps」のチェックを入れて開き直します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/6d33db13-0619-232c-103b-3f7b9a606812.png)

すると、このように各Mipmap画像を編集できる状態で画像が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/da5b3394-08c3-7770-6545-f350f6735ebd.png)
好みのMipmapを作成して頂いて、「Use Exsiting MIP maps」のチェックを入れて再保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/46cf95a7-2402-f7f4-439e-e60056d606f6.png)


UE4にインポートすると……好みのMipmapが作成できました！
![mip2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/e9b255fa-e940-d6cb-f90c-e986cf0ab145.gif)

こいつを使えば今どのMipが使用されているかも確認しやすいですね。
![mip3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/6709cf86-1ce9-5aa1-1163-f45211991d6a.gif)
お前らエンジニアはもっと恋愛の実務経験を積んだ方がいい

「お前誰だよ？」と思う人がいると思うので、簡単に自己紹介。
20歳の時からホスト・スカウトマンとして修行。アラサーで遅咲きながらエンジニアとして転身し、WEB系ベンチャーに就職。周りのレベルが高くクビになるもSESで修行。
その後、開発実務経験2ヶ月で独立し、月給20→50万とUPさせることに成功。現在、Javaの案件に設計フェーズから参画中である。


今日伝えたいのは恋愛の話。
エンジニアが恋愛を鍛えるべき理由とメリットを以下に解説していく。


#周りのエンジニアの現状
この業界にきて驚いたのが、ビジネスマナーやコミュ力は愚か、最低限の挨拶すらできない「コミュ障エンジニア」が多いということ。また、女の子と今まで一度も付き合った経験なかったり、そもそも女性に興味のない人間が多い印象を受けた。（興味のないフリをしているだけだと思うが）

そして<b>何よりも見た目がダサい</b>。高いメガネ率、いつも同じ服装、髪がボサボサ、腹の出ただらしない体型、汗臭い男がいかに多いことか。一緒に働く身としてとても不快なので直して欲しいし、彼らにとってもあらゆるスキルが相乗効果的に伸びていくので、エンジニアが恋愛を鍛えることをメリットを述べながら提案したい。

#ルックスが向上する
恋愛を鍛えていく上でもっとも効果が高く、真っ先に改善するべきは見た目。
というのも、最初は「見た目でしか評価されない」のが現実だ。
もちろん、最終的には中身の方がはるかに大切ではあるが、初めて会った人間の中身など知るよしもないので、<b>見た目が10割ありその見た目から中身を判断するしかない</b>。

恋活をしていく中でルックスを鍛えることは絶対条件なので、自ずとレベルは上がっていくだろう。本物のイケメンを目指さなくていい。出た腹を引っ込める、汗の匂いに気をつける、髪型をしっかりセットして同じ服装は避けるなど、簡単なことから取り組んでいけばいい。まずは清潔感のある雰囲気イケメンを目指そう。



#コミュニケーション能力が向上する
恋愛を鍛えるということは、女の子と正面から向き合うということだ。

ナンパや出会い系アプリ、合コン・街コン、手段はなんでもいい、女性と1:1で会話する機会が今まで以上に増えていくだろう。いま仕事をしているなら、週末だけナンパに出ることから初めてもいい。1日100人の女性に声をかけるとすると、週200人・月間800人・年間で1万人近くの女性とコンタクトを取ることになる。これを続けていれば、<b>否が応でも女性慣れせざるを得ない</b>。

また、ナンパであれば「合流」という男同士で一緒に街に出て女の子に声をかける文化があるので、対同性とのコミュニケーション能力も同時に鍛えられるチャンスもある。


#技術力を磨くチャンスが増える
恋愛と営業は非常に似ている分野だ。
営業の分野における「見込み客の選定し、相手のニーズを理解して、自分の価値を伝え、クロージング（問題解決）する」という流れは、恋愛を攻略するためのプロセスそのものだったりする。<b>恋活で培った営業力を使えば、より環境の良い現場に入れるし、周りのエンジニアやプロパーとの関係構築がスムーズになる</b>。まさしく「恋愛を制する者は営業を制する」

実際、俺は前の現場で一緒になったフリーランスの人間と仲良くなり、彼から直接案件を紹介してもらうことができた。本来であればエージェントに中抜きされるであろう金額が、企業と直で契約することにより、手取りの金額が大幅にアップするという恩恵を受けた。

また、前案件で一緒に働いていたプロパー（現場の社員）には、「色恋くんは直接フリーで契約してもいいよ」と言われるほど良い関係性を作ることができたため、いつでもフリーで契約しようと思えばできる状況にある。これらは全て、今まで恋愛を鍛えていく中で培った営業力のおかげと言っても過言ではない。



#時流に乗る
今の時代、<b>エンジニアという職業についている時点でかなり有利なポジションにいる</b>ことをもっと自覚したほうがいい。ここまで時間とお金を稼げる職業は他にはない。働きながら恋愛を鍛えるのもいいが、オススメはとしては出来るだけ早くフリーになってしまうこと。最近まで手取り16万円のサラリーマンであり、技術レベルでいうとその辺の駆け出しエンジニアと変わらない俺がフリーになれたのだから、技術力なんて最低限があれば問題ない。

フリーになれば基本的には定時で帰れるし、稼げる金額も大幅に上がるので、恋愛を鍛えるにはもってこいのサイヤ人状態になれる。逆に言うと、<b>恋愛を鍛えたい人間は、エンジニアを目指すこともオススメだ</b>。今まで少しでもナンパ経験がある人間なら、その度胸とメンタルと容姿で周りのエンジニアを出し抜ける。この業界では技術力よりも営業力・コミュ力の方がはるかに大切なので、時間とお金を手に入れたいのであればそっちを鍛えた方が早い。

<b>結論：IT業務だけでなく、恋愛の実務経験を積んで最強のエンジニアになろう。</b>
baserCMS DBマイグレーター最新版で2系→3系利用時にエラーが出た時

> Fatal error: Interface 'BcDbMigratorInterface' not found in…

[baserproject/BcDbMigrator: baserCMSのバックアップデータのマイグレーションを行うプラグイン](https://github.com/baserproject/BcDbMigrator) をgithubの最新版 **BcDbMigrator-4.0.4** を、baserCMSで2系→3系にメジャーアップデートするときに使うとエラーになりました。

[こちらの記事](https://basercms.net/develop/archives/86)の日時から推測して、当時の公開バージョン[**BcDbMigrator-1.0.3**](https://github.com/baserproject/BcDbMigrator/tree/3361a3469afbd8caa0f0de640094f97d8eff90f8) を使うことで回避できました

[**BcDbMigrator-1.0.3 Zipダウンロードはこちら**](https://github.com/baserproject/BcDbMigrator/archive/3361a3469afbd8caa0f0de640094f97d8eff90f8.zip)
[TypeScript]配列にオブジェクトを格納する時の初期化について

備忘録として残す

共通部分

```typescript

interface TestInterface {
    name: string,
    data: DataInterface[]
}

interface DataInterface {
    date: string,
    value: string
}
```

# 空配列を用意してpush()する

```typescript
let test: TestInterface = {
    name: '',
    data: []
};

test.data.push({
    date: '20191129',
    value: 'いい肉の日'
});
```

# スプレッド演算子を使用して格納する

```typescript
let test: TestInterface = {} as TestInterface;

test.data = [...(test.data || []), {
    date: '20191129',
    value: 'いい肉の日'
}];
```


# 注意点

`{} as interface`で初期化を行うとundefinedが格納される。

スプレッド演算子の方が行数は少ないがスプレッド演算子に慣れていないと可読性は落ちる
社内アプリのログイン認証をGoogleにする

#はじめに
今年もアドベントカレンダーの季節がやってきました。
僕のパートでは、実際に社内開発で検証したForgeの紹介をしていきます。

それと、去年のアドベントカレンダーの記事が地味にPVやらストックが増えていて、最近Outsystemsを導入している企業が増えているのかな？と感じました。これは嬉しいことですね。
[外資系の社内SEに転職して、Outsystemsと出会った(環境構築編)](https://qiita.com/fuyuiro/items/e7d0970ee9e934a8b65f)


#想定読者
Outsystemsのログイン機構をGoogleにしようかな～と思っている方

#事前準備
下記googleLoginのForgeをダウンロードしてください
https://www.outsystems.com/forge/component-overview/3375/google-sign-in


GoogleのDevコンソールでOAuthのクライアントIDを発行する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/41020765-67be-9ff1-5388-7cbebca8e3f3.png)



#できること
会社で利用しているメールのドメインがGoogleであれば、いちいちOutsystems上でユーザーとパスワードを用意しなくても、
Googleアカウント経由でログインが可能になる。

#中身の説明

最初からDEMO画面があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/45e1b226-d3f1-4790-7c96-1253ed32dd89.png)

Googleで発行したクライアントIDをSitePropertyのClientIdにつっこみます。
![写真.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/0e1fb97f-845f-16f2-02ef-cc522ec9c506.png)


「Sign in With Google」をクリックすると、GoogleAPIとのRest通信がはしります。
Googleで発行したクライアントIDがミスっているとここで落ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/cd1aea4d-239d-81c9-f057-a942790991ca.png)

その後Notifiyにてログイン時のメールアドレスが渡されますので、
Outsystems側のEntityとAggregateのFilterで突合。
突合したユーザの存在をチェックして、ユーザーが存在すればログインが成功します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/9fbc98be-48a0-7305-dcd1-1265a9eb062f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/d9bd6b1d-18b4-4ca9-4374-4d0e1c47d851.png)


#実際に企業で使う場合
NotifyGetMessageで取得した、対象のURLに対してRegex_Searchにて企業のドメイン以外ははじく処理をいれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/2eb3f57c-5533-bd01-1e63-dcfc25480b6d.png)


それと、
もし新入社員や中途社員など新しいメンバーがJoinした場合、Entity側に対象のメールアドレスが登録されていない場合が想定されます。
その場合は、初回ログイン認証時時にユーザーを自動的に作ってあげると良いかもです。



#終わりに

ただのForgeの紹介になってしましたが、使ってみると便利だなと思いました。
中身の処理もすごいシンプルなので、自分色にカスタマイズしてみてはどうでしょうか。

###<font color="royalblue">クリスマスまであと22日！</font>
rails-tutorial第2章

###scaffold
MVCアーキテクチャではmodel,view,controlerが組み合わさって一つのリソースと考える。scaffoldを使うとリソース単位で自動生成してくれる。
scaffoldをしてサーバーを立ち上げると、その時点からuserリソースを扱える。/users/newとかできる。

###migration file
これはrailsとDBが全く別物だから、migration fileに書いて〜を保存するスペース作ってくれない？とお願いをしなければいけない。なので、rails generate scaffold User name:string email:stringなどの指示を出した後はrails db:migrateをしないとDBにリソースを保存することができない。ちなみに、rails db:migrateをせずにrails sをすると、　migration pending(DBに何かお願いすることあるんじゃないの？）というエラーを出してくれる。rails db:migrateはべきとうせいである。つまり何度実行しても追加したmigration fileがなければ何も起こらない。

###resources
これはルーティングのパッケージ版。本来　/users => user#indexなど基本のルーティングがパッケージングされてる。

###actionのデフォルトview
例えばindexアクションを呼び出した時、renderなどのviewを呼び出す指示が書いてないことがほとんど。その場合は、アクション名からapp/views/users/index.html.erbが呼び出される仕組みになっている。

![Qiita](https://railstutorial.jp/chapters/images/figures/mvc_detailed.png)
indexアクションの場合。




#後半戦
###bundle exec
このコマンドはgem fileを読み込んだ上でexec以下のコマンドを実行するというもの。 ex)bundle exec rails --version

##テーブルの関連付け
```
class User < ApplicationRecord
  has_many :microposts
end
```
```
class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140 }
end
```
これによって、User.first.micropostsなどが実行できる。

###そもそもなんで上記のコマンドでテーブルが結合される？
これはrailsのデフォルトによるもの。
micropostsテーブルにはuser_idというカラムがある。
model名_idというカラムがあり、結合すると、model名（ここではusersテーブル）のidカラムと自動的に結合してくれるから。


###validation
```
class Micropost < ApplicationRecord
  validates :content, length: { maximum: 140 }
end
```
これによって投稿の文字数を140文字に制限することができる。


###heroku注意点
上記のようにテーブルを作った状態でherokuにアップしようとすると、エラーになってしまう。
それはmigrationfileが開発用には適用されたが、本番環境では適応されていないから。開発環境用のDBと本番環境用のDBが違うことから起きる。

そのため、　heroku run rails db:migrate　としてあげる。

つまり、migrationfileを一つでも作ったら、git push heroku masterをした後に上記のコマンドを実行しなければいけないということ。

また、DBは違えど、Active RecordによってSQLが適切に書かれるのでそこを気にする必要はない。
chromedriver/seleniumコンテナで.pfxキー認証が必要なサイトにアクセスできるdockerfileを書く

RでWEBスクレープ、慣れるとひょひょひょーいと書けてホントに便利です。

で、たまにあるんですよねちゃんとセキュリティしてらっしゃる会社さん。
実に素晴らしい事なのですが、レア過ぎてなかなか情報が無かったので突破法だけ書きたいと思います。

#なぜできないか
1. .pfx 証明書ファイルを自動で追加する方法がわからん - これが出る
<img width="1178" alt="Screenshot 2019-11-29 at 19.12.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255842/3c162ac7-2065-ccdd-0aab-d0c1965b3a5c.png">



2. 追加できたんだけど、サイトにアクセスする度にブラウザがポップアップを開く(自動クリックめんどい)
<img width="1178" alt="Screenshot 2019-11-29 at 19.14.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255842/01d2b18c-413d-2b81-e841-6fc4976db9c8.png">





#対策は：
1.　dockerfile内でユーザレベルで追加する
2.　chrome policyで、証明書の自動セレクトを有効に

です。


# dockerfile 作ろう
まずは dockerfile と同じ階層に下記のファイルを用意します。

```./keys_dir.
key_password.txt - .pfxファイルのパスワードを平文で
key.pfx
policy.json - chrome policy 設定ファイル (下記)
```

Chrome policy ファイルの中身はこちら

```policy.json
{
    "AutoSelectCertificateForUrls": ["{\"pattern\":\"*\",\"filter\":{}}"]
}
```


上記を用意したら、dockerfileを作成します。

```dockerfile
FROM selenium/standalone-chrome-debug

# chrome policy
COPY keys/policies.json /etc/opt/chrome/policies/managed/
# key 関連
COPY keys/* /home/seluser/keys/

# 必要なツールをインストール
RUN sudo apt-get update
RUN sudo apt-get install libnss3-tools

# 証明書をユーザに追加
RUN mkdir -p /home/seluser/.pki/nssdb
RUN certutil -d /home/seluser/.pki/nssdb -N
RUN pk12util -d sql:/home/seluser/.pki/nssdb -i /home/seluser/keys/key.pfx -w /home/seluser/keys/key_password.txt
```

あとはお好きな名前をつけてビルドします

```build.sh
docker build --rm --force-rm -t mytools/selenium-withcert .
```

実行しましょう。
僕はダウンロードに使うことが多いのでこのように -v でマウントします。

```run.sh
docker run -d --restart always -v /dev/shm:/dev/shm -p 4444:4444 -p 5900:5900 -v ~/sel_dl:/home/seluser/Downloads --name selenium_cert mytools/selenium-withcert
```


以上です！！！
けっこう情報が無くて調べるの苦労しました。
いつか誰かの役に立つはず...


#おまけ
たぶん関係ないと思うんですが、もし上でうまく行かなかった方のために、
参考までに他に僕がしてるprefs/argsの設定も晒しておきます。
（まさかのRだぞわっはっは。python/java他の方は読み替えをお願いします）

```RSelenium_chromedriver.R
chrome_prefs = 
  list(  
    "profile.default_content_settings.popups" = 0L,
    "download.prompt_for_download" = FALSE,
    "download.directory_upgrade" = TRUE,
    "safebrowsing.enabled" = FALSE,
    "safebrowsing.disable_download_protection" = TRUE,
    "acceptSslCerts" = TRUE
  )

chrome_args = 
  c('--ignore-certificate-errors', 
    '--ignore-urlfetcher-cert-requests', 
    '--no-sandbox', 
    '--disable-gpu', 
    '--disable-web-security', 
    '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100')

eCaps_withhead = 
  list(chromeOptions = 
         list(
           prefs = chrome_prefs,
           args = chrome_args )
        )

# 初期化
remDr <- remoteDriver(
  remoteServerAddr = sel_ip,
  port = sel_port,
  browserName = "chrome",
  extraCapabilities = eCaps_withhead
)
```

[EOF]
Lambda+APIGateway設定で「CORS の有効化」をオンにしたのにCORSエラーになる

# 「CORS の有効化」をオンにしたのに
## ハマりポイント
APIGateway設定で「CORS の有効化」をオンにしているのに，
> Access to XMLHttpRequest at 'https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/xxx/xxxx' from origin 'http://xxxxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

とエラーが返ってくる．
## 解決策
Lambdaのreturnのヘッダーに以下のように，Access-Contraolについて書かなきゃダメだった．

```json
    return {
        'isBase64Encoded': False,
        "headers": {
            "Access-Control-Allow-Origin" : "*",
            "Access-Control-Allow-Credentials": "true"
        },
        'statusCode': 200,
        'body': {}
    }
```
rails new が出来ない問題。

初めてポートフォリオの作成に入っているのですが、
rails new　出来ないという問題にぶち当たりました。
これは文字通り rails new　のコマンドを打ち込めないといことと、
エラーが発生して意図した通りにアプリケーションが作成されないという二重の意味があります。
docker-compose コマンドも含めるべきなのか？
データベースはMySQLで行くのか？ Postgreを使うのか？
またその理由は？
テストはスキップして良いのか？
bundle installはスキップして良いのか？
悩み始めるといくら時間があっても足りません。
エイヤ！と思って
$rails _5.0.6_ new task-App --database=mysql --skip-bundle --skip-test
を実行しました。
今度は GemNotFoundErrorが発生しました。
Qiitaの記事を参考に試したことは、
$sudo bundle install これは　FilePermissionErrorが出ました。
$rails -s でも別のエラーが発生し、八方塞がりに。
もしかしたらdockerで別のコンテナが稼働しており、これが何らかの影響を与えているかも
と判断し、一縷の希望を託すような気持ちで
docker stop を実行。
稼働中のコンテナはないとのメッセージが表示されました。
全くエラーの原因について見当がつかない状況でPCを再起動しました。
結果、
$rails _5.0.6_ new task-App --database=mysql --skip-bundle --skip-test
が今度はうまくいきました。
OSが最新のバージョンでなかったことが原因なのかな？
理由が分からなくて、動かず怖いというのは頻発ですが、
動くのもまた怖い、という経験をしました。
5Gになると世の中何が変わるの？

#5Gとは？

"G"はgenerationの略。
通信方式の5世代目ってことです。

大まかに、
　1G：1980年代
　2G：1990年代
　3G：2000年代
　4G；2010年代
　5G：2020年～
という歴史をたどっています。
約10年ごとに進化していることがわかりますね。
今までの轍を踏めば、あと10数年で6G、20数年で7Gと将来は進んでいくことでしょう。

##で、5Gになると通信量はどうなる？

4Gの約100倍。あくまで理論値なので、実際は20倍ほどになるとのこと。
とはいえ、超大容量かつ、超高速。遅延も抑えることができて、多数接続も可能という5G。
これら能力を有効活用すればIoT(Internet of Things)、何から何までネットワークでつながり始めます。

##何から何までネットワークでつながると？

冷蔵庫→スマホ　がつながると「牛乳が足りない」とかそういう情報が常に手元に送られてくる。
といった例がよく挙げられてますが、そんなつまらないことが5G、IoTの本質ではありません。
何かの媒体からスマホに連動するのはすでに4Gの時代から始まっていて、
5Gの時代は情報の相互間を生かせる仕組みが整いつつあるというところが魅力です。

例えば、自動ドローンでの警備。ビルに侵入者を見つければドローン同士で常に侵入者の逃走経路を把握し合い、
侵入者を追跡しながら顔認証で人物を割り出し、ビルから逃げられたとしても、
街の防犯カメラでも位置を追走。それらの情報を警察と連携して物の3分で犯人確保。

車から送られる速度を分析して、超リアルタイムな渋滞情報を元に自動運転が判断して渋滞回避したり、
他の自動車、歩行者、自転車、オートバイ同士で位置情報を交換し合うことで、更に安全な自動運転が可能に。

スマホは通信が安定するため、全ての処理をクラウドに任せて自身では処理結果を貰って表示するだけのディスプレイになり、
ポケットサイズの丸められる有機ELディスプレイがスマホに。
家の窓ガラスは常に天気や時刻などの必要な情報を表示する情報ディスプレイに変わり、
通常サイズのイヤフォンも正確な翻訳結果をほぼタイムラグなく受け取ることができるリアルタイムなほんやくこんにゃくに。

デバイス相互間での情報発信が必要になるため、多くの弊害があるはずですが、
いつか近い将来4次元ポケットの道具を世に産み出せることができるのが5Gという技術かと考えてます。
【ImageJ Fiji,Python】砂嵐画像を任意のピクセル数で簡単に生成する方法

##砂嵐画像
こういうやつです。
Shaderで任意のピクセル数の砂嵐画像がほしいな～となったので作成する方法を調べました。
もっと楽な方法あったら教えて下さい。
![Rundom.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/50ca2558-8fd4-15d3-6651-189db73bb798.png)

##ImageJ Fijiとは？

>ImageJとは、Java というプログラミング言語で書かれた画像解析のためのソフトウェアです。

>Fiji はその ImageJ の種類の内の一つで、元々の ImageJ に様々な機能が追加されているパッケージです。オープンソースである ImageJ は、研究者・開発者により機能の追加が容易にできます。Fiji is just ImageJ （Fiji こそがまさに ImageJ だ）と表現されるように、Fiji はオープンソースである ImageJ の利点を最大限に活かして多くの機能が追加され、まとめられています。

>Fiji をインストールすれば多くの機能を利用することができます。例えば、超解像顕微鏡の一つであるSTOMのデータ解析のためのプラグインが含まれています。また、Java 以外のプログラミング言語で ImageJ を操作したり機能の追加をする機能も付属しています。

【引用元】：[ImageJ について](http://satoshithermophilus.hatenablog.com/entry/2017/06/07/233144)

##手順

まずはImageJ Fijiをダウンロードします。
[ダウンロードリンク](https://imagej.net/Fiji)

ダウンロード完了したら`ImageJ-win64.exe`を起動します。

画像の通りに`Text Window`を開きます
![Fiji.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/ac1da936-33ac-36fa-0326-9f3d6819c84b.png)

Editorの言語設定をPythonにします。
![FijiLanguage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/9ec2f291-77f5-0d0b-cce6-59d17c41a007.png)

##コード

```python:バイオ系だけどプログラミング始めました　より拝借
import random
from ij import ImagePlus
from ij.process import ByteProcessor


def IntByteConverter(inputnumber):
    if inputnumber <= 127:
        return inputnumber

    else:
        return -(256 - inputnumber)


width = 100
height = 100
image_values = []
for i in range(width):
    for j in range(height):
        image_values += [IntByteConverter(random.randrange(0, 256, 1))]

bp = ByteProcessor(width, height, image_values)
imp = ImagePlus("Random", bp)

imp.show()

```

Runを押すと画像が生成されます。
あとは`Ctrl`+`S`で画像を保存すればOKです。
![CreateImage.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/5ee8e2b1-ee2a-0e0d-508c-dbbc8999df9e.png)

砂嵐のピクセル数を変更したい場合は下記の箇所の数値を変えれば可能です。

```python

width = 10
height = 10
```

![CreateImage10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/bd045f1a-762c-36e8-e2d8-f4209c238e97.png)

---
2019/11/30 追記

かなり短く書ける方法を教えて頂きました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ニッチなAPIを使った場合<br><br>from ij.gui import NewImage<br><br>imp = NewImage.createByteImage(&quot;noise&quot;, 100, 100, 1, NewImage.GRAY8 + NewImage.FILL_BLACK)<br>imp.getProcessor().noise(100)<a href="https://t.co/L64UBLB8BJ">https://t.co/L64UBLB8BJ</a>()</p>&mdash; Kota Miura (@kotapub) <a href="https://twitter.com/kotapub/status/1200412724095856640?ref_src=twsrc%5Etfw">November 29, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


```Python
from ij.gui import NewImage

imp = NewImage.createByteImage("noise", 10, 10, 1, NewImage.GRAY8 + NewImage.FILL_BLACK)
imp.getProcessor().noise(100)
imp.show()
```

##java.lang.IllegalArgumentException

保存したPythonファイルを指定して実行する際にこのエラーが出ました。
保存先のディレクトリ名にマルチバイト文字が含まれているとダメっぽいです。

##参考リンク

[ランダムな砂嵐画像を作る ImageJ + Python のプログラム](http://satoshithermophilus.hatenablog.com/entry/2017/06/26/232853)
GitHub Actionsでコードレビュー前にフォーマッタをかける

突然ですがJavaのコード、なにで書いてますか？

私見ですが、ショートカットキーが手に馴染んだIDEとそうでないIDEでは明らかに作業効率が変わる気がします。
「IDEが選べる」「PCが選べる」はエンジニア採用の現場でも売りとして扱われているようですし、実際選べない会社より選べる会社の方が嬉しい。
ただ、実際選べる環境に入ってみると、それはそれでこんな状況が起こりがち。

1. Eclipseで書かれたコードをIntelliJ愛用者が編集（逆もまたしかり）
2. 手癖でフォーマッタをかける
3. コードの差分が大変なことになる
4. レビューつらみ

フォーマッタはできれば統一したいところ。
一方で「ソースコードプッシュするときは、ビルドツールでフォーマットしてからにしましょう」とかルール化するのもそれはそれで面倒。
pre-commitのセッティングを各人にお願いしてもいいのですが、GitHub使ってるならそっちで勝手にやってくれれば楽なはず！

というわけで、設定してみました。
ビルドツールやフォーマッタはプロジェクトによって色々かとは思いますが、本記事ではGradle+Google Java Formatを扱います。

# 結論

1. google-java-format-gradle-pluginを導入  
https://github.com/sherter/google-java-format-gradle-plugin
2. GitHub Actionsのworkflowを設定  
https://github.com/tom-myz/shelffy/blob/master/.github/workflows/gradle.yml
3. アクセストークンを発行してリポジトリのシークレットに登録

これでフォーマッタバラバラでレビューしづらい問題とはおさらばできるかも！

# 気をつけるべきポイント

## 追加commitはコマンドで
実行結果をcommitする、みたいな機能は見つかりませんでした。
まじめにgitコマンドを書くほかなさそうです。

## gitの参照先がデフォルトブランチになる
トリガーが`pull_request`なのだからマージ元のブランチをローカルに複製して参照してくれてる
……なんてことはなく、ブランチのcheckoutを抜かすとHEADにコミットされます。
originは設定されているようです。

## continue-on-errorを設定したstepは終了コードに関わらずsuccessする
後続のstepに`if success()`をおいても意味が無くなります。
コマンドAが失敗した場合、コマンドBをスキップしてコマンドC以降を実行とかやりたい場合、

* コマンドA・コマンドBを同一ステップにおいてcontinue-on-error
* コマンドC以下は次のステップに配置

で実現するのがよさそうです。

## その他
何か思い出したら追記するかもしれません。しないかもしれません。

# イケてない点
* 歴史あるリポジトリだと適用した瞬間の差分が大変なことになる  
→ それ以前まで遡ろうとすると結局git blameしづらい問題
* ユーザー名とメールアドレスが具体的すぎる  
→ 実プロジェクトでやるなら専用ユーザー用意した方がいいとおもいます
* フォーマッタかけたあとのコミットにももう一度フォーマッタをかけようとする  
→ しかも結構時間がかかる。JDKのインストールからやってることもあり、内容Hello worldレベルでも1分半ほど
* コミット数が純増してログがきたない  
→ squashとかで行けそうな気もしつつ、Gitちからが足りなすぎてモチベーションがつづかなかった

# 感想
GitHub Actionsはよいものでしたが、肝心のGitの知識がなさすぎてやたらと時間かかりました。
仁義なきコスメティック・レビューから一人でも多くの開発者が解放されますように！

# 参考文献
https://help.github.com/ja/actions
http://nomadblacky.hatenablog.com/entry/2018/10/27/145451
Amazonlinux2にgoofys入れてS3をマウントした件

メ〇スは激怒した。普通にgoのインストールもyumでやってみたらバージョンが低いと怒られたのだ。

題名の通り。ちょっと工程往復する羽目になったので作業記録として遺しておく。

#下準備
git はgoofys入れるために fuseはgoofysと依存

    yum install git fuse -y

#実作業的な奴
goを入れる

    cd /usr/local/src/
    wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
    tar -C /usr/local -xzf /usr/local/src/go1.13.4.linux-amd64.tar.gz

~/.bash_profileに書く(めんどう

    export GOROOT=/usr/local/go
    export GOPATH=${HOME}/go
    export PATH=${PATH}:${GOROOT}/bin
    export PATH=${PATH}:${GOPATH}/bin

goofys入れる

    go get github.com/kahing/goofys
    go install github.com/kahing/goofys


#さあマウントしよう。ゴールはもうすぐそこだ。
今回はWPのDocumentRootとして使ってみたかったので、
権限とかゆるゆるで作ってみた。

    goofys -o nonempty -o allow_other --uid=[uid] --gid=[gid] --dir-mode=0775 --file-mode=0664 バケット名 マウントポイント

/etc/fstab に記述して再起動後も安心

    /root/go/bin/goofys#バケット名 マウントポイント fuse _netdev,allow_other,--dir-mode=0755,--file-mode=0664,--uid=[uid],--gid=[gid] 0 0

#達成されなかった目論見
ファイルのアップロードとか色々やったら一瞬で無料枠が持っていかれた。
多分ヘルスチェックで何回もアクセスされているのもあると思う。

結論としては世の人たちがやっているようにWPの静的な一部分だけをS3に落とし込んでやるのが一番よさそうである。
冗長化の際にはお気をつけて。
[playframework2.6]アプリケーション設定の読み込み方法 application.conf

playframework2.6系でアプリケーション設定(`application.conf`)の取得方法が変わりました。既存の`play.Configuration`がdeprecateになり、代わりに`com.typesafe.config.Config`が推奨されています。

```java
package play;

/**
 * The current application configuration.
 *
 * @deprecated As of release 2.6.0. Use {@link Config} instead.
 */
@Singleton
@Deprecated
public class Configuration {
```

また`play.Play.application().configuration()`で取得する方法はどのクラスからも静的メソッドからも利用できて便利なのですが「テストがしづらくなる」という理由でこちらも非推奨になったので他の方法を考える必要があります。

で、どうやって取得すればいいかですが、[公式の移行ガイド（英語）](https://www.playframework.com/documentation/2.7.x/JavaConfigMigration26)にはDI（@Inject）すればあっさり取得できるようなサンプルが記載されていますが、この記述では後述したケースでは設定を取得できません。(というか、サンプルコードはfinal指定しているのでコンパイルエラーになります。~~動くコードおいとけ！~~)

```java
import com.typesafe.config.Config;

public class Foo {
    private final Config config;

    @javax.inject.Inject
    public Foo(Config config) {
        this.config = config;
    }
}
```

**ダメな例**

- Controller以外のクラスで取得できない(PlayのDIはController以外ではちゃんと動作しない。たぶんGuiceのInjectの作法にしたがってbindとか自分で実装 ← 面倒すぎる)
- staticメソッドで取得できない（static変数にはInjectionできない）

対処方法を探して数時間。途中、(DIに関して)同じような痛みを抱えて悪戦苦闘した人の投稿も発見して共感したり。苦笑

[java - Play 2.5.3: Using dependency injection to get configuration values - Stack Overflow](https://stackoverflow.com/questions/36972305/play-2-5-3-using-dependency-injection-to-get-configuration-values)

で、結論。以下でどこからでも取得できますし、staticメソッドからも利用できます。~~移行ガイドに書いとけ！~~。

```
private static com.typesafe.config.Config _config = com.typesafe.config.ConfigFactory.load();
```

# 余談(というか愚痴)

[play framework](https://www.playframework.com/)の開発は続いています(最新は`2.7.3`で`2.8.0-RC`が進行中)が、競合の`Spring boot`と比べると勝負あったという感じですね。

初期の盛り上がりが持続しなかった原因は、ドキュメントが雑で、移行(バージョンアップ)に伴う痛みが大きすぎるからでしょうか。

マイナーバージョン変わっただけで、ガラッと作法を変えてくるのはなんだかなぁという感じでした。修正の手間に加えて、検索結果にも使えない情報が大量に紛れこむ原因にもなってました。(バージョン番号でなくコードネームで管理されていたら検索はしやすいのかも？) ただでさえJavaとScalaが混在して読み替えが必要だったりだし。

とはいえ、Playの上にがっつり作り込んでしまったのであと5年くらいは付き合うことになると思います。頑張ってほしいなー。

![GoogleTrend比較結果](https://i.gyazo.com/e432db10845110247122a96cf5d08d5b.png)
システムワイドにLinuxbrewを導入する例

rootではLinuxbrewをインストールできないが、かと言って個人ユーザーアカウントに紐づけたくはない。ということで、新たに`linuxbrew`というLinuxbrew管理用ユーザーを作り、`/home/linuxbrew`にLinuxbrewをインストールしてみる。

インストール:

```shell
# as root
useradd linuxbrew -s /sbin/nologin -c 'Linuxbrew'
chmod 755 /home/linuxbrew
su -s /bin/bash linuxbrew
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
brew list
```

パスワードを聞かれるが、3回間違えて進めばよい。

2回目以降:

```shell
# as root
su -s /bin/bash linuxbrew
eval $(~/.linuxbrew/bin/brew shellenv)
brew list
```

各ユーザーの設定:

```shell
# users: add the following line to .bashrc
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
```

本当に本当にシステムワイドでよいなら、`/etc/profile.d`以下に設定を置いてもよい。
カレーのカレーによるカレーのためのAtomic Design

## 始まりましたカレーアドベントカレンダーーーーーーーーー！
カレーが！！！好きかーーーーーーーーー！！！！！！！！！！！
今日から！25日かけて！！！！カレーを！！作るぞーーーーーーーーー！！！！！！
ちなみに一人暮らし9年目になりそうだけど、今まで1人でカレーを一度も作ったことないぞーーーーー！いけるんかこれーーーーーー！

ということで、お楽しみいただけたらいいなと思うんですけれども。

そんなこんなで、今日はカレーをAtomic Designに絡めて
記事にできたらなと思います🍛

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146512/dab4d4fc-8525-5662-71e8-2adb433663eb.png)


## Atomic Designとは
Webページを作るときのUI設計の考え方で、コンポーネント同士の組み合わせでページを作る考え方。
コンポーネントは以下の5つから構成されます。

* Atoms
* Molecules
* Organisms
* Templates
* Pages

とりあえずここでは「カレーは5つに分解できるぞ」と構えてください。

### Atoms（原子）

これ以上分けられないような単位のUIのことを指します。
カレーで例えるなら、原材料のことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146512/53a3ad68-18b8-e722-8fbb-e31a3a9a78f4.png)

* カレーで例えた場合
    * にんじん
    * じゃがいも
    * 肉
    * クミン
    * ターメリック
    * ローリエ
    * 水
    * 米粒

にんじんもこれ以上細分化できないですもんね。はい、そいつはAtomsです。

### Molecules（分子）
atomsを2つ以上組み合わせたもの。つまり、カレーで言うと、具材「達」です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146512/b3cd9b4e-e71a-99be-67da-e87e02e2d219.png)


* カレーで例えた場合
    * 炒めた野菜と肉（にんじん + じゃがいも + 肉）
    * カレースパイス（クミン + ターメリック + パプリカ + レッドチリ + コリアンダー）
    * 米粒の集合体（米 + 米 + 米）

ん〜〜〜〜美味しい匂いがしてきた。

### Organisms（有機体）
複数のMoleculesを組み合わせたもの。上記の炒めた具材と米をヴウウウンってがっちゃんこしたもんです。

* カレーで例えた場合
    * カレールー（カレースパイス + 水 + 炒めた野菜と肉）
    * 皿にのってない宙に浮いたカレーライス（米 + カレールー）

### Templates
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146512/67c7cb2f-814e-5e13-ff17-4851a17d9cb7.png)


Organismを組み合わせ、ページの枠組みを構成します。

......おっと。カレーに例えると、有機体（カレールーと米）を組み合わせて...？無理じゃない...？
じゃあここではカレーの枠組みを構成するもの（=どこに何を入れるかの定義されたもの）と捉えましょう。
つまりダムカレーの盛り付け方ですね！！！そうですよね！！！！！！！！！

* ダムカレーで例えると
    * 各地域のダムごとのお皿に以下を定義
        * カレールーはお皿の左側に200gの分量
        * ご飯はお皿の右側に250gの分量
        * 福神漬けはお皿の手前に100gの分量
        * 実体はない。（カレーで再現できなかった）

### Pages
Templateに具体的なコンテンツを入れ込んだのが、最終的なアウトプットとなるPagesです。
つまり、ダムカレーの皿に入ったカレーライス！これがまさに！Pages！

いただきまーーーーーーーーーす！！！！！！！！！！！！！


## おわりに
結論、カレーで例えてみたけど
カレーは実体だし、Atomic DesignはUI設計での考え方なので、
Atomic Designはカレーで完全には例えられない！！！！！！！