OmniAICreator/Qiita-1.07M huggingface dataset:
yolo/darknetなんとか動かした話

# エラー

自宅windowspcでgpuを使って物体検出しようとごちゃごちゃ準備して、
ようやくYOLO v3の動作テストをしようと以下のコマンドを実行したら

```python

$ python yolo_video.py --image

.
.
.
.
.
.
.

keras\engine\saving.py, line 224, in _deserialize_model

.
.

AttributeError: 'str' object has no attribute 'decode'
```



こんな感じのエラーが出て動きませんでした

# 解決
```python
pip install h5py==2.10.0
```
h5pyのバージョンを3.10.0から2.10.0にしたら動きました

# 感想
けっこう長い間環境構築できずに悩んでいたのでかなり嬉しい
明日からは楽しい機械学習ライフの始まりだ！
過去のコミットのメールアドレスを全部書き変える

gitコマンドでコミットしたときとかにメールアドレスを間違えてプライベートなメールアドレスを使ってたときに修正する方法です。
GitHubとかだと別途メールアドレスを作ってくれるのでそれに置換したいときとかに使えます。
全コミットを置換するのでコミットが多いと時間がかかります。

# 準備

```bash
git clone リポジトリのURL
```

# メールアドレスを置換

```bash
git filter-branch -f --env-filter 'if [ "$GIT_AUTHOR_NAME" = "ユーザー名" ]; then GIT_AUTHOR_EMAIL="新しいメールアドレス";fi'
git push -f
```
このコマンドは指定したユーザー名のメールアドレスを新しいメールアドレスに置換するコマンドです
指定したメールアドレスを置換ということもできます

```bash
git filter-branch -f --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "古いメールアドレス" ]; then GIT_AUTHOR_EMAIL="新しいメールアドレス";fi'
git push -f
```
ftp-deploy-cliでコマンドでゴリっとftpアップロードする

# インストール

```shell
$ npm install -D ftp-deploy-cli
```

# 初期設定
接続先サーバーの情報を入力し、`ftp.config.js`を生成、
必要ならそれは`.gitignore`に追加する

```shell
$ npx deploy init

? Please input host: test.com
? Please input port: 21
? Please input user: username
? Please input password: password
? Please input targetDir: /htdocs
? Please input localDir: dist
```

設定後の内容確認はこれ

```shell
$ npx deploy config
```

# 転送実行

```shell
$ npx deploy start
```

# 参照

