OmniAICreator/Qiita-1.07M huggingface dataset:
YouTrack でプロジェクトのルートページをゲストアクセスできるようにする

# 背景

プロジェクトのルートページは
https://09v.myjetbrains.com/youtrack/projects/b88d7f30-eefd-4fed-9a15-4bd8c34f3f5d
のような URL で表現されるようです。
(短い URL でなくて残念)

ただ、 [YouTrack でだれでもプロジェクトにアクセスできるようにする](https://qiita.com/09v/items/2f3abb791ba430e0c5a1) で設定した **Issue Reader** ロールのデフォルト権限では、

* 課題１つ１つは閲覧できる
* プロジェクトルートページは閲覧できない

ということが確認できました。

これだと、GitHub リポジトリの URL などで「Issue はこちらを見てください」と案内しにくいです。

# プロジェクトルートページをゲストアクセスできるようにする

ナットメニューの **ACCESS MANAGEMENT** > **Roles** から、 **Issue Reader** を選択し、 **Read Project Full** にチェックを入れたところ、ゲストアクセス時でもルートページにアクセスすることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603093/74b579d3-9139-98be-f405-1cb68f4ecd77.png)
docker-compose up が失敗する、止まる、固まるときの理由を調べるには docker-compose --verbose up

docker-compose コマンドに限らず、世の中の多くのコマンドで --verbose は冗長に語るオプションとして、多くのログを標準出力してくれる。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3060








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[Unity]uUGUIで可変長リストの中に可変長リストを作る

こういうやつを作ります。

![list.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/c2a23600-90af-0a3b-258d-ca4e6fd21274.gif)

## 普通の可変長リストを作る

まずはネストしていない普通の可変長リストを作ります。
始めに親にしたいオブジェクトにVerticalLayoutGroupなどのLayoutGroupを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/c6faf701-a56f-a84d-58e8-2062cbd53bbf.png)

この時点で子にオブジェクトを追加すると整列して配置されるようになりますが親のサイズは固定のままです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/db0bb963-566f-0533-295f-323da5bda632.png)

配置する要素のサイズに合わせて親要素のサイズを変更したい場合は**Content Size Fitter**を使用します。
Content Size Fitterを使用すると要素の高さ、幅を**Preferred HeightまたはPreferred Width**のサイズに変更することができます。

Preferred Widthについては公式のドキュメントに`付加的に使用可能な幅が割り当てられる前に、この Layout 要素で優先される幅。`のように記載があります。
分かりづらいですが色々やってみて慣れましょう。
要素の現在のPreferred Width/Heightはインスペクタから確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/e5ca6089-8829-d676-3a5c-53629c746e68.png)

Content Size Fitter をつけてHorizontal FitとVertical Fitを`Preferred Size`に設定すると子要素のサイズに応じて親要素のサイズが変わるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/7c995e4f-6816-0138-4673-90ca4277dd04.png)

## ネストした可変長リストを作る

次は本題のネストした可変長リストを作ります。
普通に可変長リストの中に可変長リストを入れると以下のような警告がでます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/cba68e2a-ff4a-16f8-ddb5-9d1cb512f403.png)

書いてある通りですがこれは親要素にLayoutGroupのコンポーネントが存在する場合、子要素にContent Size Fitterを使用するべきではないというものです。

これを回避するためには親のLayoutGroupコンポーネントの**Control Child Size**にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/1801a1c2-503d-d4a7-6a90-8928e0851e62.png)

このパラメータにチェックを入れると子要素のすべての要素にContent Size Fitterを付けたときとほぼ同じ動きをします。

これで大体完成ですが一点注意することがあります。
それは固定長の要素の高さがつぶれてしまうことがある、というものです。
下の画像を見てください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/0d576546-22dd-a6c4-8e54-e8afaa0775a2.png)

Listの最初の子要素であるButtonがつぶれて細長くなってしまっています。
これはButtonのPreferred Heightが10しかないため高さが10になってしまっているためです。
Preferred Heightを任意の値にするためには**Layout Element**コンポーネントを使用します。
Layout ElementのPreferred Heightにチェックを入れることで好きな値を設定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/8b70af64-266d-257e-5ee5-79b5ea20614e.png)

これで完成です。

## 最後に

知ってれば簡単なことですが知らないと苦労するので記事にしました。
uGUIは意外と色々できて便利です。
LINE WORKS で簡単に Bot を使えるようになる Power Automate カスタムコネクタ

## LINE WORKS の Message Bot API 用のカスタム コネクタの導入

https://github.com/iwaohig/LINEWORKSMessageBot の LINEWORKSMessageBot.json をダウンロードする。

Microsoft PowerAutomate の [カスタム コネクタ] にアクセスし、[+ カスタム コネクタの新規作成] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/b60a0fef-72d7-752e-5222-97376a7382c4.png)

[OpenAPI ファイルをインポートします] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/39aa38a6-c8d5-9b52-8d85-655c6a514afa.png)
 
任意のコネクタ名を入力し、ダウンロードしたファイルを選択。[続行]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/a0032d07-f073-1734-8cbd-5b1774b3a2b8.png)

必要に応じて、任意のコネクタ アイコンと背景色を指定。[コネクタの作成] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/6358d4ec-a191-a480-7948-e362c9c9e43a.png)

カスタム コネクタとして登録されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/f8778769-2b6a-12da-6c6c-ac2b7e3a9d85.png)

[接続] メニューで [+新しい接続] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/6543f44b-28d4-8f73-5889-5cb1018f7e19.png)

追加したカスタム コネクタを検索して [+] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/3a92bd49-a451-766d-1a49-788257792e89.png)

[API キー] に "Bearer [Server Token]" を入力。[作成] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/0c83c264-4bb6-8e95-d073-76bc57e52792.png)

## カスタム コネクタをフローで利用する
ここまでの手順でフローでカスタム コネクタの利用が可能になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/55a908ea-9222-0c25-a6f6-b9e59724db35.png)

フローのアクションとして、以下の 3 動作ができます。

トーク Bot のテナント登録
https://developers.worksmobile.com/jp/document/1005002?lang=ja

トーク Bot のドメイン登録
https://developers.worksmobile.com/jp/document/1005004?lang=ja

メッセージ送信
https://developers.worksmobile.com/jp/document/100500801?lang=ja

フローの作成例は別記事にまとめます。
TITLE: Power Automate のカスタム コネクタで LINE WORKS Bot を簡単に作成
URL: https://qiita.com/iwaohig/items/96334a6d239d959b7938
Python：pyenvを何も考えずに更新し「Pythonどこいった？」現象を解決する

Mac で Home brew を使っております。OS は Catalina ですが、Python のバージョンは自分で決めたいので、システムの Python3 ではなく、pyenv と pip で Python 環境を管理しています。

２回ほどあったのですが、Home brew で ```brew update``` をかけ、何も考えずに ```brew upgrade``` すると、pyenv が更新されているときがあります。
pyenv が更新されたあと、```python3``` しても「そんなファイルがありません」といわれ焦ることになります。

この場合は、

```
pyenv rehash
pyenv global 3.8.1
```

というように、rehash のあと global で使いたいバージョンを再指定すれば、もとにもどります。
普段から pyenv に馴染んでいる方々には常識でしょうが、自分の備忘録もかねて、念の為アップしておきます。

以　上
「テスターちゃん」で学ぶソフトウェアテスト⑥

