OmniAICreator/Qiita-1.07M huggingface dataset:
5G(第5世代移動通信システム)基礎

5Gについて調べたことメモ。
多分に感想が入っているので参考程度で。

## 通信世代について
通信世代は移動通信システム(通信規格および規格に適合したネットワーク)に対して使われる言葉。
5Gまでの各世代概要
#### 1G：アナログ方式音声通話
#### 2G：デジタル方式音声通話、データ通信
1993年くらいから。PDCとか。テレホマン。
#### 3G(IMT-2000)：パケットでのデータ通信
2001年くらい。FOMA、CDMA、W-CDMAとか。
欧州標準、米国標準で仕様が割れた(IMT-2000問題)
さらに日本ではDocomoがドコモ標準で先行サービス開始。ガラパゴス化(後にドコモは欧州標準と統合)
3.5G（2006年くらい、HSPAとか）、3.9G（2010年くらい、LTE）とか上位互換を意識した規格も存在。
#### 4G(IMT-Advanced)：データ通信方式の世界標準化
2015年くらい。欧州標準と米国標準が統合。やっと世界標準に。
#### 5G(IMT-2020)：DX(デジタルトランスフォーメーション)ネットワーク基盤
IoTとかDXとかその辺のワードの下地を作る目的で2020年目処の商用化を目指している。
意訳すると世界標準仕様の4Gベースで以下を実現するネットワークを組むよー。ということらしい。

- 超高速(eMBB:enhanced Mobile BroadBand:拡張モバイルブロードバンド)
- 多数接続(mMTC:massive Machine Type Communication:大規模マシンタイプ通信)
- 超低遅延(URLLC:Ultra-Reliable & Low Latency COmmunication:超高信頼、超低遅延通信)

## 5G標準化に向けての課題
IMT-2020問題と呼ばれる2つの課題があるらしい。
問題というか覇権争い。。。
### 5G商用システムの主導権争い
「超高速」「多数接続」「超低遅延」の5Gサービスを2019年中に開始するよ。と中国が宣言している。
これに対し欧州、米国(と日韓)は「超高速」については多少見えているが、その他については商用利用開始時期が明確になっていない。つまるところ中国に先に5Gネットワークを構築されてしまって、5G構想の主導権を握られてしまうんじゃないの？という問題。