- [ftp-deploy-cli - npm](https://www.npmjs.com/package/ftp-deploy-cli)
waifu2xをGoogle Colabで動かせたので共有してみた

# 実行結果

![Screen Shot 2020-12-11 at 1.52.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/6f30c0b1-27eb-8d73-d5d5-34f66fde5930.png)

# waifu2xとは

ノイズ補正をしつつ、きれいに画像を2倍のサイズにしてくれる神の御業
https://github.com/nagadomi/waifu2x

# 実行した理由

- 写真の画像をとりあえず2倍にしたい案件があった。
- おうちPCがMacなので、CUDA・NVIDIAに依存してるやつは動かせない
- Waifu2xのCaffe版とかもあってそちらだと動くんだけど、写真向けモデルは移植されてなかったり、ノイズ補正が対応してなかったりする
- [Deep AI](https://deepai.org/machine-learning-model/waifu2x)にもwaifu2xあるじゃん！！無料で使えるの！？ヒャッホー... あれ？これイラスト向けだけだ...
- 他の画像拡大系のモデルも使ってみたけど、実際試してみたら実用に耐えられなかった

# 共有した理由

- waifu2xをGoogle Colabで実行したものを探してみたけど、きちんと動いているやつが見つからなかった。
- waifu2x-caffeとかだったら結構ある

# Notebook

こちらを参照してください

https://colab.research.google.com/drive/1zprZPiWjWEnwcHqmzrLQEGm64kXiUH4d?usp=sharing

> Google Colabで実行したらTorchのインストールだけで30分〜3時間ほどかかりました
> 稼働状態によって異なるっぽいですが、初期設定だけでかなり時間がかかります。

# ハマったことなど諸々

## no CUDA-capable device is detected

RuntimeがGPUになっていない可能性があります。
[ Runtime ] -> [ Change runtime type ] で確認できるので、なってなかったら変更してください。

> :warning: 変更すると今までの実行結果が消えるようなので、なるべく早い段階で気づいてください

念の為、環境変数でも指定するといいようです。

```py
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0"
```

## luarocks: command not found

waifu2xの依存パッケージを入れていくあたりでいわれて、その前にTorchをインストールしていて、ログを追うとそこでは普通に使えてるっぽいのでなんでや！！ってなります。
結論から言うと、luaとTorchのインストールにwaifu2xと同じ作者の`nagadomi/distro`を使ったのですが、これをGoogle Colabで実行した場合、`luarocks`は`/content/torch/install/bin`の配下に作成されるようです。
デフォルトだと、この場所にはPATHが通ってないので、通します。

stackoverflowやgithubを覗くと、`nagadomi/distro`をGoogle Colabで使っている場合、同じ原因でコケている方が結構いました。

```py
# add PATH for luarocks

import os
os.environ['PATH'] += ":/content/torch/install/bin"
```

# あとがき

Google ColabというかJypter Notebookをガッツリ使った経験がまだそれほどないので、共有しているファイルでこここうしたほうがいいみたいなのがあるかもしれませんが、それは良しなに...
NUCで始めるVMware Tanzu - vSphereネットワーク紹介

本日は、[Day10](https://qiita.com/hirosat/items/537f3b75160e2a9f4a21) で構築したvSANを構成するネットワークについて、解説したいと思います。

良く分からない用語が続き、難しいと感じた方もいらっしゃったのではないでしょうか？やってみて気づくのは、vSANの難しさの半分くらいは、**vSphereネットワークの難しさ** なんじゃないかなと思います。でも本来は、お金をかけて様々なハードウェアを買い、さらには設置場所まで取られるものを、全部仮想化して構築できちゃうなんて凄くないですか？慣れると凄く便利なので、基本的な概念は、このタイミングで覚えてしまいましょう。

#NUCの構成要素
今回NUCに行っていったネットワーク設定を、1枚の図にしてみました。私が事前に用意したものは、物理ルータと（物理）NUCだけなので、薄緑枠の中は、全て仮想的に構築したものとなります。
![nuc-inside](https://user-images.githubusercontent.com/3906298/101807796-de706200-3b58-11eb-948e-c287ce607110.png)
ESXiの大きな特徴といえば、この仮想スイッチを中心としたネットワーク接続となります。何故こんな仮想のスイッチなんて用意するのかというと、ESXi上で多くのVMを管理することが前提で作られているからです。
図の各リソースの説明をまとめてみました。

| リソースメニュー | 図中の名称<br>(リソースの種類) | 説明 |
|:--|:--|:--|
| 仮想スイッチ | vSwitch<br>DSwitch | vSwitchは、ESXiの中の他のリソース同士をつなぎ合わせるものとなります。一般的な物理スイッチ同様、スイッチを中心としたN対Nのシンプルな結線となります。<br>DSwitchは、、上図では表現しきれないので、この後、別途説明します！ |
| 物理NIC | vmnic0, vmnic1..| 名前には物理と付きますが、macアドレスを管理するリソース。よって、実際に物理か仮想かは関係ありません（便宜上、仮想NICと呼び分けることはある）。例えば今回、NUC自体は一つの物理NICしか持ちませんが、nested構成にすることで、複数NIC構成を実現できました！仮想化の強みと言えます。|
| VMkernel NIC | vmk0, vmk1.. | 図の青色のリソースであり、IPアドレスを管理。仮想スイッチを介して物理NICと1対1で紐付けられます。モジュール化することで、柔軟な管理が可能となります。 |
| (標準)ポートグループ | VM Network<br>※図中に記載なし | vSwitchを介したネットワーク内で、どのようなメンバーが所属するか管理するために用いられます。 |
| (分散仮想)ポートグループ | DSwitch-xx| DSwitchを介したネットワーク内の所属メンバーを管理。 |

なお、↑のリソースメニューは、ESXiの管理画面で上部のメニューとマッピングしています。TCP/IPスタックとファイアウォールルールは、またの機会に。。
<img width="926" alt="スクリーンショット 2020-12-11 18 24 17" src="https://user-images.githubusercontent.com/3906298/101886043-4a48de00-3bde-11eb-84a7-e5e5062d9cf1.png">

###なんでそんなにネットワークを分けたいの？
上記のようなネットワークの仮想化の概念により、複数のネットワークを容易に制御することが可能になりました。ここで疑問に思うのが、「そんなに細かく制御しなくて良くない？」と思うかもしれません。ネットワーク分割の目的として、主に、「セキュリティ」と「パフォーマンス」の2つの観点により、エンタープライズ仕様のインフラを実現します。
####セキュリティ観点
「最小限の対象」に「最低限のアクセス許可」を与えることが目的となります。ネットワークを分割することで、「必要なターゲットのみ」に対し、「必要なサービス（Port）のみを許可」することが可能になります。
####パフォーマンス観点
ネットワークの帯域は有限です。特にVM環境では、多くのネットワークリソースを必要とします。限られた帯域のなかで、「この用途には優先的に多くの帯域を割り当てる」といった、QoS(サービス品質)の対象として、ネットワークを分割します。

###どのようにネットワークを分ける？
まず最低限、以下の2つにより、他のリソースへのアクセスを実現します。

| ネットワーク名 | 概要 |
|:--|:--|
| VMネットワーク | VM間をつなげるネットワーク。Macアドレス同士をつなげる |
| Managementネットワーク | MacアドレスとIPアドレスを紐付けるネットワーク |
ここから、用途によって分けていきます。以下はポピュラーな例です。

- バックアップ用ネットワーク
- vSAN用ネットワーク
- vMotion用ネットワーク

さらに、サービスレベルで分ける場合もあります。

- 開発用ネットワーク
- 本番用ネットワーク

分ければ分けるほど、インフラとしての品質は良くなりますが、その分運用が大変になってくるので、トレードオフとなります。

#分散スイッチ
先ほど保留にしていた、分散スイッチについて説明します。
分散スイッチは、**vCenter上で複数のネットワークを一元管理**することが目的となります。
まずは、この今回のNUCとvCenterを含めた構成図を見て下さい。
![homelab](https://user-images.githubusercontent.com/3906298/101912338-f7365180-3c04-11eb-9b05-ea2e197ffbff.png)
つまりDSwitchとは、各ESXi上に散らばったスイッチを、vCenter上では見かけ上、ネットワーク毎に一つのスイッチとして取り扱えます。Uplinkと呼ばれるポートグループによって、ネットワーク分離を実現します。また、最初のNICの図にもある通り、DSwitchには、分散先につなげるための「DSwitch-xx」と、IPアドレスと紐付けるための「DSwitch-management」の2つのポートグループを、セットで作成する必要があります。
このような構成を仮に物理的に行うとすると、vCenter側に12個のLANポートと12本のLANケーブルが必要ですよね？もっとesxiやNICの数が多くなると、乗算的に膨れ上がり、HW的な実現不可能なケースも出てきます。つまり、DSwitchが複雑なのではなく、このような構成をとること自体が複雑で、むしろ、仮想化により手軽に実現しやすくなっため、生まれた概念と言えます。

はい、本日は座学でしたね。。
今日まで、まったくKubernetesが出てきませんでしたので、明日からはいよいよTKGの話に入っていきたいと思います！
Tclのシリアルポートのパス名

# 概要
Windows向けにはいくつかのTcl/Tkディストリビューションがありますが、シリアルポートのパス名に差異があったので、備忘録として記しておきます。

# 結論
CygwinとMSYSは`/dev/ttySx`スタイル(xは0以上の整数)で、それ以外は`\\.\COMy`スタイル(yは1以上の整数)です。

ただしパス名のスタイルが違うだけで、openできてしまえば後の処理は同じです。

# Cygwinのtclsh
CygwinはLinuxなどUNIX OS向けに書かれたソースコードをほぼ無修正でビルド＆実行できる環境を実現しているので、シリアルポートのパス名はLinuxなどで標準的な`/dev/ttySx`スタイルになっています。

このためtclshでも`/dev/ttySx`スタイルでシリアルポートを開きます。

```tcl:Success
% open /dev/ttyS0 r+
```

一方、`\\.\COMy`スタイルは使用できません。

```tcl:Failure
% open \\\\.\\COM1 r+
```

# MSYS2
MSYS2はconfigureスクリプトとmakeでWindows向けバイナリをビルドできる環境を提供していますが、MSYS2をインストールしてみるとスタートメニューに

* MSYS2 MinGW 32-bit
* MSYS2 MinGW 64-bit
* MSYS2 MSYS

という3つのショートカットが登録されます。

「MinGW」を含む2つはまさしくそれぞれのビット数向けのビルド環境ですが、私は未だに「MSYS」の存在意義を理解できていません。(というより「MSYS」のtclshを使ってハマったのが今回この記事を書こうと思い立った本当の理由です)

## MSYS2 MinGW 32-bitのtclsh
`pacman -S mingw-w64-i686-tcl`で`/mingw32/bin/tclsh`にインストールされます。

シリアルポートは`\\.\COMy`スタイルになっています。`/dev/ttySx`スタイルは使用できません。

## MSYS2 MinGW 64bitのtclsh
`pacman -Si mingw-w64-x86_64-tcl`で`/mingw64/bin/tclsh`にインストールされます。

シリアルポートは`\\.\COMy`スタイルになっています。`/dev/ttySx`スタイルは使用できません。

## MSYS2 MSYSのtclsh
`pacman -S tcl`で`/usr/bin/tclsh`にインストールされます。

シリアルポートは`/dev/ttySx`スタイルになっています。`\\.\COMy`スタイルは使用できません。

## MSYS2雑感
プロジェクトの性格上、ビルドに関係のない`/dev/`エントリーは無いと思っていたので、MSYSの仕様は完全に意表を突かれました。

さらに、MSYSとMinGWで仕様が異なるという点も完全に意表を突かれました。

`ldd`の出力結果を比べてみるとMSYSのtclshだけmsys-2.0.dllがリンクされているので、このDLLの仕業なのかなと考えています。

いずれにせよ、同じシェルから実行できるコマンドごとにパス名が違うという点は、MSYSをCygwinのような普段遣いの環境にできない致命的な落とし穴だと感じました。

# MagicsplatのtclshおよびTkCon
シリアルポートは`\\.\COMy`スタイルになっています。`/dev/ttySx`スタイルは使用できません。

# [KitCreator](https://kitcreator.rkeene.org/)のtclsh
シリアルポートは`\\.\COMy`スタイルになっています。`/dev/ttySx`スタイルは使用できません。

# ActiveTclのtclshおよびTkCon
サインインしないとダウンロードできなくなって以来使用していないので今はどうなっているか不明ですが、8.5では`\\.\COMy`スタイルだったと記憶しています。

# WSL Debian GNU/Linuxのtclsh
シリアルポートは`/dev/ttySx`スタイルになっています。`\\.\COMy`スタイルは使用できません。

ちなみに`/dev/ttySx`を開くにはdialoutグループに所属している必要がありますが。
Ubuntu 20.04でdocker run時にvolumeを設定したら想定外のパスにvolumeが作成されていた

## いきなり結論

docker run時に、volumeを/tmp配下に設定したところ/tmp配下には作成されず、
代わりに/tmp/snap.docker/tmp配下にvolume用のディレクトリが作成されました。

当方、めんどくさがってUbuntuインストール時のFeatured Server Snapsにて
dockerにチェックを入れていました。

そのせいで、snap（Snappyの方が正式名称？）パッケージで提供されるdockerが
インストールされてしまったようです。

snapパッケージのため、Ubuntuのファイルシステムへ直接ファイルを置くことはせず、
snapによってマッピングされた先にvolumeが作成されるみたいです。

## 環境

| ソフトウェア                    | バージョン|
|:-------------------------------|------------:|
| Ubuntu                         | 20.04.1 LTS Server |

- その他
 - x86-64bit環境
 - **Ubuntuインストール時のFeatured Server Snapsでdockerにチェックを入れた**

## 実行したdocker runのコマンドと、実行後のvolumeの作成先

```
# docker run --detach \
  --publish 40443:443 --publish 40080:80 --publish 40022:22 \
  --name test_gitlab \
  --restart always \
  --volume /tmp/gitlab/config:/etc/gitlab \
  --volume /tmp/gitlab/logs:/var/log/gitlab \
  --volume /tmp/gitlab/data:/var/opt/gitlab \
  gitlab/gitlab-ce:latest
```

ボリュームに「/tmp/gitlab/config」「/tmp/gitlab/logs」「/tmp/gitlab/data」を
指定しているので、/tmp配下にgitlabディレクトリが作成されるはずと思ってみてみると。。。

```
# ls -lt /tmp
total 24
drwx------ 3 root root 4096 Dec 10 16:20 snap.lxd
drwx------ 3 root root 4096 Dec 10 16:20 snap.docker
drwx------ 3 root root 4096 Dec 10 16:20 systemd-private-35a61383cfc041f8bf4ccb7c92a2b205-systemd-logind.service-O4Ix6i
drwx------ 3 root root 4096 Dec 10 16:20 systemd-private-35a61383cfc041f8bf4ccb7c92a2b205-systemd-resolved.service-nHhtTi
drwx------ 2 root root 4096 Dec 10 16:20 vmware-root_842-2688554003
drwx------ 3 root root 4096 Dec 10 16:20 systemd-private-35a61383cfc041f8bf4ccb7c92a2b205-systemd-timesyncd.service-rkNQXi
```
上記の通り、gitlabディレクトリは存在しませんでした。
じゃあ「/tmp/gitlab/config」「/tmp/gitlab/logs」「/tmp/gitlab/data」は
どこに作成されたのかというと。。。

「いきなり結論」の章で書いた通り「/tmp/snap.docker/tmp」配下に作成されていました。

```
# ls -lt /tmp/snap.docker/tmp/gitlab/
total 12
drwxr-xr-x 20 root root 4096 Dec 10 16:56 data
drwxr-xr-x 20 root root 4096 Dec 10 16:55 logs
drwxrwxr-x  3 root root 4096 Dec 10 16:52 config
```

# 他のディレクトリを指定したらどうなるか？

例えば、volumeに/tmpではなく/srvを指定したらどうなるでしょうか？
（gitlabのdocker runコマンドって、公式HPにvolumeは/srv使えって書いてあるんですよね。）

```
# docker run --detach \
>   --publish 40443:443 --publish 40080:80 --publish 40022:22 \
>   --name test_gitlab \
>   --restart always \
>   --volume /srv/gitlab/config:/etc/gitlab \
>   --volume /srv/gitlab/logs:/var/log/gitlab \
>   --volume /srv/gitlab/data:/var/opt/gitlab \
>   gitlab/gitlab-ce:latest
81cc3ce3e813c482d7e9b8e4253ed433b28e51f133fa9df012adaef462f5dc5a
docker: Error response from daemon: error while creating mount source path '/srv/gitlab/data': mkdir /srv/gitlab: read-only file system.
```

エラーになります。
推測ですが、snapにて/srvへのマッピング先ディレクトリが指定されていないため
ディレクトリを作成することができずエラーになるようです。

# 課題

じゃぁUbuntu 20.04LTS Serverをインストール時ではなく、インストール後にaptで
docker入れたらどうなるか？
時間があるときに試してみます。
Chromebook に開発ツール（Android Studio、Eclipse、Visual Studio Code、Github Desktop）をセッティングする

Chromebook しかないけど開発したくなったので、必要な開発ツールをインストールしたメモです。

# はじめに
入れてみたものは、以下のツールです。

+ Android Studio
+ Eclipse
+ Visual Studio Code
+ Github Desktop （おまけで GitKraken）

# 手順メモ
明日の自分がハマらないようにメモします。

## Android Studio
Chromebook 用の deb があったのですぐ入りました。

参考：
https://www.helentech.net/chrome-os-officially-supported-with-android-studio/

## Eclipse
tar.gz 版しかなく、解凍して配置して、PATH の通っている bin フォルダに ln しました。また、Eclipse 起動のために、Java も入れないといけなそうでした。

参考：
https://arakaki.tokyo/blog/development_environment_on_chromebook_2/

## Visual Studio Code
Debian 用の deb があったのですぐ入りました。

参考：
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1286826.html

## Github Desktop （おまけで GitKraken）
Debian 用の deb があったのですぐ入りました。ただし、自分の Github アカウントとの認可時に、Chrome と、Linux環境とがお互い見れないのか、ブラウザを通じての連携ができませんでした。しかたなく、git clone は、ターミナルから実施しました。

参考：
https://qiita.com/hikipuro/items/79980610b0f67a3262f9
（おまけ）https://wakaba-mafin.hatenablog.com/entry/setup-gitkraken-on-chromebook

# まとめ
すべての開発ツールが入りました。そして共通しているのは、Chromebook 簡単に起動できる Linux（β版）を活用したことです。

以上
なぜJSでRecursion（再帰）を書くときはTail Call（末尾）にすべきか？

## 簡単に言うと

こう書くのではなく↓

```JS
function countDown(num) {
  if(num > 0) {
    console.log(num)
    countDown(num - 1) // <-- 再帰🙋‍♂️
  } else {
    console.log("0になったよ！")
  }
}
```

こう書いてね↓👍

```JS
function countDown(num) {
  //「Base Case」または「Exit」と呼ばれているよ↓
  if(num <= 0) { 
    console.log("0になったよ！")
    return
  } 

  console.log(num)
  countDown(num - 1) // <-- 再帰🙋‍♀️
}
```

運が良ければ、作動スピードが上がるよ！

## 何でそうするの？

ブラウザには、再帰できる数に制限があるから、一定の量を超えてしまうとあの有名な「スタック・オーバーフロー」になっちゃう。（処理できずにエラーを飛ばすの）

でも、再帰の部分のを関数の最後に書いておくと、いくつかのブラウザは勝手に「最適化」してくれて、ほぼ無制限に再帰できる。

そして、スピードもぐんと上がる。

見た目も分かりやすいし、いいこと尽くし。


## 具体的な原理は？

結構ディープな内容なので、エリート君はこちらを参照（英語）：
https://exploringjs.com/es6/ch_tail-calls.html

**要するに（日本語で）:**

通常の再帰演算ではなく、goto（次）みたいないな感じにできるから、無制限に呼び出せてスピードも早くなる。


## オタクっぽいあなたにも

ES2015(ES6)の仕様書にTCE（Tail Call Elimination）が選定されて、その後色々あってブラウザに採用されたり採用されなかったり。結局今その機能が動いているのはSafariだけなんだけど。
centos8にphp-opcacheインストール

↓php7.4をインストール

```
$ dnf module install -y php:7.4
```

```
$ php -v
PHP 7.4.6 (cli) (built: May 12 2020 08:09:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```


↓php-opcacheインストール

```
$ dnf install php-opcache
```

↓opcacheインストール後はphp -vの結果が変わる。with Zend OPcacheになっている。

```
$ php -v
PHP 7.4.6 (cli) (built: May 12 2020 08:09:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.6, Copyright (c), by Zend Technologies
```
Erlangのコマンドでobserverを開く。

iexで`:observer.start`と打てばobserverを開くことができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/75f4a105-d834-0eb8-768a-de4cf6ca2cbe.png)



```
% iex
Erlang/OTP 23 [erts-11.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :observer.start
```
WordPressの「Twenty Forteen」テーマのコンテンツを左右中央にするTips

　WordPressサイトの古いデフォルトテーマ「Twenty Forteen」を更新したら、コンテンツが左によってしまったときの対処方法。

# 処置前

コンテンツが左によってしまっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/ad429b4f-f3c9-0c6e-4800-f6a62d5fc799.png)

# 処置

１．「Twenty Forteen」を使っているサイトの管理画面の[外観]→[カスタマイズ]に入る。
<img width="120pt" alt="menu" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/16bb72be-ca66-2dc9-4ced-4e54ff872187.png">

２．[追加CSSをクリック]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/7f548319-e8ca-92f9-6773-f14e91734fae.png)

３．以下のCSSを追加。

```css
.site{margin:0 auto;}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/32718a53-ac6d-e7fb-e09f-1a065334d2da.png)


# 処置後

コンテンツが中央に来た！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/5d2ae45f-440f-4e50-e8a2-c1b644a808e9.png)
Pandasのマルチインデックスについて

## はじめに

はんなりPythonアドベントカレンダーの11日目の記事です。
私自身Pandasは本当に初心者なので、以前から気になっていたマルチインデックスについて簡単ですがまとめました。

※本記事では原則下記コードは省略しますが、記述されている前提で進めます。

```python
import pandas as pd
```

## そもそもマルチインデックスとは

行ラベル、列ラベルを階層的に持つことができる仕組みです。
文字での説明がややこしいので、実際に例を見てみましょう。

![Snag_907daffc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/33ec6f89-a673-d00d-69f1-46ef2cbfc829.png)

上の図の場合、列ラベルが2層になっています。1列目にはnameとtypeAというラベルが付与されており、2列目にはtimeとtypeAというラベルが付与されています。

## マルチインデックスの扱い(列ラベルがマルチの場合)

では、実際にデータを取得する場合を見てみましょう。

![Snag_908033e8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/36ccd210-b4e3-7ffa-b875-18fc5cf2ac96.png)

上の例では、nameとtimeのみの列を抜き出しています。
ちなみに、普通のインデックスの場合も同じ方法で列を抜き出すことができます。(下図参照)

![Snag_9081da73.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/9b4a2142-f055-cd0c-29cb-ea2b66705eaa.png)

つまり、**外側のラベルについては、通常の列ラベルと同じ方法で参照できる**、ということです。

では、次に内側のラベルで絞り込みを実施してみましょう。
その際は、IndexSliceを使います。

![Snag_908e8b5a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/ca238ba5-b64d-2972-1d7f-76bb09ac403e.png)

上図では、typeAで絞り込んだ結果です。typeAにはnameとtimeが含まれるので、typeAで絞るだけで、2列のデータを取得することができます。
マルチインデックスを利用すると、グループ化できるので、一つのラベルで複数の列を絞り込むことが可能になります。

ちなみに、もしnameとtypeAの両方を選択する場合は以下になります(本当はこんなことはしませんが)

![Snag_909161bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/26d007db-3b64-00e7-1091-730f81290b7c.png)

IndexSliceの記述では、外側のラベルから順番に記述します。


## マルチインデックスの扱い(行ラベルがマルチの場合)

次は、行ラベルをマルチにしてみましょう。

![Snag_90a0750c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/2fe7918f-6e5d-66ba-df41-749fa5b1de9e.png)


かなりややこしいのですが、まず最初にnameとtime、messageを列ラベルとして設定しています。
次に、`test = df.set_index(['name','time'])`の部分でnameとtimeをインデックスとしてセットしているので、**nameとtimeは列ラベルではなく行ラベルとしてのマルチインデックスになります**。(下図参照)

![Snag_909ba5f7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/cf0affe4-0dbb-892a-34e9-64ff3b2b5e43.png)

では、device1のデータだけを抜き出してみましょう。

![Snag_90a0a3ad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/dc1574b3-4618-003c-5ae9-2156cbe0bfc5.png)

ちなみに、device1と2020で絞り込む場合は以下になります。
locの中身を配列ではなくタプルで指定することで絞り込みが可能です。

![Snag_90a2dd22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192873/7be25ae1-b6dc-5b04-ffc8-675cb74e6abe.png)

## 最後に

マルチインデックスる利用することで、列や行をグループ化することができ、より分かりやすいデータ処理をすることができるようになります。
最初見たときは私も全然わかりませんでしたが、この記事が少しでも理解の助けになれば幸いです。
では(*^▽^*)
Raspberry PiでNintendo Switchのプロコンを使う

Raspberry PiでNintendo Switchのプロコンと、PlayStation3のコントローラを使う方法を説明します。
PS3は多くの解説記事がありますが、自分の忘備録として記載します。

# 環境
- Raspberry Pi 4 Model B or Rasberry Pi 3 Model B++
- Ubuntu Server 18.04
- Nitendo Switch プロコン
- PlayStation3 コントローラ

# Raspberry Piのセットアップ
[こちらの記事](https://qiita.com/hiro-han/items/56c4fb6a1ad4c1713a7f)でUbuntu ServerでBluetoothを有効化する方法を記載したので、記事に従ってRaspberry Piをセットアップし、Bluetoothを有効化します。

# プロコンの接続
プロコンをRaspberry Piに接続します。プロコンはBluetoothデバイスとして認識されるので、接続は簡単です。

Bluetoothサービスの起動

```
$ sudo systemctl status bluetooth
$ sudo systemctl start bluetooth

# もし実行できなかった場合は、以下ファイルに実行権限を付与して再度起動
$ sudo chmod +x /usr/lib/bluetooth/bluetoothd
$ sudo systemctl start bluetooth
```

一般ユーザでbluetoothデバイスが使えるように権限を付与

```
$ sudo usermod -a -G bluetooth {使用しているユーザアカウント}
$ sudo reboot
```

プロコンのペアリング

```
$ bluetoothctl
$ [bluetooth] scan on
{プロコンが認識されるはずなので、MACアドレスをコピー}

$ [bluetooth] pair {MACアドレス}
$ [bluetooth] trust {MACアドレス}
$ [bluetooth] connect {MACアドレス}
$ [bluetooth] exit
```
上記の手順でプロコンのペアリングが完了です。

デフォルトだと`dev/input/js0`が生成され、これがプロコンになります。ただし、rootユーザでしか使用できないので、一般ユーザで使えるように権限を付与します。

```
$ sudo chmod a+rw /dev/input/js0 
```

以上でプロコンが使用可能になります。`jstest /dev/input/js0`などで確認ができます。
また、Raspberry Piを再起動した後も、bluetoothサービスが有効になっていれば、プロコンのキーを押すだけで再ペアリングされます。


# PlayStation3 コントローラの接続
こちらは検索すると多くの記事が見つかるので、それらも参考にしてください。

はじめに`libusb`をインストールします。

```
$ sudo apt install libusb-dev
```

次に、sixpairとqtsixaというソフトウェアを使用するのでインストールします。

## sixpairのインストール
```
$ mkdir sixpair
$ cd sixpair
$ wget "https://help.ubuntu.com/community/Sixaxis?action=AttachFile&do=get&target=sixpair.c" -O sixpair.c
$ gcc -o sixpair sixpair.c -lusb
```

## qtsixaのインストール
### 必要なライブラリのインストール

```
$ sudo apt install python-qt4 pyqt4-dev-tools qt4-designer
$ sudo apt install libjack-jackd2-dev
$ sudo apt install libbluetooth-dev
```

### qtsixa
```
$ git clone https://github.com/falkTX/qtsixa.git
$ cd qtsixa
$ make
$ sudo make install
```

## ペアリング
まず、USBケーブルでコントローラを接続し、PSボタンを押します。正しく認識されると`lsusb`コマンドでコントローラが表示されます。
次に、sixpairを実行します。

```
sudo ./sixpair
```
USBケーブルを外し、以下コマンドを実行します。

```
$ sudo sixad -start &
```
すると、`sixad started, press the PS button now`というようなメッセージが表示されるので、PSボタンを押します。
接続に成功した旨のメッセージが表示され、またコントローラの4つのランプのうち1つが点灯していれば接続成功です。

こちらも`$ sudo jstest /dev/input/js0`でキー入力が確認できます。

# 参考
- [Raspberry Pi 3B にPS3コントローラを認識させる](https://qiita.com/KurokoSin/items/f0f2de392d52821e7fa6)
- [Raspberry Piとdualshock3接続（再び）](https://www.usagi1975.com/031520180722/)
【UE4】UE4側でのフレームレートを操作する手法

# 最初に
どうも、ろっさむです。

今回はUE4のフレームレートを操作するにあたって調べたことをまとめていこうと思います。
環境は以下の通りです。

- UE4.26
- Windows10


# UE4のデフォルト設定

UnrealEngineではFPSを自動的に設定するためのオプションが用意されており、それらはユーザー側から変更が可能です。デフォルトでは**可変フレームレートに対応した設定**となっています。確認するためにはまず上部メニューから `Edit > Project Settings`から設定ウィンドウを開いてください。

![image](https://user-images.githubusercontent.com/10665134/101791703-2f775a80-3b47-11eb-9758-55bb9d1095be.png)

次に左部メニューから、`Engine > General Settings` を押下してください。

![image](https://user-images.githubusercontent.com/10665134/101792751-6d28b300-3b48-11eb-84f4-c2b538ed954e.png)

開いた画面の下の方に `Framerate` という項目が存在します。

![image](https://user-images.githubusercontent.com/10665134/101792877-8cbfdb80-3b48-11eb-8365-c59091219b65.png)

こちらの項目をそれぞれ確認していきます。

|項目|概要|
|----|----|
|Smooth Frame Rate| アプリケーション毎のフレームレートの最小値と最大値を定義するかどうか。チェックすると、**設定した範囲でFPSを一定に**しようとする。 |
|Use Fixed Frame Rate | 固定フレームレートにするかどうか。チェックすると**フレームを完全に固定させる**。 |
| Fixed Frame Rate | Use Fixed Frame Rateにチェックをしている場合に、**fpsの値を設定する**。 |
|Smoothed Frame Rate Range | Smooth Frame Rateにチェックをしている場合に、**fpsの最小値と最大値を設定する**。 |
|Min Desired Frame Rate | 必要最低限のフレームレート値。 |

これらの設定を調整することで基本的なゲーム制作は可能です。

# FPSのロックを解除する

デフォルト設定だと60fpsのパフォーマンスを目指すような設定となっています。なので、ここを超えてのFPSを設定する場合にはいくつか手順が必要になるようです。

まずは、先ほどの設定項目から、 `Smooth Frame Rate`と`Use Fixed Frame Rate`をオフにします。これによって**フレームレートが制限を超え、且つエンジン側でフレームレートの調整をさせない**ようにすることができます。

![image](https://user-images.githubusercontent.com/10665134/101799195-3609d000-3b4f-11eb-9a2b-c799e23a9c70.png)


次に `VSync`（垂直同期）を無効にします。**垂直同期はゲームのfpsを60にロック**してしまいます。

![image](https://user-images.githubusercontent.com/10665134/101799695-d102aa00-3b4f-11eb-9d32-2fde2094de63.png)

次に最大フレームレートを設定します。

`Execute Console Command`ノードを使用して、`t.maxfps {fps数値}`を入力してください。このコマンドは**フレームレートの上限値をエンジンへ指示する**ことができます。



![image](https://user-images.githubusercontent.com/10665134/101800038-276fe880-3b50-11eb-8c1e-a6cbcec7d0ac.png)




# 参考

- [Smooth Frame Rate（公式）](https://docs.unrealengine.com/ja/TestingAndOptimization/PerformanceAndProfiling/SmoothFrameRate/index.html)
- [A STUDY ON REPRESENTING NATURAL SENSE OFATTACK AND DESTROYING BODY-PART IN 3D GAME BASED ON UNREAL ENGINE 4 ](http://www.jatit.org/volumes/Vol97No4/20Vol97No4.pdf)
- [UE4 ゲームを可変フレームレート対応にさせる](https://unrealengine.hatenablog.com/entry/2015/08/09/210000)
- [How to Unlock FPS in Unreal Engine 4](https://couchlearn.com/how-to-unlock-fps-in-unreal-engine-4/)
日本各地の面積をまとめて計算したい

#目的
日本のいろんなところにあるポリゴンの面積を計算したいのだけど、場所によって適した投影座標系に合わせなければならないが、いちいちESPGコード変える作業がめんどくさいので、R (とQGIS)を使ってできるだけ自動的に処理する。
(だけどちょっと小さくなった、ナンデ...)

#準備
 - 日本各地にポリゴンがあるデータ。
  - 今回は[国土数値情報 世界自然遺産](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-A28.html "国土数値情報 世界自然遺産")から**A28-10_GML**を使っています。

![世界遺産.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917414/8e76dec2-700d-04cd-b988-9e5069dd6ae5.png)

 - QGIS 3.4以上
 - R version 3.6以上

#平面直角座標系とは
　ざっくりいうと、平面なら面積を計算しやすいが、地球は丸いので、地球の狭い範囲を部分的に平面に直してから、面積を計算します。この平面に変えた座標系が平面直角座標系で、日本では19の地域に分けられていて、それぞれの地域で当てはめる平面直角座標系が違う。

- 参考 
 - [esriジャパン：座標系](https://www.esrij.com/gis-guide/coordinate-and-spatial/coordinate-system/ "esriジャパン：座標系")
 - [国土地理院：日本の測地系](https://www.gsi.go.jp/sokuchikijun/datum-main.html "国土地理院：日本の測地系")

#手順
　1. 各ポリゴンにあったESPGコードを追記する。ここではQGISで属性テーブルを編集しました。[^1],[^2]

[^1]: dbfファイルを開いて直接書き込んでも良い。
[^2]: 数が多いときは地名や系番号とEPSGコードの対応一覧表を別ファイルで作って、R上で呼び出しながら使う方が便利。

![世界遺産属性テーブル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917414/abbf5cdf-d4b5-119e-27d7-fa182da6caba.png)

 - どの地域がどのEPSGコードに対応するかは、国土地理院のマップや系番号とESPGコードの対応表をみながら入力.
 - [国土地理院：１９の平面直角座標系](https://www.gsi.go.jp/sokuchikijun/jpc.html "１９の平面直角座標系")のマップ

 - 検索すると、既に作っているサイトもあるよ。ありがたい
   * http://blog.godo-tys.jp/2012/11/21/999/
   * https://qiita.com/kudarisenmon/items/2003b982247448affcf6



　2. Rで面積計算をする。

```r:epsgMENSEKI.r
#パッケージ読み込み
library(sf) #RでGISをするときは必須
library(dplyr)  #%>%(バイプ)を扱うため

setwd("SHPファイルが保存されたフォルダ") 
Shp1 <- read_sf("世界自然遺産.shp") #shpファイル読み込み
Df1 <- Shp1 %>% as.data.frame() #shpファイルのデータをデータフレームに変換
Df1$area <- 0 #データフレームに面積の列を追加しておく[中身はすべて0]

#i番目のポリゴン→座標系変換→面積計算→データフレームに追記
for(i in 1:nrow(Df1)){ #for文で一括処理
   tmp1 <- Shp1[i,] %>% st_set_crs(4612) %>% st_transform(Df1$epsg[i])
           #元のshpファイルはJSD2000で作成されているのでepsg:4612
   Df1$area[i] <- as.numeric(st_area(tmp1)) #面積計算してデータフレーム書き換え
 }
#結果をCSVなどに出力すると良い
```
```
##結果表示##
Df1
#面積の単位はm^2
  A28_001    sekai keibango epsg                      geometry      area
1      01    知床       13 2455 POLYGON ((145.0242 44.05915... 710356000
2      02    白神       10 2452 POLYGON ((140.1686 40.496, ... 168888939
3      03  屋久島        2 2444 POLYGON ((130.5675 30.2487,... 109263115
```
#計算結果の確認
#####QGISで各ポリゴンごとに計算した結果

 - Rの計算結果を、QGISで面積計算した結果[^3]と地理院地図で計測した結果[^4]で比較してみる。
 - QGISと地理院地図は同じ値。それらより、Rで計算した結果は0.01%未満で小さい...

|  | Rで計算(m^2) | QGISで計算(m^2)| 地理院地図計測(km^2) | R/QGIS |
|:-:|:-:|:-:|:-:|:-:|
| 知床 |**710356000**   |710397478  |710.397  |**0.9999416**  |
| 白神 |**168888939**   |168907446  |168.907  |**0.9998904**  |
| 屋久島 |**109263115** |109278285  |109.278  |**0.9998612**  |

なんかぁ微妙ーーーに小さいのね..:bug:

[^3]: QGISで各ポリゴンを空間参照系を変えて保存して1つ1つ面積計算しました。
[^4]: kmlで保存してから地理院地図に読み込んで、`ツール`>`計測`で面積を選ぶ。
centos8のdnfにremiリポジトリ追加

dnfにremiリポジトリ追加

remiリポジトリ使うためにはepelも必要とのこと。

```s
$ dnf install -y epel-release
$ dnf install -y remi-release
```


試しにphpモジュール調べてみる。remiリポジトリだとphp8系がもう使えるようです。

```s
dnf module list php 
Last metadata expiration check: 0:01:31 ago on Thu 10 Dec 2020 04:21:12 PM UTC.
CentOS Linux 8 - AppStream
Name                                      Stream                                        Profiles                                                            Summary                                                    
php                                       7.2 [d]                                       common [d], devel, minimal                                          PHP scripting language                                     
php                                       7.3                                           common [d], devel, minimal                                          PHP scripting language                                     
php                                       7.4 [e]                                       common [d] [i], devel, minimal                                      PHP scripting language                                     

Remi's Modular repository for Enterprise Linux 8 - x86_64
Name                                      Stream                                        Profiles                                                            Summary                                                    
php                                       remi-7.2                                      common [d], devel, minimal                                          PHP scripting language                                     
php                                       remi-7.3                                      common [d], devel, minimal                                          PHP scripting language                                     
php                                       remi-7.4                                      common [d], devel, minimal                                          PHP scripting language                                     
php                                       remi-8.0                                      common [d], devel, minimal                                          PHP scripting language                                     

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
```

## 参考
remi公式サイト
https://blog.remirepo.net/pages/Config-en

epel公式サイト
https://fedoraproject.org/wiki/EPEL/ja
アドベントカレンダー8日目：SREを読んでみた「サービスレベル目標」編②

前回は、サービスレベル目標の内、それを定義する言葉について、学びました。
今回は、その中でも特にSLI（Service Level Indicator：サービスレベル目標）についてみていきます。

## 指標の在り方
システムを表すメトリクスは、様々なものがあります。なので、様々な定義を行うことができます。しかし、その指標はあればあるほど良いのでしょうか？仮に一つの指標でシステムの状態すべてが表されているのなら、なんら問題はなく、その指標以外があることは、本当に価値のある基準が埋もれてしまう結果になります。
一方で指標が少なすぎれば、サービスの挙動を正確に測ることができなくなります。

以下は、特定のシステムの代表的な指標です。

#### ユーザーとやり取りするサーバーシステム
* 可用性
* レイテンシ
* スループット

#### ストレージシステム
* レイテンシ
* 可用性
* 耐久性

#### ビッグデータシステム
* スループット
* エンドツーエンドのレイテンシ

#### 正確性
この指標は、システムそのものというより、システムが正確にデータを返せているか。
バックアップの復元時にデータが問題ないかなどです。
はっきりSREの責務なわけではないですが、システムの健全性を図る上で重要です。

## 指標の収集
多くの指標のメトリクスは、サーバーサイドで収集するのが、自然です。
しかし、システムによっては、クライアント側での指標の収集が必要になります。
これは、サーバーサイドのみで計測していると、ユーザーにだけ影響を及ぼしている種類の問題を見逃してしまうかもしれないからです。
ユーザビリティの改善の観点からすると、クライアント側からの指標を収集する方が、状況をよく表してます。
自分にはありがちですが、そのデータを取る意味を深く考えなかったり、データがもつ意味について、理解が及ばない時があります。
本当に意味のあるデータは何だろうと考えるべきだと思いました。

## 集計
例えば、可用性の計測として、毎秒のリクエスト数を考えます。
単純に多くのリクエストを捌けていれば、可用性の高いシステムと考えられると思います。
しかし、平均の100レスポンスを返すシステムがあったとき、コンスタントに100レスポンス返す場合でも、偶数秒の時は、0レスポンス、奇数秒の時、200レスポンス返す場合でも、平均で100レスポンス返すことになります。レスポンス数としては、変わりませんが、後者の場合は、奇数秒のとき、負荷が2倍になってしまいます。平均でみると、実際のデータの変化を隠して、しまうことがあるかもしれないので、データの分布で考えてみることも重要です。
Googleの場合は、パーセントタイルでデータを分析する場合が多いようです。
人は、レスポンスタイムにばらつきがあるシステムより、遅いが安定しているシステムを好む傾向があるので、99%タイルのみに注力するSREチームもあるようです。

## 指標の標準化
一般的なSLIは、その定義を標準化し、毎回一から考えずに済むようにすることが奨められています。以下のような例が示されています。

> * **集計のインターバル：「集計は1分とする」**
* **集計の対象領域：「クラスタ内のすべてのタスク」**
* **計測の頻度：「10秒ごと」**
* **対象となるリクエスト：「ブラックボックスモニタリングジョブからのHTTP GET」**
* **データの取得方法：「モニタリングシステムを通じて、サーバーで計測」**
* **データアクセスのレイテンシ：「最後のバイトまでの時間」**

標準化の際には、そのデータを計測する目的を書いておいた方がいいと思います。
ただ有用であるから使うとなると、その方法への偶像崇拝になってしまうと思うからです。

##まとめ
* データの意味や有用性について、意識する
* 指標の標準化を行う。

## 雑記
少しただ続けているだけの状態に陥り始めている。
1割だけ変えてみる。自分の意見を少しだけ入れる。

#### 引用
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　42-45
Next.jsの画像最適化を検証してみる

この記事は[Next.js Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nextjs)の11日目の記事です
（本当は[NextAuth.js](https://next-auth.js.org/)を試してみようと思いましたが意外と難しくて時間が足りませんでした。。）

## 概要

- 2020年10月にリリースされた[Next.js](https://nextjs.org/)のv10で画像の最適化の仕組みが入りました
    - [Next.js v10のリリースブログ](https://nextjs.org/blog/next-10#nextjs-image-component)
- この画像最適化の仕組みが適用されていることをサンプルアプリを通じて確認してみたいと思います

## Next.jsの画像最適化

- 上記ブログ記事によると主に以下のような背景で機能が導入されました

### 課題

- Webページにおける画像は[Largest Contentful Paint](https://web.dev/lcp/)に大きな影響を与える
- レスポンシブ対応のために`img`タグに`width` `height`を指定しないケースがあり、その場合カクンとなるレイアウトシフトが発生してしまう

### 解決策

- Next.jsで`img`タグをラップした[Imageコンポーネント](https://nextjs.org/docs/api-reference/next/image)を提供し、それを使うだけで上記の課題を全て解決させる
    - クライアントの環境に応じて適切な形式（WebPなど）に変換しファイルサイズも縮小してくれる
    - `width` `height`を指定しても縦横比を維持したまま自動でレスポンシブ対応してくれる

## サンプルアプリで検証

- ファイルサイズの大きい（12.6MB）画像を用意して、`img`タグと`Image`コンポーネントでそれぞれ表示してみます
- 使うタグ以外は同じ属性を設定します
- 検証に使ったページはこちらです
    - https://next-image-sample.vercel.app/

```tsx
import Image from 'next/image';
import Layout from '../components/Layout';

const IndexPage = () => (
  <Layout>
    <img src="/sample.png" width="270" height="480" />
    <Image src="/sample.png" width="270" height="480" />
  </Layout>
);

export default IndexPage;
```

### 検証1:ファイルサイズ/形式の最適化の確認

![スクリーンショット 2020-12-11 1.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/9b9f3169-0ead-df9a-104a-b9cd27392cdd.png)

- 注目する箇所に赤枠をつけました
    - `img`タグで読み込まれた1枚目は元画像のままpngで12.6MBあります
    - `Image`コンポーネントで読み込まれた2枚目はwebpで221kbになっています！
- ちゃんと最適化されていることが確認できました
    - 極端な例ではありますがレスポンスタイムも大違いですね！

### 検証2:レスポンシブ対応の確認

![スクリーンショット 2020-12-11 1.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/6ffcb1d9-8c88-ddcc-ee7b-b7eb030b99cf.png)

- ちょっと見づらいですがウィンドウサイズを狭めてみました
    - `img`タグで読み込まれた1枚目は`width`のサイズのままで横スクロールが発生しています
    - `Image`コンポーネントで読み込まれた2枚目はウィンドウサイズに合わせて縮小されています！
        - キャプチャではわかりませんがレイアウトシフトも発生しません！

## まとめ

- `img`タグを使うのと同じ感覚で`Image`コンポーネントを使うだけで最適化が施されていることを確認できました
- Next.jsの利用者側は何の負担もないので今後当たり前に使っていくといいですね！
【JavaScript】プロトタイプオブジェクトについて1

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

##Object

全てのオブジェクトの元となるオブジェクト。

Array, Functionなどオブジェクト型のインスタンスが作られる時、全てObjectオブジェクトを継承している。

Objectはprototypeという特殊なオブジェクトを持っており、Objectを継承してたインスタンスオブジェクトは、prototypeを参照することができる。

prototypeはいくつかのメソッドを持っており、プロトタイプオブジェクトと呼ばれる。当然、インスタンスオブジェクトはプロトタイプオブジェクトを使用することができる。

イメージ

```js
Object = {
     prototype : {   //プロトタイプオブジェクト
       toString : function( ){   //プロトタイプメソッド
        };
     };
  };

const obj = { };  //オブジェクト作成時に、Objectを継承する。
obj.toString() //プロトタイプメソッドを参照できる。
```
なお、インスタンス作成時にprototypeオブジェクトが複製されて、インスタンスがprototypeオブジェクトを持つ訳でなく、Objectオブジェクトのprototypeオブジェクトを参照できるようになっていることに注意。

##もし、インスタンスにprototypeメソッドと同名のメソッドを追加したら？

```js
const obj= {
  toString : function(){
      console.log("new to string");
     }
};  

obj.toString();

//  new to string
```
同名で定義した場合、プロトタイプメソッドよりインスタンスメソッドが優先される。

##Object.prototypeにプロパティーを追加した場合、インスタンスへの変化は？？

```js
const obj = {};
//Objectオブジェクトを継承するインスタンスobjを作成。
console.log(obj.name);
//undifined
//定義していないので当然

Object.prototype.name = "taro";
//Objectオブジェクトのprototypeオブジェクトのプロパティnameに"taro"という値を格納。

console.log(obj.name);

//taro

//objもObjectオブジェクトのprototypeオブジェクトのプロパティnameを参照するので、影響する。
```
if文とswitch文の使い分けってみなさんどう決めてます？私はこうしてます

自分がプログラミングを学習し初めの頃に思っていた疑問に答えますw
当時、条件分岐を作るif文とswitch文って書き方が違うけど、どういうふうに使い分けるんだろう？と思っていました。今は自分の中ではっきり使い分けています。１つの意見として初心者の方の参考になれば幸いです。

サンプルコードではC# を使用しています。

## switch文を使う時
私の考え方は、以下に挙げた「switchを選択する理由」がない場合にif文を選択しています。

switchを選択する理由：「ifより短くなる、みやすくなる場合」に選択

具体的には
(A)1つの判定したい値について、3つ以上に分岐をしたいとき。
(B)フォールスルーを使って２つ以上の条件で同じ処理にしたいとき
以上のいずれかに合致する場合にswitchを検討します。当てはまったとしても絶対使うわけじゃないんですが…

以下は(A)にも(B)にも当てはまる好例です。
switchとenumは相性がいい組み合わせです。if文だと「elseif(type == 〜)」がしつこく続いてしまいますが、さっぱり書けますね。
また、フォールスルーを活用したい時は特に使いたいです。フォールスルーは流れ落ちるというような意味で、caseを連続で書くことで、複数の値で同じ処理をする場合に明らかにifよりも読みやすく書けます。

```c#
enum Linetype
{
  None,
  New,
  Add,
  Edit,
  Delete,
  // ↑小技:最後の要素にも「,」をつけておくと、後ろに項目を追加するときに忘れなくて便利
}

// 編集可能な行の状態によって背景色を変えるときに使うイメージのメソッド
Color GetBgColor(Linetype type)
{
  // 途中でreturnで抜けるので、1つもbreakが無い例になってしまいましたが、
  // (A)の３つ以上に分岐している
  switch (type)
  {
    case Linetype.None:
      return Color.White;
    case Linetype.New:
    case Linetype.Add:
    case Linetype.Edit:
      // (B)フォールスルーを使い複数の条件について処理している
      return Color.Yellow;
    case Linetype.Delete:
      // 削除行は灰色で…というああいう感じの
      return Color.Gray;
    default:
      return Color.White;
  }
}
```


## switch文を使わない時にif文を使う
switchじゃないときはifを使っています。というか大抵if文を使うことが多いです。
必然的にbool値(マルかバツか)で判定するときはifを使います。
年齢とか幅を判定したいときはifです。
[Circle CI] steps型のparameterを利用して、ブランチごとにビルドの細部の処理を変える

複数ブランチでCircle CIのビルドを実行するとき、大まかな処理は同じだが、ブランチごとに細部のビルド処理を切り替えたいことが多々ある。「そういうときは、Circle CIのsteps型parameterで実現ですると良いかも」、という話。
(Circle CIのsteps型のparameterはC/C++で例えると、関数型ポインタのリスト)

## 状況

master/developにプッシュしたとき、大まかに以下の処理をCircle CIに実行させたいとする。

1. Setup
2. ビルド
3. デプロイ
4. 後始末(Slack通知、アーティファクト保存など)

ただし、masterとdevelopでは、細部の処理には違いを付ける。

- develop
  - Debug構成でビルドする
  - デプロイ先は外部から見えない環境にする
- master
  - Release構成でビルドする
  - デプロイ先は外部から見える環境にする


## steps型のparameterでブランチごとに処理を切り替える

Circle CIでは、jobに対して自分で定義した引数を渡すことができる。引数には型があり、steps型が指定でき、workflowから、jobにstepのリストを渡すことができる[^1]。これを利用して、ブランチごとにビルドの細部の処理を切り替える例を示す。


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

jobs:
  build:
    parameters:
      build_steps:
        type: steps
        default: # default値の指定の例を示したかっただけ。workflowから指定しているので意味はない。
          - build_debug
          - deploy_to_internal_env
    executor: foobar
    steps:
      - setup
      steps: << parameters.build_steps >>
      - post_steps

workflows:
  version: 2
  internal_release:
    jobs:
      - build:
          filters:
            branches:
              only:
                - develop
          build_steps:
            - build_debug
            - deploy_to_internal_env
  release:
    jobs:
      - build:
          filters:
            branches:
              only:
                - develop
          build_steps:
            - build_release
            - deploy_to_public_env
```

## 他の実現方法について

ブランチごとにビルドの細部の処理を切り替える方法はいろいろある。

まず、思いつくのは環境変数CIRCLE_BRANCHでブランチ名を取得して、if/elseで処理を切り替える方法だ。ただ、ときに分岐が複雑になりすぎるなどして、可読性が落ちることがある。後、1つのブランチに対してビルドを実行するトリガーが複数あり、トリガーに応じて細部の処理を切り替えたいケースには、きれいには対応できない。

他には、buildやdeployの部分を別jobにして、developのときとreleaseのに実行するJobを分ける方法もある[^2]。これだと、「ビルド前の準備 -> ビルド -> デプロイ -> 後始末」という流れは別々にメンテンナスしないといけない。

steps型のparameterを使うことで他の方法よりきれいにビルド処理を書けるかも、ということ。

[^1]: https://circleci.com/docs/2.0/reusing-config/#parameter-types
[^2]: 具体的には、build_debug, build_release Jobを定義して、developのworkflowではbuild_debug、releaseのworkflowではbuild_releaseを実行させる
kubectl cp がうまく行かない時に試すこと

# やりたいこと

podからlocal(host)へファイルをcpしたい。

# でてきたエラー、警告
```
tar: xxx: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
```

```
tar: Removing leading `/' from member names
```

# 試すこと
##### 絶対パス指定してみる

```
kubectl cp <pod>:/var/www/html/index.html ./index.html
```

##### 絶対パス(先頭の"/"なし)にしてみる

```
kubectl cp <pod>:var/www/html/index.html ./index.html
```

##### WORKDIRにファイルを配置して、cpしてみる

ファイルをWORKDIR?(exec -it <pod> -- bashで入った時のパスの場所)にファイルを配置して、パスなしのファイル名だけで```kubectl cp```

操作例

```
> kubectl exec -it <pod> -- bash
> cp ./dir/other.html ./
> kubectl cp <pod>:other.html ./othe#r.html
```

# 参考
[[k8s]kubectl copy が「tar: Removing leading `/' from member names」で失敗](https://qiita.com/toshihirock/items/78b36dea04cba0c21e7b)
[kubernetesポッドからローカルシステムにファイルをコピーする方法](https://www.it-swarm-ja.tech/ja/kubernetes/kubernetes%E3%83%9D%E3%83%83%E3%83%89%E3%81%8B%E3%82%89%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%B3%E3%83%94%E3%83%BC%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/807100161/:kubernetes)
[Kubectl cp gives "tar: removing leading '/' from member names" warning](https://github.com/kubernetes/kubernetes/issues/58692)
方程式の解法をPythonを使って解いてみる【ニュートン法】

<!-- textlint-disable -->
大学で物理学を専攻しています。今回（これが初投稿だけど・・・）はニュートン法と二分法を Python を使って解いてみようと思います。

# ニュートン法とは
**ニュートン法**、または**ニュートン・ラフソン法**は、数値解析の分野いおいて、方程式を数値計算によって解くための反復法による球根アルゴリズムの 1 つです。

手順としては、関数$f(x)$について、
1. ある$x_1$の数値を決定する
2. $f(x_1)$を求め、その$x_1$の接戦の式より$y=0$と交わる$x$の値を$x_2$とする
3. $f(x_2)$を求め、その$x_2$の接線の式より$y=0$と交わる$x$の値を$x_3$とする
4. これを繰り返すことによって、$x_1, x_2$は$f(x)=0$となる$x=a$の値に近づいていく
といった流れになっています。
![2020-03a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/32c20ee6-09fd-e6b2-3280-ae0c1d5970e1.png)

この一連の手順は、定式化されています。
接線の式は$f(x_n)=f'(x_n)(x_n - x_{n+1})$と表すことができるので、式変形すると、
$$
f(x_n)=f'(x_n)(x_n - x_{n+1})
\Leftrightarrow　x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
$$
といった形になります。

# Pythonを用いて表現してみよう
具体例として、**$f(x)=e^x-4x$ に対して $f(x)=0$**を解いていきます。
微分については$f'(x)=e^x -4$であることを用いります。$f(x), f'(x)$をそれぞれ f(x), df(x)と定義し、初期値を$x=4$とします。

## 実際のコード
```Python
import numpy as np
import matplotlib.pylab as plt

def f(x):
  return np.exp(x)-4*x

def df(x):
  return np.exp(x)-4

#初期値
x=4

#epsilon1は要求精度。これよりも数値精度がよくなったら二分法の繰り返しを終了する。
epsilon1=0.00001

# n, c, f(c) を値を出力する。\t はタブという空白を適当にあける命令です。
print("n\t x\t f(x)")
n=1
# while文でf(x)=0になるまで繰り返す
while True:
  x = x - f(x)/df(x)
  print("{}\t{:.5f}\t{:.5f}".format(n, x, f(x)))
  n += 1
  if abs(f(x)) < epsilon1:
    break 

print("x= %f" % x)
```
すると結果は$x= 2.153292$という値になります。

## 確認してみよう
実際に Python を用いてグラフを作成して、確認してみたいと思います。
使用するコードは以下の通りです。

```python
import numpy as np
import matplotlib.pylab as plt

def f(x):
  return np.exp(x)-4*x

#0<x<4の間で描画
x=np.arange(0.0,4.0,0.05)
#zは、f(x)=0を描画
z=np.zeros(len(x))
plt.plot(x,f(x),x,ｚ)
```
これより、グラフは次のように描かれます。
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/2de8ddb0-a2d4-2320-a0da-89ce83b3c7e4.png)
このグラフから、実際に、$x= 2.153292$に答えがあるとわかります。

# 余談
ニュートン法は、scipy.optimize に入っているので

```python
import scipy.optimize as spopt

def f(x):
  return np.exp(x)-4*x

spopt.newton(f,4)
```
とすれば、簡単に求めることもできます。scipy.optimize については[こちらよりご参照ください](https://docs.scipy.org/doc/scipy/reference/optimize.html)

ご高覧ありがとうございました。
# 参考文献
[ニュートン法]（https://mathworld.wolfram.com/NewtonsMethod.html）
<!-- textlint-enable -->
Scilabによるオーディオプログラミング例

Scilab
===

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)

# 概要

https://www.scilab.org/

数値解析、データ視覚化、アルゴリズム開発用プログラミング環境。GPLライセンスのオープンソース。MATLABに非常に近い構文を持つが完全な互換性はない。また、MATLABのSimulinkに似たビジュアルモデリングツールXcosも含まれる。ただし、Xcosはリアルタイム音声出力機能は持たない。サウンドファイルの入出力は可能。

1990年代にINRIA(フランス国立情報学自動制御研究所)とENPC(フランス国立土木学校)により開発。2010年Scilab Enterprises社設立、2017年Scilab Enterprises社はESI Groupに買収されたため、現在はESI Groupにより管理されている。

# 実装例

## サイン波生成

sound()の代わりにplaysnd()で音を鳴らす以外MATLABと同じです。

```matlab
Fs = 44100;
duration = 1;
frequency = 440;
gain = 0.3;
phase = 0:1/Fs:duration;
arr = gain * sin(2 * %pi * frequency * phase);
playsnd(arr, Fs)
```

## Delayエフェクト

こちらもMATLABとほぼ同じです。相違は以下の3点です。

* ファイル読み込みはaudioread()ではなくwavread()
* 配列の結合をcat()でおこなう
* 音声出力はsound()ではなくplaysnd()


```matlab
[y, Fs] = wavread('../voice.wav');

delayTime = 0.4;
feedback = 4;
wetLevel = 0.5;
attenuate = 0.5;

delaySample = round(delayTime * Fs); 
wet = attenuate * cat(2, zeros(1, delaySample), y);
for i = 2 : feedback
    currentWet = (attenuate^i) * cat(2, zeros(1, delaySample), wet);
    wet = cat(2, wet, zeros(1, delaySample));
    wet = wet + currentWet;
end
y = cat(2, y, zeros(1, delaySample * feedback));
y = y + wet * wetLevel;

playsnd(y,Fs);
```

# 感想

ScilabもGNU Octave同様オープンソースのMATLAB代替として十分な能力を持っている印象です。この分野の言語は計算結果をグラフ出力することが多いため、グラフィックキャンバスを持ったIDE上で実行することになります。ScilabのIDEも十分に洗練されていて使いやすいです。拡張用のToolboxもMATLABほどではありませんが用意されています。ここまで高機能なのでXcosでリアルタイム音声信号処理ができないのは少し残念に感じました。

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)
Typescriptを使ってないプロジェクトでVeturのtemplate内での型推論の警告(Vetur2339)が出てしまう問題への対処法

#症状
vscodeを使っていて、Vueプロジェクトでいつからか急にtemplate内で型への警告が出るようになりました。
Typescriptを導入しているプロジェクトではなく、型への警告を出されてもちょっと困るなあと思っていました。
以下のように怒られます。

```

Property '$store' does not exist on type 'CombinedVueInstance<Record<never, any> & Vue, object, object, object, Record<never, any>>'.Vetur(2339)
```

#対応

どうやら、原因はVueを書くなら誰もが入れるであろうvscode拡張機能のVeturのtemplate内での型推論機能が働いているようでした。
そこでvscodeの設定のsettings.json内で以下のようにすることで型推論の警告が出なくなりました。

```settings.json
{
  "vetur.experimental.templateInterpolationService": false,
}
```
角丸・枠線をつける方法

今回は簡単にコードで角丸・枠線をつける方法を紹介していこうと思います！

UIButton.UITextFiledなどのUIKitにはほとんど角丸・枠線をつけることができます。

コードはこんな感じ

```swift:sampleViewController

import UIKit

class sampleViewController: UIViewController {
    
    @IBOutlet weak var textFiled: UITextField!
    @IBOutlet weak var Button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        cornerRadius()
        border()
    }
    
    
    
    func cornerRadius() {
        textFiled.layer.cornerRadius = 10
        Button.layer.cornerRadius = 30
    }
    
    func border() {
        textFiled.layer.borderWidth = 5
        textFiled.layer.borderColor = UIColor.black.cgColor
        Button.layer.borderWidth = 20
        Button.layer.borderColor = UIColor.black.cgColor
        
    }
    
}

```


`cornerRadius`を使って角丸
`borderWidth`を使って枠線
`borderColor`を使って枠線の色

これらを使うと角丸・枠線をつけるができました！！
numba の Typed List が速くなった

11月の末に公開された Numba 0.52.0 では、Intel からの寄贈により Typed List のパフォーマンスがよくなった（[Release Notes](https://numba.readthedocs.io/en/stable/release-notes.html) 参照）ということなので、実際に試してみました。

## 本当に速くなっていたのは、Reflected List だった

Typed List のパフォーマンスがどれぐらい良くなったかを試すため、以下のコードで、clac_typedlist(2000) を計算してみると、ver 0.48.0 では 250ms かかっていたものが、ver 0.52.0 では 132ms と約半分に改善されていました。かなり改善されているものの、もともとが Python の速度とほとんど変わらないぐらい遅かったので、少しがっかりしました。 

```python
from numba.typed import List


@njit
def clac_typedlist(n):
    x = List()
    for i in range(n):
        y = List()
        for j in range(i + 1):
            y.append(j)
        x.append(y)
    sum_ = 0
    for i in range(n):
        for j in range(i + 1):
            sum_ += x[i][j]
    return sum_
``` 

試しにと思って、Reflected List の方も試してみました。以下のコードで試すと、ver 0.48.0 では 82ms かかっていたものが、ver 0.52.0 では 16ms と大幅に改善されています。生の Python より20倍ぐらい処理が早くなっています。

```python
@njit
def clac_reflectedlist(n):
    x = [[y for y in range(i + 1)] for i in range(n)]
    sum_ = 0
    for i in range(n):
        for j in range(i + 1):
            sum_ += x[i][j]
    return sum_
```


## 今後への期待

Typed List については問題が多く、[Projects の一つ](https://github.com/numba/numba/projects/14)になっています。それにもかかわらず長い間抜本的な改善がなかったのですが、今回、大きく改善されたのが、Reflected List の方であったとしても、Typed List の方も、今後やっと改善されていくのではないかと思われます。

Numba のメリットはなんといっても、pythonのコードを手軽に高速化できることです。また、Cuda と AMD ROCm にも対応しているので、GPU を使って計算を高速化できるというのも大きなメリットです。一方で、Python と比べると、Python の機能の一部しか使えず、制約が大きいので、不便だと感じる人は多いと思います。今後、List, Dict, Set というコンテナが十分に成熟していないという問題が解消されると Numba はかなり使いやすくなると思います。

## PyPy よりも高速になった

AtCoder 等の競技プログラミングでは、PyPy の方がよく使われていますが、AtCoder で list を使った速度の比較をしてみました。Qiita の記事「[AtCoderで Python を高速化する Numpy + Numba を使う](https://qiita.com/yniji/items/d012bb9f938e0445a3ff])」で使った ABC129 の問題 D を使って試すと以下のようになりました。Reflected List の場合、PyPy3 より速くなりました。現在の Numba では、Graph の問題で ndarray が使えない場合には困っていたのですが、PyPy より高速であれば、TLE になる心配はほぼないので安心して使えるようになります。

| 種別  | 実行時間  | 詳細|
|:--|--:|--:|
| Python(list) |  TLE | [詳細](https://atcoder.jp/contests/abc129/submissions/18665129) |
| PyPy3  | 422 ms  | [詳細](https://atcoder.jp/contests/abc129/submissions/18660137) |
| Numba (AOT np.ndarray) | 188 ms  | [詳細](https://atcoder.jp/contests/abc129/submissions/18539227) |
| Numba (AOT Reflected List)  | 307 ms  | [詳細](https://atcoder.jp/contests/abc129/submissions/18668538) |
| Numba (AOT Typed List)  | 841 ms  | [詳細](https://atcoder.jp/contests/abc129/submissions/18551393) |

なお、Reflected List、Typed List の場合は、Numba 0.52.0 を使用する必要があるため、AtCoder への提出は、自分でコンパイルをしてバイナリを提出することで行っています。
Unity ShaderGraph レシピ #2 シンプルなグリッド（色指定）

#シンプルなグリッド（色指定）
![スクリーンショット 2020-12-10 1.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/b506aefb-0154-a7c7-c035-a84501b12d4a.png)



# 作り方

### Color & Multiply
まず[白い線のグリッドを作って](https://qiita.com/Teppy/items/34d8ea7de87f94458ab2)、ColorノードとMultiplyノードで色合成して実現します。

![スクリーンショット 2020-12-10 0.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/9b8e6c28-9abb-ab28-a89e-81bfc49c662b.png)

色を自由に設定したい場合は、**白を作ってからカラーノードと掛け合わせる** と覚えましょう！
検索フォームを作成　Rails

検索フォームの作り方が分からず非常に苦労したため備忘録として残しておく。

検索の流れ
1. 検索フォームへキーワード入力
2. 該当するページへ遷移
3. キーワードを入れずに検索した場合は全データを表示

viewに検索フォームを記述
--------------------

```index.html.erb

 <%= form_tag search_path, method: :get do %>
  <%= text_field_tag :search, params[:search], class: '適宜', placeholder: '適宜' %>
  <%= submit_tag 'search' %>
 <% end %>
```
form_tag: モデルに基づかないformを作る際に利用　※検索機能ではこちらを使う
form_for: 任意のモデルに基づいたformを作る際に利用
methodをgetで指定

コントローラーにsearchアクションを追加
-----------------------------
viewの検索formで取得したパラメータをモデルへ渡す

```ruby:pages.controller
 def search
    @search = House.search(params[:search])
 end
````
モデルにsearchメソッドを記述
----------------------

```ruby:house.rb
①
 def self.search(search)
    return House.all unless search
     House.where(['city LIKE?', "%#{search}%"])
 end

①か②の記述（どちらも意味は同じ）

②
 def self.search(search)
   if search 
    House.where(['city LIKE?', "%#{search}%"])
   else
    House.all
   end
 end
```
1. 上記のsearchメソッドはコントローラーに記述しても良いが、今後も同じような記述が増えた場合に、後日見返した時や他人が見た時にわかりにくいのでモデルに記述する。
2. whereメソッドは、該当するデータを全て返すので検索結果を一覧で表示したい時に使う。
3. cityの部分は検索をかける際のカラムを指定している
4. "%#{search}%"は、"%検索したい文字列%"のように検索したい文字列の前後を%で挟むことで部分一致の検索ができる記述。

遷移先のviewに検索結果を表示する
---------------------------

```search.html.erb
  <% @search.each do |house| %>
    <%= link_to house_path(house.id)%> 
  <% end %>
```

まとめ
コントローラーに記述しすぎるのはよくないので、適宜モデルに記述していくことで可読性を高める。