#1. 「テスターちゃん」について
初心者(新人)向けに描かれたソフトウェアテストの漫画になります
たまたまJSTQBについて調べていた時に見付けたブログの記事がきっかけで読むようになりました
[JSTQBを取るメリット5選](http://testerchan.hatenadiary.com/entry/2018/02/15/001117)

今でも更新がある度にチェックしたり、書籍版を読み返したりしたり、とテスト関連の資料として活用しています

[Blog](http://testerchan.hatenadiary.com/)
[書籍版](https://books.rakuten.co.jp/rb/16202142/)

#2. LOG
[「テスターちゃん」で学ぶソフトウェアテスト①](https://qiita.com/156Musik/items/46111ec9cfae5f9aa88d)
[「テスターちゃん」で学ぶソフトウェアテスト②](https://qiita.com/156Musik/items/3c1a91126dc15bd2bf40)
[「テスターちゃん」で学ぶソフトウェアテスト③](https://qiita.com/156Musik/items/1a9450a15aa3607fe2d5)
[「テスターちゃん」で学ぶソフトウェアテスト④](https://qiita.com/156Musik/items/77d4471ae21aac937f78)
[「テスターちゃん」で学ぶソフトウェアテスト⑤](https://qiita.com/156Musik/items/b89e104010dfcced3fd0)
「テスターちゃん」で学ぶソフトウェアテスト⑥ :point_left_tone1:イマココ
[「テスターちゃん」で学ぶソフトウェアテスト⑦](https://qiita.com/156Musik/items/94a036beb46c2dc68a86)
[「テスターちゃん」で学ぶソフトウェアテスト⑧](https://qiita.com/156Musik/items/fb1aa75351660c1150f8)

#3. 仕様の把握のやり方
##3.1 仕様書を読む時のポイント
普通に読んでも「そうなんだ」くらいで終わることが多い
　⇒それだとわかった気になるだけになって、何が書いていたかおぼえていないこともある

だけど、読む時に**<font color="red">考える</font>**を挟むだけで理解度は変わってくる
**何を拾いたいか**考えながら読むのは大切

>・大事なところはどこ？
・気になるところはある？

を考えて読むと良い

##3.2 メモを使って読んでいく
・メモを用意して、大事なところや気になるところを書き出していく
・疑問点や思い浮かんだことも一緒にメモする

意識して読む場所
⇒・何をするシステムか？
　・システムの特徴は？
　・どんな機能があるか？
　・その機能はどんなことをするのか？

仕様書も完ぺきではないので、書かれていないこともある
そのため**行間を読む**(言葉で表現されていないところの読み取り)必要が生じる
☆仕様書を読んで**自分が思ったこと**も大切になってくる

仕様書は1回読んだだけでは全然読み込みが足りない
２回、３回と繰り返して読むと見えてくるものが違ってくる

###参考資料
三色ボールペンで読む仕様書(鈴木三紀夫)

##3.3 マインドマップを使う

###マインドマップとは

[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%A4%E3%83%B3%E3%83%89%E3%83%9E%E3%83%83%E3%83%97＄)

###メリット

- **グループ化**しやすい
    - 枝(ブランチ)を使って情報の関連を整理する

- 発想
    - 考えながらブランチを描いていくと、そのブランチから疑問などが思いつくことがある
    - 描きながら連想して**仕様の行間の見える化**もできる

- 一枚の絵になることで**全体を見渡せる**ことができる
    - 仕様把握の時は全体を掴むことが大切

- **共有**がし易くなる
    - 共有された側は全体像の把握がし易くなる

###描き方

1．仕様書に目を通す
　⇒どうマインドマップにまとめられるか考えながら読むようにする

2．最初にテーマを描く
　⇒絵を入れるとイメージし易くなる

3．テーマから大きな枝(メインブランチ)を生やす
　⇒慣れない内は機能や画面などでまとめていくとわかり易い

4．メインブランチを描いたら、そこから関連することを自由に描く
　　☆描きながら思いついたこと・疑問に思ったこともちゃんと描くこと
　　⇒**正解は特にない**ので、自分が思ったようにイメージを広げて描くのが大切になる

5．仕様をまとめるだけでなく、その部分から**ちょっと考える**を挟んでみよう
　　⇒**隠れていること**が見つけ易くなる

###参考資料
[マインドマップから始めるソフトウェアテスト改訂新版](https://books.rakuten.co.jp/rb/15842668/)

##3.4 ここにも意識を向けてみよう

- 出来た時のことは書かれているけど、**出来なかった時のこと**が書かれていないこともある
- **反対**を考えてみる
- **暗黙の了解**になっている箇所も書かれていない可能性もある
    - プロジェクトで当たり前になっていること
    - 企画書が当たり前と思っていること

※わからない時は放置すると後で困るので気を付けること

##3.5 まとめ
- 仕様書はただ読んでも右から左に抜けることはよくある
- **自分の考え**を挟むと把握の度合いが変わってくる
    - 疑問・気付き・気になること……など
- 仕様書に全部書かれているわけではない
    - **行間を読む**ことが重要になってくる
    - テストだと仕様書に書かれていないことがより重要になる
【Python入門】Pythonで頻出の関数やメソッドのまとめ【課題形式】

# はじめに
Pythonには、様々な組み込み関数やメソッドが用意されています。
その中でも頻繁に使用するものをまとめてみました。

# 概要
Pythonを理解する上で、[トミーさんブログ](https://obgynai.com/python-roadmap/)の課題が非常に役立ったので、本記事についても課題形式で進めていきます。
不明な点がありましたら、リンク先にて詳しく説明されているので、そちらを参考にしてみてください。

# 対象者
以下の方向けの記事となっています。
* Pythonのインストールや、JupyterNotebookの環境構築が完了済み。
* 少しPythonを触ってみた。
* 自分の実力を確認したい！

# 環境
* macOS High Sierra 10.13.6
* Python 3.7.6

# 実装内容
## 課題1 入力金額の平均金額を算出する
### 技術要素
* リストと頻出メソッドの利用(append)
* リストを計算する関数の利用(sum、len)
* 入力用の関数を利用(input)
* 条件分岐の利用

### 仕様概要
* 参加者の所持金を入力する
* 0円が入力された時点で計算を中止する
* 所持金の平均値を算出する

### 出力イメージ
![スクリーンショット 2020-04-09 5.05.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310367/ba57ed64-2372-e8e9-f6f0-92c2663f9fa2.png)

### 実装例
```python
# 入力値を格納するリストを用意
money_list = []

# 平均金額を格納
average = 0
while True:
    # 入力値を格納
    money = int(input("あなたの所持金を教えてください："))   
    if money == 0:
        break
    # リストへ入力された金額を追加
    money_list.append(money)

# ゼロ除算を考慮
if len(money_list) !=0:
    # 合計値を算出
    s = sum(money_list)
    # リストに格納されたサイズ(ここでは要素数)
    n = len(money_list)
    # 平均値を算出 
    average = s / n
    
print("全員の所持金の平均額は",average,"です。")
```


## 課題2 英単語の文字数をすべてカウントする
### 仕様概要
* 英単語を入力する。
* 何も入力されなかったら、英単語の入力を終了する。

### 仕様詳細
* リストは以下の内容で作成する。
    * アルファベットの小文字(キー)
    * 数値(初期値:0)
* 入力された英単語の単語を分解する。
* 書くアルファベットの出現回数を数える。
* 入力が完了すれば、英単語一覧をソートする。
    * ソートは単語数
* アルファベット出現回数の結果を表示する。

### 出力イメージ
![スクリーンショット 2020-04-09 5.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310367/617a28db-28d2-a122-3b90-729d05d36e56.png)
![スクリーンショット 2020-04-09 5.09.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310367/a9a32849-754f-b036-3850-6f3159b71dfd.png)

### 実装例
```python
alphabet_code= dict.fromkeys(list("abcdefghijklmnopqrstuvwxyz"), 0)
words = []

# 英単語を入力し、文字数を加算する
while True:
    word = input("英単語を入力指定ください:")
    if word == "":
        break
    words.append(word)
    for letter in word:
        if letter in alphabet_code.keys():
            # キーがあれば加算(判定しないとkeyerrorが起きる)
            alphabet_code[letter] += 1

print('')
print('入力された単語は、以下のとおりです')
words.sort()
for word in words:
    print('・' + word)

print('')
print('アルファベット出現回数の結果は、以下のとおりです')
for letter , count in alphabet_code.items():
    print("{0}\tの出現回数 : {1} 回".format(letter, count))
```

## 課題3 指定したフィボナッチ数列の結果を出力する
### 技術要素
* 関数の利用
* 再帰関数の理解

### 仕様概要
* 入力メッセージと入力フォームを表示
    * メッセージ : 「フィボナッチ数列のうち何番目の数値を表しますか」
* 入力した数値で、フェイボナッチ数列を表示

### 使用詳細 
* フィボナッチ数列の関数を作成
    * 1番目、2番目の数値は1
    * 3番目以降の数値は、1つ前の数値と2つ前の数値の和
    * while文を使用する再帰呼び出し

### 出力イメージ
![スクリーンショット 2020-04-09 5.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310367/c28a95bc-d76d-5e31-f821-ba5d8e742b7f.png)

### 実装例
```python
def fib_func(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib_func(n - 1) + fib_func(n - 2)

target_num = int(input('フィボナッチ数列のうち何番目の数値を表しますか : ') )
print(fib_func(target_num))
```

# 参考情報
本記事は、トミーさんブログの[ロードマップ記事](https://obgynai.com/python-roadmap/)に沿って課題を進めた内容となっています。
もっと細かい点が知りたい、他の使い方を知りたい方は、リンク先から学習されることをオススメします。
課題だけでなく、Pythonを0から学習するためのノウハウが公開されているので、ぜひ活用してみてください！
CentOS8からの違い

# はじめに

CentOS8になってからパッケージ管理ツールやパケットフィルタリングが変わりましたので、変更点を記載いたします。

# yumからdnfに変更

CentOS7以前はパッケージ管理ツールはyumを使用していましたが、CentOS8からはdnfに変わりました。

dnfは正式名称がDandified Yumと呼ぶくらいですので、yumの後継となっており
基本的にはyumで使用出来るコマンドやオプションはそのまま使用出来ます。

```
$ yum -y install php
$ dnf -y install php
```

# iptablesからnftablesに変更

yumと同様に今まで使用していたiptablesではなくCentOS8からはnftablesが標準となりました。

iptablesのコマンドや書き方とは大分変っておりますので、慣れるまで注意が必要です。

```
ルール確認
$ nft list ruleset
テーブル設定
familyにはip,ip6,inet,arp,bridge,netdevが設定可
$ nft add table family 任意のテーブル名
チェイン設定
$ nft add chain family 任意のテーブル名 任意のチェイン名
ルール設定
$ nft add rule family 任意のテーブル名 任意のチェイン名 dport 80 drop
iptablesの設定をnftablesに変換
$ iptables-restore-translate -f 変換前のiptablesファイル > 変換後のファイル名
```
map 派？ collect 派？

最近下記の記事を読んで。

* https://magazine.rubyist.net/articles/0038/0038-MapAndCollect.html

私、map 派でした。

そうか、関数型は結構合ってるのかもしれん。純粋関数型言語は使ったことなかったけど。なんとなく融通効かなさそう、とか、理想が高過ぎて実用的ではなさそう、みたいな先入観で捉えてましたが。しかし、私の理想とするプログラムの組み方は関数型だったのか。

仕組みと定義でソフトウェアを組み上げていくという考え方は 100% 同意。分かりづらいかもしれないが、ランダムという要素を無くしたパチンコ台みたいなもので、玉を転がしたらあるルールに従って然るべき所に自動的に転がっていくという。バグを一番少なくできるやり方だと思う。異常系も含めて想定外を無くす的な。オートマトンとかもそう。「やりたいことを宣言的に書いておけば、あとはコンピューターが頑張ってくれる」という発想は大事。

なので、初心者向けの講座で良くあるような「順に A やって、次に B やって」というプログラムの作り方はよろしくないと思うのです。

そうは言っても純粋な関数型（と何か言えるほどの見識もなく）、というのだと実際問題としてプログラム作れないんじゃなかろうか、という先入観があった。というか、今もある。その辺は原理主義者ではなく現実主義者なのかなー、と思う。

個人的には仕組みで作っていくやり方は、「フレームワークとライブラリとオブジェクト指向で組み上げていくイメージ」を持ってました。

単に見た目で Lisp を避けてただけかもしれないけど。(かっこ)ばっかりなので。今やってる [Kinx](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76) も、やたら見た目にこだわってるし。

* [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
* [Kinx リポジトリ](https://github.com/Kray-G/kinx)

ということで、map 派。そして reduce 派。Kinx での例。

```javascript:Kinx
var a = 100.times();
var r = a.map(&(e) => e * 2).reduce(&(r, e) => r + e);
System.println(r);
```

結果。

```
9900
```

あ、Array の説明してないな。近々書きます。こういう map とか reduce とか、Array 用の特殊メソッドもいくつか定義してあるので、使えると幅が広がる。

ただし、Array と Object は本質的に同じなので、Array の特殊メソッドはオブジェクトにも適用されるので注意。逆に Object という名の特殊オブジェクトは無いので、それもご注意。
［Unity初心者］privateってなに？

#環境
Unity 2019.3.7f1

#privateってなに？
ざっくり簡単にいうと、変数やメソッドを他のスクリプトからアクセスさせないようにするもの
意図せず数値が書き換えられてしまうのを防止する

最初は、
privateは他からアクセスできない
publicは他からアクセスできる
と覚えておく程度でOK！

他のスクリプトで値を使う予定のない変数にはprivateをつけておけば無難。

#privateは省略できる

###初心者さんにはこれを一番伝えたい！
実は、変数宣言時にpublicやprivateなどの"アクセス修飾子"をつけないと
**privateが省略**されるかたちになっている


次の２つは同じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/46053050-4c1c-a121-c744-3dc7754deedf.png)
↑privateが省略されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/e5c8d9eb-501c-ec39-8ed6-1a72cb03ed97.png)

他の記事を見る際は、
・privateを省略するパターン
・privateをあえて書くパターン
がありますので、この点を頭において見ていくと良いです。

私は最初これがわからずもやもやした気持ちで参考記事を見ていました。
楽しいUnityライフを！
Laravel Facade自作

LaravelのFacadeを自作する。
`Hoge::fuga()`で'piyo'を返すHogeファザードを作成する。

まずHogeクラスを作成する。

```lang:App/Support/Hoge.php
<?php

namespace App\Support;

class Hoge
{
    public function fuga() {
        return 'piyo';
    }
}
```

そしてHogeクラスを呼び出すファサードを作成。

```lang:App/Support/Facades/Hoge.php
<?php

namespace App\Support\Facades;

use Illuminate\Support\Facades\Facade;

class Hoge extends Facade
{
    public static function getFacadeAccessor() {
        return 'hoge';
    }
}
```

Hogeクラスをサービスコンテナに登録するProviderを作成。
Providerはmakeコマンドを使うことでapp/Provivdersフォルダ以下に雛形が作成されます。

```
$ php artisan make:provider HogeProvider
Provider created successfully.
```

```app/Providers/HogeProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class HogeProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
```

register関数内でHogeクラスをサービスコンテナに登録し、HogeProviderがLaravelに読み込まれるようにconfig/app.phpに登録します。

```lang:app/Providers/HogeProvider.php
    public function register()
    {
        $this->app->singleton('hoge', \App\Support\Hoge::class);
    }
```

```config/app.php
    'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        省略
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

        App\Providers\HogeProvider::class, //追加
    ],
```

これで使えるか確認してみましょう。
HogeFacadeをuseすることで`Hoge::fuga()`が使えるようになります。

```lang:適当なクラス
use App\Support\Facades\Hoge;
echo Hoge::fuga();
出力: piyo
```

# facadeのuseなしにfacadeを使えるようにする
config/app.phpにaliasを指定することでuseなしにfacadeを使うことが可能になります。

```lang:config/app.php

    'aliases' => [

        省略
        'View' => Illuminate\Support\Facades\View::class,
        'Hoge' => App\Support\Facades\Hoge::class, //追加
    ],
```

これで準備okです。`\Hoge::fuga()`で呼べるようになります。


# ideでコード補完できるようにする
providerを登録しておけばide-helperの自動生成ファイルを元にideコード補完ができるようになります。

```
 $ php artisan ide-helper:generate
```
Python3 平衡二分探索木は知らないがソートされた集合があったらいいなあって話

#はじめに結論
Pythonのsetは集合の管理ができますが、要素にindexを持っていないので「小さい方からx番目の要素を出力する」という操作を要素数 N に対して $O(N)$ でしか行えません。

あ〜遅すぎる。

結論を言うと、Binary Indexed Treeと二分探索で$O((logN)^2)$になります。もっと高速化できるかはよく知りません。

####(4.13追記)
Salmonize氏、joe氏ご指摘ありがとうございました。
$O((logN)^2)$としていますが、BIT上の二分探索を応用することで二分探索パートがBITのクエリ処理を必要としなくなり、$O(logN)$に高速化されます。

##どんな理屈？
Binary Indexed Tree(以下BIT)を用意しましょう。なに？BITを知らない？
https://ja.wikipedia.org/wiki/フェニック木

xを集合に追加する場合、BITのx番目の要素に+1するということにしましょう。
例えば、{3, 1, 4}の集合を作りたい！と思ったら、

BIT配列の3番目の要素に+1
BIT配列の1番目の要素に+1
BIT配列の4番目の要素に+1

これでOKです。

ではlower_boundを考えていきましょう。二分探索します。小さい方からx番目の要素が欲しい時、

「y以下の要素がx個以上あるか？」という判定を使って二分探索すると、BITでy以下の要素の個数は$O(logN)$でわかり、

さらに二分探索自体に$O(logN)$かかるので

合計$O((logN)^2)$です。なるほどね。

##制約
floatやstrを扱いたい場合は工夫が必要です。floatだったら元々の数を定数倍しておけばよし、strは文字コードを使えばいいですが実用的には見えません。

また動的な変更に思ったより強くないのでオンラインクエリに弱いかもしれません。
でかい数を格納する際も座標圧縮などをしないとうまくいきません。

##結論
まあsetで順序集合を考えるよりは速いかなあ...
平衡二分探索木の方が便利そう（終了）

#どんな記事にも終わりはある
そういえばコード書いてないですね。
初心者によるプログラミング学習ログ 285日目

#100日チャレンジの285日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
285日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>285日目　2h<br>・昔つくったポートフォリオ改造（ほぼ書き直し）<br><br>今度は設計とかちゃんと意識して書く<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><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/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1247977493778149378?ref_src=twsrc%5Etfw">April 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
データエンジニアがMLOpsを視野にDevOpsを学ぶ。　①とっかかり

#tl; dr
今後のために、DevOps/MLOps実務を体系的にマスターしておこうシリーズ
私の場合、とっかかりとして、フロントエンド言語のTypescript(ts)と、バックエンド言語のScala/Python(with Sparkエコシステム)をつなげるところから取り組むの良いと思った。

判断理由:

```
1) フロントエンド開発者(js/tsユーザー)にpythonは親和的
　※js/tsユーザーが併用するプログラム言語の定番の一つがpythonとなっているらしい ★１
2) tsのモデル定義とsparkのモデル定義の親和性が高い
　※Typescriptのインターフェース定義とSpark向けのcase classが特に類似。
3) tsとsparkとの相互呼び出しが容易となりつつある（「jsii」の魔法）。
 　※例、jsiiによって、typescriptで書かれたnodejsアプリのテストをScala/Pythonで行うことが可能に。
4) terraform/ansible/docker/hashi stackあたりはなんとかなる私の課題は、今風のフロントエンド。
```
★１の出典 : [JavaScriptユーザーが使う"第2のプログラミング言語"、第1位はPython](https://news.mynavi.jp/article/20200107-949725/)

# [1] nodejs上のTypescriptエコシステムの成熟。
　型有りなjs互換言語であるTypescript。jsと比べ敷居が高いところもあるのだろうが、バックエンドを型有り言語(C#/Scala etc.)で書いているエンジニアにとってはTypescriptは安心できる選択肢だ。web開発に外せない選択肢となっているnodejs上でTypescriptを動かす際のノウハウも蓄積されている模様。

以下では、`Typescript on nodejs`の近年の解の一つらしい、Nest.jsフレームワークを例に取る（フレームワークの流行り廃りはあるにしても、`Typescript on nodejs`は、今後も標準的な選択肢であり続けるたろう。）
参考　[Nest.jsは素晴らしい](https://qiita.com/kmatae/items/5aacc8375f71105ce0e4)

# [2] バックエンドとフロントエンドの狭間。
インターフェースを持つTypescriptのモデル定義は、C#やScalaと親和的だ。
一例を上げよう。
↑のNest.js素晴らしい記事、[Nest.jsによるUserインターフェースの作成](https://qiita.com/kmatae/items/5aacc8375f71105ce0e4#user%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90)のところで作っておられるUserモデルのインターフェースuser.interface.tsは以下:

```typescript:user.interface.ts
export interface IUser {
    id: string;
    name: string;
    kana: string;
    email: string;
    postcode: string;
    address: string;
    phone: string;
    password: string;
    admin: boolean;
    createdAt: Date;
    updatedAt: Date;
}
```

対して、対応するSpark向けのscalaのクラスは例えば、以下のようになる:

```IUser.scala
case class IUser (
    id: String,
    name: String,
    kana: String,
    email: String,
    postcode: String,
    address: String,
    phone: String,
    password: String,
    admin: Boolean,
    createdAt:TimeStamp,
    updatedAt:TimeStamp
)
```

　機械的な置換で行けてしまうレベルだ(ここではscalaとしたが、Typscript同様に型アノテーションのあるPython(PySpark)でも同様)。Sparkに永続化するプロパティはString/Int/Boolean/TimeStampといった基本的な型のみを使うのが実務的に簡易である。フロントエンド側も同様の書き方で安全に書いていけるならば、話が早い（nest.jsは概観するに、安全かつ生産的に書いていけそうな気がする...実際に自身で書くかどうかは別にして)。
　Typescriptで書かれたnode.js上からjsonを生成し、(間にKafka等を挟んだり、準ストリーム処理にしたりして)sparkに流し込むことができれば、後はどうとでもなる。バックエンド側では、Sparkはデータストア間のデータハブを記述する標準解の一つだ（csv,cassandra,hive,neo4j,機械学習基盤 etc.をつなぐ）。

# [3] jsiiを介し、Python/ScalaでTypescripe on nodejsのテストが可能に。
以下の記事で知った、AWS謹製のjsii。
[TypeScriptで書いたプログラムをPython等で動かす魔法の「jsii」を紹介](https://qiita.com/suzuki_sh/items/85dd85d107f453645ac9)

jsiiによって、TypeScriptのコードをPython/JVM言語(Scala)/C#から直接に呼出すことができるようになるということだ。つまり、PythonやScalaでTypescriptのテストコードを書けるということだ。実運用に入ったシステムでは、フロントエンド側の事情(サービス拡張等)によりTypescriptのモデルは変化していくもの。モデルの変化に併せ、継続的にデータの授受をテストできることはありがたい（cf. 型がないデータ（例、CSV）をsparkの世界に持ち込む際のテストはなかなか面倒）。

# 次回から手を動かす。
最近、パフォーマンスを追求したwebフロントエンドを持つシステムの裏方（データ基盤）をサクッと作ることを個人的にお勉強してきた。フロントエンドの技術には疎くなっているが、Svelte/typescript/nodejs/firebase...と順に触りながら、感覚を掴みんできた。今後も、nestjs/SSR/ts2elm...と手を動かしながら、バックエンドspark側とのつなぎをお試ししたい。nodejsとDockerをターゲットにCI/CDできるgithub actionが役に立ってくれるかな、と期待。
個人でAWSのアカウントを作成してみた

直近の業務で使ったことがあったので、試しにアカウントを作成してみました！

現場ではすでにIAMユーザまでが用意されている状態でしたので、
今回最初からの設定は初めて触るものでしたのでとても厄介でした。


なお、IAMの設定(のちに出る安全のためにやること全部やるとこ)まで実施しています。
被害出ているようなので念のため。

説明については省略します。
※公式での説明の通り実施したので…

感じたことや、注意する点について述べていこうと思います。

ここでは最初のユーザを作るまでですので、
AWSでお金はかかっておりません。


#事前に用意すべきもの
・スマートフォン(電話番号が割り振られているもの)
・クレジットカード
・複雑なパスワード3つ(できれば紙媒体で)


#アカウントについて

まず初めにここを読みながら登録していきます。
https://aws.amazon.com/jp/register-flow/
※基本全部入力必須と考えてよいです。


##AWS アカウントの作成

「AWS アカウント名」はのちにルートユーザ名で使いますので任意の文字列でよいです。
ここで任意の値を求められるとは思わなかったよ…、わざわざ調べましたよ…。


##連絡先情報

連絡先情報を入力ではパーソナルを選びます。
(確か会社名の欄がないくらいだったと思います)

住所の書き方が日本式(上から下へ書く様式)ではないです。


##お支払い情報を入力

請求が来た時の支払い用ですね、クレジットカードを登録しましょう。
うまくAWSを使えれば請求はされません。


##SMS または日本語自動音声電話によるアカウント認証

①～③を記入し④を押下するとスマホにコードが届きます。
※私はSMS受け取りにしました。

そのコードを入力し次へ進むと本人確認は終了です。


##AWS サポートプランの選択

とりあえずベーシックプランで。
今のところ大掛かりなことはやる予定はないのでこれで。



ここまででアカウントの登録が完了です。


#IAMによるセキュリティ強化

以下のページを参考にせていさせていただきました。
https://note.com/akaikaze/n/n5b1ab59cbef3
https://note.com/akaikaze/n/ne644427856e1


最初にパスワードの変更をしておりますが、
特に説明することはないです(普通のパスワード変更と同様です)。

本題は以下のIAMダッシュボードの項目です。

![IAMキャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567450/e9438b2d-df45-35bc-a38a-9709ba5a1cde.png)


##ルートアクセスキーの削除

指示に従って削除。
削除しない場合はどう危険なのかは調査中です。


##ルートアカウントのMFAを有効化

これも手順通りに実施。
2つ入力欄があるが、これは

1.<今表示されている数字6桁>
2.<1の直後に切り替わって表示された数字6桁>

です(書いてあるが念のため違う言い回しで記載)。

MFAの必要性は以前の私の記事にて簡単に解説済み。


##個々のIAMユーザの作成

ルートアカウント以外でログインできるユーザを作成します。
ここでもMFAを設定しておくとよいでしょう。


##グループを使用してアクセス許可を割り当て

IAMユーザの作成から続けてできます。

直接ユーザにポリシーつけてもいいですが、
グループにポリシーをアタッチしたうえで、グループにユーザを追加したほうが
ユーザを増やした際管理しやすいです。

ここでは一番強力な"AdministratorAccess"をつけておいたほうがよいでしょう。
(なのでMFA設定を忘れないように)


##IAMパスワードポリシーの適用

よくある""大文字を含む"や"何文字以上か"等の設定をすることができ、
IAMユーザ全員に適用させることができます。


---
これで初期設定は完了です。
これ以降は作成したIAMユーザで入っていろいろAWSを触ってみましょう！
Twitter loginをlocalhost:3000(safari)でpreflight is not success等が表示された時の対処法

#はじめに
**（*注意：この記事は学習の一環として実装した物の一部を記事にしています。本記事には正しくない情報、方法を含んでいる可能性があります。）**

#概要
どうも、Ruby on Rails を使って勉強をしているモノです。
現在、ポートフォリオ、自作webサービスを作っております。

**Omniauth-twitter**を使って**Twitter login**機能を実装してます。**localhost:3000(safari)**からTwitter APIへアクセス, Twitterからのcallbackを行う際のsafariのLogのエラーが表示されました。

- **Preflight response is not successful**
- **XMLHttpRequest cannot load https://api.twitter.com/oauth/authenticate? due to access control checks.**
- **Failed to load resource: Preflight response is not successful**

twitter omniauthを利用してappを作成する際
website URLはherokuにしているので**localhost:3000**は**CORS制限（TwitterにUser情報をアクセスする際の制限）**がかかっているのかと思っておりました。

解決する為にCORS用のコードが必要なのかと調べて数日費やしましたが、一瞬でsafariのブラウザの環境設定で解決することができたので書いておきます。

##開発環境
- Ruby on Rails
- safari(localhost:3000)
- Twitter API(twitter login機能)
- devise

{**Twitter API**,**CORS**については省略します。}

#解決方法
解決方法はいたって簡単です。
localhost:3000(safari)もしくはsafariブラウザ上のメニュー

1. **safari**の**環境設定**をクリック
2. **詳細**クリックして[メニューバーに"開発"メニューを表示"]にチェックマークを入れる。
3. チェックマークを入れると**safari**メニューに開発タグは増える
4. **開発**メニューをクリック
5. **開発タグの**の[クロスオリジンの制限を無効にする]をクリック

これで再度、**localhost:300(safari)**を起動してlogを確認すると先ほどのエラーログが消えてると思います。

##参考URL

https://qiita.com/kai_kou/items/54b61a274b77977add54
英語が苦手の僕がどうしてもやりたい英語js教材がありました

…のでやってみました。（※回し者ではありません。）

# 1. やった教材
Wes Bos氏の「javascript30」という教材です。
メールアドレスを登録するとすぐ閲覧できました。

https://javascript30.com/
https://github.com/wesbos/JavaScript30

# 2. Wes Bosと私の出会い
このQiita記事です。（めっちゃ人気！）
https://qiita.com/baby-degu/items/a06bddd1a61b7d907a55

この記事の
> このコースを修了する頃には、JavaScript、DOM、そしてブラウザーAPIを使いこなせるようになっているはずです。

この部分を読んで、「マジか！！！すごっ！！！」となったのがきっかけです。

# 3. この教材の愛すべきところ
## なんといっても無料！
海外のサイトだと、お金払えって言われると少し怖いですもん。

## 「文法理解」から「アプリ開発」へ移行する際のみぞを埋めてくれる！
Wes「基本文法を学んだあとは、たくさんのアプリを作るべきだ！でも何を作るかわからない？ならこれやって！」
僕「これだ！！！！」

## 初学者の妨げとなるものを排除！
よくわからないフレームワークや、「このアプリ以外でどこで使うの？」といったAPIは一切出てきません。
**html・css・javascript**　これだけ！

## サンプルが非常に魅力的！
https://javascript30.com/
このリンクの下のほうにサムネイルが載っています。
これが作れます。わくわくするでしょ？？

## 時間がいい感じ
長くても30分程度。一日1つ。とても気軽にできます！

# 4.この教材の問題点
英語😭

# 5.何としてもやりたかったので
とりあえす、やってみました。

# 6.意外といけた！
意外といけた理由を考えてみました。

## さすがWes!簡単な単語で説明してくれる！
単語が意外と簡単！どっかで見たことあるような単語ばかりを選んで使ってくれている。
さすが超人気講師Wes！

## 私たちはプログラマー! 共通言語を持っているではないか！
簡単な単語を使ってくれてはいるけど、私も負けてません。
まったく聞き取れないところだってありました！

でも**私たちはプログラマー。共通言語を持っている**ではないか！
**そう。javascript !!**

わからないキーワードは調べれば日本語で出てきます。そこで理解すればいいのです。
英語がわからなくても、javascriptで私たちは会話ができます！

## tips これが意外とつかえた！
google翻訳の拡張機能！
https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb?hl=ja

これの設定を「すぐにポップアップを表示する」にすると…
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205371/1ba51d5c-2cc6-3a12-e924-253a66a49f02.png)
字幕を入れてわからない単語を選択するとすぐ検索できるよ！

# 7.やって身についた（と思う）こと
* アプリケーション作るのって難しいんだろ？という固定概念の脱却（これが一番かも）
* Javascriptってこういうことができるんだ。という知識
* アプリケーションってこうやって作っていけばいいんだ。という知識
* ものづくりの楽しさ！
* 英語が理解できればもっっと広い世界が見えるかも！英語がんばろ！というモチベ向上

やってよかった！ありがとう！Wes!

# 8.恐れてはいけない！
わからないことにおそれちゃいけない。大体何とかなる！
> Never fear, Wes Bos is here… (恐れるな。Wes Bosがここにいる…)
https://medium.com/employbl/30-things-i-learned-from-javascript-30-fa37d554bfca

# 9.実は…
* 私はまだ23日目までしか完了してません（2020/04/09現在）。一日一個づつこなしていきます…
    * 4/12。完了しました！！ありがとうございます！（4/12追記）
* youtubeでも同じ動画を公開しています。だから自動翻訳機能を使えば（少し違和感のある）日本語でも学習できます。でも英語で勉強することを薦めるよ！

# 10. あとがき
興奮して急いで書いたため、誤字脱字があるかもしれません。
読みづらい文章になっています。まことにごめんなさい。後で修正します(予定は未定)。

この教材はJavascriptの基本中の基本が理解できてないと少し難しいかもしれません。
まだ身についてないよ！そんな方はこれがいいですよ!
https://jsprimer.net/
全部理解する必要はないかもしれませんが、全部目を通してからやるといいかもです！
Microsoft.Extensions.Configuration を使って、INI ファイルに書いた設定を読み込む

# Microsoft.Extensions.Configuration を使って、INI ファイルに書いた設定を読み込む

\# 以下の記事が書かれた時の版数は .NET Core 3.1 (3.1.201), Microsoft.Extensions.Configuration.Binder 3.1.3, Microsoft.Extensions.Configuration.Ini 3.1.3 となります.

exe.config はずっと微妙だなあと思っていたのですが、Microsoft 謹製の INI ファイルから設定を読む手段が提供されたので、それを使ってみる. 例として以下の INI ファイルを読むコードを作成する. 書いたコードは [GitHub](https://github.com/c-yan/MsExtConfigurationExample) にも上げてある.

```ini:config.ini
[ConnectionStrings]
Database=xxx

[AppSettings]
UserName=foo
Password=bar
RetryCount=3
```

Console App (.NET Core) プロジェクトを作成する. TargetFramework が netcoreapp3.1 (.NET Core 3.1) で作成される. 要求は .NET Standard 2.0 なので .NET Framework 4.6.1 や、.NET Core 2.0 でも動くはず.

次に `Microsoft.Extensions.Configuration.Ini` と `Microsoft.Extensions.Configuration.Binder` を nuget インストールする. これを書いている時点では 3.1.3 がインストールされる.

```powershell
Install-Package Microsoft.Extensions.Configuration.Ini
Install-Package Microsoft.Extensions.Configuration.Binder
```

そして、セクション毎に情報を詰めるクラスを書いていく.

```csharp:ConnectionStringsConfig.cs
namespace ConsoleApp1
{
    public class ConnectionStringsConfig
    {
        public string Database { get; set; }
    }
}
```

```csharp:AppSettingsConfig.cs
namespace ConsoleApp1
{
    public class AppSettingsConfig
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public int RetryCount { get; set; }
    }
}
```

最後にそれらセクション毎のクラスをまとめ上げるクラスと、INI ファイルから設定を読み込むメソッドを書いて完成.


```csharp:AppConfig.cs
using Microsoft.Extensions.Configuration;

namespace ConsoleApp1
{
    public class AppConfig
    {
        static AppConfig Instance;

        public ConnectionStringsConfig ConnectionStrings { get; set; }
        public AppSettingsConfig AppSettings { get; set; }

        public AppConfig() { }
        public static AppConfig Get()
        {
            if (Instance != null) return Instance;

            Instance = new ConfigurationBuilder()
                .AddIniFile(".\\config.ini")
                .Build()
                .Get<AppConfig>();

            return Instance;
        }
    }
}
```

以下のように簡単に設定内容にアクセスできる.

```csharp:Program.cs
using System;

namespace ConsoleApp1
{
    class Program
    {
        static readonly AppConfig Config = AppConfig.Get();

        static void Main(string[] args)
        {
            Console.WriteLine(Config.ConnectionStrings.Database);
            Console.WriteLine(Config.AppSettings.UserName);
            Console.WriteLine(Config.AppSettings.RetryCount);
            Console.Read();
        }
    }
}
```
CloudFront でデカいファイルを gzip 配信する

## Summary
CloudFront は、10 MB 超えのデカいファイルを自動的に gzip で配信してくれません。
あらかじめ gzip 圧縮したファイルを S3 に置くことで対処できました。

## 前提条件
- S3 と CloudFront でサイトを配信している。
- 10 MB 超えのデカいファイルを配信している。
- デカいファイルにも gzip 圧縮をかけたい。

## CloudFront では自動で gzip 配信できないファイル

<img width="963" alt="スクリーンショット 2020-04-09 1.16.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/bbcd7f50-208b-955f-a530-d9b8f6e5881d.png">

文章校正ができるサイトを作っていたところ、[形態素解析](https://www.atilika.com/ja/kuromoji/)のための辞書ファイルを Web ブラウザに読み込ませる必要が出てきました。
その辞書ファイルは gzip 圧縮で 20 MB、非圧縮で 100 MB のなかなかデカいファイル。
CloudFront で gzip 圧縮をかけたいのだが……

<img width="339" alt="スクリーンショット 2020-04-09 1.17.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/d6ac98fa-2323-fdd7-14b6-d7e02f8f4d8e.png">

CloudFront の「Compress Objects Automatically」を有効にしても、辞書ファイルは gzip で配信されませんでした。
記事[CloudFrontのgzip圧縮をONにした時に圧縮されるデータ](https://blog.kozakana.net/2017/11/cloud_front_gzip/)によると、10 MB を超えるファイルには gzip 圧縮が適用されないようです。

## gzip 圧縮したファイルを S3 に置く

そこで、あらかじめ gzip 圧縮したファイルを S3 に置くことにしました。
GitHub Actions を使って S3 にデプロイしているので、↓のように `gzip` コマンドを使った前処理を入れます。

[該当のコミット](https://github.com/blue-hood/kohsei-san/commit/e1f39e9805c7d779dd26ac29d851a850628e7afb#diff-3680803a67ea02b9d6b8b783f532a8ceR10)

```
- run: gzip -r docs
- run: for file in $(find docs -type f); do mv "${file}" "${file%.gz}"; done
- uses: jakejarvis/s3-sync-action@master
  with:
    args: --acl public-read --content-encoding gzip --delete --follow-symlinks
  env:
    AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    SOURCE_DIR: docs
```

docs ディレクトリ配下を配信したいとして、`$ gzip -r docs` で全ファイルを gzip 圧縮します。このとき、圧縮されたファイルには .gz 拡張子がつきます。

`$ for file in $(find docs -type f); do mv ${file} ${file%.gz}; done` で圧縮したファイルから .gz 拡張子を取り除きます。

そして、s3 の [sync](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html) コマンドを `--content-encoding gzip` オプションで実行すれば完了です。
※動作確認する際は、CloudFront のキャッシュ削除が必要かもしれません。

## gzip 配信できた！
<img width="936" alt="スクリーンショット 2020-04-09 1.31.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/df0c5eca-20c8-a83e-39ca-ddd12f4e0fea.png">

辞書データを 20 MB 以内に収めて配信できるようになりました。
それでもまだ Web サイトとしてはとてもデカい。
そこで、

- [Service Worker](https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API/Using_Service_Workers) を使ってキャッシュを永続化すれば実用範囲内かな。
- オフラインでも動くアプリにすれば妥協できるかな……？

## 文章校正サイトを作ってみました
<img width="395" alt="スクリーンショット 2020-04-09 2.27.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/a32216f9-3894-440c-6977-a58b7cacee11.png">

[校正さん](https://kohsei-san.b-hood.site/)

文章校正ができる Web サイトを作ってみました！
辞書データや校正プログラムも含めて全て Web ブラウザ上で動かしています。
[PWA](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps) に対応させたので、スマホからだとネイティブアプリっぽく使えると思います。
Dockerを導入したい

#はじめに
Macでpython3を使おうとしたら、見事に環境が破壊されたため、Dockerを導入してコンテナ上でPythonを実行することにする。

筆者の能力
- python3を入れようとして、元環境を破壊してしまうくらいの雑魚さ
- Dockerはかなり前に一度触ったことがあるため、インストールはされている

PC : MacbookPro Early2015
OS : macOS Catelina

自分の頭の中整理くらいに書いていきます。
参考ページ
[https://qiita.com/k5n/items/2212b87feac5ebc33ecb](https://qiita.com/k5n/items/2212b87feac5ebc33ecb)
[https://note.com/motchalini/n/nc0486b630b67]
(https://note.com/motchalini/n/nc0486b630b67)
https://qiita.com/chroju/items/ce9cae248cc016745c66

#作業

##イメージの取得
今回はpython3を利用するための環境が欲しいため、python3のイメージをローカルに落としてくる。python3のためのイメージはpython:3らしい

```bash
$ docker pull python:3
```
これでpython3のイメージをダウンロードできた。

## Dockerfileの作成&ビルド
最初なので、vimとpipが使えたらいいかなと思い、それだけデフォルトでインストールしておく。
適当なフォルダにDockerfileという名前のファイルを作っておく

```text:Dockerfile
FROM python:3
MAINTAINER koji-satoyama

# パッケージのインストールとアップデート
RUN apt-get update && apt-get -y upgrade && apt-get clean
RUN apt-get -y install vim

RUN pip install --upgrade pip 

```

```bash
$ docker build -t <イメージの名前> .
```
すげー長いシステムログと共に、ビルドが成功した。
おそらくvimやらapt-getやらを取っていた模様。

イメージのリストを確認すると、自分の名付けたイメージが作成されていた。
python:3というイメージから派生させて、新しくイメージを作成したというニュアンスだろうか。

```bash
$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<イメージの名前>         latest              xxxxxxxxxxxx        6 minutes ago       1GB
```

## コンテナの起動
あとは作成したイメージを元にコンテナを起動するのだが、いろいろオプションがある模様。

実行したコマンドは以下。

```bash
$ docker run -it --name <コンテナの名前> -v [ホストPCの絶対パス]:[コンテナ上のパス] -w [コンテナ上のパス] <イメージの名前> /bin/bash
```
コマンドを説明していく。
詳しくは公式ドキュメントを参考にされたい。
http://docs.docker.jp/engine/reference/commandline/run.html

|オプション|意味|
|:-:|:-:|
|-it|インタラクティブかつ擬似ターミナル割当|
|--name|作成するコンテナ名の指定。|
|-v|コンテナでホストPCのフォルダをマウントする。次で指定したホストPCのフォルダをコンテナ上に作る|
|-w|初期ディレクトリの指定。コンテナに入ったときの現在ディレクトリ|
|python_test|利用するイメージの名前|
|/bin/bash|コンテナを起動してはじめに実行するコマンド。bashを起動している|

このコマンドで、コンテナの中に入って作業ができる

## 作業が終わったら
コンテナ内の作業が終わったら、

```bash
exit
```
でコンテナから抜け出す。（他にも方法はあるが、省略）

次からコンテナに入る時は次を実行

```bash
# コンテナの再起動
$ docker restart <コンテナの名前>
#　コンテナに入る
$ docker attach <コンテナの名前>
```

# 終わりに

いろいろ調べながらだと、2時間くらいかかってしまった。
慣れないと覚えられないことも多いので、Dockerは毎日触りたい。
【Java入門】MainMethod（メインメソッド）について

# MainMethod（メインメソッド）とは？
「最初に呼ばれるメソッド」。
Javaを実行すると最初に呼ばれるメソッドなので、必ず宣言が必要なメソッドです。
もし、メインメソッドがなかったら。。。。。E R R O R！！！
※Errorの場合、おそらく👇のErrorが出るはず！！

```
エラー: メイン・メソッドがクラス⭐️（※1）見つかりません。次のようにメイン・メソッドを定義してください。
   public static void main(String[] args)
またはJavaFXアプリケーション・クラスはjavafx.application.Applicationを拡張する必要があります
```
※1）クラス名

# MainMethod（メインメソッド ）の書き方

```
public static void main(String[] args) {
    (実際の処理内容をここに書く)
}
```
※メソッドの書き方は👇を参考しよう！
[メソッドの書き方＆引数について](https://qiita.com/Lovely_030_Dong/items/d8d425350f7896d07405)

ここでのポイントは
① 必ず「public」で
② 必ず「static」で
※staticは今後もっと詳しく説明します。なぜ！？大事です。（重要度：⭐︎x1000000万）
③ 必ず「void」で
※voidではないとエラーが発生します。試してみてください！
④ 必ずString型の配列で
⑤ args？ここは変数名なので自由にどうぞ！でも、デフォルトで「args」になっている。
※変数については今後もっと詳しく説明します。なぜ！？大事です。（重要度：⭐︎x1000000万）
TorchScript の不都合メモ

v1.6.0 です.

いずれ解決されるものと思われます.
(と思ったが意外と解決されないかも...)

# isinf で any ができない

`torch.isinf(x).any()` がコンパイル時 NG(返り値が bool とみなされる. 本来は Tensor)

`torch.isnan(x).any()` や `torch.isfinite(x).all()` はうまく行きます.

# inverse() では LAPACK(BLAS)ビルドが必要.

x.inverse() をするには LAPACK(BLAS)を有効にして libtorch ビルドが必要です(一応 prebuilt バイナリでは on になっている模様で, 利用はできるが, ソースコードからビルドする場合に注意)

# reversed iterator が使えない.

```
for i in reversed(range(10)):
```

ができません.

# exp(inf) の振る舞いがおかしい

x を float32 型のテンソルとします.

```
1.0/exp(x)
```

が, テンソル x の要素が `inf` の場合, 結果が `inf` になります.
(Python での結果, および C++ での `1.0/std::exp(inf)` は 0.0 になる)

# nan_to_num が無い

`torch.nan_to_num` が使えないので, NaN を zero にとかがやりずらいです.

とりあえずは `torch.where` で代用できます.

```
zero = torch.zeros(...)
inf_mask = torch.isinf(x)
y = torch.where(inf_mask, zero, x)
```
rails 環境構築

# ruby install
1. [公式サイト](https://rubyinstaller.org/downloads/)から
   「=> Ruby+Devkit 2.6.5-1 (x64)」をダウンロード
2. exe を実行してそのまま進める。cmd が開かれて実行画面が出て無事消えたら ok
3. cmd で`ruby -v`を実行して version が返却されたら install 完了

# SQLite3 install
1. [公式サイトのダウンロード画面](https://sqlite.org/download.html)から　「Precompiled Binaries for Windows」の部分で bit 数に合わせたものを取得
2. 1 と同じ URL より「sqlite-tools-win32-x86-3310100.zip」も取得する
3. ダウンロードしたフォルダにある「sqlite3.exe」と「sqlite3.dll」を
   `-rubyinstallpath-/bin`の中にコピーして配置する

# Rails install
1. `gem install rails -v 6.0.2.2`
2. `rails -v`で帰ってきたら ok

# localhost起動
1. `Rails new project -G` で環境を作成
2. `Rails s`で環境`localhost:3000`繋がる

## 困ったとき

### yarnがない
> [公式](https://classic.yarnpkg.com/ja/docs/install/#windows-stable)からyarnのinstallをする

### webpackerが無くて落ちる
```cmd
Webpacker configuration file not found
```
とあれば、ないので`rails webpacker:install`を使ってinstallする
(この時yarnが必要)
あつ森の株価の変化を見れるプログラム（未完成）

###あつ森で1週間の株価推移を調べるときに、グラフ化出来たら見やすいなぁと思って作ってみました。
（2020/04/09追記 グラフ上に数字が出せないので未完成です。折れ線グラフが良かったかなぁ。。。どなたか手直ししてください。。。）

以下コード

```python

import matplotlib.pyplot as plt
import japanize_matplotlib

week = ["月", "火", "水", "木", "金", "土"]
ap = ["前", "後"]
stock = []
labels = []

for i in range(len(week)):
    for j in range(len(ap)):
        print("--------------------------------------------------")
        q = int(input(week[i] + "曜日,午" + ap[j] + "の株価を入力してください 000で終了:"))
        if q == 000:
            break
        else:
            stock.append(q)
            labels.append(week[i] + "/" + ap[j])
    else:
        continue
    break


if len(stock) != 0:
    print(stock)
    x = range(0, 12)
    y = stock
    plt.bar(x, y, tick_label = labels) 
    plt.show()
else:
    print("終了しました")
```
FlutterがiPhoneの実機ではビルドできない人へ

<h1>iOS13.3ではビルドできないよ！！！13.4にアップデートしましょう！！</h1>

<p>僕の伝えたいことはこれだけです。</p>
<p>謎のエラーにflutterでアプリ開発し始めた瞬間思いっきり出鼻を挫かれましたが、久々に触ってみて、iOSをアップデートしたら直りました。</p>
<p>しっかりstackoverflowか何かでアップデートに伴うバグはチェックしましょう、、、（自戒）</p>

<h3>その他注意点</h3>
Xcodeの設定を忘れずにしましょう。
<ul>
<li>Signing & CapabilityでTeamを設定すること</li>
<li>BundleIDの設定</li>
</ul>
など。

・BundleIDの設定についてのメモ
アプリのBundleIDとそれが含めるbundleのBundleIDが一致しているよ（？）みたいなエラーが出た時はそれらのBundleIDを異なるものにしたら直りました。（雑すぎてすみません）

<p>リクエストがあればできるかぎり詳しく書いていこうと思います！！</p>
FlaskとDBでwebアプリ（参考にしたサイト）

#5段階の方
##DB等の準備
[Flask + SQLAlchemyプロジェクトを始める手順](https://qiita.com/shirakiya/items/0114d51e9c189658002e)
##DBに入力
[Flask+SQLiteで5分でWebアプリ開発](https://creepfablic.site/2019/05/03/flask-sqlite/)
[Python3 の 定番ORM 「 SQLAlchemy 」で MySQL ・ SQLite 等を操作 – 導入からサンプルコード](https://it-engineer-lab.com/archives/1183#INSERT)

##DBから出力
[はじめての Flask #4 ~データベースをSQLAlchemyでいじってみよう~](https://qiita.com/nagataaaas/items/5c7c9ec4813fea85c40c)
##ログイン等
###flask-login以外
[Visual StudioとFlaskで作る書籍管理アプリ：ログイン機能の実装](https://logics-of-blue.com/visual-studio-flask-book-management-login/)
###flask-login
[Flask-Login](https://flask-login.readthedocs.io/en/latest/)
[Flask-Login の使い方【アカウント作成・ログイン・ログアウト】](https://hayatoise.com/how-to-use-flask-login/)
→MariaDBを使っている。
[初心者向け : Flaskログイン機能をつけてQAサイトを作る 1 -ログイン機能+質問機能-](https://masahiro.me/2019/09/flask-login-qustions/#outline__0_5)
↑おすすめ
[Creating a Login Page in Flask Using Sessions [2020]（Youtube）](https://youtu.be/2Zz97NVbH0U)
[↑github](https://github.com/PrettyPrinted/youtube_video_code/tree/master/2020/02/10/Creating%20a%20Login%20Page%20in%20Flask%20Using%20Sessions)
##UI周り
[適当おじさんの適当ブログ](https://www.subarunari.com/entry/2017/09/28/001946)
↑URLから要素を取ってくる方法がわかる
##デプロイ
###xserverを借りているのでxserver上で動かす。
[初心者でもわかる！XserverでPython実行環境を構築する方法](https://datacoach.me/series/xserver-linebot/xserver-python-flask-env/)


[エックスサーバーでPython3使ってAPI経由でWEBスクレイピングできる環境構築](https://qiita.com/n-Taro/items/b50ebe49cacda7327aa2)

```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
（enterキーを押し続ける。パスワード入力は無視でOK）
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
```

```
brew install python
brew install pipenv
pip3 install flask
```

以上でXserverの環境は整った。
[エックスサーバーでPython+Flask+MySQLの環境構築と格闘したメモ
](https://tarog.me/xserver-flask/)
→Flaskのサンプルコードがある。

xserverでのデプロイはうまく行かなかったのでherokuでのデプロイに切り替えた。
[初めてHerokuで独自ドメインを公開するあなたへ](https://qiita.com/kenjikatooo/items/07c3d911210a4ca96781)
[herokuでルートドメインを最速で設定する](https://qiita.com/kenjikatooo/items/279da72adddc2904179e)


#trello風の方
##キャッシュを残さなくする
##jsonファイルを取ってきて表示
[はじめての Flask #5 ~JSONを返すWebAPIを書こう~](https://qiita.com/nagataaaas/items/24e68a9c736aec31948e)
便利な参考サイトURL

■コーディング
・[MDN web docs](https://developer.mozilla.org/ja/docs/Web)：関数、メソッドが使用できるブラウザ（どのバージョンから）がわかる

■Oracle
・[(株)コーソルの技術情報](https://cosol.jp/knowledge/)：ORACLEエラーの詳細な情報が記載されている
fzf.vimでtagsを検索しながら色付きのpreviewを表示する

PHPでせめて定義元ぐらいは辿りたいんだけど、Language Serverが使えない、[phpcd](https://github.com/lvht/phpcd.vim)も使えない、けれど絶対Vim使うってときに、ctagsを使うことにした。他のプラグインとかで何とかなるかもしれないけど、何とかなるって情報が見つけられなかった。

仕方なくctagsでタグを作って[fzf.vim](https://github.com/junegunn/fzf.vim)でpreviewを表示させながら選びたい。

## どういうことか

こういうファイルがあって、test2()を辿りたい。

```php:caller.php
<?php

require_once './functions.php';
test2();
```

```php:functions.php
<?php

function test1()
{
    echo __FUNCTION__;
}


function test2()
{
    echo __FUNCTION__;
}

function test3()
{
    echo __FUNCTION__;
}
```


## どうするか

ひとまずctagsでtagsファイルを作っておく。

```shell
$ ls
caller.php  functions.php
$ ctags -R # 作る
$ ls
caller.php  functions.php  tags # tagsができあがる
$ cat tags # tagsの中身
!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME	Exuberant Ctags	//
!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
!_TAG_PROGRAM_VERSION	5.8	//
test1	functions.php	/^function test1()$/;"	f
test2	functions.php	/^function test2()$/;"	f
test3	functions.php	/^function test3()$/;"	f
```

## 設定

fzf.vimはpreviewを外部から受け取れる。今回はshellScriptを一つ作って、previewに渡す。

```shell:/path/to/ctags_preview.sh
#!/usr/bin/env zsh

NAME=$1
FILE=$2

 #タブに囲まれた3つめの検索パターンの抽出
 #/^ any $/;" を ^ any $ に置換
PATTERN=$(echo $3 | cut -f 3 | sed "s/^\///" | sed -E "s/\/;\".*$//" | sed "s/\"/\\\\\"/g")

# 前5行、後5行を表示、-48でgrepしてるのは検索文字列に色をつけるため
grep -B 5 -A 42 --color=never "${PATTERN}" $FILE | grep -48 --color=always $NAME
```

で、~/.vimrcに以下を書き込む。

```vimscript:~/.vimrcか他のconfig
command! -bang Tags
  \ call fzf#vim#tags(expand('<cword>'), {
  \     'options': '+i
  \                 --exact
  \                 --with-nth 1
  \                 --reverse
  \                 --no-unicode
  \                 --preview "/path/to/ctags_preview.sh {1} {2} {}"
  \                     '
  \ })

nnoremap <silent> <Leader>ft :<C-u>Tags<CR>
```

## こうなる

caller.phpのtest2の上で、<Leader>ftを押すと、下記のようなプレビューが表示される。（floating windowにしてある）

<img width="823" alt="スクリーンショット 2020-04-09 1.10.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146958/7f77395a-dd21-446c-39d1-fc4fbe848381.png">

まぁ……全然完全ではないんだけど……。
メディアサイトにおいてよくある動きはAMPで実装できるのか調査

# AMP

Webサイトにおいてよくある動きはAMPで実装できるのか調査しました。

## スムーススクロール
ページ内リンクで遷移する際にゆっくりとスクロールできるかどうか。
目次でよく使われる。

結論：実装できる

記述方法

```html:
<button on="tap:target.scrollTo">クリックで移動</button>

<div id="target"></div>
```

補足

スクロール先の位置を指定できるが、３パターンしかない。
デフォルトではtop, その他にcenter, bottomが存在する。

```html:
<button on="tap:target.scrollTo('position' = 'center')">クリックで移動</button>
```

![画面収録-2020-04-08-23.17.59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/d7fb9dda-e697-7c47-0782-a2367f11f7fa.gif)

https://github.com/ampproject/amphtml/blob/master/spec/amp-actions-and-events.md

## ハンバーガーメニュー

結論：基本的にはできるが、AMPコンポーネントで用意されていない動きだと実装コストがかかりそう

AMPコンポーネントで用意されている動きは、右から、または左からメニューが出てくる動き。
その他の動きを作る場合は、
`amp-bind`でclassの追加/削除をして実装？

```html:
<amp-sidebar id="sidebar"
  layout="nodisplay"
  side="right">
  <h3>Sidebar</h3>
  <div></div>
  <button on="tap:sidebar.toggle">close</button>
</amp-sidebar>

<button class="sidebar" on="tap:sidebar.toggle">
  <span class="sidebar-line"></span>
  <span class="sidebar-line"></span>
  <span class="sidebar-line"></span>
</button>
```

![画面収録-2020-04-09-0.15.08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/e74a61be-02dd-608f-cea9-89866187103d.gif)


## 横スライダー

結論：できる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/20a0794c-f686-e99d-821b-2a5b7697203d.gif" width="460">


![画面収録-2020-04-09-0.57.56_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/f1e2064a-3625-9bf6-7705-4864470266d7.gif)

```css:
.card-list {
  display: flex;
  overflow-x: scroll;
  padding: 0 10px 0 20px
}
.card {
  list-style: none;
  height: 230px;
  min-width: 143px;
  max-width: 143px;
  background-color: #858585;
}
.card + .card {
  margin-left: 10px;
}
```

```html:
<ul class="card-list">
  <li class="card">
    記事
  </li>
  <li class="card">
    記事
  </li>
  <li class="card">
    記事
  </li>
  <li class="card">
    記事
  </li>
  <li class="card">
    記事
  </li>
  <li class="card">
    記事
  </li>
</ul>
```


## モーダル

https://amp.dev/documentation/examples/components/amp-image-lightbox/?format=websites

また、CSSのみでモーダルを作る方法で、作成可能。

https://digipress.info/tech/simple-modal-window/


## アコーディオン

https://amp.dev/ja/documentation/components/amp-accordion/　　　　


##  タブ切り替え
https://amp.dev/documentation/examples/style-layout/tab_panels_with_amp-selector/preview/?format=websites
環境変数に空文字``を設定する

コンバンワ、今日も相変わらずembulkのお世話になっていたプレイライフの[合原](https://qiita.com/kieaiaarh)です。

ちょびっと気づきがあったので、tips的な記事を。

※話をスコープしたいので、[embulk](https://www.google.com/search?q=embulk&oq=embulk&aqs=chrome.0.69i59l4j69i60l3j69i65.2226j0j7&sourceid=chrome&ie=UTF-8)で自体の説明は割愛します。


# embulkでは環境変数が使える


みんな大好きバルクデータローダ[embulk](https://www.google.com/search?q=embulk&oq=embulk&aqs=chrome.0.69i59l4j69i60l3j69i65.2226j0j7&sourceid=chrome&ie=UTF-8)では、環境変数を使って、（例えば環境に応じて等）値を設定することができます。
[Rails環境下でembulkを使って快適に数十万件のデータを取り込む](https://qiita.com/play-life/items/c194405512c4cc0fcbdd#rails%E7%92%B0%E5%A2%83%E4%B8%8B%E3%81%A7%E4%BD%BF%E3%81%86embulk%E3%81%AE%E6%A7%8B%E6%88%90)とか読んでいただけますと雰囲気がわかるかと思います。

例えば、


```sh
export DB_HOST=127.0.0.1
export DB_NAME='db'
export DB_USER=db_user
export DB_PASSWORD="hogehoge"
```

とあると、これを、

```yml
#
out:
  type: mysql
  host: {{ env.DB_HOST }}
  database: {{ env.DB_NAME }}
  user: {{ env.DB_USER }}
  password: {{ env.DB_PASSWORD }}
  table: target_table
   :
```

と言った具合に参照できるようになります。

# 環境変数に''を設定するには？
ローカル環境で開発する際など、よくDBのパスワードを`''`にしているケースはあるかと思います。

```sh
export DB_PASSWORD=""

```
```sh
export DB_PASSWORD=''
```

上記の二つは、いずれも未定義状態になってしまいます。
答えは、

```sh
export DB_PASSWORD="''"
```

一応、確かめてみると...

```
$ HOGE=""                                                                                   
$ echo $HOGE

$ HOGE=''"
$ echo $HOGE

$ HOGE="''" 
$ echo $HOGE                                                                               
''　　　　　　　
```

... というわけで、

```yml
  password: {% if env.RAILS_ENV == 'development' %} '' {% else %}{{ env.DB_PASSWORD }}{% endif %}
```
というようなことをする必要はなく、

```yml
  password: {{ env.DB_PASSWORD }}
```

で済みます。

以上。