OmniAICreator/Qiita-1.07M huggingface dataset:
WSL2に移行して困っている話（未解決）

## 背景

## 背景

以前にWSL2へ移行したときの記録としてこんな記事を書いた．
[WSL2に切り替えたらhomeディレクトリで難儀した](https://qiita.com/ten_takano/items/88885ead09b9edaed527)

その後しばらく使ってみたわけだが，そうしたらhomeディレクトリでは難儀しなくなったのだが，今度は代わりにVSCodeとの相互運用で難儀することになってしまった．現状良い解決策がないので，どうしたものかなぁと思いながら記事を書いている．

## 本題

WSL2にすると，バックグラウンドでLinuxの仮想環境が立ち上がり，ホストマシンであるWindowsとはネットワーク越しの通信を行うような形で相互接続を確立しているというのは前の記事で触れたとおりだ．それ自体に問題はないのだが，ことVSCodeと相互利用をするとなると話が変わってくる．
念のためにWindows配下に移動させて同じプロジェクトファイルで検証してみたが，問題無く同じWindowで開かれたので，問題はネットワークドライブのみで起きることは間違いない．

### ターミナルからコードを開くと別Windowが開かれる問題

VSCode使いな開発者諸兄はおそらく普段からVSCode付属のターミナルを使っていることだろう．そして，デバッグではそのターミナルで表示されたエラーコードをCtrl+クリックで開いていることだと思う．（そうであってくれ）
Ctrl+クリックは地味に便利で，どのコードのどの部分か読まなくても問題の箇所へ飛ばしてくれる．慣れてしまうと自分でその箇所を開くのが面倒で仕方ない．しかし，VSCodeのターミナルの仕様（？）としてネットワークドライブにあるファイルを開く場合には別Windowで開くという挙動をするのだ．デバッグをするときにはコードの修正とターミナルでの実行を何度も反復することになるため，そのたびに新しいWindowがガンガン開いてしまうことになる．これはとてもじゃないが耐えられない．

### リポジトリの状態が自動更新されない

今日日gitを使っていないweb開発者はそうそういないんじゃないかと個人的には思っているぐらい，僕はgitに依存していて，VSCodeもデフォルトでgitの機能が盛り込まれている．しかし，リポジトリの状態がVSCodeを開いたときのみしか読み込まれないという問題が発生する．
例えば，VSCodeの左下に表示されるアクティブブランチ．これはブランチを切り替えても追従してくれず，毎回飽きもせず僕を攪乱しようとしている．他にも，左側に表示されるエクスプローラも同じような問題が起きる．どのファイルを編集したか，どのファイルがコンフリクトを起こしているかなどなど，記号の意味を理解すればかなり有力な表示にも関わらず，こちらも一切アップデートされない．何なら手動で更新ボタンを押しても反応しない．ファイルの削除や追加に関しては手動更新で反応するのだが・・・

## 現状で取れる解決策

一応3つほど解決策を考えてはいるのだが，どれも欠点がデカすぎて，まだストレスためながらWSL2で使う方が良いのでは無いかという結論に至っている．

1. **WSL2からWSLに戻す**
  まだWSL2に変えるには早すぎたんだ・・・
  でもこの方法だと，dockerをWSLから良い感じに使いたいという要求には目を瞑ることになってしまうので，開発全体で掛かるコストとしてはバカにならないのでやりたくない．
<br>
2. **速度の低下に目を瞑ってWindows配下にプロジェクトファイルを置く**
  これについては全てのコマンドが遅くなるので，果たして現実的な方法と呼べるのだろうか・・・？これをやるぐらいならPowerShellをbash風に魔改造して使う方がまだ現実的な気がしている．
<br>
3. **プロジェクトファイルをWindows配下とLinux配下で分身させる**
  プロジェクトファイルをWindows配下とLinux配下で分身させて，何かをトリガーにしてコピーをするという方法も考えられる．無駄にこれのための設定が必要だし，そもそもVSCodeのターミナルからCtrl+クリックでソースに飛べないという問題が解決していない・・・

なんとかなりませんかね？Microsoftさん
Rasberry Pi OS (Raspbian)のインストール

Rasberry Pi OS(旧raspbian)のインストールが最近Raspberry Pi Imagerからできるようになった。
https://www.raspberrypi.org/downloads/ からOSにあったものをダウンロードしてインストールすれば、すぐにRaspberry Pi OSがインストールできる。
![RasPi Imager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502095/ff322745-22e3-4b60-4486-ef1b447bb714.png)
書き込み中のRaspberry Pi Imager
お手軽だが、OSイメージのダウンロードと並行して行われているのか書き込みが非常に遅い。初めてRasPiを使う人には便利だろうけど、待ち時間が遅いのが玉に瑕。
![RasPi Imager writing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502095/a5eb116f-9bcf-41d2-68fd-93617e27d572.png)

OSイメージを一度だけ書き込むのであればそこまで気にしないが、何度も書き直す人は別のツールのほうがいいだろう。
WindowsならWin32 Disk Imager[https://sourceforge.net/projects/win32diskimager/]

書き込みが終われば、SDカードが自動取り出しさできる状態になるのでPCに刺しなおして、fat32のbootパーティションに拡張子なしでsshファイルを作成しておく。
LANケーブルを指して起動したのち、sshでアクセスしユーザー作成をしてpiユーザーを無効化しておくこと。外部に公開せずに一時的な試用であればそこまでする必要はないと思うが一応乗っ取り防止のために。





Raspberry Pi OS Imager
メリット
・書き込みが楽
・書き込み後にSDカードサイズに合わせてパーティションを拡張してくれる
デメリット
・ダウンロードと書き込みが遅い。

Windows + win32Imagewriter
Mac + ddコマンド
Linux + ddコマンド
メリット
・書き込みが上記のものより早い。
デメリット
・書き込み後にパーティションの拡張を自分でする必要がある。(Linuxではgpartedですぐに拡張可能。)

気が向けばそれぞれの速度比較をします。
actix-webをAzure App Serviceにデプロイする


カスタム Linux コンテナー (Web App for Containers)使います。

## 準備

###acr作成

```
az acr create -n レジストリ名 -g リソースグループ名 --sku basic
```

actix-webは
https://github.com/actix/examples/tree/master/docker_sample
からdockerのサンプルを拝借します。

### acrにpush

```
acr build --registry レジストリ名 --image actixweb-sample:v1.0 . 
```

App Service作成時にエラーになるので
ポータルで管理者ユーザーを有効にしました。

## App Service作成

ポータルからやってみます。
LinuxでDockerコンテナーを選択

![2020-09-02_22h51_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41243/c097dac7-b620-0362-8598-579b75d515c3.png)


レジストリとイメージを指定して作成

![2020-09-03_00h35_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41243/dd247df4-aaf3-a747-f85f-9379094f7060.png)

サンプルに合わせて環境変数WEBSITES_PORT 5000を追加しておきます。
![2020-09-03_00h38_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41243/b6370e7a-1363-de94-bd73-10c63d75f975.png)

## サイトにアクセス

![2020-09-03_00h47_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41243/9cff7cbb-0323-2bc9-6396-90f73dbf04b6.png)

動きました。

もちろん　各メトリックやログ等のApp Serviceの機能を使えます。
サクッと公開できて便利です。


## 参考

https://docs.microsoft.com/ja-jp/azure/app-service/tutorial-custom-container?pivots=container-linux
ServiceNowの便利コマンド

#概要
ServiceNowにはURLから直接実行するコマンドやアプリケーションナビゲータから実行できるコマンドがある。本記事はそれらをまとめた。

#URL
Webブラウザから直接URLを入力するを開くページ
##システム情報（利用しているServiceNowバージョンやメモリ容量など）

```
https://<インスタンス名>.service-now.com/stats.do
```
このページやアプリケーションナビゲータから「システム診断」＞「統計」＞「統計」で表示されるページと同じです。
##ログインページ
ログインページを表示します。ログイン中にログインページを表示して言語を変えてWebブラウザから２回戻ると表示していたページの言語を変えて表示することができます。

```
https://<インスタンス名>.service-now.com/login.do
```

##Flow Designerを開く
Flow Designerを開くには「$flow-designer.do」を追加します。

```
https://<インスタンス名>.service-now.com/$flow-designer.do
```
##PDFで出力

```
https://<インスタンス名>.service-now.com/＜テーブル名＞_list.do?PDF
```

例：

```
https://<インスタンス名>.service-now.com/incident_list.do?PDF
```

##CSVで出力

```
https://<インスタンス名>.service-now.com/＜テーブル名＞.do?CSV
```

##ホームページ
左上のロゴをクリックするとホームページに移動できるのでURLを入力する必要はありませんが、URLにnavpage.doを追加するとホームページに移動します。

```
https://<インスタンス名>.service-now.com/navpage.do
```
#アプリケーションナビゲータ
ServiceNowの言語を日本語にしている場合は、アプリケーションナビゲータからアプリケーションを探す場合は日本語名で検索します。しかし、英語サイトでは日本語アプリケーション名は使われていないでの見つけるのに時間が掛かります。また英語ではTableとTablesとで分かれていますが、日本語では両方とも「テーブル」になり、検索して結果から探すのにも時間が掛かります。.listや.formを使うと英語名で一覧やフォームを開くことができます。
##テーブル一覧の表示
テーブル名が分かる場合は次のようにして一覧を表示することができます。

```
<テーブル名>.list
例1：インシデント一覧
incident.list
例2：要求アイテム一覧
sc_req_item.list
例3：ログ一覧
syslog.list
```

一覧を新しいWebブラウザのタブで表示する場合はテーブル名に大文字.LISTを追加します。

```
<テーブル名>.LIST
例：ノレッジ一覧をWebブラウザの新しいタブで表示する
kb_knowledge.LIST
```
##入力フォームの表示
新しい入力フォームを表示するには<テーブル名>.formを入力します。
```
<テーブル名>.form
例：変更タスクフォームの表示

```
change_task.form
```
フォームをWebブラウザの新しいタブで表示する場合はテーブル名に大文字.FORMを追加します。

```
<テーブル名>.FORM
例：問題フォーム
problem.FORM
```

##システムプロパティの変更
アプリケーションナビゲータから開く「システムプロパティ」からできないシステム設定もあります。そのような場合は直接システム設定ページを開きます。

```
sys_properties.list
```

##キャッシュの初期化
ServiceNowのキャッシュを初期化します。バージョンアップした後にページが正しく表示されていない場合などに使います。

```
cache.do
```
論文まとめ：Towards Real-Time Multi-Object Tracking

# はじめに
ECCV 2020 から以下の論文
[1] Z. Wang, et. al. "Towards Real-Time Multi-Object Tracking". ECCV 2020.
のまとめ

- 略称
JDEモデル（Jointly learns the Detector and Embedding model）

- arXiv:
https://arxiv.org/abs/1909.12605

- github:
https://github.com/Zhongdao/Towards-Realtime-MOT

例えばMOT16 dataset だと割とSOTAに近い結果。
https://paperswithcode.com/sota/multi-object-tracking-on-mot16

<font color="red">一部書きかけ</font>

# 概要

1. 同時に多数の人をトラッキングする（multi-object tracking）モデル
2. detectionと特徴量抽出を同時に行う（1-shot）ことにより推論速度を上げた

以下の図では上２つが既存の2-shot系モデル。下の本手法JDEはbounding boxと特徴量を同時に出す。

![JDE_img00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/072152a7-1684-6cae-dbe9-01d3bfe5c955.png)

この論文の位置付けを考えるに、個人的には以下のような時代の流れ

１）2-shot系（detectionしてから、そこの特徴量を抽出する）

２）1-shot系のアンカーベース・・・本論文

３）1-shot系のアンカー無し・・・FairMOTモデル等

４）次のフレームもNNから予測・・・CenterTrack等

の中の２）あたりかなと。

# ネットワークのアーキテクチャ
ネットワークのアーキテクチャは以下。

![JDE_img01_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/226754ee-d327-5d34-5d1c-9e92b679cf30.png)
[1] Figure 2より


FPN系。

出力は以下の３種類

1. 物体か物体でないかの識別
2. bounding boxのサイズ
3. 物体のembedding

![JDE_img01_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/510cb1b6-e9ca-9e19-a6e6-240f8dc67752.png)
[1] Figure 2より

# Loss
## 1. 物体か物体でないかの識別に関する loss
識別問題なので交差エントロピー

## 2. bounding boxのサイズに関する loss
detection でよく用いられる smooth-L1 loss

## 3. 物体のembeddingに関する loss
まずアンカーとなる物体の特徴量を $f^{\top}$ 、それに対して異なるframeの同じ物体の特徴量を $f^{+}$ 、異なる人の特徴量を $f^{-}$ とする。

ベーシックなtriplet lossから考えると、

```math
\mathcal{L}_{triplet} = \max (0, f^{\top}f^{-} - f^{\top}f^{+})
```

だが、tracking datasetには同じ人のシーンが少ないので、できるだけ利用するため

```math
\mathcal{L}_{triplet} = \sum_i \max (0, f^{\top}f^{-}_i - f^{\top}f^{+})
```

とする。$f^{+}$ はミニバッチ内で最も難しい同一物体のサンプルで固定する。

だが、これだと収束が不安定かつ遅いので、以下の smooth upper bound of triplet lossにする。

```math
L_{upper} = \log(1+ \sum_i \exp (f^{\top} f_i^{-} - f^{\top} f^{+} ))
```

ここで $f^{+}$ は固定なので変形して、

```math
\begin{eqnarray}
L_{upper} &=& \log(1+ \exp(- f^{\top} f^{+} ) \sum_i \exp (f^{\top} f_i^{-}) ) \\
&=& \log \left( 1+ \frac{\sum_i \exp (f^{\top} f_i^{-})}{  \exp( f^{\top} f^{+} )} \right) \\
&=& \log \left( \frac{\exp(f^{\top} f^{+} ) + \sum_i \exp (f^{\top} f_i^{-})}{  \exp(f^{\top} f^{+} )} \right) \\
&=& - \log \left( \frac{  \exp(f^{\top} f^{+} )}{\exp(f^{\top} f^{+} ) + \sum_i \exp (f^{\top} f_i^{-})} \right) \\
\end{eqnarray}
```
と交差エントロピーっぽくなった。なので、最終的にはtriplet loss、smooth upper bound of triplet loss、交差エントロピーの３つを試している。

## 4. lossの掛け率を自動補正
<font color="red">書きかけ</font>

# マッチング
いわゆるトラッキングの第３行程、第４行程に関しては、Kalman Fileter、および Hangalian algorithmを用いる。

# 実験と結果

## 1. 他のモデルとの精度比較

他のモデルとMOT-15 datasetでMOTAやFPS等を比較した図は以下。

![JDE_img07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/c01fb8ed-f1d9-8d07-7419-93a1b1bae552.png)

2-shot系と比べて比肩しうる精度の上、速度はかなり優っている。

## 2. ablation study
<font color="red">書きかけ</font>
パスに「 ../ 」を書くとき・書かないとき

<h2>自己紹介</h2>
2020年8月末からプログラミングの学習を始めた初心者です。
<strong>黒澤さん（@kurosawa_kuro）のウェビナー「会津ワロ法則」</strong>への参加をきっかけに、Udemyを使った動画学習に取り組んでいます。

現在（2020年9月3日）は、HTMLとCSSの基礎について、学習が一巡した段階です。
より理解を定着させるため、いま一度Udemyの講座を見返しながら復習しています。

<h2>この記事の目的</h2>
黒澤さんが提唱されていた<strong>「Qiitaへのアウトプット」</strong>を実践するのが、この記事の目的です。
学習を始めたての初心者なので、有益な記事を書けるかは甚だ心もとないのですが、自分なりに気づいたことを記事にしていこうと思います。

今回は、<strong>HTMLやCSS上でパスを記述する際に、私がつまづいてしまったポイント</strong>について書いていきます。

<h2>パスを記述する際の「../」の有無について</h2>
<h3>「images/〇〇.png」のように書くケース</h3>
動画学習の中で、imgタグのハンズオンに取り組んでいた時のことです。
フォルダ構成は、次のようになっていました。

```
     親フォルダ ―――――― imagesフォルダ ―――――― 〇〇.png
                ┃                    ┃
                ┃                    ―――― xx.png
                ┃
                ―――― cssフォルダ ―――― base.css
                ┃
                ┃
                ―――― index.html
```
ハンズオンの課題は「imagesフォルダ内の〇〇.pngを、index.html上に挿入する」というものです。
    講師の先生が教えてくれた模範解答は、以下の通りでした。

```html:index.html
    <img src="images/〇〇.png" alt="〇〇の画像">
```
これを見た私は、
    （なるほど、画像の場所をフォルダ名から指定してあげるんだな）
    と、すんなりと納得することができました。

<h3>「../images/xx.png」のように書くケース</h3>
それから学習は、CSSに進みます。
 フォルダ構成は、先ほどと同じです。

```
     親フォルダ ――――― imagesフォルダ ―――――― 〇〇.png
                ┃                   ┃
                ┃                   ―――― xx.png
                ┃
                ―――― cssフォルダ ――― base.css
                ┃
                ┃
                ―――― index.html
```
今度のハンズオンは「base.cssを使って、imageフォルダ内のXX.pngを、index.htmlのbody部分の背景画像にする」というものでした。
こちらの模範解答（CSS）は、以下の通りです。


```css:base.css
    body {
        background-image: url(../images/xx.png);
    }
```

今度は少し違和感をおぼえました。
（前にimgタグで画像を挿入したときは、<strong>画像の場所を指定するのに「../」なんて使わなかったのに</strong>）

ただ、その場ではあまり深く考えずに、
    （HTMLとCSSではパスの書き方が違うのかなー）
    と、軽くスルーしてしまいました。

<h3>後で復習してみて分かったこと</h3>

後で復習してみると、「HTMLとCSSで書き方が違うのかな」というのが、大変な勘違いだということが分かりました（汗）
（復習の際には、<a href="https://webliker.info/78726/">【初心者向け】絶対パスと相対パスの違いをイラストを使って解説！</a>という記事を参照しました）

重要なのは、
    <strong>「コードを記述するファイルが、imagesフォルダと同じ階層にあるかどうか」</strong>
    だったんですね。。。

<dl>
最初のケースでは、
<dd>コードを記述するindex.htmlから見て、<strong>imagesフォルダは同じ階層。</strong>なので、<strong>「images」</strong>とだけ書けばよい。</dd><br>

一方、次のケースでは、<dd>コードを記述するbase.cssから見て、<strong>imagesフォルダは一つ上の階層。</strong>    こうした場合は、<strong>「../images」</strong>と書く必要がある。</dd>
</dl>

なるほど、スッキリしました！
<h3>復習は大事！</h3>

なお、よくよくUdemyの講座を見返すと、先生はちゃんと

```
「 ../ 」とは、一つ上のフォルダということを示します
```
とおっしゃっていました（汗）

<strong>復習は大事だなー</strong>、と痛感しました。。。

最後までお読みいただき、ありがとうございました！
2日後の電力使用量を予測してCSVで公開してみる

# はじめに

色々なところで機械学習を用いた電力使用量の予測方法についてレクチャーをしてきましたが、実際に予測した値はそんなに当ってないんじゃない？とか所詮はPoCでしょ？とか、様々なご意見を頂きましたので、実際に予測した値をCSVで公開して、その実力のほどを検証してもらおうかなと...

# 予測方法

過去に複数の方法で予測する例をQiitaの記事として公開しているので、ご覧下さい。

[電力使用量予測 with Keras (TensorFlow)](https://qiita.com/mix_dvd/items/f9e25147006ddef081c3)

# 予測対象

中国電力エリアにおける2日後の電力使用量を予測します。

# 予測結果の検証

2日後の予測結果をWebサイトにて公開し、中国電力さんの公開されている電力使用量の実績と比較できるようにしています。

https://blueomega.jp/20200811_power_prediction_challenge/yyyy-mm-dd_.csv
※ yyyy-mm-ddには予測対象の年月日が入ります。

2020年9月2日であれば、以下のURLとなります。
https://blueomega.jp/20200811_power_prediction_challenge/2020-09-02_.csv

以下のスクリプトをColaboratory上で実行すると比較ができます。

```py:
import datetime as dt
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score

# 中国電力エリアの前日までの実績データを取得
url = "https://www.energia.co.jp/nw/jukyuu/sys/juyo-2020.csv"
df_juyo = pd.read_csv(url, skiprows=2, encoding="Shift_JIS")
df_juyo.index = pd.to_datetime(df_juyo["DATE"] + " " + df_juyo["TIME"])

# 中国電力エリアの当日の実績データを取得
d = dt.datetime.now() + dt.timedelta(hours=9) - dt.timedelta(days=0)
url = "https://www.energia.co.jp/nw/jukyuu/sys/juyo_07_" + d.strftime("%Y%m%d") + ".csv"
df_tmp = pd.read_csv(url, skiprows=13, encoding="Shift_JIS",nrows=24)
df_tmp.index = pd.to_datetime(df_tmp.DATE + " " + df_tmp.TIME)

# 8月31日以降の予測データを取得
df = pd.DataFrame()
d = dt.datetime(2020,8,31)
while d < dt.datetime.now() + dt.timedelta(days=3):
  try:
    url = "https://blueomega.jp/20200811_power_prediction_challenge/" + d.strftime("%Y-%m-%d") + "_.csv"
    df = pd.concat([df, pd.read_csv(url)])
  except:
    print("No file.")
  d += dt.timedelta(days=1)

df.index = pd.to_datetime(df.pop("datetime"))

# 前日までの実績値を反映
df["act"] = df_juyo["実績(万kW)"]

# 当日の実績値を反映
for idx in df_tmp[df_tmp["当日実績(万kW)"] > 0].index:
  df.loc[idx, "act"] = df_tmp.loc[idx]["当日実績(万kW)"]

# 予測と実績を可視化
df_plot = df.copy()
df_plot = df_plot[["act", "y2"]]
df_plot.columns = ["act", "pred tuned"]

df_plot["2020-08-31":].plot(figsize=(15,5), ylim=(300,1200))
plt.show()

# 決定係数
df_scr = df[df.act > 0]
print("決定係数(R2 SCORE) : ", r2_score(df_scr.act, df_scr.y2))
```

9月3日 5時時点の実行結果です。
![Unknown-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/5fe7f6c4-6c05-8b71-665c-bef94632b04e.png)
決定係数(R2 SCORE) :  0.9494716417755021

予測値は毎日1:00と12:00に更新されますので、ご興味のある方はご覧下さい。
また、同じように予測するという力が業務に必要な方からのご連絡もお待ちしております。

## 追記

9月4日 6時時点の実行結果です。
![Unknown-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/9441c959-a31f-3f7f-0388-d11778007ad5.png)
決定係数(R2 SCORE) :  0.9454478929760703

ちょっと悪くなったかな...
[ネタバレ] ふくらPが9時間かけたことを僕がやったら何時間かかる？

# まずは，このYoutubeの動画を見てくれ．

[東大生100点は取り飽きたので人生最高得点を取る旅に出ます by QuizKnock](https://youtu.be/AISo8I4xYL4)

# 見てくれたところで，本題に

皆さんは，このチャンネルご存知でしたか？
チャンネル登録者数も140万を超え，メディアへの露出も多いので知っているひとも多いかと思います．
この動画自体は，2020年３月の動画とちょっと昔の動画になっています．

以下，動画のネタバレになってしまいます．

上記の動画で， ふくらPが最大の点数を取るために， ゲームを自作して，公開するところまでやってしまうのです．
実際に公開されているゲームが[こちら](https://play.google.com/store/apps/details?id=com.baton.Horwitz&hl=ja)
いくら頭脳派集団と言われているQuizKnockのメンバーであるふくらPさんとはいえ，
0から1週間でこんなことをやってしまうのに，
めちゃくちゃ笑わせてもらいました．
ふくらPが動画の中で，Googleや知り合いのエンジニアに聞きながら９時間かけてこのアプリを作ったと言ってました．
動画の中では，９時間”も”かけてという話の流れでしたが
正直何も知らない人がたったの9時間でアプリをリリースするところまで，
やってしまうのに，驚きを隠せません．

すごいすごいと見ていた，~~学会発表のスライド作成に追い込まれた~~僕はとあることを思いつきます．
普段Androidの開発やフロントエンドの開発をやったことが無いが，
情報系の大学生としてある程度かじっている僕が同じことをやったらどれくらいでできるんだろうと．．．

思い立ったら吉日，~~やりたくないことを目前に，~~やってみたいことを見つけてしまった僕は，
水を得た魚のように，いつの間にかカタカタしていました．


# さて，僕は何時間かけて，作ることができたでしょうか？
そうして作ったのがこちら，
https://github.com/kmdkuk/darwin_model_quiz
作ったものは，完全にパクリもいいところで，ふくらPのアイディアを反転させただけです．
Androidを直接書く経験はなかったですが，Flutterを少しだけ触ったことがあったのでFlutterで書きました．

git logがこんな感じ．
![スクリーンショット 2020-09-03 5.07.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129037/8e705b57-395b-174e-3f2a-a6a7dc7f4318.png)
最初のコミットは，`flutter create ~~~`のプロジェクト作成の時間
00時37分
実装完了したのが，次のコミット
03時09分
そして，公開の準備などして（このために勢いでGoogleに25ドルのお布施もしました．)
![スクリーンショット 2020-09-03 4.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129037/77af5519-e8be-8f6e-4c85-23a96928fbf8.png)
上記のアプリの審査待ちのところまで行けたのが，
04時34分

というわけで，
Q.ふくらPが９時間かけたことを僕がやったら何時間かかる？
A.3時間57分
でした．

PS. こんなパクリアプリが公開されるんですかね(~~あー嫌なことに対する現実逃避の能力怖い~~)

# GooglePlayStoreに公開されました．(9/7追記)

https://play.google.com/store/apps/details?id=com.kmdkuk.darwin_medal_quiz
~~厳密に，審査が終わって公開された時間がわかりませんが，
9/7 9時には，公開されていることが確認できました．~~
9/7 6:58に評価結果のメールが来ていました．
ということで申請からアプリの公開まで，
4日と2時間24分でした．
なにかの参考になれば幸いです．
"ゲーム開発者のための C++11～C++20, 将来の C++ の展望"によせて

# はじめに
ディするつもりはないですよ.
実際, すでに各社で自前のライブラリがあるのですよ.

私は, Androidが1.6の時代, NDKが発表された時代にSTLを捨てたので.

前提として, 世の中, 驚くべき〇〇が多いという事実を考慮しなければならない,
日本語どころかどの言葉も通じない, とんでもない人間が多いという事実.
言葉が通じない人間が, プログラミング言語が話せるはずもなく, 疲れからか黒塗りのハイエースに衝突.

# 項目
## std::clamp
IEEE 754特有のハックも考慮してくれるなら使用していきたい.

## 数学定数
新規のプロジェクトなら使えるけれど, `const_expr`なり`const static`で再定義してしまうと思うのだけれど, どうだろう? 結構ヤバい, 変えたらヤバい何かが起きて変えられないジレンマ.

objのフォーマット互換性がないため, Visual Studioのビルドツールを更新できないヤバいプロジェクト, ヤバすぎでしょ.

## std::string関係
信頼するとか無理でしょ, 歴史的に考えて. ASCIIこそ唯一のstringな人たちの仕様を, どうやって信じろと?

## 連想コンテナ
ああ, ゲームにあった連想配列を自前で造るのでいらないです.

## using enum
わかりにくくはならなそうなので, よさそう.

## コンテナの要素削除
ゲームにおいてはパフォーマンスより, ユーザエクスペリエンスこそ正義なので,
それについて問題にならないなら使いたい. ただし, 本当にまじ〇〇の人が存在しますし, 難しい.

C#だが, 本当にこれをプロダクトのコードに入れた人間がいる, 私は卒倒した.

```
foreach(var i in list){
    if(!i.valid()){
        list.Remove(i);
    }
}
```

## 変数未使用の警告を抑制
悪用されそうなので却下.
`__super` とかガチでいれてくるguyがいるので（本人はクールなプログラムをした気らしい）.

## ビット操作
countは移植性が保障されるなら使いたい.

## std::byte
このレベルのプログラムをする人は, 分かっている人なので有用だと思う.

## std::filesystem
エンジニア用のツール作成用ならあり. ASCII原理主義者の作ったライブラリなど誰が信じるのか.
名立たるC/C++の教科書がftellの扱いを間違えているのに, 信じられるのか.

## 構造体の初期化子
Cではすでにできていたような, 有用. 無理矢理けちをつけると, 例のD3D12_VIEWPORTは少し微妙, Vulkanをもってこようぜ, 吐き気がする.

## ラムダ式
C++ではパフォーマンスに影響は少ないので気にしない.
C#ではLINQと絡まって, ひと目でわからないコードを書く人が続出するのでヤバい. 私が理解できない馬鹿だからで収まればいいが, そんなコードをあろうことかUniteで発表するプロジェクトがある, しかも１年未満でサービス終了, そういうとこやぞ.

## 契約による設計
広まらないね, 広めたい.

## std::variant
個人的には使っても, 他人には使って欲しくないあれ, まさに共用体.

## std::string_view
まじで昨日, 毎フレームstd::stringをコピーしているコードを発見してしまったのよ, やべぇよ, やべぇよ.

## 文字列
もう無理, だめぽ.

## コルーチン
boost::contextベースで自作しているのでいらね.

## アロケータ
はげそう（もう, はげてるけど）. mimallocとか試しているのよ最近.
TypeScriptの型で遊ぶ時、再帰制限を無効化する

## 初めに
TypeScriptの型システムはチューリング完全なので何でも計算できます。
例えば繰り返し。

```ts
type Repeat<T, N extends number, R extends any[] = []> = R["length"] extends N
  ? R
  : Repeat<T, N, [T, ...R]>;

// type A = ["x", "x", "x", "x", "x", "x", "x", "x", "x", "x"]
type A = Repeat<"x", 10>;

```

わーい。ちょっと数増やすか…

```ts
// error TS2589: Type instantiation is excessively deep and possibly infinite.
type A = Repeat<"x", 100>;
```

あれ？(つらい)
再帰制限解除したいですね。しましょう。

## 注意
* 当然ですがプロダクトで使うことは想定していません、やめましょう。

## バージョンなど
* `typescript@4.1.0-dev.20200902`

行番号、コンパイラのコードはこのバージョンの物を引用しています。
`tsc --noEmit --lib esnext app.ts` でコンパイルしています。

## tsc.jsとtsserver.js
npmでTypeScriptをインストールすると `node_modules/typescript/lib/tsc.js` と `node_modules/typescript/lib/tsserver.js` というファイルが作成されます。これがコンパイラと言語サーバーの本体で、バンドラでまとめられたjsファイルです。今回はこれをいじることで再帰制限を無効化します。再帰制限のコードはどちらにも同じものが含まれているので同じ部分を同じように書き換えればいいです。

## 再帰制限のコードを調べて消す
`tsc.js` を `Type instantiation is excessively deep and possibly infinite` というエラーメッセージを元に調べると `Type_instantiation_is_excessively_deep_and_possibly_infinite` という変数が見つかります。この変数を使っているエラー報告は以下の2つです。

```ts
// tsc.js 42795行目
if (constraintDepth >= 50) {
    error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
    nonTerminating = true;
    return t.immediateBaseConstraint = noConstraintType;
}

// tsc.js 46210行目
if (instantiationDepth === 50 || instantiationCount >= 5000000) {
    error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
    return errorType;
}
```

`constraintDepth` はmapped typeとindex access typesを制約に使ったときに発生する無限再帰を防止するためのもののようなので今回は関係なさそうです。[Fix infinite constraints #26558](https://github.com/microsoft/TypeScript/pull/26558)。

`instantiationDepth` は型関数をインスタンス化する時の再帰の深さを制限するための物のようです。試しに `instantiationDepth === 10` に書き換えると `Repeat<"x", 6>` でエラーになります。

`instantiationCount` は深さではなくインスタンス化の回数を制限していますね。例えば上の `Repeat` を以下のように書き換えると `instantiationDepth` は変わりませんが `instantiationCount` は増えます。(`console.log` すれば分かります)

```ts
type Repeat<T, N extends number, R extends any[] = []> = R["length"] extends N
  ? R
  : Repeat<[T, T, T, T, T, T], N, [T, ...R]>;
```


これで再帰制限チェックコードが分かりました。消してしまいましょう。テキストファイルなのでsedで簡単に消せます。

```sh
$ sed -i '' 's/instantiationDepth === 50 || instantiationCount >= 5000000/false/' 'node_modules/typescript/lib/tsc.js'
$ sed -i '' 's/instantiationDepth === 50 || instantiationCount >= 5000000/false/' 'node_modules/typescript/lib/tsserver.js'
```

## 結果など
やったね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169698/4e279ed0-8394-9b21-79b6-af62b05cc7e8.png)

最近話題の[Template string types](https://github.com/microsoft/TypeScript/pull/40336)と組み合わせれば[既存のTSの型レベルbrainfuckインタプリタ](https://github.com/susisu/typefuck)にlexerとコードポイント変換処理を追加するだけでbrainfuckのhello world!も実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169698/513ccec9-4bb4-5090-9b33-99c0585f7a26.png)
おすすめ！関係データベース（RDB）のオープンデータリポジトリ

# 意外に少ないし、探すのが大変？RDBのオープンデータ
データ分析の学習やアルゴリズムの検証をする時に、オープンデータを良く用います。
例えば、データの種類によって、以下のようなものが挙げられます。
**テーブルデータ**
- [アイリスのデータセット](https://qiita.com/ao_log/items/fe9bd42fd249c2a7ee7a)
- [タイタニック号の生存者のデータセット](https://www.kaggle.com/c/titanic/data)

**画像データ**
- [CIFAR](https://www.cs.toronto.edu/~kriz/cifar.html)
- [coco](https://cocodataset.org/#home)

**自然言語**
- [Yelpレビュー](https://www.yelp.com/dataset)
- [青空文庫形態素解析データ集](http://aozora-word.hahasoha.net/index.html)

幅広くビジネスをとらえた時に、もっともメジャーに取り扱うことが多いのはやはりテーブル形式のデータでしょう。比較的にデータが整備されている大きい企業ではデータベースがあり、リレーショナルデータベース形式のデータが普段使われると思います。しかし、私自身最初はこのような形式のオープンデータを探すのに苦労しました。
この記事では、非常に便利なリレーショナルデータベース形式になっているオープンデータのリポジトリである[**RELATIONAL DATASET REPOSITORY**](https://relational.fit.cvut.cz/)をご紹介します。
このリポジトリを介して知ったのですが、データベースのエンジニアにとっては結構有名なデータセットもそこそこカバーされています。

# RELATIONAL DATASET REPOSITORYの特徴
リレーショナルデータベースのサンプルデータであれば、Microsoftが[AdventureWorks](https://docs.microsoft.com/ja-jp/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms)という小売り系のサンプルデータベースがあり、顧客情報、注文履歴、注文明細等と非常にリアルなもので、データベース設計時のお手本にする目的でも公開されているようです。
ですが、このデータを使おうとするならば、Microsoftの製品の[SQL Server Management Studio](https://docs.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15)を使うのが一般的で、別のデータセットになれば別のセットアップが必要になり非常に不便です。
同時に、データセットを探す側にとっては、データセットの検索や利用をする際に条件が統一されていないことがほとんどです。

このような不便を解消してくれたのが、RELATIONAL DATASET REPOSITORYで、以下のような特徴があります。

- エンタープライズのデータベースと同様リレーショナルデータベース（RDB）形式になっている
- 機械学習の予測タスクに即したターゲットが定義できるデータセットになっている
- データサイズ、テーブル数、データの関連分野、予測タスクの種類、データモデル等豊富なメタ情報を用いて、ほしいデータセットを探すことができる
- 異なる出展元が作成しているデータベースのデータセットをMySQL Workbenchですべて操作できるようなっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328424/9d1eb8dd-664b-32f0-e942-6445b92439d9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328424/bc5d4feb-6044-fb84-abea-a29d33e421be.png)



# 使用法
実際の使用法は非常に簡単で、
1. 検索条件でデータを絞り込む
2. MySQL Workbenchをインストールし、サイト内の各データセットの詳細ページにある指示に従ってデータベースに接続する
上記2ステップを踏めば、MySQL workbenchで直接データベースをたたくことができ、CSVやSQLダンプでデータダウンロードが可能です。

英語になっているため、日本ではあまり知られてないようですが、ぜひおすすめしたいオープンデータセットです。みなさんもぜひ使ってみて頂けたらと思います。

#参考情報
- [The CTU Prague Relational Learning Repository](https://arxiv.org/abs/1511.03086)
MAMP環境のrailsアプリをherokuへデプロイしてみた

#MAMP環境のrailsアプリをherokuへデプロイしてみた
そもそも、MAMP環境でrails使ってる人がまれすぎて、Qiitaに全然記述がなかったので、残してみました。

##開発環境
・Rails 6.0.3.2
・MAMP(mysql)
・Heroku

##参考にしたサイト
タイトル：herokuデプロイをmysqlでやってみた（私命名）
https://qiita.com/murakami-mm/items/9587e21fc0ed57c803d0
タイトル：herokuデプロイしたけど、bootstrapが適応されてない！（私命名）
https://qiita.com/taKassi/items/56172d140d7208230e32

##作業をした流れ
herokuデプロイをmysqlでやってみたを基に作業をすすめる

##詰まったところ1
→ローカル環境と同じとこ入力してた
開発環境と本番環境のDBの区別がついてなくて、ローカル環境の情報をそのまま入力していた。
「heroku config」をターミナルに入力して、それに従って、情報を入力しよう。

##詰まったところ2
→ポートを入力してなかった
database.ymlに、本番環境用の環境情報を入力する必要がある。
※ちなみに、この要項は、herokuデプロイをmysqlでやってみたには載ってないので要チェックだ！！！
そこへ、ポート情報を載っける必要がある！！デフォルトのポート番号は8889だが、Herokuのmysqlは3306なので、ちゃんと情報をオーバーライドする必要がある。

##詰まったところ3
→マイグレーションファイルで外部制約キーをリネームしてた
開発環境では、外部制約キーに設定しているカラムのリネームは可能だが、Heroku環境のmysqlでは、それが不可能らしい。なので、外部制約キーの設定をしたマイグレーションファイルを消し（実務的にはあまりよろしくないが）クリエイトしたテーブルを正す！！！！

##詰まったところ4
→キャッシュのせい？で、既にテーブルあるよ！的なエラーから進めなくなった
これはもう、アプリケーションとデータベースを作り直すしかないです。面倒ですが、デプロイできないよりまし。

##詰まったところ5
→bootstrapが適応されない
この時点で「デプロイできたー！！！」と喜んでいたのですが、bootstrapが適応されてない。
同じ現象に至った人は、こちらを参考ください。
https://qiita.com/taKassi/items/56172d140d7208230e32

##詰まったところ6
→bootstrap以外のCSSが適応されない
現在解析中

###終了（ここまで10時間…）

#結論
開発環境がMAMPでも、全然デプロイできる。
Ruby on Railsの新しいプロジェクトでSQLite3からPostgreSQLに変更する


Ruby on Railsで作った新しいプロジェクトのデータベースを変更する手順のまとめです。

# 環境
- mac OS Catalina 10.15.6
- Ruby 2.6.3
- Rails 6.0.3.2

# SQLiteからPostgreSQL変更する理由
Ruby on Railsのデータベースの標準は<b>SQLite3</b>ですが、<b>HerokuにデプロイするときにSQLite3だとエラーになります。</b>
`rails new`した時点でPostgreSQLに変更しておくと、あとでデータ移行する手間が省けます。

# Postgresを使う準備
## macにHomebrewをインストールする
`Homebrew`のインストールに必要となる`xcode`をまずインスロールします。

### xcodeをインストールする
```
xcode-select --install
```

### Homebrewをインストールする
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

公式ページはこちら：[Homebrew](https://brew.sh/index_ja.html)

## macにbrew経由でpostgresをインストールする
`postgresql`を指定することで最新の安定版をダウンロードできます。

```
brew install postgresql
```

## Postgresの初期設定
`.bash_profile`を更新する

```
ECHO 'export PGDATA=/usr/local/var/postgres'　>> .bash_profile
```

`.bash_profile`を再読み込み

```
source ~/.bash_profile
```

## ユーザーを作成する
データベースを管理するためのユーザーを作ります。

```
 createuser <username>
```


# RailsプロジェクトでPostgresを使う
## GemfileでSQLite3になっている部分をPostgreSQLに変える
Gemfileを更新して、SQLite3の記載をPostgreSQLに変更します。

変更前

```code:Gemfile.rb
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
```

変更後

```code:Gemfile.rb
# Use Postgres as the database for Active Record
gem 'pg'
```

bundle installでgemをinstallします。

```
bundle install
```

## database.ymlを編集してデータベースの設定をする
```code:app/config/database.yml
 default: &default
   adapter: postgresql
   encoding: unicode
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
   timeout: 5000

 development:
   <<: *default
   database: myapp_dev # 任意のデータベース名

 test:
   <<: *default
   database: myapp_sandbox # 任意のデータベース名

 production:
   <<: *default
   database: myapp_production # 任意のデータベース名
   username: <username> # 任意のユーザー名
   password: request.env['DB_PASSWORD'] # 任意のパスワード
   adapter: postgresql
   encoding: unicode
   pool:  <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
```
## .envにパスワードを書く
`database.yml`にそのままパスワードを書いてしまうと、GitHubにPublicで更新したときにパスワードが丸見えになってしまいます。
環境変数を管理するための`.env`ファイルを作りましょう。
`.env`ファイルは`.gitignore`に追加してGitHubにアップロードされるのを防ぎましょう。

```code:.env
DB_PASSWORD = '<password>'
```

```code:.gitignore
.env
```

## データベースをつくる
```
bundle exec rails db:create
```

下記のようなメッセージが出ればPostgreSQLでデータベースの作成完了です。

```
Created database 'myapp_dev'
Created database 'myapp_sandbox'
```
RedHat Enterprise Linux 7でRHSCL MariaDB 10.3を使う

# 概要
RHEL7でRedHat Software Collections (RHSCL)を使ってMariaDB 10.3をインストールする。今回はMariaDB 5.5と同居させる。

# インストール手順

```
# yum install rh-mariadb103 rh-mariadb103-mariadb-server rh-mariadb103-mariadb-backup 
```

下記サイトを参考に、MariaDB 5.6以降でのopen_files_limit, table_open_cacheの値に対応するようにする。
https://www.denet.ad.jp/technology/2017/10/centos7mysql56.html

```
# mkdir /etc/systemd/system/rh-mariadb103-mariadb.service.d
# vi /etc/systemd/system/rh-mariadb103-mariadb.service.d/limits.conf
[Service]
LimitNOFILE=10000

# systemctl daemon-reload
```

そのままMariaDB 10.3を起動すると、Listenしているポート番号やUnixソケットが衝突するため、設定を変える。

```diff:/etc/opt/rh/rh-mariadb103/my.cnf.d/mariadb-server.cnf
    [mysqld]
+   port = 3307
-   socket=/var/lib/mysql/mysql.sock
+   socket=/var/opt/rh/rh-mariadb103/lib/mysql/mysql.sock
```

MariaDB 10.3のサービスを起動。

```
# systemctl start rh-mariadb103-mariadb
# systemctl enable rh-mariadb103-mariadb
```

動作確認。
ここで、``-h 127.0.0.1``オプションなどが無いと、mysql.cnfの設定を見てUnixソケットに接続しに行こうとするため、MariaDB 5.5に接続される（ポート指定は無視される）。

```
# /opt/rh/rh-mariadb103/root/bin/mysql --version
/opt/rh/rh-mariadb103/root/bin/mysql  Ver 15.1 Distrib 10.3.13-MariaDB, for Linux (x86_64) using  EditLine wrapper

# /opt/rh/rh-mariadb103/root/bin/mysql -u root -h 127.0.0.1 -P 3307
または
# /opt/rh/rh-mariadb103/root/bin/mysql -u root -S /var/opt/rh/rh-mariadb103/lib/mysql/mysql.sock
```

# 備考
## 複数バージョンのMariaDBを共存させない場合
他にMariaDBがインストールされていない場合は、syspathsをインストールすることで通常のMariaDBのように扱える。他のMariaDBがインストールされている場合はyumの依存関係チェックでエラーとなる。

  * rh-mariadb103-mariadb-syspaths
  * rh-mariadb103-mariadb-config-syspaths
  * rh-mariadb103-mariadb-server-syspaths

## 設定ファイルなど
設定ファイル
/etc/opt/rh/rh-mariadb103/my.cnf
/etc/opt/rh/rh-mariadb103/my.cnf.d/

データディレクトリ
/var/opt/rh/rh-mariadb103/lib/mysql
[競プロ奮闘記]UnionFindを実装した

# モチベーション
筆者は弱小プログラマなわけですが、強プログラマになるために競技プログラミング始めることにしました。
やってみるとわかるんですが、結構覚えること多いんですよね。受験で数学を解いていても思うのですが、思考力はもちろん大事なんだけど試験本番で短時間で解答に至るためには引き出しの多さも大事。

ということで主要なアルゴリズムやデータ構造は１つ１つ実装していきます。

第１回となる今回はUnionFindと言われるデータ構造を実装します。

ちなみに競プロをやるモチベが効率的に実務をこなすことにあるので、競プロのみんながPo**Hubよりも利用しているC++ではなく僕の愛用言語Pythonを使っていきます。（C++のが４倍速いとかどっかの記事でみたけど４倍なんて誤差ですよね）

# UnionFind
UnionFindはN個のノードがいくつかのグループに分かれているときに
1. 任意の２個のノードa, bが属するグループをつなげて１つのグループにする。
2. 任意の２個のノードa, bが同じグループに属するのかを判定する
という機能に特化したデータ構造。

いずれもならし計算量log(N)で実装できます。

# アルゴリズム

![Screen Shot 2020-09-03 at 0.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641788/832b651c-ff7c-b578-5ffc-b8f70567f0ff.png)

![Screen Shot 2020-09-03 at 0.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641788/96274094-6a11-7d64-dd98-96ceff860996.png)

![Screen Shot 2020-09-03 at 0.55.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641788/3fac5f81-b6fb-0a2e-ee58-1907b3722607.png)


画像はいずれも[素敵なスライド](https://www.slideshare.net/chokudai/union-find-49066733/1)より

# 実装

### データ構造
弱小プログラマはまずデータをどうやってもつべきかを知らないわけですが、UnionFindというのは**親ノードが誰なのかを覚えておく**木構造です。したがってn個のノードをグループ化したければ**各ノードの親を保持するリスト**があれば良いですね。

```
class UnionFind:
    def __init__(self, n):
        self.parents = list(range(n))
    ...
```

ちなみに根ノードには親がいないので**親が自分自身のノード=根ノードとして表現します。**
最初はみんな別々のグループとして初期化するのでみんな根ノードです。

### 判定
```
    def is_united(self, x, y):
        return self._root(x) == self._root(y)
```
素敵なスライドから引用させていただいた画像にも載っていたように、根ノードが同じかどうかを判定すれば良いわけですから、_rootメソッドを使って根ノードを引っ張ってきてそれらが等しいかどうかを比べれば良いわけです。

コードを書くときは細かいサブアルゴリズムはすでに出来上がった関数があると思って書いていくことで全体のアルゴリズムを手っ取り早く書いてしまうのが一番わかりやすいと思っています。

３分クッキングで「本日はここに出来上がったじゃがいもの燻製があります」っていうアレがなかったらなかなか料理の全体像が見えてこないじゃないですか。

### 結合
```
    def union(self, x, y):
        self.parents[self._root(y)] = self._root(x)
```
これも素敵なスライドに書いてあった通りで、xの所属グループとyの所属グループを結合したかったら、どっちかの根ノードを相手の根ノードにくっつけてあげればいいだけです。

くっつけると言ってもくっつけたいノードの親を、くっつける先のノードに指定するだけですね。

### 根ノードを取得する
これまで使ってきたサブアルゴリズムは`_root`だけなので、これを実装したら完成なはずです。

```
    def _root(self, x):
        if self.parents[x] == x:
            return x
        else:
            root = self._root(self.parents[x])
            return root
```

根ノードをリターンするためには親が自分自身になるノードが現れるまで再起的に親ノードへと遡っていくだけです。UnionFind木のデータ構造では各ノードの親への参照なので簡単ですね。

でも計算量の都合上Tree構造ができるだけフラットな方が、計算量が軽くなるって偉大なスライドに書いてありました。

![Screen Shot 2020-09-03 at 1.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641788/4c881fdf-1478-6d71-3f18-a6331c1005dc.png)

そこでコードに若干の工夫を加えます。

```
    def _root(self, x):
        if self.parents[x] == x:
            return x
        else:
            root = self._root(self.parents[x])
            self.parents[x] = root  # 親ノードに直接繋ぎ直す。
            return root
```
これでUnionFind完成！

# 動かしてみる

```
uf = UnionFind(5)
uf.union(0, 3)
uf.union(1, 3)
print(uf.is_united(0, 1))  # True
```

# おしまい
一緒にエンジニア活動を頑張ってくれる仲間を探してます。LGTMやフォロー、Twitterのフォローしてくれるととても喜びます。
GoogleAppScriptでスクレイピングする方法のメモ

けっこう簡単だったのでメモ

```
  const link = 'https://hogehoge
  const html = UrlFetchApp.fetch(link).getContentText()
  const table = Parser.data(html).from('<table class="md_table">').to("</table>").build()
  const aList = Parser.data(table).from('<a ').to("</a>").iterate()
```

GASライブラリのParserを使うと、html文字列から要素の抽出がしやすいが、なんとも使いにくいところがあるので、
最終的には正規表現を使うのが良い。

出力は、スプレッドシートに吐き出すと簡単。
出力の可視化のしやすさが、GASでスクレイピングする一番のメリット。

```
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadSheet.getSheetByName(name)
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data)
```
phpDocumentorを使ってみる

環境
初書：2020/09/03
PC：macOS 10.15.6
Composer： v1.10.10

#phpDocumentorとは
> phpDocumentor 2は、PHPソースコードから直接ドキュメントを生成できるようにするツールです。 これにより、ユーザーインターフェイスから利用できるものだけでなく、ソース内に埋め込まれた機能に関する詳細情報を消費者に提供できます。

(https://www.phpdoc.org より。google翻訳による訳)
要するに、自動ドキュメント生成ツールである。
phpファイルの中に、phpdocでコメントを記述していれば、それを元にドキュメントを作成してくれる便利ツールです。
前から気になってはいたものの、ダウンロードが難しそうで断念していたが、ひょんな事からComposerをダウンロードしたので使ってみることにした。

# ダウンロード方法
composerを使う（composerは依存関係を多く使うので不便な方は注意とのこと）

```zsh
% composer require --dev phpdocumentor/phpdocumentor
```
phpDocumentorは開発環境でしか使わないよね。っていうことで--devをつける。

なんか十数行の警告があったがほんの数秒でDL完了！

（今作ってるプログラムはComposer未使用だったので、composer関連のファイルが大量に作成された。。）

# 使ってみる

```zsh
% vendor/bin/phpdoc run -d dir1 -t dir2
```
-dの後ろのdir1は、生成したいphpファイルがあるフォルダ（の相対パスもしくは絶対パス）
-tの後ろのdir2は、出力したいフォルダ
ちなみに結構フォルダやファイルが作成されるので、-tの後ろは専用のフォルダを作ったほうがいいと思う。



# 表示してみる
さっき作ったdir2のindex.htmlにアクセスすると表示される。
・・・いや、表示されない。
どうやらコンパイルエラーでほとんどのファイルが生成に失敗したらしい。（右上にあるReports->Errorsでエラー内容を見れる）

```
No summary was found for this file
```
・・・いや今まで書いてきたのはなんだったのか。
とりあえず、何かしら書き方が間違っているようなので、コードを見直してみることにする。
（多分ファイルの概要を書いていないからエラーが出たのかと）

# 終わり
分かりやすく書かないと作成しても読めないという事実。
あとはアップデートする場合は上記コマンドの実行でいいのだろうか？（未確認）

---
追記。
ファイル概要を書いてないのでエラーが出たのは間違い無いのだが、
php7.4の書き方にそもそも対応していないらしく、クラス内変数に型宣言するとエラーを吐く。
phpDocumentorのためにバージョンを下げた書き方をするわけにもいかないので、お預けかもしれない。


### 参考サイト
[PHP Documentorを使う](https://qiita.com/zaburo/items/ebd0b0d55f8abf41f001)
Windowsでキーマップを変更する

# Windowsでキーマップを変更する
- Windows PC でキーマップを変更するためのメモ
- PC は Windows 10 Home
- 本ページではレジストリエディタを用いたレジストリ設定を記載しています
  - 本ページの内容を参照される際にはすべて自己責任にて実施してください

# 要件 ( やりたかったこと )
- キーボード上のキーマップを変更 ( `CapsLock` を 追加の `Ctrl` として使う みたいな設定を行う方法のメモ )
- 追加のソフトウェアは使用しない ( OSの機能のみで実現したい )

# 変更方法
レジストリの設定を作成して変更する

## レジストリの変更方法

### 準備
レジストリの変更を行うには以下の2つの方法がある
※ 変更を反映させるためには再起動が必要

- regedit.exe ( レジストリエディタ ) でて入力する
- regファイルを作成して読み込ませる ( regedit.exe でインポートする )

どちらでやってもそんなに作業量は変わらなさそうだが、今回は regedit で直接入力したほうが楽そうなのでその方法をメモしておく
( reg ファイルは regedit から Export できるので、複数の PC に設定する場合には Export と Inport で対応するのが楽そう )

### regedit での設定ファイルの作成
regedit.exe を開き、
`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout` に `Scancode Map` を作成

### 設定内容の作成
設定内容は以下の内容で構成されるらしい

| Start offset (in bytes)| Size (in bytes) | Data |
| :---: | :---: | :---: |
| 0 | 4 | Header: Version Information |
| 4 | 4 | Header: Flags |
| 8 | 4 | Header: Number of Mappings |
| 12 | 4 | Individual Mapping |
| ... | ... | ... |
| Last 4 bytes | 4 | Null Terminator (0x00000000) |
※ Microsoft社ドキュメント [Hardware Dev Center Keyboard and mouse class drivers](https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers#scan-code-mapper-for-keyboards) より引用

説明や内容を見た感じ各値の意味は以下みたいな感じ
また、設定値はリトルエンディアンで記載する

- Version Information
  - 4byte の all0
- Flags
  - 4byte の all0
- Number of Mappings
  - エントリ数 ( nullエントリを含む )
  - 設定内容 ( キーマップの変更 ) のエントリ数 + 1 ( nullエントリ )
- Individual Mapping
  - 設定内容
- Null Terminator
  - 4byte の all0

サンプルなどは [Hardware Dev Center Keyboard and mouse class drivers](https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers#scan-code-mapper-for-keyboards) にあるので設定内容全体への詳細記法は省略する

#### Individual Mapping に関して
この項目は以下の手順で作成していけばいい

- キーボード上のキーを何と入力したいかを決める
  - 今回は既出リンク内のサンプルにもある `CAPS LOCK --> Left CTRL key` で記載する
- これをキーコードに直す
  - `CAPS LOCK` は `0x3A`
  - `Left CTRL key` は `0x1D`
- 変更したい内容をキーコードで表すと `0x3A --> 0x1D`
- 上記のキーコードでは `1byte + 1byte = 2byte` なので各種設定値の頭に all0 の 1byte を付与して Individual Mapping のバイト数 ( 4byte ) に合わせる
  - `0x003A --> 0x001D` ( `2byte + 2byte = 4byte` )
  - 今回は変更したいキーのコードが 1byte だったので頭に0埋めしたが、もともと2byteの場合は0埋め不要
- 上記より作られた値は `0x003A001D`
- これをリトルエンディアンにする
  - 設定値は `0x1D003A00` となる
- この値が Individual Mapping ( レジストリエディタに入力するときは `0x` 無しで `1D003A00` と入力できた )

キーコードに関しては `Microsoft Download Center` からdoc形式のドキュメントでダウンロードできる
( 検索したところダウンロードリンクしか見つからなかったが、本記事執筆時現在以下のキーワードで検索すると上位に出てきた )
`Keyboard Scan Code Specification - Microsoft Download Center`

# 参考
- [Hardware Dev Center Keyboard and mouse class drivers](https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers#scan-code-mapper-for-keyboards)
- Keyboard Scan Code Specification - Microsoft Download Center
AutoLayout で表のようなレイアウトをする

## やりたいこと

こういう↓ View を組みたいとき
![capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12653/4337311a-cfec-c298-53b7-4f4a1a3d5101.png)

- table タグを使ってできるレイアウトのようなもの
- 左のラベルは右寄せ。それぞれの幅は一番幅が長いものに合わせる
- 右のラベルは複数行入る。縦方向のレイアウトはこちらで決まる

## 実現方法

この要件だと UIStackView だけだと実現できなかったので、AutoLayout でゴリッとやったらできた
(Cartography と Then を使っているけど雰囲気は伝わるはず……)

```swift
let content: [(heading: String, body: String)] = [
    ("いち: ", "改行\nする\nテキスト"),
    ("に: ", "普通のテキスト"),
    ("さぁん: ", "長いテキスト長いテキスト長いテキスト長いテキスト長いテキスト長いテキスト長いテキスト長いテキスト長いテキスト")
]
let spacing = CGFloat(4)

var prev: (heading: UIView, body: UIView)?
content.forEach { heading, body in
    let headingLabel = UILabel().then {
        $0.text = heading
        table.addSubview($0)
    }
    let bodyLabel = UILabel().then {
        $0.numberOfLines = 0
        $0.text = body
        table.addSubview($0)
    }

    if let (prevHeading, prevBody) = prev {
        constrain(headingLabel, bodyLabel, prevHeading, prevBody) { headingLabel, bodyLabel, prevHeading, prevBody in
            headingLabel.leading >= headingLabel.sv.leading
            headingLabel.top == bodyLabel.top
            headingLabel.trailing == prevHeading.trailing

            bodyLabel.leading == headingLabel.trailing
            bodyLabel.trailing == bodyLabel.sv.trailing
            bodyLabel.top == prevBody.bottom + spacing
        }
    } else {
        constrain(headingLabel, bodyLabel) { headingLabel, bodyLabel in
            headingLabel.leading >= headingLabel.sv.leading
            headingLabel.top == bodyLabel.top

            bodyLabel.leading == headingLabel.trailing
            bodyLabel.trailing == bodyLabel.sv.trailing
            bodyLabel.top == bodyLabel.sv.top
        }
    }

    prev = (headingLabel, bodyLabel)
}
if let (_, prevBody) = prev {
    constrain(prevBody) { prevBody in
        prevBody.bottom == prevBody.sv.bottom
    }
}
```

## みどころ
- `headingLabel.leading >= headingLabel.sv.leading` と定義している
- 横方向は heading が、縦方向は body が決めているので錯綜感がある

## misc

他に良い方法あれば教えてください
(左のラベルが固定だったら NSMutableParagraphStyle#headIndent を使うことで、単一の UILabel で実現できるのだけれども)
グローバルIPの確認方法

## グローバルIPの確認方法

### [linux]コマンドラインで見る方法

```sh
# グローバルIPの確認コマンド
$ curl ifconfig.io
```

### [windows,Mac,linux]webで見る方法

webでアクセスする
下記などがある


- [CMANネットワーク確認](https://www.cman.jp/network/support/go_access.cgi)
- [ラッコIPアドレス確認](https://rakko.tools/tools/2/)
- [LUFTTOOL IPアドレス確認](https://www.luft.co.jp/cgi/ipcheck.php)
djangoのmodelに入っているデータをjson形式で返し、leaflet上にマッピングする方法

今回は、タイトルにもある通り、models.pyで登録したデータをrestapiを使ってjson形式で返してもらい、それをマップ上にプロットしようというものです。
僕自身、djangoも初心者レベルで地図アプリも触ったことがないので、そのレベルの同じような人が躓いたときに参考にしてもらえると嬉しいです。


#うまくいったコードです↓
```
def index_serialized(request):
    evacuation=Evacuation.objects.all()
    serialized=EvacuationSerializer(evacuation,many=True)
    content=JSONRenderer().render(serialized.data)
    return HttpResponse
```
pythonで@propertyを使った時にcan't set attributeが出る

どうもpythonでコードを書いてる者です

とかいってまだ初心者なのでエラーでつまることも多々あります。
そのなかでこれまでよくわからずに放置してきたクラスのセッターやゲッターをこの期にちゃんと学び直してみようと思い今回は書いております。ではいきましょーー

＊使用した言語等のバージョンは以下の通りです。
>python 3.7.4

#can't set attributeで引っかかる
クラスで生成したものを取得したい時ありますよね。そんな時どうするでしょうか。

```practice01.py
class C(object):
    def __init__(self) -> None:
        self.x = 1


c = C()
r = c.x
print(r)
# 1
```

簡単に書けばこうです。でもせっかくなら@propertyとか使ってみたいでしょ

```practice02.py
class C(object):
    def __init__(self) -> None:
        self.x = 1

    @property
    def x(self):
        if self.x is None:
            return None
        return self.x


c = C()
r = c.x
print(r)
# AttributeError: can't set attribute
```

はい、`AttributeError: can't set attribute`が出ました。
では、解決方法をまず提示しておきたいと思います。

```practice03.py
class C(object):
    def __init__(self) -> None:
        self._x = 1

    @property
    def x(self):
        if self._x is None:
            return None
        return self._x


c = C()
r = c.x
print(r)
# 1
```

では、なぜ`practice02.py`はうまく動作しないのでしょうか。

それは、変数名と関数名が一致しているからです。つまり、`practice03.py`のように変数の方を`self._x`としてあげれば、__変数名と関数名が異なる__のでセーフと言うことですね。

そしてpractice03.pyでいう

```getter.py
@property
    def x(self):
        if self._x is None:
            return None
        return self._x
```

の部分がゲッターと呼ばれるものですね！

#なぜゲッター、セッターを使うのか
今回記事にしたような単純なものの場合はゲッターやセッターを用いずに書いた方がわかりやすいと思います。実際に使うのは、__クラス内に存在するメソッドを属性のように扱いたい時__に用いるのではないでしょうか。

とても参考になる記事がありますので参照させていただきます。

[python3 プロパティの必要性が分かりません。](https://teratail.com/questions/246707)

この記事からも分かるように、結局ゲッターやセッターと言うのは__わかりやすくしたい時に使う手法・テクニックのひとつ__ではないでしょうか。~~つまり気分ということです。~~
うまく使いこなせるようになればより綺麗でわかりやすいコードが書けると言うことでしょう！！僕もうまく使いこなせるようにがんばって勉強していきたいと思います！

コメント欄にてわかりやすいことを書いてくださった方がいますので、そちらもご覧ください！

では！

# 追記（2021/03/30）

こちらの記事も参考になりましたので、追記しておきます。

[【Python】クラスのプロパティ（getter/setter）の書き方【入門第35回】
](https://naruport.com/blog/2019/8/27/python-tutorial-class-property-getter-setter/)
Ajaxのデバッグにログを使うのはもうやめよう！これからは開発者ツールで楽々デバッグ

## 面倒なAjaxのサーバーサイドのデバッグ
Ajax通信の際のサーバーサイドのデバッグはログに吐くテクニックを使う人が多いですが、ブラウザとログを行き来するのは億劫に感じませんか？

```php:よくあるデバッグ
error_log(print_r($result, true), 3, '/var/log/debug_log');
```


## 開発者ツールでデバッグが楽になる

そんなときはChromeの開発者ツールからリクエストの結果を確認すると捗ります。
Networkタブから該当のAjax通信を選択してPreviewを見るだけ。

(1)Networkを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206138/bba5e142-43c0-359b-1035-f43dec38306f.png)

(2)該当リクエストを選択して、Previewタブを表示する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206138/d0e6bd9d-ac64-46fe-720b-a293cef9ed1b.png)

このようにサーバーサイドが出力している値を表示することができます


この方法にすれば、

- いちいちブラウザとログを見比べる必要がなくなります
- htmlへのprintと同様の関数でいいので記述量が減ります

```php:開発者ツールのデバッグ
var_dump($result); //これだけでOK
```

簡単な割に効果が大きいのでおススメなAjaxデバッグのテクニックでした！
【Gatsby】node最新バージョンでyarnするとエラーが出るのでnodeのバージョンを変えてyarnしてみた

gatsby.jsのテーマをcloneして使おうとした時に```yarn```の時点でエラーが出たのでnodeのバージョンを変えて挙動を確認しました。

## Nodeバージョン
* v14.9.0(最版）
* v12.18.3 (LTS:長期サポート版)
* v10.22.8 (LTS:長期サポート版)
* v8.17.0 (LTS:長期サポート版)

yarn、gatsby、Macのバージョン

```
% yarn -v
1.22.4
% gatsby -v
Gatsby CLI version: 2.12.87
% sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.6
BuildVersion:	19G2021
```

## 検証に使ったGatsbyテーマ
[GitHub](https://github.com/niklasmtj/gatsby-theme-julia)
***gatsby-theme-julia***とういうテーマを```git clone```して使いました。

## 検証方法

* gatsbyのテーマを```git clone```
* node バージョンを切替える
* ```yarn```



### 1.v14.9.0（現時点の最新版）
```
% node -v
v14.9.0
% yarn
```
gypのエラーがめちゃくちゃ出ます。ググるとxcodeを再インストールするよう言われますが、したところで解決しないです。その他brewを消すとか色々試しましたが今だに解決してないです。
![スクリーンショット 2020-09-02 23.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/cb89a4b0-c783-2da5-8b31-cf1154143b52.png)

### 2.v12.18.3(LTS)
```
% node -v
v12.18.3
% yarn
```
```✨ Done in .. ```が出たのでこれは成功。
![スクリーンショット 2020-09-02 23.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/a373a739-38ef-17f8-7e62-f409fe99dcb5.png)


READMEに書いてある通り```yarn workspace demo develop```を実行するとlocalhost:8000/も大丈夫でした。
![スクリーンショット 2020-09-02 23.23.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/fd063c57-da14-3d82-1b43-18751914094e.png)

### 3.v10.22.8(LTS)
```
% node -v
v10.22.0
% yarn
```
これも成功。
![スクリーンショット 2020-09-02 23.30.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/7e01758b-57bd-7ddd-9df6-92bb2425749e.png)

### 4.v8.17.0
これも成功。

```
% node -v
v8.17.0
% yarn
```
![スクリーンショット 2020-09-02 23.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/c881e9e7-7024-1bde-63b4-c66637306177.png)



LTSのバージョンであればv8〜12は大丈夫でした。
これをきっかけに[nvmを使ったnode.jsのバージョン管理](https://qiita.com/haaaru22/items/fc946a299a60beea0003)を覚えました。
yarnで同じエラーが出る方はnodeのバージョンを確認してみると簡単に解決するかもしれないです。
ハイパーバイザーとは？

- 仮想化技術の一つ

- 従来のホストOS型に対して、ホストOSを使わずに直接サーバーに仮想化ソフト(ハイパーバイザ)をインストールして仮想マシンを稼働させる方式のこと。

- 従来の仮想化ソフトウェアでの余計なオーバーヘッドがないので、高いパフォーマンスを発揮できる。

- ハイパーバイザ型は「ホスト型」と「ベアメタル型」の二つのタイプがある。
    ・ ホスト型：ハードウェア上でプログラムを直接制御する
　 例：VMware Server、Virtual PC、Parallels Desktop

    ・ ベアメタル型：仮想化環境でプログラムを直接制御する
　 例：Vmware ESXi、Microsoft Hyper-V、Citrix Xen Server
macOSとWSL2でGitのコミットハッシュをtigからクリップボードにコピーする

`.tigrc`で下のような設定を書いて、`9`キーを押すと該当コミットのハッシュがクリップボードにコピーする、ということをやってました。

```
bind generic 9      @sh -c "echo %(commit) | pbcopy"
```

で、最近WSL2を使い始めたのですが、当然`pbcopy`コマンドはないのでどうしようかなーと思って改善した記録です。

# `clip.exe`の発見

どうもWindowsには`clip.exe`という`pbcopy`的なプログラムがあるらしく、WSL2からも`clip.exe`とコマンドを打つことで利用することができます。これを使います。

# 新しくコマンドを作る

`pbcopy`と`clip.exe`をラップして、OSごとに呼び分けるコマンドを作ることにします。ちなみに僕はfishユーザーなのでfishコマンドです。

```fish
# macOS/WSL2両対応のクリップボードコピーコマンド
function copy_to_clipboard
  # macOS
  string match -q -- 'Darwin' (uname); and pbcopy $argv; and return
  # WSL2
  string match -q -- '*microsoft*' (uname -r); and clip.exe $argv; and return
end
```

- fish内臓の`string`コマンドを利用してます。`string`コマンドは`match`サブコマンドを持っていて、文字列の比較を行うことができます。
- OSの判定は https://neos21.hatenablog.com/entry/2020/08/22/080000 を参考にしました。

# `.tigrc`に設定

```tig
bind generic 9      @fish -c "echo %(commit) | copy_to_clipboard"
```

これで`9`キーを押してコミットハッシュをクリップボードにコピーできるようになります。
Xcode12でUITableViewCell内のタップが反応しない・挙動がおかしい

#環境
- Xcode 12 Beta 6
- iOS 14 Beta 6

※ この記事で言及している問題は、Beta版ではなく正式版になると解決される可能性があります。あくまでBeta 6時点での解決方法としてお読みください。 

#発生した問題
Xcode12でビルドしたアプリをいじっていると、UITableViewを使っている画面でタップが効かなかったり挙動が変わったりしている画面を発見しました。具体的には、cell内のUISwitchが押せなかったり、cellにaddSubviewしたUICollectionViewのcellをタップしてもdidSelectItemAtが呼ばれなかったりしました。Xcode 11でビルドしていたら押せたのに。。。

#原因
調べていくと、cellの子ViewであるcontentViewにタップを奪われてUISwitchやUICollectionViewをタップできていなかったことがわかりました。storyboardやxibを使ってcellのcontentViewに乗せている場合は起こらなかったのですが、発見した箇所はすべてコード上でcellに直接addSubviewしている画面でした。

#修正方法
contentViewにタップを奪われているので、contentViewをタップに反応しないようにすればよいです。適時、

```swift:ViewController.swift
cell.contentView.isUserInteractionEnabled = false
```
を実行しましょう。

# 追記(2020/09/22)
コメントにてご指摘いただきました。パフォーマンスの観点から、iOS 14ではUITableViewCellとUICollectionViewCellがcontentViewの生成を遅延して実行するようになったようです。
https://twitter.com/smileyborg/status/1276623197207531520

また、cellに直接addSubviewしているのは本来の使い方ではなく、contentViewにaddSubviewするのが正しいです。contentViewにaddSubviewしていれば今回のバグは起こりませんでした。
https://developer.apple.com/documentation/uikit/uitableviewcell/1623229-contentview

今回のバグは、Appleが「正しい実装をしていれば開発者には影響がないはず」という修正を加え、その部分がこのアプリでは正しく実装されていなかったゆえに起こったバグでした。ですので、cellに直接addSubviewしている部分を適時contentViewに変えるのが正しい修正方針です。

```swift:ViewController.swift
cell.addSubview(view)             // これを
// ↓↓↓↓↓↓↓↓↓↓↓
cell.contentView.addSubview(view) // こっちに書き換える
```

#おわりに
新しいXcodeへの対応は情報が少なくて大変ですが、原因がわかった時はいろんな問題が一気に解決していくのが楽しいですね。
Automated Build(自動ビルド)の個人的備忘録

## Automated Build(自動ビルド)とは
<b>Github</b>や<b>Bitbucket</b>といったソースコードのホスティングサービスでビルドコンテキスト(Dockerfileやその他のビルドに必要なファイル群)を管理し、リポジトリ上のビルドコンテキストの内容が変更された場合に自動的にビルドを実行する仕組みのこと。

##DockerHubとGitHubのリンク設定
Dockerhubのリポジトリの「Builds」タブのLink to GitHubをクリックし、任意のGitHubのリポジトリを選択。

Source Type　　　　　　　　githubのBranchを対象にするか、タグを対象にするかの設定
Source　　　　　　　　　　 branch名またはタグの指定
Dokcer Tag　　　　　　　　 ビルドされたイメージにつけるタグ付の指定
Dockerfile location　　　 　　dockerfileの置いてあるパスの指定
BuildContext

「<b>Save</b>」を押す。
自動ビルドはここで設定されたリポジトリに、ファイルが<b>追加</b>されるか、<b>変更</b>された場合に実行される。

## GitHubからリポジトリをgitcloneする
```
% git clone https://github.com/ユーザー名/automated-build-test.git
```

## Cloneしたディレクトリに移動し、Dockerfileを作成し記述する
```dockerfile
## 例
FROM docker samples/static-site
ENV AUTHOR=“docker”
```

## GitHubにpushする
```haml
-# 指定したDockerfileをインデックスに登録してコミット対象にするコマンド
% git add Dockerfile
-# ファイルやディレクトリの追加・変更を、リポジトリに記録する
% git commit -m “docker commit"
-# ローカルリポジトリの内容をリモートリポジトリに送信する
% git push origin master
```
ユーザー名、パスワードを求められたら入力する。

DockerHubの「Builds」タブでAutomated Buildsのステータスが<font color="Orange">PENDING</font>になり、時間が立ち<font color="DeepSkyBlue">SUCCESS</font>になったら成功。

## 実際に自動ビルドできているか確認する
```haml
-# 自動ビルドしたイメージのpull
% docker pull Dockerhubのリポジトリ名
-# イメージの一覧表示
% docker images
```
イメージがpullできていることが確認できる。

これをうまく利用することで都度手動でビルドすることが不要になり、さらに他のアプリケーションや、サービスと連携することでコンテナの実行まで自動化することができる。