OmniAICreator/Qiita-1.07M huggingface dataset:
書籍「深層学習」を読む際に参考にしたサイト

# はじめに

深層学習という書籍を読むにあたって、様々なサイトを参考にさせていただきましたので、まとめます。
参考サイトの筆者の方々には頭が上がりません。わかりやすい情報の発信、ありがとうございます。

[Amazon / 深層学習 (機械学習プロフェッショナルシリーズ)](http://amzn.asia/d/3UZFHeg)



# 第１章: はじめに

- [Chapter 01 #ml-professional](https://www.slideshare.net/beeEaMa/chapter-01-49404580)



# 第２章: 順伝播型ネットワーク

- <https://youtu.be/L_6idb3ZXB0>
- <https://youtu.be/w9OFiOaTFs8>
- [Chapter 02 #ml-professional](https://www.slideshare.net/beeEaMa/chapter-02-49488411)
- [Deep Learning chap.1 and 2](https://www.slideshare.net/ponta63/deep-learning-chap1-and-2-74178893>)
- [2値分類・多クラス分類](https://www.slideshare.net/tdev1/243-69787300)



# 第３章: 確率的勾配降下法

- <https://youtu.be/5g0TPrxKK6o>
- [確率的勾配降下法とは何か、をPythonで動かして解説する](https://qiita.com/kenmatsu4/items/d282054ddedbd68fecb0)
- [Deep Learning chap.3_1](https://www.slideshare.net/ponta63/deep-learning-chap31)
- [Deep Learning chap.3_2](https://www.slideshare.net/ponta63/deep-learning-chap32)
- [勾配降下法の最適化アルゴリズム](https://www.slideshare.net/nishio/ss-66840545)



# 第４章: 誤差逆伝播法

- <https://youtu.be/WZDMNM36PsM>
- [Deep learning chap.4_1](https://www.slideshare.net/ponta63/deep-learning-chap41)
- [Deep learning Chap.4_2](https://www.slideshare.net/ponta63/deep-learning-chap42)
- [バックプロパゲーション](http://ibisforest.org/index.php?plugin=related&page=%E3%83%90%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%83%91%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)



# 第５章: 自己符号化器

- [Deep learning chap.5_1](https://www.slideshare.net/ponta63/deep-learning-chap51)
- [Deep learning chap.5_2](https://www.slideshare.net/ponta63/deep-learning-chap52)
- [機械学習プロフェッショナルシリーズ輪読会 #2 Chapter 5 「自己符号化器」 資料](https://www.slideshare.net/at_grandpa/chapter5-50042838)



# 第６章: 畳込みニューラルネット

- [畳み込みニューラルネットワークの仕組み](https://postd.cc/how-do-convolutional-neural-networks-work/)
- [高卒でもわかる機械学習 (7) 畳み込みニューラルネット その1](http://hokuts.com/2016/12/13/cnn1/)
- [定番のConvolutional Neural Networkをゼロから理解する](https://deepage.net/deep_learning/2016/11/07/convolutional_neural_network.html)
- [Standford wiki / Convolution schematic.gif](http://deeplearning.stanford.edu/wiki/index.php/File:Convolution_schematic.gif)
- [深層学習 第6章 畳込みニューラルネット](https://qiita.com/t_niimura/items/423468de4dc1e0fca8f4)



# 第７章: 再帰型ニューラルネット

- [RNN](https://axa.biopapyrus.jp/deep-learning/rnn/)
- [再帰型ニューラル・ネットワークの徹底調査](https://www.ibm.com/developerworks/jp/cognitive/library/cc-cognitive-recurrent-neural-networks/index.html)



# 第８章: ボルツマンマシン

- [Restricted Boltzmann Machines - Ep. 6 (Deep Learning SIMPLIFIED)](https://www.youtube.com/watch?v=puux7KZQfsE)
- [制限付きボルツマンマシンの初心者向けガイド](https://postd.cc/a-beginners-guide-to-restricted-boltzmann-machines/)
- [Chapter 8 ボルツマンマシン - 深層学習本読み会](https://www.slideshare.net/taikaitakeda/8-boltzmann-machine)



# さいごに
なんとか、読み切ることができました。
数学のスキルが少し上がった気がします。
C言語　分割統治法を使った最大値を求めるアルゴリズム

勝ち抜きトーナメントのイメージ。
隣り合った数の中で大きい方が上がってきます。
最初に呼び出すときは

```c
find_max(A, 0, 配列数-1)
```
で書くこと。

```c
#include <stdio.h>

int find_max(int A[], int left, int right)
{
    if (right == left)
        return A[left];
    int mid = (left + right) / 2;
    int x1 = find_max(A, left, mid);
    int x2 = find_max(A, mid + 1, right);
    printf("%d %d\n", x1, x2);
    if (x1 > x2)
        return x1;
    else
        return x2;
}

int main(void)
{
    int A[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    printf("%d\n", find_max(A, 0, 7));
}
```


##参考
https://www.jaist.ac.jp/~uehara/course/2008/i431/pdf/04greedymini.pdf

##感想
再帰をすんなり理解するのは難しい
wordpress タクソノミー とカスタムフィールドのちょっと便利な話

__記事を書いた時の各バージョンです。__
wordprss 5.3.2
acf pro 5.8.9

# こんなシーン
wordpressカスタム投稿と一緒に、カスタムタクソノミーを設定する際に、それぞれのタームに連動したカスタムフィールドが欲しい・・・。

__例えば__
・タームごとにアイコンを出力したい。
・タームごとに独自の（slugとは別の）クラスを付与したい。
・日本語名に対する、他言語翻訳を同時に設定したい。

やりようはいくらでもあるかと思いますが、タームに連動したカスタムフィールドを追加することでよりスマートに実現できます。
しかし、値の取得は通常のカスタムフィールドとは手順が異なります。

# タクソノミー実装
ひとまずこんなかんじでしょうか。

```php:tax.php
add_action('init', 'register_cf');
function register_cf()
{
  register_post_type(
    news,
    array(
      'labels' => array(
        'name' => __('NEWS'),
        'singular_name' => __('NEWS'), // 以下略
      ),
      'has_archive' => true,
      'public' => true,
    )
  );

  register_taxonomy(
    news_tag,
    news,
    array(
      'labels' => array(
        'name' => __('タグ'),
        'singular_name' => __('タグ'), // 以下略
      ),
      'public' => true,
    )
  );
}
```
カスタム投稿（news）にカテゴリー（news_tag）が設定されます。
あとは、acfのフィールド追加画面「位置」でタクソノミー 等しい カテゴリー（news_tag）が選択できるので、選択します。
ターム設定画面にフィールドが追加されていたら成功です。

# 値の取得
今回は、newsに「政治」というタームを追加したとします。
カスタムフィールドに英語訳「politics」を指定して、値を取得します。
（カスタムフィールド名は「`en_tag`」とします。）

```php:tag.php
// 前後の記述は省略します。

$taxs = get_the_terms($post->ID, 'news_tag');
foreach ($taxs as $tax) {
 // タームのID取得
 $id = esc_html($term->$term_id);
 $idsp = 'news_tag_'.$id;
 // IDに基づいたカスタムフィールドの取得
 echo get_field('en_tag', $idsp);
}

// 前後の記述は省略します。
```

上記の例だと、他言語サイトにおいてタクソノミーの管理がしやすくなるので、便利です。
Docker imageとかの格納場所を変更したかった。


環境はWindows10pro、Docker for Desktopについて

Dockerを使えるようになろうと、記事やらリファレンスやら読みながら環境構築中の時の事

あれ、Cドライブの容量足りなくね？と気づいた。

もともとHyperVと仮想環境勉強の為にCPUは仮想環境の使用に耐えるものは用意したが、
パーティションはテキトーでCは128GBのSSD、Dに2TBだかで切っていた。

SSDに放り込んどきたいけど他のデータ整理めんどいしDockerimageって意外と容量取るんだね・・・。
imegeファイルだけでもDに移せないか試みる。

調べたらProgramDataのDockerフォルダ配下のdeamon.jsonファイルに

```
{
 "data-root": "ディレクトリパス"
}
```
と記述するのが有力。
しかしディレクトリ漁ってもなかったので作成してDockerデーモン再起動。
反応せず。
なんでよと思いつつデーモン右をクリックしたらそれっぽいのがあった。
![スクリーンショット (281).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536796/669fb96d-43de-c158-451e-0f7394521126.png)
あー、これ直接編集すればいいのかと実行。
反映またされた挙句結局エラー。

意味わからんと、Windows版でなんか違うのかと調べること数時間
Docker for windowsと通常のDockerで仕様が全く違うことが判明。

そもそもWindowsで使えるコンテナは2種類あるらしい（もっとあるかも、無知なのでスルーして下さい）
1つはWindowsServerコンテナ、Dockerの技術が使われているWindowsServerで使えるコンテナ技術
２つ目がHyper-Vコンテナ、Windows10proでも使えるコンテナ

WindowsServerコンテナってのはそもそもDockerコンテナじゃない
これとHyper-Vコンテナを混同すると
あれ記事とかで書かれてること全くできねーんだけど！ってなるっぽい。

Hyper-Vコンテナっていうのはでlinuxコンテナをwindows使うために、
仕方なくHyper-Vで仮想ハードウェアを立て、その上にDockerimageをpullしたりコンテナを起動している模様。

つまりimageの格納場所は仮想のディスクイメージにという事らしい。
Dockerデーモン起動中にHyper-Vマネージャー見てみると確かになんか実行中になってるわ・・・。

ていうかDocker for windowsの要件にHyper-Vが条件になってる時点で気づかないとは愚鈍でしたねぇ。

よってvhdxをDドライブに移動してあげました。これでたぶん解決。


ハマった原因：構造も基礎知識も知らないまま使おうとした事。
React NativeでHighcharts を使う

# インストール

まずはGithubの公式ドキュメント通り進めます。

```
npm install react-native-highcharts --save
```

上記インストールで進めようとすると、

```
Unable to resolve module `react-native-webview` from `node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
```

で怒られます。

# エラー回避
## モジュールの追加

そこで、エラーで指摘されるスクリプトを確認すると、そのフォルダでimportしているモジュールがインストールされていません。なのでコマンドで必要なモジュールを追加します。

```
npm install react-native-webview --save
```

## CDNオプションの追加
これでインポートエラーは回避できますが、早速、公式ドキュメントのサンプル通りのスクリプトを動かそうとすると、iOSシミュ−レーターでは表示されません。。

色々と探した結果、以下のようにオプションを追加してもらえば無事表示されました。
参考記事；https://github.com/highcharts/highcharts-react-native/issues/4

```
<View>
  <HighchartsReactNative
  useCDN={true}
  useSSL={true}
  styles={styles.chart}
  options={this.state.chartOptions}
/>
</View>
```
🍰【CakePHP2】存在する値を消さずにカラム名変更のみをするマイグレーション

## 環境
PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27

## やりたいこと

カラム名変更マイグレが見つからなかったのでメモ

## やったこと

❌Migrations.migration generateの自動生成だとこれができたが
これだとカラム削除＆追加を行うマイグレなので存在する値が消去されてしまう

```app/Config/migration/xxxxxxxxx_RenameColumnHogeToFuga.php
/**
 * Actions to be performed
 *
 * @var array $migration
 */
	public $migration = array(
		'up' => array(
			'create_field' => array(
				'test_table' => array(
					'fuga' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'after' => 'item_name'),
				),
			),
			'drop_field' => array(
				'test_table' => array('hoge'),
			),
		),
		'down' => array(
			'drop_field' => array(
				'test_table' => array('fuga'),
			),
			'create_field' => array(
				'test_table' => array(
					'hoge' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false),
				),
			),
		),
	);
```

🔵これならカラム名称変更のみなので存在する値が入ったまま

```app/Config/migration/xxxxxxxxx_RenameColumnHogeToFuga.php
/**
 * Actions to be performed
 *
 * @var array $migration
 */
	public $migration = array(
		'up' => array(
			'rename_field' => array(
				'test_table' => array(
					'hoge' => 'fuga'
				),
			),
		),
		'down' => array(
			'rename_field' => array(
				'test_table' => array(
					'fuga' => 'hoge'
				),
			),
		),
	);

```
ScalaのTCPソケット通信（簡易）

# はじめに

ScalaでTCP通信をやるときに参考にできるサイトがなかったので、メモ書き程度に記しておく。
以下のサイトを参考にしてjavaからscalaに書き直した。
[【Java】TCP通信を利用したデータ送受信](https://nompor.com/2018/05/15/post-3731/)
[Java ソケット通信のサンプル](https://itsakura.com/java-socket)

# サーバ

```scala:Server.scala
import java.io.{BufferedReader, InputStreamReader}
import java.net.ServerSocket

object Server extends App{

  // ソケット作成とか
  val svSock = new ServerSocket(10000)

  // 接続を受信
  val sock = svSock.accept()

  // データを受信するための物
  val in = new BufferedReader((new InputStreamReader(sock.getInputStream)))

  //　データを受信
  val readSize = in.readLine()


  println(readSize)
  in.close()
  svSock.close()
}
```


# クライアント

```scala:Client.scala

import java.io.{OutputStream, PrintWriter}
import java.net.Socket

object Client extends App {

  // ソケット作成とか
  val sock = new Socket("localhost",10000)

  // 送信するための物
  val out = new PrintWriter(sock.getOutputStream)

  // 送信したいデータ
  val sendData = "送信出来てる？"

  // 送信
  out.write(sendData)

  println("送信内容 = 「"+sendData+"」")
  out.close()
  sock.close()
}
```

# おわりに
間違いがあれば適宜修正する。
【MySQL】migrationでいらないテーブル作っちゃったら

## 三行
- migrationでいらないテーブルを作ってしまったら
- テーブルの名前を変更したいときは
- schema_migrationsテーブルを更新しよう

## 背景
CakephpやLaravel, Railsなどのwebフレームワークではデータベースの構造を更新するマイグレーションという仕組みがよく使われています。
DBの構築などを手作業なしで行うことができてとても便利なものです。

今回はこのmigrationの仕組みを使ってちょっとやらかしたのでその内容と復旧方法をまとめます。

## やっちまったこと

1. テーブル作成のマイグレーションファイルを作成
2. マイグレーションを実行
3. 作ったテーブルの名前を変更することに
4. マイグレーションファイルを編集して違う名前のテーブルをつくるものに書き換え
5. マイグレーションを実行
6. 古い名前のテーブルと新しい名前のテーブルが同時に存在することに！

## 原因

明示的にdrop tableしたわけではないので当然といえば当然です。
とはいえ今後は使わないテーブルを作るマイグレーションファイルを残しておくのも気持ち悪いです。

## 対処
今回はローカルおよびdev環境だったので手動で対応しました。
具体的には以下2点。

- schema_migrationsテーブルの該当のレコードをdelete
- 古い名前のテーブルをdrop

dropはまぁいいですね。
普通の操作です。

schema_migrationsとはなんでしょう？

もし手元に環境があったらshow tablesしてみてください。
schema_migrationsというテーブルがありませんか？

実はこれがマイグレーションの履歴を保持しているテーブルです。
もしdropしただけだとこのschema_migrationsに古い名前のテーブルを作った時のマイグレーションの履歴が残っていてデータベースの状態とマイグレーションの履歴に不整合がある状態になってしまいます。

そのため、テーブルのdropだけではなくschema_migrationsの更新が必要になります。
今回はテーブル作成のマイグレーションだったのでdropしていますが、これがカラム追加だったならばカラムの削除が必要です。

要はマイグレーションファイルのdown関数の中で実行するはずだった手順を手動で実行してrollbackしていることになります。

## まとめ
テーブルの名前は慎重につけましょう。
【VS Code】Bashをフォルダーを指定して起動する方法

VS Codeで、ターミナルの設定をBashにしたいと思いました。
Bash起動時のフォルダーを開いているソースと同じフォルダーにしたかったのですが、Bashの起動オプションには該当するオプションが見つかりませんでした。Googleで探してみたのですが、ショートカットを使う方法しか見つかりませんでした。
試行錯誤の結果、コマンドプロンプト（cmd.exe）を使って指定できましたので、ご紹介いたします。

## 前提条件

- Windows環境の方法となります。（Windows 10でのみ確認）
- フォルダツリーが以下の場合の設定です。

  ```text
    c:\VSCode
    ├─Git
    │  └─bin
    │    └─bash.exe
    └─VSCode.exe
  ```

## 実行コマンド

- コマンドプロントを"/c"オプションを使用してフォルダーを変更後、Bashを起動しています。  
- コマンドプロンプトのオプションに関しては以下のサイトを参考にさせていただきました。  
[Programming Field:Cmd - DOS コマンド一覧](https://www.pg-fl.jp/program/dos/doscmd/cmd.htm)

  ```text
  %windir%\system32\cmd.exe /c cd /d "フォルダー名" & c:\VSCode\Git\bin\bash.exe
  ```

## Settings.json を変更

- [settings.jsonの場所](https://code.visualstudio.com/docs/getstarted/settings#_settings-file-locations)  
ページ内に Settings.json の詳細がありますので興味のある方は読んでみてください。

### Git Bash の設定例

  ```json:settings.json
    "terminal.integrated.shell.windows": "${env:windir}\\system32\\cmd.exe",
    "terminal.integrated.shellArgs.windows": [
      "/c",
      "cd /d ${fileDirname}",
      "& c:\\VSCode\\Git\\bin\\bash.exe"
    ],
  ```

## VS Codeのテーマを作成しております

せっかくなので宣伝をいたします。
Visual Studio Code用のライトテーマ、[kindfeeling-light](https://marketplace.visualstudio.com/items?itemName=Aromatibus.kindfeeling)を作成させて頂いております。
完全にわたしの好みで作っているので好き嫌いはあると思います。
お時間頂けましたら、ぜひぜひお立ち寄りくださいませ。
ArchLinuxで自動で時刻を同期する方法

## 時刻を合わせる
ArchLinuxではいろんな方法で時刻を合わせることができますが、最も簡単なのは`systemd`のクライアントを利用することです。

`systemd-timesyncd.service`を使用します。

```bash
# 自動起動
sudo systemctl enable systemd-timesyncd.service

# 同期
sudo systemctl start systemd-timesyncd.service
```
LaravelでZipファイルに圧縮する実装をしてみた(Laravel6.0以降の対応)

<h2>やりたいこと</h2>
結論からいうと、Laravelのstorage/logsディレクトリ配下の**logファイルをzip形式に圧縮するよ**って話です。

業務で関わっているサービスでstorage/logsディレクトリ以下をS3に保存する処理があるのですが、如何せんlogファイルのサイズが大きくS3のボリュームがすぐにいっぱいになってしまいます。

そこで、s3に保存するファイルをzip形式に圧縮しようとなり、その時に実装を備忘録として残します。

＊今回、あくまでzipファイルを作成するまでの処理で、s3に保存する処理は省略しています。

<h2>zipファイル作成にはZipArchiveを使えば楽</h2>
かつてはchumper/zipperをcomposerでインストールすれば簡単にzipファイルを作成できたらしいのですが、どうやらLaravel6.0以降ではchumper/zipperが使用できなくっていました。

ですので、Laravel6.0以降では**ZipArchive**を使いましょう！

以下のように書きました。
(開発の終わりでリファクタリングする予定ですが、取り急ぎのコードだということを御了承ください)

```　　　
        // 任意のファイル名を決める
        $logPath = storage_path('zip/log' . '.zip');
        // zipArchive発動
        $zip = new ZipArchive();
        $zip->open($logPath, ZipArchive::CREATE);

        for($i = 1 ; $i <=3  ; $i++) {
          // storage/logsディレクトリ以下のファイルを追加
          $zip->addFile('storage/logs/data/data-'. $i . '.log');
          $zip->addFile('storage/logs/debug/debug-'. $i . '.log');
          $zip->addFile('storage/logs/error/error-'. $i . '.log');
        }
        $zip->close()
```

これでstorage/logsディレクトリ以下にzipディレクトリが作成されて、logsファイルが圧縮された形で保管されているはずです。

<h2>追加で</h2>
例えば、3日前のlogだけを取得したい場合などはCarbonで指定してあげればいいですね。
僕は実務で以下のように書きました。

```
$subDay = Carbon::now()->subDay(3)->toDateString();

　　　　 for($i = $subDay ; $i <=$subDay  ; $i++) {
          // storage/logsディレクトリ以下のファイルを追加
          $zip->addFile('storage/logs/data/data-'. $i . '.log');
          $zip->addFile('storage/logs/debug/debug-'. $i . '.log');
          $zip->addFile('storage/logs/error/error-'. $i . '.log');
       }  
```

簡単ですが、以上になります。

<h3>参考サイト</h3>
[【Laravel】zip、gzip、bz2で圧縮してダウンロードする方法](https://blog.capilano-fw.com/?p=4549)
いつもお世話になっているサイトです。ありがとうございます。
フリーの日本語OCR（と学習済みのモデル）を公開しています。

# フリーの日本語OCR（と学習済みのモデル）を公開しています。

<img width="541" alt="OCR概要" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/95b967dd-bf1b-b810-c10f-6e19a1697a23.png">

## 日本語OCRです。

OCRとは、画像を入力して、文字を認識するプログラムです。
今回、趣味で作った日本語OCRのプログラムと学習済みのモデルを公開しました。
以下のGitHubからダウンロードして使うことが出来ます。

https://github.com/tanreinama/OCR_Japanease

### **GoogleVisionとかのOCR APIと何が違うの？**

- 無料です
- 改変自由です
- 商用利用可です
- というかMITライセンスです
- サーバー無しで動かせます

### **認識出来る文字の種類は？**

- ひらがな、カタカナ、常用漢字、幾つかの英数記号を認識します
- 白抜き文字にも対応します
- 縦書き・横書き両対応します

### **動かせる環境は？**

- Python3
- 推奨環境：GPUメモリ≧6GB、Linux OS、Pytorch、OpenCV-Python

### **モデルの学習は？**

- 今のところ、学習に使ったデータと学習用プログラムは公開していません
- 是非にと言う場合、個別に相談してくれれば、仕事として対応します

# 実行例

```sh
$ python3 ocr_japanease.py testshot1.png
file "testshot1.png" detected in 72 dpi
[Block #0]
がんばろう
[Block #1]
日本
[Block #2]
コロナウイルスにまけるな
```

**入力画像**
![testshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/abc0737b-9c00-d0a1-7143-922ad08efcf0.png)
**認識結果**
![testshot1.png-detections.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/4941011d-94ed-69b0-b86b-3daca25e8cf9.png)


# 解説

後で別の記事に書こうと思っています

# Reference

日本語OCR　https://github.com/tanreinama/OCR_Japanease
5分で理解する「Bloom filter」

#1.前提
ビットコインにおいて
SPVノードはブロックヘッダと自分に関係のあるノードの情報しかもたない。
そのため全てのブロックやトランザクションについて検証することができない

初期のSPVノードは全トランザクションをダウンロード後に自分に関係のないものを捨てていたので効率が悪かった。
→同期に時間がかるため

これを解決するためにダウンロードする時点で、自分に関係のあるトランザクションのみを入手するようなフィルターを
かけることにした。これがブルームフィルター
BTC以降の技術ではなく、1970年に Burton H. Bloom が考案したもの

#2.ブルームフィルタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/89e01c08-23b2-4c58-43d3-eab2ba48fe68.png)
 図1:ブルームフィルタを用いたブロックの受信
filterload:リモートノードとのコネクションにブルームフィルタをセットする
filteradd:データ要素を現在のブルームフィルタにセットする
filterclear:ブルームフィルタを除去する

フィルタリングはScript PubKeyやScriptSigにプッシュする個別の要素に対して行われる

<詳細>
データの有無を効率的に判断するアルゴリズム。
ブルームフィルタはn個のビット列とk個のハッシュ関数で構成される
ex:10このビット列,２個のハッシュ関数の場合

最初はこんなかんじー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/26d021f8-c0ae-d5d6-72a9-6ae17f4fd3dd.png)

図:2ブルームフィルタの初期状態

次に、要素Aを追加してみる
結果的に、出力された数字のビットを１に変換する(この場合は3と9)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/a574c2e7-58d5-d841-6048-d9080f131814.png)

図3:要素Aを追加したブルームフィルタ

同じように要素Bを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/5d55686c-0110-7ac0-a0a2-7e1fdfc62460.png)

図4:要素Bを追加したブルームフィルタ

このように、要素をハッシュにかけて出力された値をインデックスとしてビット列を走査し、そのビットの値全てが1であれば
要素が登録されている(可能性がある)と判断できる。

ん？？可能性がある？

そりゃそうだ。要素Aと同じ出力をもつ要素Cが存在する場合も考えられる



この場合は実際に登録されていないにも関わらずデータが含まれている(可能性がある)と判定するため偽陽性の誤検出の可能性がある。(可能性、可能性くどいので詳しくは[gbec動画](https://www.youtube.com/watch?v=T49UGXbDLME&list=PLr5Bi9qipPloWSpPrlSSjpiX-EDREtHFu&index=5)で)

ちなみに、ハッシュを通してフィルタをかけている以上、一度追加したデータの削除はできない。

<フィルタに用いるマッチングアルゴリズム>
自分に関係のあるトランザクションを検出するマッチングアルゴリズム。
5ステップの途中で一つでもマッチすれば、以降のアルゴリズムは無視される。

1.トランザクションのハッシュを計算し、テストする。
2.トランザクションの各アウトプットについてScriptPubkeyの各要素(ScriptPubKey全体ではなく、ScriptPubKey内のハッシュや鍵などの要素)
3.トランザクションの各インプットについて、シリアライズされたOutPointをテストする
4.トランザクションの各インプットについて、そのScriptSig内の各要素(ScriptSig内には基本的にデータしかない)をテストする
5.上記のいずれにも合致しない場合はマッチしないと判断する

#参照
[ブロックチェーンプログラミング]
(https://www.amazon.co.jp/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%83%BB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E4%BB%AE%E6%83%B3%E9%80%9A%E8%B2%A8%E5%85%A5%E9%96%80-%EF%BC%AB%EF%BC%B3%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%B1%B1%E5%B4%8E%E9%87%8D%E4%B8%80%E9%83%8E-ebook/dp/B078G94JNT/ref=dp_kinw_strp_1)
UE4 CommandletをVS上から実行してブレークポイントを使う方法

Commandletの実行でブレークポイントを使えないと動作確認が非常に面倒なので調べてみました。

## 環境
VS2017
UE4.24.3

## ソース
一先ずソースは最小構成とします。

```TestCommandlet.h
#pragma once
#include "CoreMinimal.h"
#include "Commandlets/Commandlet.h"
#include "TestCommandlet.generated.h"

UCLASS()
class UTestCommandlet : public UCommandlet
{
	GENERATED_UCLASS_BODY()

public:
	UTestCommandlet();
	virtual int32 Main(const FString& CmdLineParams) override;
};
```

```TestCommandlet.cpp
#include "TestCommandlet.h"

UTestCommandlet::UTestCommandlet(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    LogToConsole = false;
}

int32 UTestCommandlet::Main(const FString& CmdLineParams)
{
    return 0;
}
```

## Commandlet用のプロジェクト構成を作成
![ss1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/bb89aecb-1dd2-3c5e-b3a5-b2f47a9bbbf9.png)
![ss2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/829dc58f-9dee-bcbb-825a-86835ffac60c.png)
![ss3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/8237a7de-19bc-b6b2-c19a-5c60592f4971.png)
![ss4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/c0419572-83f4-0c49-b944-6a44fa704035.png)
![ss5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/35cd3e2d-1d0b-5bb7-8d20-38c6c21a2d56.png)
コマンド引数をCommandletように変更する
ここでは以下とした

```
"$(SolutionDir)$(ProjectName).uproject" -run=TestCommandlet -stdout -UTF8Output
```

![ss6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/1811bc6d-d660-4065-3c61-88f96ed37521.png)

## ブレークポイントを設定して実行
該当箇所にブレークポイントを設定してデバッグ実行を行う
![ss7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/03e62199-7ca5-30d6-5197-d0c3745a0a9a.png)


## 通常のUE4起動に戻すとき
プロジェクトの構成でDebugGame Editorに変更する
![ss8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64194/3ffbad2b-7268-f8d6-bb3f-ddb217c0abed.png)
Datawrapperで都道府県別コロナウィルス感染者マップを作ってみる

プレゼンテーション資料やWebサイト上での情報共有に、[こんな感じの塗りつぶし地図](https://www.datawrapper.de/_/skmGm/)を作ってみたいと思ったことはないでしょうか？
![skmGm--.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/14aa18dc-d271-1c9a-48cb-8c941e242d8c.png)
今回は、[Datawrapper](https://www.datawrapper.de/)というオンラインのデータ可視化サービスを使ってみたいと思います。
Datawrapperの創作者の多くは元記者ということもあり、プログラミングの知識なくインタラクティブなグラフや地図を作製することを目指したものだけあって、とても簡単にビジュアル化することができます。

#DatawrapperにSign-up
なんて必要ありません。利用プランを選択したい場合は必要ですが、なくても上記のマップなどは作れます。Free Plan、Custom Plan、Enterprise Plantとありますので、興味ある方は、Pricingのところからご確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/b0f48d79-2467-a2b6-e878-f33cbf89231d.png)

#地図を作る
["New map"](https://app.datawrapper.de/create/map)メニューから作成したい地図を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/c3f26f32-b952-bbee-14c9-bd31e8abb1bb.png)
Choropleth map: 階級区分図
Symbol map: 等級シンボルマップ
Locator map: マーカー付きマップ
が選べるようですが、今回は、Choropleth mapを選択

##背景地図の選択 - Select your map -
背景地図は、世界地図、大陸単位、国単位で選択可能です。日本地図にする場合は、都道府県区分までの地図になりますね。（できれば、地方単位のテンプレートもあれば良かったのですが）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/f789c3f7-0b94-effa-72d9-f06120a7ee58.png)

##地図データの追加 - Add your data -
次に塗りつぶしように用意するデータを追加します。表示されているグリッドに手入力してもいいですが、CSVファイルを取り込む機能もあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/af582662-b26f-bf1f-f6f4-9aff0a457a87.png)
今回は、NHKさんの[特設サイト「新型コロナウィルス」](https://www3.nhk.or.jp/news/special/coronavirus/data/)から都道府県別の感染者数データを拝借しました。

##ビジュアル設定 - Visualize -
カラーレジェンド（凡例）を設定したり、タイトルや注釈を入れることができます。特にカラーレジェンド設定では、対数分布向けの設定もできるので、今回みたいに東京だけが吐出しているようなデータマップを見栄え良くすることができると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/a02ce0e2-a789-2cdc-c232-b4afc5ca9d97.png)

##地図の配布 - Publish & Embed -
"Public chart"ボタンから、配信用の地図を生成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/0692ce8e-e9d8-b328-5085-e2663909aa1d.png)
URL共有（フルスクリーン版と事前設定サイズ版）と、自前サイトへの組み込み用のiframeコード、他にもPNGファイルへの出力も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/dc675419-a363-e798-81da-aee31c42fbe6.png)

以上、とても簡単にグラフや地図のビジュアル化ができます。もちろん、同じようなことは、他のVisualizationツールでもできるのですが、Tableau publicもアプリケーションインストールが必要だったりするので、たった4ステップで作れちゃうWebサービスはおススメです。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/d6ad10bc-75ba-8124-14d4-f144657c6473.png)](https://twitter.com/ghibi)
Azureのログの長期保存について

きになったのでしらべた備忘録です。

Logを大体Loganalyticsに放り込んでいるがLoganalyticsは最大2年保持されるがそれ以降は消えてしまう。でも3年保存したいまたは過去のやつは1年過ぎたら見ることもあまりないがとっておく必要はあってコストを抑えたいなどの需要に対応できるといいかなと。

####最終保存場所
最終的にBlobに投げつけておけば安いし勝手には消されないであろうしライフサイクルが定義できるのでいいのでは。
https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-lifecycle-management-concepts?tabs=azure-portal

####blobまで運ぶ方法

１．RunbookかLogicAppsでクエリかけたやつをBlobに出す
https://cloudsteady.jp/post/11347/
https://qiita.com/Aida1971/items/c9fcb979084aae9fd890

２．StreamAnalyticsでEventHubをかましてからBlobに置く
https://devlog.arksystems.co.jp/2016/08/03/820/
https://azure-recipe.kc-cloud.jp/2015/12/streamanalytics-1/

AzureリソースからEventHubかます方法はこのへんからたどることができそうなきがする。
https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/stream-monitoring-data-event-hubs
そもそも外部のlog分析ツールと連携するのにEventHubを使うのが一般的みたいな感じなのかな。

####LogicAppsでクエリかけてblobに置くのを試した

![longtermlogretain-logicapps1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25031/01c62487-089d-1261-2e8b-4abfb1c8b0bb.jpeg)

上記画像でしている内容は以下のとおり。
・スケジュールコネクタで一日おきに動く
・前日の日付を関数で出す
　formatDateTime(addDays(utcNow(), -1), 'yyyy-MM-dd')
・長期保存するテーブルのリストを配列にする

![longtermlogretain-logicapps2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25031/0b36117d-1909-60e3-2d23-5085167b8636.jpeg)

上記の画像でやってる内容は以下のとおり。

・配列をループ処理する
　　・保存するファイル名のデータ作成
　　・Loganalyticsに接続し現在読み込まれたテーブルのログを指定された日付の始まりから終わりまで取得
`| where TimeGenerated between(datetime(\"datetime(\"@{outputs('filename-date-create')} 00:00:00.000\") .. datetime(\"datetime(\"@{outputs('filename-date-create')} 23:59:59.999\"))`
　　・LoganalyticsからとってきたデータをCSVにする
　　・CSVをBlobの指定した場所に指定した日付のファイル名（ループの先頭でつくったデータ）で出力する

実行すると以下のようにblobに出力される。

![longtermlogretain-logicapps3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25031/ba0958c3-c36d-2111-9258-df04b90012e6.jpeg)

LogicAppsだと途中で圧縮とかはコネクタがないなと思った（エンコードはあった）けど、AutomationだとPowerShellいけるのでどうにかなるのかもしれない（ためしてない）。
テストで流しただけのマイグレーションファイルを履歴から削除する

# 環境
Vagrant + Ubuntu 16.04.5 LTS
Rails 5.2.4.2

# はじめに
テストの目的で作成したマイグレーションファイルが不要になったので、ファイル自体を、rmで削除したのだが、マイグレーションの履歴には下記のように残ってしまう事になります。気持ちが悪いので履歴からも削除してみましょう。

```
$ rails db:migrate:status

database: syougai_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200407073641  Create tasks
   up     20200408005922  ********** NO FILE **********
   up     20200408005924  ********** NO FILE **********
   up     20200408005926  Change tasks karamu not null
```

# 手順
上記の通り、**rails db:migrate:status**で表示すると、マイグレーションファイルを手動で削除したため、**NO FILE**になっています。この履歴を削除するには、まず、**Status**を**up**から**down**に切り替える必要があります。

一旦削除した、マイグレーションファイルを、ファイル名は適当でいいので、マイグレーションIDを付けた形で復活させます。

```
$ touch ./db/migrate/20200408005922_tmp1.rb
$ touch ./db/migrate/20200408005924_tmp2.rb
```

復活させたマイグレーションファイルを、エディタでそれぞれ、このように編集します。

```xxxxx_tmp1.rb
class Tmp1 < ActiveRecord::Migration[5.2]
  def change
  end
end
```

```xxxxx_tmp2.rb
class Tmp2 < ActiveRecord::Migration[5.2]
  def change
  end
end
```

マイグレーションの履歴を参照すると、ファイルが復活している事が確認できます。

```
$ rails db:migrate:status

database: syougai_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200407073641  Create tasks
   up     20200408005922  Tmp1
   up     20200408005924  Tmp2
   up     20200408005926  Change tasks karamu not null
```

復活したマイグレーションの履歴のステータスをdownさせます。

```
$ rails db:migrate:down VERSION=20200408005922
== 20200408005922 Tmp1: reverting =============================================
== 20200408005922 Tmp1: reverted (0.0043s) ====================================

$ rails db:migrate:down VERSION=20200408005924
== 20200408005924 Tmp2: reverting =============================================
== 20200408005924 Tmp2: reverted (0.0050s) ====================================
```

補足だが、マイグレーションファイル名をTmp1、Tmp2と分けた理由は、同一名にすると、ステータスをdownさせる時に、下記のエラーが出たためです。（同一名はあかんようです）

```err
$ rails db:migrate:down VERSION=20200408005922
rails aborted!
ActiveRecord::DuplicateMigrationNameError:

Multiple migrations have the name Tmp.
```

ステータスがdownされた事を確認します。

```
$ rails db:migrate:status

database: syougai_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200407073641  Create tasks
  down    20200408005922  Tmp1
  down    20200408005924  Tmp2
   up     20200408005926  Change tasks karamu not null
```

ここで、不要なマイグレーションファイルを削除します。

```
$ rm ./db/migrate/20200408005922_tmp1.rb
$ rm ./db/migrate/20200408005924_tmp2.rb
```

履歴を参照すると、削除された事が確認できます。

```
$ rails db:migrate:status

database: syougai_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200407073641  Create tasks
   up     20200408005926  Change tasks karamu not null
```

# 参考URL
https://joppot.info/2014/10/16/2104
WekanをDockerで立てる！

## Wekanとは？
カンバンツールです。
Trelloのオープンソース版ってとこですね！
私は下記のようなリストを作成して個人用Todoとして運用しています。
1. 待ち
2. 今日やること
3. 空き時間
4. 定期
5. 留意点

## docker-compose.yml
docker-compose.ymlは下記のように記載します。

```yml
version: '2'
services:
  wekan:
    image: mquandalle/wekan
    links: 
      - wekandb
    environment:
      - MONGO_URL=mongodb://wekandb/wekan
      - ROOT_URL=http://10.0.75.1:8989 # ポートは好きなポートに
    ports:
    #wekanは8080ポートを開放しているため、コンテナのポート番号は8080にする必要がある。
      - 8989:8080 # 外部公開ポート番号 : コンテナのポート番号
    # コンテナが止まった時に再起動する
    restart: always 
    

  wekandb:
    image: mongo:4.1.5
    volumes:
      - test_db:/data/db
    restart: always

volumes:
  test_db:
```

## 注意点
ROOT_URLはカンバンを移動する際に使用されるURLです。
そのため、ローカル環境内にWekanを立てる場合上記ymlに記載したURLでも問題ないですが、
サーバ等に構築して外部からアクセスする場合はIPアドレスを構築したサーバのIPにする必要があります。

```yml
  ROOT_URL=http://【構築したサーバのIPアドレス】:8989
```

## コンテナの実行
下記コマンドをdocekr-compose.ymlを作成した位置で実行します。

```powershell

docker-compose up -d
# バックグランドで実行してコンテナを立ち上げ
```

## 動作確認
ブラウザで下記URLを入力します。
これでWekanのログイン画面が表示されるはずです！

```
http://10.0.75.1:8989
```
## まとめ
無事Wekanを立てることはできたでしょうか？

TODOリストはいろいろ試しましたが、Wekanで今のところは落ち着いています。
昨今細かなタスクが常々発生します。
全てを覚えておくのは難しいので（少なくとも私は厳しかった。。）、こういったツールを使用してよりよいワークを行うのはいかがでしょうか？
C言語　数列の要素を選ぶ組み合わせをビット列で表現するコード

各要素について選択するかしないかの2択となるので、2^n 通りの組み合わせがあります。これらは次の再帰によるアルゴリズムで生成することができます。

S を S[i] が 1 のとき i 番目の整数を選択する、0 のとき選択しない、という配列とします。

```c
#include <stdio.h>
#define N 3

int S[N];

void makeCombination(int i);
void print_array(int array[], int array_len);

void makeCombination(int i)
{
    if (i == N)
    {
        print_array(S, N);
        return;
    }
    makeCombination(i + 1);
    S[i] = 1;
    makeCombination(i + 1);
    S[i] = 0;
}

void print_array(int array[], int array_len)
{
    printf("S {");
    for (int i = 0; i < array_len; i++)
    {
        printf("%d", array[i]);
        if (i != array_len - 1)
            printf(", ");
    }
    printf("}\n");
}

int main(void)
{
    makeCombination(0);
    return 0;
}
```

##N=3のときの出力結果

```terminal
S {0, 0, 0}
S {0, 0, 1}
S {0, 1, 0}
S {0, 1, 1}
S {1, 0, 0}
S {1, 0, 1}
S {1, 1, 0}
S {1, 1, 1}
```

##参考
http://judge.u-aizu.ac.jp/onlinejudge/commentary.jsp?id=ALDS1_5_A&pattern=post&type=general&filter=Algorithm


##感想
相変わらず再帰は直感的に理解しにくい
[Rails] Microsoft TeamsのタブにRedmineを表示する

# TeamsのタブにRedmineを表示したい

Teamsには、任意のWebサイトをタブに表示する機能があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/6c4b990a-636d-0ffc-2c2c-a78f05306f18.png)

## けど、できない

Railsアプリはデフォルトで`X-Frame-Options: SAMEORIGIN`ヘッダを出力するようになっているので、`iframe`を使っているTeamのタブには表示されません。

## HTTPヘッダを変更する

Railsアプリの出力するHTTPヘッダは、**/usr/lib/ruby/vendor_ruby/action_dispatch/railtie.rb**に設定されています。

```ruby
config.action_dispatch.default_headers = {
  'X-Frame-Options' => 'SAMEORIGIN',
  'X-XSS-Protection' => '1; mode=block',
  'X-Content-Type-Options' => 'nosniff'
}
```

これを書き換えるのは乱暴ですので、Redmineの設定で上書きします。

**/usr/share/redmine/config/additional_environment.rb** ファイルを作成します。

```ruby
config.action_dispatch.default_headers = {
  'Content-Security-Policy' => 'frame-src https://teams.microsoft.com/',
  'X-XSS-Protection' => '1; mode=block',
  'X-Content-Type-Options' => 'nosniff'
}
```

`X-Frame-Options`の代わりに、`Content-Security-Policy`を設定しました。

Teams全体からiframe使えちゃいますが、ないよりはマシかなぁ的な。

## Apacheを再起動

設定を有効にします。

```console
systemctl restart apache2
```

# 環境

* Redmine 3.4.4
* Ruby 2.5.1
* Ubuntu 18.04

# リンク

* [MDN Content-Securit-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
【テレワに捧ぐ！】WebカメラでPC操作しちゃおっぜー

~~本当はテレワ勃興よりだいぶ前から作ってたけど。。~~

#### みんなお馴染みなコイツが大活躍する時がやってまいりました！

![cam1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/9f5259ef-b14f-90b6-e568-a49574a91ff3.png)

# Introduction

　テレワで飯食いながらWeb見るとか**両手が塞がってる**時に画面めくってくれたら良いなって思いません?? 毎度マウスに手を持ってくの手首の負担になりますし。
　椅子に寄りかかったまま、指を立てたらタブ切り替えたり・・

### 優雅だ・・・そのDXへ行こう！

# Abstract

要約すると**「影絵でオペレーション」**ってなやつです。

![handmouse.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/16d338ca-2e18-54cf-d213-6c2de2050d4f.gif)

最初にアクションさせたい画像をアノテーションします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/a2c7a0ca-b46e-20f4-cc07-d7968caa49ee.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/38cc5b0b-9693-41d9-056a-4dcb0cdf442f.png)

　次にconfigファイルに画像に紐づく、マウスの操作なり、キー入力を定義します。それからプログラムを動かして、OpenCVの画像類似度の閾値を満たせば定義にそって操作してくれるってわけ。

# コード

[ここにおいときますんで、詳しくはリポジトリ側を見てくださいな。](https://github.com/yasutakatou/webcamops)

# あとがき

影絵方式なんで形さえあれば**どんなんでも**操作に置き換えられます。

![pine.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/0f048b5c-c685-d1f4-e734-f486bc55b60c.png)

運動不足対策にヨガのポーズ、空手の型で入力するのもいいかと
~~作業は永遠に終わらないが！！~~

ん？むしろ何らかの身体ハンデある人に向いてる実装だったりするのかな？？

~~本当はtensorflowで実装したかったんですけどSIer配給のGPUも無い、PCにはリアルタイム認識は未来過ぎた。。~~

キーボードから手を放さずに使いたい場合は以下のように100均の鏡を買ってきてアナログに対応してください！笑

![cam2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/ccf6069d-5ed5-6a1b-0fa4-8302367e7a81.png)

# FYI

[Pythonで類似度検出③ 特徴点マッチング](http://sh0122.hatenadiary.jp/entry/2018/02/04/172426)

[NLPDev / HandGesture](https://github.com/NLPDev/HandGesture)
転職市場で「市場価値の高いエンジニア」の特徴

昨今では大手企業に就職する事や一つの企業に長く務める事が正解ではなくなってきました。
特にエンジニアは副業や業務委託で働く選択しもあるので、どれだけ自分の市場価値を高められるかが大切になります。

どのようなキャリアを歩み、どのようなスキルを身に着ける事で市場価値を高めていけるか少しでも参考になりましたら幸いです。

今まで沢山のエンジニアの方とお会いした中で、キャリア・年収を上げてきた方の特徴を書かせて頂きます。

<b>※前提として、下記全てに該当しなければならないという事はありませんのでご了承ください。

<h1>市場価値の高いエンジニア</h1>

<h3>■コードを書く事が趣味</h3>
「好きこそ物の上手なれ」の通り、コードを日々書き続けられる人は必然的にスキルが伸び市場価値が高くなります。
また、そういう方の大半はGithubでのコミットやQiitaやブログでのアウトプットなど、自然とポートフォリオも出来てくるので転職市場で優位になります。

<h3>■特定の技術・手段にこだわらない</h3>
技術はあくまでも手段です。ユーザーが求める品質の高いプロダクトを提供することを目的とし、その上で今利用している技術と新しい技術を比較した上で最適な選択をする事ができるエンジニアはベストプラクティスな開発を求められるWEB系企業で必要とされやすいです。

<h3>■特定の技術領域に強みがある</h3>
特定の技術・手段にこだわらないことが大切でありますが一方で、一つの技術領域に強みがあるのは非常に市場価値が高いです。
例えば、Rubyコミッターなどのような一つの技術に秀でており、その技術であらゆる課題を解決ができるエンジニアは企業からの引き合いが多いです。
仮に尖らせている技術領域が業界で人気がなくなっても他の技術領域にピボットして成果を出していただけると思われます。


<h3>■やり切った経験がある</h3>
開発年数ではなく、どれだけ濃い経験をしてきたかが重要になります。
※どんな仕事でもそうですが。
単発で中途半場なプロジェクトを転々されているよりかは、何かプロジェクトをやり切った方の方がコミットメント力はもちろん、突破力もありそうなので評価されやすい傾向にあります。

<h3>■最新の技術を学び続けられる</h3>
エンジニアの世界は1・2年で新しい技術が次々と出てきます。
常に新しい技術を学び、実務にどう活かしていけるかを模索し続ける事は非常に大切となります。
時代が変われば、人々の生活や習慣も変化していくので、それに伴い新しいUI/UX（デバイスなど）が次々と出てきます。

未知の技術を自分で調べ、理論立てて課題解決していくスキルはもちろん、
自社で扱う技術を極める事がイコール市場で通用するとも限りません。
どのような技術を求められるかは会社によって異なるので、常に新しい技術を身に着け続けられる人は市場価値が高い傾向にあります。

<h3>■サービス・ビジネス志向がある</h3>
ユーザーが何を求めていてサービスがどうすればユーザーに支持されるか、どうしたらユーザーにとって良いプロダクトを提供し続けられるか。
更には売上や利益のKPI、マーケティング的なスキル・経験がある方は非常に市場価値が高いです。

品質の高いプロダクトは、

<b>「自分が良いと思うプロダクト」　＜　「ユーザーが良いと思うプロダクト」</b>

当然のことながらユーザーが良い、ユーザーが求めるプロダクトになります。
企業としても、売上・利益を出してくれる事は評価の対象となります。

前提として、エンジニアは技術に責任を持つ職種なので、エンジニアとしても技術力が一定以上あることが前提となります。

キャリアの分岐の一つとして、自身で所謂天才肌エンジニアではない場合、サービス志向・ビジネス志向エンジニアを目指すのは良いです。
※たまに両方強い超ハイブリットエンジニアも存在します。

<h3>■コミュニケーションスキルが高い</h3>
これは釈迦に説法かもしれませんが。
※前提として、感情表現が豊かである事を定義していません。

チーム開発をしていく中、コミュニケーションが取れる事は大切です。
エンジニア＝あまり人と話さないというイメージを持つ方もいるかもしれませんが、決してそのような事はありません。
具体的には、

・非エンジニアの職種と円滑にコミュニケーションが取れる。技術の事がわからない相手にわかりやすく伝え、一緒にプロダクト作りをし事業を上手く進めていくコミュニケーションスキル。

・論理的かつ簡潔に自分の意図を伝え、ディスカッションをしながら進めていくコミュニケーションスキル。

・人ではなく仕事に対しての指摘ができる建設的なコミュニケーション。

<h3>■チーム開発に強みがある</h3>
一人で何でも作り上げる事ができる事もポジティブですが、一方で規模が大きくなった時にチーム開発に強みがある方も市場価値が高いです。
具体的には、誰が抜けても変わらない品質でチームが回る俗人性の排除やプロセス改善・自動化・効率化などが出来る。チームの雰囲気作りが上手く心理的安全など。

<h3>■幅広い業務・技術領域をカバーした経験がある</h3>
一つの領域・技術に尖っているエンジニアとは反対に幅広い領域をカバー出来る方も市場価値が高いです。
バックエンド、フロントエンド、インフラ、ネイティブなど幅広い領域から様々な技術が扱える方は企業から重宝されます。
ただ前提として、一つ尖った技術があった上での幅広さが大切です。
T型人材として広げつつ、π型人材へとステップアップしていくことが理想となります。

<h3>■品質の高いプロダクトを常に提供しようとしている人</h3>
これもエンジニアにとって当たり前かもしれませんが、品質の高いプロダクトを常に提供しようとし、それを形にしていく事が出来る方も市場価値は当然高くなります。

昨今ではWEBや何かしらプロダクトを必ず作るような時代で、若い子はデジタルネイティブで生まれたころからスマートフォンを持っていたりします。
そんな中、使いづらい、遅い、デザインがいけていないなどのプロダクトを提供したらすぐに見向きもされなくなります。

テストコードをしっかり書く、ユーザーが求めるプロダクト作りをしていく中、高速でPDCAを回せる仕組みや設計・手法を導入するなど。
※ドメイン駆動設計、マイクロサービスなど。

しっかりと品質の高いプロダクト作りをしている人は市場価値を高める上で大切となります。

<h3>■面倒くさがりで何でも自動化したがる</h3>

良い意味で怠惰である事はエンジニアとして優秀な証だと考えています。
そもそもテクノロジーは面倒な事を自動化・効率化したり便利にしたりするので、エンジニアとして面倒な事を自動化し、短い時間で今までの成果を上げる仕組みづくりが出来る人は市場価値が高いです。

---
あくまでも私個人の意見となりますが、今までお会いしてきた中で優秀な方の特徴を上げてみました。
冒頭にも記載しましたが、全て該当する必要もないですし上記以外でも評価されるエンジニアはおりますので少しでも参考になりましたら幸いです。
【SQL 講座】データベースの概念

この資料は弊社後輩に説明するために扱った＆口頭説明の補助的資料です。
せっかく纏めたので記念に残しておくかだけのものです、悪しからず。

---

# 例えば身近な例で - 年賀状
Q. その年にもらった年賀状、どう管理するか？

A. その辺に放置
A. とりあえず手紙ボックス的なものに入れる
A. 「年賀状」でまとめて管理する
A. シュレッダーへ GO
etc...

---

# 例えば身近な例で - 年賀状
「年賀状」でまとめて管理する
->
けど、溜まっていくと嵩張る。
大量の紙の集まりから1人の住所を探し出すのは面倒。

---

# 例えば身近な例で - 年賀状

「住所を管理できる何か」があれば

* 「親戚だけ」の住所を探す
* 「東京都に住んでいる人だけ」を探す
* 「去年年賀状くれた人だけ」を探す

etc...が楽にできる！はず！

---

# データベース

* 特定の条件に当てはまるデータを集めて、使いやすい形に整理した情報のかたまりのことを「 **データベース(Database)** 」という。
* 紙上で管理する「電話帳」や「住所録」などもデータベースといえる。
* コンピュータ上でデータベースを管理するシステムのことや、そのシステム上で扱うデータ群のことを、単にデータベースと呼ぶこともある。

---

# データベースで管理するメリット

* 複数のデータをまとめて管理できる
* 目的のデータを簡単に探すことができる
* 簡単に編集して使うことができる

※デメリットを挙げるなら、データの入力は未だ手動なことが多いこと...

---

# データベース管理システムの役割

* データベースを管理するシステムのことを「 **Database Management System(DBMS)** 」という。
* DBMS は **大量のデータを自動的に整理する** 役割を担っている。

---

# SQL とは

* データベースを操作するための専用の言語のひとつ。
* データの追加、削除、並べ替えなど行えるように命令する手段。
* エスキューエル、シークェル などと発音される。
* データベース言語、問い合わせ言語などに分類される。(≠プログラミング言語)

---

# SQL を使った命令

予め、データベースに対してなんていう風に命令すればどんなことをしてくれるか、というのが決まっている。

* 「○○を **検索** してほしい」-> SELECT
* 「□□を **追加** してほしい」-> INSERT
* 「××の名前を **更新** してほしい」 -> UPDATE
* 「△△を **削除** してほしい」 -> DELETE

上記命令文に「特定の条件を満たすものだけに対して」「結果はこの並び順で」「この数が欲しい」など追加することによって、複雑な処理も行える。
[5分で分かる]AWS基本知識

# はじめに
本記事は初めてAWSに触れる人が押さえておくべき具体的なサービスと用語が何となく分かる。
そんな初心者入門の記事となっております。
# AWS基本
## リージョンとアベイラビリティーゾーン
・　AWSは世界２２の箇所にあるデータセンター群から構成されています。
（２０２０年４月時点）
・　それらデータセンターをリージョンと呼びます。
（例：東京リージョン、オレゴンリージョンなど）
・　リージョンはさらにアベイラビリティーゾーンに分割されます。
・　私たちがAWSを使う際は、どのリージョンのアベイラビリティーゾーンを使用するかを決める必要があります。
#####参考URL
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html

## VPC
・　Virtual Private Cloudの略です。
・　AWSサーバー上に構築された固有のサーバー領域をVPCと呼びます。
・　ここに各ユーザーはインフラやシステムを構築、配置します。
#####参考URL
https://aws.amazon.com/jp/vpc/

## EC2
・　Elastic Compute Cloudの略です。
・　誰でも簡単に仮想サーバーを立ち上げることができるサービスです。
・　基本的に使った分だけ課金される従量課金制が採用されています。
#####参考URL
https://aws.amazon.com/jp/ec2/features/

## EBS
・　Elastic Block Storeの略です。
・　EC2に付属している外付け記憶領域のことです。
・　通常EC2にもメモリがありますが、これはサーバーを停止すると消えてしまいます。
・　EBSはサーバーを停止した時などに、データを保守するのに必要となります。
・　アクセスすることが多いデータの保存に向いています。
#####参考URL
https://aws.amazon.com/jp/ebs/?ebs-whats-new.sort-by=item.additionalFields.postDateTime&ebs-whats-new.sort-order=desc

## IAM
・　Identity and Access Managementの略です。
・　AWSサーバーへのアクセスを安全に管理するためのサービスです。
・　サーバーへのアクセス範囲、方法を制限できます。
#####参考URL
https://aws.amazon.com/jp/iam/

## S3
・　Simple Storage Serviceの略です。
・　最大の特徴は容量が無制限なこと（ただし一つのファイルにつき５TBまで）です。
・　EBSよりも安く、バックアップデータを置くことに向いています。
#####参考URL
https://aws.amazon.com/jp/s3/

## ELB
・　Elastic Load Balancingの略です。
・　AWSサーバーへのアクセス負荷を分散するサービスです。
・　用途に合わせて三つの分散処理システムが用意されています。
・　使用することで突発的なアクセス増加に強いシステム構築ができます。
#####参考URL
https://aws.amazon.com/jp/elasticloadbalancing/

## Route53
・　AWSのドメインネームシステム（DNS）ウェブサービスです。
・　最大の特徴はとにかく落ちづらいことです。
#####参考URL
https://aws.amazon.com/jp/route53/

## Cloud Watch
・　AWS上でシステム運用するためのサービスです。
・　AWSの各サービスに関するメトリクスを収集することで、システム上のリソースやアプリケーションを最適化することができます。
#####参考URL
https://aws.amazon.com/jp/cloudwatch/

# まとめ
いかがでしたでしょうか？
現在（２０２０年４月時点）AWSでは１７５以上のサービスを展開しており、
この記事には紹介しきれなかった魅力的なサービスは他にも数多くあります。
興味を持って頂けましたら、ぜひAWSの最先端サービスを体験してみてください！！
jqで「じゃない」オブジェクトをselectする

(verson: jq-1.5-1です)
jqにJSON食わせるといろいろ楽しいことがあるのですが
例えば以下のようなJSONから

~~~ json
{
  "data": [
    {
      "id": "01",
      "name": "a",
      "fm": "m",
      "model": "HOGE"
    },
    {
      "id": "02",
      "name": "some",
      "fm": "f",
      "model": "GIKO"
    },
    {
      "id": "03",
      "name": "any",
      "fm": "m"
    }
  ]
}
~~~

- key"model"のvalueが"HOGE"のオブジェクトを選ぶ場合

~~~ bash
jq -r '.data[] | select(.model == "HOGE")'
~~~

- key"model"が存在するオブジェクトを選ぶ場合

~~~ bash
jq -r '.data[] | select(.model)'
~~~

こんな感じで書いてやればよい。

では、

- key"model"のvalueが"HOGE"ではないオブジェクトを選ぶ場合
- key"model"が存在しないオブジェクトを選ぶ場合

どうすればいいかですが、まず

- key"model"のvalueが"HOGE"ではないオブジェクトを選ぶ場合

これは簡単。

~~~ bash
jq -r '.data[] | select(.model != "HOGE")'
~~~

まぁ教えられるまでもないですが・・・

では、
- key"model"が存在しないオブジェクトを選ぶ場合
ですが色々試行錯誤して以下の感じでできることに気づきました。

~~~ bash
 jq -r '.data[] | select(has("model")|not)'
~~~

と、select,has,notを組み合わせればイケます。
hasはkeyの有無を判定するんですが、クオートしてやんないとダメっぽいです。

参考
公式マニュアル: https://stedolan.github.io/jq/manual/
What's new in React Native 0.62


この記事は [React Native Tech Blog #2](https://ducklings.connpass.com/event/169637/) で発表した内容です。

React Native の最新バージョン、0.62 がリリースされました。
マイナーバージョンのアップデートは最後に行われたのが 2019年の9月なので半年ぶりのマイナーバージョンアップとなります。

この記事では 0.62 で新しくなったことについてまとめて行きます。

## Flipper のサポート

0.62は主に React Native のデバッグ周辺が改善されています。その大きな要因として、Flipper のサポートがデフォルトで入るようになりました。

Flipper とは、Facebook が開発しているネイティブアプリ用のデバッグツールです。
この度、React Native でもその恩恵を受けられるようになった他、React Devtools など、React Native ならではのツールも組み込まれるようになりました。
React Devtools は新しい v4 が組み込まれているので、従来の React devtools よりもよりスッキリした見た目で使いやすくなっております。

![flipper-devtools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167299/65b8d0e6-837b-dd00-2e00-6a21546bd90a.png)

また、Redux Inspector など、追加のプラグインもいれられるようになっています。

React Native のデバッグにはこれまで React Native Debugger というツールが主に使われていましたが、アプリが複雑になると動作がかなり重くなったりといろんな問題がありました。Flipper はアプリのパフォーマンスをほとんど損なうことなく快適にアプリのデバッグが行えるようになります。

## LogBox

React Native で開発している人なら誰もが一度は「赤い画面」を見たことがあると思います。

React Native 0.62 では試験的に LogBox という新しいエラーメッセージの UI を試せるようになります。

![logbox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167299/43afbc17-7c0f-aa46-0838-cd8306065a87.png)

エントリーポイントである `index.js` にて、`unstable_enableLogBox()` を呼び出すことで新しい LogBox の UI が有効化されます。

```js subtitle='Add code above to index.js'
import { unstable_enableLogBox } from 'react-native';

unstable_enableLogBox();
```

## Appearance API

![appearance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167299/9f5e9697-a563-2a23-0a15-a7f5888edb2d.png)


0.62 では端末の Appearance 設定を取得できる Appearance API が追加されました。
端末のテーマ設定に合わせて、アプリのテーマを Dark Mode や Light Mode に変更することができます。

`getColorScheme` 関数を呼び出すことで、端末のテーマ設定を取得できます。

```jsx
import { Appearance } from 'react-native';

const LoginPage = () => {
  const colorScheme = Appearance.getColorScheme();
  if (colorScheme === 'dark') {
    return <DarkContents/>
  }

  return <LightContents/>
}
```

また、午後6時からDarkModeを使う、などの特殊な状況でアプリのテーマ設定を変えたいときに、その変更を Listen するために、`useColorScheme` という custom hooks も提供されています。

```jsx
import { useColorScheme } from 'react-native';

const LoginPage = () => {
  const colorScheme = useColorScheme();
  if (colorScheme === 'dark') {
    return <DarkContents/>
  }

  return <LightContents/>
}
```

自分の場合、テーマ設定に合わせて役割色を取得する `useColorScheme` をラップした CutomHooks を作成して、アプリのダークモード対応に使っています。

```jsx
import { useColorScheme } from 'react-native';

const defaultTheme = {
  textColor: '#222',
  backgroundColor: '#eee',
  primaryColor: '#ff8800'
  white: '#fff',
  black: '#000'
}

const darkTheme = {
  ...default,
  textColor: '#eee',
  backgroundColor: '#222',
}

const useThemeColor = () => {
  const colorScheme = useColorScheme()
  const isDark = colorScheme === 'dark'
  return isDark? darkTheme : defaultTheme
}

```

Appearance については、Polyfill が存在しており、Expo や古い React Native のバージョンでも使用できる、[react-native-appearance](https://github.com/expo/react-native-appearance) というライブラリも存在しています。


## その他

以上の3機能が、今回のアップデートの目玉となっております。

他にも細かい修正があり、時間があるときに追記していきます。
QR コードのバージョンと希望寸法

概要

QR コードを紙に貼り付けても、あとで読み取りできないと意味がない…
特にスキャナーで読み取った場合、事後に気が付くことが多い問題です。
そこでカコのチケンを元に試算表を作りました。ご参考ください!

参考:

- [セルの大きさを設定するためのポイント](https://www.qrcode.com/howto/cell.html)
- [コード領域を確定するためのポイント](https://www.qrcode.com/howto/code.html)
- [QR コードの情報量とバージョン](https://www.qrcode.com/about/version.html)

上記勘案した希望寸法表 (300 dpi 5 ドット構成)

| バージョン | セル長<br>(個数) | 300 dpi<br>5 ドット(mm) | シンボル寸法<br>(mm) |
|--:|--:|--:|--:|
|1|21|0.42|8.8 |
|2|25|0.42|10.5 |
|3|29|0.42|12.2 |
|4|33|0.42|13.9 |
|5|37|0.42|15.5 |
|6|41|0.42|17.2 |
|7|45|0.42|18.9 |
|8|49|0.42|20.6 |
|9|53|0.42|22.3 |
|10|57|0.42|23.9 |
|11|61|0.42|25.6 |
|12|65|0.42|27.3 |
|13|69|0.42|29.0 |
|14|73|0.42|30.7 |
|15|77|0.42|32.3 |
|16|81|0.42|34.0 |
|17|85|0.42|35.7 |
|18|89|0.42|37.4 |
|19|93|0.42|39.1 |
|20|97|0.42|40.7 |
|21|101|0.42|42.4 |
|22|105|0.42|44.1 |
|23|109|0.42|45.8 |
|24|113|0.42|47.5 |
|25|117|0.42|49.1 |
|26|121|0.42|50.8 |
|27|125|0.42|52.5 |
|28|129|0.42|54.2 |
|29|133|0.42|55.9 |
|30|137|0.42|57.5 |
|31|141|0.42|59.2 |
|32|145|0.42|60.9 |
|33|149|0.42|62.6 |
|34|153|0.42|64.3 |
|35|157|0.42|65.9 |
|36|161|0.42|67.6 |
|37|165|0.42|69.3 |
|38|169|0.42|71.0 |
|39|173|0.42|72.7 |
|40|177|0.42|74.3 |

※ 余白は上下左右に約 2 mm プラスする事を想定
Flask 単体テスト環境（test_client）

# 概要

FlaskのAPIテストをするのに「POST MAN」を使用していましたが、今更Flaskでの単体テスト方法を学んだんで備忘録。

# 例

テスト用のコードは「test.py」として別に分けています。「app.py」に簡単なルーティング設定をしています。

```python:app.py
from flask import Flask, jsonify, request
app = Flask(__name__)

@app.route("/")
def home():
  if request.is_json: # jsonのデータ指定
    return jsonify({"msg": "fault massage"}), 400
  return jsonify({"msg": "success message"}), 200

if __name__ == "__main__":
  app.run()

```

今回はget通信としていますが、これはgetのところをpost等にすればその他通信が可能です。

```python:test.py
import json
from app import app # app.py をインポート

with app.test_client() as c:
  res = c.get("/", data=json.dumps({
      "test" : "test"
    }
  ),
    headers={
      "Content-Type" : "application/json"
    }
  )
  print(res.get_data())

```
コンテナ内部からホストマシンの Redis に接続したい

ホストマシンで Redis を起動してコンテナから接続しようと試みたが、うまくいかなかった。
Redis のデフォルト設定では、接続元の IP を 127.0.0.1 に絞っているみたい。

```/etc/redis.conf
################################## NETWORK #####################################

# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1

```

bind する IP を変更してあげれば OK 。
【Rails】deviseを用いた名前ログイン機能の実装

#目標

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/cd780158-1e59-8dfc-deac-b02bf8779943.gif)

# 開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# 前提

下記実装済み。

・[Slim導入](https://qiita.com/matsubishi5/items/b639ffddecc626856039)

# ログイン機能を実装

### 1. アプリケーションを作成

```terminal:ターミナル
$ rails new devise_name
```

### 2. トップ画面を作成

```terminal:ターミナル
$ cd devise_name
```

```terminal:ターミナル
$ rails g controller homes top
```

```ruby:routes.rb
Rails.application.routes.draw do
  root 'homes#top'
end
```

```ruby:homes_controller.rb
class HomesController < ApplicationController
  def top
  end
end
```

```slim:top.html.slim
h1
  | トップ画面
```

### 3. deviseを導入

```ruby:Gemfile
gem 'devise' 
```

```terminal:ターミナル
$ bundle
```

```terminal:ターミナル
$ rails g devise:install
```

```terminal:ターミナル
$ rails g devise User name:string # モデル作成
```

```terminal:ターミナル
$ rails db:migrate
```

```terminal:ターミナル
$ rails g devise:controllers users # コントローラー作成
```

```terminal:ターミナル
$ rails g devise:views users # ビュー作成
```

```terminal:ターミナル
$ bundle exec erb2slim app/views app/views -d # ビューをslimに変換し、erbを削除
```

# 名前ログイン機能を実装

### 1. ルーティングの編集

```rb:routes.rb
Rails.application.routes.draw do
  root 'homes#top'

  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations'
  }
end
```

`devise_for :コントローラー名, controllers: {
    sessions: 'コントローラー名/sessions',
    registrations: 'コントローラー名/registrations'
}`
上記の様に記述する事でViewの変更が可能になる。
※ `「devise_for :users」`のままでは、既存のViewが表示されてしまい、Viewの編集が効かなくなる。


### 2. サインアップ画面に名前入力フォームを追記

```slim:users/registrations/new.html.slim
.field
  = f.label :name
  br
  = f.text_field :name, autofocus: true, autocomplete: "name"

.field
  = f.label :email
  br
  = f.email_field :email, autofocus: true, autocomplete: "email"
```

### 3. サインイン画面を編集

```slim:users/sessions/new.html.slim
/ メール入力フォームを削除し、名前入力フォームを追記
.field
  = f.label :name
  br
  = f.text_field :name, autofocus: true, autocomplete: "name"
```

### 4. 「application_controller.rb」を編集

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller? 

  private

    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up,keys:[:email])
    end
end
```

### 4. 「devise.rb」を編集

```ruby:config/initializers/devise.rb
#43行目をコメントアウトして[:name]に変更
config.authentication_keys = [:name]
```

### 4. 「application.html.erb」を編集

```slim:application.html.slim
body
  - if user_signed_in?
    = link_to "ログアウト", destroy_user_session_path, method: :delete
  - else
    = link_to "新規登録", new_user_registration_path
    = link_to "ログイン", new_user_session_path

  = yield
```

※ サインアップ 、ログイン後はdeviseの初期設定で「root」(homes#top)に飛ぶ