OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10：git push 時、 『permission denied』 エラーの対処方法

Gitでpushするときpermission denied (403)エラーになってしまうときの解決策を備忘録として残します。

```
remote: Permission to <<ユーザー名>>/<<アプリケーション名>>.git denied to <<古いユーザー名>>.
fatal: unable to access 'https://github.com/<<ユーザー名>>/<<アプリケーション名>>/': The requested URL returned error: 403
```

以下の状況が続いて何をやっても解決しないとき、Windowsがログイン情報(古いユーザー名)を記憶していて、それがずっと使用されているのが原因のようです。

#１．Windowsのタスクバーにある検索窓(虫メガネマーク横①)にて「資格情報マネージャ」を検索、起動する②。
![資格情報マネージャー00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267448/06443d53-6427-ee56-5541-50736f47a931.jpeg)





#２．起動したら「Windows資格情報」タブをアクティブ(水色)にする。（下図を参照）

![資格情報マネージャー0１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267448/a4a476f9-f14f-1aab-8f4d-1193f5204f89.jpeg)



#３．下方向にスクロールし、「git:https&#58;//github.com」の情報（ユーザー名、パスワード）を新しいものに書き換えます。

![資格情報マネージャー02-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267448/e63cd50d-e301-f2b8-7c1a-c98067e88820.jpeg)


#４．その後、コマンドプロンプトを再起動してから Git Push を再度行う。

もしまだエラーが出たりして、うまくいかないようであれば、対象ディレクトリのGitをいったん削除して（そのディレクトリ内の「.git」ディレクトリを削除する）「Git init」コマンドからやり直すなどしてみてください。

