OmniAICreator/Qiita-1.07M huggingface dataset:
Microbitで明るさ測定　小学校家庭科授業「快適さ」とは

###小学校家庭科授業　「快適さとは」Microbitで明るさ測定

プログラミング教育の必修化ということで、Microbitを小学校の先生に教えたところ、その先生がプログラミング教育にMIcrobitを取り入れた研究授業を行い、その手伝いをしました。

研究授業は家庭科の単元（5年生対象）で、「快適さ」というテーマで、身の回りの環境（明るさや温度）を測ることで「快適さ」について考える授業でした。
そこで、Microbitを使って、明るさや温度を測って、数値化、可視化することを行いました。
Microbitには、前面のLED25個のところに光センサーが入っています。（「明るさ」センサーはLEDとの兼用。LEDが光っていないのとき「センサー」になる。センサーの数値は「0」〜「255」。）また、裏面に温度計が入っています。
[照度計の説明](https://microbit.org/ja/guide/features/#light)
[照度計の原理説明](https://www.timeless-education.com/using-sensors-of-microbit-3979.html)


####実際に授業で使ったプログラム

![kateika1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/fcd3205f-a856-99d4-8026-b4d9aed08677.png)

######コードの解説

Aボタンを押すと明るさの測定を行います。明るさを変数に入れてもよいのですが、子どもたちが変数に慣れていないこともあるので、変数は使っていません。
LEDブロック中に棒グラフ表示のブロックが入っています。グラフ表示の後、一時停止を入れないとグラフがすぐに消えてしまいます。
このプログラムでは、グラフで表示した後、数値を読み取るために数値を表示しています。
Aボタンのプログラムを作った後、プログラムの複製でBボタンのプログラムを作ります。値、最大値、を変更することで温度センサーを作ることができます。
このプログラムを入れたMicrobitを使って、教室や廊下の明るさや温度を測って表にまとめるました。そして、「快適さ」について考えました。
小学校では、Microbitを20台用意して授業を行いました。これを子どもたちに貸し出し、家庭でも測ってくることが課題として出されました。

####少し改良したプログラム

![kateika2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/e4912b2e-5256-6f14-f697-558c555ac95f.png)


#####コードの解説

このプログラムが動いているかどうかわからないので、初めにのブロックに何らかの文字列を入れます。
ここでは「OK」と入れています。また、7秒ごとに動いていることを確認するために矢印を表示します。
さらに条件分岐を入れて明るさの値ごとに何か表示する、音を出すなどがあってもよいかもしれません。

###手伝って感じたこと
#####Microbitの明るさセンサーのばらつき
20台もあると中には、感度の極端に低いものや、高いものなどMicrobitにばらつきがあります。あらかじめチェックをして揃った感度のものだけを子どもたちに使わせるか、ばらつきも含めて「計測とは」、「品質とは」を考えさせるのもよいかとも思いました。
また、感度の低いものはすごく明るいところ用の測定に使う、感度の高いものは暗いところの測定に使うなどの用途分けに使ってもよいかもしれません。

#####データの統計処理

測定結果を表にまとめたので、平均やばらつきなどの計算やグラフを書いてみると、より発展的に可視化できるのではと思いました。統計の基礎である数値に扱い方にもなるのではと思いました。（もはや家庭科の授業ではなくなってしまいますが。）

#####感度補正
Microbitの明るさセンサーの表示は教室では大体100ぐらいを表示していましたが、照度計などでMicrobitの感度補正が必要だと思います。感度補正ということもいい課題になると思いました。（窓側では、255を振り切っていました。）

#####その他取り扱い
子どもたちが家で使うときは、電池につないでMicrobitを動かしますが、電池ボックスにはON/OFFスイッチのついたものが良いかと思いました。（学校で用意したものはスイッチのついていないもの。使うときだけ電池ボックスに電池を入れて使う。ショートの防止と電池の寿命のため）

Microbitは電圧端子（Microbit下側にある、0,1,2,3V,GND）がむき出しになっています。例えば金属の上にMicrobitを置いて動作させたとき、グランドと3V端子が短絡してしまうことがあります。そのあたりは注意が必要かとも思いました。

###参考　明るさの単位　ルクスとルーメンス
[明るさの基準について](https://www.miterukun.com/%E7%9F%A5%E8%AD%98%E7%B7%A8-1/%E6%98%8E%E3%82%8B%E3%81%95%E3%81%AE%E5%9F%BA%E6%BA%96%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)

部屋の明るさなどその場の明るさはルクス(lx)。 
照明器具自体の明るさはルーメン(lm)。 
・教室及びそれに準ずる場所の照度の下限値は、300 lx（ルクス）
・教室及び黒板の照度は、500 lx 以上であることが望ましい。
・コンピュータ教室等の机上の照度は、500～1000 lx 程度が望ましい。
・テレビやコンピュータ等の画面の垂直面照度は、100～500 lx程度が望ましい。

####明るさの目安 (lx)
屋外・快晴 	100,000
屋外・曇天 	25,000
日中の木陰（影の輪郭線から1ｍ内側）10,000
晴れた日中、室内の南窓から1ｍ内側　3,000～5,000
曇り空　5,000前後
野球場　内外野 	2,000
町の街灯下 	100
居間の全体 	200
寝室の全体 	30
満月の夜 	0.2
星明かりのみの夜 	0.02
闇夜 	0.007
#Ruby 2.7.0 で改行できるようになったコンソール irb を使ってみる

それだけ。

```
rbenv install 2.7.0-dev
```

```
irb
```

![image](https://user-images.githubusercontent.com/13635059/64682579-afce8c00-d4bc-11e9-80b6-3993f34b3389.png)


入力中であればDELETEキーで戻ることもできるみたいです！

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
シェルスクリプト if 文記述例

例1:

```bash:if-example1.sh
if [ "A" = "A" ]
then
  echo 'A'
fi
```

例2: 例1 から then を if の行に持って行った形。

```bash:if-example2.sh
if [ "A" = "A" ]; then
  echo 'A'
fi
```

例3: 例1 から echo を then の行に持って行った形。

```bash:if-example3.sh
if [ "A" = "A" ]
then echo 'A'
fi
```

例4: 全てを1行で書く形。

```bash:if-example4.sh
if [ "A" = "A" ]; then echo 'A'; fi
```
強化学習１１　OpenAI　acrobotをChainerRLでやってみる。

強化学習１０まで達成していることが前提になります。
openai acrobotでググると、Acrobot-v1が出てきます。
v1とかv0がよくわからないので、魔改造前の調査をします。
userfolder/anaconda3/envs/chainer/lib/python3.7/site-packages/gym
をVSCodeで開きます。
CartPoleで全検索をすると、CartPole-v0とCartPole-v1がありました。
むむ？
acrobotでは、Acrobot-v1だけです。
先に作ったCartPoleで、CartPole-v0をCartPole-v1に代えて実行してみました。
難易度が上がっているようです。

そのまま入れ替えてやってみましたが、なんか違う。。。。
Acrobotは振り子運動で、ある高さまで持っていくことで成功報酬が得られます。
未来における価値をあまり割り引かない設定にしてみます。
gammaを0.99にしたところ、うまく行っているように思えます。

DQN(Deep　Q　Network）を使用しています。
その説明は、たくさん紹介されているので、ググるといいでしょう。
【ZK Framework】borderlayoutを操作する


borderlayoutの使い方で少しつまづいたので、

<br>
引用元:
https://www.zkoss.org/wiki/ZK_Component_Reference/Layouts/Borderlayout


<br>
borderlayoutには、北、南、東、西、中央の子コンポーネント(UIの構成要素)があり、指定した位置に要素を配置することが出来ます。
<strong>※北、南、東、西、中央に文字列を配置した例</strong>
![borderlayout_sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520803/ca4b35b5-b29b-3ca0-ee84-2ba805244433.jpeg)


```zk:borderlayout_sample.zul
<zk>
<window title="borderlayout_sample" border="normal">
	<borderlayout width="500px" height="500px">
		<north>
			<div align="center">NORTH</div>
		</north>
		
		<east>
			<div>EAST</div>
		</east>
		
		<center>
			<div align="center">CENTER</div>
		</center>
		
		<west>
			<div>WEST</div>
		</west>
		
		<south>
			<div align="center">SOUTH</div>
		</south>
	</borderlayout>
</window>
</zk>
```


<br>
<br>
また子コンポーネントの中に入れ子で子コンポーネントを配置することが出来ます。
<strong>※北と南の子コンポーネントの中に、入れ子で子コンポーネントを配置した例。</strong>
![borderlayout_sample2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520803/744a8931-fc1f-77dc-c9ee-8639d8512af6.jpeg)


```zk:borderlayout_sample2.zul
<zk>
<window title="borderlayout_sample" border="normal">
	<borderlayout width="800px" height="800px">
		<north size="50%">
			<borderlayout>
				<north>
					<div align="center">NORTH</div>
				</north>
				<east>
					<div>EAST</div>
				</east>
				<center>
					<div align="center">CENTER</div>
				</center>
				<west>
					<div>WEST</div>
				</west>
				<south>
					<div align="center">SOUTH</div>
				</south>
			</borderlayout>
		</north>

		<south size="50%">
			<borderlayout>
				<north>
					<div align="center">NORTH</div>
				</north>		
				<east>
					<div>EAST</div>
				</east>
				<center>
					<div align="center">CENTER</div>
				</center>
				<west>
					<div>WEST</div>
				</west>
				<south>
					<div align="center">SOUTH</div>
				</south>
			</borderlayout>
		</south>
	</borderlayout>
</window>
</zk>
```

borderlayoutを別のborderlayoutで入れ子にすることで複雑なレイアウトの配置が出来るようになります。
<br>

またZK Frameworkは日本語での情報が全然出回っていませんが、公式のドキュメントが分かりやすいです。

<br>

公式:
https://www.zkoss.org/
pipでパッケージがインストールできない。

#環境
- windows10
- Python3.7.3
- pip19.0.3

#問題
Python初心者ながら見様見真似でAWSを操作したくてboto3を落とそうとしたら
pip install boto3出来ない。

```
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Collecting boto3
  Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/boto3/
  Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/boto3/
  Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/boto3/
  Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/boto3/
  Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/boto3/
  Could not fetch URL https://pypi.org/simple/boto3/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/boto3/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
  Could not find a version that satisfies the requirement boto3 (from versions: )
No matching distribution found for boto3

```

#解決策候補
## Typo?
それはない、なぜならPypiのコマンドをコピペしたから。
![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309961/077b6acc-7be2-10bd-c4da-db128a318bb8.png)

##証明書のエラー？
エラーをググるとどうも証明書の関係によって信用していないからのような記事が出てきたので実行した。
https://qiita.com/agajo/items/73d6f14855da703972e0

しかしうまくいかない。

#解決策
[公式サイト](https://www.python.jp/install/windows/pip.html)のpipのページを見ると

`複数のバージョンの Python がインストールされている環境では、どの Python の実行環境にパッケージをインストールするか、指定する必要があります。`

とある。そういえば別のシステムの関係で2.xを入れていたことを思い出してバージョン指定をして実行

```
py -3 -m pip install boto3
```

***
無事解決
Linux上のLuaTeXに手動でフォントをインストールする手順

1. 特定の一般ユーザーだけが使うなら`$HOME/.local/share/fonts`にコピーする。システム全体で使うなら`root`でフォントファイルを`/usr/share/fonts/local`以下に必要ならディレクトリを掘ってからコピーする。
2. `fc-cache -vr フォントを置いたディレクトリ`を実行する
3. 一般ユーザーに戻ってから`luaotfload-tool -u`する

以上。うまくいかない場合は

- `fc-list` コマンドで新しくインストールしたフォントが見えることを確認する
- 問題なく`fc-list`で見えるなら`$HOME/.texlive20nn`を`rm -rf`する

`LuaTeX`から見えるフォント名は`fc-list`やや`otfinfo -i`や`luaotfload-tool`で確認できる。フォントが対応しているフィーチャーは`otfinfo -f`で確認できる。
Arduinoを用いたローバー制御（実機編）

# テーマ記事へのリンク

以下の記事には今回のテーマを設定した目的や関連記事がまとめてあります。自分が見たい項目がある場合は利用してください。[自作ロボット（ローバー）のROS対応](https://qiita.com/Naotaka_K/items/122c18f163f608bf299e)

# 目次

[準備するもの](#準備するもの)

[ArduinoIDE](#arduinoide)

[ros_libの生成](#ros_libの生成)

[ArduinoIDEでの書き込み設定](#arduinoideでの書き込み設定)

[ローバーの動作チェック](#ローバーの動作チェック)

[つまずいた部分](#つまずいた部分)

# 準備するもの

1. [3WD48mmオムニホイールモバイルロボット]( https://www.vstone.co.jp/robotshop/index.php?main_page=product_info&cPath=895&products_id=5156 )（以下、ローバー）

2. Ubuntu 16.04 (Windowsでも可)

![3WD48mmオムニホイールモバイルロボット (10019)](https://www.vstone.co.jp/robotshop/images/nexus1001901.jpg)
# ArduinoIDE

Arduinoでの統合開発環境。

[公式サイト]( https://www.arduino.cc/en/Main/Software )からLinux 64bitをクリックし、寄付するかどうかの質問を乗り越えてダウンロード。

ダウンロードしたファイルを展開し、インストールする。

 ```shell
$ cd Downloads

$ tar Jxfv arduino-1.8.10-linux64.tar.xz

$ cd arduino-1.8.10-linux64

$ ./install.sh
 ```

これによりホームディレクトリにArduinoフォルダが生成される。Arduino/librariesフォルダに、適宜使用するライブラリを入れることで、rosのパッケージなどを使用することが出来る。

# ros_libの生成
ROS Melodicの場合
rosserialとrosserial_aruduinoパッケージをインストールする。

```shell
$ sudo apt-get install ros-melodic-rosserial-arduino
$ sudo apt-get install ros-melodic-rosserial
```

続いて、arduino側で使用するrosパッケージを準備する。

```shell
$ wget https://downloads.arduino.cc/arduino-1.8.13-linux64.tar.xz
$ tar Jxfv arduino-1.8.13-linux64.tar.xz
$ cd arduino-1.8.13-linux64.tar.xz/libraries
$ rosrun rosserial_arduino make_libraries.py .
$ cp -r ros_lib ~/Arduino/libraries
```

# ArduinoIDEでの書き込み設定
ツールタブのボード、Clock,シリアルポートを以下の設定にする。
- ボード：ATmega328P
- Clock：8MHz/X'tal
- シリアルポート：dev/ttyUSB0(使用する環境による)

# ローバーの動作チェック

**販売元が購入者のみにソースコードやマニュアルを公開している。そのためライブラリがないとソースコードがコンパイルできません。ご了承ください。**

以下のソースコードをcloneし、rover/arduino_scripts/rover_sirial IDEでコンパイルしてからローバーに書き込む。

Arduino IDEのシリアルモニターからコマンド(r,fなど)を入力して旋回、前進すれば成功。
**2020/11/27追記：melodicだと、なぜかスクリプトで設定した通信速度にずれが生じている。スクリプトで設定した通信速度の倍でシリアルモニタ側の通信速度を設定することで、正常に動作する。**
**例：スクリプトで"node_handle.getHardware()->setBaud(9600);"と設定したならば、シリアルモニタは19200bpsに設定する。**


```shell
$ git clone https://github.com/NaotakaKawata/rover.git rover
```

# つまずいた部分

1. 英語のマニュアルを読みながら進めていたのだが、書いてあるサンプルコードと実際に刺さっているポート番号が違う。[エンコーダ付きDCモータ]( https://www.vstone.co.jp/robotshop/index.php?main_page=product_info&cPath=313&products_id=3784 )が付属しているので返り値を見て気づいたが、初めて既製品のロボットを買ったので基本的なチェックを怠ってしまった。皆さんは気を付けてください。

2. サンプルコードも最初は提供されたソースを使い動作チェックを行いましょう。部品が壊れている可能性もあります。

   →筆者はタイヤとDCモータの間に取り付けるアルミハブの穴径が違っため、一度返送している。丁寧な対応だったのでその点は満足している。
React FCの中で別のFCを定義するな。絶対にだ！

## TL,DR
React FC（Functional Component）の中で別のFCを定義しないように気をつけましょう。

```tsx:やってはいけない実装
const Hoge: React.FC<{ username: string }> = ({ username }) => {
  // FugaはHoge FCの中で定義されている。
  const Fuga: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
    <div>
      <div>こんにちは、{username}さん！</div>
      <div>{children}</div>
    </div>
  );
  return (
    <Fuga>
      <SomeLargeContent />
    </Fuga>
  )
};
```

## FCの中で別のFCを定義することによる問題とその調査

### 何が起こったのか。
上の例の`<SomeLargeContent />`の中にて、DOMが*ユーザー入力によるstateの更新の度に*削除と再構築をしてしまい、パフォーマンスやユーザビリティの劣化等、予期せぬ挙動を引き起こしました。

クリティカルな現象としては以下が挙げられると思います。

- `transition`を使用したアニメーションを定義したが、stateの変更によるスタイルの切り替えをしようとする度にDOMが再構築されるのでアニメーションが発生しない。
- inputにユーザーが入力を行うとinputのDOMが再構築されてフォーカスがinputから外れる。
- ComponentDidMountやuseEffectがstateの変更の度に発火されてしまう。

### そもそも通常の場合は何故DOMの再構築が行われないのか
Reactはrenderによって生成された仮想DOMを前回生成された仮想DOMと比較し、その差分のみDOMを更新・削除・追加しています。なので、仮想DOMがReactに前回の仮想DOMと同一と判断されたDOMについては再構築が行われません。
[参考記事](https://qiita.com/muraikenta/items/21eb5b2e0d1c7c95e3b8)

### では、この場合はどうだったのか。
Reactの仮想DOMオブジェクトをのぞいてみましょう。

```tsx
  const Fuga: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
    <div>
      <div>こんにちは、{username}さん！</div>
      <div>{children}</div>
    </div>
  );
  const vdom = (
    <Fuga>
      <SomeLargeContent />
      {/* stateの更新用にチェックボックスを配置 */}
      <input
        type="checkbox"
        checked={state}
        onChange={() => setState(s => !s)}
      />
    </Fuga>
  );
  console.log(vdom)//仮想DOMを出力;
```
以下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294714/01d2d05f-a109-37cd-62de-e69aaa622024.png)

`key,props,type`というプロパティを持っていることがわかります。
typeに注目してみましょう。**Fuga関数が格納されています。**
仮想DOMは*「どのようなDOMが構築されるか」*以外にも*「どのコンポーネントからDOMが生成されたのか」*をtypeとして保持するようになっており、Reactはその差分も検出しています。
つまり、最終的に構築される実DOMに差分が無かったとしても、**DOMを構築するコンポーネントが異なっていれば、それは異なるDOMツリーだと解釈されます**（当然といえば当然）
FC(1)の中でFC(2)を定義した場合、**FC(2)はrenderが走る度に定義される**ので、前回のrenderと異なる仮想DOMを生成してしまいます。
これにより、実DOMの差分以上にDOMの再構築が発生してしまうのです。

## まとめ
コンポーネントを定義するときは必ず、トップレベルに定義することをお勧めします。
ルートに近いコンポーネントがこれをやらかすとアプリ全ての末端のコンポーネントまで被害を被りますので（実体験）気をつけましょう。

## おまけ：仮想DOMをハックしてDOMの再構築を食い止める
Reactは仮想DOMオブジェクトのtypeから仮想DOMが異なるコンポーネントが作られているか判断します。
これを利用しtypeをハックすることでReactに差分を誤認識させ、再構築を食い止めてみましょう。

```tsx
  const vdom = (
    <Fuga>
      <SomeLargeContent />
      {/* stateの更新用にチェックボックスを配置 */}
      <input
        type="checkbox"
        checked={state}
        onChange={() => setState(s => !s)}
      />
    </Fuga>
  );
  console.log(vdom);
  //初回に定義されたFugaコンポーネントをrefに格納しておく
  const ref = React.useRef<React.FC | null>(null);
  const firstFuga = ref.current;
  if (!firstFuga) {
    ref.current = Fuga;
  }
  //2回目以降のrenderではtypeを初回に格納したFuga関数に差し替える
  return firstFuga
    ? {
        ...vdom,
        type: firstFuga
      }
    : vdom;

```

絶対に真似しないように。
Vim の辞書ファイルからのキーワード補完について調べてみた

## はじめに

Vim の入力補完のプラグインは [deoplete.nvim](https://github.com/Shougo/deoplete.nvim) などがあると思いますが、デフォルトの機能にもキーワード入力補完機能があるようでした。

キーワード入力補完にもいくつか種類があるようですが、その中でも辞書ファイルを使った補完について、使い方を調べてみました。


## 手順

### 辞書ファイル作成

まず、補完対象にしたい単語を辞書ファイルとして準備します。

今回は例として、Git のコミットメッセージのプレフィックスを辞書ファイルに準備することにしました。(参考：[angular.js/DEVELOPERS.md at master · angular/angular.js · GitHub](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type))


```~/.vim/dict/git_prefix.dict
feat
fix
docs
style
refactor
perf
test
chore
```

### 辞書ファイルのパス指定

Vim の設定ファイルに、辞書ファイルを読み込む設定を追記して保存します。

```vim:~/.vimrc
set dictionary=~/.vim/dict/git_prefix.dict
```

### 動作確認

Vim 起動後、挿入モードに入って`CTRL-X CTRL-K` を実行すると、辞書に登録した単語が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222030/f7091200-ac80-d8d2-cae6-92eab4a5bfe8.png)


## おわりに

Vim の基本機能としても入力補完が使えることは知らなかったです。今回単語の表示はできたのですが、コロンなどの記号表示はできなかったので、他の補完も含めてまた調べてみようと思います。

## 参考

* [angular.js/DEVELOPERS.md at master · angular/angular.js · GitHub](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)
* [insert - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/insert.html#ins-completion)
スプレッドシートで特定の行列の値が特定の変更をされたらSlackに通知する

以下の `sendNotification` をトリガーで「変更時」に発火するように設定

```javascript

function sendNotification() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = ss.getSheetByName("シート1")
  const cell = ss.getActiveCell().getA1Notation()
  const changedCellRow = sheet.getActiveCell().getRowIndex()
  const value = sheet.getRange(cell).getValue()
  const message = createMessage(changedCellRow)
  if(value === "特定の変更") {
    notificationToSlack(message)
  }
}

function createMessage(changedCellRow) {
  return "ステータスが変更されました"
}

function notificationToSlack(message) {
  const postUrl = "https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXXXXXXXXXX"
  const userName = 'マイメロ'
  const room = "#random"
  const jsonData =
  {
     "username" : userName,
     "text": message,
     "channel": room,
  }
  const payload = JSON.stringify(jsonData)
  const options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  }
  UrlFetchApp.fetch(postUrl, options)
}
Windows で Vim の右クリックメニューを登録する

この記事では、GVim / neovim を Windows 10 の右クリックメニューへ登録する方法をご紹介します。 

<!-- wp:heading -->
<h2>"GVim/neovimで開く"を右クリックメニューに登録する方法 </h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>今回の手順ではファイル形式に限らず、どのファイルを右クリックしても表示されるように設定しています。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>手順</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>下記を <span class="bold-green">vim_open.reg </span>ファイルに保存します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\gvim]
@="gvimで開く"
"Icon"="C:\\Program Files\\vim\\gvim.exe"

[HKEY_CLASSES_ROOT\*\shell\gvim\command]
@="C:\\Program Files\\vim\\gvim.exe \"%1\""</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>これを保存した後、<span class="bold-green">管理者権限でファイルを開く</span>ことで完了です。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>登録後は即座に反映されますので、OS再起動は必要ありません。 </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>解説</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>先の reg ファイルでは、下記の処理を実施しています。</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>レジストリキー：HKEY_CLASSES_ROOT*\shell\gvim を作成します。</li><li>既定の値を「gvimで開く」に設定します。</li><li>文字列「Icon」を追加して、値を gvim.exe のパスにします。<br>この設定で、右クリックメニューに表示するときのアイコンを設定できます。</li><li>レジストリキー：HKEY_CLASSES_ROOT*\shell\gvim\command を作成します。</li><li>4の既定の値を gvim.exe のパスと引数 "%1" を加えた値に設定します。</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>こちらは手作業で行うことも可能です。</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>「neovimで開く」を右クリックメニューに登録する方法</h2>
<!-- /wp:heading -->

詳しくは[こちら](https://vim.blue/vim-right-click-menu-how-to-register/)で紹介しています。

## おわりに
Vim入門者のための記事を書いて情報発信しています。

[Vim入門](https://vim.blue)

Vimがもっと世に広まって、Vimmerが1人でも増えるように少しでも貢献できれば幸いです。
DockerでVimの検証環境を作る

Vimで設定値やプラグインを手軽に検証するために、一時的な環境を用意する方法についてご紹介します。

今回は Docker を使ったコンテナでの検証環境を準備する方法を紹介します。

<!-- wp:heading -->
<h2>前提</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>検証環境ですから、下記を満たせることが前提となります。</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>簡単に作れる</li><li>簡単に破棄できる</li><li>使うごとにリセットできる</li><li>設定ファイルなどをインポートできる</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>VMwareやHyper-V、あるいは VirtualBox などで仮想環境を作るのも良いですが、ちょっと重すぎる感じはありますね。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>そう考えると、コンテナ技術を利用するのがベストと言えます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>ちなみに、Windows/Linux/Mac のいずれでも利用可能です。</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>用意するVim検証環境の構成</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>ローカルで用意する各種ファイルの構成はこちらになります。</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">/vim-sandbox （このフォルダ名は何でも大丈夫）
├ --- .vimrc コンテナ内にコピーする vim の設定ファイル(1)
└ --- vim/   コンテナのvim関連ファイルのディレクトリへコピーするファイル群(2)</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>コンテナ内で、vimに関連するファイルやフォルダは下記の構成をになります。</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">/root
├ --- .vimrc vim設定ファイル(1)
└ --- .vim/  vim関連ファイルのディレクトリ(2)</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>上のファイル/フォルダは、番号がそれぞれ対応しています。</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>コンテナ構築の手順</h2>
<!-- /wp:heading -->

こちらをご覧ください。

[DockerでVimの検証環境を作る手順](https://vim.blue/vim-sandbox-docker-container/)

## おわりに
Vim入門者のための記事を書いて情報発信しています。

[Vim入門](https://vim.blue)

Vimがもっと世に広まって、Vimmerが1人でも増えるように少しでも貢献できれば幸いです。
Macでgrpc_cliを手早く動かす

## TL;DR;

あれこれインストール・ビルドを省いて、dockerイメージつかう

```sh
docker run --network=host --rm znly/grpc_cli ls localhost:1111 -l
```

## homebrewでは単体でインストールできない

grpc同梱なので、依存libraryのインストール、ビルドを気長にやる必要がある

- 自分の場合は25分コースだった


```sh
~ ❯❯❯ brew tap grpc/grpc
~/w/a/schema ❯❯❯ brew info grpc                                                                                                                                                                                        ✘ 130 wip ✭ ✱ ◼
grpc: stable 1.25.0, HEAD
Next generation open source RPC library and framework
https://grpc.io/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/grpc.rb
==> Dependencies
Build: autoconf ✔, automake ✔, libtool ✔
Required: c-ares ✘, gflags ✘, openssl@1.1 ✘, protobuf ✘
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 4,149 (30 days), 12,430 (90 days), 33,431 (365 days)
install_on_request: 2,945 (30 days), 9,072 (90 days), 28,668 (365 days)
build_error: 0 (30 days)
```


## 初回実行時だけdockerイメージのダウンロード発生

サイズは9MBくらい

- https://hub.docker.com/layers/znly/grpc_cli/latest/images/sha256-8d1790338113055b4e62e025bd13236e57c38bc53eb31251aec98d52bd1c4ce1

## 使用例

```sh
# server reflection有効にしたgRPCサーバーへの接続
docker run --network=host --rm znly/grpc_cli:latest ls localhost:50051
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter

# server reflection未対応のgRPCサーバーへ接続をトライして失敗
~ ❯❯❯ docker --network=host run --rm znly/grpc_cli:latest ls localhost:2222
Received an error when querying services endpoint.
```

## evansとgrpc_cli

evansはhomebrewでインストールできるしシングルバイナリーとして配布されてるのでインストールが楽で、rpcメソッドコールとかやりやすいUI

他方、その場でさっとprotobufの内容を取得できるのは、grpc_cliにしか無い気がする。

```sh
~ ❯❯❯ docker run --network=host --rm znly/grpc_cli:latest ls localhost:2222 -l
ls localhost:50051 -l
filename: helloworld.proto
package: helloworld;
service Greeter {
  rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
  rpc SayHelloAgain(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
}
# skip ...
```
## 試行錯誤

- `--network=host` 重要だった
    - cliがホスト側のネットワークに繋ぐときに必要
- うまく接続できないときとかは使うdockerイメージを[namely/grpc\-cli](https://hub.docker.com/r/namely/grpc-cli) に切り替えるとエラー表示が詳しくなる
    - ただし250MBくらいのイメージをダウンロードしないといけない

```sh
# znly/grpc_cli 利用時のエラーログ
➜  ~ docker run  --rm znly/grpc_cli ls 0.0.0.0:1111 -l
Received an error when querying services endpoint.
# namely/grpc-cli利用時のエラーログ
➜  ~ docker run --rm namely/grpc-cli ls localhost:1111
Received an error when querying services endpoint.
ServerReflectionInfo rpc failed. Error code: 14, message: failed to connect to all addresses, debug info: {"created":"@1573922174.884215300","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3934,"referenced_errors":[{"created":"@1573922174.884187900","description":"failed to connect to all addresses","file":"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc","file_line":393,"grpc_status":14}]}
```
Android の Camera2 API を使って Color Effect する

[Android の Camera2 API を使って カメラのプレビュー画面を表示する](https://qiita.com/ohwada/items/7bb65a566114066c8ced)
の続きです。

### Color Effect

Color Effect　(色効果) は、
カメラデバイスからの画像の色合いを変更する機能です。
この機能は機種依存です。
この機能の解釈と実装は、Androidデバイスのメーカーに委ねられている。
すべての機種で同じ動作をするとは限らない。

Camera2 API には下記の Color Effect が用意されている。
この機能がサポートされていないときは、OFF のみをリストする。

- OFF
- MONO
- NEGATIVE
- SOLARIZE
- SEPIA
- POSTERIZE
- WHITEBOARD
- BLACKBOARD
- AQUA

[reference : CameraCharacteristics.html#CONTROL_AVAILABLE_EFFECTS](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#CONTROL_AVAILABLE_EFFECTS)

### プレビュー画面に Color Effect を適用する

プレビュー画面をターゲットにして Color Effect を要求する。

```
// プレビュー画面 をターゲットにする
surface = new Surface(textureView.getSurfaceTexture()) 
            captureBuilder.addTarget(surface);
// Color Effect モードを設定する
    captureBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, effect);
// Color Effectを要求する
captureRequest　= captureBuilder.build();
    captureSession.capture(captureRequest, captureCallback, backgroundHand);
```
CaptureRequest が完了したら、Color Effectを繰り返し要求する

```
onCaptureCompleted
// Color Effectを繰り返し要求する
    captureSession.setRepeatingRequest(captureRequest, captureCallback, backgroundHandler);
```
[reference : CaptureRequest#CONTROL_EFFECT_MODE]
(https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#CONTROL_EFFECT_MODE)

### Color Effect を適用した写真を撮る

プレビュー画面と写真は、連動していない。
写真を撮る時は、ImageReader をターゲットにしてColor Effectを要求する。

```
// ImageReader をターゲットにする
surface = imageReaderStill.getSurface();
captureBuilder.addTarget(surface);
// Color Effect モードを設定する
    captureBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, effect);
// Color Effectを要求する
    captureSession.capture(captureBuilder.build(), captureCallback, backgroundHand);
```

### スクリーンショット

SEPIAの例

![color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/7b7b5a0d-2047-22b2-c42f-c0e463c6d713.png) ![sepia.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/01a6ccf6-9296-877f-bdc3-845a54bd80a6.png)

サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/Camera224
vim： カッコ補完+α

```vim:.vimrcに追加
"カッコ補完: { ( [
inoremap { {}<Left>
inoremap {<Enter> {}<Left><CR><ESC><S-o>
inoremap () ()
inoremap ( ()<ESC>i
inoremap (<Enter> ()<Left><CR><ESC><S-o>
inoremap [ []<ESC>i
inoremap [<Enter> []<Left><CR><ESC><S-o>

"補完: ' " <
inoremap '' ''
inoremap ' ''<ESC>i
inoremap "" ""
inoremap " ""<ESC>i
inoremap < <><ESC>i

"インサートモードのままカーソル移動
inoremap <C-f> <C-g>U<Right>
inoremap <C-f><C-f> <C-g>U<ESC><S-a>
```
カッコ補完はよく見たことあると思います。

しかし、こういう補完は今ひとつ使えない。
カッコ内で書き終わった後の流れ、

ノーマルモードに戻す -> 移動 -> インサートモード
が面倒すぎると思いません？！

そこで最後のやつです。**ctrl+f**（適宜）
１回押しでインサートモードのまま右に１つ移動。
２回押しでインサートモードのまま行末に移動。

カッコ補完との組み合わせで割と便利になります！
ぜひお試しを。
Dolphinというシングルユーザー用のActivityPub serverを立ててみた



activitypubというprotocolがあります。わかりやすく言うと、分散snsのprotocolです。このprotocolを使ったserverで有名なのはmastodonです。

今回、misskeyというmastodonに似たプロジェクトがあるのですが、その姉妹プロジェクトであるdolphinがシングルユーザー、つまり、お一人様インスタンスと呼ばれるサーバーに特化しているようなので、herokuで立ててみました。

https://github.com/syuilo/dolphin

```sh
$ git clone -b master git://github.com/syuilo/dolphin.git
$ cd dolphin
$ cp .config/example.yml .config/default.yml
$ npm i

$ heroku create $APP_NAME
$ ls -a ./.git
$ heroku git:remote -a $APP_NAME
# heroku buildpacks:set https://github.com/heroku/heroku-buildpack-nodejs
$ heroku addons:create heroku-postgresql:hobby-dev --version=10
$ heroku addons:create heroku-redis:hobby-dev
$ heroku config
# postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}
# redis://h:${REDIS_PASS}@${REDIS_HOST}:${REDIS_PORT}
$ vim .config/default.yml
# postgresql, redisのurl情報を入れる
  disableCache: true
drive:
  storage: 'fs'
disableHsts: true
clusterLimit: 1
id: 'aid'

$ vim package.json
  "engines": {
    "node": "11.7.0",
    "npm": "6.13.0"
  }

$ vim Procfile
web: NODE_ENV=production npm run init && npm start

$ cat ~/.gitignore
$ git add .
$ git commit -m "first heroku" 
$ git push -u heroku master
$ heroku logs

# update
$ git pull
$ git push heroku master
$ heroku run npm run migrate
```

![misskey_dolphin_heroku_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4151/4fc03158-783e-6587-a79b-14eb44c47e80.png)
SpringBoot + Spring JPAでMySQLのJSON型のValue検索

## 概要
JPAを使用してのJSON型カラムのValue値検索について調べたので、共有として。
Specificationにて検索するケース。

## 結論
MySQLの関数を使用する。

### JSON_EXTRACT
```sql
SELECT * FROM ATABLE WHERE JSON_EXTRACT("column_name", "$.key") = value;
```

なので、Spring　JPAのSpecificationを使用する場合、

```java
public Specification<T> jsonSearch(String key, String val) {
	return  (root, query, cb) -> {
	    return cb.like(cb.function("JSON_EXTRACT", String.class, root.get("names"), cb.literal("$." + key)),
		    "%" + val + "%");
	};
}
```

## 参考
[Custom expression in JPA CriteriaBuilder](https://stackoverflow.com/questions/38743901/custom-expression-in-jpa-criteriabuilder)
2000年～2019年にかけてWebのフロント開発は進歩しているのか？

# 2000年ぐらいから現在に至るまでのWebフロント

## HTMLタグオンパレード、1ファイルでMVCすべて実装

　2000年ぐらいにWeb開発をはじめた。
　当時は、HTMLで構造も装飾していた。要はほとんどHTMLで完結。
　ちなみに、デザインという考えも正直なところなく、*MARQUEE*タグというのがあって、文字が右から左に流れたりするものとか、チカチカする*BLINK*タグとか、今では、デザイン的に「ダサい」というのが普通につかわれていた。

　ちなみに、Googleでこれらのタグを調べると、ちゃんと検索結果もそういった動作をしてくれる（すげーこまかい！）。
 
 [▶ MARQUEEタグの検索結果](https://www.google.com/search?q=marquee+tag&oq=marquee+tag&aqs=chrome..69i57j0l5.4805j0j7&sourceid=chrome&ie=UTF-8)

- 検索件数が右から左に流れます。

 [▶ BLINKタグの検索結果](https://www.google.com/search?q=blink+tag&oq=blink+tag&aqs=chrome..69i57j0l5.1573j0j7&sourceid=chrome&ie=UTF-8)

= blinkの文字が点滅します。


　当時も、Javascriptの利用はあったけど、SEO対策とかセキュリティとか、デザインを考慮してあまりつかわれてなかった記憶があります。
　そして、スクリプトの中に、HTMLを直接書き込み、MVCの役割文化などソースレベルではあまりなく、1スクリプトファイルにすべての要素がありました。
　もちろん、CSSも使ったり、使わなかったりで構造と装飾を分けるなんて発想もなく。


## GoogleのSEOにあわせて、構造（HTML）と装飾（CSS）が別れてくる

　「SEO対策」という言葉がでてきて、Googleの検索にかかり安いHTMLを書こうという風潮が開発者の間でもでてきました。このころから、HTMLとCSSが明確に分かれていった記憶があります。そして、それは今も続いています。

## jQueryの登場
　
　2006年あたりから、徐々に、画面も動的な要素をもとめられるようになり、jQueryやprototypeのように、HTMLのノードや装飾を手軽に記載できるシンタックスシュガー的なライブラリーがでてきました。
　このころからJavascriptを画面で使うことが広まってきたのかなという気がします。

## CSSプリプロセッサー（CSSメタ言語）

　2006年にSassが登場し、2009年にLESSが登場しました。
　このころから、CSSも変数や関数をつかって、パーツを使いまわしたり、より書きやすい方法を採用する動きが取られるようになりました。

## SPAの登場

 2010年あたりから、Knockout.jsなどSPAのフレームワークが現れるようになり、徐々に、Javascriptの役割が増してきました。
 PCでみるだけでなく、スマホで閲覧することもこれには影響しているかもしれません。

## nodeの登場、Javascriptの文法の変化、そして、ビルドツール

　2009年にnodeが登場し、Javascriptをサーバサイドで使うことが少しずう広まると共に、JavascriptもPHPやRubyのように、構造的にプログラムを書く言語として広まっていったように思います。たとえば、import/exportなどの構文をつかって、ソースを分割したり。

　こうした構造的なJavascript開発した成果物をブラウザで使いたいけど、import/exportが対応していないものがあり、browsrifyでJavascriptをビルドするという方法が徐々に取られるようになりました。

　あわせて、ES6の文法など当時のブラウザでは解釈できないけど使いたい文法で書いて、それをブラウザで読み込めるようにするBabelなどのコンパイルをするということも行うようになってきました。

　つまり、nodeの登場あたりから、Javascriptで、モジュール分割し構造的なプログラムを作ると同時に、ブラウザへの対応を念頭にビルドするという開発手法が徐々に一般化してきました。

## 2019年現在（分割と統合、それを支えるビルドツール）

　現在のWebのフロントは、HTML（構造）、CSS（装飾・視覚効果）、Javascript(データ構造、処理、動的視覚効果）で役割をわけ、更に、CSSやJavascriptの分割・構造的にファイルをわけて、ビルドするというのが一般化しています。

　Typescriptなどもビルドを前提としたAltJSであり、今や、Webフロントに置いて、構成要素は細かく分化し、ビルドツールで統合されるのが一般化しています。



# 現在(2019年）のWebフロント開発は発展途上？　パーツとルールが揃った段階

　2000年あたりからWebシステムを開発して、なお、今現在も現役でSPA、PWA、はたまた、ElectronやFlutterなどデスクトップアプリなどにかかわっています。

　昔は、開発準備がかからないけど、開発の無駄、完成後のメンテナンスがしにくかったのは確かです。
　けれど、時代のニーズとしても、見た目も動きも大したものはなかったです。

　今は、Webフロントに求めるニーズも高いし、構造化してきているので、構成要素を分割して作成し、いろいろな人とつくっていくのは当然なことです。
　その過程として、ビルドツールは必要だと思います。それだけみたらとてもめんどくさいのですが、他の要素も考えると結果的に現在の流れは理解できます。

　けれど、やはりめんどくさい。手間がかかる。
　
　交通の進化にたとえるなら、やっと道路や車、自転車がでてきて、交通ルールがうまれたような段階でしょうか。パーツが何なのか、それらがどう振る舞うのか、そして、どういったルールでそれを使っていくのか。
　
 Webフロントは、パーツとルールができた段階です。それはそれで進歩だと思いますが、いかんせん、アプリケーションをつくるまでに、このパーツとルールを組み合わせて色々と試行錯誤をしないといけないです。

　これは、Webフロントに限らず、GUI全般にいえることかもしれません。

　GUIで部品をはったら、よろしくしてくれるまでいけばもっと楽なのにとか思ったりします。
Linux入門

##はじめに
この記事は、
Linuxとは何かと、
Linuxの基本的なコマンドをまとめているものです。

##Linuxとは?
LinuxとはOSの一種です。

OSとはオペレーションシステムの略で、
コンピュータの様々な操作機能を可能にしている、
コンピュータの根本部分です。

WindowsやmacOSがシェアの高いOSです。
そんな中で、Linuxはオープンソース(無料公開)のOSなのです👏

Linuxから新しいOSを作ることもでき、
AndroidはGoogleが開発しているLinuxをベースとしたスマホ用のOSで、
iPhoneで使われているiOSも元をたどれば、Linuxの前身のUnixだそうです。

プログラミング言語を動かす環境としてもLinuxは優れており、
例えばPHP言語を動かすにはWebサーバの環境が必要ですが、
Linux上でWebサーバを動かすことができるので便利です。（だそうです。）

##Linuxの基本的なコマンド
###現在地を確認
``pwd``で現在いるディレクトリが、
確認できます。

どこのパスで操作を行なっているのかを認識するのは
とても重要です。

また、cdで移動した直後も、
他者が見たときにわかりやすいように、
pwdでどこにいるのか明示しておくのが良いようです。

###ディレクトリを変える
チェンジディレクトリコマンド ``cd 飛びたい先のディレクトリパス``

###ディレクトリの中のファイルを表示する
``ls``

###ディレクトリを新しく作る
``mkdir``

###ファイルをコピーする
``cp コピー元 コピー先``

###ファイルの削除
``rm　消去するファイル名``　と書きます。
ディレクトリを消すには、``rm　-r 消去するファイル名``　です。

``rm -i　消去するファイル名``　とすると、
本当に消去して良いファイルなのか尋ねてくれます。（ディレクトリの場合：``rm -ri ファイル名``)
イエス`y`か　ノー `n`で答えれば良いです。

rmを使う時は、極力-iを使い、
確認をする習慣をつけるのが良いでしょう。

###ファイルの移動
``mv 移動元 移動先``

###ファイルの中身を見る
`cat　閲覧したいファイル名`

###ファイルの中身を範囲を指定して見る
`head`を使います。
`head -15 ファイル名`で初めから１５行だけ閲覧できます。

`tail`は、
`tail -15 ファイル名`で末尾の１５行が確認できます。

###相対パス
・同じ階層にあるものは、そのままファイル名か「./ファイル名」
・下の階層にあるものは、「./フォルダ名/ファイル名」
・上の階層にあるものは、「../ファイル名」
・２階層上にあるものは、「../../ファイル名」
・1階層上にあるフォルダの中のファイルは、「../フォルダ名/ファイル名」

####viエディタ
メモ帳のようなもの。
`vi 作りたいファイル名`で、
viエディタに移行されます。

viエディタには、
コマンドモードと挿入モードがあります。

viエディタに移行後、
iを押すと挿入モードになります。

コマンドモードに戻る時はエスケイプキーを押します。
wで保存、qで終了です。
wqと押すと、保存して終了です。

##参照
・YouTube： Rainbow Planet IT[Info Tech] Linux入門
・[エンジニアの入り口](https://eng-entrance.com/you_can_do_linux)
Pythonを使って大量の時系列データを少メモリー環境においてそれなりの速度で集計する方法例

# はじめに

複数拠点で1年間で収集した30秒周期のデータを読み込んで各時間の合計値を求めるという課題があり、正攻法でやったら全然処理できなかったので、ちょっと工夫した内容をメモしておきます。

# データ形式

日時と値がCSV形式で拠点ごとに入っています。

|日時|値|
|---|---|
|2018-10-01 00:00:00|4|
|2018-10-01 00:00:30|1|
|2018-10-01 00:01:00|2|
|2018-10-01 00:01:30|6|
|2018-10-01 00:02:00|7|
|2018-10-01 00:02:30|7|
|：|：|
|2019-09-31 23:59:30|7|

このデータが100箇所以上の場所から集まってくるというものです。
なお、リアルタイムではなく、一定期間の経過後に集計するという内容でした。

単純計算で、一箇所が1,051,200件、100箇所の合計で105,120,000件のデータになります。

...10億(-_-;)

# 最初にやったこと

ファイルを全て一気に読み込み、日時でグルーピングして合計値を出す！

```py:
from glob import glob
import pandas as pd

files = glob("data/*.csv")

df = pd.DataFrame()

for file in files:
    df = pd.concat([df, pd.read_csv(file)])

df = df.groupby("日時").sum()

df.to_csv("合計値.csv")
```

...RAM使用量はスワップ領域をどんどん使い、半日経って80GBを超えたところでエラーで終了。

ファイルを減らして少しずつ合計値を求める方法を試したけど、ちょっとしっくりこない。

# 最後にやったこと

ファイルを読み込んで、都度合計値を求めるというやり方にしてみました。

```py:
from glob import glob
import pandas as pd

files = glob("data/*.csv")

df = pd.DataFrame()

for file in files:
    df = pd.concat([df, pd.read_csv(file)])
    df = df.groupby("日時").sum().reset_index()

df.to_csv("合計値.csv")
```

結果、RAMを圧迫することもなく、数分で終わりました。

当たり前のことかもしれないし、わかってしまえば何てことないことだけど、ちょっと時間を使ったってしまったので、同じ苦労をする人が一人でも減れば良いなと思って記録しておきました。

さて、僕の作業はここからが本番。
データ分析、頑張ろう...(-_-;)
ちょくちょく苦しむnokogiri Error解消法

最近はdockerで構築するので無縁でしたが、久しぶりにローカルで構築して、bundleした際に、nokogiriのエラーが出たので備忘録
昔よく悩んだようなww

```
An error occurred while installing nokogiri (1.10.5), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.10.5' --source 'https://rubygems.org/'` succeeds before bundling.
```
##解決
こちらを参考にさせていただきました。

https://qiita.com/___inon_/items/59315b465251bf2e4db3

```
$ brew tap homebrew/dupes
```

廃止された？？？

```
Error: homebrew/dupes was deprecated. This tap is now empty as all its formulae were migrated.
```

とりあえす飛ばして次のコマンド

```
$ brew install libxml2 libxslt libiconv
```

またエラー

```
Error: libxml2 2.9.9_2 is already installed
To upgrade to 2.9.10, run `brew upgrade libxml2`
Error: libxslt 1.1.33_1 is already installed
To upgrade to 1.1.34, run `brew upgrade libxslt`
Warning: libiconv 1.16 is already installed and up-to-date
To reinstall 1.16, run `brew reinstall libiconv`

```
エラーの出てるbrew upgradeを打ってみる

```
$ brew upgrade libxml2
$ brew upgrade libxslt
$ brew reinstall libiconv
```
```
brew link --force libxslt
```
もう入ってる？

```
Error: libxslt 1.1.34 already installed
```
なんとか解決しました
PythonでGmailを送りたいけどエラーで無理

今日は朝からPythonのオンライン講座に登録しました。
有料ｺﾝﾃﾝﾂに入ってすぐ理解不能。

「PythonでGmailを送る」

え？？そんなんできんの？

でも私はできない。



from email import message
import smtplib
smtp_host = 'smtp.gmail.com'
smtp_port = 587
from_email = '送る人のアドレス'
to_email = '送りたい相手のアドレス'
username = '自分のアドレス'
password = 'パスワード'
msg = message.EmailMessage()
msg.set_content('test mail')
msg['Subject'] = 'test mail(sub)'
msg['From'] = from_email
msg['To'] = to_email
server = smtplib.SMTP(smtp_host, smtp_port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(username, password)
server.send_message(msg)
server.quit()


エラーの文章も載せたいけど、どれが個人情報かわからないので載せれません…
p=WantAuthError
最後に書かれているこれが気になるけど検索しても出てこない…
なんでかな。。。。
分かる方いましたらアドバイスお願いします！！！！

あきらめない
font-awesomeを駆使したい ❏HTML❏

#font-awesomeとは

ページ上にアイコンを表示させることができます。
こんなんです↓
![ダウンロード (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529651/27fb5eab-3cda-90d8-3d1a-1d8b43c94a43.png)
>https://fontawesome.com/icons?d=gallery

無料だけでも1544種類あるので十分すぎると思います。

今回はCDNを使って実装します。
手順はたった2つです。

#手順1
HTMLのheadタグ内に、
`<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">`
を貼り付ける。

```html:
  <head>
    略
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
  </head>
```

headタグの一番下に貼り付けとけば大丈夫です。

---

hamlの場合↓

```haml:application.html.haml
%head
  略
  %link{href: "https://use.fontawesome.com/releases/v5.6.1/css/all.css", rel: "stylesheet"}
```

#手順2
使いたいアイコンのコードをコピーして表示させたい位置に貼り付けます。

例えばAmazonのアイコンの場合は、

![ダウンロード (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529651/cb7ad01c-2b9c-3fa7-cb79-e11984fcac60.png)
>https://fontawesome.com/icons?d=gallery

上の方にあるコード
`<i class="fab fa-amazon"></i>`
をコピーして好きなところに貼り付ければOKです！

<br>
このアイコンはクラス名を振って、CSSで色や大きさを変更することも可能です。
font-awesomeを使ってデザインの幅を広げましょう！！

<br>
ではまた！
Django2.2 SQLite3バージョンエラー


#python manage.py runserver　実行時にエラーが発生

```
$ python manage.py runserver
(省略)
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
```
#環境
Python3.6
Django2.2.6
SQLite3.7.13



#対処
どうやら SQLiteのバージョンが3.8.3かそれ以降じゃないとダメらしい。

SQLite3の現在のバージョンを表示

```
$ sqlite3 --version
3.7.13 2013-05-20
```
現在（2019-11-15）のSQLite3の最新バージョンが3.30.1のためかなり古い。

以下のページを参考にSQLite3をバージョンアップする。

[Django2.2で開発サーバー起動時にSQLite3のエラーが出た場合の対応](https://qiita.com/rururu_kenken/items/8202b30b50e3bfa75821)

#おわり
teratailなどにもこのエラーに関する質問があったが上記のページのやり方が一番確実だった。

ソースを落としてmakeする以外にも直接リポジトリを追加してyumからアップデートしてる人もいた。
HTML?終わるよ

HTMLはもうすぐ終わる。ブラウザなどから対応はするが、じきにプログラマーからは忘れられるだろう。一部のCMSなど旧来型で生き残るだけ。HTMLがそもそもこれほど長く使われるとは想定してなかってはず。こんなサイトのように。
<a href="https://premium-catfood.com/kalkan-neko-review-reputation/" >カルカン猫の評価</a>サイトでは2020年になってもHTMLが使われている。だからこれからも一部では残るだろう。一般のプログラマーでもない人達が、WEB制作をするから。
使わないと思っていたスキルも捨てたもんじゃない

[Development Career Plan: 5 Skills You No Longer Need](https://www.itprotoday.com/development-techniques-and-management/development-career-plan-5-skills-you-no-longer-need) によると、以下の開発者スキルは不要になってきているとの事です。

 * コンパイラのバグに対処する能力
 * 開発用PC のセットアップ
 * ハードウェアに依存した機能の構築
 * OS の違いを吸収する方法
 * ソフトウェアをパッケージ化する方法

組み込み系、ゲーム系等においてはまだまだ重要なスキルではあったりしますが、これらの重要度が低くなってきているという事には大方同意です。

システム開発に限らず時代とともに必要なスキルが変化していく事は当然ですが、不要と思っていたスキルが突然必要になる事もあります。映画なんかだとそういうのって見せ場ですよね。時代に乗り遅れた古い技術者がみんなから疎まれているんだけど、あるトラブルに対処できるのがその人しか居ない！　そんな場面よくあるんじゃないでしょうか。

現実には滅多にない事ではありますが、私が遭遇したいくつかのケースを紹介します。

## 逆アセンブルで問題個所を特定

逆アセンブルというのも今世紀に入ってからめっきり利用する機会が減ってきたのですが、それでも使う機会がありました。

あるサーバーにおいて、稀に（と言っても低くない確率で） SEGV する事態が発生。そのサーバーではうちのシステムが動いているだけなので、疑われました。しかしソースのどこをどう見直しても現象に関連すると思われる箇所が見つかりません。むしろ他に原因があると考えるのが合理的であるとの判断になりましたが、お客さんはなかなか納得してくれませんでした。そこでコアダンプを頼りに逆アセンブルし、デバイスドライバ内に原因を特定。お客さんにも納得してもらいました。


## RS-232C で電源管理

あるサーバーが突然ストンと落ちる事態に遭遇。明らかにハードの劣化でしたが、色々な事情があってすぐにそのハードウェアを交換する事は不可能な状況でした。超低予算なプロジェクトであっため、電源管理ソリューションを導入する事もできず、回路を自作し RS-232C で電源管理を行う事にしました。ソフトウェアの案件でハードを設計・自作するという稀有な例でした。

![circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347126/2f1da67a-590b-9515-39ca-3c077c3132a8.png)

## 基盤のコンデンサーを交換してワークアラウンド

これは知人の例ですが、サーバーが突然リセットしてしまう事態に遭遇。こういう場合、大抵は電解コンデンサの劣化が原因で、通常ならマザボを交換するか、できればハードを丸ごと交換するのがベストです。しかしこれもまたすぐには交換できず、秋葉原でコンデンサを買ってきて付け替えるという方法で当座を凌ぎました。


## 最後に

うちは色々やってる1人企業ですが、開発案件としては普段は業務アプリを作る会社です。なので逆アセンブルやら基盤をいじったりという事は普段はやらないので、上記の例はいずれも例外中の例外です。当然ながら業務アプリを作っている人に「回路は組めるべきだ！」とか「逆アセンブルはできるべきだ！」なんて言うつもりもありません。それでも知っていると予想外のソリューションで周りやお客さんをビックリさせられるかも知れません。

まー、滅多にない事ですけどね。
docker-composeでMySQL8.0とphpMyAdmin環境構築

##はじめに
ちょっとしたことだけど、詰まったのでメモ用に。
[docker-compose でMySQL環境簡単構築](https://qiita.com/A-Kira/items/f401aea261693c395966)の記事を参考に環境構築を行っていました。

##事象
上記の記事ではMySQL5.7でしたが、MySQL8.0でやるとphpMyAdminがコケる

```
mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
mysqli_real_connect(): (HY000/2054): The server requested authentication method unknown to the client
MySQL サーバに接続しようとしましたが拒否されました。config.inc.php のホスト、ユーザ名、パスワードが MySQL サーバの管理者から与えられた情報と一致するか確認してください。
```
とか言われてしまう。
解決法を検索していると、コンテナ内のconfig.inc.phpをごちゃごちゃと触っているものが出てきてなんか面倒くさそうだった。

##解決方法
`my.cnf`に

```
default_authentication_plugin=mysql_native_password
```

を追記したらちゃんとphpMyAdminが動きました。

具体的には上記の記事の`my.cnf`に追記して

```my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default_authentication_plugin=mysql_native_password

[client]
default-character-set=utf8mb4
```
と言った感じです。

##原因
[MySQL 8.0にアップデート！注意すべき点](https://hit.hateblo.jp/entry/MYSQL/MYSQL8/SETTING)を参照しておりますと、どうやらMySQL8.0の認証方法が（たぶん）変わったらしい。
そこで、旧MySQL Clientとの互換性を確保できる上記の文言を書くことで、とりあえず問題が突破できた感じになります。
gRPCの疎通確認をCircleCIで行う

ビルドしたserverに対して、ヘルスチェックが通るか確認したい
[grpc-health-probe](https://github.com/grpc-ecosystem/grpc-health-probe)を活用して行うと簡単にできる

### ヘルスチェックを実装する
[gRPC Health Checking Protocol v1](https://github.com/grpc/grpc/blob/master/doc/health-checking.md)を満たすようにヘルスチェックを実装する
自前で実装するより、`google.golang.org/grpc/health`あたりを使うと楽だし便利

```golang
package main

import (
	"google.golang.org/grpc"
	"google.golang.org/grpc/health"
	"google.golang.org/grpc/health/grpc_health_v1"
	"log"
	"net"
)

func example() {
	lis, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	grpcServer := grpc.NewServer()
	grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
	grpcServer.Serve(lis)
}

```

## buildして、ヘルスチェックが通るか確認する
```dockerfile:Dockerfile
FROM golang:1.13 as builder

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
WORKDIR /app
COPY . .
RUN go build -a -installsuffix cgo -ldflags '-w -s' -o server

FROM alpine
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]

```

ciの設定

```yml:.circleci/config.yml
version: 2.1

jobs:
  build:
    docker:
      - image: circleci/golang:1.13
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Build image
          command: docker build -t server .
      - run:
          name: Test image
          command: |
            docker run -d -p 8080:8080 --name built-image server
            docker run --network container:built-image amothic/grpc-health-probe -addr=localhost:8080
```

`amothic/grpc-health-probe`はscratchをベースにgrpc-health-proveを置いただけのイメージです
https://github.com/amothic/docker-grpc-health-probe
sqlのテーブル結合(left join)時の注意点　ー表で解説ー


初心者は間違いやすいかも。まとめてみた。
## まずはjoinとleft joinの説明
これからtable1、2を結合していく。共通カラム:Noで結合。

table1

| No       |       名前|    年齢   |
|:-----------------|------------------:|:------------------:|
|１            |              田中|        １０|
| ２|            木村|       ５６|
| ３|              マイケル|        １２４|

table2

| No    |       趣味|    性別    |
|:-----------------|------------------:|:------------------:|
| ２           |            （null,つまりデータ無し）|       男|
| ３             |              バスケットボール|        女|

## JOINの結果

| No       |       名前|    年齢   |    趣味|    性別    |
|:-----------------|------------------:|:------------------:|------------------:|:------------------:|
| ２|            木村|       ５６|    （null,つまりデータ無し）|       男|
| ３|              マイケル|        １２４|      バスケットボール|        女|

joinは結合条件が一致しないレコードは表示されない。

## left joinの結果 
| No       |       名前|    年齢   |    趣味|    性別    |
|:-----------------|------------------:|:------------------:|------------------:|:------------------:|
|１           |              田中|        １０|    (null)|        (null)|
| ２|            木村|       ５６|    （null）|       男|
| ３|              マイケル|        １２４|      バスケットボール|        女|

No1に関して、joinでは丸ごと消えるが、left joinではnullとして結合される。

結合条件が一致してなくても全レコード表示させたいときにleft joinを使うとnullで結合される。



left join 内にwhere(抽出条件)を書くことで該当するものだけを表示し、該当外をnullにできる。
以下だと、性別＝男だけを表示するので、バスケットボールと女の部分がnullとなる。

```
left join(select * from table2 where 性別 = '男') on table2.No = table1.No
```
絞るほどnullが増えていく。

## left jon時の注意点。共通カラムが重複レコード存在するパターン
left join 内にwhere(抽出条件)を書くのは危険な場合がある。
例えば、上のテーブルで　性別＝男　と絞り、抽出したが
No＝3 にもう一人いて、その人が男である場合も含まれない。

`where　性別 = '男'` 、はNo3女とNo3男があるときNo3男側は表示されると思うが、
1つのNoに男女両方いるレコードは含まれない。
結合条件が`on table2.No = table1.No` 　つまり　No3に男以外がいるじゃん！となってNo3全てnullとなってしまう。
（結合条件が主キーとか重複しない一意な項目なら問題ない）

例：1つのNoに男女ともいるtable2

| No    |  住人|       趣味|    性別    |
|:-----------------|------------------:|:------------------:|------------------:|
| １             |  １             |              サバゲー |        男       |
| ２           |    １          |         （null,つまりデータ無し）|       男|
| ３             |    １             |             バスケットボール|        女|
| ３             |    ２             |             ソフトボール|        男|

# 対応


left join内のwhereで指定せず、両テーブルの全てのレコードを結合してから最後にwhereで絞る！
パターンを使い分けよう。

# おまけ　内部結合と外部結合
今回説明したjoinのように結合条件が一致しないレコードは表示されないのが**内部結合**。
left joinのように結合条件が一致してなくても全レコード表示されるのが**外部結合**。

joinは正しくは**inner join**と呼ばれる。
left joinはは正しくは**left outer join**と呼ばれる。

外部結合にはもう1種類あってright join（正しくは**right outer join**）がある。

### left joinとright joinの違い
`select * from table1 〇〇join table2`
とあるとき。左がtable1で、右はtable2のように見える。

left joinだとtable1が優先表示される。
[left joinの結果](#left join)の結果を見ると、table1は全て表示されtable2にないレコードはnullで結合される。

right joinだとtable2が優先表示される。
[left joinの結果](#left join)の結果を見ると、table1は全て表示されtable2にないレコードはnullで結合される。
これが逆になり、table2は全て表示されtable1にないレコードはnullで結合される。
GIGABYTE AERO 15S OLED YA-9JP5750SP で Windows 10 と Ubuntu 18.04.3 LTS をデュアルブートした際の Wi-fi の有効化

# GIGABYTE AERO 15S OLED YA-9JP5750SP

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/a75a6839-637a-b397-61c2-c69ce633e16a.png)

https://www.ark-pc.co.jp/i/72001235/

高額なゲーミングノートなのでお持ちの方は少ないかもしれないですね。
私は幸運なことに開発用にコレを買ってもらいました。

# Ubuntu 18.04.03 LTS で Wi-fi を有効化する
Linux 環境が必要だったので windows 10 と Ubuntu 18.04.03 LTS をデュアルブートしたのですが、このとき Wi-fi が効かなくて困りました。

これは以下のサイトに従ってコマンドを実行して再起動することで解決しました。

https://support.killernetworking.com/knowledge-base/killer-ax1650-in-debian-ubuntu-16-04/

こちらにもそのコマンドを記載しますと

```
$ sudo add-apt-repository ppa:canonical-hwe-team/backport-iwlwifi
$ sudo apt-get update
$ sudo apt-get install backport-iwlwifi-dkms
$ reboot
```

以上となります。

カーネルを更新するとその都度やり直さないといけないというようなことがサイトに書いてあります。カーネルが更新されたせいなのか私は2度この作業をしました。ただし、1度目は上記の方法ではなく、もっと複雑な方法でした。簡単な方法になって良かったです。

ちなみに、1度目はセキュアブートを解除するのを忘れていて私は一日中再起動を繰り返していました。2度目は、もうセキュアブートが解除されっぱなしなのか一発で Wi-fi 有効化できました。
Robloxで階段をスクリプトでつくる

# 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/4be32972-97b2-54f3-55e6-a28c27bba4ce.png)

- これで壁や床がいきなり出てきたり、消えたりなんかもできそうですね

- ServerScriptServiceに、Scriptを追加して、名前をbuildStairにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/434ea414-f664-e869-b929-099feddfd726.png)

# プログラミング

``` buildStair.lua
for j=0, 10 do
	for i=0, 10 do
		wait()
		-- 新しくPartをつくって、WorkSpaceにおく
		local myPart = Instance.new("Part", game.Workspace)
		-- 空間に固定する
		myPart.Anchored = true
		-- 少しずつずらしながら置いている
		myPart.Position = Vector3.new(i+1, i+1, 230+j)
	end
end
```
WEBエンジニア勉強会 #15 (東京都, 渋谷) に行ってきた話

# 目的

- 題名の勉強会に初参加した話を書く。

# 参加した勉強会の内容

- web系の知見を広げる会である。
- フロント、サーバ、問はず色々な話が聞ける。
- 初心者向けでもあるので、気軽に参加しやすい。
- 高頻度でたくさんの方のお話が聞ける。

# 主催者さん

[@engineer_osca](https://twitter.com/engineer_osca)さん  
お一人で運営をされている。
お手伝いさんを募集しているようです！
今回はお子さんが体調を崩されている中主催者として今回の勉強会を開催していただきました。本当にありがとうございます！！

# 今回のイベントのconnpass

[WEBエンジニア勉強会 #15 (東京都, 渋谷)](https://web-engineer-meetup.connpass.com/event/152450/)

# タイムテーブルと簡単な内容

### axiosを型安全にするラッパーを作ったらVSCodeの補完で生産性が爆上げした話 [@m_mitsuhide](https://twitter.com/m_mitsuhide)さん

- 型安全のお話をされていました。
- 実際にコーディングをされながらお話されていました。

### プレイングマネージャーになったときの話（仮） [@ykagano](https://twitter.com/ykagano)さん

- プレイングマネージャーのあるべき姿をお話されていました。
- 外部委託開発との付き合い方をお話されいていました。
 
### デザインを見ながらフロントエンドコーディングをするときの考え方 [@kkoudev](https://twitter.com/kkoudev)さん

- デザインからコードへの落とし込み方法を話されていました。
- 実際に使えるテクニックを詳しくお話してくれていました。

### ネストした JSON を CSV に自動変換する Python ライブラリを作った [@kawasin73](https://twitter.com/kawasin73)さん

- 自作のライブラリのお話をされていました。
- ちょっと自分にはレベルが高すぎました。。。ごめんなさい。

### docker関連の発表を予定 (テーマ未定) [@grem_ito](https://twitter.com/grem_ito)さん

- Dockerを用いたチュートリアルについてお話されていました。
- Docker導入のメリット、デメリット、トレードオフについて詳しく教えていただきました。 

### 世界中のフロントエンダーの残業時間を減らす、新しいフロントエンドフレームワーク [@StewEucen](https://twitter.com/StewEucen)さん

- コードの書く量を節約できるJSフレームワークのMa_gicianのお話をされていました。
- JSについて全く知識のない自分でもとてもすごいものであることが実感できました。

### WEBエンジニア歴2ヶ月で躓いたエラー10選 [shinji ukai](https://twitter.com/J8Ilr1HGmm6Oe3n)さん

- エンジニア初心者あるあるをお話されていました。
- とても盛り上がっていました。
- 個人的にとても共感できました。

### pulumi + aws [@mov_vc](https://twitter.com/mov_vc)さん

- 環境作成の自動化についてお話されていました。
- Pulumiについてお話されていました。

# この勉強会で得たもの

1. 知らない技術を知るきっかけになった。
1. 実はつよつよなエンジニアのみなさんも初心者の時期があったことを知れた。
1. なんだかんだ技術が好きな人がたくさんいた。
1. エンジニアのみなさんは比較的初心者に優しい。
1. 自分も登壇をしてみたい気持ちになった。
1. outputの大切さを改めて実感した。
1. 自分には難しい話もあったが、少なからず登壇されたみなさんの発表で全くわからない内容はなかったので楽しかった。
1. 技術的なお手本にもなったが、登壇の際の勉強にもなった。

# 最後に主催者さんからのお言葉

1. 知らない技術のキーワードだけでも覚えて帰って知見を広げてもらいたい。
1. 登壇しなかった方でも参加レポートなどを書いてoutputしよう。
1. スタッフやサポートを募集している。
1. 次回開催は年明けを予定している。
WSL の Ubuntu に Textbringer をインストール

# 概要
WSL（Windows Subsystem for Linux）上の Ubuntu に [Textbringer](https://github.com/shugo/textbringer) をインストールする手順です。

# 環境
- Windows 10 Home 64bit バージョン 1903
- WSL（Windows Subsystem for Linux）を利用
- Ubuntu 18.04 LTS
- WSLtty
- rbenv
- ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

# インストール手順
`$ sudo apt install libncursesw5-dev`
`$ gem install curses`
`$ gem install textbringer`

# 起動
`$ textbringer`