OmniAICreator/Qiita-1.07M huggingface dataset:
DialogflowでQuick Respliesを利用する(LINE bot)

# はじめに
この記事はDialogflowでLINEBotに対してQuick Respliesを使用する手順を記したものです。  
Dialogflowでのagentを作成、LINEとの連携今回説明しません。以下を参考にして作ってみてください。  
>[Dialogflowと連携してLINE Botを作る](https://qiita.com/poruruba/items/09563e251adef1e1e8af)  
>[DialogflwoでLINE BOTを作ってみました](https://9bo.hateblo.jp/entry/2018/03/21/152450)  

# 目標
今回はLINEBotに対して"リンゴとバナナ"を送ると、どちらが好きかQuick Respliesで尋ねてくるIntentの作成を目標としました。
#手順
### 1. Intent作成  
![linebot-create-agent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/7b2eea17-6902-5231-de20-8750aa5e7197.png)
Intentを作成。今回はどちらが好きかを聞いてくるため"like"と名前を付けました。  

### 2. Entityの設定
![linebot-var.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/9501a150-66f3-9daa-21ac-27caeacafd7a.png)
各対象にanyとEntityを設定。

### 3. Quick Respliesの設定

![linebot-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/153a923d-8505-21c7-6ad0-410f80396f52.png)  
1. ResponseでLINEを選択(このときLINEBotにしか利用しないIntentならばしたのDefoult設定をチェックしておくといい)  
2. "ADD RESPONSE"をクリック

![linebot-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/af9157ac-5d9d-9beb-4065-7d2699a739a4.png)
3. "ADD RESPONSE"をクリック後に出てくる選択肢よりQuick Respliesを選択  

![linebot-save.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/3c30bda3-0eba-652a-445b-954b3422d880.png)
4. 選択後に出てくる入力欄に以下の2点を入力する
    - Quick Respliesのtitle
    - 選択肢
5. 最後に変更を保存するため上の"SAVE"をクリックして完了

#　動作画面
以下のように出ていれば成功です.  
![line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/aba91064-154f-6492-252f-aeab34819d19.png)
CSSが反映されない

###CSSが反映されなかった時の対処法

私が初めてwebサイトを作った時にあれっ？てなった事です。
ググっても意外と初歩的すぎて中々出てこなかったのでメモしておきます。


背景色を以下のようにしたかったのですが...

```css:style.css
body {
    background-color: aquamarine;
} 
```

実際は背景が真っ白のままでした。

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

検証ツールを確認すると自分で設定したはずの記述が打ち消されていました。

競合しているのはbootstrapのbodyタグです。
こいつに打ち勝つ必要があります。


####対処法１　bodyにクラスをつける

```php
<body class="hoge">
```

```css
body.hoge {
    background-color: aquamarine;
} 
```

すると、body.hogeの方が優先度が上がります。
[![Image from Gyazo](https://i.gyazo.com/18c26e6462dadcc85af5f5b4e6393cee.png)](https://gyazo.com/18c26e6462dadcc85af5f5b4e6393cee)

bootstrapに勝てました。
でもたくさんあるファイルのbodyにクラスをちまちまつけるのは面倒です。

####対処法2 Bootstrapを先にロードしておく

後出しジャンケン的なイメージです。
先にbootstrapを、後にstyle.css(今回反映させたいファイル)をロードしました。後にロードしたファイルが優先的に反映されました。

```php
<script type="text/javascript" src="./../vendor/twbs/bootstrap/dist/js/jquery-3.5.0.js"></script>
<script type="text/javascript" src="./../vendor/twbs/bootstrap/dist/js/bootstrap.js"></script>
<link rel="stylesheet" href="./../vendor/twbs/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="./../stylesheet/style.css">
```
対処法１よりシンプルです。

###対処法３　!importantをつける
上記でできなかったらこの方法です。

```css
body {
    background-color: aquamarine !important;
} 
```
この方法でもbootstrapに勝てました。

以上が、cssの記述が反映されなかった時に試したことでした。

何かご指摘あればコメントよろしくお願いします。
Swift: Menu Bar ScrollView作成（UIStackView, UIScrollView, SnapKit->AutoLayout)

# SnapKit -> AutoLayout

Youtube: https://youtu.be/5ikZ6yC8cV4
<img width="967" alt="Screen Shot 2020-05-11 at 21.24.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166098/3cd35e76-7958-2726-8637-429f4b79bfbc.png">
poetry で環境ごとにインストールするパッケージを切り替える

Poetry で python の環境を管理していて、学習用サーバーと推論用のサーバーで異なるパッケージを入れたくなったのでメモ。

### 背景

基本的には全部 dependencies に突っ込んでしまえば良いと思っていたんだけど、この世の中には install だけでメモリを数GB必要とする強力かつ凶悪なパッケージたちがいるらしいので、貧弱なインフラではインストールすらできねぇ...ということが問題になった。

（一時的に）インフラ強くしろよ、というのは妥当に聞こえるが、この先数ヶ月、ないし数年に渡ってインストールが終わったあとに確実にインスタンスサイズを変える自信があるかい？僕にはない。だから工夫した。

### 本題

poetry には `optional` と `extras` という概念がある。
それぞれ `add`、`install`サブコマンドのオプションである。

結論から書くと、以下の手順でうまく行った：


#### 1. 依存パッケージ追加時

```bash
$ poetry add --optional SOME_STRONG_PACKAGE
```

#### 2. 任意のエディタで pyproject.toml に extrasパッケージを追加

```
$ vi pyproject.toml

# ↓追加
[tool.poetry.extras]
train = ["torch", "torchtext"]
↑ グループ名   ↑ インストールするパッケージのリスト（dependencies の方で optionalになっていることを確認）
```

#### 3. インストール（extrasが不要な場合）
```
$ poetry install
```

#### 3'. インストール（extrasが必要な場合）
```
$ poetry install -E train
```

## 詰まったところ

すでに poetryで管理されているプロジェクトで上記の方法を試したら、以下のエラーが出た：

```
[ValueError]        
Extra [train] is not specified.  
```

その後、 `poetry.lock` を消して再度上の `poetry install -E train` を試したら、うまく行った。

明らかにエラーメッセージが親切でない
 PRチャンス。
Google Chromeでアドレスバーからフォーカスをはずすショートカット

# なやみ

- Mac版Google Chromeでは`Command + L`を押下するとアドレスバーにフォーカスするデフォルトのショートカットがある
- が、いったんフォーカスすると入力待ち状態になったまま抜け出せない…！`Esc`も効かない…。
- これは特にVimiumユーザにとって深刻な問題で、`j`や`k`で上下移動をしたり、Vomnivarを出したりしようとしてキーを押すとアドレスバーへの入力として認識され`jjjjjjjj`みたいになる

[![Image from Gyazo](https://i.gyazo.com/107322839881688beaab0536df350692.gif)](https://gyazo.com/107322839881688beaab0536df350692)

# 解決策

- 色々調べて行き着いたのは結局Vimiumのイシューで、[同様のなやみに対するハック](https://github.com/philc/vimium/issues/840#issuecomment-17948885)がとても良かったので紹介
- 要するに「Google ChromeのSearch Engineで空のJavaScriptを実行するキーワードを設定しておく」
  - Google Chromeの設定ページ→`Manage Search Engine`（`chrome://settings/searchEngines`）へ行く
  - `Other Search Engine`から`Add`で新規作成、任意のタイトルとショートカットとなるキーワード（`unfocus`の頭文字でここでは`u`）とURLの代わりの`javascript::`を入力・保存
  - [![Image from Gyazo](https://i.gyazo.com/2e642639f539fbafb0b46c9ea35fbed5.png)](https://gyazo.com/2e642639f539fbafb0b46c9ea35fbed5)

- これでアドレスバーにフォーカスが当たっている状態で`u`→`Enter`を押下すると`javascript::`というスクリプトが実行される
  - そしてフォーカスがページの内容に戻り、無事Vimiumのキーバインドが使える
  - しかも`tab`でフォーカスを外したときのように、ページ内の何らかの要素にフォーカスするという副作用が起きない

[![Image from Gyazo](https://i.gyazo.com/e83ec1089b6146c85136ef5b11486ac1.gif)](https://gyazo.com/e83ec1089b6146c85136ef5b11486ac1)

ベンリ！！！
Ruby on Rails チュートリアル 第４章①

○この記事の要点
「第4章　Rails風味のRuby」の途中まで実施内容メモ
思ったことなどのメモ

○第4章でやること
・3章で作成したプログラムを元に、Rils／Rubyの仕組みを学習
（ヘルパー、文字列とメソッド、オブジェクト、配列と範囲演算子、ハッシュ、クラス）

○内容
■ヘルパー

説明
・組み込みヘルパー：Railsの組み込み関数。自身で作成しなくても用意されている
例．app/views/layouts/application.html.erb　で利用した
<%= stylesheet_link_tag …>
・カスタムヘルパー：自身で作成した関数
例．app/views/static_pages/home.html.erb　で利用した
<% provide(:title, "Home") %>

作業
（１）カスタムヘルパーの作成
full_titleヘルパーは、ページごとのタイトルを返す。
タイトルが指定されなかった場合⇒Ruby on Rails Tutorial Sample Appとなるようにする
（ | Ruby on Rails Tutorial Sample App　とならないようにする）

```ruby:app/helpers/application_helper.rb
module ApplicationHelper

  # ページごとの完全なタイトルを返します。
  def full_title(page_title = '')
    base_title = "Ruby on Rails Tutorial Sample App"
    if page_title.empty?
      base_title
    else
      page_title + " | " + base_title
    end
  end
end
```

自動で実行するテストはこの時点では成功。
Homeのタイトルも「Home | Ruby on Rails Tutorial Sample App」になっている。

（２）app/views/static_pages/home.html.erb　の先頭行<% provide(:title, "Home") %>を削除。文字列が与えられないようにしてみる。

```ruby:app/views/static_pages/home.html.erb
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
```
自動で実行するテストはこの時点でエラーになる。
Homeのタイトルが「Ruby on Rails Tutorial Sample App」になるが、テストは
「Home | Ruby on Rails Tutorial Sample App」が表示される想定になっている。
↓タイトルが想定している値と異なる。という内容。予想通り

```ruby:テストエラー
11:46:12 - INFO - Running: test/controllers/static_pages_controller_test.rb
Running via Spring preloader in process 5247
/home/ubuntu/environment/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /home/ubuntu/environment/sample_app/config/application.rb to limit the frameworks that will be loaded.
Started with run options --seed 49053

 FAIL["test_should_get_home", StaticPagesControllerTest, 0.27212137900005473]
 test_should_get_home#StaticPagesControllerTest (0.27s)
        <Home | Ruby on Rails Tutorial Sample App> expected but was
        <Ruby on Rails Tutorial Sample App>..
        Expected 0 to be >= 1.
        test/controllers/static_pages_controller_test.rb:17:in `block in <class:StaticPagesControllerTest>'

  5/5: [================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.29195s
5 tests, 9 assertions, 1 failures, 0 errors, 0 skips

```

app/views/static_pages/home.html.erb　を元に戻す。

```ruby:app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
```

テストのエラーがなくなる。

■感想
・ヘルパー⇒Viewで利用するメソッド的なもの。のはず。コントローラ、モデルではメソッドと言っているので。理解が違ったらご指摘ください。
・ゴールデンウィークが終わってしまったので、取り組む時間がなかったので少しだけしかできなかった。。。
httptestを試してみた

goの勉強続き。
testをやってみる

なんとか動いてCoverage 75%になったけど、100%にならないのはなんでなんだろ。
httptestでやるのはなかなか手応えがあったので、
単純な数値計算関数などに戻って、試してみようとおもう。

```http2.go
package main

import (
	"io"
	"net/http"
	"strconv"
	"strings"
)

// ResponseWriter is interface as
//	Header()  Header
//  Write([]byte)(int,error)
//  iWriteHeder(statuscoe int)

// WriteString is function as
// func WriteString(w Writer, s string) (n int, err error)

// Writer is interface as
// Write(p []byte) (n int, err error)

func ServeHoge(w http.ResponseWriter, req *http.Request) {
	agent := req.Header.Get("user-agent")
	check := strings.Contains(agent, "537")
	check_string := strconv.FormatBool(check)

	if check {
		io.WriteString(w, agent+"\n537 is error\n"+check_string+"\n")
	}
	io.WriteString(w, "Welcome! this is hoge server\n" + agent+"\n")
}

// testの方法はたぶん、
// requestを作ってuse-agentをセットしてなげる
// それを受けて、結果が書き込まれるのもの（Recorder?）を
// うまく記録して、
// その結果のBodyをチェックするのかな。

//参考：https://qiita.com/umisama/items/3d44560e1c06fa531069

func main() {
	http.HandleFunc("/hoge", ServeHoge)

	http.ListenAndServe(":12345", nil)
}

````

```http2_test.go
package main

import (
	"net/http"
	"net/http/httptest"
	"testing"
	"strings"
	"io/ioutil"
)

func TestCheckAgent(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(ServeHoge))
	defer ts.Close()

	_, err := http.Get(ts.URL)

	var request1 *http.Request

	request1, err = http.NewRequest("GET", ts.URL, nil)

	request1.Header.Add("user-agent","537")

	c := http.DefaultClient
	reply, err := c.Do(request1)

	if err != nil {
		t.Error("unexpected")
		return
	}

	data, err := ioutil.ReadAll(reply.Body)
	if err != nil {
		t.Fatalf("Error:%v",err)
	}
	if reply.StatusCode == 200 && ! strings.Contains(string(data), "537") {
		t.Fatalf("agent is not included 537 in Body:%v",string(data))
 	}

	request1.Header.Add("user-agent","532")
	c = http.DefaultClient
	reply, err = c.Do(request1)
	data, err = ioutil.ReadAll(reply.Body)
	if reply.StatusCode == 200 && ! strings.Contains(string(data), "Welcome") {
		t.Fatalf("agent is not included Welcome in Body:%v",string(data))
 	}



}
```

テスト結果

```
(base) http2 $ go test -v -cover
=== RUN   TestCheckAgent
--- PASS: TestCheckAgent (0.00s)
PASS
coverage: 75.0% of statements
ok  	http2	0.330s
(base) http2 $ 

```
AWS AmplifyのチュートリアルでReactアプリでCognitoを使って認証機能を追加する

いつも忘れないように、コンセプトから。

###コンセプト
・お金かけてまでやりたくないのでほぼ無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ

前々回の[「AWSサーバーレスのWebアプリケーションをもっと勉強する」](https://qiita.com/auf/items/f3a84ae3bbf0a3b5cbec)と前回の[「AWSサーバーレスのWebアプリケーションをもっと勉強する（その２）」](https://qiita.com/auf/items/3cd250f353d3687c28bc)の続きになります。
今回のチュートリアルはこちら↓
https://docs.amplify.aws/start/getting-started/auth/q/integration/react#create-login-ui

###認証機能を追加する

まずはAmplifyに認証機能を追加します。追加はAmplifyコマンドで行います。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/8726c289-34f3-bc09-9bfa-904302864e26.png)

実行するとこんな感じです。ローカルに取り込まれました。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/3c66913f-5d70-2fcd-5d40-015fecdec25a.png)

AmplifyのpushコマンドでAWS上の環境構築を行います。しばらく待っていると、以下のような画面で終わります。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/90acd693-1f66-c26a-db55-0d186efb5ff4.png)

AWSコンソールに飛んで確認すると、うまくいっているようです。特にエラーはありません。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/083b84f4-4de2-c571-b881-e009d9bb67e9.png)

###認証画面を作成する

今度は画面の作成です。作成といっても、チュートリアルとして用意されているログイン用の画面を利用します。App.jsに以下の2文を追加します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/a7562431-9fbb-118e-8372-38c0c75e299e.png)

その後、npmコマンドでスタアートすると、ローカルで起動します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/fb34f592-b17e-ad05-68aa-4dd16d29937e.png)

###動作確認する

実際に起動させたアドレスにアクセスすると、ログイン画面が出来上がっています。アカウントは持っていないのでCreate accountを押してアカウントを作成します。本人確認のためにメールアドレスを設定すると、メールに認証キーが送られてくるので入れることでアカウントがアクティベートされます。この辺は一般的なWebの認証と同じですね。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/3245e508-904c-2860-05a9-182e4dc08977.png)

認証を通してログインすると、以前構築したサイトにアクセスできます。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/5958103e-06aa-5e30-1e0e-8833466d9009.png)

認証の機能を構築するのは非常に難しいですが、Cognitoを使って簡単に構築することができました。Cognitoって本当に便利ですね。Webアプリケーションを構築するなら絶対に使うだろうなと思うサービスです。ちなみにAmplifyで使えるメソッドは30あり、チュートリアルにも記載されていますが、signUp, signIn, forgotPasword, signOut　などの基本的なものは揃っています。詳細は以下参照。
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html

実際に自分のサイトとして構築するには画面などを変更する必要もありますが、かなり利用できるソースコードも多いなと思います。今日はここまで。
【簡潔】Git上にコミットしたくないものを設定する方法~画像~

###概要

この記事ではGit上にコミットしたくないファイルやフォルダを指定する方法を学べます。
<br>
<br>


###方法


・画像をGitにコミットしない場合

`.gitignore`に以下を追記↓

```作成中のapp/.gitignore
public/uploads/*
```

以上で完了です。



この記事を読んでいただきありがとうございました。
ROSでRAMユーザを作り、ポリシーを割り当てたい

寺尾です。

ROSは、Alibaba Cloudで構築の自動化を行うプロダクト、RAMは、AWSのIAMと同じで認証と認可を行うプロダクトです。

ROSでRAMユーザーを作って、ポリシーを割り当てたいんですが、案外サンプルが少なくて、ユーザまでは作れるのですが、ポリシーの割り宛てに苦労しました。

ようやくできたので、何方かの助けになればと思い、残しておきます。

1つ残念なのはシステムポリシーをそのまま割り当てることは出来ず、カスタムポリシーのみということです。システムポリシーと同一内容のカスタムポリシーを割り当てれば、とりあえずやりたいことは可能です。

結果だけ知りたい方はサンプル記述例までジャンプしてください。

# ROSでRAMユーザーを作るSyntax

[RAM User 作成のドキュメント](https://www.alibabacloud.com/help/doc-detail/48371.htm) はこちらにあります。

ユーザ作成の書式はこんな感じです。

```
RAMユーザ作成Syntax (JSON)
{
  "Type": "ALIYUN::RAM::User",
  "Properties": {
    "UserName": String,
    "DisplayName": String,
    "Groups": List,
    "LoginProfile": Map,
    "Policies": List,
    "MobilePhone": String
  }
}
```

だいたい理解できるのですが、 `Policies` だけが難解でした。

やりたかったこととしては、 `AliyunECSFullAccess` や、 `AliyunOSSFullAccess` などといったプリセットされたシステムポリシーを割り当てたかったのですが、残念ながらそれが出来ないようです（たぶん）。

ですので、システムポリシーと同じ内容でカスタムポリシーを書くことになるようです。

```
ポリシーのSyntax (JSON）
"Policies": [
  {
    "PolicyName": String,
    "PolicyDocument": Map,
    "Description": String
  }
]
```

ポリシーには、Map形式のPolicyDocumentがありますが、中身が分かりません。探してみると[ALIYUN::RAM::ManagedPolicyのページ](https://jp.alibabacloud.com/help/doc-detail/48365.htm)にありました。

```
"PolicyDocument" : {
    "Version": String,
    "Statement" : [
        {
            "Effect" : String,
            "Action" : List,
            "Resource" : List
        }
    ]
}
```

RAMポリシーを定義するときに書かないと行けないやつと同じみたいです。では、システムポリシーの内容はどこで分かるんでしょうか？

【RAM】【権限管理】【ポリシー】に移動して、該当のシステムポリシーを検索します。 `AliyunOSSFullAccess` の場合はこのようになります。

![OSSFullAccess](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/06ada574-8c20-d0ff-14eb-3d441395112f.png)

必要なのは、 `Statement` の中の部分です。ここをコピーすれば良いようです。しかし、コピーしただけではエラーが出るケースがありました。

`PolicyDocument` のSyntaxを見てみると、`Action`と`Resource`は`List`で定義されているので、要素が1つでも配列で囲います。

ここまでそろえばだいたいかけるかと思います。

## サンプル記述例 (YAML)

普段からYAMLでROSテンプレートを書いているので、例示もYAMLで書きます。必要な人はJSONに変換してください。

パスワードだけは入力するようにしておきました。
これで、`AliyunECSFullAccess`と、`AliyunOSSFullAccess`相当のポリシーを割り当てるユーザーが自動で作れます。

```
サンプル記述例 (YAML)
Parameters:
  RamUserPassword:
    Type: String
    NoEcho: true
    Description: RAM User Password

Resources:
  RamAdminUser:
    Type: 'ALIYUN::RAM::User'
    Properties:
      UserName:    user1byROS
      DisplayName: user1byROS
      LoginProfile:
        PasswordResetRequired: false
        Password: Ref: RamUserPassword
        MFABindRequired: false
      Policies:
        - PolicyName: AliyunECSFullAccess_custom
          PolicyDocument:
            Version: '1'
            Statement:
              - Action: ["ecs:*"]
                Resource: ['*']
                Effect: Allow
              - Action: ["vpc:DescribeVpcs","vpc:DescribeVSwitches"]
                Resource: ['*']
                Effect: Allow
          Description: note
        - PolicyName: AliyunOSSFullAccess_custum
          PolicyDocument:
            Version: '1'
            Statement:
              - Action: ['oss:*']
                Resource: ['*']
                Effect: Allow
          Description: custom

```

# 感想

もう少し簡単にシステムポリシーを割り当てる方法がある様な気がするのですが、探して見つかればまた報告します。

（2020年5月12日追記：サポートに連絡したら方法が無いと。。。とりあえずリクエストを上げておきました。）
【MySQL】データベースの操作コマンド

# mysqlへ接続
SQL文を実行するため、データベースへ接続します。

```
mysql -u root
```
**mysqlに「root」というユーザー名で接続するという意味になります。**

# SHOW DATABASES文

データベースを一覧で表示させるSQL文です。

```
SHOW DATABASES;
```
**「; セミコロン」はSQL文の終わりを意味し、ない場合は**
**以下の様に入力待ちになります。**

```
mysql> SHOW DATABASES
    ->
```
こうなった時は「;」のみ入力し「Enter」を押すと正常に実行されます。


# CREATE DATABASE文 
CREATE DATABASE文を実行すると、指定した名前のデータベースが作成されます。


```
CREATE DATABASE データベース名;
```
# USE文
データベースを選択するSQL文です。
実行すると指定したデータベースが選択状態になります。

```
USE データベース名;
```

__________
ご覧いただきありがとうございました。
HTMLとCSSのレイアウト『ベース』

# 初投稿は聖杯レイアウトの作成です。


一番最初は、何回かに分けて、
HTML，CSS，JavaScriptを使った、
ホームページをデザインしていきたいと思います。



今回については
『しまぶーのIT大学』さんの動画を参考にレイアウトを作成します。


## 聖杯レイアウトとは

上方にヘッダー、下方にフッター、中部左右にナビゲーションを配置して真ん中にコンテンツを置く、20世紀後半に主流だった典型的な段組のことだそうです。

昔は作るのが難しいとされていたそうですが、
『Flex Box』をつかい簡単に作成できるようになりました。



##完成したソースコード

こちらが動画を見て完成したソースコードです。


```html:index.html

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link href="./style.css" rel="stylesheet" />
<title>sample</title>

</head>

<body>
   <header>header</header>
   
   <div>
      <nav>left</nav>
      <main>center</main>
      <aside>right</aside>
   
   </div>
   
   
   <footer>fotter</footer>
   
</body>
</html>


```

```css:style.css


body {
    margin: 0 auto;
    width: 800px;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    
    }


header{
    height: 150;
    }
    
    
div {
    display: flex;
    flex: 1;
    
    }
    
    
main {
    flex: 1;
    }
    
nav {
    width: 150px;
    }
    
aside{
    width: 200px;
    }
    
footer {
    height: 200;
    }
    
@media screen and (max-width:900px) {
    
body, nav, aside{
     width: 100%;
    }
    
div {
    flex-direction: column;
}



```


##学習の際に気をつけた点

当たり前なのですが、動画を見て書いただけでは学習にならないので、
どこのコードがどこに適用されるかを実験しながら書きました。
コピペは基本的にしちゃダメです！
TypeScript  async 

````app.ts
import A from "./new";

interface User {
    name:String,
    id:number,
    role:String
}

class MyUser implements User {
    constructor(name:String,
    id: number,
    role: String){
      this.name = name;
      this.id = id;
      this.role = role;
    }
    name: String;
    id: number;
    role: String;
}

let tick = new Date().getTime();

var getSpan = () => {
 return  new Date().getTime() - tick;
}

console.log("start "+ getSpan());


function getUser() {
    return  new Promise<User>((resolve, reject) => {
        setTimeout(()=>{
            console.log("get the user "+ getSpan());
            resolve(new MyUser(A,1,"admin"));
        },2000);
    });

}
    
async function  display() {
    let user =  await getUser();
    console.log(user.name + " " + getSpan())
}

display();

console.log("end " + getSpan());
````

````new.ts
const A:String = "aa";
export default A;
````

https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
MVC

#イメージ

<img width="910" alt="スクリーンショット 2020-05-11 20.37.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533191/6bd80866-a331-a255-37d4-c29f17556e56.png">

#意味

モデル/ビュー/コントローラーの頭文字をとってまとめたキーワード。

Railsを初めとしたwebアプリケーションシステムの処理の流れの総称

大まかな処理の流れは上のイメージを参考にして下さい
BeagleBone Greenを動かそう

stay homeなこの頃、以前「これでぼくもめいかーだ」と意気込んで買ったBeagleBone Greenを倉庫の奥から引っ張り出して、久しぶりに動かしてみようかなと思った人（そんな人は私だけかもしれませんが）が、最初の一歩で躓かないように。

# アップデート！アップデート！アップデート！
大事なことなので、3回繰り返しました。

BeagleBone GreenをUSBで接続すると、USBドライブが見えますよね。その中にSTART.htmとかREADME.htmとかあるので、それに従えば良いんでしょ。とか、同梱されている説明書があるから、それを読めば良いんでしょ、とか、考えては*いけません*。普通はそれで正解ですが、どちらの説明も時代遅れのものになっている可能性があります。オープンソースハードウェア上に構築されたオープンソースソフトウェアですから、変化の勢いはすごいです。（少なくとも私の手元にあったBeagleBone Greenでは、どちらも説明が古くて引っ掛かりました。）

アップデートのやり方は、さすがQiita、Qiita内に記事がありますので、ここはリンクを張らせてもらいます。→[BeagleBoneGreenを動かす02](https://qiita.com/pata128/items/0969204eb071670ce398)

# さもないと
（多少は（普通の）技術者の役に立つ記事でも書こうかとアップデートの仕方を書こうとしたら、すでにあるのを見つけてしまったので、こちらの方向に逃げているというのは内緒）

説明書では次に"Install drivers"とかあるので、それに従ってドライバをインストールしようとするとインストールできません。少なくとも私の手元のWindows10ではできませんでした。（以前はできた記憶があるのですが、その時は時期からWindows7だったのだと思います。）ここで、「ドライバのインストーラーに何か問題があるのかな」とそちらの方向に走ると、はまります。ネットで検索すれば全く同じ現象に悩んでいるらしい人が見つかることは見つかるのですが、エラー画面のメッセージはスペイン語だかフランス語だか、、、、、

ここで挫けてしまうと、BeagleBone Greenはまた倉庫の奥へ、、、

# だから
アップデートです。（はい、アップデートの仕方は[こちら](https://qiita.com/pata128/items/0969204eb071670ce398)（再掲））アップデートすれば「USBで接続すると、USBドライブが見えますよね。その中にSTART.htmとかREADME.htmとかあるのでそれに従えば良いんでしょ。」というのは、その通りです。
![readme.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535021/76e88937-9d0a-ad63-8a2c-ee34f670160d.png)
試しにREADME.htmを開くと、こんな感じで、そもそも*最初に*"Update board with latest software"（ボードを最新のソフトウェアでアップデートする）とか書かれているんです。
>This step may or may not be necessary, depending on how old a software image you already have, but executing this, the longest, step will ensure the rest will go as smooth as possible. 
(意訳: ボードが新しければ、アップデートしなくてもいいかもしれないけど、アップデートしておけば、ここから先の説明で躓かないよ！)

stay homeが（特に私の住んでいる自治体では）まだ続きそうですが、皆さん、楽しい（？）メイカーライフを。

# [おまけ] 呪い（？）のmicroSDカード
[BeagleBoneGreenを動かす02](https://qiita.com/pata128/items/0969204eb071670ce398)に従って作成したmicroSDカードですが、ブートの流れを直接書き換えてしまいますので、アップデート以外には使えなくなります。（microSDカードから起動すると、必ず書き込みが始まってしまう。）[BeagleBone Blackを動かそう](https://qiita.com/koizumistr/items/5dd82027b7a2b1d0aa6e)のように他のBeagleBone Green/Blackをアップデートするには便利ですが、普通はアップデートは一度やれば十分でしょうから、いわば「呪い」のmicroSDカードの出来上がりです。（まあ、消して違う内容を書き込めば何も問題はないのですが。）
（あ、これ、[BeagleBoneGreenを動かす02](https://qiita.com/pata128/items/0969204eb071670ce398)の悪口を言っているわけではないです。[BeagleBoneGreenを動かす02](https://qiita.com/pata128/items/0969204eb071670ce398)に書いてあるのはBeagleBone Green/Blackをアップデートする標準的な手順ですので、残念ながら（？）必ず呪い（？）のmicroSDカードができてしまいます。）
typescript environment 

````
npm i -g typescript
````
then you can use `tsc` command to compile `ts` files to `js` files.

````
D:\workspace\type-test>tsc app.ts -w
[19:47:56] Starting compilation in watch mode...
````
````
tsc --init
message TS6071: Successfully created a tsconfig.json file.
````
````tsconfig.json
{
  "compilerOptions": {
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
     "outDir": "./dist",                        /* Redirect output structure to the directory. */
     "rootDir": "./src",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
     "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    /* Advanced Options */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
}
````

````
npm init -y
Wrote to D:\workspace\type-test\package.json:

{
  "name": "type-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
````
````
npm i -D typescript ts-node nodemon @types/node
````
then use nodes api like

````
import * as http from 'http';
````

````nodemon.json
{
    "watch": ["src"],
    "ext": ".ts,.js",
    "ignore": [],
    "exec": "ts-node ./src/app.ts"
}
````

````
npx nodemon
````
when changes happened in src fold, `ts-node ./src/app.ts` will be executed.


##ESlint


install vscode extension ESlint

````
npm install -g -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin 
````
Inside VS Code use: Ctrl+Shift+P or Shift+Cmd+P
Preferences: Open Settings (JSON)

````setting.json
{
  "eslint.validate": ["typescript"]
}
````
create `.eslintrc.json`

````.eslintrc.json
{
    "parser": "@typescript-eslint/parser",
    "plugins": ["@typescript-eslint"],
    "rules": {
      "semi": ["error", "never"],
      "quotes": [2, "single"]
    },
    "parserOptions": {
      "ecmaVersion": 6,
      "sourceType": "module",
      "ecmaFeatures": {
        "modules": true
      }
    }
  
  }
  
````
````
eslint
````

that's all. cool!
よく使うヘルパ関数まとめ

##ヘルパ関数とは
ヘルパ関数とは、PHPとは別でLaravelが用意している便利な関数たちです:blush:

##よく使うヘルパ関数
####1. dd()
PHPでいうvar dump()。
指定された変数の内容を表示し、スクリプトの実行を停止する。

```php
dd($value);
```

####2. auth()
ログイン情報の取得、チェックなどを行う。

- ログインユーザー情報取得

```php
$login_user = auth()->user();
```

- ログインチェック

```php
if(auth()->check()) {
   //ログインしました
}
```

####3. env()
.envの中に書かれている文字列(環境変数)を取得する。

**例）**.envに```DB_CONNECTION=mysql```と書かれている場合

```php
$env = env('DB_CONNECTION');
dd($env);
//出力：'mysql'
```

####4. config()
env()と似ていますが、configディレクトリ配下の値を取得できます

**例）**config/app.phpの```'timezone' => 'Asia/Tokyo'```を取得したい場合

```php
$config = config('app.timezone');
dd($config);
//出力：'Asia/Tokyo'
```

####5. route()
view側でURLを指定するときに使う

```php
<form method="POST" action="{{ route('contact.store') }}">
  @csrf
  氏名 
  <input type="text" name="your_name">
  <br>
  件名
  <input type="text" name="title">
</form>
```

####6. view()
Controller側で特定のViewを表示させたいときに使う。

```php
public function create()
{
    return view('contact.create');
}
```

####7. collect()
配列をコレクションに変換してくれる。

**例)**以下の配列で、idが３のnameを取り出したい場合

```php
$members = [
    [
        'id' => 1,
        'name' => 'hanako'
    ],
    [
        'id' => 2,
        'name' => 'taro'
    ],
    [
        'id' => 3,
        'name' => 'anna'
    ],
];

$member = collect($members)->firstWhere('id', 3);
dd($member); 
//出力：'anna'
```

####8. array_get()
配列の中からデータを取得するときに使う。

**例）**以下の配列から「京都」を取得したい場合

```php
$prefectures = [
    'japan' => [
        'kanto' => [
            'tokyo' => '東京'
        ],
        'kansai' => [
            'kyoto' => '京都'
        ]
    ]
];
$pref = array_get($prefectures, 'japan.kansai.kyoto'); 
dd($pref);
//出力：'京都'
```
【JavaScript】クラスの継承

#【JavaScript】クラスの継承（子クラスの作り方）

親クラスをベースにした子クラスを作ることで、親クラスが持つ処理を子クラスに継承することができる。
継承することで、親クラスと子クラスの共通処理をsuperで短くまとめることができる。

##子クラスの作り方

クラスを作る際に次のようにextendsで記述する。

    class 子クラス名 extends 親クラス

プロパティやメソッドの継承にはsuper();を追加する


##例文

テキストを表示するShowMessage クラスを拡張するため、ShowMessageExtends 子クラスを作る場合

親クラスの内容

```js
    class ShowMessage {　//親クラス
        constructor(text) {
        this.text = text;
        }

        show() {
        console.log(`${this.text}`);
        }
    }
```

子クラスの内容

```js
    class ShowMessageExtends extends ShowMessage {　//子クラス： class 子クラス名 extends 親クラス
        constructor(text, extendsText) {
        super(text);//super()で親クラスのプロパティを継承
        //this.text = text;　プロパティが継承
        this.extendsText = extendsText;　//子クラスShowMessageExtendsの独自処理（プロパティ）だけを書けばよい
        }

        show() {
        super.show();//super()で親クラスのメソッドを継承
        //console.log(`${this.text}`);メソッドが継承
        console.log(`and more ... ${this.extendsText}`);//子クラスShowMessageExtendsの独自処理（メソッド）だけを書けばよい
        }
    }
```

テキストの設定、出力処理

```js
    const showMessages = [
        new ShowMessage('JavaScriptの勉強中'),
        new ShowMessage('Qiitaに投稿'),
        new ShowMessageExtends('Extend comments','written by kuro.'),//子クラスの処理
    ];

    showMessages[0].show();
    showMessages[1].show();
    showMessages[2].show();
```

実行結果

```text
    JavaScriptの勉強中
    Qiitaに投稿
    Extend comments
    and more ... written by kuro.
```

実際に書いて、デベロッパーツールでの出力を確認しておりますが、誤りがありましたら、ご指摘頂けますと幸いです。
Firebase Local Emulator Suiteにネットワーク越しでアクセスする

# 結論
`firebase.json`に

```json
"emulators": {
  "functions": {
    "host": "0.0.0.0"
  },
  "firestore": {
    "host": "0.0.0.0"
  },
  "database": {
    "host": "0.0.0.0"
  },
  "hosting": {
    "host": "0.0.0.0"
  }
}
```

を追加しましょう。

# 経緯
Firebaseによる開発を加速するために[Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite)を導入しました。Firebaseのローカルでの開発環境を整えるうえで最大の課題はFirestoreのエミュレーションをどうするかですが、Firebase Local Emulator Suiteではうまくやれそうです。

HostingやCloud Functionsも当然のことながらエミュレートするのですが、当方の開発環境は仮想マシン上に構築しているため、ネットワーク越しのアクセスとなります。ところが、

```shell
firebase emulators:start --help
```

としてみても

```
Usage: firebase emulators:start [options]

start the local Firebase emulators

Options:
  --only <emulators>          only specific emulators. This is a comma separated list of emulator names. Valid
                              options are: ["functions","firestore","database","hosting","pubsub"]
  --inspect-functions [port]  emulate Cloud Functions in debug mode with the node inspector on the given port
                              (9229 if not specified)
  --import [dir]              import emulator data from a previous export (see emulators:export)
  -h, --help                  output usage information
```

となっておりホストの設定オプションがない。こちらの[Stack Overflowの記事](https://stackoverflow.com/questions/58260877/access-firebase-emulator-from-local-network)に助けられました・・・。

その後かろうじて[ソースコード内にドキュメントらしきもの](https://github.com/firebase/firebase-tools/commit/3ac9c0f04de7fdaa18670ef3b99ce7594c0b5dc5#diff-82a6f9bb5a6dec53f59ec6e735ba3727R90-R101)を発見しました。めでたしめでたし（？）
scikit-learnのtree.plot_treeがとても簡単・便利だったので簡単に使い方をまとめてみた

Pythonで実装された機械学習ライブラリの[scikit-learn](https://scikit-learn.org/stable/modules/tree.html#tree)は様々なアルゴリズムを簡単に試せることからしばしば利用されています。花形と言えばTensorFlowやPyTorchですが、お堅い現場ではなかなか使えません。。。そんなscikit-learnで教師有り学習の代表的な手法「決定木」を学習後に描画時に便利な関数がVersion0.21.xから実装されたので従来のGraphVizを用いる方法と比較しつつ試してみました。

# 従来の可視化方法: GraphVizを利用
従来はGraphVizという別のライブラリをインストールして、利用していました。結構手間が掛かります。。。

```bash:GraphVizのインストール@Mac
brew install graphviz
pip install graphviz
```

```bash:GraphVizのインストール@Ubuntu
sudo apt install -y graphviz
pip install graphviz
```

```python:GraphVizを用いた方法
import graphviz
from sklearn import tree
from sklearn.datasets import load_iris

iris = load_iris()
clf = DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)

graph = graphviz.Source(tree.export_graphviz(clf, class_names=iris.feature_names, filled=True))
graph
```
## 実行結果
実行結果は`graph.render('decision_tree')`を実行するとPDFとして保存できます。

![graphviz](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/32327c63-bcdb-faf8-03b4-f58890e0f483.png)

# tree.plot_treeを利用
`tree.plot_tree`を用いてGraphVizを利用して描画した物と同様の図を描画してみます。scikit-learnのtreeモジュールに格納されている為、追加のインストールは不要です。(`filled`オプションはデフォルトではFalseですが、Trueにすると彩色されます)

```python:tree.plot_treeを用いた方法
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree

iris = load_iris()
clf = DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)
iris = load_iris()
plt.figure(figsize=(15, 10))
plot_tree(clf, feature_names=iris.feature_names, filled=True)
plt.show()
```

## 実行結果
GraphVizを用いた方法と同じ図を出力出来ました。Jupyter Notebook上で実行すれば、描画結果をそのまま右クリックして画像として保存も出来ます。

![plot_tree](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/0b7c7447-683b-eeb9-129b-33024cc360a2.png)

## 2020/11/27追記: クラス名も決定木に表示
`class_name`オプションを追加すると最終的に分類されたクラス名も表示出来ます。

```python
plt.figure(figsize=(15, 10))
plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names, filled=True)
plt.show()
```

![plot_tree2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/3e87a8d7-ef01-8042-15de-6fa761dd987a.png)

# まとめ
scikit-learnのtree.plot_treeと従来のGraphVizを用いる方法を決定木の可視化に対して行い、tree.plot_treeが(従来の方法より)簡単かつ便利だと実感しました。今後積極的に活用していきたいと思います。

# Reference
* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html#tree)
* [sklearn.tree.tree_plot](https://scikit-learn.org/stable/modules/generated/sklearn.tree.plot_tree.html)
EXCEL：選択中のセル範囲で散布図を作成するマクロ

選択データの散布図を作成するマクロのメモ書きです。

    Option Explicit
    
    Sub MakeGraph()
        
        Const CHART_WIDTH As Long = 300
        Const CHART_HEIGHT As Long = 300
        
        Dim myShapes As Shapes
        Set myShapes = ActiveSheet.Shapes
        
        Dim myChart As Shape
        Set myChart = myShapes.AddChart(xlXYScatterLinesNoMarkers)
        
        With myChart
            .Chart.Legend.IncludeInLayout = False
            .Chart.Legend.Position = xlLegendPositionCorner
            .Width = CHART_WIDTH
            .Height = CHART_HEIGHT
            .Line.Visible = msoFalse
        End With
        
    End Sub
Valve Indexをしばらく使ってみた

しばらくValve Indexを使ってたのですが、
ネガティブよりな感想を書いてみます。

というのも、昔はハイエンドVRHMDならValve Index一択！と思ってたのですが、
半年ほど使って、どうもそうではないぞ、という記事になります。

#HMD

これに関しては言うことないです。
個人的には画質というより密度(スクリーンドア)を重要視するので、
黒網が殆ど見えないRGBストライプの液晶は好印象です。

FPSも120でるので、体感でも画面のスムーズさを感じます。
PCの性能は要求されます。
VRChatでは鏡をだすと大体のワールドで60FPSに低下します。

FPSを高めに設定しているせいか、
他のデバイスと比べて画面がフリーズしやすいイメージはあります。
主にアプリの起動時や読み込み時など、明らかに負荷がかかっている時、
画面が止まってしまいます。
ただ、一時的なもので、大体は問題ありません。

とはいえ、HMDに関しては正直、ViveProなどでも同等のスペックだと思います。

#コントローラ

Indexといえばコントローラです。
5本指を認識するコントローラとして、発売前から話題になっていました。

指が独立して認識するのは、一長一短です。
VRChatだと、ピースサインが作れません。
人差し指と中指がつながったポーズになってしまいます。

あと、規定のハンドサイン以外で欲しいハンドサインがないんですね。
中指とか小指を立てるぐらいかなぁ…。
あんまり多用したいハンドサインではないですね。

操作性では、IndexコントローラだとOculus Touchに準じた操作になるアプリがあります。
しかし、Oculus Touchと比較して中指トリガーはありませんから、
中指が握り込まれているかで判断します。
これが、自分が押したつもりではないのに押されているという扱いになります。

例を出すと、SteamHome。
中指で握って上下に振ってスクロールできます。
この時、スクロール中は人差し指トリガーが無効になります。

Indexで操作する時、中指を伸ばした状態で反応しないように
人差し指トリガーを引く必要があります。
これが非常にやりにくいです。

そして劣化。
買って半年ほど、使用時間で言えば、200時間程度でしょうか。
もうすでに左スティックは使い物にならないレベルで劣化しています。

具体的には上を押して離すとニュートラルに戻りません。
下も調子悪いですが、左右に関しては問題ありません。
多用する上下方向に劣化が出ているあたり、

この症状は多くの人で聞かれていて、私だけではないようです。
Oculusのユーザーなどではあんまり聞かれないので、
Indexが特別壊れやすいのは個人差ではないと思います。
SSH接続できるDockerコンテナを作る

AWS Fargate を Bastion として SSH Tunnel とかやりたかったんだけど、当然の事ながら Docker コンテナを SSH できるようにする必要がありました。

## Dockerfile

```dockerfile
FROM ubuntu:18.04

RUN apt-get update && apt-get install -y openssh-server

RUN mkdir /var/run/sshd

ARG ROOT_PASSWORD
RUN echo root:${ROOT_PASSWORD} | chpasswd

RUN sed -i 's/#\?PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]
```

## コンテナ立ち上げ

```sh
# build docker image.
docker build --build-arg ROOT_PASSWORD=password -t ssh_container .

# run docker container
docker run -itd --rm -p 2222:22 --name ssh_container ssh_container
```

## SSH接続

```sh
ssh root@localhost -p 2222
password: password
```

## SSH鍵認証したい場合

#### 鍵作る

```sh
ssh-keygen -f id_rsa

ls
id_rsa id_rsa.pub
```

#### コンテナに公開鍵を突っ込む

上で紹介した Dockerfile の `EXPOSE 22` の上辺りに下記を追加してください。パスワードは消しちゃいます。

```dockerfile

# 省略...

# ARG ROOT_PASSWORD
# RUN echo root:${ROOT_PASSWORD} | chpasswd

# 省略...

COPY id_rsa.pub /root/authorized_keys

RUN mkdir ~/.ssh && \
    mv ~/authorized_keys ~/.ssh/authorized_keys && \
    chmod 0600 ~/.ssh/authorized_keys

EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]
```

#### 接続

同様に build してから SSH の際に秘密鍵を指定するのみです。

```sh
ssh root@localhost -i id_rsa
```

# 参考

- [Dockerize an SSH service](https://docs.docker.com/engine/examples/running_ssh_service/)
- [Dockerのubuntu:18.04でSSHサーバーを立てるDockerfile](https://scrapbox.io/nwtgck/Docker%E3%81%AEubuntu:18.04%E3%81%A7SSH%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E7%AB%8B%E3%81%A6%E3%82%8BDockerfile)
- [公開鍵でコンテナにssh接続する出来るようにするDockerfileの例](https://qiita.com/YumaInaura/items/7509061e4b27e03ea538)
Kaggle の CSV ファイルの一部を切り出す

Kaggle COVID19 Global Forecasting (Week 5)　の入力ファイルは非常に大きくエディター で開くことができません。そこで、サブセットを作成してみました。
日本と韓国を含む５つの地域のデータを切り出します。
元データは Alphabet 順なので、Japan から Korea までを抽出します。

```sh:pickup_csv.sh
FOLDER="../../input/covid19-global-forecasting-week-5"
#
NN=152
MM=$(($NN+5))
echo $NN,$MM
echo
echo $((104*2*$NN + 2)),$((104*2*$MM + 1))
echo $((45*$NN*2 + 2)),$((45*$MM*2 + 1))
echo $((45*$NN*6 + 2)),$((45*$MM*6 + 1))
#
head -n 1  $FOLDER/train.csv > train.csv
head -n 1  $FOLDER/test.csv > test.csv
head -n 1  $FOLDER/submission.csv > submission.csv
#
awk -v start=$((104*2*$NN + 2)) -v end=$((104*2*$MM + 1))  'FNR==start,FNR==end'
 $FOLDER/train.csv >> train.csv
awk -v start=$((45*2*$NN + 2)) -v end=$((45*2*$MM + 1))  'FNR==start,FNR==end' $
FOLDER/test.csv >> test.csv
awk -v start=$((45*6*$NN + 2)) -v end=$((45*6*$MM + 1))  'FNR==start,FNR==end' $
FOLDER/submission.csv >> submission.csv
```

入力

```bash
$ wc *.csv
  935011   935011 12445187 submission.csv
  311671   382861 24396108 test.csv
  720305   884833 59473149 train.csv
```

出力

```text
$ wc *.csv
  1351   1351  17132 submission.csv
   451    541  31488 test.csv
  1041   1249  77167 train.csv
```
UnityCloudBuildでDev/Stg/Prodの実行環境を切り替えてビルドする

# 概要

Dev/Stg/Prod で実行環境を分けている Unity プロジェクトで、git ブランチごとに実行環境を切り替えてクラウドビルドしたかったが、参考になりそうな記事が見つからなかったのでメモしておく。

[Services - Cloud Build - Unity](https://unity3d.com/jp/unity/features/cloud-build)

# 環境

- Unity 2018.4.22f1

# 環境を分ける意味

Unity プロジェクトが外部サーバーと通信する際に、開発/検証/本番で API サーバ等のエンドポイントを切り替えることで開発を安全かつ迅速に行うことが出来るようになる。詳細はすでに多くの記事で解説されているので下記の記事等を参照。

[ステージング環境とは？開発環境、検証環境との違いと役割 | WWWクリエイターズ](http://www-creators.com/archives/780)

弊社では API サーバと Firebase のエンドポイント切替が対象で、下記のように手動で環境を切り替えていた。

```csharp
// 実行環境の列挙
public enum EnvironmentType
{
   Dev, // 開発環境
   Stg, // 検証環境
   Prod // 本番環境
}

// 実行環境の定義
public static class Environment
{
    // TODO: これをビルドのたびに手動で切り替える
    public static readonly EnvironmentType Type = EnvironmentType.Dev;
}

// APIのエンドポイント取得箇所(別クラス)
public static string Url()
{
    switch (Enviroment.Type)
    {
        case EnviromentType.Dev:
            return DevUrl;
        case EnviromentType.Stg:
            return StgUrl;
        case EnviromentType.Prod:
            return ProdUrl;
        default:
            Debug.Log("実行環境が未設定です");
            return "";
    }
}
```

この場合、ローカルで各種環境をビルドする際は問題にならないが、Unity CloudBuild を利用した場合は少し面倒になる。CloudBuild 用のブランチで毎回実行環境を変更してコミットしなければならないからだ。

可能であれば CloudBuild の設定から自動で切り替えが出来ればと思って調べていたが、有用な記事に出会えなかった。(CloudBuild の環境変数はビルド時にしか参照出来ないので、実行時に環境を切り替えるのには向かなかった)

しかし、Unity のドキュメントを見ていると下記の記事を見つけた。

[カスタムスクリプト #define ディレクティブ - Unity マニュアル](https://docs.unity3d.com/ja/2018.4/Manual/UnityCloudBuildCustomScriptingDefineDirectives.html)

環境ごとの `#define` を予め CloudBuild のコンフィグに設定しておけば環境ごとの切り替えが出来そう？と思って最小プロジェクトで検証したところ無事に成功したので、この方針で実行環境切り替えを行うことにした。

# CloudBuildで環境切り替え

Dev のビルドはローカルで行うので、今回は Stg と Prod 環境のみ作成。
下記のカスタム定義を CloudBuild -> Config -> Advanced Options からそれぞれ設定した。

- `#define ENV_STG`
- `#define ENV_PROD`

実際に作成した TARGET は下記の通り。PROD は production ブランチを参照し、STG は staging ブランチを参照している。(左が PROD, 右が STG)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44388/389c100f-8e2b-0549-963b-67b245c10817.png)


環境自動切り替え用のコードは下記の通り。

```csharp
public enum EnvironmentType
{
   Dev, // 開発環境
   Stg, // 検証環境
   Prod // 本番環境
}

public static class Environment
{
#if ENV_STG        
    public static readonly EnvironmentType Type = EnvironmentType.Stg;
#elif ENV_PROD
    public static readonly EnvironmentType Type = EnvironmentType.Prod;
#else
    public static readonly EnvironmentType Type = EnvironmentType.Dev;
#endif
}
```

あとは STG と PROD でそれぞれ CloudBuild を走らせるだけ。
CloudBuild はローカルビルドより時間が掛かるので、Slack に通知を飛ばすと便利。

[Unity Cloud Buildのビルド結果をSlackに通知するには - Qiita](https://qiita.com/murapong/items/b0ae10cbb6be7d5b4cd4)

ちなみに CloudBuild は Addressables にも対応しているのでとても良い。

[Addressables1.8.3のアセットをUnityCloudBuildでビルドする - Qiita](https://qiita.com/yakimeron/items/821e101307e69c8eddaf)

# まとめ

リリースのたびに毎回手元で全環境ビルドしていたのでリリースコストがかなり高く検証にも物凄く手間が掛かっていたが、本記事の対応でサポートしている全てのプラットフォームのSTG/PRODビルドがまとめて行えるようになったので、リリースのサイクルは大幅に改善出来るのではないかと思う。

同じように、API サーバ等の外部サービスを環境ごとに切り替える Unity プロジェクトを開発している人の力になれればと思う。(特に Unity CloudBuild の記事はあまり数が多くないので)
Embedded Frameworkを導入した際にipa生成が失敗した話

## 結論
* Embedded Frameworkの`Build Phases`から`Embed Frameworks`を削除する

## 経緯
* iOS Project内で依存関係を強制するために、Embedded Frameworkを以下のように作成し、AppはDomainとDataを参照でき、DomainはDataのみ参照できるように構成
    * App (本体)
    * Domain (Embedded Framework)
    * Data (Embedded Framework)

* scheme周りも諸事情で弄っていたので、いつもfastlaneでbuildしているところ、まずは手動で`.ipa`ファイルを作成できるか確認しようとした

## 結果
**IPA proccessing failed**
<img width="1112" alt="スクリーンショット 2020-05-11 18.27.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154832/e1a2dbce-d2af-e6bf-7a7a-b8c03d6a7948.png">

`Show Logs`から原因を確認していくことに…achiveの時間で該当するフォルダを見つけ出し

<img width="1122" alt="スクリーンショット 2020-05-11 18.28.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154832/2122b6c5-d080-da28-624d-8c0a53fcfbc0.png">

`IDEDistribution.standard.log`を開く

<img width="1222" alt="スクリーンショット 2020-05-11 18.29.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154832/eea7822a-1c34-ab18-dbf6-5a9cea0b61d7.png">

ログが大量にある中、ログの密度の濃いところと薄いところの境界あたりで怪しい部分を発見。

```
Failed to resolve rpath for Data: Could not resolve @executable_path for @executable_path/Frameworks from Data
```

どうもDataモジュールのpathが解決できないらしい。
過去Embedded Frameworkを使ってたProjectを参考に、Embedded Frameworkの`Embed Frameworks`(下記画像赤点線枠)が不要ぽいので消してリトライ。

<img width="724" alt="スクリーンショット 2020-05-11 18.16.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154832/0aca1471-e8da-9319-6cc5-12368055a917.png">

## Success!!
無事ipaが作成でき、対応完了！
文系SEが考えるサーバとは

最近『オーバシュート』やら『クラスター』、『リモートワーク』に『アベノマスク』と横文字が氾濫しています。

IT業界も例に漏れず多くの横文字が氾濫していますが、果たして自分は各々の定義を明確に説明できるのか、という疑問を持ちました。

今回は、自分用のメモを残す意味でアウトプットします。

#お約束
以下の注意書きをよく読み、用法用量を守って正しくお使いくださいmm

* 文系SEが新入社員やIT業界初心者向けに執筆した記事です。
* 記載されている情報が必ずしも正しいとは限らないので、必ず自分でも調べ直してください。
* 日本生まれ日本育ちですが、日本語が怪しい箇所が多々あります。見つけた場合は、優しくご指摘いただければ幸いです。

#サーバってなに？
そもそも『サーバ』ってなにというお話が今回の主題です。

『サーバ』と聞いて、『コンピュータ』、『パソコン』などを想像する人もいれば、
『Webサーバ』、『APIサーバ』、最近だと『仮想サーバ』などを想像する人もいるかと思います。

では、まず辞書で『サーバ』の意味を引いてみましょう。

>サーバとは、コンピュータネットワークにおいて、他のコンピュータに対し、自身の持っている機能やサービス、データなどを提供するコンピュータのこと。また、そのような機能を持ったソフトウェア。
出典：IT用語辞典　http://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%83%90.html

書いてあることが難しすぎて、意味がわかりませんでした….orz

こういう時は、イメージで理解するといいとお婆ちゃんが言っていた気がします！

##コンピュータとサーバの関係
<img width="842" alt="スクリーンショット 2020-05-11 17.18.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635116/edd44192-2e65-729e-ab3c-88e366b1734f.png">
上記のイメージの通り、スマホやニュースなどで見かけるスパコン(スーパーコンピュータ)の『京』などもコンピュータの一種です。

##サーバとは…
上記を踏まえることで以下のように定義することができます。

**サーバはコンピュータ(の一種)であるが、(全ての)コンピュータはサーバではない**

もっと突っ込むと、サーバは辞書の内容を引用するのであれば、他のコンピュータのためのコンピュータといったところでしょうか。

は？と思われる方もいるかと思います。

具体例で表すために、スマホでamazonのページを開いてみてください。

表示されたページは、スマホが提供しているわけではなく、amazonのサーバが提供している情報をスマホが表示しているだけです。
（スマホの中にはamazonのページはありません。スマホからamazonのサーバに依頼することでページの情報を送ってもらっています。）

『Webサーバ』、『APIサーバ』などは、そのサーバが何を提供するか明示的にわかりやすくするための名称というわけです。

#おまけ
以下、サーバと切っても切れない『ハード(ウェア)』と『ソフト(ウェア)』についても紹介します。

#ハードウエアとソフトウェアってなに？
『サーバ』のお話をするとよく耳にするのが、『ハード(ウェア)』と『ソフト(ウェア)』という言葉です。

ゲーム好きの方ならイメージしやすいかと思いますが、『スーファミ』や『64』、『Play Station』の本体が『ハード』です。

『マリオRPG』『大乱闘スマッシュブラザーズ』『バイオハザード』など各タイトルが『ソフト』です。
『ハード』は実行場所(環境)、『ソフト』は実行内容とでも言えばイメージしやすいでしょうか。

##コンピュータとソフトウェアとハードウェアの関係
<img width="842" alt="スクリーンショット 2020-05-11 18.00.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635116/f693c50d-cc0e-00de-855e-f107387a1cdc.png">

上記のイメージの通り、実体を持っているものかどうかで『ハード(ウェア)』と『ソフト(ウェア)』は定義できます。

また、コンピュータの種類毎に『ハード(ウェア)』や『ソフト(ウェア)』に必要な要素は異なります。

サーバは基本的に画面描写することがないのでディスプレイや外部入力装置のキーボードなどは不要です。
逆にパソコンなどには処理に必要なプログラム言語やDBなどは不要で、表計算などのソフトが欲しくなります。

『ソフト(ウェア)』は大きく『システムソフトウェア』と『アプリケーションソフトウェア』に分けることができます。

『システムソフトウェア』は『ハード(ウェア)』の管理や制御を担当するソフトウェアを指します。
代表的なものだと『OS』などが挙げられます。

『アプリケーションソフトウェア』はワープロや表計算を行なうといった目的に応じて
コンピューターのプログラムを応用(アプリケーション)したソフトウェアを指します。
代表的なものだと表計算やメディアプレイヤーなどが挙げられます。

##OSってなに？

>OSとは、ソフトウェアの種類の一つで、機器の基本的な管理や制御のための機能や、多くのソフトウェアが共通して利用する基本的な機能などを実装した、システム全体を管理するソフトウェア。
出典：IT用語辞典　http://e-words.jp/w/OS.html

サーバの説明よりは分かりやすくて安心しましたw

OSはソフトウェアの中核を担うソフトウェアという認識で問題ないかと思います。
重要なのはコンピュータの種類毎に適したOSがあるということです。
<img width="843" alt="スクリーンショット 2020-05-11 19.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635116/85381dc4-75c6-e579-a5e6-4fbb8c52aa78.png">

#まとめ

* 『コンピュータ』とは『計算処理を実施する機械』のことを指します。
* 『コンピュータ』にはいくつか種類があり、代表的なものに『パソコン』や『サーバ』、『スマホ』などがあります。
* 『コンピュータ』は『ハードウェア』と『ソフトウェア』で構成されています。
* 『ハードウェア』は物理的に存在するもの、『ソフトウェア』は実体が存在しないものを指します。
* 『ソフトウェア』は『システムソフトウェア』と『アプリケーションソフトウェア』に分けることができます。
* 『OS』は『ソフトウェア』の一種で、『ソフトウェア』の中核を担います。

#最後に

『サーバ』の話じゃなくて『コンピュータ』の話になってないか、この記事……..
nullにLIKE句を使うとnullになる

# 発端

業務でSQL文を組む機会が時々あるのだが、ある時「抽出するユーザーのメールアドレスから自社内のものを除く」という条件を含むSQL文を書くことになり、取り急ぎ書いたのであった。抽出すべきユーザーのメールアドレスは(ユーザーアカウントがあればレコードが生成されていると見なして良い)二つのテーブルにあったため、簡単に書くと次のような文になった。

```sql
SELECT user_main.mailaddress, user_additional.mailaddress
FROM user_main
JOIN user_additional
ON user_main.id = user_additional.userid
WHERE user_main.mailaddress NOT LIKE '%@mycorporation.%'
AND user_additional.mailaddress NOT LIKE '%@mycorporation.%';
```

しかしSQL文をレビューしてもらう最中、「user_additional.mailaddressが`NULL`の時があって、その時は`user_main`にレコードがあっても抽出されない」と指摘を受け、実際にそうらしかったので、コードを修正することになった。

```sql
-- ... WHERE user_main.mailaddress NOT LIKE '%@mycorporation.%'
AND (
     user_additional.mailaddress IS NULL
  OR user_additional.mailaddress NOT LIKE '%@mycorporation.%'
);
```

# 調べてみた

後になって実際にはどのような処理の影響でこうなっていたのかが気になったので、以下のようなSQL文を実行してみた。

```sql
SELECT ('a' LIKE '%'); -- true
SELECT ('a' NOT LIKE '%'); -- false
SELECT (NULL LIKE '%'); -- null
SELECT (NULL NOT LIKE '%'); -- null
```

以上のように、`null`に対して`LIKE`句を使うと必ず`null`になることが分かった。なので、最初のコードのようにこれらを`AND`で連結している文では、`NULL`がレコードに入っていると抽出対象から外れてしまう。
Microsoft Teams でチームにメンバーを一括登録する

# 参考

* [Adding bulk users from a .csv file to a Microsoft Teams team](https://medium.com/@joaquin.guerrero/adding-bulk-users-from-a-csv-file-to-a-microsoft-teams-team-374414b9d8c9)
* [Add-TeamUser](https://docs.microsoft.com/en-us/powershell/module/teams/add-teamuser?view=teams-ps)

# 方法

PowerShell で [Microsoft Teams の cmdlet](https://docs.microsoft.com/en-us/powershell/module/teams/?view=teams-ps) から操作して追加します。

# 注意

以下の手順で私の環境では動いていますが、 `Set-ExecutionPolicy` はセキュリティ上あまりよろしくない操作かもしれません。識者の意見求む

# 手順

## 1. PowerShell ISE を管理者権限で起動

* 検索バーで powershell と入力 → PowerShell ISEを右クリック、管理者実行
* 普通の PowerShell でなく __PowerShell ISE__ でないと権限のエラーが出た気がします。


## 2. Teams に接続

```powershell:
Install-Module -Name MicrosoftTeams
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Connect-MicrosoftTeams
```

→ MS のダイアログが現れるのでサインイン

## 3. チームのID を調べる

Teams アプリで、対象チームのURLを「リンクの取得」で調べる。

```
https://teams.microsoft.com/l/team/…/conversations?groupId=b70145bc-f04b-44a6-9192-8816f3cab935&tenantId=テナントID
```

のようになっているので、groupId を抜き出す。


Azure Active Directory Admin Center
https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/AllGroups 

にサインインし、チーム名を検索して調べる。ID は b70145bc-f04b-44a6-9192-8816f3cab935 のような文字列。

## 4. 追加するアカウントのメールアドレス一覧のCSVファイルを作る

CSV ファイルといっても1列しかないファイル。次のステップのワンライナーで Teams に流し込む。

|email|
----
|foo@example.com|
|bar@example.com|
|baz@example.com|
|...|

最初の行は email, 次の行からは改行区切りでメールアドレスを並べる

## 5. 上記の PowerShell ISE で以下を実行する

```powershell
Import-Csv -Path "CSVファイルのフルパス" | foreach{ Write-Output $_.email; Add-TeamUser -GroupId グループのID -user $_.email; Write-Output "Done"; Start-Sleep 10 }
```

グループのID は上で調べたグループIDの文字列 (`"b70145bc-f04b-44a6-9192-8816f3cab935"` 等)。

このワンライナーは `Add-TeamUser` でチームにメンバーを1人ずつ追加する。概ね即時反映されるようだ。
追加のたびに10秒ウェイトを入れている。

私の環境ではウェイトがないと追加に失敗する(*)ことがあったので入れている。もっと短くても良いかもしれない。


(*) 具体的には、ADのグループには反映されるが Teams には反映されないメンバーができてしまった（この状態で半日ほど待ってみたが改善せず、上記 Admin Center で削除して再実行しなければならなかった）。
バッチ開発初心者が躓きやすいと感じたところ

#1.変数の定義
下記のように書くと空白も認識されて変数に代入されてしまう。
（他の言語に慣れているとついやってしまう）

```
set value = hoge
```

下記のように記述するのが正解です。

```
set value=hoge
```

#2.if文、for文でのエラー
if文、for文で条件式とカッコの間に
スペースを入れないと、エラーとなる。

```
if [条件文](
 [処理]
)
rem コマンドの構文が誤っています
```

```
if [条件文] (
 [処理]
)
rem 処理が実行される
```

#3.forループの中で変数が置き換わらない

遅延環境変数の展開というものがあるらしい。
ざっくり対処法を述べると下記をバッチの上部に記載する。

```
setlocal enabledelayedexpansion
```

バッチ内では普通、変数の呼び出しにパーセント記号「%」を用いるが
代わりに「!」を用いる。

```
!value!
```