OmniAICreator/Qiita-1.07M huggingface dataset:
HTML5 FormでのValidation

# やりたかったこと
Formのinput要素のバリデーションを最小の労力で実現する。バリデーションの結果、どこの何が問題なのかが分かればいい。

（やりたくないこと：JavascriptとHTML5の仕様追及:frowning2:）

# できた。と思ったのですが。。。

```html
    <form id="form1">
      <input type="number"
             id="size"
             title="Size"
             maxlength="20"
             min="1"
             required
       />
       <input type="submit" id="simExec" value="実行" />
    </form>
```
いやぁ、HTML書くだけでvalidationしてくれるなんて、素敵な世の中になったものだ、ことのときはそう思っていたんです。
AjaxでリクエストパラメータをJSON形式にしてAPIへ送信したかったので、ボタンのonclickイベントに送信する関数を登録していました。

```js
document.getElementById('simExec').addEventListener('click', sendSimRequest);
```

実はいまだに謎なのですが、ブラウザを開いて最初に送信したときだけ、送信されずに画面がリロードされます。その後はボタンを押せばリクエストが送信されます。submitでFormがリロードされるのは仕様ではありますが。。。
最初にも書いたとおり、この辺りの仕様を追求するのは避けて、submitをやめることにしました。

# ここからが本題：FormのsubmitなしにValidationする
別にそれがやりたかったわけではないのですが、逃げ回った結果、そこに行き着いた、ということです。

## formとsubmitをやめた
```html
    <div id="form1">
      <input type="number"
             id="size"
             title="Size"
             maxlength="20"
             min="1"
             required
       />
       <button type="button" id="simExec">実行</button>
    </div>
    <div id="message" style="color: #ff0000"></div>
```
submitの挙動から逃げるために、こんな感じに。もともとリクエスト送信はJavaScriptだったので、気軽ということもありました。
`id="message"`が突然出てきていますが、その理由は以下で。

## でもvalidationはしたい。
inputに定義した制約は生きています！ただ、submitしないとそれを拾ってメッセージをポップアップ表示するアクションが行われない**だけみたい**です。
そこで、以下のようなJavaScriptでValidation結果を拾って、エラーメッセージとして表示します。ここで`id="message"`のところを使います。

```js
function execute() {
  if (!validateInput(document.getElementById('size'))) return false;

  //この後で、例えばリクエスト送信する。
}

function validateInput(element){
  clearMessage();

  if (!element.willValidate) return true;

  if (element.validity.valueMissing) {showMessage(element.title + ":Input required."); return false;}
  if (element.validity.typeMismatch) {showMessage(element.title + ":Type mismatch."); return false;}
  if (element.validity.tooLong) {showMessage(element.title + ":Too long."); return false;}
  if (element.validity.rangeUnderflow) {showMessage(element.title + ":Input value is under the limit."); return false;}
  if (element.validity.rangeOverflow) {showMessage(element.title + ":Input value is over the limit."); return false;}
  if (element.validity.stepMismatch) {showMessage(element.title + ":Input value is not match the step."); return false;}

  return true;
}
```

言わずもがな、な内容ですが、メッセージ表示と消去のfunctionも掲載しておきます。

```js
function showMessage(msg){
  document.getElementById('message').innerHTML = msg;
}
function clearMessage(){
  document.getElementById('message').innerHTML = "";
}
```
便利な機能でも、少しそこから外れようとしただけでレールに全く乗れなくなる、よくある話ですね。でも、validationの値が取れたのはよかった。


