OmniAICreator/Qiita-1.07M huggingface dataset:
S.M.A.R.TでUncorrectable error in data(Offline Uncorrectable)が発生したので，ファイルを特定してHDD(ext4)からデータを救出

S.M.A.R.TでUncorrectable error in data(Offline Uncorrectable)が発生したので，ファイルを特定してHDD(ext4)からデータを救出
=============================

背景
------------


4.0TのHDDを長いこと使っていた．

```
Seagate BarraCuda 3.5(SMR)
ST4000DM004-2CV104
```

で，たまたま`gsmartctl`を走らせてみたらError Logが真っ赤ではないか．
しかもUncorrectableとか書いてあるしもうヤバい．

具体的にはこんなエラー

```
Uncorrectable error in data at LBA = 0x2e7ff908 = 780138760
```

なんて脅してきた．
LBAだけ与えられてもどのファイルか分からないとどうしようもない．
というわけで早速チェックしていく．


そんな長いこと使っていたといってもSpindle Motor Power-on Hoursだけでいうと17,476だったので，728日およそ2年ぐらい．
そこそこ起動させっぱなしにしていたとはいえ，24時間365日付けていたわけではない．

Statisticsを見た限り，

Number of Reallocation Canditate Logical Sectorsが16あって，
Number of  Reported Uncorrectable Errosが4
そして，Time in Under-Temperature(C)が1,360だ．

Time in Under-Temperature(C)の意味が分からないのだが，冷えすぎるとダメなの？



の前に
--------

こんなエラーが出るってことはHDDは壊れかけなので，
できるだけ余計な負荷を与えないようにしたい．
ファイルの書き込みや削除なんか．
ゴミ箱を絡にしたりrmしたりも注意だ．

そして新しいHDDの購入手続きを進めておくこと．
私はバックアップをとらない過激派(HDDはどうしても常時可動させたくなっちゃう)なのでストックはない．

ファイルの特定の流れ
-----------

本当はS.M.A.R.T.が出してくれたエラーをそのまま使えるといいんだけれど，
LBAからファイルの位置を特定する方法が見つからなかったので，
`badblocks`を使ってもう一度チェックする．

ここで`badblocks`のデフォルトのセクタサイズは1024になっているので，

```
sudo fdisk -l
```

とでもして，セクタサイズを調べておく．
購入時にフォーマットしたのがデフォルトの4096なのでこれを`-b`オプションで指定する．

```
sudo badblocks -v /dev/sdxx -b 4096
```

ちなみにこの時はパーティションを区切った後のを指定しておいた方が楽だ．(/dev/sdaではなく/dev/sda1ということ)
でないとsda1のパーティションの始まりの場所を引く必要が出てくる．

というわけでこのコマンドを実行すると数字が出てくる．
この数字がエラーの発生した箇所を示してくれている．


次にこの場所にファイルがあるかどうかを確認する．
これ以降は`debugfs`を使う
私の環境ではこれ以降のコマンドは返ってくるまでにかなり時間がかかった．
遅くても我慢強く待つのがよいだろう．

```
sudo debugfs /dev/sdxx
debugfs: testb <block num>
```

ここで使用中でなければ救出の必要はない．
こんな風に返ってくる

使用されている場合

```
Block <block num> marked in use
```

使用されていない場合

```
Block <block num> not in use
```

今回はなんとmarked in use.ファイルが壊れてしまった．

まあまだ何とかなるかもしれないと思い，
ブロック番号からinode番号を調べる．

```
debugfs: icheck <block num>
```


これでファイルがあれば二つの数字が帰ってくる．
一つ目がブロック番号で2つ目がinode番号だ．


```
debugfs: ncheck <inode num>
```

これでファイル名が特定できる．

ファイルを救出する
--------------------

この時点でファイルが壊れているので，後はどこまで読めるかだ．
致命的な場所さえ壊れていなければ，最近の優秀なソフトでは以外とそのまま読み込めたりするので，まだ諦めてはいけない．

ここでcpコマンドはディスクの読み込みエラーを起こすと途中で止まる

```
cp: error reading <file>: Input/output error
```

というわけで，それでも無理矢理読んでくれるコマンド`ddrescue`を使う．
使い方は`cp`と同じだ．

```
ddrescue <src> <dst>
```

コマンドの詳細は残っていないが
今回は512byteつまり4096の1セクタ分が壊れてしまったようだった．

ファイル自体はzipで画像1ファイルだけ解凍に失敗したが，画像としては読み出せた．
ただ画像の途中から色は変わっていたが，上出来だ．


新機HDDに移行する
---------------

というわけで壊れかけのHDDから新しいHDDにデータを移行する．

パーティショニングやフォーマットについては割愛．

今回はHDDはまだ元気そう？だったのでcpコマンドでいった．
ただ，もっと自体が深刻であれば`ddrescue`を使った方がよいだろう．

途中でcpが失敗しても分かるように，そして途中経過が分かるように次のようにした．


```
cp -r -v /mnt/<src>/* /mnt/<dst>
```


`-r`で再帰的に`-v`で途中経過を表示するようにした．
テストセンターでの受験方法

#はじめに
私はこれまで数々の資格試験に挑戦し、20回以上テストセンターを利用しました。この記事ではその中で得られた知見を共有するものです。
何度もテストセンターに通っているとわかりますが、多くの会場ではIT系資格以外の試験も行われています。就活中と思われる学生がSPIを受験しているのも見かけました。はじめてパソコンを使った資格試験やSPIに挑戦する方向けに、テストセンターでの受験のしかたを解説します。
なお、この記事では私がこれまでに受験してきたIT系資格を元に記載しており、受験する試験によっては若干異なる可能性があります。
必ず各資格試験の公式サイトもご参照ください。

#予約方法
一般的にはピアソンビューやプロメトリック、オデッセイなどのサイトから予約します。試験によっては別のサイトから予約することもあります。（例えばGIACの場合は、GIACのサイトから予約します）
予約する際に、日時と場所を決めます。この日時と場所はよく考えて選んでください。

日時は、確実にその会場に到着できる日時を選びます。私の場合は、試験開始1時間以上前に会場付近に到着し、近くのカフェなどで勉強するようにしています。万が一交通機関のトラブルなどで到着が遅れても間に合うようにするためです。
場所は自宅や職場近くのテストセンターを選びますが、テストセンターの規模、設備にはかなり差があります。事前にテストセンターの名前でググっておき、試験会場の写真を確認しておくことを推奨します。少なくとも隣とパーティションで区切られている会場を選びましょう。
テストセンターの規模が小さい場合、予約がやや取りづらいことがあるかもしれませんが、個人的には規模の大小よりも、試験に集中できる環境かどうかが重要だと思います。場所によっては電車や車の音が気になるかもしれません。会場によってはヘッドホンのような耳栓が用意されている場合もあります。これも事前にググっておけば確認できます。

#持ち物
試験によって持ち物は変わりますが、一般的な持ち物を記載します。
絶対に忘れてはいけないのが身分証明書です。ほぼすべての試験で確認されますし、2つ以上の提示を求められる場合もあります。
通常は運転免許証やパスポート、マイナンバーカードの中から2つ持っていけば問題ないと思います。これ以外を求められる可能性もありますので、受験する試験の公式サイトでご確認ください。
試験によっては参考書や電卓などが持ち込めるかもしれません。受験する試験の公式サイトで確認ください。
参考書で直前まで勉強したいという場合は、試験会場では勉強できないことがあるので、近くのカフェを利用することを強くお勧めします。試験会場に着いたらもう勉強禁止なので受験してくださいと言われるかもしれません。

なお、就活中の学生の方で、SPIを受験する際の服装を気にする人がいるようですが、テストセンターの受付の人は採用試験とは関係ありませんので、服装を気にする必要はありません。（当然ですが、テストセンターではなく、会社でSPIを受ける場合はスーツの方が良いと思います）

#試験の受け方
##受付
最初に受付をします。予約した時間と名前、受験する試験の名前を言えば良いです。試験によって異なりますが、同意書への署名、写真撮影、デジタル署名[^1]、静脈認証登録（今のところCISSP、SSCPのみ経験）などが行われます。
私物は持ち込めるもの以外はすべてロッカーにしまいます。ポケットも空にします。

##受験
受付が終わったら、試験を受けるパソコンの前に案内されます。後はパソコンに表示される指示に従って操作するだけです。
多くの試験は、選択式の問題です。正解と思われる選択肢をマウスで選択します。1つを選ぶものもあれば、2つ以上を選ぶ場合もあります。
ごく一部ですが、記述式の問題もあります。その場合はキーボードを使って入力します。
またさらにごく一部の試験では、仮想マシンを操作して解答[^2]するものもあります。そのような試験は公式サイトにその旨が記載されているはずですので事前にご確認ください。

