OmniAICreator/Qiita-1.07M huggingface dataset:
ウィキデータ語彙素(Lexeme)の紹介-2 動詞の登録

[著作権保護期間満了の辞書](https://ja.wiktionary.org/wiki/Wiktionary:%E8%91%97%E4%BD%9C%E6%A8%A9%E5%88%87%E3%82%8C%E8%BE%9E%E6%9B%B8%E3%81%AE%E4%B8%80%E8%A6%A7)の中から「[大日本国語辞典](https://dl.ndl.go.jp/info:ndljp/pid/954645)」を選んで、私なりのやり方で実際に登録してみます。お気づきの点などありましたらコメント欄でご指摘頂けると嬉しいです。

現代人から見ると古典的な記述が多く見られます。まずは国語辞典から始めたいので、適宜読み替えながら登録してみます。

# 1 見出し語を選ぶ
「大日本国語辞典」の中から動詞の「[起く](https://dl.ndl.go.jp/info:ndljp/pid/954645/282)」を選んでみます。
![](https://i.imgur.com/rq82bpF.png)
口語体では「起きる」という見出しになります。

# 2 未登録チェック
すでに登録されていないか確認します。右上の検索窓で「L:起きる」と入力して検索。
![](https://i.imgur.com/uSnZa8n.png)
登録済みでした。
![](https://i.imgur.com/8GL2kr5.png)
既存の語彙素「起きる」を選んで未登録の属性を追記することにします。
なお、新規作成は画面左パネル上部寄りの「語彙素の新規作成」から行います。

# 3 共通属性の登録
![](https://i.imgur.com/EWfxRdi.png)
・読み仮名：「おきる」
・修正ヘボン式ローマ字表記（ローマ字）：okiru
・発音（音声ファイル）：[Lingua Libre](https://lingualibre.fr/wiki/Special:RecordWizard)を利用すると簡単にコモンズに登録して、その音声ファイル名を使用できます。（詳細は別途紹介予定）
・IPAによる発音表記：okirɯ（「[日本語の音素と音声の対応](http://home.att.ne.jp/yellow/townsman/onso_onsei.htm)」から転記していますが簡易的なもののようなので詳しい方はコメント頂けると幸いです。）
・IPA点字：⠊⠣⠙（「[Unicode点字変換](https://uhyo.github.io/tenji-web/)」を利用させてもらいました。）
![](https://i.imgur.com/ceYaJO8.png)
# 4 語義の登録
「大日本国語辞典」の語義を現代文に読み替えます。
語義1)伏したるより立ちあがる。→寝た状態から立ち上がること。
語義2)眠り覚む。寝所より出づ。→眠りから覚めること。寝床から出ること。
語義3)うつし心になる。気がつく。→現実に返る。気がつく。（古語）
語義4)うかびいづ。浮く。→浮かび出る。浮く。（古語）
![](https://i.imgur.com/MYetvXA.png)
「語義を追加」をクリックして追加します。
![](https://i.imgur.com/xxmXcYG.png)
・言語：「ja」または「日本語」と入力すると自動補完してくれます。
・注釈：用意した語義を入力します。
![](https://i.imgur.com/zAkHqVr.png)
右寄りの「+追加」で
典拠：大日本国語辞典
という文を語義に追加し、さらに「情報源を追加」をクリックして出典に関する情報を入力します。

古語については
言語変種：古語法
という文を語義に追加して表現します。

このように読み替え（翻案）したものへの典拠や情報源の付け方は不要、あるいはもっと良いやり方があるかもしれませんが、ひとまずオリジナルの出典を付けるやり方としました。

# 5 文例の登録
語彙には、その用例があると理解しやすくなります。「大日本国語辞典」の用例はほぼ古典のため現代人にはわかりづらいので、せめて近代以降の文例を探します。利用対象として、著作権保護期間内の辞書以外で引用の範囲であればほぼ問題ないのですが、ここでは[青空文庫を全文検索](https://www.aozora.gr.jp/index.html)して探しました。

語義1に相当する文例)
> この地面のうちでは寝るとも**起きる**とも勝手にせよ（夏目漱石「[草枕](https://www.aozora.gr.jp/cards/000148/files/776_14941.html)」）

語義2に相当する文例)
> 早く床につき早く**起きる**ことは、人を壮健、富裕、賢明ならしむ（佐々木邦「[朝起の人達](https://www.aozora.gr.jp/cards/001750/files/55800_57280.html)」）

共通属性欄で、語義と語形を示して登録します。
![](https://i.imgur.com/G5sTwov.png)
語義と語形については該当する「L番号-枝番」を指定すると、自動的にその値に置き換えられて表示されます。
![](https://i.imgur.com/cNeW2GK.png)
これで「[起きる](https://www.wikidata.org/wiki/Lexeme:L843)」に属性をいくつか登録できました。

（つづく）

[ウィキデータ語彙素(Lexeme)の紹介-1](https://qiita.com/higa4/items/f0ecd4bfdec10ce86285)
Affinity matrixの個人的ノート (具体例で理解するピクセルを対応付ける行列計算)

#はじめに
Deep論文を読んでたら、式だけだと混乱してくるところがあります。個人的なメモとこれから投稿する論文解説記事の補足として書きます。

時間$T$におけるフレーム$f_1$内のある物体が,時刻$T+1$のフレーム$f_{2}$では別の場所に移動しているとする。このとき$f_1$の各pixelと,$f_2$の各ピクセルの対応関係を考えたいとする。

このとき、論文でよく出てくる式として以下のような式がある。
$y_{j}=\sum_{i} A_{i j} c_{i}$ (1)

ただし、$y_{j}$は$f_{2}$の$j$番目のピクセル値、$c_{i}$は$f_{1}$の$i$番目のピクセル値, $A_{i,j}$は変換行列(affinity matrixともいう)である。

文字だけを読むとややこしくなってくるのでこれを具体的にイメージするというのがこの記事の目的

#1 数式の意味と具体例(画素値の対応)
ここでは簡単に画像のサイズが2×2行列だとして考えてみる。また中に入っている画素値は、イメージしやすくするため数値ではなく記号的にB(青),R(赤),G(緑),P(紫)を表す文字が入っているとする。
例えば$f1,f2$の画像は図1に示すような画像、もしくは行列になっている。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/c2be2b7d-75c5-6715-782f-25cb38271fa1.png)
__図1__

$y_{j}$,$c_{j}$はフレームのピクセル値(画素値)を表す。画素値を表すときは(グレースケール画像と仮定すると)2次元行列$y_{m,n}$で座標を指定することが多いが、(1)式ではそれらすべて1次元にReshapeして頭からiやjとindexを割り振ることになる。(図2参照)。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/55e6eac6-7f43-74e5-2bd6-4d7336b245ac.png)
__図2__

では$f1,f2$を対応づける変換行列$A_{i,j}$はどういう形をしているだろうか？
これは$f1$,$f2$がそれぞれ$4×1$行列ということを考えると,$4×4$の次のような行列になる。実際に(1)式がなりたっていることが確認できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/e090ddd0-54ac-7117-25c3-2d530d745422.png" width="200">

なお,$A_{i,j}$は$f_{1}$の$i番目$のピクセルと$f_{2}$の$j$番目のピクセルの類似度とも解釈できます。

Deepではモデル出力を$A_{i,j}$にして,行方向にsoftmax関数をかけることで,ピクセル対応の確率予測を行うことがあります。

なお、$A_{i,j}$は互いの行列サイズが異なるときにも使用できる。その場合、$A_{i,j}$の行列サイズは($f_{1}$のピクセル数$N_{1}$)×($f_{2}$のピクセル数$N_{2}$)になります。



#2 数式の意味と具体例(座標の対応)
これまでは画素値の変換の仕方を見てきたが、座標の対応の仕方も見ておきます。
$l_{j}^{12}=\sum_{i=1}^{N_{1}}A_{i j} l_{k}^{11}$ (2)

$l_{j}^{mn}$は$f_{m}$から$f_{n}$の$j$番目のピクセルに移動する$f_{m}$の座標です。文章だけだと混乱しますね。言っていることは難しくないので具体例で考えればすぐわかります。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/55e6eac6-7f43-74e5-2bd6-4d7336b245ac.png)
__図2　再掲__
$l_{1}^{12}$は$f_{2}$の1番目のピクセル(画素はR)に移動する$f_{1}$の座標です。
$f_{1}$でRが入っている座標は(1,2)ですよね。ということで$l_{1}^{12}=(1,2)$となります。イメージできましたか？
j番目のピクセルと言われたときはReshape後の,座標と言われたときはReshape前で考えなきゃいけないのが混乱pointです。


では数式で理解していきます。
まず式内の$l_{k}^{11}$から考えます。文章で言えば$l_{k}^{11}$は$f_{1}$から$f_{1}$の$j$番目のピクセルに移動する$f_{1}$の座標です。
$f_{1}$と$f_{1}$は同じものなのですから、$f_{1}$の$(x,y)=(1,1)$座標に対応するのは$(1,1)$座標に決まっています。ここで$(1,1)$座標は先ほどの例をみると、1番目のピクセル、$(1,2)$座標は2番目のピクセルというように対応していましたね。よって$l_{1}^{11}=(1,1)$,$l_{2}^{11}=(1,2)$,$l_{3}^{11}=(2,1)$,$l_{4}^{11}=(2,2)$となります。

では、先ほどの$A_{i,j}$を用いて$l_{j}^{12}$を計算するとどうなるでしょう？なお、$x$座標、$y$座標は別々に計算します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/0d71eff6-df16-68e2-670e-95fe22c5bce3.png" width="400">
x,y座標の結果をまとめると
$l_{1}^{12}=(1,2)$,$l_{2}^{12}=(1,1)$,$l_{3}^{12}=(2,2)$,$l_{4}^{12}=(2,1)$という結果が得られました。

これを用いて$f_{1},f_{2}$で対応する座標点の変換ができるようになります。



#3 Color energyの保存
ここで示したピクセル変換はColor energy(グラム行列)が保存されることがわかります。要するに$f_{1} f_{1}^{\top}=f_{2} f_{2}^{\top}$が成立しています。
実際に
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221156/7222516d-99e7-c73f-7e79-6c0c8953b458.png)

となり、一致することが確かめられます.
体系的にIntellijIDEを学ぶ_下書き

## .idea directory.
### Config to be shared and under vcs, and not to be shared and under vcs.

Project settings are stored in the project directory as a set of XML files under the .idea folder. This folder contains both user-specific settings that shouldn't be placed under version control and project settings that are normally shared among developers working in a team, for example, the code style configuration.

When you place a project under version control, your personal settings are automatically ignored. IntelliJ IDEA moves workspace.xml — the file with your personal settings — to the list of ignored files to avoid conflicts with other developers' settings.

Configuration files are processed according to your choice. Once you modify the project settings, and a new configuration file is created, the IDE shows a notification at the bottom of the screen prompting you to select how you want to treat configuration files in this project:

View files: view the list of created configuration files and select, which of them you want to place under version control. After that, the selected files will be scheduled for addition to VCS.

Always Add: silently schedule all configuration files created in the .idea directory for addition to VCS (applies only to the current project).

Don't Ask Again: never schedule configuration files for addition to VCS; they will have the unversioned status until you manually add them to VCS (applies only to the current project).
conda+direnvで仮想環境を自動で切り替える

# 方法
condaで仮想環境を切り替えるには、

```
conda activate <ENV_NAME>
```
ですが、いちいちプロジェクト毎に切り替えるのは面倒です。

direnvを使うことで、自動で環境を切り替えることができます。
該当のプロジェクトに.envrcを作成し、以下を記述します。

```.envrc
eval "$(conda shell.bash hook)"
conda activate <ENV_NAME>
```

こうすることで、該当プロジェクトに移ったら、.envrcが実行され指定した仮想環境が自動でactivateされます。
該当プロジェクトを抜けるとunsetされ、仮想環境からも自動で抜けることができます。

---

ちなみに、
`conda activate` だけだと `conda init`を先に実行しろとおこられます。（おこってるわけじゃないと思いますが）
このコマンドはcondaをセットアップした時点でもう実行しているはずです。なので素直に.envrcに記述するのはちょっとアレな感じです。

そもそも `conda init`ではいろいろなファイルを作成したり、bash_profileに追記してくれたりします。この作成されるファイル群の中に`/<condaのパス>/etc/profile.d/conda.sh`が含まれています。ここに `conda activate` のスクリプトが書いてあります。
`conda shell.bash hook`はそのconda.shの中身を返してくれます。evalすることによりconda.shを実行し `conda activate`が使えるようになります。


# 参考
https://github.com/conda/conda/issues/7980
Minicondaを使う

# Miniconda
軽量版Anacondaです。AnacondaにたくさんのライブラリやIDEなどが含まれているのに対し、MinicondaはcondaやPython, 必要最小限のライブラリに絞られています。

# 何がいいのか
**Anacondaと比べて軽量**
インストール時、Anacondaは諸々入っているため、数GBくらいになります。
その点Minicondaは必要最小限しか入っていないので数百MBで済みます。

**condaが使える**
condaはPythonのパッケージ管理と、Python自体のバージョン管理ができるツールです。
pipを使って環境構築をした場合、`pip+pyenv`が必要になるところ、`conda`だけで済みます。
特に、MacOSでPythonの環境構築はデフォルトのPythonとの兼ね合いで詰まりやすいので、condaだけでまかなえるのは楽です。

**Minicondaって名前がかっこいい**
pipよりもcondaの方がかっこいいし、AnacondaよりもMinicondaの方がかっこいいなと感じてます。響きだけの話です。


# 使い方
公式Minicondaサイトからhttps://docs.conda.io/en/latest/miniconda.html より、イントーラを使用してインストールします。

### 仮想環境を作る

condaを使って仮想環境を作成します。

```
conda create -n py36 python=3.6
conda activate py36
```

とすることで、Python3.6の仮想環境py36が作られ、activateでその環境へ切り替えることができます。

この時に、親切にもプロンプトの先頭に `(py36)$` と環境名をつけてくれます。
不要な場合は、

```
conda config --set changeps1 False
source ~/.bash_profile
```

とすることで、.condarcに書き込まれ表示されなくなります。

仮想環境から抜けるには

```
conda deactivate
```
とすることでデフォルトのbaseに戻ります。

### ライブラリの追加
ライブラリは以下のコマンドで追加できます。

```
conda install pandas
```
もし、デフォルトのチャンネルでライブラリが見つからない場合、 `conda-forge`で探すのも1つの手です。

```
conda search -c conda-forge pixiedust
conda install -c conda-forge pixiedust
```

デフォルトで見つからないとpipを使いたくなりますが、condaとpipの併用はできるだけ避けたいところです。
`conda-forge`でも見つからない場合は [Anaconda Cloud](https://anaconda.org/) を見てみるといいです。

# 参考
Anaconda公式インストールガイド https://conda.io/projects/conda/en/latest/user-guide/install/macos.html
Anaconda Cloud https://anaconda.org/
【AndroidStudio】TextClock使用時にデザインビューが表示されない件について

# 概要
先日、AndroidStudioの最新版(3.6.2)をインストールしたのですが、前環境で作成していたアプリのデザインビューが表示されなくなってしまいました。
エラーを確認してみると、「Render problem」と示されています。

いろいろ調べたところ、原因はTextClockの使用にあるみたいです。
stackOverflowの情報ですが、これはAndroidStudioのバグだと思われます。

英語のソースがあるのでわざわざ書くことでもないと思いましたが、私がそれで時間を食ってしまったので、共有させてください。
また、初投稿ですので至らぬ点がございましたらご指導のほどよろしくお願いいたします。
<参考文献>
"TextClock render problem in layout preview"
https://stackoverflow.com/questions/60565227/textclock-render-problem-in-layout-preview

# 解決策
これは根本的な解決ではなく、あくまでも対処であります。
[stackOverflowのアンサー](https://stackoverflow.com/questions/60565227/textclock-render-problem-in-layout-preview)にもありますように、

「xmlタグのTextClockをTextViewに置き換え、ビルド時にTextClockに置き換える」のがもっともストレスがない方法かと思います。

当然、以前のバージョンにダウングレードするのも対処法の１つです。時間がかかりますが。

# 終わりに
そういえば、AndroidStudioの最新版(3.6.2)ではPaletteからTextClockがなくなっていますね。
廃止されたとか、非推奨になったとかの情報は見つかりませんでしたので不思議です。
WordPressのuploadsにあるファイルへの直接アクセスを制限（WP新仕様対応）

WooCommerceというWordPress用プラグインでショップを構築している。最近、デジタル商品（PDF）の販売もやり出しているのだが、一つ問題があって、WordPressはメディアファイルをアップロードすると``/wp-content/uplaods/``というディレクトリ以下にファイルが置かれるのだが、これには何も制限がかかってなくて、直接URLを入力したらファイルが表示されてしまう。これじゃ販売してる意味がないし、検索エンジンクローラーにも引っかかってしまう。

まぁFTP使って、直接アクセスできない領域に置けばいいじゃないかという話もあるのだが、諸事情からそれは見送り（詳細省きます）。次のような要件を.htaccessで実現することにした。

## 要件

1. デジタル商品（.pdf、.mp3、.zip）へのアクセスは禁止
2. ただし拡張子の前に\_sampleと着いているものはアクセス可能。
   e.g. hoge\_sample.pdf、hoge\_sample.mp3、hoge\_sample.zip
3. リファラで自身のサイトからアクセスする場合はアクセス可能。

## 実際の.htaccessはこうなる

ネット検索すると``<Files ~~~>``で拡張子などを条件にアクセス制御しているが、同じ条件に当てはまっても例外を作る場合があまり見つからないようだ。次のように書いてみた。

```apache:.htaccess
SetEnvIf Referer "^https?://hoge-hoge\.com" mysite
<Files ~ "\.(pdf|mp3|zip)$">
order deny,allow
deny from all
allow from env=mysite
</Files>

<Files ~ "_sample\.(pdf|mp3|zip)$">
allow from all
</Files>
```
``<Files>``~``</Files>``が2つあるのがミソだ。簡単に解説する。

- ``””``で囲った中身は正規表現
- ``<Files``の後にある``~``（チルダ）が正規表現を使いますという意味
- ダブルコーテーション中では拡張子に使う``.``はバックスラッシュ（Windowsなら円マーク）でエスケープしなくてはならない
- ``SetEnvIf``でリファラが""の中にあるものを``mysite``という名前で呼ぶことにする（これなんていうの、エイリアス？環境変数？）。これを``allow from``のところで``env=mysite``と指定する。
- 2つめの``<Files>~</Files>``で例外を作る。この2つの``<Files></Files>``の順番を入れ替えると意図通りに動作しない。

この``.htaccess``を``/wp-content/uploads/``に置けばOK。というわけで参考になればと思って大したことのないTipsですが、書いてみました。.htaccessってたまにしか書かないしね。では！

**追記：** Wordpress管理画面のメディアライブラリから表示させるときにはアクセス制限はかかりません。
**追記2:** root権限を持っているならhttpd.confに書き込んだ方が良い。プラグインやWordpress本体のアップデートで.htaccessが書き換わることがあるようだ。Debianなら/etc/apache2/sites-available/hoge.confなど。書き換えたらApacheは再起動する。
ツイートアプリのDB設計

##はじめに
大苦戦しています。DB設計。
こうして書き起こすことで、自分の頭にも叩き込んでいる状態😅
手を動かせばどうにかなるかなぁと思い、早速やっていきます。

#tweetアプリの DB設計
## usersテーブル
|Column|Type|Options|
|------|----|-------|
|email|string|null: false|
|password|string|null: false|
|nickname|string|null: false|
##### ※email/password/nicknameのそれぞれにNOT NULL制約を指定。【null: false】

### Association
- has_many :tweets
- has_many :comments

##### ※usersテーブルは、tweetsテーブル、commentsテーブルに対して「１対多」なので、has_manyで関連付け。


## tweetsテーブル
|Column|Type|Options|
|------|----|-------|
|image|text||
|text|text||
|user_id|integer|null: false, foreign_key: true|
##### ※image/textは特にOptionが無いので空欄。
##### ※user_idを外部キーとして設定。commentsテーブルからuser_idを参照できるようにする。

###Association
- belongs_to :user
- has_many :comments

##### ※tweetsテーブル⇆usersテーブル = 「多対１」なので【belongs_to】
##### ※tweetsテーブル⇆commentsテーブル = 「１対多」なので【has_many】

## commentsテーブル
|Column|Type|Options|
|------|----|-------|
|text|text|null: false|
|user_id|integer|null: false, foreign_key: true|
|tweet_id|integer|null: false, foreign_key: true|
##### ※textは空欄を許可しない「NOT NULL」を設定。【null: false】
##### ※user_idは「NOT NULL」と外部キー設定。【foreign_key: true】
##### ※tweet_idも同上。

###Association
- belongs_to :tweet
- belongs_to :user

##### ※commentsテーブル⇆tweetテーブル = 「多対１」なので【belongs_to】
##### ※commentsテーブル⇆usersテーブル = 「多対１」なので【belongs_to】


と、こんな感じで仕上がる訳だ。
うんうん、なんとなく頭でつながった感。
AWS　クライアント端末のグローバルIPをセキュリティグループに登録するPSファイル

AWSでシステム構築して運用していく方向けに記事を投稿しようと思います

#### 1.背景
　AWSを運用する際クライアント端末からインターネットを介しSSHする事が多々ありました
その際、インターネット回線はよく使われるであろうフレッツなどの回線を利用していました
インターネット回線は固定IPサービスはDHCPより高価であるためDHCPにしていましたが、時々グローバルIPが変わってしまい、AWSのセキュリティグループを設定し直すのが面倒なので、ツールを作成しました
ツール（PowerShellのファイル）を叩いていただければ、クライアント端末のグローバルIPを自動でAWS上のセキュリティグループに穴あけしてくれる様になっております。

#### 2.前提条件
- クライアント端末にAWSCLIが導入されていること
- クライアント端末にPowerShellが実行できる環境であること
- 「3.PowerShellファイル」で紹介するLIST.txtを「C:\SCRIPT\LIST.txt」に配置していること


#### 3.PowerShellファイル
```ruby:SGset.ps1
#GIP取得
$OldGIP = Get-Content "C:\SCRIPT\LIST.txt"

$TempGIP = (Invoke-WebRequest inet-ip.info/ip).Content
$TempSubnet = "/32"
$NewGIP = ${TempGIP} + ${TempSubnet}

#セキュリティグループに新たに情報登録
aws ec2 authorize-security-group-ingress --group-id sg-XXXXX --protocol tcp --port 22 --cidr ${NewGIP}
#セキュリティグループに古い情報の削除
aws ec2 revoke-security-group-ingress --group-id sg-XXXXX --protocol tcp --port 22 --cidr ${OldGIP}

#今回の情報をLISTファイルに上書き
echo $NewGIP > C:\SCRIPT\LIST.txt
```
※セキュリティグループID「sg-XXXXX」はSSH対象のEC2に付与しているセキュリティグループIDに変更する必要有り
※PowerShellのファイル自体はどこに配置しても問題無いです

```ruby:LIST.txt
8.8.8.8/32
```
※初回は古いセキュリティグループが無いので、GoogleDNSをLISTファイルに記載
※以降は勝手にLISTファイルが更新されます

#### 4.結論
　PowerShellファイル自体はもう少しシンプルにできるかもしれませんが。。
取り合えず投稿第一弾となります。既出でしたら申し訳ございません。
【第1回】pythonで某Authenticator的なツールを作ってみた

2次開発的な。自主学習。
ｇ−−ぇAuthenticator的なものをちょっとpythonで作ってみようと思って
とりあえず、作った。
これまた1回目

次は、ソースに直接、鍵とかユーザー名を入れるんじゃなくて
ちゃんとシステムチックな感じに整えていきます。

```python 
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tkinter as tk
import pyotp


totp = pyotp.TOTP('ZAQWSXCDERFVBGT') #鍵的な値
totp.now()

# tkinterでwindowの作成とタイトルを作る
# windowサイズの指定
root = tk.Tk()
root.title(u"g_authentication_tool")
root.geometry("300x200")

# 表示用ラベル
Static1 = tk.Label(text=u'user1')
Static1.pack(side='left')

Static2 = tk.Label(text=totp.now())
Static2.pack(side='left')

root.mainloop()
```
PEP 585 (Type Hinting Generics In Standard Collections) を読んだよメモ

`__origin__` という属性がどこからやってきたのを調べていたところ、 [PEP 585 -- Type Hinting Generics In Standard Collections](https://www.python.org/dev/peps/pep-0585/) という PEP を見つけたので、本来の目的を忘れて流し読みしてました。まだ Draft ステータスですので、今後採用されるかどうかはわかりませんが、自分の理解をメモに残しておきます。

## 概要

* これまでの型アノテーションでは、コレクションを表現するのに専用の型を使っていた (`typing.List` や `typing.Dict` など)
* コレクションの実装クラスと型クラスを統合し、標準のコレクションクラス(`list` や `dict` など)で型アノテーションできるようにしよう
* いずれ `typing` 配下のジェネリックコレクション型は廃止したい

## 用語

* Generic
    * パラメータ化可能な型。一般的にはコンテナを指す。
    * 別名 parametric type、generic type とも。
    * 例: `dict`
* parametrized generic
    * コンテナ要素の型を指定した Generic のインスタンス
    * 別名 parametrized type とも。
    * 例: `dict[str, int]`


## アプローチ

これまでの `typing.List` や `typing.Dict` の代わりに、 `list` や `dict` を用いる。以上。

```python
def find(haystack: dict[str, list[int]]) -> int:
    ...
```

### やらないこと

* `isinstance(obj, list[int])` には対応しない
* `issubclass(cls, list[str])` にも対応しない

### メモ

内部的には `types.GenericAlias` のインスタンスを作ることを想定している。そのため、 `__origin__` や `__args__` を使って型情報を取り出せる。

```python
StrList = list[str]

assert isinstance(StrList, types.GenericAlias)
assert StrList.__origin__ is list
assert StrList.__args__ is (str,)
```

## 感想

* 普段使うクラスとは別に、アノテーション専用の型があるのはシンプルではないので、これはとてもよさそう (もう慣れてしまったけど)
* typing のジェネリック型が廃止されるとき (5年後ぐらい?) に古いコードで悲鳴が上がりそうでつらい
* Python3 のバージョンが進むにつれて、型アノテーションまわりが Python の言語仕様に強く結びついていくのを感じる。
    * 未だに型チェッカーは外にあるけれど、Python を書くときは形を書くべきという流れになっていきそうな…
    * パフォーマンスやテストで使われ始めるともう止められない予感がする

## 追記

いつのまにか PEP 585 の採用が決まっており(Accepted)、3.9.0a6 で使えるようになっていました。以下、少し前にインストールした 3.9-dev での様子です。

```bash
$ python3.9
Python 3.9.0a6+ (heads/master:7f7e706, May  9 2020, 13:35:20)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> list[int]
list[int]
>>> dict[str, int]
dict[str, int]
>>> tuple[int, ...]
tuple[int, ...]
```
jQueryを使って簡単なカテゴリー 一覧のモーダルを作成する

# はじめに
javaScriptが苦手で仕方ない私が苦しみ紛れにモーダルを作成をした時の記録です。
参考になるかわかりませんが、気休め程度にでもご覧ください
# 経緯
フリマサイトによくあるトップページにあるカテゴリー検索の機能
（こんなやつ↓↓↓）
[![Screenshot from Gyazo](https://gyazo.com/798936a108529ace45c0477d93593d08/raw)](https://gyazo.com/798936a108529ace45c0477d93593d08)

これの担当となった私はjavaScriptがどうしても苦手で実装に詰まってしまった時の話です。
何度トライしても思うように実装できなかった私
（何か他にもっと簡単であっと言わせるような方法はないものだろうか？）
と考え、思いついたのがモーダルの作成でした。
作ってみると意外と評判がよかったので投稿いたします。
# モーダルとは？
ある場所をクリックしたりすると突然出てくる小さなウィンドウのこと。
今回はカテゴリーから探すという部分をクリックすると一覧が表示されるモーダルを作成します。
# 作成手順
①モーダルのビューを作成し、cssで非表示にする。
②click時のイベントを設定する。（今回はカテゴリーから探すの部分）
③clickイベントによりモーダルを表示
④同じくclickイベントによりモーダルを隠すアクションを追加する。
大まかにこんな手順で作成します。
# 完成したモーダル
まず最初に作成したモーダルを載せておきます
[![Screenshot from Gyazo](https://gyazo.com/afc5ca3cb57fa987d77c773d7a60ec19/raw)](https://gyazo.com/afc5ca3cb57fa987d77c773d7a60ec19)
最初に作ろうとしたものからかなり妥協してしまいましたが^^;

・トップページのカテゴリーから探すをクリックすると小さなウィンドウが現れる。
・CLOSEの部分をクリックするとウィンドウが消える。

という単純な機能です。
今回深掘りはしませんが、中のカテゴリーをクリックするとそれぞれのカテゴリー別商品一覧へ遷移するようになっています。
# モーダルの作成
最初にモーダルのビューを作成します。

 ```header.html.haml
.category_modal
  #category-index
    .index-title
      %p.title カテゴリーで検索
      .close-modal
        %p.close CLOSE
      - @parents.each do|parent| ※ancestryでカテゴリーの親・子・孫の関係が出来ていることを前提としています
        .category-list
          = link_to parent.name, category_path(parent.id) , class: "parent_category", id: "#{parent.id}"
      .category-all
        = link_to "カテゴリー 一覧", categorys_path
```
```header.scss
.category_modal {
  background-color: rgba(0, 0, 0, .6);　薄く黒がかった背景
  bottom: 0;
  display: none; ⬅️ここがポイント
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 100;　
```
ここでのポイントはSCSSに記載したdisplay: none;の部分、つまり初期段階では作成したモーダルを非表示にしています。
これを後からjQueryを使って表示させるのです。
# ②Click時のイベント設定
次にイベントの設定を行います。
jsファイルを作成し（ここではmodal.js),イベントの記述を行います。

```modal.js
$(function() {
  $('#category-list').click(function(){
    //カテゴリー一覧をクリック
  });
});
※　＃'category-list'の部分がトップページのカテゴリーから探すの部分についているIDとなります。
```
# ③Clickイベントによるモーダルの表示
カテゴリーから探すをクリックした時に先ほど作成したモーダルを表示させます。
ここではfadeInメソッドを使用します。

```modal.js
$(function() {
  $('#category-list').click(function(){
    $('.category_modal').fadeIn();　⬅️追加
  });
});
```
これで半分完成！！
# ④CLOSEでモーダルを非表示に戻す。
ここで終えてしまうとモーダルが表示されたままの状態になってしまうので、今度はモーダルを非表示にするための設定をします。
やり方は同じですが、モーダルを非表示にするにはfadeOutメソッドを使用します。

```modal.js
$(function() {
  $('#category-list').click(function(){
    $('.category_modal').fadeIn();
  });
  $('.close-modal').click(function(){
   //モーダルのCLOSE部分をクリック
    $('.category_modal').fadeOut();
  });
});
```
これでモーダルの非表示が完了しました！！
あとは細かい部分のSCSSの設定や各種リンクの作成でなんとか切り抜けました。
# 最後に
技術的にはjQueryのfadeInとfadeOutの２つのメソッドを使っただけでしたが、これを見た勉強仲間からは『おっ』という反応が返ってきてちょっと学習コスパの良い実装でした。

将来的に触って楽しいサイトを作成してみたいと思っているのでモーダルの作成は少し面白かったです。
今度は本来の目的物である一覧表示の投稿が出来るように精進してまいりますので応援よろしくお願いいたします。

最後までご覧いただきましてありがとうございました！！
【ruby】『ruby入門(メモ３)』恐竜判定(if ... elseとcase when)

###0．はじめに
今回は判定文(if,when)を勉強する。
参考urlの内容を少しだけアレンジ。
この子からパワーを貰って、勉強を進めている。

![indominus_20200410.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/1fe70c53-2848-b00d-3217-080291075c9a.jpeg)



###1.判定文(if else)

2つの条件について判定して、何かをさせたいとき下記のように記述できる

__　if 条件1__
__　　条件1の時実行する処理__
__　else__
__　　条件1以外の処理__
__　end__

###2.判定文(3つ以上の条件について判定したいとき if elsif else)

3つ以上の条件について判定して、何かをさせたいとき下記のように記述できる

__　if 条件1__
__　　条件1で実行したい処理__
__　elsif 条件2__
__　　条件2で実行したい処理__
__　else__
__　　条件1、2以外の時実行したい処理__
__　end__
 
####複数条件判定(if elsif else)のサンプル
入力した数字で、ヴェロキラプトルかティラノサウルスかotherかを表示するプログラム。

```ruby:if_else.rb
puts '---------which do you choose(104 or 132)----'
# 画面からの入力は、getsで受け取る
speed = gets.to_i
# speedが104のときは
if speed == 104
	puts 'Tyrannosaurus'
# speedが132のときは
elsif speed == 132
	puts 'Velociraptor'
# speedが132でも104でもないときは
else
	puts 'other dinosor'
end
```
#####★実行結果

```
c:\ruby_pg>ruby if_else.rb
---------which do you choose(104 or 132)----
132
Velociraptor
```

###3.判定文3つ以上の条件について判定したいとき(case when else)

3つ以上の状態を持つものについて判定したいとき、
if elsif elseを使うより下記のようにcase whenを使うと効率のいい場合がある。


__　case 判定対象__
__　when 条件1__
__　　条件1でき実行したい処理__
__　when 条件2__
__　　条件2で実行したい処理__
__　　...__
__　else__
__　　いずれの条件にも該当しない時にで実行したい処理__
__　end__



__★★好きな恐竜を表す番号を入力すると、その恐竜名を表示するサンプルプログラム__

```ruby:if_else.rb
#略
puts "\n"
puts '-------what dinosor do you like? --------'
puts 'input 1 if you like Tyrannosaurus --------'
puts 'input 2 if you like Velociraptor --------'
puts 'input 3 if you like Stegosaurus --------'
puts 'input 4 if you like Triceratops --------'
puts 'input 5 if you like Brachiosaurus --------'

# 画面からの入力は、getsで受け取る
dino_no = gets.to_i
#dino_noの場合分け
case dino_no
#1の場合
when 1
	puts 'you like Tyrannosaurus'
#2の場合
when 2
	puts 'you like Velociraptor'
#3の場合
when 3
	puts 'you like Stegosaurus'
#4の場合
when 4
	puts 'you like Triceratops'
#5の場合
when 5
	puts 'you like Brachiosaurus'
#他の場合
else
	puts 'you like ???'
end
```

###実行結果
```
c:\ruby_pg>ruby if_else.rb

-------what dinosor do you like? --------
input 1 if you like Tyrannosaurus --------
input 2 if you like Velociraptor --------
input 3 if you like Stegosaurus --------
input 4 if you like Triceratops --------
input 5 if you like Brachiosaurus --------
3
you like Stegosaurus
```

###参考url
[dotinstall(ruby入門)](https://dotinstall.com/lessons/basic_ruby_v3)
Dockerでdebファイルのビルドをする

3つのファイルを使います

```build.sh
#!/bin/bash
set -e
if [[ $UID == 0 ]]; then
    echo "You must not run this as root." 1>&2
    exit 1
fi

if !(type docker >/dev/null); then
    echo "Docker is not installing on this machine." 1>&2
    exit 1
fi

# dockerコンテナビルド前に行う処理はここから
WORKDIR=$(cd $(dirname $0); pwd)
NAME=base-files-11ubuntu4
#ここまでの間に記述する

# イメージ名build_debはビルドするdebファイルによって書き換える
# 例: build_base-files
sudo docker build -t build_deb ${WORKDIR}
sudo docker run -e NAME=${NAME} -e UGID="${UID}:$(id -u)" -v ${WORKDIR}/out:/deb -it build_deb
```

Dockerfile

```Dockerfile
FROM ubuntu:20.04
ARG NAME="base-files-11ubuntu4"
#ビルド対象のディレクトリ名を記述
ARG UID=65587
#コンフリクトしないように大きい値で
RUN sed -i"" -e 's%http://[^ ]\+%mirror://mirrors.ubuntu.com/mirrors.txt%g' /etc/apt/sources.list \
&& apt-get update \
&& apt-get -y upgrade \
&& apt-get install -y --no-install-recommends build-essential devscripts zstd gawk libc6 libcrypt1 debhelper dh-systemd apt-utils sudo \
&& rm -rf /tmp/* /var/tmp/* \
&& apt-get clean
# 依存関係をインストールする

RUN echo "root:root" | chpasswd && \
    adduser --disabled-password --uid ${UID} --gecos "" docker && \
    echo "docker:docker" | chpasswd && \
    echo "%docker    ALL=(ALL)   NOPASSWD:    ALL" >> /etc/sudoers.d/docker && \
    chmod 0440 /etc/sudoers.d/docker
#sudoがパスワード入力無しで使えるユーザの作成

RUN mkdir -p /debuild/build /deb 
ADD ./${NAME} /debuild/build/${NAME}
ADD ./debuild.sh /debuild/debuild.sh
RUN chmod +x /debuild/debuild.sh \
&& chown -R docker:docker /debuild
USER ${UID}
WORKDIR /debuild
CMD ["./debuild.sh"]
```

``` debuild.sh
#!/bin/bash -e
if [ $UID != 65587 ]; then
    echo "You have to run this on Docker" 1>&2
    exit 1
fi
#Dockerコンテナ以外で実行されることを抑制

export EDITOR=vim
cd /debuild/build/$NAME

#ビルド前の処理を記述

debuild -us -uc
#ビルド

cd ..
tar cf ${BASE_FILES}serene${VERSION:5}.tar \
base-files-dbgsym_${BASE_FILES:11}serene${VERSION:5}_amd64.ddeb \
base-files_${BASE_FILES:11}serene${VERSION:5}.dsc \
base-files_${BASE_FILES:11}serene${VERSION:5}_amd64.build \
base-files_${BASE_FILES:11}serene${VERSION:5}_amd64.buildinfo \
base-files_${BASE_FILES:11}serene${VERSION:5}_amd64.changes \
base-files_${BASE_FILES:11}serene${VERSION:5}_amd64.deb \
lsb-release-udeb_${BASE_FILES:11}serene${VERSION:5}_all.udeb
zstd ${BASE_FILES}serene${VERSION:5}.tar
sudo mv -f *.xz /deb 2>/dev/null
sudo mv -f *.zst /deb 2>/dev/null
sudo chown -R ${H_UGID} /deb 2>/dev/null
#ビルドしたものをtar.zstに圧縮、ソースパッケージと共にホストとの共有ディレクトリへ
```
JavaScriptのNumber() 関数で文字列やnullを数値に変換した結果

## JavaScriptのNumber() 関数とは
プリミティブ型オブジェクトのNumberを生成する

## 変換した結果
```js
console.log(Number('123'))       // 123
console.log(Number('12.3'))      // 12.3
console.log(Number('12.00'))     // 12
console.log(Number('123e-1'))    // 12.3
console.log(Number(''))          // 0
console.log(Number(null))        // 0
console.log(Number('0x11'))      // 17
console.log(Number('0b11'))      // 3
console.log(Number('0o11'))      // 9
console.log(Number('foo'))       // NaN
console.log(Number('100a'))      // NaN
console.log(Number('-Infinity')) //-Infinity
console.log(Number(undefined))   // NaN
```

### NaN（Not a Number）について
NaNは数値ではないことを示します。

### 注意点
Number('')やNumber(null)は、<b>NaNではなく0を返す</b>ので注意が必要です。 
ただNumber(undefined)はNaNを返します。 
私は一度ハマりました…。

## 参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number

http://e-words.jp/w/NaN.html
Dockerの始め方

# はじめに

ここでは、Dockerの利用を始めるにあたり必要になるユーザー登録やインストール方法について解説します。


# DockerHubへの登録

まず、[DockerHub公式ページ](https://hub.docker.com/)にアクセスします。
ユーザーIDやメールアドレスなどを入力してユーザー登録します。

![dockerhub_top.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/34078f82-1d5f-2716-7380-68d4b1648d56.png)

無料のCommunityプランを選択します。

![dockerhub_plans.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/11c4ff8a-add9-1954-865b-5135482744c0.png)


# Dockerのインストール

Dockerデスクトップ版をダウンロードしてインストールします。

![docker_download.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517951/1d8dc0d6-9ac9-e445-9028-21a76ba5895f.png)


# まとめ

ここでは、Dockerの利用を開始するにあたって必要な初期設定について解説しました。
以上の設定が終われば、Dockerコンテナを利用できるようになります。
コマンドプロンプト起動時にマクロを読み込んでもらう

個人的な備忘録として残しておく
#はじめに
今までコマンドプロンプト上でもlsコマンドを使っていたが、当然だが別のＰＣだと使えなかった。
そういえばdoskeyを使って
```doskey ls=dir```
とかで設定したような気がするなと思って試したが、当然だがプロンプトを閉じるとリセットされる。
起動すると自動でマクロを読み込んでくれる方法はないかと探して、できるようになったので手順を描いておく。

以前こんなことをやらずにマクロを設定した気がするので、もっと簡単な方法があるはずだがどうにも思い出せなかった・・・

####1.コマンドプロンプトにもbashrcのようなものがあるらしい


なぜかコマンドプロンプトには同じような機能はないと思っていたが、あったらしい。

コマンドプロンプト上で
```cmd /?```
を実行すると、
![コメント 2020-04-11 101814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617466/3fd97fec-3687-8235-19ca-24e846b58faa.png)
と書いてあった。
これをいじればなんとかなるっぽい。

####2.レジストリエディタでレジストリ変数を編集する
windowsキー＋Ｒで、ファイル名を指定して実行を開いて、```regedit```と入力する。

![コメント 2020-04-11 102327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617466/105fc701-8047-40a3-65da-545e4338d7f5.png)

これでレジストリエディタが開かれるので、先ほどコマンドプロンプト上で見たパスを探す。
二つ提示されるうち（おそらく）どちらでもいいので、今回は```HKEY_LOCAL_MACHINE\~~~```の方を編集する。

![コメント 2020-04-11 102801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617466/d8d505ce-98b1-bd4f-fa23-f391be72c02e.png)

多分規定だとこんな感じになっていると思うので、ここに右クリックで新規追加する。
名前は```AutoRun```で、文字列値 or 展開可能な文字列値で設定する。

後はこの追加したAutoRunに右クリック⇒修正を選択し、値のデータにコマンドを書けばコマンドプロンプトを起動したときに実行してくれる。

今回はマクロが目的なので、マクロを記述する。

![コメント 2020-04-11 103610.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617466/8602f1cd-5c2a-50d4-e103-708d4406a84c.png)

これで起動するたびにdoskeyしなくてもlsがコマンドプロンプトで使えるようになった。実態はdirだけど。

ちなみに、当然だが、一個のマクロを設定する代わりにマクロを記述したファイルを用意して、
```doskey /macrofile=マクロを記述したファイルのパス```
とするのも有効。

おしまい
【rails】production環境でバッチ処理の環境読み込みがdevelopmentになってしまうときの対処法

#実行環境
AWS EC2+RDS
Rails 5.2.4.2
Ruby 2.7

#経緯
自動でメール送るバッチ処理を本番環境で行うために、
rakeファイルにタスクを書いた状態で

`$ bundle exec whenever RAILS_ENV=production`
（自動化の設定ファイルの実行コマンド）
を実行し、

`$ bundle exec whenever --update-crontab RAILS_ENV=production`
（crontabへの書き込みコマンド）
を実行しました。

その後、タスクの挙動を
`$ tail -f log/cron.log`で見てみると
エラーが発生していた。

#エラー内容
rake aborted!
ActiveRecord::StatementInvalid: Could not find table 'テーブル名'

#原因
`$ bundle exec whenever RAILS_ENV=production`
実行後のターミナルでの表示が以下のようになっていました。

```
* * * * /bin/bash -l -c 'cd /home/ec2-user/アプリ名 && RAILS_ENV=development bundle exec rake ファイル名:タスク名 --silent >> /home/ec2-user/アプリ名/log/cron.log 2>&1'
```

RAILS_ENV=developmentになっています。
こちらが原因です。

schedule.rbでの環境指定は以下のようにしており、問題ないはずでした。

```config/schedule.rb
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env
```
本番環境のコンソール上でもENV['RAILS_ENV']をいれると"production"と返ってきていました。


ですが、
以下のように、RAILS_ENVの中に何が入っているか確認すると・・・・・・
何も入ってませんでした！

```
$ env | grep RAILS
RAILS_ENV=
```

#解決策

以下のコマンドを実行

```
$ export RAILS_ENV=production
```

すると

```
$ env | grep RAILS
RAILS_ENV=production
```

RAILS_ENVにproductionが入りました。


そしてもう一度`$ bundle exec whenever RAILS_ENV=production`
を実行すると

```
$ bundle exec whenever RAILS_ENV=production

* * * * * /bin/bash -l -c 'cd /home/ec2-user/relearn && RAILS_ENV=production bundle exec rake ファイル名:タスク名 --silent >> /home/ec2-user/アプリ名/log/cron.log 2>&1'
```

RAILS_ENV=productionに変わっています。
これで問題なく動作しました。

#まとめ
・production環境で動いているように見えても、実際にgrepメソッドで確認してみるとdevelopment環境であることがある。
・デプロイしようとすると必然的に開発環境と本番環境の違いでメソッドや各機能に不具合が起きやすいので、修復には理解度の高い状態での実装が必須になる。
・Linuxコマンド少しだけでも使い慣れておいた方が良い。

##参考
・https://opiyotan.hatenablog.com/entry/rails-whenever
・https://pikawaka.com/rails/env
Nuxtでページ遷移のアニメーション

ハマったのでφ(..)メモメモ
# 環境
* nuxt2.12
* Composition Api
* vuetify
* typescript

# ハマった内容
レイアウトが変わった際にsetupが2度実行される

## 間違ったコード
```vue:layout/default.vue
...
<v-slide-x-transition>
  <nuxt />
</v-slide-x-transition>
...
```
```vue:layout/layout2.vue
...
<v-slide-x-transition>
  <nuxt />
</v-slide-x-transition>
...
```
この状態で別で用意したlayoutに変えた時に2度setupが実行されました。

```vue:pages/index.vue
<template>
  <v-btn to="/nextpage"></v-btn>
</template>

<script lang="ts">
import { defineComponent } from "@vue/composition-api";
export default defineComponent({
  name: "index",
  layout: "default",
  setup(){
    // setup code...
  }
});
</script>

```

```vue:pages/nextpage.vue
<template>
  <v-btn to="/nextpage"></v-btn>
</template>

<script lang="ts">
import { defineComponent } from "@vue/composition-api";
export default defineComponent({
  name: "nextpage",
  layout: "layout2",
  setup(){
    console.log("2回実行される！！");
  }
});
</script>

```

# 正しいお作法
ちゃんとドキュメントに書いてました。
[API: transition プロパティ](https://ja.nuxtjs.org/api/configuration-transition/)

## レイアウトファイルを元にに戻す
```vue:layout/default.vue
...
  <nuxt /> // ここにtransition groupを書くのは間違い
...
```
```vue:layout/layout2.vue
...
  <nuxt />　// ここにtransition groupを書くのは間違い
...
```
## nuxt.configファイルを修正
```typescript:nuxt.config.ts
import { Configuration } from "@nuxt/types";

const config: Configuration = {
...
  transition: {
    name: "slide-x-transition",
    mode: "out-in",
    duration: 300
  },
  layoutTransition: {
    name: "fade-transition",
    mode: "out-in",
    duration: 300
  },
...
}
export default config;
```
思い通りの動きになりました！
#### 追記
```
 WARN  transition property is deprecated in favor of pageTransition and will be removed in Nuxt 3                                                                                              01:52:16
```
Nuxt3からpageTransitionにしないといけないようです。


# ~~transition~~ pageTransitionとlayoutTransitionの違い
transitionは同じレイアウト間でページの移動が発生した時に発火します。
layoutTransitionは違うレイアウトに移動したときに発火します。

# 結論
ちゃんと公式ドキュメントに目を通しましょう。orz...
Djangoでテストのカバレッジを取得する

弊社で開発しているDjangoアプリケーションのテストのカバレッジを取得したくなったので、Coverage.pyを利用してカバレッジを取得します。

まずはCoverage.pyをpipenvでインストールします。

```
$ pipenv install -d coverage
```

インストールできたら、pipenv shellで仮想環境を起動し、以下のコマンドでプロジェクト全体でテストを実行します。テストが完了すると、簡易的にテストを結果を表示します。

```
$ coverage run --source='.' manage.py test
Creating test database for alias 'default'...
Ran 40 tests in 7.188s

OK
```

以下のコマンドでカバレッジを表示できます。

```
$ coverage report
Name                                                    Stmts   Miss  Cover
---------------------------------------------------------------------------
config/settings.py                                         48      0   100%
config/urls.py                                              7      0   100%
config/wsgi.py                                              4      4     0%
core/admin.py                                             216     15    93%
core/api.py                                              1240    840    32%
core/apps.py                                                3      3     0%
core/helpers.py                                            89     72    19%
core/models.py                                           1079    290    73%
core/serializers.py                                       227      3    99%
core/urls.py                                               43      0   100%
core/views.py                                             156    116    26%
core/visualize.py                                         267    267     0%
・・・（以下略）・・・
---------------------------------------------------------------------------
TOTAL                                                   11170   8081    28%

```

カバレッジを取得する範囲をコマンドのオプションで指定することができますが、コマンドを実行するたびに指定するのが面倒くさいので、.coveragercを定義して、コマンドのオプションを省略できるようにします。

```:.coveragerc
[run]
omit =
    */tests/*
    */migrations/*
    */__init__.py
    .venv/*


[report]
omit =
    */tests/*
    */migrations/*
    */__init__.py
    .venv/*


[html]
directory = cover
```

最後に以下のコマンドで上記のカバレッジをHTMLファイルとして出力することもできます。

```
$ coverage html

## テストの実行からHTMLファイルの出力までワンライナー実行
$ coverage run --source='.' manage.py test && coverage report && coverage html
```
CSSではじめ数秒点滅させ、後は通常表示させたいです。

お世話になります。

下記コードのように点滅させようとしているのですが、点滅した後にすぐ消えてしまいます。
この点滅設定の後に表示させるようにするにはどのように処理をしたら良いでしょうか？



```html
<div class="light_box"></div>
```

```css

//widthとheightは別途つけてあります

.light_box{
  opacity: 0;
  animation: flash 0.2s 3 linear;
}

@keyframes flash {
  50% {
      opacity: 1;
  }
}
```

点滅後の処理について、調べても見つからずご教示頂けると幸いです。
お手数ですがよろしくお願いいたします。
Colab TPUでもtensorflow.kerasでBilinear法のアップサンプリングを行う方法

#前置き
Google Colaboratoryでは、無料でクッソ早いプロセッサであるTPUを使って機械学習ができます。（Google ColaboratoryのTPUについて、詳しくは「[Google ColaboratoryのTPUを試してみる](https://qiita.com/koshian2/items/25a6341c035e8a260a01)」という記事を見ればわかりやすいです。）
しかしTPUには制限があり、使える関数が限られています。例えば`keras.layers`の`Upsampling2D`はTPUでは使用ません。（対処法に関しては「[TPUでアップサンプリングする際にエラーを出さない方法](https://blog.shikoan.com/tpu-upsampling/)」が詳しいです。）
TPUで使える関数についての詳細は「[利用可能な TensorFlow オペレーション](https://cloud.google.com/tpu/docs/tensorflow-ops?hl=ja)」で分かるのですが内容がtensorflow 2.xに対応してないので、tensorflow 2.xの`tf.image.resize`でBilinear法のアップサンプリングをしたら予期せぬエラーや動作にハマって地獄を見ることになるかもしれないのです。
そこで今回はtensorflow 2.xでもBilinear法のアップサンプリングができる方法を記したいと思います。

#実装
tensorflow 2.xでもtensorflow 1.xの関数を使うには`tf.compat.v1`から目的の関数を呼び出せばいいので自ら実装はしません。（下手に実装したら遅くなるだろうし...）
TPUに対応していることが判明しているtensorflow 1.xのBilinear法のアップサンプリングの関数は、`tf.image.resize_bilinear`で、変数を`align_corners=True`にしたときのみ対応しています。
よって、`tf.compat.v1.image.resize_bilinear`を使います。
この関数をkerasのレイヤーにすると以下のようになります。

```python
from tensorflow.keras.layers import *

# Lambdaレイヤーを使う
def upsampling_tpu_bilinear(x, scale=2):
    w = x.shape[1]*scale; h = x.shape[2]*scale
    tf.compat.v1.image.resize_bilinear(x, (w, h), align_corners=True)

Lambda(upsampling_tpu_bilinear, arguments={'scale': 2})(inputs)
```

#最後に
これでTPUでもBilinear法のアップサンプリングができます。
「[モザイク除去から学ぶ　最先端のディープラーニング](https://qiita.com/koshian2/items/aefbe4b26a7a235b5a5e)」という本（めちゃくちゃオススメです！）でも解説されていますが、Nearest Neighbor法でアップサンプリングされた画像は「おかしな」画像なので、GANのような繊細なネットワークではBilinear法のアップサンプリングも効果的かもしれませんね。
webページHTMLから簡単に配列は作れないものか？というあなた

##はじめに
こんにちは初めてキータ記事を投稿するものです。誤字脱字には目をつぶっていただけたら嬉しいです。
私が最近通っている某プログラミングスクールで習ったancestryジェムを個人アプリで使ってみようかなと思ったのですが、欲しいデータを様々なワードでググってみても出てこない（当然ですが）、そこで置換機能を使ってwebページからデータを整形して使ってしまおうということでいろいろ勉強したことを記事にしようと思います。




#webページからデータを所得して配列を作る
私の場合は業界のカテゴリーを作りたかったので業界動向serch.comさんを参照させてもらいました（https://gyokai-search.com/2nd-genre.htm）


<img width="732" alt="2fb4da334f942a3b460f3a34daad80fd.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413517/8b61a648-f5ff-0703-ad92-fae1b649b08a.png">

まずはコピーアンドペーストしてください

```ruby
 
金融
金融
銀行
証券
ネット証券
商品先物
生命保険
損害保険
消費者金融
クレジットカード
リース
建設・不動産
建設
不動産
マンション
マンション管理
住宅
住宅設備
電気通信工事
土木
建設コンサル
ビル管理
高速道路
駐車場
物流・運送
運送
航空
鉄道
海運
倉庫・運輸
IT・メディア
通信
ＩＴ
ソフトウェア
インターネット
モバイル
携帯電話
携帯電話販売
ネット広告
テレビ
広告
出版
新聞
印刷
エネルギー・資源
石油
電力
ガス
化学
塗料
繊維
鉄鋼
非鉄金属
電線
金属製品
ガラス
土石製品
製紙
ゴム・タイヤ
自動車・機械
自動車
自動車部品
トラック
二輪車・バイク
中古車
機械
造船重機
プラント
建設機械
工作機械
パチンコ（製造）
電機・精密
家電
電気機器
重電
電子部品
精密機器
医療機器
カメラ
時計
OA機器
半導体
食品
食品
食肉
冷凍食品
パン
製粉
菓子
ビール
清涼飲料
水産・農林
飼料
小売・卸
小売
卸売
総合商社
専門商社
百貨店
スーパー
コンビニ
ドラッグストア
家電量販店
ホームセンター
ディスカウント
100円ショップ
書店
スポーツ用品店
リサイクル
カー用品店
生活関連
トイレタリー
製薬
インテリア
通販
文具
雑貨
スポーツ用品
衣料・装飾
化粧品
アパレル
靴
メガネ
ジュエリー
サービス
サービス
人材派遣
教育
介護
警備
冠婚葬祭
ブライダル
葬儀
コンサルティング
飲食
飲食
カフェ
ファミレス
ファーストフード
寿司
居酒屋
中食
娯楽・レジャー
旅行
ホテル
レジャー施設
スポーツクラブ
ゴルフ場
カラオケ
映画
玩具
ゲーム
```
当然っちゃ当然なのですが膨大な量です（世の中には色んな仕事がある）

そしてそしてこれをエディタに元々備わっている置換機能で配列にしていきます（マックの方はcommand + F)

この置換機能は検索機能だけでなく正規表現にも適応しているらしく、さらに知識のある方ならコードのスペルミスや同じクラス名を一気に別のクラス名に変換するなんてこともできるみたいですね（めちゃ便利）

<img width="1100" alt="3cae0343a455373f00f7164914b69026.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413517/3b010736-60ea-f854-2fa8-3125d0a41798.png">

上の空欄に検索したい文字を入れて下の空欄に変換したい文字を入力すればいいです。今回の場合は
１、　先頭を意味する^ と入力して'を記入
２、　文末を意味する$　と入力して'を記入で変換
<img width="1125" alt="8cdb239cd8c309be84f4cac66a53ec82.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413517/02911a91-9469-9ce8-7901-3ac31245c6b2.png">
いい感じですね
それでは最後に配列の[]をそれぞれつけていかなといけないんですが一列にするために最後の変換を行います
改行を意味する？\nを ,に変換
<img width="1126" alt="6d96544cf82a64bf23dbe1c89131f8c4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413517/3f3e3e38-c8f7-961a-c2b9-228a67f39f16.png">

はいこれで後は[]で挟んで終わりです。

##終わり
ホントはもっと専門的な記事を書けたらいいんですがまだまだ勉強中の無職なので現状これくらいが限界ですorz
今後より質の高い記事を書いていきたいと思います！

参考記事（正直この記事を見た方が参考になるかもです）
https://qiita.com/haruki1277/items/e17f6fc7072389f0f6e3
【Unity初心者】テキストや画像などUIの移動方法　RectTransform

#環境
Unity 2019.3.7f1

#移動方法
ゲームオブジェクトなどはTransformコンポーネントをもっており、
この数値をスクリプトからいじることで移動できます。
一方、テキストなどのUIはTramsformコンポーネントではなく、RectTransformコンポーネントを持っています。
したがって**RectTransformコンポーネントの値をいじる**ことで移動させることができます。


#具体例
実際にテキストオブジェクトを動かしてみましょう。

###前提の作業内容
1.新規スクリプト作成(スクリプト名は"Test"にした)
2.テキストオブジェクト作成
3.空のオブジェクト作成
4.新規スクリプトを空のオブジェクトにドラッグ＆ドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/c51b5c99-a125-a9d0-8399-3be3b9ae8390.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/7cda7802-2db7-62ac-800d-d85945211165.png)



####　スクリプト名"Test"の中身は次のように書く

```CSharp:Test
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//スクリプトでUI(テキストなど)扱うときはこれ必須！！

public class test : MonoBehaviour
{    
    public RectTransform a;//RectTransform型の変数aを宣言　作成したテキストオブジェクトをアタッチしておく
   
    //スタート関数
    void Start()
    {        
    }

    //アップデート関数
    void Update()
    {
        a.position += new Vector3(0.1f, 0, 0);//毎フレームx座標を0.1ずつプラス        
    }
}

```


スクリプトを書いてスクリプトセーブ後、空のオブジェクトのインスペクターはこのようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/10855698-de38-ab13-5d35-4e0b8908d01a.png)

この赤丸部に、あらかじめ作成したテキストオブジェクトをアタッチする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/791d1e0c-a092-dd1b-fd80-cf9459186326.png)
こうすることでテキストのRectTransformコンポーネントの数値をいじれるようになる。

あとは実行するとテキストが動きます。
Manjaro Linuxに変える備忘録

家のパソコンをWindows10からManjaro Linuxに変えることにした。

話は脱線するかもしれないが、家のパソコンはゲーム機を兼ねているためWindowsにしていたが、面白いプロジェクトがあったので、貢献ついでに変えたいと思う

[ValveがWindowsゲームをLinuxで動かす互換レイヤー「Proton」を発表 | SlackNote](https://slacknotebook.com/valve-releases-compatibility-layer-for-linux-proton/)

# USBに書き込む


isoをダウンロードして、USBに書き込む。

isoはここ[Manjaro - Downloads](https://manjaro.org/download/)

書き込みにはbalenaEtherを使う。

[balenaEtcher - Flash OS images to SD cards & USB drives](https://www.balena.io/etcher/)

はちゃめちゃにUIが良いので多分みれば操作できる。

書き込んだら再起動してF12とかを連打してUEFIに入り、Boot Priorityの順番を変え、USBが一番最初に読み込まれるようにする。

で、起動されたらタイムゾーンをAsia/Tokyo,言語を日本に、キーボード配列はUSのまま(Majestouch MINLAユーザなので)

で、Boot:って書いてあるところをエンターでライブ環境に移る。

ライブ環境の左下辺りにあるところからインストール。

# 諸々

- システムアップデート

`$ sudo pacman -Syu`

- yayを入れる

超ざっくりな理解だが、AUR(Arch User Repository)を入れるのを楽にしてくれるツール。

```
$ git clone https://aur.archlinux.org/yay
$ cd yay && makepkg -si --noconfirm && cd .. && rm -rf yay
```

- Chromeを入れる

yayを入れてるとかなり楽

```
$ yay -S google-chrome
```

- 日本語入力できるようにする。

公式の情報は古くて一部使えないみたいなので注意

[日本語の設定 - Manjaro Linux](https://wiki.manjaro.org/index.php?title=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E8%A8%AD%E5%AE%9A)

ここの**Fcitx-Mozcのインストールと設定**をおっかけた。

でも一部だけ違いある。

```
旧

$ sudo pacman -S fcitx-mozc fcitx-gtk2 fcitx-gtk3 fcitx-qt4

新(こちらを利用してください)

$ sudo pacman -S fcitx-mozc fcitx-gtk2 fcitx-gtk3 fcitx-qt5
```

あとは公式通りにおっかければ良し。

ちなみに実際どうやって切り替えすんねん！USキーボードだし・・・って気持ちになっていたら、**Ctrl+Space**で切り替えが出来た。

とりあえずこれでやりたいことはできるようになったのでそろそろ筆を置く。

なにかインストールしたいときはAURにあるかどうか見に行ったほうが良さそうなのでそこだけ覚えるようにしたい。


# 参考
- [「Manjaro Linuxに変える」を編集 - Qiita](https://qiita.com/drafts/3eee23163d63dac88acf/edit)
- [Arch Linux に yay をインストール - Qiita](https://qiita.com/ekzemplaro/items/6714469c1fb1ae06b80f)
- [Manjaroのインストール - Qiita](https://qiita.com/Yooooo/items/29ca36af5dcafb4db4ce)
- [yayの導入 - Qiita](https://qiita.com/yamad_linuxer/items/11f114a22f73e3aab502)
dockerのコンテナの中に入る

#概要
webアプリケーションを勉強中で、dockerが良いということを知ったので、古いパソコンにUbuntuを入れて色々調べながら、何とか環境を構築したのですが、いざ動かそうとしたときに`rails`コマンドとかが実行できず、そこら辺を理解するのに時間がかかったので、まとめました。

#実行できなかった理由
当たり前なんですが、railsの実行環境はコンテナの中にあるので、コンテナに入る必要がありました。
そして、その方法を色々調べた結果、2つの方法があることが分かりました。

#dockerコマンド
```
docker container exec -it コンテナ名 bash
```
コンテナ名は

```
docker-compose ps
```

で見ることができます。また、

```
docker container ps
```
より得られるコンテナIDを入力してもいけました。

#docker-composeコマンド
```
docker-compose exec サービス名 bash
```
ここでのコンテナ名は`docker-compose.yml`で入力したサービス名となっています。

#補足
`exec`コマンドは、起動中のコンテナ内で、指定したコマンドを実行するコマンドで、`bash`や`sh`を実行することで、コンテナ環境とカーネル等をつなげてくれます。
このとき、`docker container exec`の方は端末の起動オプション`t`と標準入力を開き続けるオプション`i`を指定する必要があります。
`docker-compose exec`の方はデフォルトで端末が割り与えられるようになっているみたいなので、オプションをはいらないです。
コンテナ内のコマンドを1回だけ実行したい場合は、`bash`を`rails -v`などに書き換えればOKです。

#参考
[docker-compose exec](https://matsuand.github.io/docs.docker.jp.onthefly/compose/reference/exec/)
[【初心者向け】シェル・ターミナル・コンソールの違いとは？](https://eng-entrance.com/linux-basic-shell-terminal-console)
[docker runとdocker execの違いの解説](https://www.memotansu.jp/docker/852/)
PythonでMongoのデータを簡易検索

##PythonでMongoのデータを簡易検索
本当は別のことをしていたのですが、どうしても気になり、脱線して作ってみました。
海外ドラマ（NCIS）が好きで良く見ているのですが、
データベースの検索シーンで、「xxx : zzzz」と入力していたような気がします。
ちょうど、JSONやMongoDBをpythonで扱っていたので、あれ？JSONの形に似てる？？と思い、MongoDBのデータを対象とした超簡単な検索用部品を作ってみました。
単にpymongoのfilterの引数に正規表現を使っただけのものです。
本当はもっと簡単で美しい書き方があると思います。

```python:findstring.py
import pymongo

# MongoDB接続情報
client = pymongo.MongoClient('localhost', 27017)
db = client[#db名]
co = db[#コレクション名]

# 検索情報の生成　printやinputは動作検証用です。
print("検索のためのkeyとvalueを入力してください")
print("key:valueの形 例 remarks:12時 ")
str_f0=input()
str_f1=str_f0.split(":")[0]
str_f2=str_f0.split(":")[1]

# 検索
data = [d for d in co.find(filter={str_f1:{'$regex':str_f2}})]
for d in data:
    print(d[str_f1].splitlines())
```
エラー処理、大文字・小文字への対応、複数の検索語への対応などの機能はありませんが、たぶんすぐに忘れてしまうので、今後の肥やしとして投稿させていただきます。
高卒技能員の「皆さん初めまして」

自己紹介です。

よくQiitaで啓蒙高い・勤勉な皆様を拝見して、「ほぇぇ、、」と興奮と感銘を受けながら日々学ばせて頂いてる私こと、かんくろうです。


不躾ながら、この度リマインド、思いついたことのアウトプット目的で今後投稿していきます。


内容としては
Python
MySQL
統計学
機械学習
深層学習
などなどです。


表題にある様、場違い感が漂いますが、だからこそ、誰でも理解できる記事を目指して、私でも理解できた方法、考え方を想うがまま書き殴れたらと思います

どうぞよしなに
JavaScriptの日付計算は月末考慮しないとハマる

JavaScriptでn年後の同月の月末を求める処理が必要になり、`Date`オブジェクトを使って日付の加減算を行ったのだが、思わぬ罠が潜んでいたので共有することにした。

# Dateオブジェクトで日付の加減算
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date

`Date`オブジェクトには`getMonth`や`setMonth`など、年月日の数字を取得／設定できるメソッドが用意されているため、これを使うのが一般的だろう。

```js
var date = new Date("2020/4/11");
date.setMonth(date.getMonth() + 1);
console.log(date.toLocaleDateString()); // 2020/5/11
date.setFullYear(date.getFullYear() - 2);
console.log(date.toLocaleDateString()); // 2018/5/11
```

# 月末を求める場合は`setDate(0)`
月末を求める場合は、`Date`オブジェクトを求めたい月の翌月に設定し、`setDate(0)`を実行する。

>- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate
    - 例えば、dayValue に 0 を与えた場合、日付は前月の最終日に設定されます。

```js
var date = new Date("2020/4/11");
date.setMonth(date.getMonth() + 1);
date.setDate(0);
console.log(date.toLocaleDateString()); // 2020/4/30
```

# 月末を考慮していないとハマる罠
たとえば、2020/1/31を基準に、Nヶ月後の月末日を求めたい時は以下のようにするだろう。

```js
var date = new Date("2020/1/31");
var n = 1; //翌月の月末日(2020/2/29)を求めるために1を設定
date.setMonth(date.getMonth() + n + 1); // 2020/3/31 に設定する
date.setDate(0);
console.log(date.toLocaleDateString()); // 2020/2/29 になる
```

ところが、これを以下のように月計算を分割すると正しい結果が得られない。

```js
var date = new Date("2020/1/31");
var n = 1; //翌月の月末日(2020/2/29)を求めるために1を設定
date.setMonth(date.getMonth() + n);  // 2020/3/2に設定されてしまう
date.setMonth(date.getMonth() + 1);  // 2020/4/2に設定されてしまう
date.setDate(0);
console.log(date.toLocaleDateString()); // 2020/3/31 になってしまう
```

しかも、この現象は基準日が2020/1/29以前であれば発生しないという厄介なものだ。

# 月末への対策
**加減算を行う前に**日付を1日に設定するのが簡単だろう。

```js
var date = new Date("2020/1/31");
date.setDate(1); // 2020/1/1に設定する
date.setMonth(date.getMonth() + 1);  // 2020/2/1に設定される
date.setMonth(date.getMonth() + 1);  // 2020/3/1に設定される
date.setDate(0);
console.log(date.toLocaleDateString()); // 2020/2/29 になってくれる
```

# さいごに
まとめてみると簡単なことだが、コードレビューでこれを発見するのは困難ではなかろうか。
特に、日付演算を不用意に関数化して分割しているとなおさらだろう。

テスト工程で見つける前提とするなら、観点として月末という**境界値チェック**が必要となることは覚えておきたい。
ABC備忘録[ABC160 C - Traveling Salesman around Lake] (Python)

>#問題文
1周$K$メートルの円形の湖があり、その周りに$N$軒の家があります。
$i$番目の家は、湖の北端から時計回りに$A_i$メートルの位置にあります。
家の間の移動は、湖の周りに沿ってのみ行えます。
いずれかの家から出発してN軒すべての家を訪ねるための最短移動距離を求めてください。
#制約
$2≤K≤10^6$
$2≤N≤2×10^5$
$0≤A_1<...<A_N<K$
入力中のすべての値は整数である。

[C - Traveling Salesman around Lake](https://atcoder.jp/contests/abc160/tasks/abc160_c)


#解法
家は円周上に並んでいると考えることができるので、隣り合う家同士の距離をそれぞれ求め、それらのうちもっとも大きいものを除外したものの和を取ればよい。

```python
K, N = map(int,input().split())　
A = list(map(int, input().split()))
 
li = []
for i in range(N - 1):
  li.append(A[i + 1] - A[i]) #liに対して配列Aの要素間の差分を追加
  
li.append(abs(A[0] + (K - A[-1]))) #配列の初項と末項のみ別で追加
print(sum(li) - max(li))
```
[JavaScript] thisを含むイベントリスナーを登録/解除する

# はじめに

JavaScriptにおいて、`this` を含むイベントリスナーを解除するには、 `bind` を使用します。

# イベントリスナーの登録

JavaScriptの `addEventListener` は、イベントに合わせて呼び出される処理（イベントリスナー）を登録する関数です。例えば、WEBページが表示されたときに1回だけ登録して、クリックイベントの呼び出し処理を行うような場合に使用します。

```JavaScript
let btn = document.getElementById('btn');
btn.addEventListener('click', () => { /* クリックしたときの処理 */ });
```

# イベントリスナーの解除

`() => { /* クリックしたときの処理 */ }`  は、関数名が定義されていない関数（無名関数）です。この無名関数は、イベントリスナーを1回だけ登録する場合は有効です。

しかし、イベントリスナーを登録して解除する場合は、無名関数では解除することができません。

```JavaScript
btn.removeEventListener('click', () => { /* クリックしたときの処理 */ });
```

`removeEventListener` はイベントリスナーを解除する関数です。上記のように無名関数で実装した場合、登録と解除の関数は同じ関数ではないため、登録した関数に対して解除されません。クリックイベントが発火されてしまいます。

イベントリスナーを解除するためには、無名関数ではなく関数名を定義して実装します。

```JavaScript
let onClick = () => { /* クリックしたときの処理 */ };
btn.addEventListener('click', onClick);
btn.removeEventListener('click', onClick);
```

# thisを含むイベントリスナーの登録

`let onClick = () => { console.log(this.video) };` のようなに関数内に `this` が含まれる場合はどうでしょうか。 

```JavaScript
console.log(this.video); // 参照できる
let onClick = () => { console.log(this.video) }; // 参照できない (=undefined)
btn.addEventListener('click', onClick);
btn.removeEventListener('click', onClick);
```

`this` を参照することができません。

ここで `bind` の登場です。
 
```JavaScript
console.log(this.video); // 参照できる
let onClick = () => { console.log(this.video) }; // 参照できる
let onClickBind = onClick.bind(this);
btn.addEventListener('click', onClickBind);
btn.removeEventListener('click', onClickBind);
```

`let onClick = () => { console.log(this.video) };` で使用している `this` を `bind` で登録することで、参照することができます。


# デモプログラム

bindを使用したイベントリスナーの登録・解除のデモプログラムを紹介します。

[デモプログラム](https://yunbow.github.io/sample-video-js/02/)

このデモプログラムでは、1つ動画を再生する度に、再生開始前に動画再生のイベントリスナーを登録して、再生終了後にイベントリスナーを解除しています。イベントリスナーには、動画情報を `this` で参照しているため、イベントリスナーの登録後に、 `bind` を使用しています。

# さいごに

ソースコードをGitHubに公開しています。

[ソースファイルはこちら](https://github.com/yunbow/sample-video-js/tree/master/02)

以上です。