OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxあるある。

今日はLinuxのあるあるについて書いてみようと思います。
 [Linux Advent Calendar 2020](https://qiita.com/advent-calendar/2020/linux "Linux Advent Calendar 2020")２１日目です。

なんか調子悪くてさっきまで寝てました。
やっと食事してきたところです。

Linuxあるあるなんですが。
これ以外とRHES系におおいんですよね。
#最新版のスクリプト言語がない
これ一番困りました。
PHP７で組みたくてもPHP5系しかなかったり。
リポジトリ追加しまくったり。
挙句の果てに入れたものがコンフリクトして動かなかったり。
これがひどかったのはAmazonLinuxでした。
あれは一番最悪で古いものが安定して動くと思っている典型的なLinuxディストリビューションでした。
それがいやだからRHESをやめたわけではないんです。
#ハード系はUbuntuが一般的。
これなんですよ。
自分がRHESをやめUbuntuに移行したのは。
実は当時カーエレクトロニクス系のLinuxのビルドを担当していたんですが。
YoctoがじつはUbuntuしか動かなかったんですね。
やもなくUbuntuを学ぶことになったんですが。
これが実は好天気になりました。
#Ubuntu最高
正直言わせてもらうとUbuntuってコマンドでもGUIでも軽いんです。
VM環境もUbuntu歯科用意されていなかったのも切り替えの転機でした。
正直リポジトリーの追加の山と格闘するのに疲れ果てていた自分はこの機を逃さず移行いちゃいました。
いまはUbuntuのほうが楽ですね。
組みやすいしいろんなことできるし新しいものも手に入るしWindowsやMacで動いている開発ソフトの大半が動きます。
しかもGUIで。
#これからのLinuxは
正直言うとLinusの体調が心配なのといろんなことにやつれきっているように見受けられます。
正直トランプがここまで追い込んだんだからちょっと可愛そうな気がします。
これほどの開発者が移民騒動に巻き込まれるなんて論外です。
しかもアメリカや色んな国の大半のスーパーコンピュータや陽子コンピュータのOSってLinuxが多いって知ってますか。
これを潰そうとしたトランプには処罰があっていいと思っています。
多くのアメリカのIT企業で働く日本人たちも困ってたみたいです。
次の政権にはもうこんな思いをしないように心がけてもらいたいもんです。
Linuxがまた再びLinusとともにあらんことを。

なんか疲れてきたので今日はここまで。

明日は [takeshi_se_tenshoku](https://qiita.com/takeshi_se_tenshoku "takeshi_se_tenshoku")さんです。
何を書いてくれるんでしょう。
楽しみ。
だけど殆どのアドベンドカレンダー読めてない(泣)。
Pipenv環境でVSCodeのデバッグ時にModuleNotFoundErrorになる

VSCodeのバージョンが1.51時点での解決法です。バージョンによって解決法が異なるようで、情報がすぐ古くなる可能性があります。ご注意ください。

結論から言うと、インタプリタの指定をしましょう。

## Moduleのインポートに失敗する
![ModuleNotFoundError.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/812f6747-602f-21da-73b9-bc4dbcd4c093.png)

左下のPythonの指定はbrewでインストールしたpython3.9です。aws関連のcli入れるとどうしても入ってしまって、指定されてしまっているようです。

## インタプリタの指定
pipenvのvirtualenv環境のpythonを指定する必要があります。まずは、virtualenv環境のPathを確認します。

```shell
$ pipenv --venv
/Users/xxx/.local/share/virtualenvs/xxxx
```

左下のPythonのバージョン表記部分をクリックしてインタプリタの指定を行います。
![Interpreter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/07734c06-22d6-4b11-ee06-6c56d76d3186.png)

これで問題なくデバッグできます！
![Debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/6fd95c60-27ed-0f67-4e67-d942ea29e45c.png)

## おわりに
普段はWebアプリケーションの環境でDockerを使っています。Docker環境はまだプレビューですが、Remote - Containersの拡張を使って開発しています。かなり便利で気に入っています :blush: 
今回の場合は扱うファイルサイズが大きいため、Pipenvの環境で開発を行いました。npmに慣れているので非常に使いやすいです。
AWSのElemental MediaConvertを使ってみた

動画配信系のWebサイト作ろうと思ったときようにメモ程度に

#AWS MediaConvertとは

S3に置いた動画ファイルをストリーミング形式に変換してくれるサービス。
例) .mp4形式の動画ファイル　→　.hls形式に変換



###用意するもの

動画を配置するS3バケット
変換された動画を配置するS3バケット
MediaConvert用のIAMロール
動画ファイル


###やること

大きく分けて３ステップ

1.MediaConvertを利用する準備(IAMロール作成&S3バケット作成)
2.MediaConvertでジョブテンプレートを作成
3.MediaConvertでジョブテンプレートからジョブを作成＆実行



##ステップ１：MediaConvertを利用する準備(IAMロール作成&S3バケット作成)

a. S3バケットを作成
   └ 動画を配置するS3バケット
   └ 変換された動画を配置するS3バケット

b. [動画を配置するS3バケット]に動画ファイルを配置する。

c. MediaConvert用のIAMロール作成

IAMからロールを作成する。
ポリシーはテンプレートをそのまま使用する。
　

##ステップ２：MediaConvertでジョブテンプレートを作成
MediaConvertのコンソールからジョブテンプレートを作成する。
![スクリーンショット 2020-12-21 22.03.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745880/51246ce7-b065-2fdd-84ad-9d7cb7cd7846.png)

名前をつける。
![スクリーンショット 2020-12-21 22.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745880/bdad3d97-9038-713c-76c3-b85bada6cecc.png)

入力はそのままにする。
![スクリーンショット 2020-12-21 22.04.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745880/14c231d4-e7b5-6b29-a939-1cb34865bec1.png)

出力グループを追加する。(写真ではファイルグループを選択)
![スクリーンショット 2020-12-21 22.04.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745880/890d98ab-d2f3-020b-cfbd-e66b1d545826.png)


設定値を入力する。
![スクリーンショット 2020-12-21 22.19.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745880/ec2132b9-34e7-2264-e4a3-a67ba295b8a2.png)

設定値は以下の通り。

解像度：1280*720
フレームレート：30/1
ビットレート(ビット/秒)：1000000

作成ボタンを押すとジョブテンプレートが作成される。
　

##ステップ３：MediaConvertでジョブテンプレートからジョブを作成＆実行

作成したジョブテンプレートを選択し、ジョブを作成する。
設定値は以下の通り。

入力グループ
入力ファイル URL：　[動画を配置するS3バケット]/[動画ファイル]

出力グループ
送信先：[変換された動画を配置するS3バケット]

AWS の統合
IAM ロール：[MediaConvert用のIAMロール]

作成ボタンを押すとジョブが作成され、実行される。


[変換された動画を配置するS3バケット]を確認すると返還された動画ファイルが配置されている。


##まとめ
変換された動画ファイルはCloudFront経由で公開できそう。
ジョブ作成の自動化はLambdaで実現できそう。
「No file/folder found for package ***」のエラー解消方法

# はじめに
個人的な備忘録としてのメモです。

# 問題点
`poetry add package名`とした時にたまに `No file/folder found for package`というエラーが発生することがあります。  
たまにというか、自作ライブラリを `poetry add "git+ssh://git@github.com/ijfumi/****`とした時に発生したりします。  

これはエラー文言にもある通り、「パッケージがないよ！」ってことなのですが、大体以下のようなディレクトリ階層になっていたりします。

```
mypackage
  ┣ data/
  ┣ config/
  ┣ main.py  
  ┣ services/
    ┣ __init__.py
    ┣ aaa_service.py  
    ┗ bbb_service.py
  ┣ poetry.lock
  ┣ pyproject.toml
  ┗ README.md
```

`service` ってディレクトリあるじゃん？って、思う方もいるのかなと思います（実際、私はそうでした）

# 解決策
`poetry` に限らず、 `pip`でもインストールしたいパッケージと同じ名前のディレクトリがルートディレクトリにあり、
そこに各処理のコードが格納されている必要があるのです。

例えば、以下のような階層です。

```
mypackage
  ┣ data/
  ┣ config/
  ┣ main.py  
  ┣ mypackage/
    ┣ services/
      ┣ __init__.py
      ┣ aaa_service.py  
      ┗ bbb_service.py
  ┣ poetry.lock
  ┣ pyproject.toml
  ┗ README.md
```

問題点のとこで記述していた階層を、上記の様に変更することができれば問題解決します。

もし階層が変更できない場合でも `pyproject.toml` に以下の記述を追加するだけで、解決します。

```
packages = [
    { include = "services" }
]
```

ただ、この方法は `extra `なディレクトリを追加する方法なので、できれば階層変更の方が良いのかなと思います。

[pyproject.toml#package](https://python-poetry.org/docs/pyproject/#packages)

# おわりに
記載内容について、誤記や漏れなどありましたら適宜コメント頂けると幸いです。
Azure Functions で MeCab を使ってみた！

この記事は、[求ム！Pythonを使ってAzureで開発する時のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-python) の 3 日目です（後から追っかけで書いています）。

----
機械学習の自然言語処理（文章解析）をしていると活躍するのが Mecab です。機械学習以外でも MeCab を利用して簡単な自然言語処理（形態素解析とか）をしたいときがあります。

機械学習モデルとして構築するとファットなので、Function として実装し、色々なところ（サービスやシステム）から呼び出すことを想定しています。

Azure Functions は Python に対応しているし、機械学習のように重たい処理を行わなければ（＝Mecab で形態素解析する程度）Azure Functions で動くだろうという推測に基づいて作りました。

結論から書くと、実装もでき、動作しました。

が、自分（だけ？）のハマりだったのは

**Mecab を使うなら requirements.txt に記載する必要がある**

という点です。

かなり長時間ハマったので、これを読んだみなさん（？）は[こちら](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python?WT.mc_id=AZ-MVP-5001601#publishing-to-azure)をご覧になって用量、用法を守って正しくお使いください。

**4 日目は @changeworld の「[これからデータ分析するなら Data Science Virtual Machines が最高の環境！](https://qiita.com/changeworld/items/1755e35d2be3098b84fa)」です。引き続きお楽しみください。**
【FileMaker】「げんきかな？チェック」アプリ解説 3 - ほぼ決まっている値の入力はタップせよ

「げんきかな？チェック」というサンプルアプリを自粛中に作っていたのですが、その解説シリーズ第３弾です。

[【FileMaker】「げんきかな？チェック」アプリ解説 1 - 概要と画面遷移](https://qiita.com/tyuma/items/7921fe1a6f55c603977c)
[【FileMaker】「げんきかな？チェック」アプリ解説 2 - ボタンでスワイプを擬似再現](https://qiita.com/tyuma/items/8e7ad8e33f7efc8e9566)

今回は、このアプリで実装した体温計の数字入力についてです。

# 動き
まずは、こんな動きを。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日はこれ^_^<a href="https://twitter.com/hashtag/FileMaker?src=hash&amp;ref_src=twsrc%5Etfw">#FileMaker</a> <a href="https://twitter.com/hashtag/filemakergo?src=hash&amp;ref_src=twsrc%5Etfw">#filemakergo</a> <a href="https://t.co/Zpv97g0HRS">pic.twitter.com/Zpv97g0HRS</a></p>&mdash; Guppy Web Service (@GuppyWebService) <a href="https://twitter.com/GuppyWebService/status/1341012042908540929?ref_src=twsrc%5Etfw">December 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

体温計の数字を入力するのに、最初テンキーなどで入力するのではなく、体温計に表示されている数字と同じ数字をタップして入力支援を行う、という感じです。
この実装理由は、「見たまま」わかるのがおおよそ幼稚園や保育園年少さん以上かな、と想定したためです。

# 実装方法
今回のはタップした数字を引数にスクリプトを実行しています。
数字をセットするだけなら一行野郎でも問題ないのですが、今回はポップアップボタンで実装しているので、入力が終わったらポップオーバーを閉じる実装も追加しています。
![スクリーンショット 2020-12-21 21.56.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/561523e5-dc1d-3413-2967-47a001f2eb91.png)

タップする選択肢がない場合も考え、数字でも入力できるようにしました。
この範囲の体温を外れるって、よっぽどだと思いますが。。。
![スクリーンショット 2020-12-21 21.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/d006de81-ff80-b6c1-e8fb-033ac5c24454.png)
ここでは、FileMaker Goで実行することを想定してタッチキーボードタイプを数字10キー（テンキー）にしています。
不要な入力を避けるために、数字テンキーにしています。
このほうが入力に迷わないですしね。

# タブレットを意識する
タブレットというキーボードレスの環境を想定して実装するのがFileMaker Goで常に考えることだと思ってます。
なるべくならタップや音声入力で済ませること。
ただし、必要に応じてタップや音声入力ができない（難しい）場合も想定して最低限のキーボード表示に済ませること。
などを意識しておくとタブレットでヒュンヒュン出て画面を占領されてしまうキーボードに悩まされないと思います。
仕事を楽しむコツ

仕事を楽しむコツ

「楽しそうに仕事しますね。」と言われたことがあります。その時はよくわからなかったのですが、どうも私は知らず知らずのうちに仕事を楽しんでいるようです。

ソフトウェア開発には色々と大変なこともあるのですが、仕事を楽しむための工夫をしているのかもしれません。今回はそんなことを書いてみたいと思います。

# 楽をする
## そもそもコンピュータは楽をするためのもの
コンピュータの始まりは大陸間弾道弾の計算だそうで、面倒な軌道計算をまかせる目的だったようです。

「紺屋の白袴（こんや(こうや)のしろばかま）」という言葉がありますが、目の前に計算機があるのに、ツールを使わずに肉体労働化してしまうエンジニアが意外と多いので、グレーカラーとかIT土方とか言われちゃうんですよね。

世の中には色々なツールや手法があるので、使えるときにはどんどん使って楽をしましょう。

## どっちが楽か合理的に考える
使えそうなツールでも、メリットだけでなくデメリットもあります。今までの手作業による開発方法をやめることがデメリットになってしまいます。具体的には、

* ツールを学ぶ必要がある
* ツールが使えなくなると作業ができなくなる（依存する）
* 他の人でも使えるように最低限の導入手順や利用方法を残す必要がある
* 見積もり誤差があるので期待する効率化ができるとは限らない
* 効率化されると仕事が減って達成感がない
* 慣れていないので何となく不安でストレスを感じる、など

色々考えると、効率化のメリットがすぐに出ないと感じるかもしれません。でも、ツールを入れて入れなくても効率が変わらないなら、何か問題が起きたり、同じような仕事をする場合、上記のデメリットはほとんどなくなり、ツール化のメリットが感じられるでしょう。これは、リファクタリングやテスト自動化の導入と同じですね。

面倒な仕事を終えると大きな達成感を感じるでしょうし、慣れた作業は安心感があります。しかし、新しい知見や効率化され対応力のある未来は訪れません。将来も含めてどの方法のリスクが少ないか、合理的に考えてください。

## 恥ずかしがらずに聞く
後輩や部下ができると成長が止まる人がいます。「若い子に聞けないでしょう」という人です。同じプロジェクトの仲間なのだから恥ずかしがらずに聞けばよいと思います。聞くことを恥ずかしがる人は、若い人の知識が得られないので出世するうちに時代遅れになってしまいます。

大学の先生を見ていると、大先生ほど定義を大事にされるので、基本的なことほど確認されます。中途半端に理解するのではなく、説明できるレベルの知識とそれ以外を明確に分けられるからこそ、多くの知識を蓄えて適切な判断や推論ができるのだと思います。

# プロセスプログラミング

ソフトウェア開発をどう進めるか、それはプログラミングと変わりません。正常処理だけでなく、あらかじめ予想される例外をどのように扱うか、対策を考えないといけません。

## 時間だけは戻らない

プログラムの出来が悪い時、処理が途中で終わってしまい、プログラムを書き換えて処理をやり直さないといけません。

仕事も同じです。「段取り八分」というように、仕事の成否は段取りでほとんど決まります。何も考えず、簡単なところから手をすけたり、決定が遅れているからと問題解決を図らないまま、適当に別の作業をしておくなどという進め方は、徐々に問題を大きくします。

時間は戻ることがありません。しっかりと作戦を練ってから作業を進めましょう。

## 期待しない

複数人で開発する場合はインタフェースを決めて開発しますが、いざ結合すると動かないことがあります。プログラミングでも思い込みでライブラリを使うとよく起きることです。

テストしていないというのは論外ですが、テストしていても仕様の理解不足や勘違い、厳密でなかったので別の解釈をしていたなんてことがあります。「現地現物」というように実物で確認して、早めに小さく失敗しましょう。

実物がすぐに確認できないなら、情報を集めるしかありません。どんなテストをしたか？する予定か？細かなところはどう認識しているか？ストレートに聞くと良いでしょう。高圧的にではなく、自分も間違える可能性のあることを踏まえると良い関係が築けるでしょう。

## 先に手を打て
「段取り」と言っても色々あってキリがない。そう思われるかもしれません。でも、2割8割の法則あるいはパレートの法則と呼ばれるように、多くの問題は一部に集中することが多く、そこを狙います。

発生しそうな問題をリスクと呼びますが、リスクの定義は、発生確率×影響度です。この積を踏まえて、どのリスクを避けるか、下げるか、保険をかけるか、あきらめるか、を判断します。

リスクは時々刻々と変化します。問題のありそうなところは早めに検討ましょう。技術的な検討をすませて仕様を早く決定した方が良い場合が多いですが、関連する仕様が変わる場合などでは、ぎりぎりまで変更できるようにした方が良い場合があります。

# 気の持ちよう

同じ問題に直面しても、楽しめる人とそうでない人がいます。

## 義務感より責任感

世の中には難しい問題があります。暗号でも使われる素因数分解などは簡単に解けません。難しい問題が簡単に解けないのは担当者の問題ではなく、問題が難しいから時間がかかるのです。

責任感の強い人には、難しい問題を抱え込んでつぶれる人もいます。でも、責任をもって問題を把握して、難しいことは難しい、時間がかかるときは時間がかかる、できない時はできないということが責任ある行動です。解決策が考えられるに越したことはありませんが、問題を共有して仲間や上司を頼ることが必要な時もあります。

## プロジェクトのゴールを考える

やりたいことややりたい方法がある人も苦しみがちです。別の開発ではうまくいくことでも、今のプロジェクトやそのメンバーでうまくいくかを考えてください。

プロジェクトのゴールを考えると、自分の気持ちがどうでもよくなってきます。今やりたいことよりも、やらないといけないことの実践がプロジェクトを成功させます。目標に向かって集中したなら、その達成感はとても大きく、その喜びはみんなで分かち合えます。

## トラブルを楽しむ

進んでトラブルに巻き込まれる必要はありますが、トラブルに巻き込まれたならめったにない機会を楽しみましょう。上に書いたように問題の多くは集中していますから、冷静になって問題点を見極めましょう。

難しい問題ならできなくて当たり前、少しでもよくできたなら大きな成果です。新しい問題で経験したことは、これまでにない知識と経験を与えてくれるでしょう。

身体を壊してまで達成しないといけない仕事はありません。計画通りではないかもしれませんが、問題のない範囲でうまく対処できたなら、それは成功と言えるでしょう。

# まとめ

坂本龍馬好きの私は、合理的な発想が好きです。達成感とか自己犠牲、あるいは立場、など判断に関わりそうなことはわがままだと思います。トータルでどっちが楽かという合理的な考え方が仕事を楽にします。

頑張るという言葉の語源の一説に「我を張る」が転じたという説があります。自分で頑張っていると思っていても、合理的な判断から外れていればそれは、我を張っているのではないでしょうか？

あなたが楽になる判断をすることが、仕事を楽しむコツだと思います。
ブラウザのアドレスバーにnode情報を直入力してブロック高を確認する

# 概要
ブラウザにnode情報を直入力してブロック高を得ます。
これでスナップショットまでどれくらいかなーとか確認できます。

# 方法

https://nemnodes.org/nodes/
ここからNIS1のnode情報を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/b2ad2e5a-dc52-aec3-6958-ff751d7cc06b.png)

ブラウザに
http://{NIS1 Node}:{Port}/chain/height
と打ち込むことで現在のブロック高を確認できるのですが、この例では

http\://47.88.230.169:7890/chain/height
となります。

以下実行例です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/19b999d9-901f-e863-8046-d1ac943c7101.png)

スナップショットのブロック高は「3025200」なので、
この数値になるのを楽しみに時折実行してみても良いかもしれません。

ちなみに、NIS1のnode情報ページの最上部にこれと同じ情報が表示されていますので
特段これを実行する必要は無いです。
無駄に負荷をかけるのは控えましょう。


# [2020/12/24 11:35追記]

※ 高負荷祭は中止になりました
https://twitter.com/NemtusOfficial/status/1341917487219109888
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/4c6afd24-4615-7b1c-0fba-4ef7b3b0e735.png)


~~いや、私はど～してもnodeに負荷をかけてみたいんだ！という方は超負荷祭りにご参加ください。
負荷をかけて感謝されるという滅多にないチャンスですよ～
https\://twitter.com/NemtusOfficial/status/1338311779990925312~~
【React】navigator.mediaDevicesでnavigator is not definedとなった時の対処法

## はじめに
Reactでリロード時に接続可能のデバイスにアクセスしたいとき、コンポーネント内で`navigator.mediaDevices.enumerateDevices()`を使用した時、

```
(node:13144) UnhandledPromiseRejectionWarning: ReferenceError: navigator is not defined
......
```
と出てきて少しハマったので解決した方法を共有したいと思います。

### navigatorとは
[公式ドキュメント]('https://developer.mozilla.org/ja/docs/Web/API/Navigator')を参考にすると
>Navigator インターフェイスは、ユーザーエージェントの状態や身元情報を表します。スクリプトからその情報を問い合わる、および活動を続けるためにそれら自体を登録することができます。


## TL;DR

- 原因はコンポーネント直下でnavigatorを呼び出していることだった。
- 解決法はuseEffect内でnavigatorを実行すれば良い。

## useEffectの処理の走るタイミングを知る
元々僕がやっていたコードは以下でした。（以下は間違いコードです。真似しないでください。）

```react
//間違えコード
const Index: React.FC = () => {
  navigator.mediaDevices.enumerateDevices().then((devices) => {
    devices.map((device) => {
      //取得できたdeviceを使ってリスト形式に表示させたかった。
    });
  });
  return (
    <ul>
      {/*取得できたdeviceをここでリスト表示させたい。*/}
    </ul>
  );
}
```

以上のコードだと、Indexコンポーネントがレンダリングされると同時のタイミングでnavigatorが呼び出され、処理がされてしまいます。

navigatorはユーザーエージェントの状態や身元情報を取得するので、まだレンダリングのタイミングではそれらの情報が取って来れなかったために`navigator is not defined`エラーが出てしまったのだと考えました。

### useEffectを復讐
今までの僕の勝手なuseEffectの認識（第二引数になにも入っていないデフォルトの状態）は

>useEffectはただ画面をリロードするタイミングで処理がされるものなんでしょ！

とあまり深く考えずに認識してしまっていたので、今回のこの件で再確認することができました。
useEffectは、改めて公式ページを確認したところ、

>useEffect は毎回のレンダー後に呼ばれるのか？ その通りです！ デフォルトでは、副作用関数は初回のレンダー時および毎回の更新時に呼び出されます。

以上のようにコンポーネントのレンダリングが完了後に実行される物でした。

よって、最終的なコードは以下のようになりました。

```react
//正解コード
const Index: React.FC = () => {

  {/*useEffect追加*/}
  useEffect(() => {
    navigator.mediaDevices.enumerateDevices().then((devices) => {
      devices.map((device) => {
        //取得できたdeviceを使ってリスト形式に表示させたかった。
      });
    });
  });
  
  return (
    <ul>
      {/*取得できたdeviceをここでリスト表示させたい。*/}
    </ul>
  );
}
```

これでコンポーネントがレンダリングされた後にnavigatorを実行してあげることで値を取得することができ、エラーを解決することができました。


他により良い方法があれば教えていただけたら嬉しいです。

## 参考ページ
- https://developer.mozilla.org/ja/docs/Web/API/Navigator
- https://ja.reactjs.org/docs/hooks-effect.html
git でサブディレクトリのみの変更履歴とファイルを取り出す

git subtree split でできる

```
$ git subtree split -P サブディレクトリ -b ブランチ名
$ git switch ブランチ名
$ ls
サブディレクトリのファイルしかない
$ git log
サブディレクトリの変更履歴しかない
```
Cluster Creator Kitで実装した機能を逆引きで説明する

##はじめに
先日オンラインで行われた[ClusterGAMEJAM2020 in WINTER](https://www.contest.cluster.mu/)に参加しました。
その際に実装した機能を逆引きでまとめます。

<img width="700" alt="Title" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/d8db8780-c8b2-aea6-6929-dc7b6243d3f2.png">

https://cluster.mu/w/fe97464b-e8ed-4edf-8fd1-dd472b1991f7
よかったらプレイしてみてください。

##↓↓機能を逆引きで説明します。↓↓

**①オブジェクト生成時に効果音（SE）を鳴らしたい！**
**②召喚したモンスターのHPを設定したい**
**③発射するボールの所持数を動的に増やす**
**④アバターの移動速度を速くする**
**⑤プレハブをランダムの位置に生成する**

###①オブジェクト生成時に効果音（SE）を鳴らしたい！
オブジェクト生成時、PlayAudioSourceGimmickを通じて音を再生します。
![Oncreateitemtrigger1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/b1a42a5b-32e4-fe9a-5d89-cf672a35dc2c.png)
**OnCreateItemTrigger**
→TargetをGlobal
→Keyを設定
**PlayAudioSourceGimmick**
→OnCreateItemTriggerで設定したKeyをKeyへ設定

###②召喚したモンスターのHPを設定したい
オブジェクト生成時、HPを100の状態となる
![Oncreateitemtrigger2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/c5e2277e-216c-a93e-cc77-f9407f36a1bf.png)
**OnCreateItemTrigger**
→TargetをGlobal（外部からHPを減らす可能性があるため）
→ParameterTypeをIntegerに設定（floatも設定できる）
→IntegerValueを100に設定

###③発射するボールの所持数を動的に増やす
オブジェクトをクリックすると、ボールの所持数が1ずつ増えていきます。
![Oncreateitemtrigger3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/ea20dc27-39ad-2ce2-0a43-0742394bd8f5.png)
**InteractItemTrigger**
→TargetをGlobalに設定
→Keyを設定

**GlobalLogic**
BallCount（Integer）に、1ずつ足していくように設定
＊事前にGlobalでボールの所持数（BallCount）を作っておく

###④アバターの移動速度を速くする
ワールド入場時、アバターの速度が10早くなります。
![Oncreateitemtrigger4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/35c05dea-3937-397d-4ce0-f4b134b477d0.png)
**OnCreateItemTrigger**
→TargetをGlobalに設定
→Keyを設定
→ParameterTypeをFloatに設定（設定できる速度がFloatのため）
→FloatValueを10に設定（高いほど早くなる）

**SetMoveSpeedRatePlayerGimmick**
→TargetをGlobalに設定
→OnCreateItemTriggerで設定したKeyをKeyへ設定

###⑤プレハブをランダムの位置に生成する
ワールド入場時、ランダムの場所に指定した数のオブジェクトを生成する
![rand4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/7307d091-c16f-26c1-0a0e-8a3c6c28e321.png)
**OnCreateItemmTrigger**
→TargetをGlobalに設定
→Keyを設定

![rand1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/0d881c63-0f89-f49f-0c5a-ad34e3f13dc0.png)
**ItemTriggerLottery（生成する複数の場所のオブジェクトを設定）**
→Weightを1に設定（重み）×3
→Target、Keyを設定×3

![rand2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/7d0e4a25-3bd0-7ce8-d87a-5336edc7a6a8.png)
**ItemLogic**
→Keyを設定
→BlockCountが0以上の時にRandomGenerateを発火するように設定

![rand3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/1d7a826e-1901-9ec2-c679-359376828612.png)
**CreateItemGimmick**
→ItemTriggerLotteryで設定したKeyをそれぞれのKeyに設定
→ItemTempleteに生成するプレハブを設定
→SpaawnPointに生成する位置を設定

生成する位置は下記のような配置にしました。
![rand5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/08c49e30-6e3d-a924-9cb0-7136e2e17f68.png)

##おわりに
Cluster Creator Kit の機能の逆引きが増えれば、初心者でも実装が容易になりそうですね！
今後も機会があればワールドを作りたいです。

##参考
https://www.contest.cluster.mu/
Ubuntuを入れたら自分がやること

1.コンソールを英語化
https://motomichi-works.hatenablog.com/entry/2018/09/28/233228
2.ディレクトリの英語化
https://qiita.com/RayDoe/items/ea945a3b6583d5c01d1e
3.chromeをインストール
https://www.google.com/chrome/?hl=ja
4.tweaksを入れる

```
sudo apt install gnome-tweak-tool
sudo apt-get install chrome-gnome-shell
```

https://linuxconfig.org/how-to-install-tweak-tool-on-ubuntu-20-04-lts-focal-fossa-linux
https://ubuntuapps.net/blog-entry-1119.html
開発者が開発に注力できる Azure Spring Cloud !

この記事は、[求ム！Cloud Nativeアプリケーション開発のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-cloudnative) の 7 日目です（後から追っかけで書いています）。

----
本記事では、「[Azure Spring Cloud](https://azure.microsoft.com/ja-jp/services/spring-cloud/?WT.mc_id=AZ-MVP-5001601)」について、ご紹介したいと思います。

## 概要 & クイックスタート

[Azure Spring Cloud](https://azure.microsoft.com/ja-jp/services/spring-cloud/?WT.mc_id=AZ-MVP-5001601) はフル マネージドの Spring Cloud サービスとして、Microsoft と VMware が共同で作成した今年一般提供されたばかりのサービスです。

* [Azure Spring Cloud の一般提供を開始 | Azure の更新情報 | Microsoft Azure](https://azure.microsoft.com/ja-jp/updates/azure-spring-cloud-is-now-generally-available/?WT.mc_id=AZ-MVP-5001601)
* [Azure Spring Cloud: Spring Boot アプリのフル マネージド サービスを一般提供開始 | Azure のブログと更新プログラム | Microsoft Azure](https://azure.microsoft.com/ja-jp/blog/azure-spring-cloud-a-fully-managed-service-for-spring-boot-apps-is-now-generally-available/)

[Azure Spring Cloud](https://azure.microsoft.com/ja-jp/services/spring-cloud/?WT.mc_id=AZ-MVP-5001601) は、Spring Boot ベースのマイクロサービスのアプリケーションを動作することに最適化されたフルマネージドサービスです。

どんなものなのだろうか？と興味をもたれた方は[こちらのクイックスタート](https://docs.microsoft.com/ja-jp/azure/spring-cloud/spring-cloud-quickstart?tabs=Azure-CLI&pivots=programming-language-java&WT.mc_id=AZ-MVP-5001601) を試してみてください。

クイックスタートは一時間もかからずに終わると思うので、かかる[料金](https://azure.microsoft.com/ja-jp/pricing/details/spring-cloud/?WT.mc_id=AZ-MVP-5001601)としては約 100 円とワンコインでお釣りがきます。

## Blue-Green Deployment

Spring Boot アプリを開発してきた人からすると何が嬉しいの？と疑問に思われると思いますが、Azure Spring Cloud の一番の特徴（と私が思っているもの）は、Blue-Green Deployment の仕組みが組み込まれていることです。
※Blue-Green Deployment とは現状の本番環境（Blue）とは別に新しい本番環境（Green）を構築した後に、ロードバランサーの接続先を切り替えるなどして新しい本番環境をリリースする運用方法のことで、これによって、本番環境を停止する時間が実質ゼロになります

手順の詳細は[こちら](https://docs.microsoft.com/ja-jp/azure/spring-cloud/spring-cloud-howto-staging-environment/?WT.mc_id=AZ-MVP-5001601) になります。

実際に Spring Boot のアプリを動かしてみたところ、裏では Azure Kubernetes Service 上で動作しているように思えるのですが、Kubernetes の存在を感じさせません。

Azure Kubernetes Service はその名の通り、Kubernetes のマネージドサービスですが、構築や運用にはどうしても Kubernetes の知識が必要になり、インフラの知識がない人からすると、学習コストは低くありません。
そういう意味で、Azure Spring Cloud だと、裏で動作しているであろう Kubernetes 周りのことを気にすることなく、アプリケーションのビルドとデプロイに注力できるので、アプリ開発者には魅力的だと思います。

**8 日目は @changeworld の「[.NET 5 の移行事例 FAQ編](https://qiita.com/changeworld/items/20a69613609e37d43085)」です。引き続きお楽しみください。**
最終課題:RomanNumerals

\![macOS-11.0.1](<https://img.shields.io/badge/macOS-11.0.1-brightgreen>) \![ruby-2.6.1p33](<https://img.shields.io/badge/ruby-2.6.1p33-brightgreen>)


# はじめに

本稿はマルチスケールシミュレーションという講義の最終課題についての記事です


# 目次

1.  [課題内容](#課題内容)

2.  [課題解答](#課題解答)

3.  [参考資料](#参考)


# 課題内容

課題：[roman numerals](https://qiita.com/daddygongon/items/2d0a73a51ddab2d9da1b)

（Rubyを用いて）アラビア数字(arabic numerals)を受け取り，ローマ数字(roman numerals)を返すmethodを書きなさい


# 課題解答

つまり、以下の表の左を入力とした時、右が出てくるようにしなさいよ。ということ。。。

| アラビア数字| ローマ数字|
|-----:|:----|
| 1    | Ⅰ  |
| 4    | Ⅳ  |
| 16   | XVI |

むずそう。というかどういう規則で書かれてんねんこれ、、、

というわけで調べてみます。

> **ローマ数字**
> 
> ローマ数字(Roman Numeral)には多少のバリエーションがありますが、一般的には下記の基本規則によって表現します。
> 
> I (1)、V (5)、X (10)、L (50)、C (100)、D (500)、M (1,000)という記号(i、v、x、l、c、d、mのように、小文字も可)を使用する。上記以外の数字は、これらの記号を組み合わせ、数を加算して得られる数字で表わす。例：II (1+1=2)、VI (5+1=6)ただし、4と9およびそれらの10n倍の数字は、右の数から左の数を減算して表わす。例：IV (5-1=4)、IX (10-1=9)、XL (50-10=40)、XC (100-10=90)
> 
> 引用：[ローマ数字](https://www.asahi-net.or.jp/~ax2s-kmtn/ref/roman_num.html)

なるほど。。。

いかに実際に作ったコードを記載する。

```ruby:RomanNumerals.rb
class Roman
    attr_accessor :num
    def initialize(num=999)
	@num = num
    end

    def to_roman
	i = 0
	s = ""
	old = @num
	intn = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
	romn = ["M", "CM", "D",  "CD", "C",  "XC", "L", "XL", "X",  "IX", "V",  "IV", "I"]
	while @num!=0 do
	    while @num/intn[i]>0 do
		s = s + romn[i]
		@num = @num - intn[i]
	    end
	    i += 1
	end
	puts old.to_s + " = " + s
    end
end

greeter = Roman.new()
greeter.num = ARGV[0].to_i
greeter.to_roman
```

クラス化もしたことで、コードも簡潔で、割とまとまったプログラムが書けたと思います。。。

ただ、900や40などを"CM", "XL"と登録するのは我ながらズルしている感じがします。（苦笑）

以下に出力結果を載せます。

    $ ruby roman_numerals.rb 999
    999 = CMXCIX
    
    $ ruby roman_numerals.rb 1997
    1997 = MCMXCVII


# 参考

以下のサイトを参考にしました。

-   [課題本文](https://qiita.com/daddygongon/items/2d0a73a51ddab2d9da1b)
-   [ローマ数字](https://www.asahi-net.or.jp/~ax2s-kmtn/ref/roman_num.html)
-   [Rubyの第7歩　Class編](https://qiita.com/Rooter-edi/items/f8cfd5a996dac48a91ac)



------
 - **source** ~/grad_members_20f/members/Rooter-edi/qiita/roman_number.org
押したくても押せなかった人のために「バスの停止ボタン」を作る

# どうも7noteです。子供の頃、押したくても押せなかった大人のために。作りました。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/85a7f75b-46a1-c544-b279-b1bcf8e7add0.gif)

※音は出ません

押し込むボタン風につくります。
ランプがついているようにさせるため、文字に影などもつけています。

## 作り方

```index.html
<div class="btn">
  <div class="lanp"><span>とまります</span></div>
  <div class="push">お降りの方は<br>このボタンを<br>押して下さい</div>
</div>
```

```style.css
.btn {
  width: 110px;
  background: #E1B662;
  border-radius: 15px;
  padding: 15px 10px;
}

.lanp {
  text-align: center;
  background: #493B57;
  border-radius: 10px 10px 0 0;
  padding: 10px 0;
  color: #EA281C;
  text-shadow: 0px 0px 5px #EA281C;
}

.lanp span {
  visibility: hidden;  /* 初期状態では文字を見えなくする */
}

.lanp.on span {
  visibility: visible; /* クラスonがついたら文字を表示 */

}

.btn .push {
  background: #DD6F31;
  border-bottom: 5px solid #C0221F;
  border-radius: 0 0 10px 10px;
  padding: 5px;
}


.btn .push:hover {
  cursor: pointer;
}

.btn .push:active {  /* 押されている間だけ効かせるCSS */
  border-bottom: 5px solid #DD6F31;
  padding-top: 7px;
  padding-bottom: 3px;
}
```

```script.js
$(function(){
  $(".push").on("click",function(){  /* pushが押された時 */
    $(".lanp").addClass("on");       /* ランプ部分にクラス(on)をつける */
  });
});
```

※[jQuery](https://qiita.com/7note/items/45bd8efbedd557667218)を使用しています。

## 解説

特に解説しなければならないポイントもないのですが、ちょっとだけポイント紹介。

クリックされている最中だけにCSSを効かせるのは`:active`の疑似セレクタを使うことで再現できます。
`:active`でborderの色を変更しつつ、上下の`padding`を微調整してボタンを押し込む再現をしています。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
【備忘録】プリミティブ値とラッパーオブジェクト【TypeScript】

# プリミティブ値

TypeScript,JavaScript初学者が**プリミティブ値**と**ラッパーオブジェクト**について勉強したのでメモを残す。

## 静的型付け言語 vs 動的型付け言語

- どちらも型は存在する(動的片付け言語は型がないと言われがちだが*ソンナコトナイヨ*)
- **静的型付け言語**は変数や、関数の引数及び戻り値の型がプログラムの実行前にあらかじめ決まっていなければならない
- **動的型付け言語**はそれらが実行時の値によって文字通り動的に変化するということ

*JavaScrip（動的型付け言語） の場合*

```
$ node
> let val = 100;
> val = 'hoge';
'hoge'
```

### その他の動的型付け言語

- Python
- Ruby
- PHP
  など

*TypeScript（静的型付け言語） の場合*

```
$ ts-node
> let val = 10;
> val = '200';
200

> val = 'hoge';
[eval].ts:3:1 - error TS2322: Type '"hoge"' is no assignable to type 'number'.
```

- TypeScrip は`let`で変数宣言してもデータ型が異なると値の再代入は**コンパイルエラー**になる。


## その他の静的型付け言語

- C/C++
- C#
- Java
- Swift
  など

## JavaScript のプリミティブ型

JavaScript は値がプリミティブでありオブジェクトではない、インスタンスメソッドを持たないデータである

- **Boolean 型**
  - プリミティブは`true`と`false`
- **Number 型**
  - 数値を扱うデータ型。
- **BigInt 型**
  - Number 型より大きな数値を扱うためのデータ型。Number 型と代入や計算、等値比較などはできない。
- **String 型**
  - 文字列を扱うためのデータ型。
- **Null 型**
  - プリミティブ型`null`は何のデータも存在してない状態を明示的に示す
- **Undefined 型**
  - プリミティブ値`undefined`が割り当てられるもの
    - 宣言のみが行われた変数
    - オブジェクト内の存在しないプロパティへのアクセス
- **Symbol 型**
  - `Synbol()`関数が**Symbol**型の値を返す。
  - `Boolean`や`new String`、`new Nnumber`のようなプリミティブラッパーオブジェクトは**Symbol**型には存在しないため、もしラッパーオブジェクトを生成したいのであれば、`Object()`関数を使用できる。

  
  ```typescript
  Symbol("foo") === Symbol("foo"); // false
 
  let sym = Symbol("foo");
  typeof sym; //  'symbol'
  // Objectでラッパーオブジェクトを生成
  let symObj = Object(sym);
  typeof symObj; //  'object'
  ```

# ラッパーオブジェクト

- **ラッパーオブジェクト**とは ``null`` と ``undefined`` 以外のプリミティブ型を抱合するもの。string 型のラッパーオブジェクトは ``String``、number 型のラッパーオブジェクトは ``Number`` など。
- ラッパーオブジェクトは ``valueOf()``メソッドでプリミティブ値を取り出せる。

```
> const str1 = 'hogehoge';
> const str2 = new Srtring('hogehoge');
> str1 === str2
false
> str1 === str2.valueOf()
true
```

- プリミティブ型の値に対してアクセスするとき、**対応するラッパーオブジェクトに自動変換する**という仕様がある。

*何か指摘等ございましたら、コメントでお願いいたします。*

# 参考
- [りあクト！ TypeScriptで始めるつらくないReact開発 第3版【Ⅰ. 言語・環境編】](https://booth.pm/ja/items/2368045)
- [Symbol - JavaScript | MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
- [動的言語と静的言語の違い - Qiita](https://qiita.com/wann/items/16920b070dc0483f152a)
画像アップローダーをReactとFlaskで作る

###ポイント
画像自体は外部ストレージで管理して、DBでは画像URLを管理。

#ローカル開発の全体像
![スクリーンショット 2021-01-03 21.26.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/ab1fa5f9-573d-3ae1-f6f8-ffc9ed81e30e.png)


#学び
###back_endとfront_endのgit管理は分ける
まともにアプリを一から作ってデプロイしたことがなかったので、今回初めて分かったのですが、herokuの場合はroot直下にherokuを動かすためのファイルをいろいろ作る必要があって、そこの階層をスタートにすると読み込むpathがローカルの時と変わってきて、、みたいな感じでごちゃごちゃになりました。なので予めgit管理を分けておけばこのような自体は未然に防げたと思います。

###herokuはファイルシステムを扱えない
これに今回一番苦戦したんじゃないかなと思うのですが、herokuで例えば”コマンドを実行してsample.txtファイルを作る”ということは全くできなくなっています。
今回私の場合は

1. 画像を一旦uploadsディレクトリ配下に画像ファイルとして保存して後で読み込む
2. migrationsディレクトリをherokuコンソール上でmigrateする(migrate用のファイルが作られます)

この二つで詰まりました。どちらもheroku上でgit管理外のファイルを新しく生成しようとしており、herokuの仕様上ダメでした。対処法は以下の通りです。

1.PILのImageを利用

```python

# bytes形式で読み込み
img = Image.open(file) #FileStorageクラスがなかなか厄介
# メモリでデータを保持する
bio = io.BytesIO()
img.save(bio, format=image_format)

blob.upload_from_string(data=bio.getvalue(), content_type=content_type)
```

2.ローカルでmigrateまで済ませた後にpushしてheroku上でupgradeのみ実行する

###隠しjsonファイルをheroku上で読み込むには環境変数に無理やり入れる
firebaseの認証にjsonファイルを読み込む必要がありました。

```
cred = credentials.Certificate('./serviceAccountKey.json')
```

ただ、これは大事な情報でgitで管理はできないため、heroku上にはないことになってしまい、jsonファイルがないよというエラーが発生しました。解決策としては中身のjsonを無理やり環境変数に入れることで対応しました。

```
export SERVICE_ACCOUNT_KEY='{"type": "service_account","project_id": "...
```
アドベントカレンダー19日目：SREを読んでみた「Googleにおける自動化の進化」編⑤

前回は、Googleの自動化の実例を扱いました。クラスタの状態をProdtestで検証できるようになったSREチームは、システム管理者からクラスタを5日以内に立ち上げてほしいという要望を受けました。SREチームはどのような対応をしたのでしょうか？

## 不整合の冪等な解消
Prodtestによって、クラスタが準備ができているかどうかを検出することはできます。しかし、この状況を修正するとなると、それぞれのSREチームがいち早くバグが修正されるしかありません。
この状況を解決するために行ったことは、「設定ミスを検出するPythonのユニットテスト」を「設定ミスを修正するPythonコード」に変更するということでした。
設定の検証を行い、テストに失敗した時は修復スクリプトが実行されます。修復に数回失敗した場合は、修復に失敗したとみなして、ユーザーへ通知します。
この時点において、これは自動化技術の頂点のように思われました。
しかし、この試みには大きな落とし穴がありました。
テスト、修正、2回目のテストの間のレイテンシにより、テストがうまくいかないことやすべてのテストが冪等になっているわけではないので、あてにならないテストの後に修正がつづきシステムの状態が不整合になってしまうことがありました。

## 特化する傾向
自動化のプロセスには、3つの面で差異が生じます。

> * **対応への適用。すなわち自動化を正確に行えるか。**
* **対応にかかっている時間。プロセス開始後の各ステップの動作の速度。**
* **対応の関連度。もしくはこの自動化でカバーされる実際のプロセスの比率。**<sup>1</sup>

このため、まず対応がしやすく、手作業に時間がかかっており、関連度が高いものから対応を始めました。ターンアップの時間を少なくするために、多くのチームは単一の「ターンアップ」チームへどの自動化を実行すべきかを指示しました。
各ターンアップチームは、起動処理中の各ステージの構築をチケットで管理し、割り当て状況を追跡できるようにしました。そして、最終的に適切で、正確で、素早い自動化プロセスが出来上がりました。
しかし、現実世界は日々変化をします。それにより、設定やデータが変化します。自動化の関連度は低くなり、適切でもなくなっていきます。ですが、この問題がターンアップの速度に影響を与えるには、多少の時間がかかりました。
しかし、この時サービスを動作させるチームの責任範囲から自動化のコードのメンテナンスをと実行を外すことで、組織はよくないインセンティブを持つことになりました。
サービスを動作させるチームは、サービスの技術的負債と取り除くことにインセンティブを持たない。自動化の処理を実行しないチームは、自動化しやすいシステムを構築することにインセンティブを持たない。プロダクト管理者は、シンプルさや自動化よりも新しい機能を優先する。

### 新しい制約
これは、まったく無関係なセキュリティ要件によって、この状況から抜け出すことができました。
この頃、分散された自動化の多くはSSHに依存しており、ほとんどのコマンドの実行にroot権限を必要とするので、セキュリティ的に扱いずらくなっていました。そのためSREが持っていた権限を制約し、作業上の必要最小限にする必要がありました。そこでそれまで使用していたsshdを認証済みでACLを使用するRPCベースのローカル管理デーモン（Admin Server）に置き換えました。これは自動化で必要なローカルでの変更を行う権限を持っています。これにより、監査証跡なしにサーバーへ変更やインストールができなくなりました。ローカル管理デーモンとパッケージリポジトリにはコードレビューが義務づけられていたので、権限の逸脱が起こりづらくなりました。
Admin Serverは、デバックとセキュリティのためにRPCリクエストの送信者、パラメータ、RPCの結果がログに残りました。

## サービス思考のクラスタのターンアップ
Admin Serverがサービスチームのワークフローに組み込まれると、SREはシェルスクリプトの作成からACLの下で動作するピアレビューを受けたRPCサーバーの構築へ移りました。
後にサービスを所有するチームがターンアップのプロセスも受け持つ必要があることが広く認識された後、クラスタのターンアップ/ターンダウンのRPCを扱うAdmin Serverの作成も、サービス所有者が受け持つことになりました。（クラスタのターンアップをサービス指向アーキテクチャとしてアプローチする方法とみなした）
各チームはターンアップの自動化に必要なAPIを提供します。クラスタがネットワーク準備完了状態になれば、クラスタのターンアップの一部を担う各Admin Serverへ自動化の仕組みからRPCが送られます。
これにより、低レイテンシで要望を満たし、かつ正確なプロセスができたことになります。

##まとめ
セキュリティ要件を満たすことにより、Admin Serverを導入する必要が出ました。
その際に、クラスタのターンアップをSOAとみなすことで、自動化もサービス所有者が担うことになりました。

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　84-86
Spring BootアプリケーションをCloud Runにデプロイ with gradle

Spring BootのアプリケーションをCloud Runにデプロイしていく
https://qiita.com/indes888/items/feb431bd0a0a4cce142b
の続き

## 前提条件
* GCPのアカウントを持っていてプロジェクトを作成済み
* gcloudがインストールされて初期設定が済んでいる

## マルチステージビルドにする
ビルドとアプリケーションの起動を１つのDockerfileを使ってまとめる


```dockerfile:dockerfile
FROM gradle:6.7.1-jdk11 as builder
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build bootjar

FROM openjdk:11-jre-slim
EXPOSE 8080
RUN mkdir /app
COPY --from=builder /home/gradle/src/build/libs/*.jar /app/bootjar.jar
ENTRYPOINT ["java", "-jar","/app/bootjar.jar"]
```
dockerbuild時にgradleビルドが実行される。
dockerbuild + dockerrun は以下のコマンド

```
docker build -t bootbuilder:v0.2 .
docker run -it --rm -v "$PWD":/home/gradle/src -p 8080:8080 bootbuilder:v0.2
```
localhost:8080にアクセスして文字列が表示されたら起動確認完了

## Cloud Runにデプロイする
GCPのダッシュボードからCloud Runを選択し、APIを有効化しておく必要がある
まずはCloud Buildを使ってContainer Registoryにイメージをpushする

```
gcloud builds submit --tag gcr.io/$PROJECT_ID/bootbuilder:v0.2
```
$PROJECT_IDには使用するプロジェクトIDを挿入する
ビルドが実行されてイメージがpushが完了するとContainer Registoryからイメージを確認できる

次にContainer RegistoryからCloud Runにイメージをデプロイする

```
gcloud run deploy --image gcr.io/$PROJECT_ID/bootbuilder:v0.2 --platform managed
```
サービス名とデプロイするリージョンが聞かれるので適当に進める
最後に
Service URL: https://XXXXXXXXXXXXXXXXXXXXX.a.run.app
と表示されるのでアクセスして文字列が表示されればデプロイは完了
URLはCloud Runのダッシュボードからも確認できる

Cloud Runはデフォルトでコンテナの８０８０ポートにリクエストを転送するのでアクセスできる
使用するポートはgcloud run deployの--portオプションで変更可能

--platformオプションの説明は以下を参照
https://cloud.google.com/sdk/gcloud/reference/beta/run/deploy#--platform

#### 参考資料
https://codefresh.io/docs/docs/learn-by-example/java/gradle/
https://cloud.google.com/run/docs/quickstarts/build-and-deploy
Windowsコマンドでファイル行数を数える

1 下記ソースをloc.batとして保存する。

```bat
@echo off
if "%~1"=="" echo Usage: %~nx0 ^<SourceDirectory^> [FilenamePartern] & goto :EOF

set _fnp=%2
if "%_fnp%"=="" set _fnp=*.*

for /r %1 %%f in (%_fnp%) do (
    for /f "tokens=1-3 delims=:" %%i in ('find /c /v "" "%%f"') do (
        if "%%k"=="" echo %%f	%%j
        if not "%%k"=="" echo %%f	%%k
    )
)
```

2 以下、使用例になる。

  loc.bat c:\java\src

  loc.bat c:\apex\src |clip

以上
LIFF思ってたより簡単にできた ~入門編~

この記事はエイチーム引越し侍 / エイチームコネクトの社員による、[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hikkoshizamurai-connect) 22日目の記事です。

# はじめに
引越し侍でもLINEを利用するシステムが増えてきて、
次に何かできないかなと思ったのをきっかけに触ってみました。

色々とやることがありそうで、大変そうだと思っていましたが、
実際にやってみると簡単に試すことができたので、手順を書いていきます。

# LIFFとは
LIFF（LINE Front-end Framework）とは、LINEのアプリ上で動くWebアプリのプラットフォームで、
LINE上にフォームを設置して入力情報をシステムと連携させるといったようなことができるようになります。

例えば、ヤマト運輸さんだと受取日時の変更や再配達依頼などのサービスを提供されていますね
<img width="200px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/d0f605a2-f666-c596-e2aa-7e7bfb3da805.png">

# 準備
今回は以下のサービスを使って実装していくので、アカウント作成とインストールをしてください。

- [LINE公式アカウント](https://www.linebiz.com/jp/entry/)
- [Heroku](https://jp.heroku.com/home)
- [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)
 
# 実際にやってみる
### 1. LINEのプロバイダーとチャネル作成
以下のサイトを参考に、プロバイダーとチャネルを作成してください。
[チャネルを作成する](https://developers.line.biz/ja/docs/liff/getting-started/)

### 2. Herokuのプロジェクト作成
Herokuにログインし、「Create New App」からプロジェクトを作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/1b71e374-ebe5-3d55-2336-d80b95c87fbb.png)

### 3. LIFFアプリプロジェクトを入手
LINEが公式でサンプルプロジェクトを提供してくれているので、今回はこちらを使って進めていきます。
[公式サンプル](https://github.com/line/line-liff-starterI)

以下のコマンドを実行してサンプルを取得
`git clone https://github.com/line/line-liff-starter.git`
### 4. HerokuにDeploy
以下コマンドを実行し、Deployしていきます。

```
$ heroku login
$ cd line-liff-starter/
$ git init
$ heroku git:remote -a 手順2で入力したAppName
$ git push heroku master
```

### 5. アプリをLIFFに追加する
作成しておいたチャネルのLIFFに追加をしていきます。
チャネルを選択し、 [LIFF]メニュー → [Add]
<img width="500px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/58a590a3-c42b-7c73-71ef-e5f7941d767a.png">

こちらのページを参考にしてください。
[LIFFアプリをチャネルに追加する](https://developers.line.biz/ja/docs/liff/registering-liff-apps/#%E5%A7%8B%E3%82%81%E3%82%8B%E5%89%8D%E3%81%AB)
とりあえず試すなら、EndPointURL以外は適当で良さそうです。


### 6. LIFFアプリを開く
手順5でアプリをLIFFに追加するとURLが発行されるので、試しにLINEのアプリ上で開いてみてください。

URLは手順5と同じ[LIFF]メニューで確認できます。
<img width="200px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/20c5c513-4201-bffe-630e-164b69922d37.png">

URLを開くとこんな感じでLIFFが起動します。
<img width="200px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/21b28ec3-53df-967f-273d-4c0393999576.png">

### 7. LINE公式アカウントとLIFFアプリの起動を紐付ける
LINE公式アカウントマネージャーを開き、リッチメニューを作成します。
[LINE公式アカウントマネージャー](https://manager.line.biz/)

今回はお試しということで、見た目は適当で。
ポイントは、タイプに「リンク」を選択し、URLに手順6のLIFFのURLを入力します。
<img width="300px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/721e0398-498e-22d4-0b0f-198141b066af.png">

保存をすると、メニューが表示されるようになり、
<img width="300px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/1dda78b9-a093-1a76-c908-8e573073bf8a.png">

クリックすると、作成したLIFFが起動します。
<img width="200px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249008/21b28ec3-53df-967f-273d-4c0393999576.png">

# 最後に
今回はお試しということで基本的なことしかしていませんが、
色々と触ってみて、面白い発見があったら応用編も書いてみようと思います！

# 次回
明日は@namiitaの記事になります！
お楽しみに！！
[Shopify] ページ管理 II、ページの一覧を表示する

昨日はShopify上でのページ生成を見ました、
今日はページの一覧の取得と、特定のページを取得してみます。

前回の記事はこちら
[[Shopify] ページ管理 I、ページを生成する](https://qiita.com/syantien/items/d814d0291e56970a08eb)


昨日はプログラマチックにコンテンツを生成するということでしたが、逆にShopifyで管理しているページを自社アプリに表示するなどで利用することもできるかと思います。

では見てみましょう。

# Shopify APIのエンドポイント

エンドポイントはこちらです

```
GET
/admin/api/2020-10/pages.json
```

# モデル

データモデルは前回と同様ShopifyPageObjectModelがベースとなり、下記のように定義しました。

```csharp

public class ShopifyPageObjectRootModel
{
  public ShopifyPageObjectModel page { get; set; }
}
```

# APIコール

実際にAPIをCallしているメソッドはこちらです

```csharp

public async Task<ShopifyPageListObjectRootModel> GetListOfPagesAsync(string storeUrl, string token, ShopifyPageListRequestModel filter)
{
　　client = new HttpClient();
　　var url = "https://" + storeUrl + path + "pages.json";
　　
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
      new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.Add("X-Shopify-Access-Token", token);

    var response = await client.GetAsync(url); ;

    var resultString = await response.Content.ReadAsStringAsync();

    var responseLog = new Dictionary<string, string>();
    responseLog.Add("ApiResponse", resultString);
    _telemetry.TrackEvent("from /pages.json", responseLog);

    return JsonConvert.DeserializeObject<ShopifyPageListObjectRootModel>(resultString);
}

public class ShopifyPageListRequestModel
{
  public string limit { get; set; }
  public string since_id { get; set; }
  public string title { get; set; }
  public string handle { get; set; }
  public string created_at_min { get; set; }

  public string created_at_max { get; set; }
  public string updated_at_min { get; set; }
  public string updated_at_max { get; set; }
  public string published_at_max { get; set; }
  public string published_at_min { get; set; }
  public string fields { get; set; }
  public string published_status { get; set; }
}

```

# コントローラー

さきほどつくったメソッドをCallしているコントローラーの一部はこちらです

```csharp

var pages = await _shopifyPageHandlers.GetListOfPagesAsync(sdomain, organization.ShopifyAccessToken, new ShopifyPageListRequestModel() { });
```

# ビュー

そしてViewはこちらです

```html

<table class="table table-bordered table-striped">
  <tr>
    <td>
      Title/Handle
    </td>
    <td>
      Published At
    </td>
    <td>
      Author
    </td>
  </tr>
  @foreach (var item in Model.Pages.pages)
  {
    <tr>
      <td>
        @item.title
        <br />
        @item.handle
      </td>
      <td>
        @item.published_at
      </td>
      <td>
        @item.author
      </td>
    </tr>
  }
</table>
```

実際のビューはこちらです

![uploading...0]()![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/2988c44d-f855-7310-fc2f-0056484c2a04.png)

# 次回

今回は一旦リスト表示をしましたが、毎度すべてのページを戻されても使えないので、
次回はリストのフィルタリング（検索）をみて行きたいと思います。
RspecでFailure/Error: require File.expand_path('../config/environment', __dir__)の原因と対処

###はじめに

Rspecを導入した時に以下のエラーと遭遇しました。

```
An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

NoMethodError:
  undefined method `active_storage' for #<Rails::Application::Configuration:0x000055b12abba7c0>
```

Rails: 6.0.3.4
rspec-rails: 4.0.1

---

###対象となる読者

Rspec導入したけど動かないよ。タイトルのエラー出てるよ。という人向け。

---

### 結論

原因はactive_storageのroutingを出したくないので、 `config/application.rb` 

```application.rb
# require "active_storage/engine"
```

上記記述をコメントアウトしていたことでした。

```application.rb
require "active_storage/engine"
```

この状態に戻すとテストが通った。

やったね！

以下の記事のAnswerにあるように、`require "active_storage/engine"`の記述は他のフレームワークと使う時に必要なようです。
['method_missing': undefined method `active_storage' for (NoMethodError)](https://stackoverflow.com/questions/52349351/method-missing-undefined-method-active-storage-for-nomethoderror)

類似のパターンとしてはbundle updateのタイミングで発生することがあるようです。

- [RSpecでFailure/Error: require File.expand_path('../config/environment', __dir__)が出たときの対処法](https://qiita.com/KessaPassa/items/a4ee4c1cb5b0b7bc38f4)

- [Failure/Error: require File.expand_path('/../config/environment', __dir__)　というエラー](https://qiita.com/magatama/items/e9922dec831a48a3c8b0)
リモートリポジトリの変更のやり方とその後の対処法

たまにクライアント側のgithubアカウントでリポジトリを管理したいという連絡をいただくことがあるけど、普段はあまり使わないコマンドもあるので、自分のメモ用に残す。
# 1. リモートリポジトリの変更
下記のコマンドでリモートレポジトリを登録・編集・削除して新しいリポジトリを登録したり、必要なくなったレポジトリを削除・編集したりする

#### 登録されているリモートレポジトリ一覧を確認する
```
git remote -v
```

####  新しいリモートリポジトリを追加
```
git remote add [repository name] [repository url]
```

####  リモートリポジトリのURLを編集
```
git remote set-url [repository name] [repository url]
```

####  リモートリポジトリの削除
```
git remote rm [repository name]
```

# 2. 上流ブランチを変更する
もう一つ忘れてはならないのは、すでに使っているブランチの上流ブランチが昔の上流ブランチのままになっていること。
#### 上流ブランチの確認
まずローカルブランチに当てられている上流ブランチを確認する

```
git branch -vv
```

#### .git/configをエディターで編集する
```
git config --edit
```

# 3. その他
ちなみに`git remote -v`や`git branch -vv`以外にもリモートレポジトリと上流ブランチを同時に確認できるコマンドが下記

```
git config --list
```
「はじめまして kintone」から 1 年経ったお話

# kintone をはじめて 1 年経った

本記事は [kintone 2 Advent Calender 2020](https://qiita.com/advent-calendar/2020/kintone2) の 21 日目の記事です。
さて、ついに年の瀬です。
2020 年はなかったことにしようなんて考えてみたりしましたが。
1 年間で何か成長したかもしれない…ということで振り返ってみましょう。

昨年、投稿した [kintone 2 Advent Calender 2019](https://qiita.com/advent-calendar/2019/kintone2) では
「[kintone を初めて1ヶ月で学んだこと](https://qiita.com/holynight_201/items/d667eba735ff24e81538)」というテーマで参加しました。
そこで今年の Advent Calender では、最近のトピックだったり、
1年間でどんなことを勉強してきたのかについて振り返ろうと思います。

## kintone Associate を取得

昨日の [kintone 2 Advent Calender 2020 の投稿](https://qiita.com/MoriMority/items/27d866f9f8ab7fdc149e)でも
Associate の勉強方法について紹介されています。
自分自身の kintone の知識がきちんと整理されているか確認するために
受験するのはおすすめです。

また、今年の6月頃には 試験対策テキストの第2版も発売されて、
今まで「億劫だな…」と思っていた、現行の kintone のバージョンと
試験問題で扱われる kintone のバージョンの差分が少なくなっています。
2020 年 12 月 21 日現在では、2020 年 12 月版の kintone にアップデートされていますが、
試験内容は以下の表のような対応バージョンになっています。

|試験|バージョン|
|---|---|
|kintone Associate|2020 年 4 月 1 日時点の kintone|
|kintone App Design Specialist|2020 年 8 月 1 日時点の kintone|
|kintone Customization Specialist|2020 年 8 月1 日時点の kintone|

つまり、サクッと勉強して早めに受験したほうが
勉強にかかるコストも少なくなるということです。
やっと Associate を取得することができたので、
次は App Design Specialist か Customization Specialist を受験しようと思っています。
Associate については受験している方も多いのか、
勉強法についても紹介されているのを見かけますが、
上位資格についてはあまり見かけないので、
受験した際にはまた記事を書きたいと考えています。

参考: [kintone CERTIFIED（キントーン認定資格試験）](https://cybozu.co.jp/kintone-certification/)

## cybozu developer network のコミュニティに住んでみる

「コミュニティに住む」ってなんだか変な言葉かもしれないのですが、
定期的に [cybozu developer network](https://developer.cybozu.io/hc/ja)（以下、devnet）の[コミュニティ](https://developer.cybozu.io/hc/ja/community/topics)を覗くことで、
いろんなユーザーのカスタマイズ方法について知ることができました。

もちろん初めの頃は、読むことがほとんどでしたが、今では回答することを心がけています。
誰かの質問に答えるときに自分自身の知識が間違っていないかなどを
振り返る機会にもなるので一石二鳥です…！

### コミュニティで回答しやすい質問

「コミュニティに住む」ことを心がけているうちに、
回答が付きやすい質問というものがなんとなく分かってきました。
コミュニティに質問をするユーザーの方は kintone 初心者の方ももちろんいらっしゃるので、
「質問ってどう書けばいいのだろう…」と思う方も多くいるかもしれませんが、
「良い質問をするためのガイドライン」が devnet にはあります！
![devnet-new-post-v1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100759/996d9a9f-2532-5797-a56b-67cab46b83a8.png)


今年の6月頃、突如現れたこのガイドライン、実は最近またリニューアルされて、
ソースコードを分かりやすく書く方法についても教えてくれています。
いざ質問に答える側になってみると、
ソースコードがハイライトがかかった状態になっているものとなっていないものだと
明らかに前者のほうが読みやすいですし、質問の回答を考える時間が短縮されるので、
質問をする方はぜひガイドのソースコードの貼り方を参考にしてみてはいかがでしょうか。

## おわりに

今年の kintone Advent Calender も楽しいカスタマイズが紹介されたりしていますが、
技術的なところからは少し離れた cybozu developer network に注目して書いてみました。

コロナウイルスの感染が拡大する中、
在宅勤務の長期化などにより kintone に触れる人がまた増えていくのでは、と思います。
導入しやすいことが kintone のメリットでもありますが、
カスタマイズを行うことによってできることは広がります。
2021 年も kintone や cybozu developer network を活用してたのしい kintone ライフを！
SendGrid を使いメール送信専用の Thunderbird の設定を行う

オズビジョンのSREチームリーダの卜部です。

弊社では一部業務でメーラー を一括メール送信用に使っています。これまで、ID/PW を使った SMTP を設定していたのですが、今後使えなくなるとのお知らせが SendGrid のサイト上に掲載されていました

-  [【重要】APIキー認証および二要素認証が必須に変更されます](https://support.sendgrid.kke.co.jp/hc/ja/articles/900004682143--%E9%87%8D%E8%A6%81-API%E3%82%AD%E3%83%BC%E8%AA%8D%E8%A8%BC%E3%81%8A%E3%82%88%E3%81%B3%E4%BA%8C%E8%A6%81%E7%B4%A0%E8%AA%8D%E8%A8%BC%E3%81%8C%E5%BF%85%E9%A0%88%E3%81%AB%E5%A4%89%E6%9B%B4%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99)

このことにより、APIキーを使ったメール送信方法に限定されることとなりました。
また、あわせて、メールを送信するのみで、受信は一切使わないため、ダミーの POP3 サーバを立ち上げ設定を完了させていきます。


# 準備

1. まず、API Key を作成します
    - [APIキーの作成](https://sendgrid.kke.co.jp/docs/User_Manual_JP/Settings/api_keys.html#-Create-an-API-Key) を参考に作成します。
    - メール送信のみでしたら、「Restricted Access」の「MailSend」のみで十分です
2. [Thunderbird](https://www.thunderbird.net/ja/) ダウンロードし、インストールします
3. ダミーの pop3 サーバを立ち上げるので [Node.js](https://nodejs.org/ja/) をインストールします
4. [mock の pop3 サーバのスクリプト](https://gist.github.com/oz-urabe/6e30ec01af8863ac87c12c709954c694) をダウンロードします

Mac の場合、ターミナルで、Windows の場合、コマンドプロンプトで、以下を打ちます
スクリプトをダウンロードした PATH で実行します。

```bash
$ node mock-pop3-server.js
```

コレを起動しないと設定完了しないため、完了させるためだけに起動させます。

# 設定

1． Thunderbird を起動し、[ツール] -> [アカウント設定] で設定画面を開きます
2. [アカウント操作] から [メールアカウントを追加] を押下
3. [お名前] ※差出人名になります, [メールアドレス], [パスワード] ※ sendgrid で取得した APIKEY
4. [手動設定] ボタンを押下
5. 受信サーバー
    - プロトコル:  POP3 を選択
    - サーバ: localhost
    - ポート番号: 110
    - SSL: 接続の保護無し
    - 認証方式: 通常のパスワード認証
    - ユーザ名： なんでもいい
6. 送信サーバー
    - サーバ: smtp.sendgrid.net
    - ポート番号: 587
    - SSL: STARTLS
    - 認証方式: 通常のパスワード認証
    - ユーザ名： apikey (固定)
7. 完了ボタンを押下


![スクリーンショット 2020-12-21 21.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/8fe2edba-aa9a-a472-7205-d846ec215000.png)

以上で完了です。

送信するだけなので、次回以降は `node mock-pop3-server.js` は起動する必要はありません。「受信サーバに接続できない」旨のエラーメッセージはでますが、無視です！

受信サーバを使う場合は、適切なものをいれてください。
js基本のキ

・ルール
大文字、小文字は区別される。
forEachはいけるが、foreachはエラーになる。


・定数、変数
const 定数
let 変数
あたいがコロコロ変わるとややこしいので、基本はconstを使いつつ、必要な時にletを使う。
名前のつけかた。
英数字、＄、＿のみ使える。
数値からはじめることはできない。


・関数をオブジェクトのプロパティの値にした場合、その関数をメソッドと呼ぶ



・静的メソッド
インスタンスを介さず呼び出せるメソッドを静的メソッドと呼ぶ。メソッド名の前にstaticをつけてあげる。
thisはクラスから作られたインスタンスを指すため。インスタンスを作らず呼び出すこのメソッドは、thisを使えない。

・継承
class 子クラス　extends 親クラス　{
}
extends...拡張する
子クラスの constructor() で this キーワードを使うには constructor() の最初で super() を記述する必要がある。親クラスでthis.textがあれば、super(text)

superに繋げて書けば親クラスのメソッドを呼べる
親
show() {
     console.log(`${this.text} - ${this.likeCount}likes`);
    }
子
show() {
      super.show();    <=  console.log(`${this.text} - ${this.likeCount}likes`);
      console.log(`... sponsored by ${this.sponsor}`);
     }

・今時はprettirとESlintを組み合わせて使うらしい。

・ビルド
ソースコードを実行可能な状態にすること
Windows10の便利なショートカットキー

ちょっとした工夫で効率化！02【PR】パソナテック Advent Calendar 2020　22日目の記事です。
Windows10以前のOSでは、一部ショートカットキーは機能しません。あと、レベルは私の独断と偏見でつけています。

# 常識編
プログラマに限らず、仕事などでWindowsを使う人ならだれでも知っているようなものです。

| キー | 機能 |
|:-:|:-:|
| Ctrl + C | コピー  |
| Ctrl + V  | コピーしたものを貼り付け  |
| Ctrl + X  | 切り取り  |
| Ctrl + A  | 全選択  |
| Ctrl + S  | 上書き保存  |
| Ctrl + Shift + S  | 別名保存  |
| Ctrl + Z  | 元に戻す  |
| Ctrl + Y  | やり直す  |
| Ctrl + F  | 検索  |
| Alt + ←/→ | ページを戻る/進む   |
| Alt + Tab | タスク、ウィンドウを切り替える |

# 中級編
ちょっと知らない人も多そうなショートカットキーです。

| キー | 機能 |
|:-:|:-:|
| Ctrl + O  | ファイルを開く  |
| Ctrl + P  | 印刷する  |
| Ctrl + N  | ファイルの新規作成  |
| F2 | ファイル、フォルダの名前変更  |
| Shift + 十字キー  | 範囲選択  |
| Home  | カーソルを、行の先頭に移動する  |
| End  | カーソルを、行の末尾に移動する  |
| Alt + F4  | ウィンドウを閉じる  |
| Ctrl + Shift + Esc  | タスクマネージャーを開く  |

# 上級編
Windows10になって登場したものなどです。知らない人も多いかも？

| キー | 機能 |
|:-:|:-:|
| Win + D  | デスクトップに移動  |
| Win + 1 ~ 0  | タスクバーから対応するアプリを起動  |
| Win + Ctrl + D| 仮想デスクトップを追加   |
| Win + Ctrl + ←/→  | 仮想デスクトップを切り替える  |
| Win + V  | クリップボードに張り付けたものの履歴を表示  |
| Win + Shift + S  | 範囲選択をしてスクリーンショット  |
| Win + E  | エクスプローラーを起動する  |
環境変数について調べる(メモ)

こちらもなんとなくで使用しているので
きちんと言語化できるように深堀りして調べる

##環境変数とは
環境変数とは**外部サービスのパスワード**や、**APIの秘密鍵**など
Githubにあげたくない`機密情報の漏洩を防ぐ`ために
サーバーなどのOSに保存しアプリに渡す仕組みのこと
→そのままGithubにあげてしまうと、外部サービスを使用され
多額の請求がきた などの記事をみたことあるので気をつける…

またOSが動いているときに使用する変数
プログラムの実行時などに必要となる

##設定方法
今回行うのは
「**dotenv-rails**」というgemを使う方法
通常.envを読みこませるにはコマンドが必要だが、
「dotenv-rails」というgemを導入することにより自動的に読み込んでくれるらしい

他にも「**.bash_profile**」に記述する方法があるらしい

###「Dotenv-rails」を使用して設定してみる

####Gemをインストールする
まずは、Gemをインストール

```Gem.file
gem 'dotenv-rails'
```

お約束

```ターミナル
bundle install
```

####「.envファイル」を作成
ルートディレクトリに「.env」というファイルを作成する

自分は、sample_app で作成しています

```
~/environment/rails/sample_app
❯ pwd

/Users/ユーザー名/environment/rails/sample_app
❯ touch .env

~/environment/rails/sample_app
❯ ls
Gemfile      Rakefile     config       lib          public       tmp
Gemfile.lock app          config.ru    log          storage      vendor
README.md    bin          db           package.json test

~/environment/rails/sample_app
❯ ls -A
.env          .ruby-version Rakefile      config.ru     package.json  tmp
.git          Gemfile       app           db            public        vendor
.gitignore    Gemfile.lock  bin           lib           storage
.history      README.md     config        log           test
```
→ファイルを作成してlsコマンドでみてもない！と焦らない
オプションで「-A」をつけるとみることができます


####環境変数を設定してみる
作成した.envファイルに環境変数を記述します。
vimとかで編集してください

````:.env
#使用したいキーやパスワードを記述
KEY='*******'
SECRET_KEY='*******'
```

####gitignoreを編集する
「.envファイル」に定義されている情報を不正利用されないように、
**Gitの管理から外す**必要がある
そのため、.gitignoreを設定する

```:gitignore
#下記を追記
.env
```
これで、Gitにあげる心配がなくなりました

#####もし、Gitの管理下にあげてしまった場合
既にgitにpushしてしまっている場合下記のコマンドで
「.envファイル」をgitの管理から外せる

```
git rm --cached .env
```

####環境変数を呼び出す

呼び出しかたは.bash_profileと同様です。

```sample.rb
#設定した環境変数の呼び出し
ENV['KEY']
ENV['SECRET_KEY']
```

「**rails c**」 でも確認できるそう

```rb
irb(main):002:0> ENV['KEY']
=> '*******'
```

##参考記事
https://railsguides.jp/configuring.html
https://wa3.i-3-i.info/word11027.html
https://qiita.com/yuichir43705457/items/7cfcae6546876086b849
http://e-words.jp/w/%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0.html
https://qiita.com/hayatokunn/items/d8a9e9deec33e9022b4f
https://qiita.com/ryosuketter/items/ceb592dc6b23a20e51b5