※本稿は下記のサイトを参照させていただきました。心より感謝いたします。
　　[Github で push しようとすると 403 (permission denied)エラーになる](https://www.white-space.work/github-403-permission-denied/　"キータ")）
ライブラリレスで0からJavaScriptで手書き数字認識やってみた（MNISTデータ使用）

# 概要

前回は学習用データとテストデータの読み込みを実装しました。
[機械学習メモ - ブラウザ上でMNISTデータファイルをDrag&Dropで受け取って手書き数字をとりあえず表示する - Qiita](https://qiita.com/kob58im/items/80971a854efa92871fa9)

今回はバックプロパゲーションを実装し、実際に学習～認識までを試してみました。（中間層は１個だけ。フィルタ層とかは無し。）
ネットワークの学習の様子を可視化したかったですが、エッジ数が数万個になるので断念しました。。

# データ読み込み後の画面キャプチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/0e396dc3-9aa8-68e2-0254-bc9ac92f8fa8.png)

# CodePen上で動作するもの

対象のデータをDrag&Dropすると、学習用データ60000個中の20000個分を学習します。※十数秒以上はかかると思います。
今回の実装だと精度は実用には耐えれないレベル。実用レベルにもっていくには結構専門知識が要りそう。

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="qBZvYLp" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Neural Network learning step demo using MNIST">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/qBZvYLp">
  Neural Network learning step demo using MNIST</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考サイト

## YouTube

<b><font color="red">音量注意！！</font></b>

- [【深層学習】誤差逆伝播法｜バックプロパゲーション](https://youtu.be/X8hK4ovQoLg)
- [Deep Learning入門：ニューラルネットワーク学習の仕組み](https://youtu.be/r8bbe273vEs)
- さらに専門的な内容 ⇒ [Neural Network Console - YouTube](https://www.youtube.com/channel/UCRTV5p4JsXV3YTdYpTJECRA)

## その他

- [AIプログラマになれる本 - 日経ソフトウェア](https://info.nikkeibp.co.jp/media/NSW/atcl/books/062300004/) / サンプルコード[^1]
- [誤差逆伝播法をはじめからていねいに - Qiita](https://qiita.com/43x2/items/50b55623c890564f1893)
- [機械学習メモ - ブラウザ上でMNISTデータファイルをDrag&Dropで受け取って手書き数字をとりあえず表示する - Qiita](https://qiita.com/kob58im/items/80971a854efa92871fa9)

[^1]: 直リンクを貼るのはよろしくない気がしたので、リンク先から入手してください。今回参考にしたのは`ai_mook_download.zip\1\Part1\DetectApp` の中にあるC#のソースコードです。（移植するのはライセンス的にまずそうだったので、答え合わせ的な使い方をしました。）
ルネサス ARM MCU RE01で低消費ベンチマークULPMark-CPを実施してみた

RE01 256KBで低消費電力ベンチマークであるULPMark-CPを実施してみた。
##この記事で学べること
* REファミリ（ルネサスSOTBプロセス ARM MCU製品）のULPMark-CPの結果が本当に出ることを確認
* 実際のULPMark-CPに使用するツール、実際の測定画面を知ることができます。


※詳しい環境立ち上げ方法はまたの機会に。


#結果
期待どおり<b><font color="DeepPink">最大706（4回施行の平均スコア703）が出ることを確認した。</b></font>電圧：1.8V
※私の環境はノイズ源が多いようでボードを置く位置でスコアがガラリと変わった。PC机に機器が密集しているためと推測。
適度な環境であれば、もっと良いスコアを期待できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/e2adbf59-00e8-230e-5eb8-1df7ac22ee6d.png)

<b>実際の測定結果↓（4回連続で測定をしています）</b>
画面左に出てくる数字が各測定のスコアです。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/c275fbed-1c02-fc0d-b29c-e71f581699e2.gif)

#背景
ルネサスがSOTBプロセスMCUとしてリリースしたREファミリが、<b>EEMBCのULPMark-CPで705スコアを取得</b>したと発表している。
RE01の評価ボードを入手することができたので実際に測定してみる
[リンク：RE01 ULPについて参考](https://www.renesas.com/jp/ja/products/microcontrollers-microprocessors/re.html)


#環境

+ 評価ボード：[ルネサス RE01 256KB評価キット(EK-RE01 256KB)](https://www.renesas.com/jp/ja/products/software-tools/boards-and-kits/eval-kits/ek-re01-256kb.html) (リンク先から購入先へ飛べる）
+ 実行プログラム：[EMBC掲載プログラム](https://www.eembc.org/viewer/?benchmark_seq=13245)
+ 測定装置　[STマイクロX-NUCLEO-LPM01A](https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-utilities/stm32-lpm01-xn.html?dl=OsTn0kfEBSBBBE9QaRF8Gw%3D%3D%2CRxFPu0J3EgeyObyCxmUgigriIgY4KV1EVED5pIaVGCuXpUXysq31JwyRrI6vfmOgnMcptA4mTno63jfXdT9iacbH1p0cZqRIyIwofgQGlQAe6ntgEsdH3Tsv%2Ftch9yL5rgL6o91O0RWPoYZK0Q8iYCA5j6LzWAjoMEwYQtDyzdSrHNA7QDcdg%2FWodyJ3gFkH3S39x2slw%2BaWzynyRsBYeSTVPAON5ttuE7OpNrcWKFznM%2FfRHEHEjeGqcO%2FDV2UkstLFbn0iaU5JD23rBETw7gvwKoqZbl%2BE6o%2BfV6OP25jn26p5L6kWnLsu5VSsuQiLWcnzzqN0lJM4Bq7beZ8chA%3D%3D&uid=nJbdhom4GwuYwdF1f98lujrstOoMumn2MafZ9GaLkIk=)
+ 測定ツール　[STマイクロ STM32CubeMonPwr](https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-performance-and-debuggers/stm32cubemonpwr.html)


#参考文献
1. [ルネサスエレクトロニクス RE01ファミリWEB](https://www.renesas.com/jp/ja/products/microcontrollers-microprocessors/re.html) R7F0E01182CFP
2. [EEMBC ULPMark-CP WEB](https://www.eembc.org/ulpmark/scores.php)
3. [EK-RE01 256KBでLチカする(e² studio編)](https://qiita.com/nizuki926/items/a3fe3e71fb9435e9dd4c) @nizuki926さん記事
4. [REファミリ 環境立ち上げ説明動画](https://academy.renesas.com/?eid=1625) ※以下の画像参照


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/5f0ba730-838e-2c0b-5419-4a376c01daee.png)

#実際の測定ボード写真
![IMG20200930095029.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/14ee311b-73a1-b34e-7139-9e51cff7f111.jpeg)

#ULPMark-CP スコア（2020/09/30時点）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/82a96ad2-2df8-5e82-c666-8103425cc4cc.png)
Amazon linux2上にcrowiをインストールする

crowiについてはこちら
https://site.crowi.wiki/
見やすいWikiが作れます

##node.jsインストール
nodebrewを入れて好きなバージョンに切り替えられるようにする

```
curl -L git.io/nodebrew | perl - setup
vi ~/.bash_profile
export PATH=$HOME/.nodebrew/current/bin:$PATH
source ~/.bash_profile
```
nodeのバージョンを確認し、8.11.1に切り替える
nodeのバージョンが新しすぎるとエラーで落ちるので、nodeのバージョンは8.11.1でいきましょう。

```
nodebrew ls-remote
nodebrew install-binary v8.11.1
nodebrew use 8.11.1
```
すぐにバージョンを確認しても反映されていないことがあるので、ターミナルを再起動

```
node -v
```
v8.11.1が表示されればOK

##MongoDBをインストール
定義ファイルを作成

```
sudo vi /etc/yum.repos.d/mongodb.repo
```
以下の通り記載

```
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
```
完了したらインストール

```
sudo yum --enablerepo=mongodb install -y mongodb-org
```

##MongoDBにデータベースやユーザー追加
MongoDBがインストール出来たらcrowi用のデータベースを追加

```
mongo
use crowidb
switched to db crowidb
```
続いてユーザーを追加
パスワードなどは適当

```
db.createUser({user: "crowi", pwd: "password", roles: [{role: "readWrite", db: "crowidb"}]});
```
作成したら一回MongoDBから抜けて起動

```
sudo yum install -y mongodb-org
sudo service mongod start
```

##Nginxインストール
Amazon linuxが提供しているトピック一覧を確認

```
amazon-linux-extras
```
nginx1などが出てくると思われる。未インストールであればdisabledとなっているはず
Nginxをインストール

```
sudo amazon-linux-extras install nginx1
```
再度確認するとステータスがenabledに変わるはずなので、バージョンも確認

```
nginx -v
```
Nginxを起動

```
sudo systemctl start nginx.service
sudo systemctl status nginx.service
```
このままだとEC2サーバ起動時にNginxが立ち上がらないので自動起動の設定をONにする

```
systemctl is-enabled nginx.service
sudo systemctl enable nginx.service
systemctl is-enabled nginx.service
```

##Nginxの設定ファイルを作成

場所は様々ですが・・・

```
sudo vi /etc/nginx/conf.d/crowi.conf
```
中身に以下記載

```
server {
  listen   *:80;
  server_name crowi.hoge.com;

  access_log /opt/nginx/logs/crowi_access.log;
  error_log  /opt/nginx/logs/crowi_error.log;

  location / {
    proxy_pass http://127.0.0.1:3001;
  }
}
```

##Crowiのインストール
```
git clone --depth 1 https://github.com/crowi/crowi.git
cd crowi
git checkout v1.6.0
sudo npm install
```

これでlocalhostにアクセスするとcrowiが表示されるはず

##プロセスの常時起動設定
環境変数の設定
3001ポートで動かしたい

```
export PASSWORD_SEED=なんでもOK
export MONGO_URI=mongodb://crowi:パスワード@localhost/crowidb
export PORT=3001
export NODE_ENV=production
```
終わったらforeverのインストール

```
npm install forever -g
```
プロセス起動

```
forever start app.js
forever list
```

これでlocalhostにアクセスすると、crowiの設定画面が見られるようになるはずです。
あとは管理者ユーザーを登録してcrowiライフスタートです。
basicなどはcrowiの設定画面から設定が出来るのでかんたんです。

##何らかの理由で落としてしまったときにやらないといけないっぽいこと
nginxの再起動と環境変数の再設定〜

```
systemctl restart nginx

export PASSWORD_SEED=なんでもOK
export MONGO_URI=mongodb://crowi:パスワード@localhost/crowidb
export PORT=3001
export NODE_ENV=production

forever start app.js
```

###参考（ありがとうございます）
https://qiita.com/zwirky/items/83cd83e4094e502092d2
https://qiita.com/Hwoa/items/a01f2c6325b0f719905a
[UE4]シーケンサーから映像を出力する方法

#はじめに
hortorum所属クリエイターの北原隼大です。

「物語を伝えるアニメ」が作りたくて、UE4やVroid studioを中心に3DCGゲームを開発中です。


#シーケンサーから映像を出力する方法
今回紹介するのは、「UE4でシーケンサーから映像を出力する方法」についてです。
![AnyConv.com__ThirdPersonExampleMap_(3) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/0a193e11-8277-0887-9ecc-bdca6a2021e4.gif)
これについて詳しい説明の載った公式ドキュメントがありますが、それを参考に検証したところ躓いた箇所があったので、公式ドキュメントに加えてどういった操作をしたのか（+自分がどの操作を間違えたか）、紹介したいと思います。

（参考記事）
シネマティック ムービーの出力 | Unreal Engine ドキュメント
https://docs.unrealengine.com/ja/Engine/Sequencer/Workflow/RenderAndExport/RenderMovies/index.html
【UnrealEngine4】を映像制作で使うためのTips
https://dftalk.jp/?p=21578

(検証環境)
4.25.3

#操作の流れ

まずは

- Add Level Sequence (レベル シーケンスを追加)
- Cine Camera Actorの設置
- シーケンサーでキーフレームを打ち、カメラを動かす

ここまで終えた状態です。公式ドキュメントでいうところの、手順1~5にあたります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/087b72d9-8002-2424-a432-62aa9992fdeb.png" width=100%>
__Cine Camera Actorの設置は、公式ドキュメントとは違い、「アクタを設置」を使って行いました。__
![qu_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/47515ff4-60da-217b-9fc8-c3bdfa11cfb8.png)
出力する予定の映像の内容は、「キャラクターにピントを合わせつつ右から左へカメラをスライドする」です。

そして、シーケンサー 内で、[Render Movie (動画を出力)] ボタンをクリックして動画を出力しようとしますが……。
![AnyConv.com__ThirdPersonExampleMap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/07719eb0-d5c8-bd70-6ec8-aeebd5cb24f7.gif)
出力された映像がこちらです。「キャラクターにピントを合わせつつ右から左へカメラをスライドする」映像は出力されませんでした。
出力した映像はおそらく、設置されているThirdPersonの視点でしょう。

これを解決するために、Camera Cutsを使います。
#Camera Cuts
試行錯誤した結果、Camera Cutsで出力したいカメラをメインに設定することで、撮影したいカメラで映像を出力できることが分かりました。
![qu_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/1610f043-8f73-3dd4-4924-ed4523ea0a94.jpeg)
①シーケンサーから↑画像で選択してある「新しいカメラ…」をクリック。Camera Cutsを呼び出します。
![qu_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/92f9bd88-503e-c813-abed-5594798e11df.png)
②そして「+」ボタンから、出力したい映像を撮ったカメラを選択。
![qu_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/6fb3cae9-3b58-fd72-1feb-6a950ba87696.png)
③出力する前に、範囲分の尺をCamera Cutsで指定しているか確認してください。

ちなみに、公式ドキュメントの通りに設定すると、Camera Cutsを生成したうえで、設置したカメラをメインに登録した状態で始められます。
僕が操作を間違えたのは、
>__Cine Camera Actorの設置は、公式ドキュメントとは違い、「アクタを設置」を使って行いました。__

この部分です。
同時に複数のサイトを見ていたので作業時に気付きませんでしたが、公式ドキュメントにおける手順３を「アクタを設置」によって代用していたので、Camera Cutsを生成せずに手順５まで進んでいました。Camera Cutsがシーケンサーに置いていない時、代わりに設置されているThirdPersonの視点が出力されるようです。
#プレイヤーの表示
しかし、撮影対象がプレイヤーだった場合、Camera Cutsを使ってもキャラクターが表示されません。
![AnyConv.com__ThirdPersonExampleMap_(4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/6276c6fa-e736-6ffb-dea5-fff7ef51e95c.gif)
その時は、
![qu_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/74886993-4ec2-16c7-d315-dcdc4339ac77.png)
ここにチェックを入れてください。すると、エディター画面で見えていた映像通りに出力されます。
![AnyConv.com__ThirdPersonExampleMap_(3) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746110/3a199fa3-b129-c9ef-721a-2be77a9e5c16.gif)
これで完成です。
非同期処理async,awaitについて

# 非同期処理について
JavaScriptでは非同期処理を行う選択肢は主に3種類あります。
「Promise」「async,await」「Observable」です。
ここではasync,awaitについて記載します。

## async,awaitの特徴
async,awaitはPromiseの派生です。
Promiseを簡略化して記載することができます。
また、非同期処理を直列で実行したい場合に入れ子にならない利点があります。
Promiseとasync,awaitは混同して利用することができます。

## 構文
Promiseで記載した非同期処理をasync,awaitに書き換えます。

***Promise***

```
method() {
  asyncFunction(parameter).then(closureOfSucceedCase).catch(closureOfFailureCase);
}
```

***async, await***

```
async method() {
  try {
    const response = await asyncFunction(parameter);
  } catch (error) {
    // 異常系処理
  }
}
```

PromiseをreturnするasyncFunctionの前にawaitをつけて呼び出すことで、
同期呼び出しのように呼び出すことができます。
responseにはPromiseでthen()で渡されるパラメータがセットされます。
catchケースは、Promiseでcatch()が呼ばれる時に動きます。
また、***awaitを利用する処理を書いている関数には必ずasyncを書かなければなりません。
asyncが付いた関数を呼ぶ関数にもasyncをつけなければなりません。***

## 動作する順序
下記の順で処理が動きます。
awaitは非同期処理が完了するまで次の行に移りません。

```
async method() {
  // ①
  try {
    // ②
    const response = await asyncFunction(parameter);
    // ③ (非同期成功時)
  } catch (error) {
    // 異常系処理
    // ③ (非同期失敗時)
  }
  // ④
}
```

## メリット
下記のように非同期処理を連続して実行したい場合に、Promiseのような入れ子にはならず
見易くなる点がメリットです。

```
const response1 = await asyncFunction1(parameter);
const response2 = await asyncFunction2(parameter);
const response3 = await asyncFunction3(parameter);
```
Scala × AWS X-Ray × AWS CDKでサービス間を可視化してみる

## はじめに
AWSの勉強をしていて、X-Rayって名前だけ聞いて何に使えるかなんとなく雰囲気では知ってるけど
使ったことないなとおもったので、どういう風に各サービスの実行時間が見えるのか試してみた記事です。


## 実行環境
・scala: 2.13.3
・sbt: 1.3.13
・aws-cdk: 1.57.0

はこんな感じでサンプルコードは以下になります。
https://github.com/hiroyuki-nishi/xray

## AWS構成図

 ![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/6bedb046-699a-bb3f-20f3-603dba2d3815.png)

とりあえず最小限のAWS構成で試してみます

### CDKの設定ポイント

LambdaのX-Rayをアクティブにするだけなら `tracing(Tracing.ACTIVE)`を追加してあげるだけで
設定できます。
より詳しい解説[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-xray.html)を参照してください

```.scala

  private val function = new Function(
    this,
    "account-test",
    FunctionProps
      .builder()
      .functionName(s"notify-days-shift-test")
      .code(
        Code.fromAsset(
          s"${presentationPath}/notifydaysshift/target/scala-2.13/notifyDaysShift.jar"
        )
      )
      .runtime(Runtime.JAVA_8)
      .handler("shiftdays.App::handleRequest")
      .timeout(Duration.seconds(180))
      .memorySize(1024)
      .environment(Map("REGION" -> "ap-northeast-1").asJava)
      .tracing(Tracing.ACTIVE) // ココ
      .build()
  )

```

## X-Rayの結果

トレースはこのような感じで結果が残ります。

![スクリーンショット 2020-09-27 18.58.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/632c9cdf-0f6c-aa71-a5af-242d7ca52f8a.png)


**コールドスタート時**
GraalVMとか何もしてないので流石に立ち上がりが遅い・・・
GetQueueURLの取得？も思った以上に時間がかかっているのがわかります。


![cold.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/743f052a-a8d2-e453-041f-2e398bb0994d.png)


**ウォームスタート時**
先ほどと比べて速いですね！
![warn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/5781c53d-e17e-5e2c-ed6a-0868a8411811.png)

## おわりに
Lambdaの設定一つでX-Rayを使えるようになるのはいいですね。
あとは、コスト面やKinesisを使ったEventSourcingなどどこまでトレースされるのかは色々試してみたいところです。
JSで関数の処理から本質的でない処理を分離するProxyパターン

どのような言語であり汎用的な関数の設計は
SOLID原則の単一責任の原則に基づいたほうがいいと思っています。

ただ、ビジネスロジックが入り込むと特定の処理に対し、ログやメール送信するなど
いわゆる付随する組み合わせ(Compound)な処理になっていきます。
すると、本質的な処理から付随した処理を分離しづらくなっていきます。

このようなオブジェクト指向ではうまく分離できない特徴（クラス間を横断 (cross-cutting) するような機能）をアスペクトと呼びます。

JavaScriptでは関数に対してProxyを使うことで体系的に本質でない処理を関数から分離することが出来ます。

参考：[handler.apply()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply)

```js

// 単体テストするのはこっち（本質的な処理）
function sum(a, b) {
  return a + b
}

const handler = {
  // ロギング、メール送信などの処理を分離する
  apply: function(target, thisArg, argumentsList) {

    // 実行前にログを残す
    console.log(`args: ${argumentsList}`)

    // 引数をそのまま渡す
    const result = target(...argumentsList)

    // 結果のログや付随するメール送信などの処理など
    console.log(`result: ${result}`)

    return result
  }
}

const wrapSum = new Proxy(sum, handler)
wrapSum(1, 2)
```


次のように書いても同じやんと言われたらそうなんですけど、
Proxyのほうが体系的に書けるのがいいのかなと思います。


```js

// 単体テストするのはこっち（本質的な処理）
function sum(a, b) {
  return a + b
}

function wrapSum(target, ...argumentsList) {

  // 実行前にログを残す
  console.log(`args: ${argumentsList}`)

  // 引数をそのまま渡す
  const result = target(...argumentsList)

  // 結果のログや付随するメール送信などの処理など
  console.log(`result: ${result}`)

  return result
}

wrapSum(sum, 1, 2)
```
Ubuntu上でnodenvをインストール、任意のバージョンを有効化

# 前提

Ubuntu Server (今回のバージョンは`22.04`）を標準で（minimalではない）インストールした環境

# 事前に必要なパッケージをインストール

```bash
sudo apt install build-essential
```

# nodenvを取得

参考 : [https://github.com/nodenv/nodenv#basic-github-checkout](https://github.com/nodenv/nodenv#basic-github-checkout)

```sh
git clone https://github.com/nodenv/nodenv.git ~/.nodenv
cd ~/.nodenv && src/configure && make -C src
```

# 環境変数を設定

上記サイトで

```txt
2.Add ~/.nodenv/bin to your $PATH for access to the nodenv command-line utility.
  ・・・
  For Ubuntu Desktop and Windows Subsystem for Linux (WSL):
    $ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bashrc
```

と説明されているので、

```sh
/bin/cp -a ~/.bashrc ~/.bashrc.`date '+%Y%m%d-%H%M%S'`.bk
echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bashrc
```

として、`.bashrc`のファイル上で、`PATH`に追記します。
※インストールする先の環境に応じて、上記サイトの説明に従って設定しましょう。

```sh
~/.nodenv/bin/nodenv init
```

を実行すると、

```txt
# Load nodenv automatically by appending
# the following to ~/.bash_profile:

eval "$(nodenv init -)"
```

のように表示されるので、`eval "$(nodenv init -)"`を`.bashrc`の末尾（先程のPATHの設定の次）に追記します。
※こちらもインストールする先の環境に応じて、設定するファイルを決めましょう。

# SSHでログインし直す

SSHで一度ログアウトし、ログインし直します。
※~/.bashrcの変更を反映するため

# プラグインをインストール

```sh
mkdir -p "$(nodenv root)"/plugins
git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build
git clone https://github.com/nodenv/nodenv-update.git "$(nodenv root)"/plugins/nodenv-update
```

# nodeの環境を作成、有効化

```sh
nodenv install --list
```

を実行すると、インストール可能なバージョンの一覧が表示されます。
数字から始まるバージョンにだけ絞る場合は、grepを使って以下のように絞ります。

```sh
nodenv install --list | grep -E "^ *[0-9]+.+$"
```

```txt
・
・
・
18.7.0
18.8.0
18.9.0
```

ここでは、最新のバージョンをインストール
※2022.09.13時点では、`18.9.0`

```sh
nodenv install 18.9.0
```

```sh
nodenv versions
```

を実行し、インストールされたバージョンが表示されることを確認します。

先程インストールしたバージョンを有効にします。

```sh
nodenv shell 18.9.0
```

特に何か表示されるわけではないので、

```sh
node -v
```

を実行し、先程有効化したバージョンが正しく表示されることを確認します。

```txt
v18.9.0
```

# システムごとに独立した環境を作成

nodenvでは、pyenv-virtualenvやvenvのように、ひとつのバージョンをもとにして__仮想環境を複数作成する機能はない__ようです。
しかし、Node.jsでは、ローカルのモジュールをインストールすることができるので、__システムのディレクトリ内でローカルモジュールとしてインストール__することで、仮想環境はなくとも、システムごとに独立した環境として使うことができそうです。
Raspberry Pi - Firefoxでヘッドレスとプロファイルを使ってPythonでスクレイピングする

# 目標
Firefoxでヘッドレスとプロファイルを使ってPythonでスクレイピングする。
ちなみにRaspberry Pi zeroではチップがARM6なのでこのやり方では動作しない。

## 環境
Raspberry Pi 3 model B+
OS: Raspberry Pi OS
Python3.7

# Chromeではダメなわけ
Chromeではヘッドレスモードでのユーザープロファイルが使えなかった。



## seleniumのインストール
```bash
$ pip3 install selenium
```

## Firefox ESRのインストール
Raspberry Pi OSで動作するものはiceweaselとFirefox ESRがあるが、iceweaselは動作が不安定だったので急遽、Firefox ESRを採用。

```bash
$ sudo apt install firefox-esr
```

## geckodriverのインストール
```bash
# ARM7のバイナリをダウンロード
$ wget https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-arm7hf.tar.gz
$ tar -zxvf geckodriver-v0.23.0-arm7hf.tar.gz
$ sudo mv geckodriver /usr/local/bin
```
**GitHub:** [mozilla / geckodriver v0.23.0](https://github.com/mozilla/geckodriver/releases/tag/v0.23.0)

## ユーザープロファイルを使う
- firefox-esrを使うのでディスプレイのあるパソコンでFirefox ESRをインストールする。  
https://www.mozilla.org/en-US/firefox/78.3.0/releasenotes/

- Firefox ESRで**Googleにログイン**したり**Twitterにログイン**したりいろいろやった後...

- セッション情報はFirefox ESRのプロファイルのcookies.sqliteとplaces.sqliteにあるのでとってくる。 
プロファイルの場所 
```C:\Users\user\AppData\Roaming\Mozilla\Firefox\ ********.default-esr```
![ScreenShot_20200927182722.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197942/18509e93-26f0-ad2c-07f4-df71b75bd673.png)


- 取ってきたファイルをRaspberry Piに転送してcookies.sqliteとplaces.sqliteを分かりやすくフォルダにまとめる。（フォルダ名は任意）

```bash
pi@raspberrypi:~ $ cd myProfile
pi@raspberrypi:~/myProfile $ ls
cookies.sqlite  places.sqlite
```

## 動作確認
```python
from selenium import webdriver
from bs4 import BeautifulSoup
from time import sleep

Options = webdriver.FirefoxOptions()
# ヘッドレス
Options.headless = True
# 必須
Options.add_argument('--no-sandbox')
Options.add_argument('--disable-gpu')
# エラーの許容
Options.add_argument('--ignore-certificate-errors')
Options.add_argument('--allow-running-insecure-content')
Options.add_argument('--disable-web-security')
# headlessでは不要そうな機能
Options.add_argument('--disable-desktop-notifications')
Options.add_argument("--disable-extensions")
# UA設定（なくてもいい）
Options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0')
# 言語
Options.add_argument('--lang=ja')
# ユーザープロファイル
Options.profile = "myProfile"

driver = webdriver.Firefox(options=Options)
driver.get("http://www.example.com/")
print(str(driver.page_source))
print("successfully!")
```
エラーが出た場合はgeckodriver.logに詳細が記録される。

## 結論
もっと簡単なやり方があると思うのだが、個人的には意外に大掛かりだった。
軽いサイトならヘッドレスでスクレイピングすることが出来たが、10MB以上あるサイトはRaspberry Piでは重すぎて処理の途中でタイムアウトになってしまった・・・
Raspberry Piでのスクレイピングは安定性がないので遊びで使う程度なら十分だ。

## リファレンス
https://vaaaaaanquish.hatenablog.com/entry/2017/06/06/194546
「robocopy」コマンドでファイルコピー速度を上げる方法いろいろ 

## はじめに
robocopyコマンドで大量のファイルコピーを行う際に、コピー速度を上げる幾つかの方法について記載します
robocopyのバージョンによっては、該当オプションが無い場合もありますので、ご注意ください。
また、環境によっては一概に速度が向上するとは限りませんので、あくまで私の環境にて効果が有ったという点にご留意下さい。
(Windows Server 2012 R2で動作確認しています)

## コピー環境の整備
ファイルコピーを行うにあたり、コピー元とコピー先のネットワーク的な距離が近い方が良いです。
具体的には、同じネットワークセグメントにする等です。
(出来ればL2スイッチで完結するように)
また、Gigabit Ethernet以上の利用が望ましいです。

## コピー速度の向上に有効なオプション
①「再試行オプション」の指定
　　コピー失敗時デフォルトの再試行数は、待機時間30秒で100万回です。
　　これでは、いつまで経っても終わらないのでリトライ回数と待機時間を指定します。

```text
　/R:n :: 失敗したコピーに対する再試行数: 既定値は 1,000,000。
　/W:n :: 再試行と再試行の間の待機時間: 既定値は、30 秒です。
```

```text
オプション指定値例
　/R:1 /W:1
```

②「マルチスレッドコピー」の指定
　CPUコア数が多数ある場合は、この値を調整するとコピー速度が向上します。
　マシン環境により最適値は異なるため、値を調整して最適な値を探します。

```text
　/MT[:n] :: n 個のスレッドのマルチスレッド コピーを実行します (既定値 8)。
　　　　　　　n は 1 から 128 までの値である必要があります。
```

```text
オプション指定値例
　/MT:64
```

③「ログオプション」の指定
　通常ログは、コマンドコンソール画面に出力されますが、ログファイルとして出力するとコピー速度が向上します。


```text
　/LOG:ファイル :: ログ ファイルに状態を出力します (既存のログを上書きします)。
```

```text
オプション指定値例
　/LOG:C:\work\test.log
```

④「進行状況」の非表示指定
　ログが見づらくなるので、コピーの完了率の表示を出さないようにします。

```text
　/NP :: 進行状況なし - コピーの完了率を表示しません。
```

```text
オプション指定値例
　/NP
```

## 最後に
個人的に一番効果が有ったのは、ログをファイル書き出すということでした。
コマンドコンソール画面に表示させていた時と比べて、コピー速度の向上が実感できました。
Tera Termで、コピー時のログを画面に表示させないようにすると、コピー速度が向上しますが、これと同じ理屈なのでしょうか・・・
(画面表示に時間を取られている?)
AOJ 2286 Farey Sequence

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2286
##見た感じ
$F_n$と$F_{n-1}$の間で増えた、n以下かつ1以上の数でnと互いに素な奴の個数(これをオイラーのΦ関数とよぶらしい)を求めておけば、あとはそれの累積和をとって終わりになると思った。
あとはΦ関数をいかに求めておくかで、
これは

```math
n=\Pi_{i=1}^{m(n)}p_i^{a_i}
\\ \phi(n)=n*\Pi \left( 1 - \frac{1}{p_i} \right) 
```
で計算できるので、エラトステネスの篩みたく素数pを発見するたびに、その倍数たちに$1-1/p$をかけてあげていけばうまくいく。
##解法
前計算をO(n\log n)でやって、O(1)で答えを出力していく
##ソースコード
```c++
const int N_MAX=1000005;
vll dp,test;

void Main(){
    int x=0,y=INF10,z=1;
    //入力
    cin>>x;
    rep(i,x){
        cin>>y;
        test.pb(y);
    }
    //処理
    dp.resize(N_MAX,0);
    rep1(i,N_MAX)dp[i]=i;
    rep2(i,2,N_MAX){
        if(dp[i]!=i)continue;
        for(ll j=i;j<N_MAX;j+=i){
            dp[j]=dp[j]/i*(i-1);//かけていく
        }
    }
    rep2(i,2,N_MAX){
        dp[i]+=dp[i-1];//和をとる
    }
    //出
    arep(s,test){
        cout << dp[s]+1 <<endl;//0/1を入れてないので足す
    }
}

int main(){
    cin.tie(nullptr);
    cout<<fixed<<setprecision(12);
    Main();
}
```
非同期処理Promiseについて

# 非同期処理について
JavaScriptでは非同期処理を行う選択肢は主に3種類あります。
「Promise」「async〜await」「Observable」です。
ここではPromiseについて記載します。

## Promiseの特徴
非同期処理の完了を待ち合わせ、成功した場合、失敗した場合の処理を登録することができます。
また、複数の非同期処理を纏めて実行し、全ての完了を待ち合わせることもできます。

## 構文
### 利用側

#### 一つの非同期処理を実行する

```
asyncFunction(parameter).then(closureOfSucceedCase).catch(closureOfFailureCase);
```

closureOfSucceedCaseには非同期処理が成功した時の処理を登録し、
closureOfFailureCaseには失敗したときの処理を登録することができます。

```
(非同期実行結果から受け取るパラメータ) => { 非同期が完了したときの処理 }
```

例) REST APIを呼ぶときのサンプルコード

```
// ①
const url = 'http://127.0.0.1:4300/newsfeeds';
// ②
this.httpClient.get(url).toPromise().then(response => {
  // ⑤ (成功時のみ)
  const newsfeeds = new Newsfeeds();
  newsfeeds.decode(response);
  resolve(new Response(newsfeeds));
  // ⑥ (成功時のみ)
}).catch(error => {
  // ⑤ (失敗時のみ)
  console.error(error);
  reject(error);
  // ⑥ (失敗時のみ)
});
// ③
console.log('非同期が終わる前に動く');
// ④
```
コード内に数字を埋め込みましたが、処理は数字の順に動きます。
⑤⑥は非同期処理が完了したときに呼ばれますので、③や④より後に動作します。
⑤⑥はサーバからレスポンスが返ってきたときに動作します。

#### 複数の非同期処理の完了を待ち合わせる
下記のように記載します。

```
const promises = [];
promises.push(new Promise((resolve, reject) => {
  // 非同期処理を実行する
  // 非同期処理が成功したらresolve()を呼ぶ
  // 非同期処理が失敗したらreject()を呼ぶ
});
// ↑promisesに必要な分非同期処理を追加する

Promise.all(promises).then(closureOfSucceedCase).catch(closureOfFailureCase);
```

closureOfSucceedCaseはpromisesに登録した非同期処理が全て成功した場合に呼び出され、
closureOfFailureCaseはpromisesに登録した非同期処理が一つでも失敗した場合に呼び出されます。

### 提供側
Promiseを提供する処理は下記のように記載します。

```
asyncFunction(parameter): Promise<型> {
  return new Promise((resolve, reject) => {
    // 何か処理をする
    if (xx) {
      // 成功した場合はresolve()を呼ぶ
      // すると呼び出し元でthen()に設定したクロージャが動き出す
      // 引数にはthen()のクロージャに渡すパラメータを入れる
      resolve(data);
    } else {
      // 失敗した場合はreject()を呼ぶ
      // すると呼び出し元でcatch()に設定したクロージャが動き出す
      // 引数にはcatch()でクロージャに渡すパラメータを入れる
      reject(error);
    }
  });
}
```
主要4社のクラウド音声認識精度の比較

# Amazon, Google, IBM, Microsoftの音声認識精度を比較してみました
- 今回使用した音声データは私の研究に関するミーティング(大学院でのゼミ)をAirPodsで録音したものを使用しています．ミーティングの参加者は3~5人です．音声には個人情報も含まれるため公開することはできませんのでご了承ください．
    - データ量:300発言(約27分)
    - 音声の質は生活音やノイズがかなり含まれています．音声の質としては良くないです(CSJなどの音声認識用コーパスに比べて)
- Googleなどの音声認識精度は論文に掲載されているようにかなり良い精度(日本語でもWER一桁)です．
    - 研究用の質の良い音声を使用しているので精度がかなり良い
    - ***日常生活での音声に対してはどの程度の認識精度なのかはあまり報告されていない***
- 今回は***日常生活の中の音声をどれだけの精度で認識できるのか***を調べてみました．加えて，研究に関する音声なので専門用語も多く含まれます．どれだけ専門用語に対応しているのかも気になるところです．
- [Amazon, Google, IBM, Microsoftの音声認識サービスを使用](https://qiita.com/kamikennn/items/e88ecaf6b76a71cfd1e6)という記事に書くAPIの使い方をまとめてあるのでよかったら参考にしてください．

## 認識精度比較
- Amazon, Google, IBM, Microsoftに加えて，Kaldi(CSJ,JNS,S-JNAS,CEJCで学習)での認識精度も載せておきます．

```
        GCP
        WER: 0.3344722854973424
        CER: 0.2765527007889945

        AWS
        WER: 0.36209150326797385
        CER: 0.2218905472636816

        Azure
        WER: 0.28109824430332464
        CER: 0.21596337579617833

        Watson
        WER: 0.4107744107744108
        CER: 0.29126794258373206

        Kaldi
        WER: 0.616504854368932
        CER: 0.47915630285543725
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391974/cbe98175-f5e2-df4d-bb6d-248094f9487e.png" width=75%>

- 結果からMicrosoftが最も高精度であることがわかりました．Googleが一番良いと思っていたのですが違いました．WERを見ると一番良いMicrosoftでも28%程度であることがわかります．音声の質が良ければWER1桁まで良くなりますが，日常生活の音声ように生活音やノイズの多い環境ではここまで精度が落ちてしまうことがわかりました．しかし，Kaldiは悲惨であることから，GoogleやMicrosoftなどの音声認識器はある程度のノイズに対応できていると思います．

- 一応認識結果の一つを載せておきます

```
正解文: 近 さ っていう の を 計算 できる ので これ を 使い まし た で 打撃 音 を それぞれ マテリアル ごと に えと 距離行列 に し て さっき の こういう 感じ で 濃度 で 表す っていう の を やり まし た で この 二次元 の マップ に 置き換える っていう の も 一応 やっ て み た ん です けど なんか やる こと に すごい

Google: 近 さ っていう の は 計算 できる ので これ を 使い まし た でも 打撃 音 を それぞれ マテリアル ごと に 距離行列 に し て さっき の こういう 感じ に なり まし た この 2次元 の マップ に 置き換える っていう の も 一応 やっ て み た ん です けど なんか やる こと に すごい

Amazon: 近 さ って いう の を 計算 できる ので これ を 使い まし た で で も 打撃 音 を それぞれ マテリアル ごと に と 距離 行列 に し て さっき の こういう 感じ で ノード で 表わす って いう の が あり ます で この 人間 の マップ に 置き換える って いう の も 一応 やっ ! て み た ん です けど 何 か やる こと に 凄い

Microsoft: 近 さ っていう の を 計算 できる ので これ を 使い まし た ね でも 打撃 音 を それぞれ マテリアル ごと に と 距離行列 に し て さっき の こういう 感じ で 飲ん で 表す っていう の が あり まし た で この 2次元 の マップ に 置き換える っていう の も 1 応 やっ て み た ん です けど なんか やる こと に すごい

IBM:司 って いう の を 計算 できる ので これ を 使い まし た で でも 打撃 音 を それぞれ マテリアル 毎 に 時計 に 行列 に し て さっき の こういう 感じ な の で 表す って 言え ない です ここ の 人間 の マップ に 置き換える って いう の も 一応 やっ て み た ん です けど 何 か やる こと に 凄い

Kaldi: 近 さ っていう の 5 日 計算 できる の で は これ を 使う まし た て ない ので 打撃 音 を それぞれ マテリアル ごと に 除去 林業 率 に対して 7 さっき の 声 感じ 子 ノード で 表す ッティ 名前 話し 下 4 9 2 次元 の の 特に 置き換える っていう の を 一 度 やっ 受け身 た ん です けど 何 か やる こと に 都合 よい
```
iOSブラウザでinputのdatetypeで有効な値を入力してくださいとエラーが出た

# 概要

下記の条件で"有効な値を入力してください"とエラーが出たのでその対象法

- iOS
- chromeブラウザ
- inputのtype="date"
- rails

# 対処法

なぜかはわからないけどvalueに元から値を入れると解決した

## dateの取得

```ruby
value="<%= Date.today.strftime("%Y-%m-%d")
```

で今日の日付を"%Y-%m-%d"の形式にして入れた
[Laravel] プロジェクト開始までのコマンド忘備録

## 概要

Laravel プロジェクトを開始するまでのコマンドをまとめた個人メモ。

## 前提条件

* MacOS
* Composer, Laravel インストールされている
    * https://readouble.com/laravel/6.x/ja/installation.html
* Docker がインストールされている
    * https://docs.docker.com/get-docker/

## プロジェクトの開始

Version6系を使用し、`tasklist`というプロジェクト名で作成する

```
$ composer create-project --prefer-dist laravel/laravel tasklist ^6.0
```

## DB作成

Dockerを使用し、`mysql` コンテナを立ち上げる。

```
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
4ded8e15debd        mysql               "docker-entrypoint.s…"   6 days ago          Up 6 days           0.0.0.0:3306->3306/tcp, 33060/tcp   mysql
```

プロセスで表示された`CONTAINER ID`を使用し、コンテナに接続後DBの作成を行う
mysqlのパスワードは`MYSQL_ROOT_PASSWORD`引数で指定した値。

```
$ docker exec -it 4ded8e15debd86c73e637b0c612bf30f0cd9de0aec04b4c09a0f53a6fa16f35d bash
root@4ded8e15debd:/# mysql -u root -p -h 127.0.0.1
Enter password: mysql
mysql> CREATE DATABASE tasklist;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tasklist           |
+--------------------+
5 rows in set (0.03 sec)
```

## DB 接続情報の定義

プロジェクト配下の `.env` ファイルで接続情報を定義する。
接続情報は個々の環境に合わせて変更すること。

```
$ cd tasklist 
$ vim .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tasklist
DB_USERNAME=root
DB_PASSWORD=mysql
```

## DB接続の確認

Webアプリが正常にDB接続できているか確認を行う。
以下のように表示されている場合接続できている。

```
$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.10 — cli) by Justin Hileman
>>> DB::reconnect();
=> Illuminate\Database\MySqlConnection {#3233}
```

## タイムゾーンの変更

デフォルトではUTCのため、`Asia/Tokyo`に変更する。

```
$ vim config/app.php

'timezone' => 'Asia/Tokyo',
```

## アプリの起動

内部サーバを起動させる。
デフォルトで用意されている `welcome.blade.php` のviewが表示される

```
$ php artisan serve --host=127.0.0.1 --port=8080 
```

## 備考

コンテナを停止する際は以下コマンドを実行すること。

```
$ docker stop { CONTAINER ID }
```
CodeWarでの勉強（ruby）③　squeeze, gsub

##この記事について
最近始めたCodewarを通じて学べたことを少しずつアウトプット


##問題
>Implement the function unique_in_order which takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements.


関数unique_in_orderを使って引数としてシーケンス？を受け取り、同じ値が隣接してなくて、要素の順番にしてリストを返すようにさせる。

```ruby
unique_in_order('AAAABBBCCDAABBB') == ['A', 'B', 'C', 'D', 'A', 'B']
unique_in_order('ABBCcAD')         == ['A', 'B', 'C', 'c', 'A', 'D']
unique_in_order([1,2,2,3,3])       == [1,2,3]
```


##僕が考えた方法
①繰り返して使われている値を消そうと思って、受け取った引数を配列に直してから`uniq`にしようと思ったけど、以下のようになるから失敗。

```ruby

def unique_in_order(iterable)
  iterable.chars.uniq
end

unique_in_order('AAAABBBCCDAABBB')
=>["A", "B", "C", "D"]

```


②連続した値を一纏めにできないかと思って検索すると、`squeezeメソッド`を知った。
https://docs.ruby-lang.org/ja/latest/method/String/i/squeeze.html
>squeeze(*chars) -> String[permalink][rdoc][edit]
chars に含まれる文字が複数並んでいたら 1 文字にまとめます。

```ruby
def unique_in_order(iterable)
  iterable.squeeze.chars
end

unique_in_order('AAAABBBCCDAABBB')
=>["A", "B", "C", "D", "A", "B"]
```


できたぜ！！！！

##しかしまだ終わらない
提出すると以下のように3つのことで怒られた❤️

```ruby
① <NoMethodError: undefined method `squeeze' for []:Array>
② <NoMethodError: undefined method `squeeze' for [1, 2, 3, 3]:Array>
③ <NoMethodError: undefined method `squeeze' for ["a", "b", "b"]:Array>
```

全てに共通しているのは配列に対して`suqueeze`は使えないということだ。


###つまり
引数が文字列の場合に`iterable.squeeze.chars`を実行して、配列の場合は`iterable.uniq`をやってやったらいいんじゃないのか？

##成功したぜ！！！

```ruby
def unique_in_order(iterable)
  if iterable.class == String
    iterable.squeeze.chars
  else
    iterable.uniq
  end
end
```


##理想の回答

```ruby
def unique_in_order(iterable)
  case iterable
    when String
      iterable.gsub(/(.)\1*/, '\1').split('')
    when Array
      iterable.uniq
  end
end
```
あ、ちょ待って。分からへん(笑)

###gsubメソッド

>gsub(pattern, replace) -> String
文字列中で pattern にマッチする部分全てを文字列 replace で置き換えた文字列を生成して返します。

```ruby
#正規表現を使わない場合
#文字列.gsub(置換したい文字列, 置換後の文字列)

#正規表現を使う場合
#文字列.gsub(/正規表現/, 正規表現に該当した箇所を置換した後の文字列)

p 'abcdefg'.gsub(/def/, '!!')          # => "abc!!g"
p 'abcabc'.gsub(/b/, '<<\&>>')         # => "a<<b>>ca<<b>>c"
p 'xxbbxbb'.gsub(/x+(b+)/, 'X<<\1>>')  # => "X<<bb>>X<<bb>>"
p '2.5'.gsub('.', ',') # => "2,5"
```

正規表現を使ってやっているのか〜。
ここに関してはもうちょっと調べてから更新するようにします！
LPIC-1 取得までの道

#初めに
以前に LPIC-1 を取得したので、その備忘録的なものを書いていこうと思います。

#LPIC-1 取得以前の知識
期間的には、一か月ぐらいです。（101 に2週間, 102 に2週間という感じです）
Linux の基本的なコマンドは知っている状態でした。(cd, find, for, if, awk, sed など)
しかし、Linux のシステムやストレージ関連、セキュリティなどはほとんど知らない状態で、そうなんだと思うことが多々ありました。

例）ssh で接続はできるけど、ssh-agent とかの仕組みなんて知らなかった。(ファイルの存在とかも)
　　dig コマンドの名前は知ってるけど、実際に打つようなことはしていなかった。（nslookup 使ってた）

#勉強に使ったもの
**LPICレベル１　スピードマスター問題集 versiono 5.0** --> 基本的にはこれで勉強
**Ping-t(webサイト)** --> 仕上げに利用
※　Ping-t の102の過去問は有料なので、お金を支払ってもいいと思う人は使用してください。

### 実際の勉強の流れ
1週間　問題集
その後、1週間 ping-t と スピードマスターの模擬試験をひたすらやる

上記の流れでひたすら、解きまくっていました。
Ping-t とかは全部金にしてから受験したほうがいいと思いますが、自分は時間がなかったため、模擬試験の部分で80% ぐらいを連発できるようになった時点で受験しました。

落ちるリスクを回避するには、金にするのがいいと思います。

#まとめ
すごく簡単になってしまい、すみません。
資格を取るという意味では、これで十分だと思います。
実際に Linux 環境を構築して手を動かさないと忘れてしまったり、実務で使えるような深い理解はできないですが、言葉を知っていると困ったときに調べやすかったりするので、この方法での資格取得はそういう意味ではいいかもしれないです。

上位資格については、また書きたいと思います。
変数を渡すタイプのPythonのデコレータについての考察

Pythonで開発をしていると、関数の前後に共通処理を挟みたくなるケースが良くあるかと思います。その場合に良く使われるのはデコレータ(関数の上の行にアノテーションを付けるやつ)ではないでしょうか。この記事では、デコレータの基本的な使い方と、後半では変数を渡せるタイプのデコレータについて考察してみたいと思います。
※本記事の動作検証には、Pythonのバージョン3.7.3を使用しています。

---

一番シンプルなデコレータは、以下のような実装です。

```python

def decorator(func):
    def decorated(*args, **kwargs):
        print('decorated 開始')
        func(*args, **kwargs)
        print('decorated 終了')
    return decorated
```

このデコレータを実際に使う場合には以下のようにします。

```python

@decorator
def sample(name):
    print('{}が動作しました。'.format(name))
```
このデコレートされたsample関数を実行すると、以下のようにprint出力される事から
期待通りにsample関数の前後に処理を挟めている事が分かります。

```cronsole
decorated 開始
sampleが動作しました。
decorated 終了
```

何故このような動作になるかと言うと、@はシンタックスシュガーで
実は以下のコードと等価だからです。

```python

def sample(name):
    print('{}が動作しました。'.format(name))

# @decoratorと等価
sample = decorator(sample)
```

---

ここまでは比較的分かりやすいのですが、変数を渡せるタイプのデコレータを理解しようとした時に、つまづくケースが多いのではないかと思います。
※以下に、変数を渡せるタイプのデコレータの実装例を記載します。

```python

def annotation(param):
    print('annotation 開始')
    
    def decorator(func):
        print('decorator 開始')
        print('param:{}'.format(param))
        
        def decorated(*args, **kwargs):
            print('decorated 開始')
            print('param:{}'.format(param))
            
            func(*args, **kwargs)
            print('decorated 終了')
           
        print('decorator 終了')
        return decorated
    
    print('annotation 終了')
    return decorator
```

先ほどのシンタックスシュガー(@)の動きを考えると、最上位の関数(annotation)の引数は関数じゃないといけないのではないか？と思いがちですが、実際に下記のコードは正常に動作します。

```python

print('アノテーション付きの関数を定義')

@annotation(param=999)
def sample(name):
    print('{}が動作しました。'.format(name))
    
print('アノテーション付きの関数を実行')

sample('sample')
```

以下にprint出力を記載

```cronsole
アノテーション付きの関数を定義
annotation 開始
annotation 終了
decorator 開始
param:999
decorator 終了
アノテーション付きの関数を実行
decorated 開始
param:999
sampleが動作しました。
decorated 終了
```

上記のprint出力を見ると、annotation関数終了後に呼び出されているdecorator関数の中から
annotation関数の引数であるparamが参照出来ています。
何故このような挙動になるのかと言うと、関数が参照出来る変数は関数を定義した時に決まるので、annotation関数内で定義されたdecorator関数は、annotation関数の引数であるparamを参照する事が出来るからです。
※このようなオブジェクトの事をクロージャと言います。
同様に、decorated関数もクロージャになっている為、paramとfuncを参照する事が出来ます。

また、print出力の内容を考察すると、変数を渡せるタイプのデコレータのシンタックスシュガー(@)は、以下と等価だと考えられます。

```python

def sample(name):
    print('{}が動作しました。'.format(name))

# @annotation(param=999)と等価
sample = annotation(param=999)(sample)
```

---

###参考資料

[Pythonのクロージャについて: 関数のスコープと、関数が第一級オブジェクトであることからちゃんと考える](https://qiita.com/kangetsu121/items/2fd0c6ec2729fc711340#fn3)
生体認証システムの導入（情報セキュリティ）ー午後

応用情報技術者平成28年秋期 午後1

ファイル：2016h28a_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/28_aki/pm01.html

メモを簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。

１、表2中のcに入れる適切な字句を解答群の中から選び，記号で答えよ。

cはPKIですね。
この認証を実現するには、クライアント証明書が正しいことを保証する第三者機関であるCA(Certification Authority，認証局)の設置が必要ですので、PKIですね。

・PKI(Public Key Infrastructure，公開鍵基盤)は、公開鍵暗号方式で鍵の所有者を保証する一連の仕組みです。公開鍵暗号方式を用いた認証ではPKIの導入が必須となります。CAはPKIの構成要素の1つです。



＜＜表2　T君が検討した認証方式＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6e966bf5-ca59-e6b0-44e5-622c3482907c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/24a4e51a-b725-d708-0784-b76fa24c0392.png)


・LDAP
　LDAP（Lightweight Directory Access Protocol）とは、ユーザーやコンピュータの情報を集中管理する「ディレクトリサービス」へのアクセス時に用いられるプロトコルの一つである。複数のバージョンがあるが、現在はさまざまな改善がなされたLDAP 3が主流となっている。

　LDAPを利用することで、LDAPクライアントはLDAPサーバ上のデータを検索、参照したり、追加や削除、変更などの操作を行ったりすることができる。ただし、ディレクトリサービスの性質上、頻繁なデータの変更や複雑な関係を持つデータの管理には向かず、あくまで情報の検索と参照が速いという特性を持つ。

　LDAPサーバとの通信内容そのものは暗号化されていないため、経路上の安全性を高めるために別途SSL/TLSなどと併せて利用する場合もある。

　LDAPサーバ機能を実装している有名な例として、MicrosoftのActive Directory、オープンソースソフトウェアのOpenLDAPなどが挙げられる。


２、〔導入製品の決定〕について，(1)，(2)に答えよ。
（１）本文中の下線①で，マニューシャ方式は実害が少ないとT君が考えた理由を，その特徴に着目して25字以内で述べよ。

元の指紋全体を再現できないため（私の答え）
→
漏えいしても元の指紋全体を再現できないから（参考答え）

＜＜導入製品の決定＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/eec48471-0ce7-f466-6aee-4c975e75b70d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/488d4413-98b4-24dd-d422-2581d6d1d195.png)


（２）本文中のd，eに入れる適切な理由を，それぞれ30字以内で述べよ。
dは導入方針により、個人情報と指紋情報を物理的に分けてほしいですね。

個人情報と指紋情報を物理的に分ける（私の答え）
→
個人情報と指紋情報を物理的に分けて管理できる（参考答え）

eは導入製品の決定の表３により、
　A、Cは指紋情報の格納場所がPC内であるため、除外される
　Eは指紋情報の格納場所が個人情報と同じサーバであるため、除外される
　
　BとDのPKですね。
　コストはほぼ同じですが、
　Bの他人受入率が低いですね。それで最良です。

他人受入率が低いと本人拒否率が同じ（私の答え）
→
誤って他人を本人と認識する確率が低い（参考答え）

＜＜導入方針＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/13f5a606-2db8-40e7-29c1-84d7e8ca80ba.png)

参照：

PKIとは
https://jp.globalsign.com/ssl-pki-info/pki/aboutpki.html#:~:text=PKI(%E5%85%AC%E9%96%8B%E9%8D%B5%E6%9A%97%E5%8F%B7%E5%9F%BA%E7%9B%A4,%E8%BA%AB%E5%85%83%E3%82%92%E4%BF%9D%E8%A8%BC%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

LDAP（Lightweight Directory Access Protocol）とは
https://www.atmarkit.co.jp/ait/articles/0401/01/news015.html#:~:text=LDAP%EF%BC%88Lightweight%20Directory%20Access%20Protocol%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%84,%E3%81%AE%E4%B8%80%E3%81%A4%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
ClingをインストールしてJupyter NotebookでC++を使えるようにする

メモる(までもなかった)。


# 手順

```terminal
$ brew install cling

$ cd /usr/local/Cellar/cling/0.6/libexec/share/cling/Jupyter/kernel

$ pip install -e .

$ jupyter-kernelspec install cling-cpp17
$ jupyter-kernelspec install cling-cpp1z
$ jupyter-kernelspec install cling-cpp14
$ jupyter-kernelspec install cling-cpp11


# これで起動する
$ jupyter notebook
```

できた。嬉しい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/895d253f-7e52-8fa5-f076-d5ddb50e39b5.png)



参考: https://github.com/root-project/cling/tree/master/tools/Jupyter
Zsh  zplug + prezto でプロンプトのカスタマイズ

zshのplugin managerって種類が多く、何を使えばいいか。。
ひとまず、`zplug`から各pluginをインストールする方向でローカル環境を構築してみた。

# ローカル環境
* macOS Catalina 10.15.6
* zsh version 5.7.1

# まずzplugのインストール
* homebrewから zplug をインストール

```
$ brew install zplug
==> Downloading https://github.com/zplug/zplug/archive/2.4.2.tar.gz
==> Downloading from https://codeload.github.com/zplug/zplug/tar.gz/2.4.2
##O#- #
==> Caveats
In order to use zplug, please add the following to your .zshrc:
  export ZPLUG_HOME=/usr/local/opt/zplug
  source $ZPLUG_HOME/init.zsh
==> Summary
:beer:  /usr/local/Cellar/zplug/2.4.2: 198 files, 369.8KB, built in 2 seconds
$
```
https://formulae.brew.sh/formula/zplug

# .zshrc編集
#### `ZPLUG_HOME` のexport  
zplugインストール時の表示通り、以下 `.zshrc`に追記

```
  export ZPLUG_HOME=/usr/local/opt/zplug
  source $ZPLUG_HOME/init.zsh
```

#### 入力補完plugin
以下、`.zshrc`に追記

```
zplug "zsh-users/zsh-autosuggestions"
zplug "zsh-users/zsh-completions"
zplug "chrissicool/zsh-256color"
```

#### コマンドプロンプトをカスタマイズするためのprezto prompt
zplugからpreztoのprompt pluginを取り込むため、以下 `.zshrc`に追記

```
zplug "modules/prompt", from:prezto
```

#### `.zshrc` に記載したpluginのインストール
上記、記載したpluginを実際にインストール & ロードするため、以下 `.zshrc` に追記

```
if ! zplug check; then
    zplug install
fi

zplug load
```

#### コマンドプロンプトのテーマを選択する
prezto prompt のコマンドプロンプトをロードするため、以下、 `.zshrc` に追記
（プロンプトテーマは色々ありますが、　シンプルな minimal にしてみました。）

```
prompt minimal
```

# .zshrc読み込み
最後に`.zshrc`をロードする

```
$ source ~/.zshrc
```

# prezto promptの使い方
#### prompt テーマ
以下のコマンドで promptテーマ一覧が表示される

```
$ prompt -l
Currently available prompt themes:
agnoster cloud damoekri giddie kylewest minimal nicoulaj paradox peepcode powerlevel10k powerlevel9k powerline pure skwp smiley sorin steeef adam1 adam2 bart bigfade clint default elite2 elite fade fire off oliver pws redhat restore suse walters zefram
```

#### 各テーマのプレビューも確認できる
試しに　cluudテーマをプレビューしてみた。

```
$ prompt -p cloud

prompt_cloud_setup:38: command not found: pmodload
cloud theme:
☁  ~  command arg1 arg2 ... argn

cloud theme with parameters `✯':
✯  ~  command arg1 arg2 ... argn

cloud theme with parameters `> yellow red':
>  ~  command arg1 arg2 ... argn
```

#### テーマを変更する
`adam1` テーマに変更してみた。

```
$ prompt adam1
xxxx@localhost ~ %
```

# 参考資料
* https://github.com/zplug/zplug
* https://github.com/unixorn/awesome-zsh-plugins
* https://mikebuss.com/2014/04/07/customizing-prezto/
* https://github.com/sorin-ionescu/prezto
【勾配消失】DenseNet ResNetの違い

ResNetは知ってるけど、DenseNetってなに？って思って調べたら面白かった。
どっちも勾配消失させない為の構造だが、どんな違いがあるのだろうか。


<h1>DenseNetの仕組み</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ef8d27e7-d7b8-8c8a-8085-4a0ab3e2ff1c.png)
これが普通のConvolution Network

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b8e69388-3992-0a98-a21a-54908b412820.png)
Residualではskipした結果を足し合わせる(sum)。残差を学習する事で勾配消失を避けられ、深い層でも学習が進むようになった。
しかし、足し合わせたら元の情報を保ってないので情報の伝達を邪魔しているのではないかと考えた。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/7572f928-fe0a-e531-5442-2acce4af7051.png)
そこで、Dense Blockではそのまま前の結果を結合(concatenate)する事にした。Dense Blockを用いる事で前の情報をそのまま加味することが出来る。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/6ea043af-bf82-c36f-24c2-e6be50b6271f.png)
層毎にKの層が増えていくとすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3d8c725c-0d8b-a70c-bf67-04015d9453c0.png)
で表せられる。
K0->入力層の数
K ->畳み込みの出力層の数(Grouth Rate)
l ->l番目のlayer


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/69bf3260-f18e-9ed1-9c39-e2e7b764b6f0.png)
上記でも説明したように、出力をk channelになるように畳み込む


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ccc50bf9-7843-f52c-d0c1-ed3c7d836548.png)
さらに 1x1 convolutionを行い次元数を削減してから 3x3 convolutionを行うことで計算量が軽くなる。


<h1>利点</h1>
<h3>computational efficiency</h3>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/2da6a396-64d4-025d-32d6-be31e57dc30d.png)
ResNetの場合 C chanel のinputに C chanel のoutputで O(CxC)となる
DenseNetの場合 lxk chanel のinputに k chanel のoutputでO(lxkxk)となる
kはcよりかなり小さくて良いので、DenseNetより計算量が少なくなる。

<h3>特徴量の複雑さ</h3>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c2c87761-14a8-9c05-09e8-033eec392a03.png)
層を重ねる毎に特徴量は複雑になる。最終的に一番最後の複雑な特徴量を使う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/6225b68f-4094-6140-81dc-85f04e9736df.png)
前の層を結合することで、すべてのレベルの複雑な特徴量を加味出来る

<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ea930c61-f32e-8fa0-dedc-d2e4c4d964a4.png)
resnetと同じエラー数でより少ないparameter数ですんでいる。



<h1>参考文献</h1>
Densely Connected Convolutional Networks
https://arxiv.org/pdf/1608.06993.pdf
Review: DenseNet — Dense Convolutional Network (Image Classification)
https://towardsdatascience.com/review-densenet-image-classification-b6631a8ef803
Rails5  Rspecテスト時のエラー ArgumentError:  Factory not registered: user

## はじめに
Ruby on Rails5 速習実践ガイドのChapter5-8にて、"bundle exec rspec spec/system/tasks_spec.rb"をターミナル上で実行したところ、下記のエラーにハマりました。
その備忘録です。

## 発生している問題・エラー
```
Failures:

  1) タスク管理機能 一覧機能表示 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
     Failure/Error: user_a = FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com')
     
     ArgumentError:
       Factory not registered: user
     
     # /Library/Ruby/Gems/2.6.0/gems/factory_bot-4.11.1/lib/factory_bot/registry.rb:24:in `find'
     # /Library/Ruby/Gems/2.6.0/gems/factory_bot-4.11.1/lib/factory_bot/decorator.rb:10:in `method_missing'
     # /Library/Ruby/Gems/2.6.0/gems/factory_bot-4.11.1/lib/factory_bot.rb:100:in `factory_by_name'
     # /Library/Ruby/Gems/2.6.0/gems/factory_bot-4.11.1/lib/factory_bot/factory_runner.rb:12:in `run'
     # /Library/Ruby/Gems/2.6.0/gems/factory_bot-4.11.1/lib/factory_bot/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
     # ./spec/system/tasks_spec.rb:7:in `block (3 levels) in <top (required)>'

Finished in 5.33 seconds (files took 1.31 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/system/tasks_spec.rb:19 # タスク管理機能 一覧機能表示 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される

```

## 原因・解決方法

ディレクトリ名のスペルミス

######正　factories　
######誤　factries　

ディレクトリ名も誤字がないように気を付けないとだめですね・・。
[PHP] selfとstaticの違いメモ

##要点
self: 定義時のクラスを指す
static: 実行時のクラスを指す

##例
```
class Foo
{
    public function helloGateway()
    {
        self::hello();
    }
    
    public static function hello()
    {
        echo __CLASS__ . 'hello' . PHP_EOL;
    }
}

class Bar extends Foo {
    public static function hello()
    {
        echo __CLASS__ . 'hello' . PHP_EOL;
    }
}

$bar = new Bar();
echo $bar->helloGateway();
//この場合はFoohelloが出力される
```
Clean My Mac Xを使った後にDockerが使えなくなった事件

##この記事について
MacOSをアップデートしようと思ったのですが、ストレージが「その他」でいっぱいになり、いらないファイルやらを消してくれる「**Clean My Mac X**」を使用して、Macの再起動後にDocekrを立ち上げようとすると、添付画像のエラーが表示されました。

今回はこのエラーを解決するためにやったことをまとめた記事です。



![スクリーンショット 2020-09-27 7.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/e2fb74dd-942e-5b4a-be9a-1dedb401b1d0.png)



###Clean My Mac Xとは
>CleanMyMac Xは、システム内のキャッシュファイルやジャンク(破損)ファイル、使用していないファイル(言語データや過去の古いファイル)などを、スキャンして削除できるアプリです。


https://www.cleanmymac.jp/
https://o9sec.com/2019/08/14/2978/


##環境
**Mac Catalina**：10.15.5
**Docker**：2.3.0.3？
※DockerのバージョンはDockerを開く事ができなくて確認できませんが、今年の6月ごろに使い始めたので恐らくこのバージョンです。









##問題解決に参考した記事
https://github.com/docker/for-mac/issues/4526
参考記事だと、古いバージョンをインストールすると問題が解決された方もいっらしゃるようですが、私の場合は解決できませんでした。


##やったこと
- Dockerをアンインストールしてから再度インストール

- Docker Desktop Community 2.2.0.5でインストール


◆参考記事内でできなかったこと
https://github.com/docker/for-mac/issues/4526#issuecomment-640237696
いくつかgoodが押されているのでやってみたみたいのですが、日本語に訳しても何をすればいいかわからないので挑戦できていないです。

###真似できなかった参考記事の日本語訳
>BIOSで「Intel（VMX）仮想化テクノロジー」を有効にする必要があります。
これを有効にする場所を知るには、BIOSメーカーを確認してください。
これは「仮想化（VT-x）」とは異なります
それらを有効にすると、再び機能します。



##私の場合の解決方法
**Clean My Mac X**のおかげでストレージにアップデートするための枠ができたので、MacOSをアップデートすると、ちゃんと使えるようになっていました！



##反省
バージョンいくつか試してうまくいかないようならそもそもシステム周りのファイルを消された可能性があったから、無闇に削除するとえらい目に合っちゃう。。。
f.collection_selectの"選択して下さい"を選んだときのバリデーション

#1.やりたいこと
`<%= f.collection_select :address_id, @customer.addresses, :id, :full_address, :include_blank => "選択してください" %>`
フォームにおいて選択せずに一番上の"選択して下さい"を選んだ際にバリデーションをかけたい。
#2.実装する
```rails:app/controllers/orders_controller.rb
 params[:order][:address_id] ==  ""
 flash[:notice] = "選択して下さい"
 redirect_to new_order_path
```
パラメータから送られている値を見ると`""`となっていたのでイコール文を`""`に変更。
#3.終わりに
これを実装したかった時にQiitaやGoogleで検索しても全然出てこなかったので
投稿しました。
しっかりターミナルを見て返ってきてる値を確認しないといけないと痛感しました。