試験にもよりますが、通常は後から見直すためのフラグを立てるボタンが画面上に表示されているはずです。自信がない問題は後から見直すためにフラグを立てておくと良いです。最後まで解答した後、すべての問題を見直す、フラグを立てた問題だけを見直す、任意の問題を見直すのいずれかを選べます。見直しが終わったら試験終了ボタンを押すと、試験が終了します。
なお、最近CISSP試験は見直すことができなくなったようですのでご注意ください。GIACの試験も見直すことはできません[^3]。1つ1つの解答を間違えないようにしましょう。

##試験終了
試験終了ボタンを押すか、制限時間が0になったら試験が終了します。アンケートが表示される場合もあります。
合否は通常はその場で表示されるか、受付でもらうレポートに合否が記載されています。試験によっては合否判定がその場で行われないこともあるようです。
受付で結果レポートをもらいます。（試験によってはレポートが出ないこともあります）
指示があるまではロッカー内の私物を取りに行かないでください。不正行為とみなされることがあります。
最後にロッカーから私物をとって終了です。

#まとめ
私にとっては当たり前のことではあるのですが、ちょうど新社会人になったばかりで資格取得を命じられたという人もいるでしょうから、テストセンターでの受験のしかたを書いてみました。参考になれば幸いです。

[^1]: ここでいうデジタル署名とは、PGPなどのデジタル署名ではなく、データとして記録される自筆の署名のことです。
[^2]: GIACの一部の試験やCompTIAの一部の試験が該当します。
[^3]: GIACの試験では、見直すことはできませんが、解答を保留することはできます。ただし、保留できる問題数に制限があります。
Rspecでメール内にあるURLを取得する

メールについてのRspecを書くときに詰まったので備忘録代わりに記事にします！

### やりたいこと
SystemSpeec内でAction Mailerを使って送信されたメール本文のリンクURLを取得して利用したい
ヘルパーを使ったxxx_pathをしようと思ったが、今回はパスワードリセットで、deviseの処理で生成されたパスワードリセットトークンを含んだURLがほしかった。

### 結論
**URI.extract(str)**を使って文字列からURLを抽出する
https://docs.ruby-lang.org/ja/latest/method/URI/s/extract.html

## 実際のコード(deviseを利用したパスワードリセットのテスト）

```
visit 'members/password/new'
expect(page).to have_content("パスワードを忘れましたか?")

find('#xxxxx').set('example@example.com')
click_button("パスワードの再設定方法を送信する")
# システム上クリックされた後にタイミングでメールが送信される

expect(page).to have_content('xxxxxxx')
```

## 本題部分
```
# これで配信したメールのインスタンスを取得できる
password_reset_mail = ActionMailer::Base.deliveries.last 

# 本文をエンコードして取得
mail_body = password_reset_mail.body.encoded

# 文字列からURLの配列で取得。今回はURLは１つだけなので1番目を取得
password_reset_url = URI.extract(mail_body)[0]

visit password_reset_url
expect(page).to have_content('パスワードを変更')

この後実際にフォームを入力させたりする
```

もっといい方法があればぜひコメントいただければと思います！！

## 参考
[Action Mailer の基礎 | Rails ガイド](https://railsguides.jp/action_mailer_basics.html)
[Mailer specs - RSpec Rails - RSpec - Relish](https://relishapp.com/rspec/rspec-rails/docs/mailer-specs)
[ingleton method URI.extract](https://docs.ruby-lang.org/ja/latest/method/URI/s/extract.html)
【Vue × Firestore】ボタンを発火させた際、認証ユーザーページをリロードさせる


#ボタンを発火させた際、認証ユーザーページをリロードさせる

```html:mypage.vue
<button @click="updateBtn" class="update-btn flex">更新</button>
```

```javascript:mypage.vue
<script>
import firebase from "firebase";
import Header from "@/components/header.vue";
import Vue from "vue";

  ~ 省略 ~

  methods: {
    updateBtn() {
      firebase
        .firestore()
        .collection("users")
        .doc(this.$route.params.uid)
        .set(
          {
            name: this.name,
            sex: this.sex,
            age: this.age,
            access: this.access,
            selfpr: this.selfpr,
            profession: this.profession,
            uploadedImage: this.uploadedImage,
            genre: this.genre,
            favMovie: this.favMovie,
            time: firebase.firestore.FieldValue.serverTimestamp(),
          },
          { merge: true }
        );
      this.$swal({
        title: "内容確認",
        text: "この内容で投稿しますか？",
        icon: "info",
        buttons: true,
        dangerMode: true,
      }).then((willDelete) => {
        if (willDelete) {
          this.$swal("投稿しました。", {
            icon: "success",
          });
          this.$router.go({
            path: `/mypage/${this.$route.params.uid}`,
            force: true,
          });
          //プロフィール編集されたらページをリロード
        } else {
          this.$swal("キャンセルしました。");
        }
      });
    },

  ~ 省略 ~

</script>
```
updateBtn()が押下されたらページをリロードさせるようにしてますが、

[動的ルートマッチング「this.$route.params」について](https://qiita.com/TMTN/items/35a0263953bda7346736)

上記記事でも書かせて頂いたように、this.$route.params.uidで現在のURLのパラメータを取得して
単純に/mypage/${this.$route.params.uidという形式でリロードをさせてます。

```javascript:router.js
 {
    path: "/mypage/:uid",
    name: "Mypage",
    component: Mypage,
    meta: { requiresAuth: true },
  },
```
```javascript:mypage.vue
this.$router.go({path: `/mypage/${this.$route.params.uid}`,force: true,});
```
Windows Server 2019 のリモートデスクトップ設定

#TL;DR
[コントロールパネル] - [システム/リモートアクセスの許可] - [リモートデスクトップ/このコンピュータへのリモート接続を許可する]

#はじめに
Windows Server 2019でリモートデスクトップの設定をするだけの記事です。

#1.設定
Windowsメニューを起動し、コントロールパネルをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/f94936b2-b63d-a738-4ba1-ede48af350a6.png)

システム欄にある、リモートアクセスの許可をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/98ae0f63-295c-8c62-089d-e1d7bec3e8d7.png)

このコンピューターへのリモート接続を許可するを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/fa4d035a-40a6-e5eb-3d8a-aebe5d17534c.png)

ファイアウォール例外の確認が出ますが、OKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/0db1475f-6d00-208e-9fba-e4c3d34c09dc.png)


OKを選択すると、設定が完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/2df149d8-6a69-6113-2a65-1a1c49eaa353.png)

#2.接続確認
ネットワークで繋がっている別のPCなどから、リモートデスクトップにて接続可能か確認します。

うまくつながらない場合、以下を確認することが多いですが、原因が特定できない場合はネットワーク管理者かサーバ管理者に問い合わせしたほうがよいでしょう。

```powershell:接続確認①
ping [リモート接続するIPアドレス]
tracert -d [リモート接続するIPアドレス]
```

→古典的なネットワーク接続確認ですが、接続先のネットワークやfirewallで制限している場合があるので、こちらの確認方法だけで接続NGと判断してしまうのはあまりよくないです。
</b>
</b>

```powershell:接続確認②
test-netconnection [リモート接続するIPアドレス] -port 3389
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/97a513b7-a114-efce-4333-bd3ae2278093.png)

→powershellを利用する方法です。リモートデスクトップで利用するtcp:3389ポートが解放されているかを確認する方法です。ping ngでもこちらだと疎通OKになるパターンは多いかと思います。

上記両方ともでダメな場合、要因が複合的または専門的となるため、ネットワーク管理者かサーバ管理者に可能な限り詳細に説明しながら解明するようしてください。


#3.認証エラーが出る場合
以下エラーが発生して接続できない場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/10296c1b-7fd8-94b0-15db-05ae3a7dcdea.png)

```text:リモートデスクトップ接続
認証エラーが発生しました。
要求された関数はサポートされていません

