OmniAICreator/Qiita-1.07M huggingface dataset:
PHP うまく説明できなかった集

僕は基本[BoostNote](https://boostnote.io/ja/)を使ってメモをしているのですが、phpの学習がひと段落ついたので一旦Qiitaにアウトプットしときます。内定先の課題の一つでtodosアプリのソースコードを「新規作成」「更新」「削除」それぞれの処理の流れに沿って、コードを全行・全メソッド説明するというものがあり、その説明をメンターにしている中で、言葉に詰まったところを今回は書きます。
頑張って自分と同じくらいの学習度の人に伝わりやすいように。順番はぐちゃぐちゃです。

## $_POST
- HTTPPOSTメソッドで送信された値を取得する変数

## 暗号化とハッシュ化の違い
####ハッシュ化
- 不可逆変換なので元データを復元できない

##### 用途
- パスワード保管等

#### 暗号化
- 秘匿変換なので元データを複合化することができる

##### 用途
- 機密情報の秘匿等

## checkTokenによる整合性を確認する意味

```php
function checkToken($token)
{
    if (empty($_SESSION['token']) || ($_SESSION['token'] !== $token)) {
        $_SESSION['err'] = '不正な操作です';
        redirectToPostedPage();
    }
}
```
非正規ルートからのアクセスを防ぐため

## SESSION
サーバーとクライアントつまり、ユーザーとアプリケーション側がやり取りする上でアプリケーション側がユーザーを特定するために使用する

## エスケープ処理の必要性
悪意のあるコードを特定するため

## htmlspecialchars
フォームから送られてきた値や、データから取り出した値をブラウザに表示する

## リファラ
あるページを開いたユーザーがどのページから流入してきたかを知るための情報

## PDO
PHPとデータベースサーバーの間の接続

## PDOStatement
プリペアドステートメント(SQL文を最初に用意しておいて、その後はクエリ内のパラメータの値だけを変更してクエリを実行できる機能のこと)を表す

## PDOException
PDOが発するエラーを出力する

## bindValue
値をパラメータにバインドさせる

## :textの読み方と意味

#### 読み方
プレースホルダ

####　意味
SQL文の中で「ユーザーが入力した値を代入する箇所」

#### 使う意味
プレースホルダを使わずにユーザーから入力された値を直接SQLに結合してしまうと不正な値が入力された時、SQL文が壊れるもしくは、別の文に変化する恐れがある(SQLインジェクション)
プレースホルダを使うと、その部分はあくまで「値として処理し、SQL文として実行されなくなる」

## prepareとqueryの違い
```php
$stmt = $dbh->prepare($sql);
$stmt = $dbh->query($sql);
```
### 共通点
- 引数に指定したSQL文をデータベースに対して発行する

### 違い
####prepare
ユーザーからの入力を利用する
####query
ユーザーからの入力を利用しない

## 最後に
１回目のレビューの際は言葉がたどたどしすぎてたくさん指摘箇所がありましたが、２回目以降の訂正箇所は大体こんな感じでした。
初心者はprogateで達成感を得て満足するより、プロが書いたコードとかを実行される順に追っていき、全ての関数やメソッドを理解していき、第三者に説明する練習がいいんじゃないかなとやってみて思いました。
DockerでSassを使ってみた

未来電子テクノロジーでインターンをしているtokky08です。
Dockerについて勉強したのでアウトプットとして書いていきます。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。


#Dockerって何？
コンテナ型仮想化技術のことです。
パソコンの中にもう一つパソコンを作るイメージです。

#DockerとVMの違いとは

**VM**

 - OSのバージョンの違いなどで構築に手間がかかる
 - オーバーヘッドが大きい

**Docker**

- 仮装環境はコンテナと呼ばれるもので、オーバーヘッドが小さい
- 環境構築が容易


VMと違ってDockerは仮想化の単位ごとにOSを持つ必要がないため、より少ないリソースで素早く動作させることができる。

#イメージって何？
コンテナを起動するのに必要な設定ファイルをまとめたもの。
このイメージはDocker Hubからpullすることが多いです。

#コンテナって何？
イメージから作られるもの。
ミドルウェアの環境構築がされた実行環境。


#DockerでSassを使う

[SASSのSCSS記法を触ってみたRuby](https://qiita.com/ftnext/items/baa8874494d54d1084de)
こちらの記事を参考にしました。

ファイル構成はこんな感じです。

```
docker-sass
      - Dockerfile
      - docker-compose.yml
      - css
          - style.scss
```


```:Dockerfile
FROM ruby:2.5.1

RUN gem install sass
```

```:docker-compose.yml
version: '2'
services:
  scss:
    build: .
    volumes:
      - .:/var/www/scss
    stdin_open: true
    tty: true
```

sassをインストールするためrubyの環境構築を行います。その上でsassをインストールします。これが`Dockerfile`の内容です。

```
$ docker-compose up -d
```
このコマンドでdocker-compose.ymlに記述した設定からコンテナ起動します。`-d`はバックグラウンドで行うって感じです。

```
$ docker exec -it コンテナ名 bash
```

execでコンテナの中に入ります。
これで、一応流れとしてはひとまず終わりです。あとは、sassを使っていこうって感じです。

ファイル編集をホスト側で行い、その編集をコンテナ内にも反映させて作業を行います。これをバインドマウントを行うといいます。バインドマウントは`-v ホスト側のパス:コンテナ側のパス`オプションで実行できますが、今回は`docker-compose.yml`に記述してます。

```
volumes:
      - .:/var/www/scss
```
ここです。`.`がホスト側のパスで`/var/www/scss`がコンテナ側のパスです。
さて、execでコンテナ内に入ったので`var/www/scss`に移動します。

```
root@2ffc40c8a946:/# cd var/www/scss
root@2ffc40c8a946:/var/www/scss# ls
Dockerfile  css  docker-compose.yml
```
見事、ホスト側にある[Dockerfile/css/docker-compose.yml]がコンテナ内にあることが確認できました。
`cd`コマンドで`css`フォルダ内に移動します。

```
$ sass --watch style.scss:style.css
```
このsassコマンドを実行して、ホスト側で.scssファイルを編集してみましょう。

```
root@2ffc40c8a946:/var/www/scss/css# sass --watch style.scss:style.css
>>> Sass is watching for changes. Press Ctrl-C to stop.
>>> Change detected to: style.scss
      write style.css
      write style.css.map
```
見事、sassコマンドが機能しました。ホスト・コンテナ側両方のファイルをみてみると、新たに`style.css`と`style.css.map`ファイルが作成されていることが分かります。

これがバインドマウントを用いてファイル編集をする流れでした。

#まとめ
以前、sassの勉強会を開いた時windowsやubuntuの方がrubyの環境開発に苦戦していたのでDockerを使えばめっちゃ簡単じゃんと勉強して思いました。まだまだDockerについてよく分からない部分はありますがこれからも勉強して使いこなせるようにしたいです。勉強会を開く時などは環境構築が1番の山場だと言っても過言ではないのでDockerを使えば全員簡単に同じ環境が構築できるのですご！！と思いました。これからはDocker使わなければ・・・
[Terraform] Terragruntのinputs内のlistは推論だとstringとして扱われる模様

## Terragruntのバージョン
terragrunt version v0.21.1

## 問題
下記のtable_definitionsは何もしないと内部でlistにならないようです。自分の環境ではstringとして扱われていました。

```hcl
inputs = {
  table_definitions = [{
    table_name = "$1_example",
    schema     = <<EOF
  {
    "name": "ticker",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "株の識別子"
  },
  {
    "name": "price",
    "type": "FLOAT",
    "mode": "NULLABLE",
    "description": "株価"
  }
EOF
  }]
}
```

## 解決策
下記のように、仮引数の（変数）側で型を宣言してあげると正しくlistとして処理されました。

```tf
variable "table_definitions" {
  default = []
  type    = list(map(string))
}
```

## 終わりに
直接的に関係してるissue自体は閉じられているけど、関連issueは放置されているので直されてないのかもしれない。

## 参考
[Issues with lists/sets in 0.19 #740](https://github.com/gruntwork-io/terragrunt/issues/740)
[ java ] 抽象クラス

前回の記事ではインターフェースについて述べた。
https://qiita.com/QiitaD/items/835ed6ee4e52cb6b214a
今回は、インターフェースとしばしば比較される「抽象クラス」について記す。

##抽象クラスとは
抽象メソッドを一つ以上持つクラスのことである。抽象メソッドはサブクラスで必ず実装しなければならないので、開発者にオーバーライドを強制することができる。

##扱い方
抽象クラスを扱ううえで以下のようなルールがある。
1. インスタンス化できない
2. 抽象メソッドをオーバーライドしなければならない
3. サブクラスでコンストラクタの記述が必要である。

##インターフェースとの相違点
以下が相違点を表にしたものである。

|  | 抽象クラス | インターフェース |
|:-----------|:------------:|:------------:|
| 実装を持つメソッド      | 実装可        | 実装不可         |
| メンバ変数     | クラスのメンバ変数      | 定数       |
| 多重継承       | 不可        | 可         |

##実装
以下のように実装できる

~~~java
//抽象クラスViecleの実装
abstract class Viecle {
    //抽象メソッド
}
~~~

またサブクラスは抽象クラスを継承することで実装できる。

~~~java
//抽象クラスViecleの実装
abstract class Car extends Vielce {
    //スーパークラスのコンストラクタ呼び出し
    //抽象メソッドのオーバーライド
}
~~~
Xcode SwiftUI 選択時にデフォルトで作成されるプロジェクトのフォルダやファイルの備忘録

プロジェクト作成時にたくさんフォルダやファイルができるのだが、
まとまった資料がヒットせず、初心者にはよくわからなかったので整理した。
プロジェクト名をtest1とした場合。
![截屏2019-11-1815.48.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/4d413a1d-362f-f500-fd0b-154182274b04.png)

●AppDelegate.swift : アプリ「開始時」、アプリ「終了時」の管理用、肥大化を避けるために多数の処理をここに書くことは推奨されていない
https://developer.apple.com/documentation/uikit/uiapplicationdelegate

●SceneDelegate.swift : アプリ「起動中」（アクティブになった、バックグラウンドになった）の状態変化管理用、マルチインスタンス立ち上げる場合の管理用

※AppDelegate.swift と SceneDelegate.swift のすみ分けは次の資料が参考になる：
https://qiita.com/ninoko1995/items/b28a712d5f620dbebb6f

●ContentView.swift : 開発者が記述する大方のコードの集約場所、何もなければこちらに集約が基本(サンプルの Hello, World! 文字列はこちらで発見できる)

●フォルダ　Assets.xcassets : アイコン、写真や色等のアセットカタログ

●LaunchScreen.storyboard : アプリ開始時に表示する画面
※表示秒数を長くする場合はsleep()をAppDelegate.swift, 
didFinishLaunchingWithOptionsの配下で指定できる

●Info.plist : パラメーターリスト（表示アプリ名、アイコンファイル指定、ステータスバースタイル、バージョン、バックグラウンドで実行、縦横向き指定・・・）

●xxx.xcdatamodeld : プロジェクト作成時に "Use Core Data" を選択すると作成される。
Core Dataとは　https://developer.apple.com/documentation/coredata


***** 以上は開発で通常意識するもの *****

●フォルダ：Preview Content
　●フォルダ　Preview Assets.xcassets : Assets.xcassets の検証用

●フォルダ：xxxTests : プロジェクト作成時に"Include Unit Tests"を指定すると作成されるフォルダ、必ずしも使わなくて良い
　●xxxTests.swift 
  ●Info.plist 

●フォルダ：xxxUITests : プロジェクト作成時に"Include UI Tests"を指定すると作成されるフォルダ、必ずしも使わなくて良い
　●xxxUITests.swift 
　●Info.plist 

●Products : 
　●xxx.app : ビルド後のプログラム本体
　●xxxTests.xctest : "Include Unit Tests"のビルド
　●xxxUITests.xctest : "Include UI Tests"のビルド

クラスを適用する範囲を指定できるようで、
例えばContentView.swiftは初期時は次の表示になっているが、
Tests, UITestsから呼び出す場合はチェックを入れること。
![截屏2019-11-1816.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/7cb1c83a-469b-9cf4-44e5-dcc9a899c86c.png)
#Mac で CPU  を使って重くする・負荷状態を作るには YES と言いなさい ( $ yes > /dev/null &  )

# 参考

[ひたすらMacを重くする「ストレステスト」をお手軽に - 新・OS X ハッキング!(248) | マイナビニュース](https://news.mynavi.jp/article/osxhack-248/)

# yes コマンドとは

こんなコマンドあったんだ。

>シンプルな、と言えばyesもそうでしょう。引数なしで実行すると、改行されたyが無限に出力され続けます。

[Unixコマンド”yes”についてのちょっとした話 | POSTD](https://postd.cc/a-little-story-about-the-yes-unix-command/)

# 実行

yesをバックグラウンド実行。

`yes > /dev/null & `

# top で確認

こんなに使うのか！

![image](https://user-images.githubusercontent.com/13635059/69016867-ee655300-09e5-11ea-8916-2dfb5a0aae11.png)

# さらに重くする

>前掲のyesコマンドだが、実は複数回繰り返せば他のコアの負荷も上げることができる。4コアのCore i5では、以下のようにyesコマンドの実行を4回繰り返せばいいというわけだ。

# 終了

`killall yes`

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2736








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
SSL証明書が発行できない環境でmastodonのインスタンスを建てた際にハマった部分

#はじめに
この記事は[前回のお話](https://qiita.com/narita1126/items/2926407b3a6ec46ab517)の続きです。

#インスタンスを建てた際にハマった部分

##安全じゃないため接続できないといわれる
現状のほとんどのmastodonのインスタンスを建てる記事は2017~2018年に集中しているため.env.productionからLOCAL_HTTPSの設定ができなくなったということが言及されておらず、私は最初にこの部分でハマってしまいました。（気づかなかった自分がバカなだけなんだがなw）
###解決方法
1. オレオレ証明書を使う
2. mastodonのバージョンを下げる

私はマストドンのバージョンを下げて対処しました。
##Redisのエラーで起動できない
mastodonのバージョンを下げて対処した結果、次はRedisがエラーを吐いてしまい起動できなかった。（サイトには接続できたがページが表示されない）
###原因
docker-compose.ymlのバージョン変更をしていなかった。

バージョンを3から2へ変更したら問題は解決しました。
#インスタンスの設定時にハマった部分
##画像が投稿できない。
マストドンのサーバーを立ち上げることができて、文字のみのトゥートはできたものの、画像の投稿やアイコン画像を変更することができなかった。
###原因
権限の問題。
###解決方法
chown -R 991:991 /(mastodon)/public/system/
このコマンドを打ち込んだら解決した。

またエラーがあったら追記していきます。
基本情報技術者試験の勉強計画　第５週（11/18週）

## 目標と結果
### 目標
・FE90まで終了する
・3e-ビジネスまで終了する
・目標達成する
### 結果
・FE90まで終了した
・3e‐ビジネスまで終了した
・目標は何とか達成した
## 振り返り
### keep
・目標達成する
・過去問道場を少しづつ行う
### problem
・いつもギリギリになってしまい、余裕を持てない
・週では達成できているが、一日の目標が達成できていない日がある
### try
・時間があったら復習
【DBMS_CLOUD】COPY_DATAプロシージャのfile_uri_listに指定するURLについて


オラクルのObject Storageを使った場合の、DBMS_CLOUDでの操作におけるソース・ファイルURIの形式について説明します。

COPY_DATAプロシージャの基本構文は以下のようになります。


```bash

DBMS_CLOUD.COPY_DATA (
	table_name        IN VARCHAR2,
	credential_name   IN VARCHAR2,		
	file_uri_list     IN CLOB,	
	schema_name       IN VARCHAR2 DEFAULT,
	field_list        IN CLOB DEFAULT,
	format            IN CLOB DEFAULT);
```

[DBMS_CLOUDサブプログラムの要約](https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/dbms-cloud.html#GUID-9428EA51-5DDD-43C2-B1F5-CD348C156122)


# Pre-Authenticated Requestを行わない場合

```

https://swiftobjectstorage.<リージョン名>.oraclecloud.com/v1/<テナント名>/<バケット名>/<ファイル名>
```

# Pre-Authenticated Requestを行う場合
```

https://objectstorage.<リージョン名>.oraclecloud.com/p/<自動生成されるハッシュ値>/n/<ネームスペース>/b/<バケット名>/o/<ファイル名>
```

### ドキュメント
* [DBMS_CLOUDパッケージ・ファイルのURI形式](https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/file-uri-formats.html#GUID-5D3E1614-ADF2-4DB5-B2B2-D5613F10E4FA)
Bot Builder v4.5 のユニットテスト: 概要とプロジェクトの作成

このシリーズでは BotBuilder v4.5 で新たに追加されたユニットテストのフレームワークを見ていきます。
BotBuilder のユニットテスト全体の流れについては [Bot Builder v4 でのテストシリーズ](https://qiita.com/kenakamu/items/2a567e31e5d2960dda70) も併せて参照してください。

# 拡張機能のアップデートとプロジェクトの作成

Visual Studio 用にユニットテストを含んだテンプレートが公開されています。こちらを使って新しいプロジェクトを作成してみます。

1\. Visual Studio 拡張機能 | 拡張機能の管理より、「Bot Framework v4 SDK Templates for Visual Studio」のバージョンを確認。古い場合は最新へ更新。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/00904df6-db31-0dda-cf51-c70458e24dd0.png)

2\. 新規プロジェクトより bot を検索。「Core Bot with Tests (Bot Framework v4)」を選択して「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/988711c7-4ae2-178e-abd3-963e10682743.png)

3\. 任意の名前を付けて作成。ここでは MyBotWithUnitTest とした。ソリューション作成後、ボットのプロジェクトとユニットテストプロジェクトがあることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c94f4d0c-d74a-10c8-40c3-eb7c9687c1bf.png)

4\. 中身はこれまでの CoreBot と同様、航空チケットの予約ボットであることを確認。まだ LUIS など必要なコンポーネントを設定していないため、このままでは動作しないが、今回はユニットテスト用として作成したため、このままにしておく。

# ユニットテストを実行

ユニットテストは LUIS やデータベースなど、外部の依存サービスがない状態で動作すべきであり、BotBuilder v4.5 のテストフレームワーくもそのように設計されています。まずはこの状態でテストが動作するか見ていきましょう。

1\. ソリューションをビルドしてエラーがないことを確認。表示 | テストエクスプローラーを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/8c93ae90-6052-87fb-033e-c32fc2c85653.png)

2\. 既存のテストが多数ある事を確認して、「すべてのテストを実行」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/545760f4-29b6-6519-d098-b1cb756d6bb9.png)

3\. テストが無事終了することを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/2b07f304-c36a-1093-9811-b09d03dd9809.png)

# ベースとなるユニットテストフレームワーク

BotBuilder v4.5 では xUnit が使われています。xUnit は NUnit と並んでよくつかわれているテストフレームワークであるため、使ったことがある開発者の方も多いと思いますが、次回以降で使い方を見ていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/f075890a-e82b-a147-f629-9db2f304ed5b.png)

# テスト対象

テストの対象は Bot クラス、コントローラー、ダイアログ の 3 つです。今後中身は別途確認してきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/36ed95ed-1037-9362-b15c-5c00d35f211d.png)

# 使われているフレームワーク

ユニットテストのフレームワークとしては [xUnit](https://github.com/xunit/xunit)
サービスの各種モックには [Moq](https://github.com/Moq) ライブラリが使われています。

[xUnit はこちらのクイックスタートを参照](https://xunit.net/docs/getting-started/netfx/visual-studio)
[Moq はこちらのクイックスタートを参照](https://github.com/Moq/moq4/wiki/Quickstart) 

# まとめ

これまで自力でセットアップしてきたユニットテストが、SDK の一部となり正式なフローも公開されたことで、よりテストしやすくい、またサンプルも見つけやすくなりました。次回はテストの内容についてみていきます。


[次の記事へ](https://qiita.com/kenakamu/items/61a331ad5a87cf57c35a)
[目次へ戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883)
【Oracle SQL】nohupでsqlファイルを実行する


sqlをバックグラウンド実行したいときに、nohupを組み合わせて使うことができます。



```bash

nohup sqlplus /nolog @ファイル名.sql >> ログファイル名.log &
```
コマンド実行後に以下の形式でプロセスIDが表示されます。

```

[数字]プロセスID
```
エンターを押すと、入力カーソルに戻ります。
　
### nohup
>「nohup コマンド &」のようにnohupを付けてコマンドを実行すると、このHUPシグナルを無視させます。つまり、仮想端末を閉じたりログアウトしたりしても、コマンドは終了せず、そのまま処理を続行します。

### 参考
* [【 nohup 】コマンド――端末を閉じてもログアウトしても処理を続ける：Linux基本コマンドTips（137） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1708/24/news022.html)
達人に学ぶSQLで文字化けしたらエンコーディングを「ShiftJIS」にしよう

達人に学ぶSQL徹底指南書のダウンロードデータをエディタで開いたら文字化けしてしまいました。
エンコーディングをShiftJISにしたら直ったので、同じようにお困りの方はエンコーディングをShiftJISにしてみてください。

そういえば、同じ著者のキリンが描かれた初級者用のSQLの本のダウンロードデータも文字化けしていました。
こちらもShiftJISに変更すれば直るはずです。

SQLがんばりましょう！
Rails は IN 句に NULL を入れて良いのか？

つまり `User.where(code: [1, 2, nil])` なんて書き方は大丈夫なの？

## 結論

配列なら大丈夫です、Railsが勝手にやってくれます、速度面だけは少し注意
サブクエリは駄目です

## 不安な理由： SQLではNULL比較ができない

SQL では `IS NULL` を使う必要があり IN 句で NULL は正しく動きません

```sql
WHERE code IN (NULL) -- NG: code が NULL のレコードが取れない
WHERE code IS NULL   -- OK
```

## 確認: 実行SQLを出力する

全部 IN 区に入れず `OR code IS NULL` と勝手に NULL 考慮 SQL を作ってくれます
楽だけど `where(code: [1, 2, nil])` の実装からは認識しにくい `OR` が生えてる
速度のほうは大丈夫？

```ruby
> User.where(code: [1, 2, nil]).to_sql
=> "SELECT `users`.* FROM `users` 
    WHERE (`users`.`code` IN ('1', '2') OR `users`.`code` IS NULL)"
```

## 注意: サブクエリ

与える配列が他テーブルから取得した場合を考えます
`pluck` 等で一旦配列にしてから与えると上記の通り考慮されますが
`select` でサブクエリとして与えると変換する余地がなく SQL に従い無視されます

```ruby
User.where(code: Profile.pluck(:code)).to_sql
=> "SELECT `users`.* FROM `users` 
    WHERE (`users`.`code` IN ('1', '2') OR `users`.`code` IS NULL)"
User.where(code: Profile.pluck(:code)).to_a
=> [#<User: code=1>, #<User: code=2>, #<User: code=nil>]

User.where(code: Profile.select(:code)).to_sql
=> "SELECT `users`.* FROM `users` 
    WHERE `users`.`code` IN (SELECT `profiles`.`code` FROM `profiles`)"
User.where(code: Profile.select(:code)).to_a
=> [#<User: code=1>, #<User: code=2>]  ## code=nil が取れない！
```

## 補足: NOT IN でも同じ

```ruby
User.where.not(id: [1,2, nil]).to_sql
=> "SELECT `users`.* FROM `users` WHERE NOT ((`users`.`id` IN (1, 2) OR `users`.`id` IS NULL))"
```

## 感想

記述が少なくて便利なのは裏で色々やっていることの裏返し
ActiveRecord を使いこなすには、どのような SQL が作られるかを知っておきたい

## 参考 

* [MySQL: NULLは比較できない](https://qiita.com/g-snowhawk/items/637b04266a1f614329bf)
railsで複数モデルを保存するとき

Railsで複数モデルを同時に保存する必要がある際、トランザクション内で

```rb
ActiveRecord::Base.transaction do
  保存成功時の処理 if models.all?(&:save)
  raise "error"
end
```

みたいに書きたいことがあったが、all?はある要素の`save`がfalseを返した場合、それ以降の要素についてsaveメソッドを実行しない。saveメソッドの実行によりエラーメッセージを取得したいような場合、全ての要素について実行してもらう必要がある。今回は以下のように書いた。

```rb
ActiveRecord::Base.transaction do
  保存成功時の処理 if models.inject(true){|result, elem| result && elem.save }
  raise "error"
end
```

もっと良い書き方があれば是非ご指摘ください。

**2019/11/20 追記**
@betrue12さんから`models.map(&:save).all?`で良いのでは？とご指摘いただいて、確かにその通りでしたので追記させていただきます。下記のように書き直しました。

```rb
ActiveRecord::Base.transaction do
  保存成功時の処理 if models.map(&:save).all?
  raise "error"
end
```
Node.jsでperformance.now()を使用した際に"ReferenceError: performance is not defined"というエラーが出る

## TL; DR
以下のいずれかの方法でperformanceオブジェクトを宣言する。

```javascript
const performance = require('perf_hooks').performance;
```
もしくは

```javascript

const { performance } = require('perf_hooks');
```

## 詳細

```javascript
var t0 = performance.now();
console.log( 'Do something' );
var t1 = performance.now();
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");
```

上記のようなコードをNode.jsで実行すると`ReferenceError: performance is not defined`というエラーが出た。
Node.jsで[Performance API](https://developer.mozilla.org/ja/docs/Web/API/Performance_API)を使用するには[Performance Timing API](https://nodejs.org/api/perf_hooks.html#perf_hooks_performance_timing_api)のドキュメントにあるように`pref_hook`モジュールをインポートしてあげる必要があるみたいでした。

## 発展
Chromeでは、わざわざインポートしなくても`performance.now()`が使えるのにどうしてNode.jsではインポートする必要があるのか疑問に思いとさらに調べてみました。

どうやらNode.jsではPerformance APIはまだ試験的に実装されている段階なのでChromeとは違いglobalオブジェクト(Chromeの場合はwindow)にエクスポーズしていないみたいでした[^1]。
globalにエクスポーズするプルリクも既に出ている[^2]ので試験的な段階が終了すればNode.jsでもモジュールをインポートせずに使えるようになりそうです。



[^1]: https://github.com/nodejs/node/issues/28635
[^2]: https://github.com/nodejs/node/pull/29432
【初心者】jQuery　さまざまなメソッド　classとid【備忘録１６】

##11/15～11/16に勉強したこと【jQuery】

HTML/CSSで実現できなかったクリックに応じた
アクションやフォーム・アニメーションを表示することが可能。

$('セレクタ').メソッド(引数);
で「何を(セレクタ)どうするか(メソッド(引数))」で基本的に書かれる。

###さまざまなメソッド１

隠したり、表示するときに使うメソッド。
【例】

```js

//隠す
$('h1').hide();

//表示させる(css)
img{
 display:none;
}

//表示させる(js)
$('img').show();

```

###さまざまなメソッド２
アニメーション付きで隠したり表示させたりするメソッド。
【例】

```js

//アニメーション付きで徐々に消えていく
$('h1').fadeOut();

//アニメーション付きで徐々に表示
$('h1').fadeIn();

//アニメーション付きで下から上へスライドで消えていく
$('h1').sLideUp();

//アニメーション付きで上から下へスライドで消えていく
$('h1').slideDown();

```
それぞれ、アニメーションのあるメソッドは
メソッドの後の()の中に文字や値を入れることで指定が可能。
「slow」と入力するとゆっくりに、
「1500」と入力すると1.5秒の間に表示・隠すことができる。

###idとclass
htmlを書く際に今までclassを使って
部分的に名前を付けてcssに反応させることができた。
他にidという文字を使って同じように名前を付けることができる。

同じよう・・・とは言いますが、違いがあるので注意！
#####＜複数使用＞
-　id⇒同ページで複数はダメ！

```js
<div id="first">....
<div id="first">....
```
-　class⇒同ページで複数OK！

```js
<div class="one">....
<div class="one">....
```

#####＜同じ要素の中でのidとclass＞
同じ要素の中でidとclass両方付けることは可能

```js
<div id="red" class="blue">....
//とか
<div class="green" class="red">...
```

#####＜優先順位＞
idとclassだと優先的に処理されるのは【id】の方

```js
//html
<div>
   <p id="blue" class="red">色</p>
</div>

//css
.red{
  color:red;
}

#blue{
  color:blue;
}

```
【出力】
青色で「色」と出力される。

###classとidをセレクタに入力
cssで書いてたのと同じようにclassを書くときは【.class名】
idを書くときは【#id名】で書くようにする。



####◎おまけ知識～TOPへ戻る～
htmlで「トップに戻るリンクを作りたい」とき
【例】

```js
<div id="top">...</div>
<a href="#top">トップへ戻る</a>
```

上記のように、リンク先を「#top」にすることで
ページ内リンクを簡単に作れる。
MacでDocker上に日本語環境のMySQL8.0を建てる

# 前書き

* DockerにMySQLコンテナを日本語環境でサクッと建てたい！
* MySQLのバージョンは最新のバージョン(8)にしたい！
* Macで作業したい！

を叶えるためのメモ。
タイトルでMacと謳っていますがWindowsでもほぼ同じ手順です。
違いはDockerのインストーラーがMac用かWindows用かだけです。

# 環境

* Mac 10.15.1 (Catalina)
* Docker for Mac


# 事前準備
1. Docker Desktop for Mac をインストールする
　参考URL：https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81

2. Kitematic をインストールする
　→DockerコンテナをGUIで操作できるアプリ。インストール手順はタスクトレイのDockerアイコンから。
　　docker-composeで設定した共有ディレクトリやポートなどの確認もこれで行いました。


# docker-composeでMySQLコンテナを立てる

参考URL

* [docker-compose でMySQL環境簡単構築](https://qiita.com/A-Kira/items/f401aea261693c395966)
* [最速で日本語環境のMySQL Dockerコンテナを建てる方法](https://qiita.com/muff1225/items/48e0753e7b745ec3ecbd)


上記を参考に、MySQL8のコンテナを日本語環境で建てる。
特に2つ目のリンクはほぼそのまま参考にさせていただきました。

```yml:docker-compose.yml
version: '3'

services:
  mysql:
    build:
      context: ./mysql
      dockerfile: Dockerfile
    environment:
      MYSQL_ROOT_PASSWORD: root   #rootユーザのパスワード
      MYSQL_USER: test            #ユーザアカウント
      MYSQL_PASSWORD: password    #ユーザアカウントのパスワード
      MYSQL_DATABASE: testDb      #DB名
      TZ: "Asia/Tokyo"
    ports:
      - 13306:3306
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/sql:/docker-entrypoint-initdb.d
```

```dockerfile:Dockerfile
FROM mysql:8.0

# Set debian default locale to ja_JP.UTF-8
RUN apt-get update && \
    apt-get install -y locales && \
    rm -rf /var/lib/apt/lists/* && \
    echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8

# Set MySQL character
RUN { \
    echo '[mysqld]'; \
    echo 'character-set-server=utf8mb4'; \
    echo 'collation-server=utf8mb4_general_ci'; \
    echo '[client]'; \
    echo 'default-character-set=utf8mb4'; \
} > /etc/mysql/conf.d/charset.cnf
```

上記のディレクトリイメージは以下の通り。

```txt
├── docker-compose.yml
└── mysql
    ├── Dockerfile (上記のファイル)
    ├── data (ディレクトリ)
    └── sql (ディレクトリ)
```



接続確認は適当なDBクライアントでOK.
個人的には`DBeaver`を使いました。Windowsだと`A5:SQL Mk-2`が好きなのですが…。

初期構築用のCreateTableやInsertなどのSQLファイルはsqlディレクトリに放り込むイメージです。
iOS firebase cloud functionsのcallで3840エラーが出たら

#エラーが起きる時
###functions側（Typescript）

```typescript
import * as functions from 'firebase-functions'

export const callTest = functions.region('asia-northeast1').https.onCall(data => {
  console.log('callTest called!')

  return {
    A: 'Hello World',
    B: 42
  }
})
```

###クライアント側

```swift
import Firebase

// ~省略~

func call() {
    Functions.functions().httpsCallable("callTest").call { (result, error) in
        if let result = result,
            let resData = result.data as? [String : Any] {
                print(resData)
                print("***成功だよ")
        }
            
        if let error = error {
            print(error)
            print("***エラーだよ")
        } else {
            print("***エラーはないよ")
        }
    }
}
```

###エラー

```
Error Domain = NSCocoaErrorDomain 
Code = 3840 
"JSON text did not start with array or object and option to allow fragments not set." 
```

#解決法
クライアント側で`Functions.functions()`をするとき、呼び出したいfunctionがデプロイされているregionを指定する。

```swift
func call() {
    Functions.functions(region: "asia-northeast1").httpsCallable("callTest").call { (result, error) in
        // ~省略~
    }
}
```

原因はよくわからなかったので知っている方がいれば是非教えてください。
音オペレーションで革命的なUXを！


### まえふり

もう年末が近いですね。
1999年の大みそかから2000年になった時に将来の不安よりドキドキ感が強かったもんですがもうあれから20年近く時間が過ぎてしまったんですねー。
AIやらマネージドサービスやらで、がしがしプラットフォーマーが世の中をひっぱってってくれているんですが、

 - 「[XXX     ] [検索]　(カチッ)」とかいうCMに出てくるやつ
 - （ラジオで）「番組へのお便りはなんちゃらアットマークにメールください」

こういうのいい加減めんどくさいUXなんでやめたら良いと思うんです。20年前のURL一字一句手打ちとどう違うのかと。
どんなに短くなっても復活の呪文を打つのが変わらないならおんなじかと。

ITリテラシー問題とするのであれば音声認識、言語処理がリテラシーが低い人にも使い易く人気ですが
スマートスピーカーのウェイクワードって恥ずかしい。日本人が消極的なんじゃなくて普通にヘンに見える。
言霊とか人形供養とかセンシティブに魂を扱って来た遺伝子がそう思わせてるんじゃないか。（因果推論）

QRもスマホだしてアプリさがしてうごかしてQRコードにかざしてURLクリックしてとスマートなようなそうじゃないような。

**デバイス同士で会話してくれ！人間巻き込むな！**

### 音でデータを送る

ちょっと前にChripというのを紹介している記事があって、

[音通信ライブラリChirpを利用してTHETAを操る](https://qiita.com/KA-2/items/3de2e5a590c7768c6325)

面白かったので使ってみたが各種SDKとか組み込めるネタがバッチシあるのに内部でAPIトークン持ってるので
タダだけど提供側に見られちゃってる感があるのでもっと、きさくに使えるの無いかなーって探したら、あったQuiet.js。

[Quiet.js Transmit and receive data in the browser at 44.1kHz](https://quiet.github.io/quiet-js/)

ただこれブラウザでjavascript呼び込む仕組みにべったり依存しているので汎用的には動かない。

よって**魔改造開始**

[Google Extension　要は音でブラウザに入力できる](https://github.com/yasutakatou/quietjs_extension)

[node.js　要は音でキーボード操作できる](https://github.com/yasutakatou/quietjs_nodejs)

*※quiet.jsのライセンスがよく分からないので同梱していません。同じフォルダにquiet.js、quiet-emscripten.js、quiet-emscripten.js.memを置いてあげれば動きます。*

**複数台PCでエージェント立ち上げてスピーカーで流せばオーケストラ・オーケストレーション（？？？）だな、これ！**

あとこの技術が楽しいのは不可聴領域を使えるので、そこにノイズにならないような音であれば同時に流してもOK！つまり、

 - CMにまぜてしまえばスマホワンポチで特設サイトまで誘導
 - 電車内で流せば車内放送の聞き逃し、満員電車でトレインチャンネルが見れないが解消
 - 社歌にデータ混ぜて打刻とかすればいい。~~普通社歌って絶滅危惧種だからこのアイディア無し~~

こういう使い方もできるわけで相当可能性があると思われます。
というわけでバンバン使うといいよ！

**あ、録音&輻輳されたら死亡です。**

### 愚痴

スマホからキックしたくてcordovaに組み込むのトライしましたが、
もともとのJSコードをそれ作者にどうなのよ？というレベル改造しまくらないと動かないみたいなのでやめました。
今からKotlinや、React Native学習してよしんば動いたとしても1Qくらいかかっちゃう気がするのに、
スマホ自体にhttpd入れてループバックでブラウザから開くと余裕で動くのにアプリだと動かないとかブラウザの利便性異常だと思った。
同じことするだけなのにイチから勉強するモチベーションが。。
なんとか突破したかったけど参考に録音系のアプリ探してみても、ただ、外部のサイトをブラウザで開くだけのアプリばっか出てきてうんざりしたところで打ち止め。
*※ブラウザで開くとThe AudioContext was not allowed to start. とか諸問題も回避できる。*
ゲームのデモ状態のときの動き(右左に自動で動かす))　~timeclock DAY3~

#完成イメージ
![Screenshot_20191118-154019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529120/c0164b7f-e1cc-075f-e579-bb1511265340.png)
こんな感じで上(赤ゾーン)から下(青ゾーン)に障害物が落ちる
→下のところ(青)で避けるっいうゲーム
*説明のしたにHTML,cssもかいてあるのでコピペで動かしてみてください…

##コード
```javascript

//要素をhtmlから引っ張り出す
var escaper = document.getElementById("escaper");
var escaperzone = document.getElementById("escaperzone");
var text = document.getElementById("text");
escaper.style.left　=　"0px";
function demomove(){
  var demonumber = Math.floor(Math.random()*4);
  
  var demoleft=escaper.getBoundingClientRect().left;
  
  if(demonumber==0){
   var demoleft = demoleft+escaperzone.clientWidth*0.1;
  }
  else if(demonumber==1){
    var demoleft = demoleft+escaperzone.clientWidth*0.05;
  }
  else if(demonumber==2){
    var demoleft = demoleft-escaperzone.clientWidth*0.1;
  } 
  else if(demonumber==3){
    var demoleft = demoleft-escaperzone.clientWidth*0.2;
  } 
  else{
    console.log("not move");
  }
  if(demoleft<=0){
    demoleft = demoleft*-1;
  }
  if(demoleft>=escaperzone.clientWidth*0.9){
    demoleft = escaperzone.clientWidth*0.9-Math.abs(demoleft-escaperzone.clientWidth);
  }
  console.log(escaperzone.clientWidth);
  text.innerHTML=demoleft;
  escaper.style.left = demoleft +　"px";
  }
setInterval(demomove,1000);
```

↓右左に適当に動かすためのもの

```javascript


var demonumber = Math.floor(Math.random()*4);
  var demoleft=escaper.getBoundingClientRect().left;
  
  if(demonumber==0){
   var demoleft = demoleft+escaperzone.clientWidth*0.1;
  }
  else if(demonumber==1){
    var demoleft = demoleft+escaperzone.clientWidth*0.05;
  }
  else if(demonumber==2){
    var demoleft = demoleft-escaperzone.clientWidth*0.1;
  } 
  else if(demonumber==3){
    var demoleft = demoleft-escaperzone.clientWidth*0.2;
  } 
  else{
    console.log("not move");
  }
```

ランダムで乱数出してその乱数に応じて動かす。数値を変えるだけで動きが大きく変わる

↓端に当たったときの対応

```javascript
if(demoleft<=0){
    demoleft = demoleft*-1;
  }
  if(demoleft>=escaperzone.clientWidth*0.9){
    demoleft = escaperzone.clientWidth*0.9-Math.abs(demoleft-escaperzone.clientWidth);
  }
```

上が左端にいったとき
値がマイナスなのでマイナスをかけてプラスにする　　

下が右端にいったとき
親要素(全体)の横幅より大きいのでその大きい分を親要素から引く
例)
変化前
全体1000px Ｘ座標1100px
↓全体-|Ｘ座標-全体|
↓Math.abs=|値|=値の絶対値
変化後
全体1000px Ｘ座標900px

また動かすものの左端がx座標になるので、親要素(全体の数値)をそのまま使ってこの処理をするとはみ出る
→数値の基準を親要素の横幅-動かす要素の横幅にする

実在に動かす(設定)

```javascript
text.innerHTML=demoleft;
  escaper.style.left = demoleft +　"px";
```

ついでに左端からの距離を表示してます

繰り返し

```javascript
setInterval(demomove,1000);
```

上のすべての処理はdemomoveという関数でまとめられているので、1秒ごとに実行する

###いるかわからないけど装飾類↓
```HTML 
<html>
 <head></head> 
 <body> 
  <div id="topzone"> 
   <p id="text">ptw</p> 
  </div> 
  <div id="escaperzone"> 
   <div id="escaper"></div> 
  </div> 
 </body>
</html>
```
```css
#topzone{
  width: 100vw;
  height: 90vh;
  background-color: red;
}

#text{
font-size: 10vw;  
}

#escaperzone{
  width: 100vw;
  height: 10vh;
  background-color: blue;
  position: relative;
}

#escaper{
  width: 10%;
  height: 100%;
  background-color: green;
  left: 300px;
  position: absolute;
}
```

###まとめ
以上で適当に右左に動いてくれる。
ユーザーのプレイに戻すときはclearIntervalを使ってdemomoveを動かせないようにする。
function($query)を使って条件しぼってwhereInにぶっこむ


```php
public function getArticleEditors()
    {
        return $this->model->whereIn('staff.id', function($query) {
            $query->from('article')
                ->selectRaw('distinct article.assigned_user_id');
        })
            ->select('staff.id', 'staff.name')
            ->get();
    }
```

最後にget()をつかうとcollectionクラスのオブジェクト(中身はmodelクラス)になって、get()を省略すると、builderクラスのオブジェクトになる。
google広告　出し方

・出した広告と関係ないキーワードでも広告は出せる。
google広告→キーワード　有効or承認になっていればOK。

パパ活などアダルトなキーワード
→通るかどうかは一度入れてみて、有効になるかどうかで判断するしかない

アフィリエイトサイトの広告
→審査は厳しくなるが、通る可能性はある。

上限クリック単価の変更
設定→入札単価→クリック数の最大化→矢印→上限 CPC による入札の上限　で金額を入力。

◯除外キーワードの設定
キーワード→除外キーワード

![概要 - 891-025-1338 - Google 広告.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484062/b9757586-93b9-e3b2-8eef-dc2aad832444.png)
黄色いチェック
品質スコアが低いコンポーネント
・高いほど、表示順位が上がる
→検索しても出てきづらくなっている

どう上げるの？

・広告とキーワードの関連性を考える
・最終ランディングページに関連したものにキーワードを変える

◎表示回数
安定するのに２週間ほどかかる。
入札単価を変えるなど工夫してみると上がる。
Webデザイナーがサイトを作る時、いつも.htaccessに書いていること


Webデザイナーのあやおり子です。

Webページを作成する時は、必ずと言ってもいいほど.htaccessを設定しています。
今回は、サイトを作る時にいつも.htaccessに書いてあることを紹介します。

# 前提

- `# ~`と書いてある行はコメントアウト(.htaccessの仕様)
- 直書き(スクラッチ)で作る※WordpressなどのCMSにすると、プラグインやサーバー・CMSの仕様によって記述内容を調整する必要があるため)
- 新規サイト

# 記述コード全て

```
# XAMPPの権限対策
# Options Indexes MultiViews FollowSymLinks

# ページがなかった場合、リダイレクト
ErrorDocument 404 /404

# Basic認証
AuthType Basic
AuthName "Input your ID and Password."
# AuthUserFile テスト環境絶対パス
AuthUserFile 本番環境絶対パス
require valid-user

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # 拡張子省略
  RewriteCond %{REQUEST_FILENAME}\.php -f
  RewriteRule ^(.+)$ $1\.php

  # SSL設定
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

  # www設定
  RewriteCond %{HTTP_HOST} ^www.サイト名.com
  RewriteRule ^(.*)$ https://サイト名.com/$1 [R=301,L]
</IfModule>

```

# 解説
一文ずつ解説していきます。

## XAMPPの権限対策

```
# Options Indexes MultiViews FollowSymLinks
```

私のXampp設定が悪いんだと思うのですが...
この文章を書かないと、私のローカル環境が表示されません!!
本番に上げる時はコメントアウトしており、
テスト環境の時はコメントアウトを外しています。


## ページがなかった場合、リダイレクト

```
ErrorDocument 404 /404.php
```

ページがなかった場合に表示される404ページを指定します。
この場合、(`サイトドメイン/404.php`)がリダイレクト先です。
LPでしたら、トップページを指定してもいいかもしれません。

## Basic認証

```
AuthType Basic
AuthName "Input your ID and Password."
# AuthUserFile テスト環境絶対パス/.htaccess
AuthUserFile 本番環境絶対パス/.htaccess
require valid-user
```

私の場合、コーディングの8割が新規サイトですので、ベーシック認証は必須です。
.htaccessの場所を絶対パスで記述します。

## 書き換え設定

```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

設定したい項目を書く

</IfModule>
```
`<IfModule mod_rewrite.c>`の中に書いてあるのは、
もし書き換えが可能だったら場合に実行する項目のこと。
以下が`<IfModule mod_rewrite.c>`に記述する項目です。

### 拡張子省略

```
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1\.php
```

Wordpressではなく直書きで書く場合は、
何も設定しない場合`サイトドメイン/ファイル名.php`が標準のURLとなります。
しかし、ファイル名.phpと毎回書くのもめんどくさいし、急に「CMSに変えたい」と言われた時に対応出来ません。
この記述を加えることで、`サイトドメイン/ファイル名`で表示されるようになり、リンクが楽になります。

直書きだと分かりづらくなるので、セキュリティ的にも向上するんじゃないのかなーとも思います。

なお、この記述がある上で`サイトドメイン/ファイル名.php`と入力してすると、
`サイトドメイン/ファイル名`にリダイレクトされます。

私の会社ではPHPファイルしか使わないのですが、HTMLファイルも扱う場合は、
上記ファイルの'.php'を'.html'に変えたものを追記する必要があると思います。

### SSL設定

```
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
```

HTTPでアクセスされたものをHTTPSにリダイレクトします。

### www設定

```
RewriteCond %{HTTP_HOST} ^www.サイト名.com
RewriteRule ^(.*)$ https://サイト名.com/$1 [R=301,L]
```

www付きでアクセスしてきた場合、wwwなしに書き換えます。
テスト　橘田　応用数学、機械学習、深層学習：前編１

# 応用数学
## 線形代数学：行列～特異値分解
特異行列の求め方をすっかり忘れていて、自信が無くなった。（100文字以上書く）

# 機械学習
## 線形回帰モデル：機械学習とは～ハンズオン

# 深層学習（前編1）
## Section1：入力層～中間層：深層学習1-1～1-6

これを「未投稿」のまま完成まで続け、レポートが完成したら「投稿」すれば、１つのURLになるのかな？
特定のディレクトリ内のファイル中の文字列をまとめて置換

# まとめて置換する

特定のディレクトリの中にある全ファイルの中にある、特定の文字列を一気にまとめて置換する方法を自分用にメモ。grepの-rオプションにより子ディレクトリ内のファイルについても再帰的に適用される。

- ファイルを上書きする

```
grep '置換前の文字列' -rl '対象のディレクトリ' | xargs sed -i -e 's/置換前の文字列/置換後の文字列/g'
```

- バックアップファイル(.bak)を残す

```
grep '置換前の文字列' -rl '対象のディレクトリ' | xargs sed -i.bak -e 's/置換前の文字列/置換後の文字列/g'
```

- 置換する文字列にスラッシュ( / )が含まれる
 - sedコマンドに用いる区切り文字にはスラッシュ( / )以外も使用できる

```
grep '置換前の文字列' -rl '対象のディレクトリ' | xargs sed -i -e 's#置換前の文字列#置換後の文字列#g'
```
ESXiに表示されたSSHとESXiシェルの警告表示を消す方法

#概要
ESXiのweb GUIにログインした際、以下のメッセージが表示されることがある。

```
「ホストの ESXi シェルは有効になっています」
「ホストの SSH は有効になっています」
```

これらはそれぞれESXサーバのシェル・SSHが有効の際に表示されるのだが
とても鬱陶しいので警告を消す。

#方法
1. ESXiのweb GUIにて、左ペインより管理を選択→「詳細設定」をクリックする

2. 「詳細設定」の画面が開くため、左ツリーから「UserVars」を選択し、最下部にある「UserVars.SuppressShellWarning」の値を"0"→"1"に変更する
　※"0"が警告有効、"1"が警告無効

以上
UPS関連個人的メモ（VMware）

#ESXi
サーバ本体のダウンロードページよりESXiの最新をダウンロード
（DELLの場合[ここ](https://www.dell.com/support/home/jp/ja/jpbsd1/?c=jp&l=ja&~ck=mn)からシリアル検索）

インストール時はエクスプレスビルダー経由でOSタイプを「Any Other OS」に設定


#UPS設定（APC）
フロントパネルより
・設定モードをアドバンスドへ変更
・IP設定
にてIP関連を設定

ブラウザより設定したIPへアクセス（アカウントはデフォルトでapc/apc）
各種設定を行う

#vMA
https://partner.clubapc.jp/

上記URLにログイン後、ソフトウェアのダウンロード→製品番号入力→最新の仮想アプライアンスをダウンロード
ESX GUI
より新規仮想マシン作成→ダウンロードしたOVAを選択しマシン作成
【初学者】Gemを使用せず画像投稿機能を実装する【Rails】

Progate修了後レベルを対象にした記事になります

#画像投稿機能でつまづきました。
Progateで画像情報をアップデートする（既に作成されたユーザー情報のプロフィール画像を変更する）ということは学べました

しかし「新規記事投稿時に画像を添付する」ことは学べなかったので、実装時につまづいてしまいました。

##Gemは使用しない
Gemを使用すれば早いかもしれませんが、エラーから目を背けては基礎知識の習得ができないと思い使用しませんでした。

###画像添付しない投稿機能
```ruby:view
    <%= form_tag("/posts/create") do %> 
     <div>
        <input type="text" name ="title">
        <textarea name="content"></textarea>
        <input type="submit" valie="投稿">
     </div>
    <%end%>
```

```ruby:post_controller
  def create
    @post = Post.new(title: params[:title],
                     content: params[:content],
                     user_id: @current_user.id）

    if @post.save
      flash[:notice] = "投稿しました"
      redirect_to("/")
    else
      render("posts/new")
    end
  end
```
ここまではProgateで学んだ知識をそのまま記載しているだけです。
View側から送られた情報をParams[:]で受け取り保存。
redirectで別のViewへ移動しています。
保存に失敗したらもともViewに戻ります。

###画像を添付する投稿機能
```ruby:view
    <%= form_tag("/posts/create",{multipart:true}) do %> 
     <div>
        <input type="text" name ="title">
        <textarea name="content"></textarea>
        <input type = "file" name ="post_image">
        <input type="submit" valie="投稿">
     </div>
    <%end%>
```

Viewに関してはProgateで学んだ知識のみで変更可能です。
・form_tagに`{multipart:true}`を追加
・画像添付用の`<input>`を追加




```ruby:post_controller
  def create
    @post = Post.new(title: params[:title],
                     content: params[:content],
                     user_id: @current_user.id,
                     post_image: nil) 
    @post.save
    
    if params[:post_image]
      @post.post_image = "#{@post.id}.jpg"
      image = params[:post_image]
      File.binwrite("public/post_images/#{@post.post_image}",image.read)
    end

    if @post.save
      flash[:notice] = "投稿しました"
      redirect_to("/")
    else
      render("posts/new")
    end
  end
```

`post_image: nil`の記述は無視して構いません。
※DBのテーブル状にpost_imageのカラムがある事をエディタ上でも視覚化したかっただけです。

###違うところ
Viewから受け取ったあと、画像の取り込みを行う前に`@post.save`することが必要でした。

`@post.post_image = "#{@post.id}.jpg"`
という記述では「15.jpg」のように「**そのpostのid**＋jpg」に画像ファイル名を定義しています。
しかし`@post.save`をしていないと
「まだpost.idがない状態」となってしまい画像ファイル名が「.jpg」という**idが入っていないもの**になってしまいます。

###こうして記事にしてみると、こんな簡単な事だったのかと悲しくなりました・・・。僕の２日間を返してくれ・・・。
QualityForward APIをER図化してみました

[QualityForward](http://bit.ly/382le83)はクラウドベースのテスト管理サービスです。Web APIを提供しているのですが、その全体像が掴みづらいので、erdを使ってER図化してみました。

![qualityforward.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/fa48f287-c658-c791-2f33-39b4ec2714e6.jpeg)


実際のerファイルの内容です。

```yaml
[Tenant]
*id
name
cidr_whitelist

[Project]
*id
tenant
name
description
label_pass
excluded_from_progress_pass
supplement_pass
default_label_category1
default_label_category25
default_label_content1
default_label_content10
created_at
updated_at

[User]
*id
name
email
current_tenant_id

[TestSuite]
*id
project_id
name
label_category1
use_category1
label_category25
use_category25
label_content1
use_content1
label_content10
use_content10
coverage_panel_column
created_at
updated_at

[TestSuiteVersion]
*id
test_suite_id
name
status
user
note
latest_test_cycle_duration_sec
lock
lock_memo
created_at
updated_at

[TestCase]
*id
test_suite_version_id
no
priority
category1
category25
created_at
updated_at

[TestPhase]
*id
project_id
name
start_on
end_on
redmine_issues_url
test_suite_assignments
created_at
updated_at

[TestSuiteAssignment]
*id
test_phase_id
test_suite_version_id

[TestCycle]
*id
status
name
target_priorities
target_results
target_test_case_no_list
test_suite_assignment_id
start_on
end_on
created_at
updated_at

[TestResult]
*id
user
test_case_id
test_case_no
test_cycle_id
result
result_supplement
executed_at
content1
content3
created_at
updated_at


Tenant *--1 User
Project *--1 Tenant
TestSuiteVersion *--1 User

TestSuite *--1 Project
TestPhase *--1 Project
TestSuiteAssignment *--1 TestPhase
TestSuiteAssignment *--1 TestSuiteVersion
TestCycle *--1 TestSuiteAssignment

TestSuiteVersion *--1 TestSuite
TestCase *--1 TestSuiteVersion
TestResult *--1 User
TestResult *--1 TestCase
TestResult *--1 TestCycle
```

実際のデータベースではもっと細かくフィールドやテーブルが存在しますが、外部に公開しているレベルでは以下の10個のモデルを扱います。

- Tenant
- Project
- User
- TestSuite
- TestSuiteVersion
- TestCase
- TestPhase
- TestSuiteAssignment
- TestCycle
- TestResult

基本的にこの各モデルに対してWeb APIが提供されていますが、TenantとTestSuiteAssignmentはWeb APIが用意されていないので注意してください。Tenant（利用企業情報）を使うことは殆どないと思いますが、TestSuiteAssignmentは利用機会が多いでしょう。TestSuiteAssignmentはTestPhaseを取得する際に一緒に入ってくる情報になります。

Web APIの全体像が分からない場合にはER図化してみると分かりやすいです。提供側としてもうまく連結していない部分や過不足した情報が分かるようになるのでお勧めです。

[QualityForward](http://bit.ly/382le83)
[勉強会まとめ] Mean teachers are better role models

# 読んだ論文
"Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results"
[論文のリンク](https://arxiv.org/pdf/1703.01780.pdf)
2017年にSoTAをとっていた。

[d-SNE](https://qiita.com/H_satomi/items/3ac1f5846bab841a6778)のSemi-Supervised Extensionで用いられている手法なので読んでみた。

# どんなもの？

- Temporal Ensemblingの大きなデータセットを扱いにくいという問題を解決するためにモデルの重みの平均化する手法を提案
- Temporal Ensemblingよりも少ないラベル付きデータで学習が可能

# 新規性

- Temporal Ensemblingで用いられた予測値の代わりに重みの平均化を用いる点

# 技術や手法
## 半教師あり学習

Temporal EnsemblingやMean Teacherは、StudentモデルとTeacherモデルを用いる。StudentモデルをTeacherモデルに似せることで半教師あり学習を行う。
Teacherモデルがターゲットラベルを作り、それをStudentモデルが学習する。

## Mean Teacher

![image.png](https://user-images.githubusercontent.com/544269/35131133-af6bb794-fd07-11e7-84bf-113e363cf980.png)

最後の重みを直接使うより、学習段階で重みを平均化する方がより良いモデルが作れるらしい。また、重みの平均化により中間表現の表現能力も向上するらしい。
StudentモデルとTeacherモデルの重みを共有する代わりに、Teacherモデルの重みはStudentモデルの重みの指数移動平均(Exponential Moving Average)を用いる。

Temporal Ensemblingと比べた、実用的な面での利点が2つ挙げられている。

- ターゲットラベルの精度が上がるとStudentモデルとTeacherモデルのフィードバックループが速くなり、推定精度が向上する。
- 大規模なデータセットとオンライン学習に対応する。

### Consistency Cost
consistency costはStudentモデルの出力とTeacherモデルの出力との距離として定義される。
consistency cost$J$は、
Studentモデルの重みを$\theta$, ノイズを$\eta$, 
Teacherモデルの重みを$\theta'$, ノイズを$\eta'$
とすると以下のように書ける。

$${\displaystyle J(\theta) = \mathbb{E}_{x, \eta',\eta}\left[\lVert f(x, \theta', \eta')-f(x, \theta, \eta)\rVert^2\right]}$$


$\Pi$モデルやTemporal EnsemblingとMean Teacherの違いは、Teacherモデルの予測の作り方である。$\Pi$モデルでは$\theta'=\theta$を用い、Temporal Ensemblingでは連続予測の加重平均で$f(x, \theta', \eta')$を近似するが、Mean Teacherでは、学習ステップ$t$での$\theta_t'$を以下の式のようにした。

$${\displaystyle \theta_t'=\alpha \theta_{t-1}'+(1-\alpha)\theta_t}$$

$\alpha$は、平滑化係数でハイパーパラメータである。
確率的勾配降下法(SGD)を用いて各学習ステップでノイズ$\eta$, $\eta'$をサンプリングすることによってconsistency costを近似できる。
実験では、平均二乗誤差(MSE)をconsistency costとして使用する。



### Mean Teacherの学習方法
ラベルありのデータでStudentモデルを学習させて重みを更新し、Studentモデルの重みからTeacherモデルの重みを更新するという手順で学習させる(?)
Studentモデルの出力と正解ラベルのlossに、正則化項としてTeacherモデルとStudentモデルの出力の距離を追加し、全体のlossとしている(?)

# 感想

半教師あり学習の$\Pi$モデルやTemporal Ensemblingといった手法を知らないのでMean Teacherも、いまいちしっくりきていない。Temporal Ensemblingなどの手法を理解する必要がありそう。
(K.S)
さくらVPSに設置したデータベースに外部からアクセスして、さくらのレンタルサーバ ライトプランでWordPressを使う

# やりたいこと
データベースの使えないさくらのレンタルサーバの最安プラン（131円/月）で、外部（別で借りてるさくらVPS、585円/月）のデータベースを使いWordPressを使えるようにする。

# 前提条件

###さくらVPS側
- SentOS7
- Apache/2.4.6
- MariaDB

「ネコでもわかる！さくらのVPS講座」を読みながらたどたどしく構築したWeb環境
https://knowledge.sakura.ad.jp/8218/

###さくらレンタルサーバ ライト（以下、さくらライト）側
- レンタルサーバライトに本登録してFTPで接続できるようにしておく
  
    
# さくらVPS MariaDBでの作業
### ログイン

```
# mysql -u root -p
```
### 外部接続用のユーザーをMariaDBに作成

IPはさくらライトのもの。コントロールパネル＞サーバ情報の表示の、【IPアドレス】の箇所。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/6d8b7cfc-b0f2-671a-015e-44260ed786a0.png)
ここでは仮に下記のようにする。

- ユーザ名　　:　exuser
- 接続元IP　　:　xxx.xxx.xxx.xxx
- パスワード　:　pass

```
CREATE USER 'exuser'@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'pass';
```
### ユーザに権限を付与

```
GRANT ALL ON *.* TO 'exuser'@'xxx.xxx.xxx.xxx';
```

### ユーザが追加されたことを確認

```
SELECT User,Host FROM mysql.user;
```
### DBから抜ける
```
exit
```

##SentOSでの作業
###DB用ポート3306を開放

```
firewall-cmd --zone=public --add-port=3306/tcp --permanent
```

###ファイアウォールのリロード

```
firewall-cmd --reload
```

###追加を確認

```
firewall-cmd --list-ports
```

ここまでが、一度だけ必要な設定。
これ以下はWordPress設置するごとに必要な作業。

#データベースを用意する

WordPress用のデータベースを作成する。下図はphpMyAdminの場合。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/162692db-bea9-bf49-de1b-8661f32a5bdb.png)


#WordPressに関する作業
###WordPressをダウンロード
https://ja.wordpress.org/download/

###WordPressをアップロード

FTPかFTPSでサーバにアクセス、解凍したファイルをそのままアップする。
下図ではwwwの下にドメインごとのフォルダを作成してある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/3517da03-8bb0-1d79-63b6-bc4a38bec6b6.png)

###アップロードしたURLにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/6753fd02-b84d-cc33-17e7-6666d8eb6e62.png)

###データベース情報を記入する

- データベース名　　:　さっき作ったデータベースの名前
- ユーザー名　　:　さっき作った外部接続用に作ったユーザー名
- パスワード　　:　さっき作った外部接続用ユーザーのパスワード
- データベースのホスト名　　:　VPSのIPアドレス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/bea25fc4-e41f-0388-9897-4f50fb08ea84.png)

###【インストール実行】を押して完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223715/f8b6e287-af4b-216c-e326-3a9915c5885b.png)

# つまづいたところ
ライトプランはSFTPが使えないの知らなくて「つながらないー＞＜」を30分くらいやってた。ちゃんと書いてあるので読もう。

- [プラン比較](https://www.sakura.ne.jp/plans.html)

# なぜVPSにまとめなかったのか

- VPSの512MB プランは5ゾーンまでしか使えないのでマルチドメインしてたらゾーンが足りなくなった。追加（+10ゾーン 1,000円/月）や上位プラン4G3,200円/月もあるができるだけ安くどうにかしたかった。

- VPSはJavaの勉強のためだけに借りたので、それ以外は普通のレンタルサーバで十分だしそっちのほうが安い。

- さくらレンタルサーバの一番安いプラン131円/月借りた。ドメイン20個まで使える。メールサーバも自分で管理しなくていい楽だ。しかしデータベースが使えない。

- データベースはVPSに置いたの使えばいいのでは

からの今回の施策。無事 月額585円＋131円でドメインいっぱい設定できるようになってよかった。
台形則による定積分

高校数学で学ぶ台形則による定積分について書きます。
プログラミングは好き・出来るのに数学に苦手意識を持ってしまっている不幸な高校生が一人でも減る事を願っています。

# そもそも定積分とは？

以下より丁寧に説明出来る気がしないので、ベネッセを紹介します。
https://kou.benesse.co.jp/nigate/math/a14m1402.html

積分する事によって面積が求められるんだよというお話。
積分を素直に実現するプログラムを書くのも良いですが、本記事では台形則と呼ばれる方法で定積分を行う方法を紹介します。

# 台形則による定積分の求め方

Wikiに詳しく書かれているので、キャプチャの紹介のみとします。
https://ja.wikipedia.org/wiki/%E5%8F%B0%E5%BD%A2%E5%85%AC%E5%BC%8F

<img width="650" alt="スクリーンショット 2019-11-18 15.21.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/fa56d520-d929-e1df-bcb1-27233d880a16.png">

暗号みたいですが、図形で書くとイメージが出来ます
<img width="194" alt="スクリーンショット 2019-11-18 15.23.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/6de92b3b-3d26-f010-abd5-91d2dcca40a8.png">
出典：https://nekodamashi-math.blog.ss-blog.jp/2016-11-14

被積分関数に対し、等間隔で点を打ち複数の台形を作ります。
その台形の合計値を求める事により定積分を実現しているという訳です。
それでは実際にコードに参りましょう。

# C#による実装

```csharp:Trapezoidal.cs
        public void Trapezoidal(double a, double b)
        {
            var bunkatsuNum = 50;
            var haba = (b - a) / bunkatsuNum;
            var x = a;
            double sum = 0;

            for(int k=1;k<=bunkatsuNum-1;k++)
            {
                x = x + haba;
                sum = sum + targetFunction(x);
            }

            sum = haba * ((targetFunction(a) + targetFunction(b)) / 2 + sum);
            Console.WriteLine(sum);
        }

        private double targetFunction(double x)
        {
            return x * 2 + 2;
        }

```

taegetFunctionの中身を積分したい式にしてくれれば良いです。
今回の例は、要するに
2X + 2であり、積分するとx^2 + 2xになります。

実際に動かして見ると、ちゃんと定積分出来ます。
今後も同様の記事を書き続けるので、頑張って数学嫌いを克服していきましょう!!
【秘密鍵/公開鍵】RSA暗号より強い、Ed25519を用いてSSHキーを作成する

## きっかけ
RSA暗号よりEd25519の方が強いらしいよ。と言われた。
で、使い方も調べたのでメモ。

## エドワーズ曲線デジタル署名アルゴリズムとは
>Ed25519は、ツイストエドワーズ曲線を用いたエドワーズ曲線電子署名アルゴリズムの実装の一つである。
>by Wikipedia

詳しくはこの人の記事が良いかも？
[電子署名EdDSA(ed25519)の数的構造](https://qiita.com/angel_p_57/items/a1dc4e9c0b18a23c5242)

## SSHキー作成
```
$ ssh-keygen -t ed25519 #SSHキー作成
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/[ユーザ名]/.ssh/[SSHキー名]):  #作成される場所と名前。問題なければEnter。
Enter passphrase (empty for no passphrase):  #パスフレーズの入力。
Enter same passphrase again:  #パスフレーズの再入力。
$ ls ~/.ssh #SSHキーが作成されたことを確認
```

## Githubなどに公開鍵を登録する際のコピーが楽になるコマンド

```
$ pbcopy < ~/.ssh/[SSHキー名].pub #公開鍵をクリップボードにコピー
```
## おわりに
「とりあえず」で少しでもセキュアになるならやっておいた方が良さげなのでぜひやってみてください＼(^^)／

Twitterフォローもよろしくです！
 - [@noumi0k](https://twitter.com/noumi0k)
io-tsでJSONの型検査をする

TypeScript内でJSONを使うことは多いが悩みの一つが`JSON.parse()`の戻り値は`any`になって型が不明になることである。

```ts
const x: number =  JSON.parse(json);
```
とすると型はつくにはつくが特に検査するわけではないので

```ts
const x: number =  JSON.parse('"abc"');
const y = x.a * 2 // => NaN になる
```
とやってランタイムで滅茶苦茶になってしまうのは防げない。

io-ts (https://github.com/gcanti/io-ts) を使うとJSONの型検査ができる。しかしこれはTypeScriptで関数型プログラミングをするライブラリのfp-ts(https://github.com/gcanti/fp-ts) をベースにしているのでこちらの知識が必要になる。

ライブラリの中にはnumberやstringの検査するものと組み合わせてobjectを作ったりするものがある。

以下Jestのテストコードでの使用例。

```typescript
import * as t from "io-ts";
import { isRight, map, right } from "fp-ts/lib/Either";
import { pipe } from "fp-ts/lib/pipeable";

describe("JSON.parse()のみ", () => {
  test("stringをobjectと処理するとundefined", () => {
    const x = JSON.parse(`"a"`);
    expect(x.b).toBeUndefined();
  });
  test("存在しない属性はundefined", () => {
    const x = JSON.parse(`{"a":123}`);
    expect(x.b).toBeUndefined();
  });
  test("stringをnumberとして処理するとNaN", () => {
    const x: number = JSON.parse(`"a"`);
    expect(x * 2).toBeNaN();
  });
});

describe("io-tsを使う", () => {
  test("stringはnumberではない", () => {
    const x = t.number.decode(JSON.parse(`"a"`));
    expect(isRight(x)).toBeFalsy();
  });
  test("numberはstringではない", () => {
    const x = t.string.decode(JSON.parse(`123`));
    expect(isRight(x)).toBeFalsy();
  });

  test("オブジェクトの検査", () => {
    const X = t.type({ a: t.number });
    const x = X.decode(JSON.parse(`{"a":123}`));
    expect(x).toStrictEqual(right({ a: 123 }));
  });
  test("オブジェクトのプロパティが一致しない", () => {
    const X = t.type({ x: t.number });
    const x = X.decode(JSON.parse(`{"a":123}`));
    expect(isRight(x)).toBeFalsy();
  });
  test("余分なプロパティがあっても良い", () => {
    const X = t.type({ a: t.number });
    const x = X.decode(JSON.parse(`{"a":123,"b":456}`));
    expect(x).toStrictEqual(right({ a: 123, b: 456 }));
  });
  test("exactを使うと余分なプロパティは消える", () => {
    const X = t.exact(t.type({ a: t.number }));
    const x = X.decode(JSON.parse(`{"a":123,"b":456}`));
    expect(x).toStrictEqual(right({ a: 123 }));
  });
  test("unionの例", () => {
    const X = t.union([
      t.type({ x: t.literal("number"), a: t.number }),
      t.type({ x: t.literal("string"), a: t.string })
    ]);
    type XType = t.TypeOf<typeof X>; // 型情報が取れる
    const num = X.decode(JSON.parse(`{"x": "number", "a":123}`));
    const str = X.decode(JSON.parse(`{"x": "string", "a":"xyz"}`));

    const f = (a: XType) => {
      switch (a.x) {
        case "number":
          return a.a * 2;
        case "string":
          return a.a.length;
      }
    };
    expect(pipe(num, map(f))).toStrictEqual(right(246));
    expect(pipe(str, map(f))).toStrictEqual(right(3));
  });
});

```
JavaScriptで正方行列の行列式を計算する

以下の行列Aがある時、

```math
A = 
\begin{matrix}
a & b & c\\ 
d & e & f\\
g & h & i
\end{matrix}
```

行列式はこう計算出来る。

```math
\begin{vmatrix}
A
\end{vmatrix}
=
\begin{vmatrix}
a & b & c\\ 
d & e & f\\
g & h & i
\end{vmatrix}
=
a\times
\begin{vmatrix}
e & f\\
h & i
\end{vmatrix}
- b\times
\begin{vmatrix}
d & f\\
g & i
\end{vmatrix}
+ c\times
\begin{vmatrix}
d & e\\
g & h
\end{vmatrix}

```

JavaScriptで実装してみるとこうなった。

```javascript
function determinant(m) {
  if(m.length === 0) return 1;
  let x = 0;
  for(let ic = 0; ic < m[0].length; ic++) {
    let ans = m.slice(1).map(row => row.filter((_, index) => index !== ic));
    x += ((-1) ** ic) * m[0][ic] * determinant(ans);
  }
  return x;
};
```

for文をもっと宣言的に書けそう。。。