### グローバル周波数帯はどれになるの？問題
日米韓は5Gの周波数帯として28GHz、欧州、中国が推進しているのは26/33/42GHz帯。
これに対し2015年のWRC(世界無線通信会議:国際電気通信連合(ITU)主催の無線関連の国際規定を改定するための会議。法的拘束力あり）で28GHzが5G利用候補枠外とされたため米国が激おこした問題。2019年に開かれる予定のWRCでは28GHzも候補に追加する方向で丸く収まることが期待されている。

## 5Gへの移行プラン
5Gに関する仕様や規格が決まったとして実際どうやって移行していくのか。
#### NSA(Non-StandAlone)方式
ざっくり言うと、4Gの設備を流用して端末間の通信仕様だけを5Gにする方式。
メリット：設備は流用なのでコストと移行期間は節約できる。
デメリット：言うても4G設備なので通信速度はともかく、5Gが目指す多数接続や低遅延対応はできない(=なんちゃって5Gになる)
欧米日韓はこの方式で切り替えようと検討中
#### SA(StandAlone)方式
5Gのネットワークを4Gとは別に作る。ダイナミックに切り替える感じ。
中国はこちらの方式で商用ネットワークを作ろうとしている。

## 5GC(5G CoreNetwork)の拡張
5Gのキーワードとして以下のようなものがあるらしい。
### ヘテロジニアス(異種混合)ネットワーク
5G規格以外のプロトコルであったり周波数帯であったりしてもPDG(Packet Data Gateway)機能なるものを使って相互通信できるようにするよ。というもの。
機能部としてコンバータみたいなものを噛ませることでどうにかして5Gネットワークに乗せるみたいな仕組み全般を指すっぽい。
### MEC(Mobile Edge Computing)
端末に近いところでUPF(UserPlatformFunction)処理することで遅延低減させるぞ。という内容。
CPF(ControlPlatformFunction)処理は高速通信のネットワークスライスで賄って、通信量の多いユーザデータは低遅延用のネットワークスライス使ってエッジ経由で折り返すとかそういう構成をとることで実現する
【視聴メモ】Google Search: State of the Union (Google I/O'19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=ufcijo46LCU
Speaker(s): John Mueller, Martin Splitt

## Abstract

> Learn about the latest Google Search features and how to take advantage of the new APIs and capabilities to help optimize your content (text, images, and video) to be discovered on the Search results pages.

訳

> 最新のGoogleSearchの機能とどのようにしてそれらのAPIと能力をコンテンツがサーチ結果として見つかりやすいように最適化すればいいかを学びましょう。

## Contents

* SearchにとってWebサイトとは…
    * URLによってWebでホスティングされてる物体
    * 公にアクセスできるもの
    * Googleにページをインデックスすることを許可しているもの
* 新しいWebサイトはどうやってインデックスされるか（次のどれか）
    * すでにインデックスされているサイトからリンクされる
    * （roobts.txt で禁止されていないもの）
    * sitemap
    * RSS feeds
    * Indexing API
    * Search Console
* クローリングには時間がかかる
* 最近のWebサイトはただのHTMLではないですね（下記）

```
<body>
  <div id="app"></div>
  <script src="main.js"></script>
</body>
```

* Googlebot is now evergreen!
    * ご存知の通り
* 十分にテストしたので新しいGooglebotは間違いなく動作しますよ
* UserAgentを更新するときは必ず事前に告知します
* 変更しないというわけではないのでUAの対応はフレキシブルにできるように
* 時代はモバイル
    * モバイル端末を所有してる人は手を上げて
    * 手を上げてという質問に手を上げたくない人は手を上げて
* すでに50%以上のWeb閲覧はモバイルから行われている
* クローリングの際にモバイルかデスクトップかがURLで別れているとインデクシングがうまくいかないので、レスポンシブで表示できるようにしたほうがいい
* `www.`とか`m.`とかで分けないように
* Googleとしてどっちを提供すべきかわからなくなっちゃう
* ページの何がインデクシングされるか
    * title, meta, headings, text, images, videos
    * タイトルは検索クエリによってGoogleが勝手に変えるので意図した文字列が出なくても気にしないでね

**画像検索**

* 検索結果として出やすいのはページのトップにあって関連する語句の近くにある写真
* 構造化データを使って画像に関するデータを記述しよう
* URLはそれだけで意味がわかるものにしよう（IDや連番ではなく）
* cssの`background-image`ではなくimgのsrc+altで記述しよう
* レスポンシブな画像は`<picture>`で
* LazyLoadingする際には`IntersectionObserver`で実装されているものを使おう
    * ていうかimgタグで`loading="lazy"`しよう
* 画像はもはや画像検索の結果だけでなくDiscoverでも表示される

**構造化データ**

* schema.org を読んでいい感じにしよう
* レシピとかQAとかステップとかいろいろな方法にそれぞれ適した構造化方法があるので積極的に使っていこう

**Search Console**

* ドメインを追加してから4-5日でクロールされる
* ドメインごとにインデックスされてるページの数がわかる
    * されてないやつはなんでされてないのかがわかる
* 検索結果のパフォーマンスがわかる
    * インプレッション数・クリック数・CTR・検索順位
* 5XXが出たページを記録しておいてくれる
    * 直したらまとめてテストができる
* あるクエリに対する分析も見れる
* Duplex for web に対応するにはSearch Consoleでエラーがないように

## Memo

* SEOまわりは知らないことが多かったが、ようはお行儀よく丁寧に構造化してましょうということだと思う
    * 「正解のある書き方」が好きなので結構好き
【React.js】flowで型チェックを回避しつつArray型の項目をサーバー側へのPostパラメーターとして設定する方法

flowで型定義したReact.jsにて、Array型で定義したstate項目(前提： 中身は数字のみ)をサーバー側へのPostパラメーターとして設定しようとしたら以下のようなエラーメッセージが表示された。

~~~Node.js:flowの型チェック実行コマンド
npm run flow
~~~

~~~React.js:表示されたエラーメッセージ
Cannot coerce Array型state項目名 to string because array type [1] should not be coerced.
~~~

結論、該当のArray型項目をPostパラメーターに設定する際、JSON.stringifyする事でflowの型チェックエラーに抵触しないようにできた。

~~~React.js:Postパラメーター設定イメージ
params += `パラメーター項目名=${パラメーター項目となる変数名}&`;
params += `パラメーター項目名=${JSON.stringify(Array型項目となる変数名)}&`;
~~~

意外と、Array型項目をPostパラメーターの項目として設定する際のflowの型チェックエラーの対応方法を探すのに手間取った。。。。
【学習メモ】Rubyのモジュール，クラスにおけるメソッド

## はじめに
- Rubyのモジュール，クラスにおけるメソッドがどう動くのかわからなかったので書いて試してみた
- 初学者のメモなので参考にしないように

## 本文
```ruby
module ModA
	def  self.metA
		puts "This is metA."
	end
end
ModA.metA # Modモジュールのモジュールメソッド（という？）metAを呼び出す
module ModB
	def metB
		puts "This is metB."
	end
end
# ModB.metB # ERROR: metBはインスタンスメソッド（という？）であるからエラー

class Cla
	include ModA # ModAモジュールをClaクラスにmixin
	include ModB
	@@var = 5
	def self.metC
		puts "This is metC. --- @@var: #{@@var}"
	end
	def initialize
	end

	def metD
		puts "This is metD."
	end
end

puts "--- クラスメソッドのテスト ---"
# Cla.metA # ERROR: モジュールメソッドはincludeの対象にならない
# Cla.metB # ERROR: モジュールのインスタンスメソッドはインスタンスメソッドとしてincludeされる
Cla.metC # Claクラスのクラスモジュール metC によってクラス変数@@varを表示する
# Cla.metD # ERROR: metDはクラス内で定義されたインスタンスメソッド

puts "--- インスタンスメソッドのテスト ---"
ob = Cla.new # ewメソッドによってClaクラスのインスタンスを生成しobレシーバーに渡す．
# ob.metA # ERROR: モジュールメソッドはincludeされていない．
ob.metB
# ob.metC # ERROR: metCはクラスメソッドである．
ob.metD
```
```
This is metA.
--- クラスメソッドのテスト ---
This is metC. --- @@var: 5
--- インスタンスメソッドのテスト ---
This is metB.
This is metD.
```

- モジュールのメソッドをinclude, extendによってクラスにどのようにmixinされるのかを表した．

||MM|IM|
|:-:|:-:|:-:|
|include|-|IM|
|extend|-|CM|
- MM（Module Method）
- IM (Instance Method)
- CM (Class Method)

## おわりに
- なんとなくわかった
とあるRailsエンジニアのリモートワークトライアル 2019-06-04 on Twitter

# とあるRailsエンジニアのリモートワークトライアル 2019-06-03 on Twitter
 [*](https://twitter.com/YumaInaura/status/1135564381390028802")
<https://github.com/YumaInaura/YumaInaura/issues/2136>
# プログラミングってある程度、噛み込まないと、やっぱり美味しくならないよな。

 [*](https://twitter.com/YumaInaura/status/1135857737558966272")

# 業務ドメインの理解に比べればプログラムのコード理解はまだ明確な形があるだけやさしい。

 [*](https://twitter.com/YumaInaura/status/1135859498491338753")




# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Ethereum SmartContract（スマートコントラクト）の開発環境を構築する - Ropsten 編

# 概要

今回は一番環境設定が簡単な、WebのIDE環境で開発環境を構築していきます。
また、今回はEthereum NetworkのTestNet(Ropsten)を使用します。

# これから開発を始める皆様へ

Ethereum SmartContractのデプロイは、他の言語と異なる点があります。
具体的には、デプロイには費用（ETH）が発生します。
これは、デプロイ先がEthereum Networkになるので
Ethereum Networkの使用料が発生するためです。

# 1. MetaMask

MetaMaskは複数あるEthereum Network（Live, Test, Private）を切り替えてくれる、プロキシの役割をしてくれるツールです。

### インストール方法

MetaMaskはGoogle Chromeのプラグインでインストールすることができます。
詳しいインストール方法は、下記の記事が参考になります！！

>参考になった記事
>[Ethereum testnet (Ropsten)のアカウントを作成して1 ETH取得する手順](https://qiita.com/tmikada/items/cdc5a3871f655cb7b67d)


# 2. Remix（IDE）を表示する

Google Chromeで下記のURLを表示することで、開発がスタートできます。

https://remix.ethereum.org

#  3. コンパイルしてみる

`Remix`の画面をひらいて、`Start to compile`をクリックします。

<img width="1440" alt="スクリーンショット 2019-06-05 0.25.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/6acf9fbb-6dd8-f1f0-6923-52a5f479ca1c.png">

参考までに、今回使用したSource codeを下記のまとめておきます。

```js:SampleCode
pragma solidity ^0.5.0;

contract HelloWorld {
    
    constructor() public {
    }
   
    function get() public pure returns (string memory) {
        return "HelloWorld";
    }
}
```

# 4. デプロイしてみる

- まず、`Run`タブ内の`Deploy`をクリックする。

<img width="1440" alt="スクリーンショット 2019-06-05 0.47.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/457ef90a-9395-9d79-fdf5-28045705a29b.png">

- 次に、`確認`ボタンをクリックするとデプロイできます。

<img width="1440" alt="スクリーンショット 2019-06-05 0.49.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/aa376c21-e795-e198-16e5-93c0efa54bcb.png">

### 進捗を確認する

- コンソールに吐き出された、URLから進捗が確認出来ます。

<img width="1440" alt="スクリーンショット 2019-06-05 0.50.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/b88ca53c-4248-76f1-d0c3-eaede60c86cd.png">

- 赤線内の文字列が`Success`になったら、完了です。

<img width="1140" alt="スクリーンショット 2019-06-05 0.50.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/9bfe517e-ff06-71c9-bb44-827184e067e1.png">


# 5. functionを実行してみる

デプロイが完了したら、functionを実行してみましょう！
赤線内のgetをクリックすると、`Helloworld`の文字列が返ってくるのが分かります。

<img width="1440" alt="スクリーンショット 2019-06-05 0.53.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65794/abf7aeee-77b3-52be-d43d-db0ea1354b09.png">
【備忘録】Pipenv

Pythonのパッケージツールである[pipenv](https://pipenv-ja.readthedocs.io/ja/translate-ja/)の備忘録です。


### パッケージ名に数字が含まれていると、Pipfileのパッケージ名が二重引用符で括られる

`pipenv install`コマンドで`Pipfile`を更新すると、以下のように`Pipfile`内のflake8が二重引用符で括られます。


```
$ pipenv install yapf flae8 --dev
$ cat Pipfile

[dev-packages]
yapf = "*"
"flake8" = "*"
```

TOMLファイルとしては`flake8`を二重引用符でくくる必要はありません。

>Bare keys may only contain ASCII letters, ASCII digits, underscores, and dashes (A-Za-z0-9_-). Note that bare keys are allowed to be composed of only ASCII digits, e.g. 1234, but are always interpreted as strings.

https://github.com/toml-lang/toml#keys 引用


[Keys in Pipfile shouldn't be quoted, even when they contain numbers](https://github.com/pypa/pipenv/issues/1933)
[Why psycopg2 quoted in a Pipfile](https://stackoverflow.com/questions/55271712/why-psycopg2-quoted-in-a-pipfile)



### `--editable`の編集可能なパスとは？

https://ja.stackoverflow.com/questions/54746/ 参考

### プレリリース版をインストール
デフォルトではプレリリース版をインストールしません。
https://pipenv-ja.readthedocs.io/ja/translate-ja/diagnose.html#your-dependencies-could-not-be-resolved

# Better Pattern

### Pipenvのおすすめな方法
* 一般的には、 Pipfile と Pipfile.lock の両方をバージョン管理してください。

https://pipenv-ja.readthedocs.io/ja/translate-ja/basics.html#general-recommendations-version-control 引用

### setup.pyとの併用
>実行に必要なパッケージは setup.py で管理し、開発に必要なパッケージは Pipfile で管理する

https://techblog.asahi-net.co.jp/entry/2018/11/19/103455 引用

https://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#pipfile-vs-setup-py 参考




# 参考サイト
https://techblog.asahi-net.co.jp/entry/2018/11/19/103455
Qtでwindows用のデプロイパッケージを作成する　

Qtのバージョンは5.12.3
Qtのwindows用デプロイツールであるwindeployqtで作成します。
windeployqtはQtCreatorをダウンロードすれば通常付属しています。

PowerShellを使用してコマンドを実行。

## 1. リリースモードでビルドする
 Release用のビルドディレクトリにexeファイルがあることを確認してください

## 2. 配布パッケージ用のディレクトリを任意に作成しexeをコピー.

```
$ mkdir app-package
$ cp /build/release/XXX.exe /path/to/app-package
```
エクスプローラーでフォルダ作成＆コピー＆ペーストをしてもOK。

## 3. windeployqtでデプロイパッケージを作成.


### 前提: windeplayqtのあるbinディレクトリを環境変数に追加しておくこと。
Qtをインストーラーからインストールした場合はC直下にQtがおかれていると思います。

```
C:\Qt\5.12.3\msvc2017_64\bin
```

今回はmsvc2017_64bitのコンパイラを使っているので上記にbinディレクトリを追加しています。QtCreatorで設定しているコンパイラのアーキテクチャに一致するbinディレクトリを指定してください。

その他のアーキテクチャの例。Qt5.12.3には多数のC++コンパイラが用意されています。

```
C:\Qt\5.12.3\msvc2015_64\bin
C:\Qt\5.12.3\msvc2017\bin
C:\Qt\5.12.3\winrt_x86_msvc2017\bin
```

ちなみに、QtCreatorで設定したコンパイラと、環境変数に追加するbinのアーキテクチャが異なるとエラーになります。


## windeployqtを叩く
QtQuickを使用している場合 --qmldriでqmlのソースファイルがあるディレクトリを指定します。

```
$ cd <デプロイパッケージ用フォルダ>
$ windeployqt --qmldir C:\path\to\QmlRoot.\Hoge.exe
```

以上で、exeが正常に実行される。
 
参考：本家ドキュメント
[https://doc.qt.io/qt-5/windows-deployment.html](https://doc.qt.io/qt-5/windows-deployment.html)
比較的軽い気持ちでmacOS Catalinaを試そう

SwiftUI + Xcode 11をフルにお試しできるmacOS Catalinaを、できるだけ簡単に、かつ普段の環境に極力影響を与えることなく使ってみましょう。
※普段の環境に影響がないことを保証するものではないため、万が一のデータ破損・消失に備えてください。

# パーティションを区切らずデュアルブートできます
Mojaveをインストールしたアップグレード対象MacでAPFSフォーマットなら条件は満たしています。
2019/6/5時点ではもちろんApple Developer Programに加入している必要もあります。

![disk.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75820/08eb9ac3-cba3-dca6-a0c8-17ce3eef14e4.jpeg)

ディスクユーティリティの「パーティション作成」ボタンから、パーティションを作成せず「ボリュームを追加」[^1]。
[^1]: ボリュームの＋ボタンでも、対象SSDの右クリックメニューからでもいいようです。
その後Catalinaのインストーラーを起動し、インストール先を新規作成したボリュームにすればOKです。
OSの切り替えはBoot Campと同様に起動時Optionキーから。
詳しくは公式ドキュメントをどうぞ。
[個別の APFS ボリュームに macOS をインストールする](https://support.apple.com/ja-jp/HT208891)

# ボリュームならSSD容量を節約できます
「ボリュームを追加」する場合はこれ単体で領域を占拠せず、親のAPFSパーティションを共有します。
Catalinaのテストのために最大で何GB必要だろう……と悩む必要はありません。
[Mac の複数の APFS ボリュームで領域が共有されているかどうかを「システム情報」で確認する](https://support.apple.com/ja-jp/guide/system-information/sysp560a2952/mac)

# NDAに注意
Appleのβ版やPreview版の内容はNDA縛りがあるはずなので、うっかり中身に言及した記事を書かぬよう気をつけましょう。
本投稿はApple社の公開WebページおよびmacOS Mojaveの機能に基づいています。
Ruby, MechanizeでPOSTリクエストを送信して，Slackにメッセージを投稿してみた

#何をしたか
今回は，最近勉強しているRubyのMechanizeというライブラリを使って， Slackにメッセージの投稿をしてみました．

Mechanizeといえば，スクレイピングの際にフォーム入力とsubmitをコード上で行えることが魅力の１つだと思います．スクレイピングを勉強したての自分には遊ぶのがめちゃくちゃ面白いライブラリです．
そんなMechanizeですが，実はフォームがなくても,postメソッドなるメソッドを用いればPOSTリクエストを送信することができるそうです．
これとSlackが提供している Incoming WebHooks という機能を使うとこんなことができてしまいます．

![スクリーンショット 2019-06-04 22.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/1a04d1b6-6d01-f55f-57c5-2be364dc0a6e.png)

これは自分で打ってるんじゃありませんよ？Rubyのプログラムを利用してSlackに投稿してるんです！
しかもこの機能たったの5行で書けちゃいます．
ちなみに対話機能は今はないので，1人で会話してることになりますが，何かしら別の機能をつければ，Todoリストやら天気やら自分に通知できるはずです！　がんばれば対話もできるのではないでしょうか．
では以下やり方です．

#やり方
##環境
-Mac Mojave version10.14.4
-ruby 2.4.3
-Mechanize 2.7.6

##手順
1. slack Incoming WebHooksで　webhook urlを取得する
2. MechanizeのpostメソッドでSlackに投稿する

以上です!

##手順１ Slack Incoming WebHooksで　webhook urlを取得する
詳しくは別記事を書くので，もしよくわからなかったらそっちを読んでください

まず，以下のurlのxxxを自分のslackのurlに変えてアクセスしてください.slackのページ内のリンクからも辿れるでしょうがこちらの方が早いので．
https://xxx.slack.com/apps

1. 上のページのアプリ検索フォームで,**Incoming WebHooks** と検索し，アプリのページに飛ぶ
2. **Add Configuration**　を押す
3. Incoming WebHooksを追加したい Channel を選択して　**Add Incoming WebHooks Integration**　を押す
4. 最後のページで， **WebHook URL**が記載されてるのでコピーして使ってください

利用する際は対象のURLに以下のようなJSONをリクエストボディとしてPOSTリクエストを送信すればいいそうです．
`payload={"text": "This is a line of text in a channel.\nAnd this is another line of text."}`

##手順2  MechanizeのpostメソッドでSlackに投稿する
※遭遇したエラー対処法は後ほど別記事で紹介

postメソッドの仕様
 https://www.rubydoc.info/gems/mechanize/Mechanize#post-instance_method
`post(uri, query = {}, headers = {})⇒ Object`
第一引数に，リクエストを送信するurl
第二引数に，リクエストボディ
第三引数に，リクエストヘッダー
をいれればいいみたいです．
第二引数と，第三引数は上の式からもわかるように，　空の場合は空のハッシュが入ります．
ここは私は勘違いしてはまってしまいました．．
わかってる人は普通にわかると思うんですが，空の時にハッシュが入るだけで，ハッシュである必要はないんです！！

今回各引数は以下のようになります

第一引数→　**WebHook URL**
第二引数→　**JSON**
第三引数→　**空**

ここで第三引数が空でいい理由は実はよくわかってません．．HTTPリクエストの構造的にヘッダーは必要かと思われるのですが，いらないみたいです．（なくても通ります．）どなたかわかる方がいれば教えていただきたいです．

##コードと出力結果

###コード
xxxxxの部分は自分のものに書きかえてください

```
require 'mechanize'

agent = Mechanize.new
webhook_url = 'https://hooks.slack.com/services/xxxxx'
payload = '{"text" : "できました！"}'
agent.post(webhook_url,payload)
```

###出力結果
![スクリーンショット 2019-06-05 0.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/8cc945d2-b0e6-a01a-943e-8f4f493d8693.png)

送るJSONに
`"username":"好きな名前"`
や
`"icon_emoji":"アイコンのid"`
を指定することもできます
※アイコンのidはWebHook URL が載っていたページで調べることができます．

次のJSONを送った場合は
`payload = '{"username": "JARVIS","icon_emoji":":ghost:","text" : "完成！"}'
`
このような出力になります
![スクリーンショット 2019-06-05 0.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/1394b1e0-849e-0a66-0967-5f38c98f2718.png)



#終わりに

これでmechanizeの使用の幅を広げて，かつSlackで遊ぶことができるようになりました！
何か定期的にリマインドしてくれるbotか，ゆくゆくは対話できるものを作ってみたいと思います

ちなみにslackに投稿する場合は，今回の方法以外に slack-notifierというgem(ライブラリ)を使う方法もあります．その場合，コードはさらに短くなります．笑．　もしアイコンや名前の指定がincoming webhooksでしかできないのであれば今回の記事は役にたつかなと思います．ではまた．

slack-notifierを用いた時のコード

```
require 'slack-notifier'
notifier = Slack::Notifier.new(webhook_url) #事前準備で取得したWebhook URL
notifier.ping('Hello')
```
TypeScript を使って obniz で Lチカ

obniz SDK v2.1.0 がリリースされました！
https://github.com/obniz/obniz/releases/tag/v2.1.0

今回から型定義が導入されたため、TypeScript での開発が捗ります！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53393/78bfe96a-0d47-7a07-7a86-6e74e9ed4092.png" alt="" width="653">
こんな感じで...!!

ということで早速 TypeScript を使って obniz で Lチカをします。

## 開発環境

- PC: MacOS High Sierra 10.13.6
- Node.js: v10.15.1
- npm: 6.9.0 (or yarn: 1.15.2)
- TypeScript: 3.5.1

## Node プロジェクトの準備

1. 作業ディレクトリ作成

    ```bash
    $ mkdir work
    $ cd work
    ```

2. Node プロジェクト作成

    ```bash
    $ yarn init
    yarn init v1.15.2
    # package.json の設定は適当に連打
    question name (work): 
    question version (1.0.0): 
    question description: 
    question entry point (index.js): 
    question repository url: 
    question author: 
    question license (MIT): 
    question private: 
    ```

3. Node モジュールをインストール

    ```bash
    $ yarn add obniz
    $ yarn add -D typescript @types/node
    ```

4. tsconfig.json を準備

    ```json:tsconfig.json
    {
      "compilerOptions": {
        "sourceMap": true,
        "outDir": "dist",
        "target": "es6",
        "module": "commonjs",
        "moduleResolution": "node",
        "lib": ["es2018", "dom"]
      }
    }
    ```

5. npm scripts を準備 (規模が小さいので不要だけど)

    ```diff:package.json
      ...
      },
    + "scripts": {
    +   "build": "tsc",
    +   "start": "node dist/main.js"
    +   "clean": "rm -rf dist"
    + }
    ```

6. ソースコードを準備

    ```bash
    $ mkdir src
    $ touch src/main.ts
    ```

### 最終的なディレクトリツリー

```bash
.
├── node_modules
├── package.json
├── src
│   └── main.ts
├── tsconfig.json
└── yarn.lock
```

## Hello World!

```ts:src/main.ts
import * as Obniz from 'obniz';

const OBNIZ_ID = '1234-5678';

const obniz = new Obniz(OBNIZ_ID);
obniz.onconnect = async () => {
  obniz.display.clear();
  obniz.display.print('Hello World!');
};
```

### 実行

```bash
$ npm run build
$ npm run start
```

### 結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53393/40bf71e0-13e1-03c3-ca84-42bb3bcf9192.jpeg" alt="" width="256">

## Lチカ

```ts:src/main.ts
import * as Obniz from 'obniz';

const OBNIZ_ID = '1234-5678';

const obniz = new Obniz(OBNIZ_ID);
obniz.onconnect = async () => {
  const led = obniz.wired('LED', { anode: 0, cathode: 1 });
  led.on();

  setTimeout(() => {
    led.off();
  }, 3000);
};
```

### 実行

```bash
$ npm run build
$ npm run start
```

### 結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53393/09d66ccd-8109-0e53-4749-f2a4fd180c7f.jpeg" alt="" width="256">

## 最後に

本記事の内容は、
以下のリポジトリを `clone` すれば試せるはず...
https://github.com/chibi929/obnizxts

[obniz](https://obniz.io/ja/) は [パーツライブラリ](https://obniz.io/ja/sdk/parts) が豊富でサンプルコードも充実しているので簡単！
TypeScript でより開発が捗る
[Docker知識不要]Docker上でのHugo環境の作り方

# Docker上でのHugo環境の作り方

こんにちは、ITエンジニアの田中です！
この記事を読むと下記の事ができるようになります。

- Docker上でHugo環境を作れる。
- Docker上のHugoのコンテナに入り新規記事を作る事ができる。
- Docker上のHugoの簡易サーバーを動かしホストOSのブラウザから閲覧できる。

下記のことが事前に完了していることが前提です。

- Dockerがインストールされている
- ホストOSでgitが使用できる

## 私の最初の失敗

Docker Hubにある下記のイメージを使用してHugo環境を作成しようとしました。
publysher/hugo

しかし、起動に失敗。理由は多分事前にHugoのコンテンツがなかったことが原因です。
事前に環境がないから作りたいと思っていていたのでハードルが高い。。。。
もっと簡単に作りたい。そして、ローカル環境にgo開発環境を作らないで、かつあたかもローカルで記事を書いたりしたいと思っていました。

事前知識もなくHugo環境をdockerで作れる！方法を見つけたので共有します。

## フォルダ構成

docker-compose用の任意箇所にフォルダを作ってください。
フォルダ名をhugoとします。

hugoフォルダ配下に下記のファイルを作成します。
- DockerFile
- docker-compose.yml

## Dockerfile内容

下記のDockerfileを作成します。

```
FROM debian:stretch
LABEL maintainer "you1978 <you1978@hotmail.com>"

# Install pygments (for syntax highlighting) 
RUN apt-get -qq update \
	&& DEBIAN_FRONTEND=noninteractive apt-get -qq install -y --no-install-recommends python-pygments git ca-certificates asciidoc \
	&& rm -rf /var/lib/apt/lists/*

# Download and install hugo
ENV HUGO_VERSION 0.69.2
ENV HUGO_BINARY hugo_${HUGO_VERSION}_Linux-64bit.deb

ADD https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY} /tmp/hugo.deb
RUN dpkg -i /tmp/hugo.deb \
	&& rm /tmp/hugo.deb

# Create working directory
RUN mkdir /usr/share/blog
WORKDIR /usr/share/blog

# Expose default hugo port
EXPOSE 1313

# Automatically build site
ONBUILD ADD site/ /usr/share/blog
ONBUILD RUN hugo -d /usr/share/nginx/html/

# By default, serve site
ENV HUGO_BASE_URL http://localhost:1313
CMD hugo server -b ${HUGO_BASE_URL} --bind=0.0.0.0
```

## docker-compose.yml

下記のdocker-compose.ymlファイルを作成します。

```
version: '3'
services:
  web:
    build: .
    image: my/hugo
    volumes:
      - ./site:/usr/share/blog
    ports:
      - "1313:1313"
    stdin_open: true
    tty: true
```

## Hugoの新規サイトを作成する

ターミナルにて、Hugoフォルダに移動して、下記のコマンドを実行する。

```
> docker-compose run -w /usr/share web hugo new site blog 
```

実行するとHugoフォルダ直下siteというフォルダが作成されています。

## Hugoのテーマを適用する

下記のコマンドを使用して
ホストOS上でsiteの下のthemeフォルダに移動します。
今回はanankeというテーマを例として使用します。

```
> cd site/themes
> git clone https://github.com/budparr/gohugo-theme-ananke.git
```

下記のファイルを移動させてください.

移動元
 site/themes/gohugo-theme-ananke/exampleSite/config.toml

移動先
 site/config.toml

config.tomlを開いて、下記の行をコメントアウトしてください。

```
 # themesDir = "../.."
```

## Hugoイメージの構築

下記のコマンドを実行しHugoイメージを構築します。

```
docker-compose build
```

## Hugoの起動

下記のコマンドを実行しサイト

```
docker-compose up -d
```

## サイトにアクセスする

ブラウズを開いて、下記のURLをアドレスバーに入れてください。

```
http://localhost:1313/
```

下記の画面が表示されたら成功です。
![page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/c4f56a9d-8818-b2ea-548d-caff5a2def87.png)

## 新しいページを作成する

下記のコマンドを実行すると新しいページが作成されます。

```
docker-compose run web hugo new post/page2.md
```

下記のファイルを編集するとサイトも更新されます。
hugo/site/content/page2.md

大きく変更するとサイトが更新されない時があります。
その場合は、コンテイナを再起動してください

```
docker-compose down
docker-compose up
```

以上、[Docker知識不要]Docker上でのHugo環境の作り方でした。
コメントお待ちしています。
AWSの構成をまとめてみた

エンジニアバイトをしているところでAWSについて知る機会があったのでざっとまとめてみました。

## EC2
AWS上の仮想コンピュータのことです。AWS上の仮想コンピュータの単位をインスタンスという。

## ECS
EC2上にDocker化したアプリケーションをデプロイ、実行、管理することができる。

## タスク定義
アプリケーションの設計図。動かしたいアプリが何のコンテナで構成されているのかをjson形式でかいたテキストファイル。

## ECSサービス
タスク定義で指定した数だけのインスタンスを同時に実行し維持してくれる。もしタスクが何かしらの理由で停止したら、指定した数を維持しようと自動でタスクを立ち上げてくれる。

## ECR
コンテナを保管、管理するところ。

## ecs-agent
窓口の役割。ここをとおしてインスタンスないで稼働するコンテナを起動、停止などを管理する。

## ALB
アプリケーションロードバランサーのこと。ここがクライアントからの通信を受け取ってどのサーバーにリクエストを送るのかを判断してくれる。

### Lisner
ALBから受け取ったリクエストのプロトコルとポート番号をチェックし、設定されたものかを見てくれる。

### target group
設定されているプロトコルとポート番号から、登録しているインスタンスまでリクエストを送ってくれる。

## ざっと流れとして
GitHubからpushされたものがCircle CIに渡され、そこでデプロイされる。このときコンテナが立ち上がり、毎回ECRに保管される。立ち上げたコンテナはタスク定義をもとにEC2の仮想サーバー内のECS内で実行、管理される。
ユーザーはALBでリクエストを振り分けられ、リクエスト内のポート番号とプロトコルからどのサーバー内のアプリに送られるかがわかる。
pandasのDataFrameがto_sqlで保存できないときの対処法

pandasのDataFrameをMySQLに保存しようとしたときに、pandas.io.sql.DatabaseError: Execution failed on sql WHERE type='table' AND name=?;: not all arguments converted during string formattingとエラーが出て詰まったので解決した方法を残しておきます。


## サンプルソース

```sanple.py
import pandas as pd
import pymysql

data = {
  'red'  : ["apple"],
  'yellow': ["banana"],
  'orange' : ["orange"]
}
df = pd.DataFrame(data)
print(df)
##     データフレーム↓
#      red  yellow  orange
# 0  apple  banana  orange
```

例になりますが、私は上記のようなDataFrameをpandasのto_sqlを使ってMySQLに保存しようとしていました。
下記がその時のコードです。

```sample.py
import pandas as pd
import pymysql

data = {
  'red'  : ["apple"],
  'yellow': ["banana"],
  'orange' : ["orange"]
}

def mysql_connect():
    connection = pymysql.connect(
    host="localhost",
    user="root",
    db="sample_db",
    password="password",
    charset="utf8",
    cursorclass=pymysql.cursors.DictCursor)
    return connection

con = mysql_connect()
df = pd.DataFrame(data)
df.to_sql("table_name", con, index=None)
```
この方法でdbに保存しようとするとタイトルのエラーが発生してしまいました。原因を調べてみると、どうやら変数「con」にdbのコネクションを格納してto_sqlの引数に渡す方法はdbがsqliteの場合かsqlalchemy等を使ってマッピング(ORM)をしてあげないといけないらしいです。

こちらは参考にした記事になります
https://stackoverflow.com/questions/43136121/questions-about-pandas-to-sql

## 解決方法

今回はsqlalchemyを使うことで解決しました。

```sample.py
import pandas as pd
import pymysql
import sqlalchemy as sqa

data = {
  'red'  : ["apple"],
  'yellow': ["banana"],
  'orange' : ["orange"]
}

# データベースの情報を変数urlに入れています。
url = 'mysql+pymysql://root:password@localhost/sample_db?charset=utf8'
engine = sqa.create_engine(url, echo=True)
df = pd.DataFrame(data)
df.to_sql("table_name", url, index=None)
```

ちなみにデータベースのurl指定の書き方は以下になります(pymysqlの場合)

```
mysql+pymysql://<username>:<password>@<host>:<port>/<database>?charset=<charset_type>
```

詳しい書き方はこちらの記事が参考になります
https://www.st-hakky-blog.com/entry/2017/08/13/130202
BlenderからCharacterCreatorに自作Outfitsを取り込む手順

CharacterCreator(以下CC)に3Dソフトで自作した服装を取り込む手順をメモしておきます。
CCは使い始めたばっかりなんで、ワークフローに取り込めるか吟味中ですが、服飾品の試着が容易なので、モブキャラを生成するのに向いています。CCについては[こちら](https://www.reallusion.com/jp/character-creator/)を参照してください。

#制作環境
Blender2.79
CharacterCreator3.03

#最終イメージ
![cloth2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/9778f3ca-b962-04b2-3dad-422903d16110.png)
（........へそが出てるのは仕様です........ダ、ダサい.........）
#Blenderからfbxファイルで出力する
服のモデリング等は本筋から外れますので、割愛。モデリング済みと仮定して進めます。
始めに[ここ](https://www.reallusion.com/jp/character-creator/custom-outfit.html)からフィッティングのベースとなるボディテンプレートをダウンロードします。ページ上段の __テンプレートをダウンロード__ からダウンロードできます。
ダウンロードが完了したら、解凍し、**CC3_Body_Templates > Maya > FBX > CC3_Neutral_Maya_fbx** からfbxファイルをBlenderにimportします（テンプレートには男性、女性、中性型の三種が含まれますがなんでもいいです）。importに成功すると以下のような人間型ポリゴンが取り込まれるはずです。![CC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/168732ed-bb89-d0f5-cac9-0c2b228501ef.png)

importできたら、Armatureを親に自作したOutfitを子して、親子付けしてください。ウェイトをつける必要はないです。
![CC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/edaabbff-1a30-2ce1-2d2b-27faed29edb2.png)

次に、**Armature以下を全選択します**(ctrlを押下しながら選択すると、親子関係に含まれるもの全部を選択できます)。
で、File > fbxでexportします。
このとき、Add Leaf Bonesのチェックを外しておきましょう。つけっぱなしにしておいてもCCにfbxファイルは取り込めますが、エラーが大量に表示されるので消しておきます。
![CC3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/015d21c5-2c57-da06-5389-262236ae48a4.png)

Blender側での操作は終了です。

#CCにfbxファイルをimportする
Create > Cloth, Hair,... を選択します。
![CC4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/8cba1421-c52d-57ba-d73a-ef7e927180ea.png)
![CC5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/aa1097c4-f8b2-f854-aa4d-060223e53458.png)
fbxkeyファイルなるものを選択しないと、importさせてくれません。なので、冒頭でダウンロードしたテンプレートに含まれるfbxkeyファイルを設定しましょう。Blenderに取り込んだ人型モデルと同じ階層あるfbxkeyファイルを使います。
![CC6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/42921ab9-a6d4-e780-6512-16e334fc4e33.png)
Stateに<font color="Red">赤字でCritical</font>が出ていなければ大丈夫です。Warning?　無視します。
以上でimportは完了です。

#Outfitsのウェイト調整
![CC7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/3002aecb-3924-f72d-a3a0-1edfe977fe80.png)

importした段階ではおそらくウェイト付けが破綻しているので、CC側で再設定します。
![CC8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/edfee18e-80f1-af48-4a9b-d5d81650f755.png)
Sceneで取り込んだOutfitを選択し、
![CC9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/0e068fdb-3241-04d4-efc6-de043bba3bdb.png)
Transfer Skin Weightsから、
![CC10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/37b7700c-8a06-aeb8-1d01-e0331df60a6c.png)
DefaultをApplyします。
すると、
![CC11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/cded75af-e038-c68c-08ef-653eb6b3789c.png)
ウェイトが再設定されます。

###参考
https://forum.reallusion.com/291503/Blender-Workflow?PageIndex=1
https://developer.reallusion.com/cc_resource.html
Firebase Admin SDKを使ったPush通知

# はじめに
Firebase Cloud Messaging (FCM)を利用して、サーバからスマホへのPush通知を試してみました。サーバからFirebase経由でPush通知を送信する方法を書いていきます。具体的には、以下の図の赤枠の範囲になります。

<img width="300" alt="20190604-firebase-message-server-setup1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/454233fc-c767-0fc2-7ac8-4f70727414ce.png">




# 環境
- Python 3.7.3

# 準備

- Firebase Admin SDKをインストールします。
- 
```
$ pip install firebase-admin
```

- Firebase consoleからfirebase接続用の鍵ファイルを取得します。

 - 以下の図のように、Firebase consoleの左上にある歯車マークを押して、プロジェクトの設定画面を開きます。
 - この画面から「サービスアカウント」のタブをクリックします。
 - 「新しい秘密鍵の生成」ボタンを押すと、秘密鍵のファイルがダウンロードされます。

<img width="350" alt="20190604-firebase-message-server-setup1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/d1aa530f-7682-f3fd-2e69-b7c66ab70e65.png">

<img width="500" alt="20190604-firebase-message-server-setup2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/f884d726-fec0-b5fa-587d-f4fea9563573.png">


# 特定のスマホにPush通知

特定のスマホ(YOUR_REGISTRATION_TOKEN)へPush通知を送信します。
コードは以下です。`path/to/serviceAccountKey.json`は、ダウンロードした秘密鍵のファイルを指定します。

``` python
import firebase_admin
from firebase_admin import credentials
from firebase_admin import messaging

cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)

# This registration token comes from the client FCM SDKs.
registration_token = 'YOUR_REGISTRATION_TOKEN'

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='test server',
        body='test server message',
    ),
    token=registration_token,
)

# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
```

`YOUR_REGISTRATION_TOKEN`は、iosの場合は、以下のSWIFTのコードで取得した端末ごとのトークン(result.token)になります。

``` swift
InstanceID.instanceID().instanceID { (result, error) in
    if let error = error {
        print("Error fetching remote instance ID: \(error)")
    } else if let result = result {
        print("Remote instance ID token: \(result.token)")
        self.instanceID.text  = "Remote InstanceID token: \(result.token)"
    }
}
```

# トピックに参加しているスマホにPush通知
特定のトピックに参加している複数のスマホにPush通知する方法です。
例えば、"weather"のトピックに参加しているスマホにPush通知するときは、
メッセージの作成部分を以下のように変更します。
具体的には、`token`の部分を`topic`に変更するだけです。

``` python
message = messaging.Message(
    notification=messaging.Notification(
        title='test server',
        body='test server message',
    ),
    topic='weather',
)
```

iosでトピックへの参加は、以下のようなコードで実現できます。

``` swift
Messaging.messaging().subscribe(toTopic: "weather") { error in
    print("Subscribed to weather topic")
}
```


# 参考文献
- [サーバーに Firebase Admin SDK を追加する(公式)](https://firebase.google.com/docs/admin/setup/)
- [アプリサーバーからの送信リクエストを作成する(公式)](https://firebase.google.com/docs/cloud-messaging/admin/send-messages/)
Android開発者登録 2019年6月ver

# 前置き
参考にさせていただいた記事とそこまで乖離ないですが、微妙に画面とか操作が異なったので書かせていただきました。

# 準備
- Googleアカウント
- クレジットカード($25)（2019/6/4時点:2,755円）  
 ※Appleと違って、初回に支払いすればオワリ。年会費はかからなそう。

# 手順
2. developerページにアクセス：https://developer.android.com/index.html
3. ヘッダーメニューの右側からログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/40d8ef54-6ae8-88ac-17af-47dc18b6f15b.png)
4. 開発用に使用したいアカウントを任意に選択してログイン
5. 上部メニューより、Google Playを選択：https://developer.android.com/distribute
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/57b1e939-8187-ae26-db60-0eec695695ee.png)

6. PLAY CONSOLEを起動：https://play.google.com/apps/publish/signup/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/a3124c3c-7db0-8c0e-2a4a-7e43235a5f9d.png)
7. Google Playデベロッパー販売/配布契約書を読み、同意(チェック)する＆支払いに進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/3e7f7df0-7a09-0f36-caa8-8fc90206253c.png)

7. 必要情報を入力していく
    8. デベロッパー名：サークル名入れました
    9. メールアドレス：Googleアカウントに紐付くもの（ログインしてるから自動入力されても良いのに……）
    10. ウェブサイト：サークルのHPアドレス入れました
    8. 電話番号：「+81-」を頭につけて、+81-90-XXXX-XXX




# 参考
[Android開発者登録 2018年3月Ver.](https://qiita.com/nao_design/items/b360454c89c2bebf4d22)
【Blender】衝突で勢いよく飛び散るシミュレーション（cell fracture）

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Blender v2.79.6
⭐️Mac Book

↓↓完成した内容
https://twitter.com/nonnonkapibara/status/1135914166282096643

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">🍧Blender🍧<br>衝突で、勢いよく飛び散る<br>⭐️シミュレーション⭐️試してみたよぉ<br>何だか、作ってて気持ちいい〜😍爽快💫<br>そして🌻逆再生🌻ができるのね😊<br>Blenderってすごいなぁ👏<a href="https://twitter.com/hashtag/blender?src=hash&amp;ref_src=twsrc%5Etfw">#blender</a> <a href="https://twitter.com/hashtag/Blender3d?src=hash&amp;ref_src=twsrc%5Etfw">#Blender3d</a> <a href="https://t.co/4Vn7I3gIi1">pic.twitter.com/4Vn7I3gIi1</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1135914166282096643?ref_src=twsrc%5Etfw">June 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<img width="1101" alt="スクリーンショット 2019-06-04 23.38.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/fdf238bf-bb30-e02e-f8b0-fb7c00b04ca8.png">

<img width="858" alt="スクリーンショット 2019-06-01 23.54.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/fd3fb567-ebf5-f136-4e33-d9c1edd0d08d.png">

<font color="Magenta">
キャプチャ画像が多いので
続きは、「はてなブログ」に記載してます↓
</font>

[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2019/06/05/000015)

<br><br><br><br><br><br>
Launch Cloudbreak 2.9.1 from the quickstart template on AWS

Cloudbreak 2.9.1 Document:
https://docs.hortonworks.com/HDPDocuments/Cloudbreak/Cloudbreak-2.9.1/quickstart-aws/content/cb_launch-cloudbreak-from-the-quickstart-template-aws.html
Launch Cloudbreak from the quickstart template on AWS

## リージョンを選択
<img width="1177" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/52d47aa8-61cd-ef21-ffd6-1f46648e0a8e.png">


<img width="1335" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/e80fd8a8-bc98-3f0e-21ce-8c4a08bd8b20.png">
Python で sqlite3 を触るときに null をそれっぽく書いて見たかった。


```python
null = type(str(), tuple(), dict(__repr__=lambda self: 'null'))()
user_name = 'Donald Trump'
f'INSERT INTO user VALUES {null, null, user_name}' 
```
```
>>> f'INSERT INTO user VALUES {null, null, user_name}' 
"INSERT INTO user VALUES (null, null, 'Donald Trump')"
>>> 
```

autoincrement するときは null とかを使っても便利というのは stackoverflow 先生が教えてくれた。

* [SQLite autoincrement - How to insert values? - stackoverflow](https://stackoverflow.com/questions/8250814/sqlite-autoincrement-how-to-insert-values/32758876#answer-32758876)
Railsで短縮できるコマンド一覧

Railsでは、コマンドを打ってローカルにサーバを起動させたり、作成したアプリケーションのテストなどさまざまなことができます。
そのコマンドの中でも、短縮して実行できるコマンドがいくつかあります。
なので、ぜひ参考にしてコマンドを打つ作業時間の短縮を体験してみてください。

## Railsで短縮できるコマンド
この記事の読み方としては、上に「元（短縮しない形）のコマンド」。
下に「**短縮した形のコマンド**」という感じで読み進めていってください。

### ローカルにてサーバを起動する
ローカルにてサーバを起動するコマンドです。

```
rails server
```

↓ 短縮すると

```
rails s
```

### 作成したアプリケーションのテストを実行する
作成したアプリケーションのテストを実行するコマンドです。

```
rails test
```

↓ 短縮すると

```
rails t
```

### コントローラやモデルの生成する
コントローラやモデルを生成するコマンドです。

```
rails generate
```

↓ 短縮すると

```
rails g
```

### コンソールを実行する
コンソールを実行することで、Rubyのコードを使用できるようにするコマンドです。

```
rails console
```

↓ 短縮すると

```
rails c
```

### Gemfileに指定されたGemをインストールする
Gemfileに指定されたGemをインストールするコマンドです。

```
bundle install
```

↓ 短縮すると

```
bundle
```

### 最後に
Railsでの短縮コマンドは以上になります。
また、 [Railsドキュメントのrailsコマンド(rails)](http://railsdoc.com/rails "Railsドキュメントのrailsコマンド(rails)")では、ここでは紹介しきれないRailsのコマンドがいくつも書かれてあるので、ぜひ参考にしてください。
Railsでの短縮コマンドを知らなかったという人は、この記事を機にこれから短縮コマンドを使って作業時間を短縮していきましょう。
PyTorchとNumpyでsortのベンチマーク

#PyTorchとNumpyでSortを簡単に計ってみた。
PyTorchでは、sortアルゴリズムとして、クイックソート(quick sort)と基数ソート(radix sort)を使っている。クイックソートは、PyTorchベタに実装されているものであり、基数ソートはCUDAのライブラリthrust::sortで実装されている。また、numpyは基本はクイックソートであるが、それ以外のアルゴリズムも実装されている。

以下のコードで測定したので、Pythonから見て純粋な計算時間である。ここでは、2次元テンソル(100x100, 1000x1000, 10000x10000)て調べた。

```
import torch
import numpy as np
a = torch.randn(100,100)
b = torch.randn(1000,1000)
c = torch.randn(10000,10000)
%timeit torch.sort(a,1)
%timeit torch.sort(b,1)
%timeit torch.sort(c,1)
a = a.cuda()
b = b.cuda()
c = c.cuda()
%timeit torch.sort(a,1)
%timeit torch.sort(b,1)
%timeit torch.sort(c,1)
d = np.random.randn(100,100)
%timeit np.sort(d,1)
e = np.random.randn(1000,1000)
%timeit np.sort(e,1)
f = np.random.randn(10000,10000)
%timeit np.sort(f,1)
```
上のデータをpandasでプロットする。CUDA(Tesla T4)のほうが、2桁近く性能改善している。なお、K80でも2倍程度時間がかかるだけでそれでも早いことがわかる。また、CPUでの単純な比較では、numpyがpytorchより2割程度性能が良い。なお、xは上記の要素数。yはマイクロ秒(usec)である。

![sort_t4_k80.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153471/273a0348-1bca-675a-7492-b0119d034e8e.png)
上の図を描画するスクリプトは以下である。なお、日本語化したい場合、Japanize-matplotlibを使えば、2行追加で日本語化(IPAゴシックフォント化)できる。

```
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'x': [100, 1000, 10000], 'torch_cpu': [403, 57200, 7190000],
                    'torch_cuda_t4': [25, 782, 401000], 'torch_cuda_k80' : [37, 1640, 694000],
                    'numpy': [289, 44000, 5850000]})
fig, ax = plt.subplots(figsize=(5, 3))
df.set_index('x').plot(
    ax=ax,
    logy=True
)
ax.set_title('Sort elapstime (usec)')
#ax.set_xlabel('')
ax.set_ylabel('y')
plt.show()
```

#参考資料
- ソースコード
    - [at::sort](https://github.com/pytorch/pytorch/blob/v1.3.0/aten/src/ATen/native/native_functions.yaml#L5168)
       - [THCTensor_(sort)](https://github.com/pytorch/pytorch/blob/v1.3.0/aten/src/THC/generic/THCTensorSort.cu#L296) (CUDAの場合)
          - PyTorchのCUDAでは、スライス時一定サイズ(2048要素)以上のソートは、thrust::sortを用いている。
              - [thrust sorting](https://thrust.github.io/doc/group__sorting.html)
       - [THTensor_(sort)](https://github.com/pytorch/pytorch/blob/v1.3.0/aten/src/TH/generic/THTensorMoreMath.cpp#L675)(CPUの場合)
- [uehara1414/japanize-matplotlib](https://github.com/uehara1414/japanize-matplotlib) matplotlibの日本語化
    - [matplotlib日本語対応](https://yolo.love/matplotlib/japanese/)　日本語化matplotlibの使い方
    - (余談)seabornを使う場合、sns.set()を実行すると、[フォント設定が上書き](https://github.com/uehara1414/japanize-matplotlib/issues/1)されてしまう。このため、そのあとにimport japanize-matplotlibとする必要がある。
pip install jupyter を叩くと -bash: pip: command not found と表示される場合

# 事象

表題の通りですが、以下のようになってしまいました。

```
$ pip install jupyter
-bash: pip: command not found
```

# 対処方法

どうやらパスが通ってないとのことで、絶対パスを調べました。
`Anaconda` をちょうど入れたばかりでしたが、ここで役に立つんですね。

 - 参考：[【PYTHONエラー】PIPでインストールできない　PIP: COMMAND NOT FOUND](https://tabinou.com/archives/1259)

```
$ find / -name pip
...(中略)...
/anaconda3/bin/pip
...(以下略)
```

ということで絶対パス指定で再度コマンド実行して、無事インストール完了しました。

```
$ /anaconda3/bin/pip install jupyter
(出力省略)
```

ちなみに `jupyter` コマンドも効かなかったので、同じように対応しました。

```
$ jupyter notebook
-bash: jupyter: command not found

$ find / -name jupyter
...(中略)...
/anaconda3/bin/jupyter
...(以下略)

$ /anaconda3/bin/jupyter notebook
(出力省略)
```
rails6から追加される`ActiveRecord::Relation#pick`について

# ユースケース

たとえば、年齢20歳以上絞り込んだユーザー1人のidを取得したいとき

# よくある書き方

以下のように書くことで`id`が取得できますが、この書き方だとパフォーマンスが悪くなる事もあります。

```ruby
User.where("age > 20").pluck(:id).first
```

この処理を行った場合、以下の処理が実行されます。

1. `where`でレコードを絞り込み
2. `users.id`のリストをアプリケーションに返す
3. `users.id`のリストから`Array`を生成
4. 生成した`Array`に対しrubyの`Array#first`で1件抽出する

この場合、アプリケーションで1件しかデータを使用しないのにDBは該当する全てのデータを返すので余計な処理やリソース消費が発生します。

# 対応

limit句を使用してあげます。
limit句を指定する事でDBはレコードを1件見つけた時点で検索を止めて結果を返すので高速になります。(全ての場合に高速になる訳ではありません。)

```diff
- User.where("age > 20").pluck(:id)).first
+ User.where("age > 20").limit(1).pluck(:id)).first
```

# rails6から追加される`ActiveRecord::Relation#pick`

上の`.limit(1).pluck(:id)).first`のショートハンドがrails6の`pick`メソッドです。
このメソッドを使用する事でさらに簡潔にコードを記述する事ができます。

```diff
- User.where("age > 20").limit(1).pluck(:id)).first
+ User.where("age > 20").pick(:id)
```

## 実装を確認する

そのまんま

```ruby:activerecord/lib/active_record/relation/calculations.rb
def pick(*column_names)
  limit(1).pluck(*column_names).first
end
```
「登録まで最大で2営業日ほどお時間を頂いております」

# 結構時間かかるのね
- 一昨日みた[@nayuneko:Go言語で東京メトロAPIを叩く](https://qiita.com/nayuneko/items/ca2651e3a613c8e3256a)にのっていたコードを勉強の為サンプルコードとして実際に実行してみようと思ってサイト見た
- 「登録まで最大で2営業日ほどお時間を頂いております」と書いてある。結構時間かかるのね（汗
- そんなこんなで今日は出来ないけど、一昨日に比べて少し方向性が見えてきた気がする

# 今日の気持ち
- 「上手く、正常に動作しているコードを一先ず動かしてみる」「中身を見て動作を学ぶ」「自分の要件に合わせて部分的に修正し、動くか試してみる」今までOSの設定等で当たり前にやってきた事だけど、今回初めてのプログラミングと言う事あって初心を忘れていた
- しかしこれが当たり前に効果があると最近痛感してきた。真似てみる、真似ぶは学ぶとはまさにその通りだと思った
- [「GIZMODO@6時間以下の睡眠は徹夜するのと同じだった」](https://www.gizmodo.jp/2019/05/new-year-holidays-spent-doing-nothing-zzz.html)を見たので昨日はそうそうに寝てしまった。でも確かに最近そうだと思う。そんな訳でちゃんと7時間睡眠しよう。おやすみなさい
Visual Studio Code[VS Code] のインストールと日本語設定

# 初めに
英語の勉強だと思って英語表示でVisual Studio Codeを使っていたけど
結局日本語が便利そうだと気付いたのでインストール手順をメモ

# 環境
windows 10

# インストール
ここからインストールしてください
https://code.visualstudio.com/download

# 日本語設定
VS Codeは最初は英語設定だが、拡張機能を使って日本語設定にすることができる。
Extensions で「Japanese Language Pack For Visual Studio Code」を選択、インストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426354/aa13630a-6a1d-100f-fc43-11c58fe00085.png)

その後再起動すると日本語表示になった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426354/12ca08f9-b5b7-9dd4-a8aa-8e93623d6d1e.png)

ならない場合、viewからcommand palette(```Ctrl + Shift + P```でも開く)
configure display languageで"ja"を選択

# 最後に
Visual Studio Codeは文字補完、git連携、拡張機能の多さでめちゃめちゃ便利だと感じています。
ぜひ使ってみてください！
Rubyのスタイルガイドを公開している企業をまとめてみた

# はじめに
業務でRubyの社内コーディング規約を作成することになり、他社の例を参考にしようと調べてまとめてみました。

# スタイルガイド公開企業

###Cookpad
おなじみのCookpad社のスタイルガイド。[SHOULD]と[MUST]で分けてあるのがいいなと思いました。
https://github.com/cookpad/styleguide/blob/master/ruby.ja.md

### Shopify
カナダ発のECプラットフォームを提供する企業であるShopify。例で示されていない部分も結構あるので、英語に慣れていないと読みづらいかもしれません。
https://shopify.github.io/ruby-style-guide/

### Airbnb
民泊でおなじみのAirbnb社。個人的には、最も参考にしたいと思えるぐらい腑に落ちました。
https://github.com/airbnb/ruby

# 最後に
調べたもののあまり見つけられなかったので、もし「この会社もスタイルガイドを公開しているよ」ということがあれば教えていただけると幸いですし、今後も随時追加するつもりです。
外部パッケージ依存のあるElixir scriptを簡単に走らせる

# 何が嫌か
Elixirで例えば[HttPoison](https://github.com/edgurgel/httpoison)やら[Jason](https://github.com/michalmuskala/jason)やらを使ってサクッとスクリプトを書いて実行したいのにサクッとならない。

mapをjsonにエンコードする以下のようなスクリプトを書いたとして

```elixir
%{foo: "bar"}
|> Jason.encode!
|> IO.puts
```

これを普通に`elixir`コマンドで実行しようとすると

```
$ elixir foo.exs
** (UndefinedFunctionError) function Jason.encode!/1 is undefined (module Jason is not available)
    Jason.encode!(%{foo: "bar"})
    foo.exs:2: (file)
    (elixir) lib/code.ex:767: Code.require_file/2
```

怒られる。世知辛い世の中。

当然といえば当然で、プロジェクトマネージャたる`Mix`を使うとパッケージはグローバルにインストールされることはない。というかできない。
これはこれでプロジェクトごとにパッケージがクリーンに保たれるので、某pythonみたいにvirtualenvなんてものを考える必要はない。
その点でelixirおよびmixは素晴らしいと言えるのだが、時々こういう感じで困る。

# 結局どうしたか
escriptにdependencyを全部ぶち込んでElixir scriptを動的に読み込んで実行することでだいたい解決できた。
以下に`erun`として公開している（驚くほど実装の中身がない）。
[s417-lama/erun](https://github.com/s417-lama/erun)

Jasonをdepsに指定すればさっきの例は以下のようにちゃんと実行される。

```sh
$ erun foo.exs
{"foo":"bar"}
```

## 使い方

(1) cloneする

```sh
git clone git@github.com:s417-lama/erun.git
```

(2) `mix.exs`をいじって好きなdepsを指定する

```elixir
  defp deps do
    [
      {:super_package, "~> 1.0"},
      ...
    ]
  end
```

(3) deps.get

```sh
mix deps.get
```

(4) コンパイルしてインストール

```sh
mix escript.install
```

(5) 使ってみる

```sh
$ erun -e "IO.puts :hello"
hello
```

あと、地味に`Erun.args/0`を呼ぶと引数を取得できる。

```sh
$ erun -e "IO.inspect Erun.args" foo bar 1
["foo", "bar", "1"]
```

# 何ができないか
`iex`でグローバルなパッケージを読み込みたいが、`erun`ではできない（スクリプト限定）。
なにか良いアイデアはないでしょうか...？
フッターの位置の変更

自分でサイトを作っていた時にこのようになってしまいました。![footer problem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423166/4a490706-29c2-0c63-61cd-60c82f7abad4.png)

画像の中に入っている文字が実はフッター要素で記述している部分なんです。
しかし、main要素である画像の上に表示されています。
この問題をどう解決したかを説明します。

##position:absolute;を用いて、フッターの位置を下に固定する
```
pisition:absolute;
bottom:0;
```
このように記述することでフッターの位置を一番下に固定できます。
[Taneppa!](https://taneppa.net/footerbottom/) こちらのサイトを参考にさせていただきました。より詳しい解説はこちらをご覧ください。


##フッターの要素を取り出す
実は上の方法では私の問題は解決できませんでした。
そこで今回は,

```
<main>
　問題があったfooter内のcode
</main>

<footer>

<footer>
```

このように力技になりますがfooter内で書くことを諦め、mainタグ内の一番下に記述する。
その後上で説明したpositionで位置を固定することでフッターのように見せることが出来ました。
下が変更後のページになります。

![footer improve.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423166/d413dbc6-5c4b-020e-c641-3dbd9c98e723.png)


以上が私の解決策になります。
他の解決策があれば、アドバイスお願いいたします。
Go言語　一行づつ、ファイルに文字を追加して表示する

#1行づつ、ファイルの末尾にファイルを追加と表示
go言語で1行づつファイル読み込みと末尾に一行文字列を追加する方法です。


```go:linewrfile.go
package main

import (
	"bufio"
	"fmt"
	"os"
)
//ファイルの存在確認
func fileck(filename string) bool {
	_, err := os.Stat(filename)
	return err == nil
}
//ファイル読み取りその結果を行列出力
func fileread(filename string) []string {
	var output []string
	var fp *os.File
	var err error
	if !fileck(filename) {
		return output
	}
	fp, err = os.Open(filename)
	if err != nil {
		panic(err)
	}
	defer fp.Close()
	readline := bufio.NewScanner(fp)
	for readline.Scan() {
		output = append(output, readline.Text())
	}
	return output
}
//ファイル書き取り、ファイルが存在しない場合は作成
func filewrite(filename string, word string) {
	var fp *os.File
	var err error
	if !fileck(filename) {
		fp, err = os.Create(filename)
	} else {
		fp, err = os.OpenFile(filename, os.O_RDWR|os.O_APPEND, 0666)
	}
	if err != nil {
		panic(err)
	}
	defer fp.Close()
	fmt.Fprintf(fp, "%v\n", word)
}
func main() {
	filewrite("memo.txt", "aa")
	fmt.Println(fileread("memo.txt"))
}
```
実行すれば、memo.txtが出来上がり、aaという文字列ができます。
実行ごとに行が増えていきます。
GitHubの複数レポジトリを同一アカウントでデプロイ（Deploy Key利用）


Github の Deploy keys は、他のレポジトリで利用している公開鍵を登録しようとすると"Key is already in use"とのエラーが出て登録できません。そのため、レポジトリごとに Deploy kyes の鍵を変える必要があります。

普通はレポジトリごとにサーバーのアカウントを変えて Key も変えるものだとは思いますが、あえて同じアカウントでデプロイしたい場合の設定を調べてみました。

## .ssh/config での設定も可能だが…

調べてみるとすぐに .ssh/config でレポジトリごとにホスト名を変えて鍵を切り替えましょう、との説明が見つかりました。

確かにそれでも実現可能なのですが、できれば .git/config などで設定できないか、と試行錯誤したところ以下の設定にたどり着きました。

## Git 側で使用する鍵を切り替える方法

1つめのレポジトリはいつも通り ~/.ssh/id_rsa.pub を使って登録で大丈夫です。
2つめのレポジトリ以降は以下の手順で Clone します。

### 新しく鍵を作成

```bash
cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "Githubに登録したメールアドレス" -f 鍵の名前
``````

### 作成した公開鍵をレポジトリの Deploy Keys に登録する

https://github.com/アカウントID/レポジトリ名/settings/keys から登録します。

### 鍵を指定してレポジトリを Clone、その後利用するSSHコマンドを設定

```bash
# 鍵を指定して clone
GIT_SSH_COMMAND='ssh -i ~/.ssh/鍵の名前' git clone git@github.com:アカウントID/レポジトリ名.git
cd レポジトリ名
# 利用するsshコマンドを設定
git config --local core.sshCommand 'ssh -i ~/.ssh/鍵の名前'
```

これで、git pull する際も作成し指定した鍵が利用される状態になります。
NoOps Meetup Tokyo #6 参加レポート

２０１９年６月４日（火）に開催された「NoOps Meetup Tokyo」第６回 の参加レポートです。
[NoOps Meetup Tokyo #6 (connpass)](https://noops.connpass.com/event/131553/)

<img width="652" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65426/a3206833-c2ff-1742-1050-e5277e777704.png">

# オープニング
岡 大勝 さん（NoOps Japan 発起人）
<img width="408" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65426/103c8332-2cfe-deb4-cf54-80498b88f929.png">

共感駆動のSRCAサイクル「共感」⇒「尊重」⇒「貢献」

# 今日のセッション
<img width="399" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65426/c07b7f3a-b2eb-0021-6de6-7366d5956891.png">

## [Observability を支える Stackdriver](https://docs.google.com/presentation/d/e/2PACX-1vTkcZYwxRDJYZgWI2E4Iewklb_ojKskVty5-4sl7T8VwKekqTQPrf0kku6p7dz7lriqxccGBrTJTmb9/pub?start=false&loop=false&delayms=3000#slide=id.g48a57ebc11_0_0)
山口 能迪さん（Google）

## [物理データセンターでも NoOps](https://speakerdeck.com/ymmt2005/wu-li-detasentademo-noops)
山本 泰宇さん（サイボウズ）

## [NoOpsを実現するSREの存在意義と役割](https://speakerdeck.com/katsuhisa91/class-sre-implements-noops)
かつひささん（スタディスト/SREラウンジ）

## パネルディスカッション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65426/899c3255-8f6a-884b-c6af-05ce021063b8.png)

-  どうやってNecoメンバーのスキルを集めたのか？
  - １から育てている。
- 属人性の排除について（共通化と属人性について）
  - 昔は、人が変わっても業務は変わらない。
  - 今は、毎年変わる。Googleでも毎年新サービスが出てくる。
  - そうなると、人が重要となってくる。
  - SECIモデル。暗黙知を共有化。
  - 属人性は暗黙知の塊。これを表面化して落とし込む。
- 技術の共有化をどうやっている？
  - スキルマップを作成している。
- SRE、NoOpsの実現の為に、チームの価値観、文化の醸成をどうやっているか
  - ワンクリックでロールバックできるようにしておくなどをして、  
個人の責任にしないようにシステムでフォローする。
  - トップダウンでは変わらない。
  - お互いやりたいことに併せていくと相互理解が進む。
  - 無理にしないことも大事。
  - 25,000人の開発。すべてシステムでルールが決められている。
  - 公用言語が決まっている。目視のレビューもある。
  - テストで壊れたら壊した人が直さなければならない。
  - ルールが決まっている。人間に責任を押し付けるのではない。
  - そういう仕組みになっている。 
  - SREは継続的に提供するところで役立つ。
  - ビジネス的な決定権を持った方に理解を求める。
  - ２０年以上固い会社でアーキテクチャーを導入しようとしたが、だめなものはだめ。
  - 心理的安全性は大事。怖くない状況。
  - ビジネスサイドの方の心理的安全性が担保されていない？
  - 経営の立場の方に、どうしたら安心してもらえるか。
- どうやってインシデントコマンダーを育てているか
  - スキルマップを見て、育てる。
  - インシデント発生時は、アプリケーションを開発しているチームとSREチームが入る。
  - スキルが足りないなら別の人も入る。
  - セカンダリとして入ってプライマリのやっていることを覚えさせる。
    
## その他
- [「システム開発で属人性を排除したらダメ」有名ITアーキテクトが指摘 (日経XTECH)](https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00138/053100293/)
- [Cloud Native Days Tokyo 2019](https://cloudnativedays.jp/cndt2019/)
- [de:code 2019 振り返り Night!](https://connpass.com/event/132783/)