リモートコンピューター:[リモート接続するIPアドレス] 
原因は CredSSP 暗号化オラクルの修復である可能性があります。
詳細については、https://go.microsoft.com/fwlink/?linkid=866660を参照してください
```

こちらですが、簡単に言うとリモート接続先サーバおよび接続用PCのWindowsパッチ最新版が適用されていません。解消するためにはWindows Updateを掛けてください。

ただし、そうはいかない環境もあるかと思いますので、暫定回避策としては以下があります。なお、セキュリティレベルとしては通常より低下させることになりますので、できる限りWindows Updateにて対応するようにしてください。

対処法：ネットワークレベル認証でリモートデスクトップを実行しているコンピュータからのみ接続を許可する(推奨)のチェックを外す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/85b28225-c77e-1167-19a9-f491e6ce0656.png)


#参考


https://support.microsoft.com/ja-jp/topic/cve-2018-0886-%E3%81%AE-credssp-%E3%81%AE%E6%9B%B4%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0-5cbf9e5f-dc6d-744f-9e97-7ba400d6d3ea


https://faq.mypage.otsuka-shokai.co.jp/app/answers/detail/a_id/296542/~/%5Bwindows10%5D-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E6%8E%A5%E7%B6%9A%E3%81%A7%E8%AA%8D%E8%A8%BC%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A8%E3%81%AA%E3%82%8B
ローカル環境でgitの環境を整える。

#注意
これは、私の大学の授業で、提出先がGitHubであったため、まとめたものです。
類似する改善点はあるかもしれませんが、非常に限られた環境について書かれています。
**以上を確認した上で、記事を読んでください。**
カレントディレクトリ（今、自分がいるファイルの場所）が重要になります。自分がどこにいるか確認するための

```:コマンド
> pwd
```
を覚えておくと便利です。
#筆者の環境
windows10
ダウンロード元 chrome
githubログイン中ブラウザ chrome
#手順
1 gitをインストール。特にこだわりが無ければnextやり続けてok
2 インストールされたGit Bashを起動
3 開かれたディレクトリで、作業ディレクトリ（今回、sit-workとする。）を作成。<br>フォルダの管理に慣れている人（この場合はローカルに慣れていればそれでよい）は、ここで好きなディレクトリに移動して作業ディレクトリを作ればOKです。

```:コマンド
> mkdir sit-work
```
```:ディレクトリ構造(ファイルの並び)
~ (<-今ここ--git bashを開いたときはここにいる。)
|- sit-work (<-これ作った)
```
4 作業ディレクトリ内に入る(cd sit-work)

```:コマンド
> cd sit-work
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work (<-今ここ)
```
5 作業ディレクトリ内で、次のコマンドを実行

```:コマンド
> git init
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work (<-今ここ)
```
6 作業ディレクトリ内で、次のコマンドを実行(git clone [URL])<br>今回、ユーザー名をnameとする。

```:コマンド
> git clone https://github.com/***-***-*****/ex1-name
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work (<-今ここ)
    |-ex1-name(<-できてるので、lsコマンドで確認してみよう)
```

7 cloneで持ってきた課題を解く。

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work(<-今ここ)
    |-ex1-name
         |-src
           |-main
               |-java
                   |-Ex1.java(<-これを解く。)
```
8 cloneで持ってきたディレクトリに移動<br>

```
> cd ex1-name
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work
    |-ex1-name(<-ここに来る)
```
9 git add [ファイル名(./src/.../Ex1.java)]の実行

```:コマンド
> git add ./src/main/java/Ex1.java
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work
    |-ex1-name(<-今ここ)
         |-src
           |-main
               |-java
                   |-Ex1.java
```
10 git commit -m "comment"の実行

```:コマンド
> git commit -m "repair error"
```

```:ディレクトリ構造(ファイルの並び)
~
|- sit-work
    |-ex1-name(<-今ここ)
         |-src
           |-main
               |-java
                   |-Ex1.java
```
11 git pushの実行

```:コマンド
> git push
```
しばらくして、最後の行に+や-がでてくればOK
終了です。お疲れさまでした。
# エラーについて
人によっては、

```:エラーメッセージ
Run

 git config --global user.email "you@example.com"
 git config --global user.name "Your Name"
```
が含まれる文章が出てくるかもしれません。
そのときは、以下の2つのコマンドを実行してください。

```:実行すべきコマンド1
> git config --global user.email "you@example.com"
```
you@example.comはGitHubに登録したメールアドレスだと良いでしょう。

```:実行すべきコマンド2
> git config --global user.name "Your Name"
```
Your NameもGitHubに登録したユーザー名にすると良いでしょう。
docker: Cannot connect to the Docker daemon とエラーが出た時まず行うこと。

'docker run'　や 'docker ps'などのドッカーコマンドを打ち込んだ時、以下のようなエラーが発生することがあるのではないでしょうか。

```
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.
```
まず
###dockerを起動していますか？

エラーの解決に一意専心してしまうと意外と気づかないかもしれません。
以下の画像のようにまずdockerhubに入り、ログインしてdockerが起動されているかを確認することをお勧めします。
私はdocker desktopですので、上にマークが表示されます。

![スクリーンショット 2021-04-30 21.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985033/f817ec93-b860-6c92-3aa7-f163df7c3173.png)


余談ですが、
当該エラーで検索すると　sudo等を編集したり、シェルを編集したりとさまざまな方法がでてきます。
私はそれらを色々試しましたが、長い時間を使った結果。docker hubを起動していないということを見落としておりました。
私のような初学者様方はまずは基本に立ち返ることをお勧めします。

お恥ずかしいですが、私の失敗が少しでも役にたてばと思います。
機械学習を学んでみたのでそのまとめ①前処理