# 参考文献
(http://webbeginner.hatenablog.com/entry/2014/11/01/172318)
[[JavaScript]HTML5 Form Validationの制御と注意事項](https://qiita.com/leedohyung-dba/items/b762e21018edc4d0387c)
Rails 絵文字を登録〜Mysql2::Error: Incorrect string value〜

Railsで作ってるフォームに絵文字を登録しようとして

`Mysql2::Error: Incorrect string value`と怒られた。
絵文字の形式が対応してないよーってことらしく、`utf8`を`utf8bm4`に変換すれば解決するらしかった。


##database.yml
utf8になっていたらutf8mb4に変換！

```database.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_bin
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  port: <%= ENV['DB_PORT'] || 3306 %>
  reconnect: true
```


#DB
`mysql`のなかで

```
mysql> SHOW VARIABLES like 'char%';
+--------------------------+----------------------------------------------------------+
| Variable_name            | Value                                                    |
+--------------------------+----------------------------------------------------------+
| character_set_client     | utf8mb4                                                  |
| character_set_connection | utf8mb4                                                  |
| character_set_database   | utf8mb4                                                  |
| character_set_filesystem | binary                                                   |
| character_set_results    | utf8mb4                                                  |
| character_set_server     | utf8mb4                                                  |
| character_set_system     | utf8                                                     |
| character_sets_dir       | /usr/local/Cellar/mysql@5.7/5.7.28/share/mysql/charsets/ |
+--------------------------+----------------------------------------------------------+
8 rows in set (0.02 sec)
```

これはもう変更後なんだけど、変更前は`utf8`祭りなので

```
SET character_set_database=utf8mb4;
```

で↑のように`utf8mb4`に変換される

テーブルことにもできるはずなんだけど、何だかうまくいかなかったので全部utf8mb４にかえっちゃった


参考：　https://qiita.com/katsuyan/items/0c7ed34d9f8235b8363a
Salesforce の Org Development 用の Buildpack を作った話

こんにちは。[Heroku Advent Calendar 2019](https://qiita.com/advent-calendar/2019/heroku) の 13日目です :shamrock:
Heroku は初参戦ですがよろしくお願いします！
[Salesforce のほう](https://qiita.com/advent-calendar/2019/salesforce-platform) は15日目に書いてます！！

Heroku のほうでは **Heroku Buildpack for Salesforce** について書いてみます :writing_hand:

# Heroku Buildpack for Salesforce

Heroku Pipeline を利用して Salesforce の開発ライフサイクルを実現するための Buildpack が公式から提供されています。こちらは **Package Development Model** (Scratch Org を使うやつ) 前提となっています。

- https://github.com/heroku/salesforce-buildpack

しかし、**Org Development Model** (Sandbox とか Developer 環境を使うやつ) でやりたい場合の Buildpack がまだ提供されていません。なので、Fork してみました。

# Heroku Buildpack for Salesforce - Org Development

- https://github.com/takahitomiyamoto/salesforce-buildpack-org-dev

まだ個別設定が残ってるのできれいにしていきたいと思いますが、自分で使う分にはこれでばっちりです。もし使いたいかたは Fork して使っていただくか、プルリクをください。

先日の Salesforce World Tour Tokyo 2019 の Developer Theater に登壇した際に紹介したのですが、残念ながら Live Demo が失敗してしまいました :sob:

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">準備をおざなりにしてしまった結果、<a href="https://twitter.com/hashtag/DontStopDeploying?src=hash&amp;ref_src=twsrc%5Etfw">#DontStopDeploying</a> のデモがstopしてデプロイできないという屈辱を味わいました。場所を変えてリベンジします。<a href="https://twitter.com/hashtag/SalesforceTour?src=hash&amp;ref_src=twsrc%5Etfw">#SalesforceTour</a> <a href="https://t.co/OAkwbqlmo7">https://t.co/OAkwbqlmo7</a></p>&mdash; Taka *heat* Miyamoto (@takahito0508) <a href="https://twitter.com/takahito0508/status/1177368606423703552?ref_src=twsrc%5Etfw">September 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

コードのバグではなくて、単なる手順ミスだったのですが、このままだと恥ずかしいのでリベンジさせてもらいます。来年の <b>[Japan Dreamin' 2020](https://www.japandreamin.com/sessions/dont_stop_deploying/)</b> に同じ内容で登壇しますので、もしよかったら応援に来てください。また、そのころには [README](https://github.com/takahitomiyamoto/salesforce-buildpack-org-dev/blob/master/README.md) もちゃんと書けていると思うので、よかったら覗いてみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212555/c6e3050c-75b0-43c0-6bc6-2fb3252899ee.png)
 
# おまけ
なお、もしも mdapi コマンド経由でやりたいなら、すでにサンプルが提供されていますのでご参考まで。

- https://github.com/wadewegner/salesforce-dx-pipeline-mdapi-sample

以上になります。それではまた。
svgSpriteに色(fill)が効かない


##問題。
gulp-svg-spriteで作ったsvgSpriteにCSSのfillが効かない！
->全部真っ黒に...

##原因！
元データのsvg自体にfillがついているとCSSが効かない。
なんだ簡単だ。すぐに解決できそう。

https://qiita.com/rinoside/items/65bd2f84751dc45585c1
https://qiita.com/sats/items/7060afe95c25b13b8c78
上記を参考にしました。

解決法としては、
①svg-spriteのプラグインのsvgoを使う。
②svg-cheerioを使う！

## ①のプラグインのsvgo
svgoとは
https://github.com/svg/svgo
svgをいろいろ軽量化してくれる。こりゃいいや。

↓書き方

```javascript
const svgSpriteTask = () => {
    return gulp.src(`${paths.srcImg}/svg/*.svg`)
        .pipe(plumber())
        .pipe(svgSprite({
            mode: {
              symbol: {
                dest: 'svg',
                sprite: 'symbols.svg'
              }
            },
            shape: {
              transform: [
                {
                  // 下記にsvgoの設定を書いていく。
                  svgo: {
                    plugins: [
                      // ここでfill属性を排除
                      {removeAttrs:{attrs: 'fill'}}
                    ]
                  }
                }
              ]
            }
        }))
        .pipe(gulp.dest(`${paths.distImg}`))
};
```
 
バッチリですね！
gulpを走らせます！

## svgoでもcheerioでもfillが消えない
コンパイル後のファイルでfill検索してみるとわんさか残ってます。あれれ..
その後cheerioもしてみるも消えない。

諦めかけてsvgファイルをよく見たら、style属性の中にfill記述が！！！
つまり...

## styleも消す！

```javascript
const svgSpriteTask = () => {
    return gulp.src(`${paths.srcImg}/svg/*.svg`)
        .pipe(plumber())
        .pipe(svgSprite({
            mode: {
              symbol: {
                dest: 'svg',
                sprite: 'symbols.svg'
              }
            },
            shape: {
              transform: [
                {
                  svgo: {
                    plugins: [
                      // これを追加することで<style>が消える
                      {removeStyleElement: true},
                      {removeAttrs:{attrs: 'fill'}}
                    ]
                  }
                }
              ]
            }
        }))
        .pipe(gulp.dest(`${paths.distImg}`))
};
```

これをgulpで走らせたら無事消えました。属性だと思い込んでたけど違った...
元ファイルをよくみることは大事ですね。灯台下暗し。
UnicodeDecodeError: 'cp932' codec can't decode byte...

## ERROR

```
UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 132: illegal multibyte sequence
```

## OPEN WITH ENCORING
```.py
json_file = './test.json'
with open(json_file, encoding="utf-8_sig") as f:
    data = json.load(f)
```
blueqatで量子もつれ(entanglement)

## この記事に関して
ここではpythonライブラリのblueqatを用いて量子プログラミングを行っていこうと思います。
内容は[公式のチュートリアル](https://github.com/Blueqat/Blueqat-tutorials/tree/master/tutorial-ja)を元に作成しています。
今回は量子もつれ(entanglement)を実装します。

## 量子もつれとは
前回は $\left|+\right>,\left|-\right>$ を考えました。今回は2量子ビットの以下の値を考えてみます。

``` math
\frac{1}{2}\left(\left|00\right>+\left|01\right>+\left|10\right>+\left|11\right>\right),
\frac{1}{\sqrt2}\left(\left|00\right>+\left|11\right>\right),(\left|00\right> = \left|0\right>\otimes\left|0\right>)
```

左の状態は純粋状態のテンソル積で $\left|+\right>\otimes \left|+\right>$ と表せます。
では右の状態はどうでしょう、手を動かせばわかりますがこれは純粋状態のテンソル積でかけません。

このように2つの状態が絡み合っている状態を量子もつれ(emtaglement)と言います。

量子もつれの利点は情報の絞りこみを行うことができる点にあります。
たくさんの組み合わせのビットをうまく絞りこむことで欲しい状態の確率を引き上げることができます。

## 回路の作成
今回は Hゲートと CXゲートを使います。
$\left|+\right>\otimes\left|0\right>$ にCXを施すことで作られます。

``` math
H\left|0\right>\otimes\left|0\right> = \frac{1}{\sqrt2}(\left|00\right>+\left|10\right>)\xrightarrow{CX}\frac{1}{\sqrt2}(\left|00\right>+\left|11\right>)
```

#### 実装
上の状態を実装してみます。

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit(2).h[0].cx[0,1]
c.m[:].run(shots=1000)

結果
Counter({'11': 474, '00': 526})
```
00 と 11 が約50%で取れていることがわかります。

## GZH状態 (3量子ビットもつれ)
3量子ビットのもつれとしてGHZ状態というのがあります。
まずは値から

``` math
\frac{1}{\sqrt2}(\left|000\right>-\left|111\right>)
```
もつれてますね。

値の導出は言葉では難しいので以下に式を述べます。

``` math
\begin{array}{ll}
\left|0\right>\otimes\left|0\right>\otimes\left|0\right>&\xrightarrow{H\otimes H\otimes X}
&\left|+\right>\otimes\left|+\right>\otimes\left|1 \right>\\
&\xrightarrow{CX[1,2]}
&\left|+\right>\otimes\frac{1}{\sqrt2}(\left|01\right>+\left|10\right>) = 
\frac{1}{2}(\left|001\right>+\left|010\right>+\left|101\right>+\left|110\right>)\\
&\xrightarrow{CX[0,2]}&\frac{1}{2}(\left|001\right>+\left|010\right>+\left|100\right>+\left|111\right>)
\\
&\xrightarrow{H\otimes H\otimes H}
&\frac{1}{\sqrt2}(\left|000\right>-\left|111\right>)
\end{array}
```
(最後の計算はかなり省略していますが成り立ちます。)

#### 実装
上の状態を実装してみます。
`[:2]`とは上から2つのビットにゲートを施し、
`[:]`とは指定したビット全てにゲートを施すことを意味します。

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit(3).h[:2].x[2].cx[1,2].cx[0,2].h[:]
c.m[:].run(shots=1000)

結果
Counter({'111': 496, '000': 504})
```
000 と 111 が約50%で取れていることがわかります。

## まとめ
今回はblueqatを用いて量子もつれ(entanglement)を実装しました。
次回は様々な量子ゲートを実装してみます。
【MySQL】ERROR 1206 (HY000): The total number of locks exceeds the lock table size

SELECTしてINSERTしようとした時に，下記のエラーが出た．
どうやらデータが多くバッファプールが足りなくなったようです．

```sh
ERROR 1206 (HY000): The total number of locks exceeds the lock table size
```


そのため，`~/etc/my.conf`に
`innodb_buffer_pool_size=404750336`
を追記．sudo権限必要です．

```~/etc/my.conf
innodb_buffer_pool_size=404750336
```

更新したら再起動．

```
$ mysql.server restart
```

確認すると

```mysql
> show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 536870912 |
+-------------------------+-----------+
1 row in set (0.00 sec)
```

足される形になるんですね．

いろいろ調べてみると



https://qiita.com/mita2/items/8fd915164f0851c96e54
こちらの記事が参考になりました．
KubernetesをGrafana + Prometheusで監視する(ことにした)

この[記事](https://qiita.com/megasys1968/items/aa94ddfb92f57e08c4dd)を書いてから四半期が過ぎ、いろいろと動かすアプリが増えてきて、いい加減にやらないと、と思い、どんな監視方法があるのかを調べてみた。すると有料のものを除けばGrafana + Prometheusが一般的な印象だった。

## まずはZabbixで挑戦
でも過去の経験とか、既に監視で使っているとかの理由で、Zabbixにしてみた。
たまたま[Zabbix on Kubernetes](https://github.com/monitoringartist/kubernetes-zabbix)というリポジトリでマニュフェストファイルがあったので簡単に構築できそうだったし。
でも、、、

* zabbix-all-in-one-bare-metal.yamlで使われるZabbixコンテナイメージのmonitoringartist/zabbix-xxlは2年前で更新が止まってる。
* 同じグループに、Dockerに特化した?monitoringartist/dockbix-xxlというのがあり、今年4月にも更新されていた。
* そこでmonitoringartist/dockbix-xxlに書き換えてデプロイ。Zabbixは正常に起動した。
* しかし、直ぐにZabbix ServerのSwapが足りないとの警告がでる。kubernetes構築時はSwapをOffにするから?ちょっと不安に。
* dockbix-agent-xxl-daemonset.yamlでエージェントを配置。けどエージェントがZabbixに接続できないとエラーが出続ける。。。

のように自分の力不足で参入障壁を超えられずに断念しました。

## やはりGrafana + Prometheusで監視

なので定番の方法にしました。アプリのフレームワークとして使用しているSpring Bootが提供する監視インターフェスのMicrometerとも相性が良いし。([MicrometerがZabbixをサポートしてない](https://github.com/micrometer-metrics/micrometer/issues/65)のは驚いた。)

こちらの[記事](https://qiita.com/miyacomaru/items/6fa4121e7ba765e9efd6)を参考にさせて頂き、[Kubernetes Setup for Prometheus and Grafana](https://github.com/giantswarm/prometheus)でデプロイ。

```
kubectl apply -f https://raw.githubusercontent.com/giantswarm/prometheus/master/manifests-all.yaml
```
すんなりと起動して、Ingressの設定も加えてGrafanaの画面を見て、何も設定せずに各podのリソース使用状況が表示され、その簡単さにちょっと感動しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/54ae4e6a-e2b9-69db-11c5-3d9d878b615e.png)
もちろん、どんな情報が表示されてて、何か足りない情報がないかとか、検証しないといけないことの多さを考えると、ちょっとクラクラしますが。。。

### トラブル: kubeletインスタンスの監視ができない

Prometheusの[Alerts]画面を見るとInstanceDownの警告がでてた。
意味が判らず他の画面を見てたら[Status]-[Targets]画面の、kubernetes-nodesにある全エンドポイントがDOWN状態だった。エラーを見ると、各ノードの10255ポートに接続できないとのこと。

10255ポートはkubeletが認証なしで接続できるポートだったけど、セキュリティの関係で、Kubernetes 1.11以降のkubeadmで構築すると無効([参照](https://qiita.com/shmurata/items/a65e083cd91d42b241e7))になってた。

セキュアな10250ポートにアクセスする方法を模索したけど、いまいち設定方法が判らず、、、
Prometheusの監視定義?kubernetes_sd_configsでは元々10250ポートにアクセスするのを、manifests-all.yamlでは10255ポートに変更していたので、これを解除してみたけど駄目だった。。。

これは今後の課題ということにして、暫定的にnode-exporterにアクセスすることで警告を回避。

```yaml
      - job_name: 'kubernetes-nodes'
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
          - role: node
        relabel_configs:
          - source_labels: [__address__]
            regex: '(.*):10250'
            replacement: '${1}:9100'
            target_label: __address__
```

でもdaemonsetはmasterノードで動かないよね。masterノードの監視はどうするのが正しいのか調べたけど、それらしきものが見つからず、手動でnode_exporterを動かすことにした。
幸いにもRHEL/CentOS/Fedoraならリポジトリが用意されてた。

```
# curl -Lo /etc/yum.repos.d/_copr_ibotty-prometheus-exporters.repo https://copr.fedorainfracloud.org/coprs/ibotty/prometheus-exporters/repo/epel-7/ibotty-prometheus-exporters-epel-7.repo
# yum install -y node_exporter
# systemctl start node_exporter
# systemctl enable node_exporter
```

これでmasterノードのDOWN警告も回避しつつ、メトリクスも収集できる筈。
Rustを使ってWhitespaceを動かしてみた

# はじめに

こちらは SLP KBIT Advent Calendar 5日目の記事です。
ぜひご覧ください。

[SLP KBIT Advent Calendar](https://adventar.org/calendars/4214)

この記事では題名に書いてある通り、Rustを使ってwhitespace言語を動かしてみました。
ぜひみなさんのネタにしてください。


# Whitespaceとは？

Whitespaceは、難解プログラミング言語の1つです。どのように難解なのか、実際にプログラムを見てみましょう。
以下のプログラムは、「Hello World」と出力されるものになっています。

<pre>
hello.ws
   &#9;  &#9;   
&#9;
     &#9;&#9;  &#9; &#9;
&#9;
     &#9;&#9; &#9;&#9;  
&#9;
     &#9;&#9; &#9;&#9;  
&#9;
     &#9;&#9; &#9;&#9;&#9;&#9;
&#9;
     &#9;     
&#9;
     &#9; &#9; &#9;&#9;&#9;
&#9;
     &#9;&#9; &#9;&#9;&#9;&#9;
&#9;
     &#9;&#9;&#9;  &#9; 
&#9;
     &#9;&#9; &#9;&#9;  
&#9;
     &#9;&#9;  &#9;  
&#9;
        &#9; &#9; 
&#9;
  
</pre>

とてもきれいなコードですね()
もちろん手抜きではありません。このWhitespace言語は「半角スペース」「タブ」「改行」の三つのみでプログラムが書けるんです。

# 環境構築

今回、Whitespaceのインタプリタをこちらからお借りしました。
~~https://tech.hellorusk.net/entry/2018/11/23/221127~~
(現在は利用できません)

また、私はRustを入れていなかったので、こちらのサイトにしたがって進めました。
~~https://acn.blue/install-rust-language-windows-10/~~
https://doc.rust-jp.rs/book-ja/ch01-01-installation.html

Rustのインストールはとても簡単です。ぜひ入れちゃってください。


# 実行

 ファイルがあるディレクトリまで移動し、以下のように実行してください。

```
$ rustc src/whitespace_interpreter.rs
$ whitespace_interpreter.exe [実行したい.wsのファイル]
```

このようにすると実行できます。


# 書き方

以下のサイトを参考にしながら書いていきました。
https://magazine.rubyist.net/articles/0022/0022-Legwork.html#fn:1

何も見えなくて難しそうではありますが、割と単純です。多分。
かなりアセンブリに近いものになっています。
また、打ち込んでる途中に思考が途切れてしまうと、最初から見ないと書けない、みたいな問題が起きちゃいます。


# なんとなく作ったプログラム

　以下のプログラムは「1+1」の計算をしています。私自身できたときはとても感動したのですが、何も見えないため何もわかりません・・・

<pre>
wa.ws
   &#9;
   &#9;
&#9;   &#9;
 &#9;
</pre>
そこで以下のように、スペースを「S」、タブを「T」として書いてみました。

```
SSST
SSST
TSSST
ST
```
1行目は「SS」でスタックに数値をプッシュしますよ～、という意味になります。その後、Sを0、Tを1として2進数で数字を表しています。ただし、先頭の数字は正負を表します。そのため「ST」は「1」となります。その後の改行は終端記号を表しています。
2行目も同様です。
3行目は「TSSS」でスタックの上から二つを足し算しますよ～、という意味になります。その後、「T\nST」でスタックの先頭の数字を数値として出力しますよ～、という意味になります。

大雑把に説明するとこんな感じです。　

# おわりに

正直言って何の役にも立たないプログラミング言語の紹介をしました。とはいえ侮れないもので、WhitespaceでAtCoderを解いた方もおられます。
https://qiita.com/rsk0315_h4x/items/a0a81c3d636029288fa6

また、今回お借りしたインタプリタは未完成であるため、時間があるときに完成させたいなと思っています。
TypeScript: Nominal Typingを汎用的にする実装アイディア

コンセプト実装を書いたところで力尽きました。いつか解説も書きたい。

```typescript
// Nominal型の汎用的な機能を提供するモジュール
namespace NominalTyping {
  type Unbrand<T, U extends symbol> = Omit<T, U>
  export type CreateType<T, U extends symbol> = (object: Unbrand<T, U>) => T
  export const CreateType: CreateType<any, any> = object => object
}

namespace Module1 {
  import CreateType = NominalTyping.CreateType
  // タグプロパティのキーをモジュールプライベートにすることで、オブジェクトの生成方法を限定する
  declare const type: unique symbol
  export interface Foo {
    [type]: 'Foo' // タグプロパティのスコープがモジュールに閉じているので、タグの値は短い文字列でもグローバルで衝突することがない
    id: number
  }
  export interface Bar {
    [type]: 'Bar'
    id: number
  }
  // 正規のオブジェクト生成方法を提供する
  export const Foo: CreateType<Foo, typeof type> = CreateType
  export const Bar: CreateType<Bar, typeof type> = CreateType
}

namespace Module2 {
  import CreateType = NominalTyping.CreateType
  declare const type: unique symbol
  export interface Foo {
    [type]: 'Foo' // Module1.Fooと同じ値だが問題ない。
    id: number
  }

  export interface Bar {
    [type]: 'Bar'
    id: number
  }
  export const Foo: CreateType<Foo, typeof type> = CreateType
  export const Bar: CreateType<Bar, typeof type> = CreateType
}

namespace ClientCode {
  import Foo = Module1.Foo
  import Bar = Module1.Bar
  import Foo2 = Module2.Foo

  const foo = Foo({ id: 1 })
  const bar: Bar = foo // typeの値が違うので代入できない。
  const foo2: Foo2 = foo // たまたま同じ構造であっても、typeが指すシンボルが別物なので代入できない
  const foo3 = {} as Foo // 型アサーションは防ぎようがない
}
```
ワイ「ファイアウォール...?#前編」

ファイアウォールについて、復習も兼ねてなにそれ？人向けに語ります。
実際にはこういう時に設定が必要だよ！というのが分かるようになることを目的にしています。

# TL;DR
サーバにアクセスする際は、ファイアウォールという機能で通信が制限されます。
制限されているので、使いたい場合は許可設定が必要ですよ。

#背景
長いので技術的な話だけ知りたい人は、[ファイアウォールの概要の前に](#ファイアウォールの概要の前に)へジャンプ。


あるところの業務システムで、オンプレサーバ運用していたものを全てクラウド化した。
仮想マシンの払い出し作業は、ベンダーさんにこんな設定で払い出してくださいって依頼したら、
あとはやってくれて、仮想マシンが使えるようになる。

AWS/Azure/GCP使ったことある人は、イメージつくと思うけど、画面ポチポチして仮想マシン払い出す作業はベンダーさんがやってくれるイメージ。

よって、こっちとしては仮想マシンのリソースとか負荷分散装置の有無とかファイアウォールの設定とかを決めるだけでいい。

さて、この各設定をどうやって決めているかというと、動かすアプリケーションを導入する業者さんに決めてもらう。
特に、ファイアウォールに注目して話していくと、例えば、Webサービス使う場合、HTTPS(443/tcp)のポートを開放する必要があるわけだけど、クラウドサービスには、AzureならNSG、AWSならセキュリティグループ/ACL、GCPは特にネーミングなし？のように、マシン自体のファイアウォール（Windows Firewall,firewalld等）以外にも、ファイアウォール機能が用意されており、適切に設定する必要がある。

Azureの例は以下の記事参照。
[Azure Network Security Group(NSG)についておさらい](https://qiita.com/yotan/items/d5e3e8dcc94a2099fa05)
公式の図を用いるとこんな感じで、点線の「NSG1」と書かれたとこで通信を制限できる。
さらに、VM1というところでマシン自体のファイアウォールを設定可能である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159147/80342e32-2cba-45d7-28e9-7222fbb4ffd0.png)


しかし、この設定がなかなかテキトーで、「このポート開放するって言ってるけど、ホントにあってる？」とかよくある。
そして、このポートじゃないですねとなり、設定を変更しましょうとなる。

するとどうなるかというと、今度はベンダーさん側に「最初はAポート空けてっていったけどやっぱりBポート空けて！」と、どんどん無駄な時間がかかるのである。

この業務特有のボトルネックですが、導入するシステムで解放する必要があるポートは把握できるようになりたい。

そんな思いもあり、みんなで基本的なファイアウォールへの知識を深めていけたらと思います。

# ファイアウォールの概要の前に
概要の説明の前に、以下でIPアドレスとポートを使って通信するよ的な話をする。

そもそも、サーバってなにしてるのって話ですが、アクセスしたら何かできるようになります。
WEBサーバならWEBサイトが見れるし、DBサーバならデータを保存/検索できるし、Mailサーバならメールを送れるようになる。

この時「アクセスする利用者」と「アクセスされるサーバ側」は以下のようなイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159147/94fe751a-554a-3f28-ef78-39cca3f2b6a7.png)



さて、利用者側はどうやってアクセスしたいサーバまでいくでしょうか。
それはIPアドレスとポート番号を利用します。

IPアドレスはインターネット上の住所みたいなものです。
ポート番号はというと...家の中のドアみたいなものです・・か？
この住所の家の、1番の扉はトイレ、2番の扉はお風呂みたいな・・？（この例は伝わるのか・・・）
要は機能ごとにポートが分かれていて、番号がついていないところにアクセスしても何もないよって話なんですが。

Qiitaの記事にアクセスしたい場合を考えると、ブラウザを使って「qiita.com：443番」にHTTPのリクエストを送っています。
それで、「qiita.com」はDNSサーバで名前解決されてIPアドレスが分かるので、結局「IPアドレス：443」でアクセスする感じです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159147/6fe6bbf4-df45-e8be-620e-d1022e31a010.png)



なお、別のポートにつなぎに行っても何も表示されません。
例えば、ブラウザで「qiita.com:8080」と入力しても何も表示されません。
この場合はサーバまではたどり着けるけど、WEBサービス用のポート「443」番にアクセスしていない状態です。


# ファイアウォールの概要
さてここから、本題です。
ファイアウォールでは送信元IPアドレスやポートに関し通信を許可/拒否することができます。
下の図はポートに関し、443portへは許可、8080portへの拒否というルールを設定した場合はこんな感じを図にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159147/ba24c0b3-0c38-d570-e3d0-ad3042fa77f6.png)


portだけでなく送信元のIPアドレスでも設定は可能で、例えば、自社で使用しているIPアドレスからの通信のみ許可すれば、外部からの通信は出来なくなります。

そうやってサービスが使用可能な範囲を狭めて、セキュリティを担保していく感じです。

ちょっと長くなったので（背景のせい）前後編に分けます。
Advent Calendar　6日目に書きます。
[ワイ「ファイアウォール...?#後編」](https://qiita.com/ECOHOHOHOO/items/bfaf6b56a06af80fd5ce)
empty submoduleを(reset等の後で)複数回remote addする

resetやブランチを移動するなどして、2回、`git submodule add`すると、`If you want to reuse this local git directory instead of cloning again from (snip) use the '--force' option`なるエラーとなり、submoduleの追加に失敗する。
指定通りに--forceすればよい。以下のbashで検証できる。

- https://github.com/cielavenir/submodule-child-readme

```bash
function make_submodule() {
git submodule add -f https://github.com/cielavenir/submodule-child-readme.git
}

git clone https://github.com/cielavenir/submodule-test
cd submodule-test
git config user.name cielavenir
git config user.email cielartisan@gmail.com

make_submodule
git submodule

git reset --hard
rm -rf .gitmodules *
git checkout .

make_submodule
git submodule
```

しかし、submodule上にmirrorを作りたかった場合など、empty submoduleの場合は事情が違ってくる。.gitmodulesを力技で書く必要がある他、--forceに加え当該submoduleをaddする必要があるらしい。
以下のbashで検証できる。

- https://github.com/cielavenir/submodule-child

```bash
function make_submodule() {
tab=$'\t'
if [ ! -d submodule-child ]; then
    git submodule add -b master -f https://github.com/cielavenir/submodule-child.git
    if [ ! -f submodule-child/.git ]; then
        echo '[-] need to write .git manually'
        echo "gitdir: ../.git/modules/submodule-child" > submodule-child/.git
    fi
    git add submodule-child
    cat << EOM >> .gitmodules
[submodule "submodule-child"]
${tab}path = submodule-child
${tab}url = git@github.com:cielavenir/submodule-child.git
EOM
fi
git add .gitmodules
}

git clone https://github.com/cielavenir/submodule-test
cd submodule-test
git config user.name cielavenir
git config user.email cielartisan@gmail.com

make_submodule
touch submodule-child/readme
git -C submodule-child add readme
git -C submodule-child commit -m 'initial'
git add submodule-child

git submodule

git reset --hard
rm -rf .gitmodules *
git checkout .

make_submodule
git submodule
```
別所にある同名モジュールをロードする

以下のようなモジュールを作成すれば、別所にある同名モジュールをロードできます。PYTHONPATHをいじれない場合等にどうぞ。
(Py2/3動作確認済)

```py
import os
import sys

if sys.version_info[0]>=3:
    from importlib import reload

sys.path.insert(0,os.path.abspath(os.path.join(__file__,'..','..','..','real')))
import hello
reload(hello)
```

full sample: https://github.com/cielavenir/import-transfer
なんだかんだ使うUtil

##ライブラリ自作

備忘録です
コメントとか適当なのであしからず

```Utils.java
package util;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.Arrays;

public class Utils {
	
	/** --------------- Object --------------- */
	
	/** nullでなけれは真 */
	public static final Predicate<Object> nonNull = v -> v != null;
	
	/** nullなら空文字に変換 */
	public static final Function<Object, String> nullToEmpty = v -> v == null ? "" : v.toString();
	
	/** nullと数値でないものなら0に変換 */
	public static final Function<Object, Integer> nullToZero = v -> {
		try {
			return v == null ? 0 : Integer.parseInt(v.toString());
		} catch (NumberFormatException e) {
			return 0;
		}
	};
	
	/** --------------- String --------------- */
	
	/** nullでも空文字でもなければ真 */
	public static final Predicate<String> nonEmpty = v -> v != null && !v.equals("");
	
	/** nullでも空文字でも空白文字(半角全角)でもなければ真 */
	public static final Predicate<String> nonBlank = v -> v != null && !v.equals("")
			&& Arrays.stream(v.split("")).anyMatch(x -> !x.equals(" ") && !x.equals("　"));
}
```

日付型とかはもうほんと勘弁してほしいだいっきらい
php7.4でnull合体演算子、からの〜「??=」構文追加

以前
[php7.0からの新機能null合体演算子の使い方](https://qiita.com/a-nishimura/items/8af1af667ca1851ccdc6)
で紹介しましたが、

2019/12/01(日)のPHPカンファレンス2019でphp7.4の改善として`??=構文`の追加が紹介されておりました。

```
php5
$a['user'] = isset($a['user']) ? $a['user'] : 'nobody';

↓

php7
$a['user'] = $a['user'] ?? 'nobody';
```
null合体演算子でこう実装できていたものが、
これがさらにphp7.4では

```
php7.4
$a['user'] ??= 'nobody';
```
と書けるようになったとさ。

 

あと、
**ショートクロージャ**はまだしばらくは見慣れそうにないなぁ。。。
山手線で堂々とお気に入り風俗嬢の出勤情報を確認できるステルスサービス「Cyber Office クラウド」

<img width="640" alt="スクリーンショット 2019-12-05 10.03.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/4e622939-0002-e2c5-8b05-5398a18fd5f4.png">
<img width="638" alt="スクリーンショット 2019-12-05 10.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/a358a9e1-a21f-39e5-4213-520820eb9ef8.png">



#1　解決すべき課題

<b>ぼく「私はオキニ嬢が決まっている。その出勤を確認したいだけなんだ・・・・。」</b>
でも電車では風俗サイトなんて見れない、自宅でも家族がいるし、嫁は相手にしてくれない、でも独りの時間にそんなサイトばっかり見て時間が過ぎ去るのは嫌だ！

私が必要とするサービスを自分のために作ってみました。

<b>1:見る場所問題</b>
風俗関係のウェブサイトってどうしても見る場所を選びますよね。じっくり新人や新店舗を見たい人に関しては、専用サイトで見る必要がありますしそれでいいと思います。しかし、すでにお気に入り嬢が決まっていてその娘達の出勤だけ見たいという人には、XXXサイトを行き来するのは大変な苦労です。

当然家族団欒の場や電車などの公共の場では見る事ができません。

<b>2:時間の浪費問題</b>
私はお気に入り嬢の出勤だけを見たいだけだったのに、気がつけばエロサイトをネットサーフィンしてしまい、大変な時間を費やしたことがあります。サクッと出勤だけ確認できれば他の事にも時間が使えると思いました。

<b>3:見た目の問題</b>
掲載されているイメージがやはりセクシーすぎて、１の問題を引き起こします。もちろん1人で見る場合にはいいのですが、公共の場には向きません。

以上の課題を解決したいと思います。

#2-1 設計案
・ どこで見てても良いUI
・ 正確なお気に入り嬢の出勤情報を横断的に捕捉

簡単ですがひとまずこれを目標にして制作しました。

#2-2 使用技術と骨子
・正確な嬢の出勤情報は大手風俗情報サイトよるとも[Yorutomoさん]からスクレイピングして、データを解析する事にしました。

・フォームにyorutomoの嬢の個別ページを入力するだけで、自分だけのオキニ嬢出勤表が作れるようにしました。

・ 使用技術
Ruby on rails / Heroku / nokogiri / mechanize / Boot strap /devide  

#3 使い方
・１：ビジネス管理アプリ風Uiにログインします。Deviseで管理画面を作っています。今のところ、confirmableは切っていますので、適当なメールアドレスでも登録できるでしょう。

<img width="1136" alt="スクリーンショット 2019-12-05 9.41.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/e68e8116-c233-9452-5b0e-5236b009a400.png">

2:上部メニュービジネスメンバーの追加からオキニ嬢のURLをよるともからコピペします。

<img width="1142" alt="スクリーンショット 2019-12-05 9.32.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/7f4e68f3-ec84-c90a-93bb-51ae234eb945.png">


<img width="1112" alt="スクリーンショット 2019-12-05 9.44.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/63c4bbe2-b37e-05ae-712d-0f197c52087d.png">

よるとも側のページは個別の嬢の詳細ページでURLは以下のような感じのはずです。
https://www.yorutomo.net/tokyo/m2/a6/shop"店番号"/gal"女性番号"/

3:いくつか自分のお気に入り嬢を登録すると店舗横断型のスケジュール表が完成します。
<img width="1142" alt="スクリーンショット 2019-12-05 9.32.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178644/9dbabbab-b04c-986d-4d4c-54eb6cfe7bc4.png">

ユーザーインターフェイスは極力風俗関係の色を排除し、嬢の名前も初めの一文字のみの表示としています。なお迷いましたが、やはり予約はこのまましたいので電話番号は表示するようにしました。

「ペン」アイコンで編集・「ゴミ箱アイコンで」削除が可能です。

#4 良かった事と課題
・　電車でも人目を気にせずお気に入り嬢の出勤を確認できるようになった。
・　公式サイト、風俗情報サイトをサーフィンしまくる時間が削減できた。

[課題]
・　スマホにしっかり対応するUl設計。
・　嬢の名前をはっきりと出すとステルス効果が薄れるので、現在は一文字表示にしているが良い方法はないものか。

もし需要があればURL公開しますので使ってみてください。技術としては今あるものを重ね合わせた一般的なもので作っています。
【Laravel】routes.phpでDBから値を取得する

routes.phpからレコードの値を取ってきてそのままviewへ表示させたい、という部分があったので、メモ程度に書きます。

#環境
PHP : 5.6.30
MySQL : 10.1.21
Laravel : 5.1.46

#テーブル
以下サンプルテーブルです。
wordsテーブル

|id  |message  |
|---|---|
| 1  | Hello |
| 2  | こんにちは |

#コード
~~~route.php
Route::get('/', function () {
  // cookieからidを設定する
  if ($_COOKIE['lang'] == 'en') {
    $id = 1;
  } else {
    $id = 2;
  }
  
  // DB::table()を使用して値を取得する
  $query = DB::table('words')
    ->select('message')
    ->where('id', $id)
    ->first();

  $message = $query->message

   return view('main',['message' => $message]);
}
~~~

~~~main.blade.php
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        {{$message}}
    </body>
</html>
~~~

bladeの方はおまけ的な感じですが、一応念のため。
最近便利だった開発ツール

最近「便利!」と思った開発ツールを紹介します。
すべて基本無料で使えるツールです。


## Figma
[Figma](https://www.figma.com/)とは、デザインツールです。
ブラウザ上でいろいろお絵描きできるうえ、複数人で同時編集できます。
スマホ用ページのモックを書くのに使いましたが、すこぶる便利で感動しました。

##### 便利ポイント
* ブラウザ上でいい感じに絵が描ける
* 直感的に使える
* ショートカットキーがイラレとだいたい同じ
* ペンツールもイラレと同じ感覚で使える
* ドラッグ＆ドロップでレイヤー移動できる
* ドキュメント中で使用している色が見れる
(色数を減らすのに役立つ。適当に色を使うと↓のようにカラーパレットが汚れる)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/cd4c641a-4342-5ace-cd49-e02d41411547.png)

* 対象のデバイス(iPhone8とかiPhoneXとか)を選択すると、画面サイズに合わせた白四角を出してくれる
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/530926b1-9782-658d-9074-81beabfbd380.png)

* 再生ボタンを押すと、選択したデバイス上に表示している感じで各ページをスライド再生できる
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/a5601332-1f43-fd6d-0e0b-a80982fd6c1c.png)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/7db4a4f2-82f4-0cb4-39c3-f34faf16aa13.png)

* 同時編集できるため、リモートで打ち合わせをしながらその場で手直しできる
* png, jpg, svg, pdfでエクスポートできる
* (試してないけど)css出力もできるらしい

##### 補足
* 筆者はプログラマです。昔、少しだけイラレcs2を使っていました。
* とある懇親会で、ブラウザ版Figmaは本職デザイナからするとちょっと遅い、という話を聞きました。  
(デザイナさんはデスクトップ版を使ったほうがいいかも)

<br>

## REST Client
[REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)とは、VSCodeの拡張機能です。
テキストファイルに書いたHTTPリクエストを送信し、レスポンスを見ることができます。
テキストファイルゆえの気軽さ、取りまわしの良さが魅力です。

#### 使い方
* VSCodeで適当なテキストファイルを開く
* HTTPリクエストを書く
* `Ctrl+ALt+R`するとリクエストを送信
* 別タブが開き、返ってきたレスポンスが表示される
![Screenshot from 2019-12-04 18-26-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/96b32d65-2b5c-ada2-6194-58934a73e5b0.png)

#### 便利ポイント
* 複数リクエストを書き溜められる
* 作業メモと共存できる
(メモの合間に、雑にリクエストを書ける)
* レスポンスの一部をコピーしてコード中にペースト、とかしやすい

#### より詳細な使い方
https://qiita.com/toshi0607/items/c4440d3fbfa72eac840c

<br>

## fzf, peco
[fzf](https://github.com/junegunn/fzf)および[peco](https://github.com/peco/peco)とは、Linuxのコマンドです。
コマンドライン操作における項目の絞り込みや選択をいい感じにしてくれるコマンドです。
[この記事](https://qiita.com/yukiarrr/items/9c21d97f6c8ac31de157)を参考にgitコマンドを拡張したら大変便利でした。

#### 便利ポイント
* インストールするだけでbashのコマンド履歴参照が楽になる(下記参照)
* 文字入力するとリアルタイムで結果が絞り込まれる
* ↑↓キーで選択できる
* `|`(パイプ)を使って各種コマンドと連携可能
* コマンドAの結果をコピー -> コマンドBの引数にペースト(ex. git branch -> git checkout)   
みたいな操作を(がんばれば)解消できる  



#### 使用例: bashのコマンド履歴参照(インクリメンタルサーチ)
1. ターミナル上でCtrl+Rするとコマンド履歴が表示される
(bashデフォルト: 1件分しか出ない <=> fzf: 複数表示されるし、↑↓キーで選択できる)
![Screenshot from 2019-12-04 18-56-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/9280ca59-398c-b8c0-a15a-fbc1be1f9a44.png)

2. 続けてnpと打つと、「np」で始まるコマンドが絞り込まれる
(npm xxxを絞り込む意図)
![Screenshot from 2019-12-04 18-56-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/ebbd2ded-7b8d-1efc-5c40-31bc48e3878b.png)

3. さらにcと打つと"npm ci"が絞り込まれる
(bashデフォルト: 前方一致検索 <=> fzf: いい感じ(fuzzy)に絞り込んでくれる)
![Screenshot from 2019-12-04 18-56-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162371/aae5d277-2aba-4719-c473-e1ef9e46d28e.png)


<br>

## Skyway, ngrok
Skywayとは、ブラウザ上でリアルタイム通信をするための便利プラットフォームです。
ngrokとは、ローカル環境を簡単に外部公開できる便利サービスです。
興味がある方は[先月書いた記事](https://qiita.com/arene-calix/items/129dddd0d9db8f3f516f)をご覧ください。

<br>

## 最後に
世の中には便利なツールがあふれていて、素敵。
fzf, pecoは正直ぜんぜん使いこなせていないので、いい使い方をご存じなら教えてほしいです。
忘備録-Swiftの基本的なデータ型

#範囲型と片側範囲型
例
0..<10
“a”…“f”
3.4…
…16
..<1.7

##範囲型と片側範囲型のプロパティ

```swift
let hoge = 0...10
print(hoge.lowerBound)
print(hoge.upperBound)
```

##ストライド型

```swift
for x in stride(from: 0.0, to: 12.0, by: 0.5){
    print(x,terminator:"")
}
```

##可変個の引数が利用できる関数

```swift
func add(_ number: Int...) -> Int{
    var num = 0
    for n in number {
        num += n
    }
    return num
}

print(add(1,2,3))    // 6
print(add(0,2,3,4,4,9))    // 22
print(add(121))    //121
```

##部分文字列の取り出し

```swift
let hoge = "hogehoge"
let start = hoge.index(hoge.startIndex, offsetBy:1)
let end = hoge.index(start, offsetBy:3)
print(hoge[start])    // o
print(hoge[start ..< end])    // oge

```
リーダブルコードを未経験が読んで理解したこと

触ってない言語、機能について書かれている今必要なさそうなところは飛ばして、自分（初心者）がすぐに実践できそうな知識についてまとめてみました。



# 優れたコードとは？？

他者が読んで理解できるコード。
コードは短い方がいいが、『理解するまでの時間』を短くする方がよい。
そのため短くすることで逆にわかりにくくなるようであれば短くする必要はない。


## 名前に情報を詰め込む
##### 変数や関数、クラス名でも名前に情報を詰め込むのが大事。名前は短いコメントのようなもの。

- 明確な単語を選ぶ
getPageだと何のページをgetしているかわからない。インターネットから取ってきたページなら、downLoadPage等の方がわかりやすい。

- tmpやretvalなどの汎用的な名前は避ける。
明確な理由があれば使用してもいい。

- 抽象的な名前より具体的な名前を使う

- 変数名に大切な情報を追加する
ミリ秒を表す変数なら、変数名の後ろに_msとつけると何の変数かわかりやすい。

- 名前の長さを決める

- スコープが小さければ短い名前でも良い。

- 頭文字と略語
 string⇨strなど他人にも通じる略語を使うのがいい。BackEndManager⇨BEM等、他の人がわからない略語はNG

- 不要な単語は捨てる
 DoServeLoop（）だったら、ServeLoop()でも必要な情報は損なわれてないのでOK。なくても通じる単語は捨てる。

- 名前のフォーマットで情報を伝える
エンティティごとに異なるフォーマットを使う。
C++言語であれば、クラス名はキャメルケース、変数名は小文字にしてスネークケースで定義する、など。
ローカル変数とクラス変数も、異なるフォーマットで書くと一目見て何かわかるので良い。

- その他フォーマット規約
プロジェクトや言語によってもフォーマット規約は変わってくる。
JavaScriptでは、jQueryのライブラリ関数を呼び出したときは、変数名の頭に$をつけるというものがある。⇨iQueryのオブジェクトだと明確にわかるため。
HTMLだと、タグのid名の区切り文字にはアンダースコアを、class名の区切り文字にはハイフンを使う規約が有力。


## 誤解されない名前をつける
##### 自分のコードを読んでいる人が、自分の意図を正しく理解できることが大事。

- 限界値を含め場合はminとmaxを使う。
CART_TOO_BIG_LIMITという名前だと意味があいまい。（未満なのか以下なのかがわからない）⇨MAX_ITEM_IN_CARTのほうが意味が伝わりやすい。

- 範囲を指定する場合はfirstとlastを使う
startは適切な名前になるが、stopは複数の意味に解釈できるため、firstとlastを使用する方が適切。

- 包含/排他的範囲にはbeginとendを使う

- ブール値（真偽値）の名前
read_passward = true
パスワードをこれから読み取る？もう読み終わっている？適切な名前ではない。
user_is_authenticated = true
こっちのほうが適切。また、名前を否定形ではなく肯定系にしたほうがよい。

- ユーザーの期待に合わせる
getで始まるメソッドだとメンバの値を返すだけの軽量アクセであるという規約がある。
この規約を守らないと、DBからすべてのレコードを取ってくるときの変数名にgetをつけたりすると、間違って使用したりしてコストが高くなってしまう。

- 複数の名前を検討する


## コードの美しさ

- 一貫性のある簡潔な改行位置

- メソッドを使った整列

- 縦の線をまっすぐにする

```
$aaa     =  "test";
$b       =  "test";
$cccccc  =  "test";
```
イコールの位置を合わせると見やすい。

- 一貫性と意味のある並び
アルファベット順にしたり、「最重要」なものから重要度順に並べたり、対応する HTML フォームの <input> フィールドと同じ並び順にするなど。

- 宣言をブロックにまとめる

- コードを段落に分割する
文章と一緒。見やすくなる。

-　個人的な好みと一貫性
クラス定義のカギカッコの位置など、最終的には個人の好みによる部分が大きい。
間違ったスタイルを使っているプロジェクトもあるが、その場合はプロジェクトの規約に従うのが大事。
一貫性の方が重視される。


## コメントすべきことを知る

- コメントすべきではないことを知る
コードを見てわかることは書かない。関数の名前と同じことを日本語でコメントアウトするなど

- ひどい名前はコメントをつけずに名前を変える
コメントで説明するくらいなら、関数等の名前をもっとわかりやすい名前に変える。
関数名等はいろんなところで使用されるため、そっちを変えた方がよい。
「優れたコード > ひどいコード + 優れたコメント」

- 自分の考えを記録する
優れたコメントというのは「考えを記録する」ためのものである。
たとえばこんなの

```
// このデータだとハッシュテーブルよりもバイナリツリーのほうが 40% 速かった。
// 左右の比較よりもハッシュの計算コストのほうが高いようだ。
```
 コメントから情報を得ることができ、下手に最適化しようとして時間を無駄に使う必要がなくなる。
コードが汚い理由を書いてもいい。

- コードの欠陥にコメントをつける
プログラマがよく使う記法

| 記法　　　　       |　意味　　　　　　　　    | 
|:-----------------|--------------------: |
| TODO:            |あとで手をつける 　　　    |  
| FIXME:           |既知の不具合があるコード    |
| HACK:            |あまりキレイじゃない解決策   | 
| XXX:             |危険! 大きな問題がある    |

- 定数にコメントをつける
定数を定義するときはなぜその値を持っているかという背景を持っている

- 読み手の立場になって考える

- 「全体像」のコメント
- 
```
# 顧客が自分で購入した商品を検索する
```
このような、全体像が掴めるコメントをしておく。
新人向けチートシート: flexbox

# コンポーネントを並べる
## 横に並べる
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="taisukek" data-slug-hash="OJPQxgo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="OJPQxgo">
  <span>See the Pen <a href="https://codepen.io/taisukek/pen/OJPQxgo">
  OJPQxgo</a> by taisukek (<a href="https://codepen.io/taisukek">@taisukek</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```
.parent {
  display: flex; //親要素でflexコンテナーであることを宣言
}

.child1{
  flex: 0 0 100px; //子要素でflex率を指定
  background: lightgreen;
}

.child2{
  flex: 0 0 200px;
  background: lightsalmon;
}
```

## 縦に並べる
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="taisukek" data-slug-hash="povaWpz" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="povaWpz">
  <span>See the Pen <a href="https://codepen.io/taisukek/pen/povaWpz">
  povaWpz</a> by taisukek (<a href="https://codepen.io/taisukek">@taisukek</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```
.parent {
  display: flex;
  flex-direction: column; //子要素の並び方向はflex-directionで指定する。デフォルトはrow。
}

.child1{
  flex: 0 0 100px;
  background: lightgreen;
}

.child2{
  flex: 0 0 200px;
  background: lightsalmon;
}
```

#コンポーネントの幅を残りいっぱいにする
##サンプル
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="taisukek" data-slug-hash="GRgJooL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="GRgJooL">
  <span>See the Pen <a href="https://codepen.io/taisukek/pen/GRgJooL">
  GRgJooL</a> by taisukek (<a href="https://codepen.io/taisukek">@taisukek</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## flex-basisとflex-growを利用する
```
.parent {
 /*子要素にflexレイアウトを適用する*/
  display: flex;
}

.child1 {
　/*要素の幅を100pxに指定*/
  flex: 0 0 100px; 
}

.child2 {
  /*
    要素の幅を残りいっぱいにする
    (<親要素の幅> - <flexレイアウト適用対象のflex-basis値の合計>)
  */
  flex: 1 0 0; 
}
```

### flexとは
flexはflex-grow, flex-shrink, flex-basisの短縮系のため以下2つは同じ

```
 flex: 1 0 0;
```

```
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: 0;
```
Ruby on Rails 6のDockerでの環境構築

Ruby on Rails Advent Calendar 2019 5日目の記事になります。

Ruby on Rails 4.2のみ経験者でちょっと触れただけですが、3年ぶりくらいに環境構築してみました。
本当は環境構築だけじゃなくて弄くり回しかったところですが、環境構築だけでタイムアップでした。

[【Rails】Rails 6.0 x Docker x MySQLで環境構築](https://qiita.com/nsy_13/items/9fbc929f173984c30b5d)
[zazk/Rails-6-Docker-Alpine](https://github.com/zazk/Rails-6-Docker-Alpine)
[Quickstart: Compose and Rails](https://docs.docker.com/compose/rails/)
を大いに参考にさせていただきました。

# 環境

- macOS Mojave
- Docker for Mac
- Ruby on Rails 6.0
- PostgreSQL 11.1

## 初期状態のディレクトリ構成

```
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── entrypoint.sh
└── docker-compose.yml
```

## Dockerfileの設定

```dockerfile
FROM ruby:2.6
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn \
    && mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
```

## docker-compose.ymlの設定

```docker-compose.yml
version: "3"
services:
  db:
    image: postgres:11.1-alpine
  web:
    build: .
    command: bundle exec rails server -b 0.0.0.0
    volumes:
      - ./:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

## Gemfileの設定

```gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
```

## Gemfile.lockの作成(空のファイル)

```
$ touch Gemfile.lock
```

## entrypoint.shの作成

```entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

## 一旦Buildしてrails newでアプリ作成

```
$ docker-compose build
$ docker-compose run web rails new . --force --webpack --database=postgresql
```

## 再度Build

```
$ docker-compose build
```

`./config/database.yml`の編集

```database.yml
・
・
・
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: db
  username: postgres

development:
  <<: *default
  database: postgres
・
・
・
```

## docker-compose up を実行してサーバー立ち上げ

```
$ docker-compose up 
```

## アクセス

[0.0.0.0:3000](http://0.0.0.0:3000/)にアクセスすると

[![Screenshot from Gyazo](https://gyazo.com/cff436a6681ddee992a109b4e9405577/raw)](https://gyazo.com/cff436a6681ddee992a109b4e9405577)


## 苦戦したところとか

- webpackerはyarn必須で辛い。というかyarnがないとそもそもサーバーすら立ち上がらないのか...
- 依存関係が複雑すぎてbundle installでコケまくる
- とりあえず公式ドキュメント読んだ方がいい。Alpine Linux難しい。

明日は[@jkr_2255](https://qiita.com/jkr_2255)さんの記事です！
GCP アップデート (11/29-12/5 2019)

Next London後だからか全然アップデートなくなった。。

### AI Platform: [Dec 3, 2019](https://cloud.google.com/ml-engine/docs/release-notes#december_3_2019)
- デプロイしたモデルに対するリクエストとレスポンスをロギングしてくれる機能が、モデル作成時に有効化すると有効されれないバグが。
  - 先に作成して、その後でAPIで有効化する必要がある。

### Billing: [Dec 1, 2019](https://cloud.google.com/billing/docs/release-notes#December_01_2019)
- 11/2019の請求から、プロジェクトレベルの請求を消したよ。
  - 必要な場合はCost Tableレオp-とからダウンロードして使ってね。

### Billing: [Dec 4, 2019](https://cloud.google.com/billing/docs/release-notes#December_04_2019)
- ラベルをフィルタやグルーピングで利用できるようになったよ。

### dialogflow: [Dec 4, 2019](https://cloud.google.com/dialogflow/docs/release-notes#December_04_2019)
- mTLSをwebhookの通信で使えるようになったよ。
- Cortanaエクスポータがコンソールから削除されたよ。

### GKE: [Dec 4, 2019](https://cloud.google.com/kubernetes-engine/docs/release-notes#december_4_2019)
- gVisorが有効な1.14.2-gke.10未満のバージョンのクラスタからのアップデートで問題が合ったのを直したよ。

### BigQueryML: [Dec 4, 2019](https://cloud.google.com/bigquery-ml/docs/release-notes#December_04_2019)
- k-meansの初期化でKMEANS++が使えるようになったよ。
  - RANDOMよりも良い。

### Datastore: [Nov 18, 2019](https://cloud.google.com/datastore/release-notes#November_18_2019) feed日付不正。
- datastoreのデータをエクスポート、インポートできるmanaged export and import機能がコンソールから使えるようになったよ。

### App Engine: [Nov 7, 2019](https://cloud.google.com/appengine/docs/standard/java/release-notes#november_7_2019)
- Java SDkが1.9.77に上がったよ。
- Jakarta Jasper JSPコンパイラが9.0.24になったよ。

### Stackdriver: [Dec 4, 2019](https://cloud.google.com/stackdriver/docs/release-notes#December_04_2019)
- monitoringがGCPコンソールに統合されたよ(ベータ)
- 今までの画面とGCPコンソールどっちからでも設定を見たり変更が可能。
- みてみようと思ったら、ベータのオファーはランダムに送られていて自分は見れませんでした。。

### App Engine: [Oct 30, 2019](https://cloud.google.com/appengine/docs/standard/python/release-notes#october_30_2019)
- Python SDKが1.9.87に上がったよ。(feed日付ひどい。。)


### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
removeEventListenerで登録解除出来ない

`removeEventListener` で登録解除したはずのコールバック関数が呼ばれてしまう事象が発生しました。
以下のようなコードとなります。

```javascript
function clickedCallback() {
    console.log('click event called.');
}

// コールバック関数登録時
document.addEventListener('click', clickedCallback, true);
// 登録解除
document.removeEventListener('click', clickedCallback);
```

登録時に第3引数の `useCapture` に `true` を設定した場合、解除時にも設定する必要があります。
以下のように指定することで無事解除することが出来ました。
第3引数のデフォルト値は `false` のようです。バブリングフェーズのコールバック関数が解除されていたようです。

```javascript
// 登録解除
document.removeEventListener('click', clickedCallback, true);
```

## 参考

* [MDN web docs](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/removeEventListener)
* [DOMイベントのキャプチャ/バブリングを整理する 〜 JSおくのほそ道 #017](https://qiita.com/hosomichi/items/49500fea5fdf43f59c58)
フロントエンドマスターへの道 その1 React Hooksを使ったQiitaの一覧、検索アプリ

- [2020年のフロントエンドマスターになりたければこの9プロジェクトを作れ](https://qiita.com/rana_kualu/items/915345b8f3f870cfe2aa)

せっかくなので作ってみようと思う。今回は 1 の Build a movie search app using React (with hooks) を作る。ただそのままだとただのコピペになってしまうので、今回取得するのは movie の取得ではなく Qiita の記事一覧にします。

どのフレームワークも何年か前にはさわっていたけど、最新の情報はなんとなく見たことある程度の知識しかありませんので詳しい解説をするものではありませんのでご注意ください。誤った理解のご指摘などがあれば大変助かります！

完成品はこちら（キャプチャの左はじがすこし切れた……）

![Screenshot from 2019-12-05 08-20-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17669/2a524772-f4a7-8542-336a-2ecd1f457fee.png)

- https://github.com/hbsnow-sandbox/react-hooks-example

CSS は基本的には今後も雑にしか作らずに、あまり本質的ではない Lint とかフォーマットの設定とかはデフォルトで入っていないものについては何もしない予定。

## install

参考サイトのように `npx create-react-app hooked` でインストールしてもいいんだろうけど、大体の人は TS で書きたいと思うので、インストール時には `npx create-react-app hooked --typescript` としなければいけません。自分は普通に忘れたので今回は普通の JS で書きました。

## hook

- https://ja.reactjs.org/docs/hooks-effect.html

`useEffect` と `useState` と `useCallback` というのは関数名だけは知っていた。

useEffect については

> React のライフサイクルに馴染みがある場合は、useEffect フックを componentDidMount と componentDidUpdate と componentWillUnmount がまとまったものだと考えることができます。

昔の知識のおかげか上記解説のヒントにあったこの説明が一番分かりやすくて、こういうある特定のタイミングで実行したい処理があった場合に

- https://ja.reactjs.org/docs/hooks-reference.html

上記の hook から探して適切なものを使う、ということなのだろうかと理解した。

```javascript
useEffect(() => {
  (async () => {
    const params = new URLSearchParams()
    params.set('page', 1)
    params.set('per_page', perPage)
    try {
      const response = await fetch(`https://qiita.com/api/v2/items?${params.toString()}`, {
        headers: {
          'Authorization': `Bearer ${API_KEY}`
        }
      })
      setArticles(await response.json())
    } catch (err) {
      setErrorMessage(err)
    }

    setLoading(false)
  })()
})
```

実際に `useEffect` を使ったコードはこうなった。async/await に書き換えたんだけど、戻りが `Promise<T>` になっているとまずいようで

```javascript
useEffect(async() => {
```

こうすることはできない。そのため即時実行関数を使うしかないのかなと思いこうしておいた。多少ググってもみたのですが、似たような感じのコードしかなかったのでこうするしかなさそう。

## dotenv

たぶん一番苦労した。

最初に答えを書いておくと、`create-react-app` には最初から dotenv が含まれているため、開発環境では `.env.development.local` に `REACT_APP_` から始まる値で設定しないといけない。

ぐぐれば結構でてくるし、当然ドキュメントにも書いてある。

- https://create-react-app.dev/docs/adding-custom-environment-variables/

`yarn add dotenv` とかやってしまってハマった。

## 感想

流石に1とあって簡単。後半きつそうなので不安しかない
SlackBotにGIFを検索して流す機能を実装したら治安が崩壊した話

Qiitaご利用の諸君はおそらく社内でのコミュニケーションにSlackを利用していることだろう。

+ 特に開発しなくても便利に使える便利なアプリが山程ある
+ GitHubやGitLabの更新をメッセージとして流したりIssueなどをその場で発行できる
+ Emoji無限(？)に増やせるたのしい！！！

これだけの利点があるのだから今更強烈な事情がない限りChatOps基盤にSlackを導入するのはほぼ必然と言い切ってもいいだろう。

そしてSlackではもっとコアな機能を持ったボットなどを開発する人たち向けにAPIを用意している。

今回はSlackのAPIの一つ、RealTimeMessageAPIを用いて開発していたSlackのBotにとある機能を実装したこと、リリースをした話をしようと思う。

# 新機能の概要

Botがinviteされているチャンネルで

> 特定の書式(今回は `put_gif ` )+検索文字列

と飛ばすとBotがそれを識別して適当なAPIからGIF画像のリンクを引っ張り、それを投げるというような機能を実装しようという話がチャンネル内で上がった。

丁度卒業研究が終わったところで暇だったので片手間で実装、そのままリリースすることにした。



# 実装の概略

### GIF検索に利用するAPI
今回は[tenor API](https://tenor.com/gifapi/)の提供するAPIを使う。
似たようなAPIに[GIPHY](https://developers.giphy.com/)があるが、使ってみるとあまり検索結果がよくなかった(設定が悪かった？)ので移行した。

### 利用する言語など
アプリケーション全体の実装をRuby(v2.6.5)で行った。
また、RTM APIとの相互通信のためにWebsocketを使うため、`faye/websocket`も利用させてもらっている。

### デプロイ
個人で持っているEC2インスタンスの中にdocker及びdocker-composeを使って置いた。

### GIFを拾ってくる部分の関数に関して
機能のコア部分だけ切り抜いてきた。
これをメソッドとして入れてやればGIFのリンクを返す関数ができる

```gif_get.rb
# frozen-string-literal: true

def gif_get(search_query)
  require 'http'
  # 環境変数は`docker-compose.yml`経由で`.env`を参照している
  tenor_api_key = ENV['TENOR_API_KEY']
  response = JSON.parse(HTTP.get('https://api.tenor.com/v1/search',
                                 params: { key: tenor_api_key,
                                           q: search_query,
                                           limit: 50 }))
  
  # 検索結果が0の場合は'SearchCount: 0`とだけ返して、
  # それ意外の場合は `Array#sample` でランダム抽出してURLを返す
  if response['results'].empty?
    'SearchCount: 0'
  else
    response['results'].sample['media'][0]['gif']['url']
  end
end


```

# 実際の成果物
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320738/35b07cfb-ebbe-2ec8-0555-c8f840f9d8fd.gif)

ローカルでコンテナを展開しているので少し応答が遅れてしまっているが、本番のEC2上においているコンテナは1秒以内で応答を返してくれるので常用可能な機能になっている。

-------

ここからが本題

# で、弊部のワークスペースに入れた結果
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320738/0ef779ba-44b3-a64e-6efd-bd915854565c.png)
なんだよこれ
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320738/d93e2277-fd2e-5ca0-e66b-1663fcef59c4.png)
TAGは関係ねえぞ
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320738/1dcd8ac6-8dae-ee43-ca6c-1d860d8990d0.png)
**THE 世紀末**と言わんばかりに遊ばれてしまった。事実今日だけで300くらいはメッセージの送受信があったように思える

# この機能を一般的なグループが入れて良いものか
結論から言うと進捗阻害にしかならないのでやめておいたほうがいい(あたりまえ)

今回は非公認のサークル組織であるためにこんなもんがまかり通っているが、汎用性はともかくとして実はこれ以外に **色々モラル的にアレなやつまで出てきてしまった** ことがあった。

他の方々などはやるのであればAPIアクセス時のリクエストパラメータに `contentfilter` というキー項目があったのでそちらを `meddium` なり `high` なりに指定してフィルタリングをかけたほうが良い。

逆にSlackにセンシティブなもんが出したい！みたいな人は `off` でもいいんじゃないだろうか。覗き見られたら死亡だけど。


# 最後に
開発しているSlackBotはソースコードをGitHubにて公開しているのでSlackを面白い感じにしたいサークルなどがあれば触っていただければ、と思います
[nkc-ug/NKCUG_Slack_Bot](https://github.com/nkc-ug/NKCUG_Slack_Bot)

PRや新機能導入のIssueなどは弊部部員以外の方も歓迎します。
ただし**導入して進捗が落ちた**とかの文句は受けないぞ。