　Udemyで[【世界で74万人が受講】基礎から理解し、Pythonで実装！機械学習26のアルゴリズムを理論と実践を通じてマスターしよう](https://www.udemy.com/course/ml-with-python/)を受講したので、その内容をまとめます。


# 前処理
まず機械学習とはざっくり言うと、機械学習のモデルに対して何らかのデータを与えると何らかの出力を得るものなので、データに不備があると正しい出力を得ることができなくなってしまう。そこで機械学習のモデルに与える正しいデータに加工することを前処理といいます。

![qiita_20210430_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/4d500794-7ddd-be57-95a7-4c00576f9842.png)

## 独立変数と従属変数
　ここでもまたざっくり言うと機械学習モデルに対して入力するデータを独立変数と出力されるデータを従属変数と言います。
　独立変数のことを説明変数、従属変数のことを目的変数とも言います。（というか、そっちの方がよく使われている気がする。）

## 欠損値の処理
　データの中に抜け落ちているものがあると正しく処理できないので、対処する必要があります。対応方法としては以下の２つになります。
・抜けているデータのある列を列ごと削除する。（削除するとデータそのものが無くなってしまうので、あまり良くない。目安として削除できるのは全体の1%未満。）
・抜けているデータをなんらかの値（平均値、中央値、最頻値など）で補完する。

skleanを使った欠損処理(平均値補完)

```python
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer.fit(df)
df = imputer.transform(df)
```

## 独立変数と従属変数のエンコーディング
数値以外のデータはOne-hot encodingやBinary Encodingを用いて機械学習で計算できるように変換する。

## 訓練用データセットとテスト用データセットの分割
データセットは訓練用データセットとテスト用データセットに分割して機械学習モデルで使用する。
訓練用データセットで機械学習モデルを作成し、テスト用データセットで作成した機械学習モデルが妥当であるか検証する。

独立変数(X)と従属変数(y)を訓練用独立変数(X_train)、テスト用独立変数(X_test)、訓練用従属変数(y_train)、テスト用従属変数(y_test)に分割

```python
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)
```

## フューチャースケーリング(標準化)
フューチャースケーリング(標準化)とは尺度の違うデータを標準正規分布のスケーリングし直すことで、同じ尺度に変換し、機械学習モデルの認識する重要性の違いを取り除く処理になります。
StandardScalerを使うことで、平均:0、標準偏差:1のデータに変換することができる。

```python
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
y_train = sc.fit_transform(y_train)
```
【Vue × Firestore】ログイン後、ヘッダーから認証済みのマイページへ遷移させる


#ログイン後、ヘッダーから認証済みのマイページへ遷移させる

```html:header.vue
 <li><router-link :to="`/mypage/${this.uid}`" class="header-link neon3 flash">MYPAGE</router-link></li>
```

```javascript:header.vue
<script>
import firebase from "firebase";
export default {

         ~ 省略 ~

  created() {
    const currentUser = firebase.auth().currentUser;
    //現在ログインしているユーザーを取得
    this.uid = currentUser.uid;
    firebase
      .firestore()
      .collection("users")
      .doc(currentUser.uid)
      .get();
  },

         ~ 省略 ~

};
</script>
```

firebase.auth().currentUserにて現在ログインしているユーザーを取得してます。

usersというコレクションを参照して、現在ログインしているユーザー（currentUser）から「uid」を取得して
get()を使ってuidデータをFirestoreから取得。

```javascript:header.vue
  created() {
    const currentUser = firebase.auth().currentUser;
    //現在ログインしているユーザーを取得
    this.uid = currentUser.uid;
    firebase
      .firestore()
      .collection("users")
      .doc(currentUser.uid)
      .get();
  },
```

ページを遷移させる為に一度this.uidに 「currentUser.uid;」を格納してから
${this.uid}として対象ページに遷移させています。

```html:header.vue
 <li><router-link :to="`/mypage/${this.uid}`" class="header-link neon3 flash">MYPAGE</router-link></li>
```
CSS完全に理解した

一部に人気のあるCSS完全に理解したTシャツのあの絵。
自分みたいにまだプログラミングを始めてそんなに経ってない人とってはCSSを理解するのに
手っ取り早い教材ではないでしょうか？
そういうわけで自分なりに調べて再現してみました。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stylesheet" href="kanzenni.css">
    <title>test</title>
  </head>
  <body>
    <div class = "main">
      <p class = "main-box">
    CSS<br>完全に理解した
    </p>
    </div>
  </body>
</html>
```


```css
.main{
  font-size: 20px;
  position: relative;
  border: 1px solid;
  border-radius: 5px;
  width: 140px;
  height: 80px;
}

.main-box{
  padding-left: 30px;
  white-space: nowrap;
  position: relative;
  bottom: 20px;
}
```

フォントサイズやボックスのサイズを調整し、p要素をposition relativeで隙間を開けました。
また、文字をボックスの外に突き出すために`white-space: nowrap;`を記述しました。

white-spaceプロパティとはソース中のテキストについて、自動改行するか複数の空白を一つの空白にするか、改行を空白にするかなど、改行やスペース、タブの扱いを指定するプロパティとのことで、今回はソースの外にはみ出すためにwhite-space: nowrapを記述しました。

![ba4a66b1879027c16c8964d66e04628d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1301666/690a2763-45bf-81ba-9c3c-b9e94d188072.png)

結果はこんな感じになりました。
一応成功でしょうかね？
[Unity / Addressable Assets System]  実機で自前のサーバーからbundleデータが読み込めない問題

基本的な導入方法はこちらのサイトを参考にさせて頂きました。エディタ上で読み込むところまでは特に問題なくできるかと思います。
https://note.com/graffity/n/n8620f244894a

#現象
エディタ上では正常に読み込めているが、実機(iOS・Android端末)では読み込めないという現象。

#試したこと
ネット上の情報を参考にUnity内での設定を確認するも、特に問題は無し。

ローカルにエクスポートされたServerData以下のbundleファイルを消してみると、読み込めず。
->エディタ上では正常にダウンロードしているように見えたが、実は失敗していて、代わりにローカルのファイルを読んでいたということが発覚。何らかの原因でサーバー上のbundleファイルが読めていない模様。

さらに調査を進めると、catalog_jsonファイルは読み込めているが、そこからサーバー上のbundleファイルを読むには至っていないことが分かった。

bundleファイルのパーミッションは「604」ということでユーザーが読んでくる分には問題なし。読んだファイルがどうにかなっている模様。

#結論
アスキーモードによるjsonファイルの破損。

Filezillaの設定画面で転送形式を「バイナリ」にすることで解決。

アスキーモードだと、改行コード部分で修正が入ってしまうようで、今回はそれがjsonデータの破損につながってしまっていた。
絵で分かる git push --force-with-lease

## git push --force-with-lease の仕組み

`git push --force`の代わりに安全な`git push --force-with-lease`を使おうとよく言われるが、内容をいまひとつ理解していなかったので絵に描いた。

![force_with_lease1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92354/4dc2e411-2dd3-19fd-4da0-f4c71f8b5c2b.png)


## git push --force-with-lease は絶対安全ではない

ただし以下のように他人が追加のコミットをした状態でも、`git push --force-with-lease`が成功して、他人の追加コミットを消してしまうことがありえる。
`git push --force-with-lease` は絶対安全**ではない**。
![force_with_lease2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92354/3b167811-a9ee-c3b0-b461-51f2ddaa01d6.png)
【Vue × Firestore】ログイン後、認証済みのマイページに遷移させる。


#ログイン後、認証済みのマイページに遷移させる。

```html:signin.vue
<template>
  <div>
    <Header />
    <div class="signin flex">
      <div class="signin-inner flex">
        <h2>ログイン</h2>
        <input type="text" placeholder="Email" v-model="email" />
        <input type="password" placeholder="Password" v-model="password" />
        <button class="btn" @click.prevent="signIn">ログイン</button>
        <p>
          アカウントをお持ちでない方は
          <router-link to="/signup">こちらへ</router-link>
        </p>
      </div>
    </div>
  </div>
</template>
```

```javascript:signin.vue
<script>
import firebase from "firebase";
import Header from "@/components/header.vue";

　　~ 省略 ~

export default {
  name: "Signin",
  data() {
    return {
      email: "",
      password: "",
    };
  },
  components: {
    Header,
  },
  methods: {
    signIn() {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
        .then((res) => {
          //ログイン時に取得したemailとpasswordを引数であるresに渡す。
          this.$swal("ログインに成功しました。 ", {
            icon: "success",
          });
          this.uid = res.user.uid;
          //this.uidに 「res.user.uid;」を格納
          return (
            firebase
              .firestore()
              .collection("users")
              .doc(res.user.uid)
              //usersのドキュメントを参照して、上記で引数として受けたresのuid取得
              .get()
          );
        })
        .then(() => {
          this.$router.push(`/mypage/${this.uid}`);
        })
        .catch(() => {
          this.$swal("ログイン情報が間違っています。", {
            icon: "error",
          });
        });
    },
  },
};
</script>
```

まずfirebase.auth().signInWithEmailAndPassword(this.email, this.password)で
ログイン時に取得したemailとpasswordをresという引数に渡してます。

```javascript:signin.vue
    signIn() {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
        .then((res) => {
          //ログイン時に取得したemailとpasswordを引数であるresに渡す。
          this.$swal("ログインに成功しました。 ", {
            icon: "success",
          });
```

usersというコレクションを参照して、上記で取得したresから「uid」を取得して
get()を使ってuidデータをFirestoreから取得。

```javascript:signin.vue
     return (
            firebase
              .firestore()
              .collection("users")
              .doc(res.user.uid)
              //usersのドキュメントを参照して、上記で引数として受けたresのuid取得
              .get()
          );
```

ページを遷移させる為に一度this.uidに 「 res.user.uid;」を格納してから
${this.uid}として対象ページに遷移させています。

```javascript:signup.vue
          this.uid = res.user.uid;
          //this.uidに 「res.user.uid;」を格納

         ~ 省略 ~

        .then(() => {
          this.$router.push(`/mypage/${this.uid}`);
        })
```
Android 12 DP 3で追加されたSplash screenの挙動を見てみる

Android 12 で新たに Splash screen の API が登場したので、どのような挙動で何ができそうか書いていきます。

※ Android 12 はこの記事を書いている 2021/4/30 時点で DP 3 なので、おそらく API 自体にも変更が入るはずです。今すぐに対応が必要というわけではないのですが、今後の動向は気にしておきましょう。

## [2021/7/1 追記] AndroidX　にバックポートのライブラリがリリースされました

https://developer.android.com/jetpack/androidx/releases/core#core_splashscreen_version_100_2


## Android 12 では強制的にスプラッシュが表示される

- DP 3 時点では targetSDK のバージョン関係なく Android 12 でアプリを起動すると Splash screen が表示されるようになっています
- そのため既存のアプリを Android 12 DP3 で起動させると Splash screen が表示されます

https://twitter.com/NabeCott/status/1385071525695418370?s=20

- DP 3 時点ではこれを無効にする記載がありません  
(見落としているかもなので、見つけた方がいればコメントお願いします :pray: )
- 既存アプリでスプラッシュの画面を独自に実装している場合は 2 回続けてスプラッシュの画面が表示されることになります


## Splash Screen の API でアプリの初期化処理は可能

- スプラッシュが出ている間に初期化処理を行い、初期化処理が終わればスプラッシュを閉じるという処理は以下のようなコードで可能です。

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check if the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready; start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content is not ready; suspend.
                    false
                }
            }
        }
    )
}
```

- ただこの処理は Android 12 だけで使うことになるので、Android 12 までのバージョンでは別途スプラッシュ用の画面を用意することになります
(Jetpack でなんとかならないだろうか…)


## アイコンと背景色と Splash screen を閉じるときのアニメーションをカスタマイズ可能

- Splash screen のデフォルトの背景色は `android:windowBackground` が適用される
  - `android:windowBackground` を変更するとアプリの他画面の背景色にも影響があるので、Splash screen だけ背景色を変えたい時のために `android:windowSplashScreenBackground` の属性が追加されている
- `android:windowSplashScreenAnimatedIcon` でアニメーション付きのアイコンを設定できたり、(デザインガイドラインでは推奨されていないが)`android:windowSplashScreenBrandingImage` でスプラッシュの下にも画像を表示させることができる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/22de9736-ac7f-662e-53f6-e268cc6cee8c.png" width="200px" />


- Splash screen を閉じる時のアニメーションもコードでカスタマイズできる  
https://developer.android.com/about/versions/12/features/splash-screen#customize-animation

## ドキュメント
- https://android-developers.googleblog.com/2021/04/android-12-developer-preview-3.html
- https://developer.android.com/about/versions/12/features/splash-screen
【Vue × Firebase】動的ルートマッチング「this.$route.params」について


#動的ルートマッチング「this.$route.params」について

公式サイト：[Vue Router 動的ルートマッチング](https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html#%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%E5%A4%89%E6%9B%B4%E3%81%AE%E6%A4%9C%E7%9F%A5)

「this.$route.params」は現在のURLのパラメータを取得する際に使用します。

##現在のページが、/signup の場合

現在のURLのパラメータに取得する値がない為、router.params.uidの値は「undefind」なります。


##現在のページが、/mypage/hoge の場合

現在のURLのパラメータを取得する為、router.params.uidの値は「hoge」になります。
Rail6 + Bootstrap v5.0-beta3のメモ

# 環境
    rails (6.1.3.1)
    webpacker (5.2.1)
    "bootstrap": "^5.0.0-beta3",

## 僕の場合
1. bootstrapはyarn(package.json)で管理
2. StylesheetはAssets pipelineに任せる
3. JavaScriptはWebpack(er)に任せる

## 手順
```
# 1.
$ yarn add bootstrap@next @popperjs/core

# 2. CSSをAssetPipelineにぶちこむ
$ vi config/initializer/assets.rb
# node_modulesがAssetの検索パスに入っているのを確認
Rails.application.config.assets.paths << Rails.root.join('node_modules')

# ここにファイル作ればデフォルトでapplication.cssで読み込まれる
$ vi app/assets/stylesheets/bootstrap_loader.scss
@import 'bootstrap/scss/bootstrap.scss';

# 3. JSをWebpackerでコンパイル
$ vi app/javascript/packs/application.js
import "bootstrap"
```


## memo
- Webpacker v6からフォルダ構成変わるって聞いた気がするので要注意(要確認)
- CSS/SCSSもWebpackerにぶち込みたいけど現状コンパイルが都度走って遅いっぽい
    - 設定変更できないのか？
【Heroku】サブドメインを使ってhttps対応

サブドメインでのssl対応に苦戦しました。
うまくいった方法を記録しておきます。

## 設定したい内容
```zsh
# herokuアプリのデフォルトのドメイン
mydomain.herokuapp.com
# 設定したいサブドメイン
hogehoge.mydomain.com
```

## 手順
### Heroku側にドメインを追加
```zsh
$ heroku domains:add hogehoge.mydomain.com
```

### HerokuのプランをHobbyプランに変更
Heroku管理画面から設定。
無料のプランだと、カスタムドメインのSSL化ができないようです。

### SSLの有効化
`Herokuの管理画面` > `Settings` > `SSL Certificates`からSSLを有効化

### DNSターゲットの確認
まずはHerokuの管理画面で、DNSターゲットを確認。(`Settings` > `Domains`)
![ 2021-04-30 19.53.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/2f141314-f820-a165-c1dc-bf8a11efb26e.png)
末尾が`.herokudns.com`で終わるやつです。

### CNAMEレコードの設定
(お名前.comとかの管理画面から)ドメインのDNS設定で、CNAMEレコードに先ほど確認したDNSターゲットを設定。

```
CNAME  hogehoge  hiogehioerheefoiefjerrrfe.herokudns.com
```
設定が反映されるまで数時間待つ。

### http→httpsにリダイレクト
今回Railsアプリを動かしていたので、production.rbの設定をいじって対応。

```config/environments/production.rb
config.force_ssl = true
```

## ハマったポイント
当初CNAMEレコードにherokuのデフォルトのドメインを設定していて、httpだと動くのにhttpsだと`NET::ERR_CERT_COMMON_NAME_INVALID`のエラーが出てしまって戸惑いました。

## 参考
https://support.dnsimple.com/articles/heroku-error-ssl/

https://devcenter.heroku.com/ja/articles/understanding-ssl-on-heroku

http://kayakuguri.github.io/blog/2017/01/05/heroku-custom-domain/
マインドマップでAWSのデータ分析サービスを勉強【データ収集編】第１回 − Kinesis Data Stream

AWSのデータ分析系のサービスを体系的に学ぶため、UdemyのAWS Certified Data Analytics Specialty 2021 - Hands onコースを受けました。

一般的なデータ分析流れに含まれるステップ、データ収集、データ保存、データ処理、データ分析、データ可視化に、それぞれが利用するサービスを学び、マインドマップに整理しました。

元々データ取集編を全て１つのマインドマップに整理したかったが、
サービスの利用には、Kinesis Data Streamだけでも把握しないといけないポイントが沢山ありました。。。

そのため、データ分析編は２回に分けてまとめたいと思います。
１．AWS Kinesis Data Stream
２．AWS Kinesis Data Firehose, SQS, IoTなど

今回はKinesis Data Streamのまとめです。

※ こちらの記事は、[AWS クラウドサービス活用資料集](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)と[Udemy](https://www.udemy.com/)にあるAWS Certified Data Analytics Specialty 2021 - Hands onというコースを参照しております。

![AWS Data Collection Services - Kinesis Stream.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544279/868e8956-ec45-8437-e37c-bae64febc485.png)
iptablesでロードバランサー機能を簡単に実現

# 概要
linux iptablesコマンドでロードバランサー機能を簡単に実現する。

```
#パータン①：remoteからfront serverのポート3000にアクセスする場合
client pc ---> front server(port 3000) ---> backend server(port 80)
                                  |-------> backend server(port 81) 

#パータン②：front serverからローカルのポート3000にアクセスする場合
front server(port 3000) ---> backend server(port 80)
                   |-------> backend server(port 81)      
```
#環境
**AWS EC2 VM（Debian） ２台**
**・front server**
public ip: 18.183.27.124
private ip: 172.31.11.10

**・backend server**
public ip: なし
private ip: 172.31.8.4


#設定手順
## front server設定
・**IP forwardを有効にする**

```
admin@ip-172-31-11-10:~$ cat <<EOF | sudo tee /etc/sysctl.d/ipforward.conf
> net.ipv4.ip_forward=1
> EOF
net.ipv4.ip_forward=1
admin@ip-172-31-11-10:~$ 
admin@ip-172-31-11-10:~$ sudo sysctl --system
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/ipforward.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.d/protect-links.conf ...
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.conf ...
admin@ip-172-31-11-10:~$ 
```
・**iptablesにルールを追加する**

```
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
#又は、
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.31.11.10

#パータン①
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 3000 -m statistic --mode random --probability 0.5 -j DNAT --to-destination 172.31.8.4:80
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 3000 -j DNAT --to-destination 172.31.8.4:81
#パータン②
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A OUTPUT -p tcp --dport 3000 -m statistic --mode random --probability 0.5 -j DNAT --to-destination 172.31.8.4:80
admin@ip-172-31-11-10:~$ sudo iptables -t nat -A OUTPUT -p tcp --dport 3000 -j DNAT --to-destination 172.31.8.4:81
```

## backend server設定
ポート80と81をlistenできれば、httpdやnginxなど、何でもいいです。

```
# terminal #1
admin@ip-172-31-8-4:~$ sudo nc -lnv -p 80 < index.html
listening on [any] 80 ...

# terminal #2
admin@ip-172-31-8-4:~$ sudo nc -lnv -p 81 < index2.html
listening on [any] 81 ...
```

#検証手順

```
#パータン①
~ 🍀  > curl 18.183.27.124:3000
<html>
<h1>say hello!</h1>
</html>
^C
~ 🍀  > curl 18.183.27.124:3000
<html>
<h1>say hello 2!</h1>
</html>
^C
~ 🍀  > 

#パータン②
admin@ip-172-31-11-10:~$ curl 172.31.11.10:3000
<html>
<h1>say hello!</h1>
</html>
^C
admin@ip-172-31-11-10:~$ curl 172.31.11.10:3000
<html>
<h1>say hello 2!</h1>
</html>
^C
# DNATを実施しますので、何のIPアドレスでもOKです。（除外：localhost,127.0.0.1）
admin@ip-172-31-11-10:~$ curl 1.2.3.4:3000
<html>
<h1>say hello 2!</h1>
</html>
^C
admin@ip-172-31-11-10:~$
【Javscript】async/awaitを試してみたーasyncについて（No.1）

# 初めに
非同期処理のpromiseを学習したら、asyncとawaitというものが出てきたのでそれについて学習した内容を書いてみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

前回の記事：https://qiita.com/redrabbit1104/items/02bc16cf5abd4ed10ec1
https://qiita.com/redrabbit1104/items/b8b61a72f849fa3e8881

# asyncはpromiseを返す
async functionは戻り値としてpromiseを返す非同期関数です。普通の関数と何が違うのかasync functionとfunctionをそれぞれconsole.logで表示してみました。

```javascript
//asyncの場合
async function testAsync() { }
console.log(testAsync());

//普通の関数
function test() { }
console.log(test());
```
結果は以下の通りです。
![スクリーンショット 2021-04-30 8.11.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/2f6ce08c-3728-b577-6ee5-8cc7171f439d.png)
関数の中身が何もないので同じく「undefined」という戻り値が返ってきましたが、asyncの場合「Promise」が返ってきました。

# asyncの戻り値promiseはresolveかrejectどちらか
asyncの戻り値はpromiseということは分かりましたが、正常に処理ができた場合とそうでない場合にちゃんとresolve(処理成功）とreject(処理失敗）が戻ってくるのでしょうか。気になったので試してみました。

❶async関数の処理がresolve(成功）した場合
文字列helloを戻り値にするtestAsync関数を定義して、console.logで表示してみました。

```javascript
async function testAsync() { return 'hello'; }
console.log(testAsync());
```
戻り値"hello"とPromiseの状態が「fulfilled」と表示されました。
![スクリーンショット 2021-04-30 18.48.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/d0e3981e-d78c-d482-6413-a585595aa317.png)

❷async関数の処理がreject(失敗）した場合
処理が失敗するケースを作るために、returnの値をhelloという定義していない変数にしてみました。

```javascript
async function testAsync() { return hello; }
console.log(testAsync());
```
処理が失敗しrejectedと出ました。予想通りです。
![スクリーンショット 2021-04-30 18.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/f07eea60-512b-c753-a772-6a779ccf9eeb.png)
このようにasyncはpromiseを返し、resolve（成功）かreject（失敗）のどちらかのstateを返すことが分かりました。

# promiseの代わりにasyncが使われる理由
①asyncの中でしか呼び出すことができないawait構文を使うことで、promiseのthenで処理を繋げるより簡潔に書ける。
②awaitで指定した関数は実行される時間を決めて呼び出すことができる。

#終わりに
今回はasyncについて学習して内容を纏めてみました。次回はawaitを使ったasync関数をいろいろ試してみたいと思います。

# 参考サイト
https://qiita.com/soarflat/items/1a9613e023200bbebcb3
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
https://ja.javascript.info/async-await
失敗のあるイニシャライザ


# 失敗のあるイニシャライザとは ????

失敗のあるイニシャライザとは、引数が誤っていたり、データの形式が間違っていたりした場合、
**インスタンスの代わりにnilを返す**ことによって以上を知らせる機能のことです。
通常のinitに?をつけて記述します。

例えば、構造体Humanで、nameプロパティに長さが５以上の引数が入力された場合、イニシャライザを失敗させてみましょう。

# 失敗のあるイニシャライザの定義
```swift:init.playground
struct Human {
  
    var name: String!
    
    init?(_ name: String) {
        guard name.count < 5 else { 
            print("イニシャライズ 失敗")
            return nil 
        }
        self.name = name
        print("イニシャライズ 成功")
    }   
}
```

initのあとに?がついているのがわかります。
そのあと、「nameの長さが5以上」のときに、return nilしていることがわかり、これこそがイニシャライザの失敗が実装されている部分です。
逆に、「nameの長さが5未満」のときは、self.name = nameで、適切にプロパティに初期値が格納されます。



# インスタンス化
では実際にインスタンス化してみましょう

```swift
let human1 = Human("hogehoge")
print(human)
// >>イニシャライズ　失敗
// >>nil
```
この例だと引数nameに５文字以上の値が入力されるため、guard文に引っかかり失敗します。


```swift
let human1 = Human("ken")
print(human)
// >>イニシャライズ　成功
// >>Optional(__lldb_expr_21.Humans(name: Optional("ken")))
```

この例だと引数nameに５文字未満の値が入力されるため、適切に初期化されます。これが失敗のあるイニシャライザの機能でした！

<br>
<br>
<br>

余談：詳細swiftって本読みやすくて面白いですよ
【PHP】API実行ツールを作ってみよう(その3)

#はじめに
PHPでツール作成の5回目です。
前回のAPI実行ツールでは主にテキストデータ(クエリパラメータ)の送受信を行いましたが、
今回は添付ファイルを用いた送受信ツールを作成したいと思います。

#クライアント
クライアント側は[ツール作成の1回目](https://qiita.com/noji505/items/0ec1e4c50d3ed43958c6)で使用した
Chrome拡張機能の[Talend API Tester](https://chrome.google.com/webstore/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm) を使用します。
インストール方法や基本的な使い方などは[1回目](https://qiita.com/noji505/items/0ec1e4c50d3ed43958c6)の記事を参照下さい。

1.以下のようなファイルを作成します(CSV形式)
![qiita_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/c0361a50-280d-9742-53fe-89e17f4cfe2a.png)

2.Talend APIの設定を以下のように行います。
![qiita_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/911d39b8-c67e-ad67-c67e-b4f4d3129ff5.png)

①POSTを選択します
②アクセスするURLを指定します
■http\://localhost/api_temp/server.php?fname=test.csv
③送信データを指定します
■今回はファイルをアップロードするので、「Text」→「File」に変更します
④アップロードするファイルをドラッグ＆ドロップします
⑤送信ボタンを押します


#サーバ
クライアントの準備は出来たので、続いてサーバ側を作成していきます。
1.「<b>c:￥xampp￥htdocs</b>」フォルダに「<b>api_temp</b>」フォルダを作成します
![qiita_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/6e5fe6d1-527f-4a39-7b03-92dfd2110798.png)

2.上記のフォルダ内に「<b>file</b>」フォルダを作成します
![qiita_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/53eea2c2-f736-8599-e4fa-e329c8dea3db.png)

3.「<b>api</b>」フォルダ内に「<b>server.php</b>」ファイルを作成します
中身は下記になります

```php:server.php
<?php
$saveFolderName = "./file";

// リクエストパラメータチェック
if( !isset($_GET['fname']) ){
    echo "エラー:リクエストパラメータにファイル名が指定されていません。";
    return;
}
$fname = $_GET['fname'];

// ファイル名拡張子チェック
$fileNames = explode( ".", $fname );
if( count($fileNames) <= 1 ){
    echo "エラー:リクエストパラメータにファイル名が指定されていません。";
    return;
}
$extName = $fileNames[1];
if( $extName != 'csv' ){
    echo "エラー:ファイル名の拡張子が不正です。";
    return;
}

// ファイル保存
$params = file_get_contents('php://input');
if( strlen($params) <= 0 ){
    echo "エラー:ファイルが不正です。";
    return;
}

$outputFile = "".$saveFolderName."/".date("Y-m-d_His")."_".substr(explode(".", (microtime(true) . ""))[1], 0, 3).".".$extName."";
file_put_contents( $outputFile, $params );

// レスポンス
echo "Success";
?>
```
#コード解説
- 5～22行目・・クライアントからのリクエストデータのエラーチェックを行っています。
- 24～32行目・・クライアントからの送信データを取得し、ファイルへ保存しています。
- 34～35行目・・クライアントへレスポンスを返しています。

#クライアント動作確認
・「<b>Send</b>」ボタン押下後、画面下のResponseに「<b>200 OK</b>」が表示されていて、
右下の「<b>BODY</b>」に「<b>Success</b>」と表示されていれば成功しています
![qiita_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/249d7fa9-4730-07c7-b367-f1d00977608d.png)

#サーバ動作確認
1.実行日時のファイル名で<b>CSVファイル</b>が作成されていることを確認
![qiita_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/ec0001c9-148e-4a17-9a53-0eb7fb8f3477.png)

2.CSVファイルを開き、クライアントから送られたファイル内容と一致していることを確認
![qiita_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/39a99e53-372b-060a-77e8-b95bbaf1b169.png)

#最後に
実際の業務では今回のようなファイルがAPI経由で送られてきて、その内容を保存するといったことが結構あるかと思います。
またファイル送信は別会社が担当し、自分はデータ受信(今回のPHP側の部分)を担当するといったケースも良くあるので、
特にエラーチェック(<b>ファイル名</b>、<b>ファイル形式</b>、<b>データの中身</b>など)は厳密にし、エラーが発生した際にどちら側に原因があるのか？を特定し易くしておくと良いと思います。
次回は、クライアント部分をPHPを使って作成したいと思います。
Basic認証について


環境変数を利用する
-

GitHub上の公開リポジトリでソースコードを管理している場合、コードを読める何者かに、不正にBasic認証を突破されてしまいます。その対策として、コードに直接ユーザー名とパスワードを記述するのではなく、環境変数を利用する実装に切り替える方法があります。

環境変数はzsh、またはbashの設定ファイルに記載します。

 zsh（ズィーシェル）
-

「zsh」はログインシェルと呼ばれるもので、プログラムを実行する時に、ユーザーの要求に一番最初に対応する役割を担います。隠しファイルなので、特別な設定なしではFinderなどには表示されていません。環境変数を記載する場所は、設定ファイルである「.zshrc」の中です。

 bash（バッシュ）
-

「bash」とは、zsh同様、ログインシェルの1つです。zshとの違いは、OSがCatalina以降であれば「zsh」、Mojave以前であれば「bash」が自動で適用されます。環境変数を記載する場所は、設定ファイルである「.bash_profile」の中です。

これらの設定ファイルは、vimというコマンドを用いて編集します。

 vim（ヴィム）
-
「vim」とは、サーバー上で使用できるテキストエディタです。vimコマンドを用いることで、指定したファイルの編集をターミナルから行うことが可能です。
以下が使用例になります。

【使用例】

```rb:terminal
% vim ~/.zshrc  
```

vimには
「通常モード」と「インサートモード」があります。
通常モードは、コマンドを打つことでファイルを保存したりvimを終了したりできます。
「通常モード」のコマンドには以下のようなものがあります。

|コマンド|説明|
|:--|:--|
|:w|作成・編集したファイルを保存します。|
|:q|viコマンドを終了します。|
|:q!|編集した内容を保存しないでviコマンドを強制終了します。|
|:wq|編集した内容を保存してviコマンドを強制終了します。|

インサートモードは、ファイルに編集を加えることができます。この場合、「i」キーを押すことで「insert（インサート）モード」になり、文字の入力が可能です。ファイル編集後は、Escキーを押すと「通常モード」に戻ります。

ファイル編集後は、sourceコマンドを実行する必要があります。

###手順①
以下のコマンドを実行してください。

```rb:ターミナル
% vim ~/.zshrc
```

###手順②

「iキー」を押して、インサートモードに移行しましょう。
ターミナルの左下に「INSERT」と表示されたら成功です。


###手順③
zshの内部に、以下の記述を追加しましょう。

```rb:ターミナル
export BASIC_AUTH_USER='admin'
export BASIC_AUTH_PASSWORD='2222'
```

###手順④
記述を追加したら「escキー」を押して、 「:wq」と入力しましょう。入力後、「Enterキー」を押して終了します。

###手順⑤
最後に、「sourceコマンド」を実行しましょう。

```rb:ターミナル
% source ~/.zshrc
```
Composerコマンドまとめ

## はじめに
PHPで開発をしていたら使うであろう `Composer` についてまとめました。

## 目次

- 前提知識
    - Composer
    - composer.json
    - composer.lock

- コマンド
    - composer init
    - composer install
    - composer update
    - composer require
    - composer remove

- オプション
- 参考文献

## 前提知識

前提知識として以下のことを理解する必要があります。

### Composer

***依存関係にあるライブラリ( パッケージ )を管理してくれるツール*** のこと。

### composer.json

プロジェクトで使用されているパッケージを定義している。

### composer.lock

依存するパッケージのリストが記載されていて、バージョンをロックしている。

## コマンド

### "composer init"

```
composer init
```

**「composer.json」** を生成するために使用するコマンド。
プロジェクトの一番はじめに使用するものなので使用頻度はあまり高くありません。

### "composer install"

```
composer install
```

**「composer.lock」** に書いてある内容を読み依存関係をインストールする。
`composer init` コマンド直後( 初回 )は **「composer.lock」** が生成されていないはずなので **「composer.json」** の内容が読まれ**「composer.lock」** が生成される。
初回は **install** コマンドを使い二回目以降は **update** コマンドを使用する。

※ 新しいパッケージを導入するときは別コマンド( `composer.update` か `composer require` )を使用します。

### "composer update"

```
composer update
```

**「composer.json」** の内容をもとに **update（ 更新 ）** する。

注意が必要で **「composer.lock」** の内容も **update** されるということ。複数人で開発していると、パッケージのバージョンに差異が出て開発した機能にバグが出てしまう恐れがある。

これを防ぐためにも **update** を使用するときは確認をリーダーに確認を取る、もしくは、パッケージを追加するときは `require` コマンドを使用すると良いかもしれない。(あくまで個人的見解なのでチームのルールがあれば従ってください)

### "composer require"

```
composer require [パッケージ名]

# 例えば
# PHPMDを追加
composer require "phpmd/phpmd=@stable"
```

パッケージを追加したいときに使用するコマンド。

### "composer remove"

```
composer remove [パッケージ名]

# 例えば
# PHPMDを削除
composer remove "phpmd/phpmd"
```

パッケージの削除をしたいときに使用するコマンド。

## オプション

コマンドの最後に `--dev` をつけると **「composer.json」** の ***"require-dev"*** に読み込ませたり追加できたりすることができる。***"require-dev"*** とは開発環境で使用している使用したいパッケージが定義されているということ。

他にもオプションはあるのでドキュメントを一度は覗いてみるとよいかもしれません。


## 参考文献

- [composer install](https://getcomposer.org/)
- [Composerの使い方](https://qiita.com/sano1202/items/50e5a05227d739302761)
- [composer install と composer updateの違い](https://qiita.com/YusukeHigaki/items/47dd3ec23544225f7301)
- [composer.json と composer.lock、install と update の違い](https://blog.apiless.com/2019/07/06/composer-install-update/)
【React】Material-UIで導入したコンポーネントのカラー変更方法

<h2>Material-UIの色</h2>
Material-UIでボタンやアプリバーなどを手軽に導入できますが、そのまま導入するとデフォルトの色で配置されます。

アプリによってはデフォルトとは違う色合いでコンポーネントを使いたい場合があると思います。

今回はデフォルトから指定の色に、コンポーネントの色を変更する方法について書いていきます。

<h2>実装方法</h2>
いきなりですが実装方法です。
今回はアプリバーの「基本的な検索フィールド付きApp Bar」を使用します
デフォルトは下記画像になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/d8f48cdc-f637-9ff5-13fb-efa9925396fa.png)

基本的に青色を基調とし、数字は赤色になっています。

このコンポーネントのコードに、そのままコンポーネントのcolorをredにしてもコンポーネントの色は変わりません。

コンポーネントの色を変えるには、
1.createMuiThemeを定義して、色を定義する
2.上記で定義したcreateMuiThemeをthemeとして親要素の引数で渡す
上記2点をする必要があります。
下記のようになります。

```react:APP.js
import React from 'react';
import PrimarySearchAppBar from "./component/MaterialUIHead";
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';

//primaryとsecondaryで、色を指定します
const myTheme = createMuiTheme({
  palette: {
    primary: {
      main: "#9c27b0",
    },
　　secondary: {
      main: "#76ff03",
    },
  },
});

function App() {
  return (
    //PrimarySearchAppBarの親要素にThemeProviderを配置し、themeに上記で定義したmyThemeを渡します
    <ThemeProvider theme={myTheme}>
        <PrimarySearchAppBar></PrimarySearchAppBar>
    </ThemeProvider>
  );
}

export default App;
```

上記コードを適用すると、下記のようになります。
今回はPrimaryに紫、secondaryに黄緑色を指定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/9a1d23a5-10da-180a-16dd-3585fb388dd2.png)

<h2>色について</h2>
ちなみに、任意の色の16進数を下記で定義できます。
Material-UI Playground
https://material-ui.com/ja/customization/color/#playground

<h2>参考</h2>
Material-UI コンポーネント内のテーマへのアクセス
https://material-ui.com/customization/theming/#accessing-the-theme-in-a-component

Material-UI基本的な検索フィールド付きApp Bar
https://material-ui.com/ja/components/app-bar/#app-bar-with-a-primary-search-field

Material-UI Playground
https://material-ui.com/ja/customization/color/#playground
seedを使って、DBにデータをインポートする

# seedファイルとは

seedファイルは、初期データをDBに入れる時に使うファイルのことです。
何かのアプリを作成する場合に、作成したDBにデータ（ユーザ登録データなど）を入れる際に使います。
１件づついれる方法もあれば、CSVファイルなどでデータをまとめてインポートすることもできるので、何かと重宝するファイルです。
この記事では、私が学習した基本的なseedの使い方とCSVファイルをインポートする方法をアウトプットしていきます。
なお、テーブルの作成やマイグレーションファイルの作成方法などは省略します。
####学習環境
MacOS　BigSur
Ruby 2.6.5
Ruby on rails 6.0.3.6
Mysql 5.6.51

# 基本形
ここでは、「Hansoku」という名前のモデルを作成しており、マイグレーションファイルには、

```ruby:20210416141031_create_hansokus.rb
class CreateHansokus < ActiveRecord::Migration[6.0]
  def change
    create_table :hansokus do |t|
      t.string :hansoku_name,           null: false
      t.integer :damage,                null: false
      t.string :status,                 null: false
      t.timestamps
    end
  end
end
```
と記載しているとします。
そのモデルに対して、カラム名に応じて、保存したい値を`seed.rb`に以下のようにcreateメソッドの引数に保存したい値を定義してあげます。

```ruby:seed.rb
Hansoku.create(
  :hansoku_name => "金テキ", 
  :damage => 100, 
  :status => "動けない"
)
```
この形が基本的な形です。
個別に複数作成する場合は、配列形式にしてやり、

```ruby:seed.rb
Hansoku.create[(
  :hansoku_name => "金テキ", 
  :damage => 100, 
  :status => "動けない"
),(
  :hansoku_name => "目つぶし", 
  :damage => 60, 
  :status => "動けない"
)]
```
などと記載してあげます。


# CSVファイルをインポートする
次に、大量のデータをDBに初期データとして導入する方法として、CSVファイルをインポートする方法があります。
seedファイルにCSVファイルを読み込み、DBにインポートするのです。

```ruby
require 'csv'

CSV.foreach('db/hansoku.csv', encoding: 'Shift_JIS:UTF-8') do |hansoku|
  Hansoku.create(
    :hansoku_name => hansoku[0], 
    :damege => hansoku[1], 
    :status => hansoku[2], 
  )
end
```
標準ライブラリのCSVライブラリを呼び出し、`.foreach`メソッド[foreachメソッドについてはこちら](https://docs.ruby-lang.org/ja/latest/method/CSV/s/foreach.html)を使用します。
このメソッドは、CSVファイルの各行がブロック変数に渡され、モデルに定義したカラムを「,」区切りのCSVファイルの左から順番に配列の添字で指定することができます。
上記コードで説明すると、

```
:hansoku_name => hansoku[0], 
　　# インポートするCSVファイルの最初のカラムはモデルの「:hansoku_name」へ
:damage => hansoku[1], 
　　# インポートするCSVファイルの２番目のカラムはモデルの「:damage」へ
:status => hansoku[2] 
   # インポートするCSVファイルの３番目のカラムはモデルの「:status」へ
```
といった感じでインポートされることになります。
なお、CSVファイルは指定されていないと文字コードのエンコード方式が`shift-jis`になっているので、エンコーディングが必要な場合は、変換させないとエラーが発生します。

# 最後にこのコマンド

seedファイルに記載した後は、

```
rails db:seed
```
のコマンドを実行してあげると、seedに書かれた内容をDBに反映させることができます。
Azure StorageをCentOSにマウントする

# マウント先ディレクトリ作成

マウント先のディレクトリを作成します。

```
# mkdir /mnt/sample
```

# コマンド

以下コマンドでマウントが可能です。
ストレージアカウント名とkey1名は、Azure Portalから確認しましょう。

```
# sudo mount -t cifs //<ストレージアカウント名>.file.core.windows.net/<ファイル共有名> /mnt/sample -o vers=3.0,username=<ストレージアカウント名>,password=<key1名>,dir_mode=0777,file_mode=0777
```

# 自動マウントする場合
## マウント設定

`/etc/fstab`に設定を追記します。

```
//<ストレージアカウント名>.file.core.windows.net/<ファイル共有名> /mnt/sample cifs,vars=3.0,credentials=/etc/smbcredentials/sample.cred,dir_mode=0777,file_mode=0777
```

## Credentials情報

credentials情報を`/etc/smbcredentials`に作成します。

```sample.cred
# mkdir /etc/smbcredentials
# cd /etc/smbcredentials
# touch sample.cred

# echo 'username=<ストレージアカウント名>' > sample.cred
# echo 'password=<key1名>' > sample.cred

# chmod 600 sample.cred
```

## マウント実行

マウント設定を反映します。
何もメッセージが出なければ成功です。

```
sudo mount -a
```

# 確認

以下のように表示されれば問題なくマウントされています。

```
# df
Filesystem                                            1K-blocks    Used Available Use% Mounted on
/dev/sda2                                              30929148 3779512  27149636  13% /
devtmpfs                                                 462776       0    462776   0% /dev
tmpfs                                                    474920       0    474920   0% /dev/shm
tmpfs                                                    474920   12852    462068   3% /run
tmpfs                                                    474920       0    474920   0% /sys/fs/cgroup
/dev/sda1                                                508580   82188    426392  17% /boot
/dev/sdb1                                               4060864   16380   3818488   1% /mnt/resource
tmpfs                                                     94984       0     94984   0% /run/user/1000
//<ストレージアカウント名>.file.core.windows.net/<ファイル共有名>  10485760      64  10485696   1% /mnt/sample
Djangoの環境構築

#今回実施したこと
仮想環境上にDjangoをインストールした。

# 学んだ知識
仮想環境の構築方法とDjangoを用いたプロジェクトの作成。

# PowerShellによる仮想環境の作成
① WindowでPowerShelを開き、管理者による実行を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/cf92971e-f4e0-4cfb-c17a-801d8deb9345.png)

②作業用のディレクトリをエクスプローラーから作成しておく。
※今回はProgramingというディレクトリを作成しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/01cd3cbb-f9e0-9f0c-f498-556b18085438.png)

③作成したディレクトリにPowerShell上で移動する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/f5f215b9-bb77-2261-17d4-105a69b60412.png)

``` 
 cd C:\Users\Programing
``` 
④以下のコマンドを実行し、仮想環境を構築・立ち上げを実施する。

``` 
python -m venv test
test\Scripts\activate
``` 
仮想環境に入れると先頭に(環境名)で表示される。
※dectivateを入力することで仮想環境から抜けることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/6cc07bf4-d6b3-c6e9-8ad2-4e857d761f98.png)

# djangoのインストール
①以下のコマンドを実行しdjangoをインストールする。
※コマンドに失敗した場合はpipをUpdateする必要があることが考えられる。

``` 
pip install django
``` 

②仮想環境にプロジェクトを構築する。
※今回は「mysite」というプロジェクトを構築する。

``` 
python test\Scripts\django-admin.py startproject mysite
``` 

悩んだポイントでアプリケーションとプロジェクトの概念が存在するが、
1つのプロジェクト内に複数のアプリケーションを構築することができる認識で問題なし。
※アプリケーションの構築は次の記事に記載することにする。

・アプリケーションとは、実際の処理を行うWeb アプリケーションを指します。
　　ex.)ブログシステムや公開レコードのデータベース、単純な投票アプリ

・プロジェクトとは、あるウェブサイト向けに設定とアプリケーションを集めたものです。
一つのプロジェクトには複数のアプリケーションを入れられる。

イメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/098bf738-5fef-6f7d-e4e8-306cb55f3b25.png)

ここまでのディレクトリ構成は以下の通り。

``` 
mysite/
    ├── manage.py
    |
    └──mysite(プロジェクトと同じディレクトリ名)
          |
          ├── __init__.py
          ├── settings.py
          ├── urls.py
          └── wsgi.py
``` 

③サーバを立ち上げる。

``` 
cd .\mysite\
$ python manage.py runserver
``` 

④ブラウザに「http://127.0.0.1:8000 」を入力しアクセスする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952898/ef3540c3-a29e-fe56-277d-5c2a60b785bd.png)
TouchDesignerで外部モジュールがimportできずに苦しんだときのメモ

#TouchDesugnerで外部モジュールがimportできない!!!!
※この記事はメモ感覚で書いているので少々文が荒いところがあるかもしれません。
##問題の概要
TouchDesignerにおいてposenetをimportしようとして、``Python 64-bit Module Path``にそのモジュールが含まれるフォルダを指定しているがmoduleが見つからないと怒られる。
##今回の解決方法
**TouchDesignerの再起動!!**
``Python 64-bit Module Path``は**TouchDesignerを再起動しないと更新されない**そうです。
~~これはひどい~~
これであなたの不具合も解消されることを祈ります...
##参考
[TouchDesignerで外部pythonのライブラリを参照する時には3.5系を指定する]
(https://qiita.com/shks/items/38aa1567f2c5246796e6)
この記事のおかげで治りました!ありがとうございます!