OmniAICreator/Qiita-1.07M huggingface dataset:
【忙しい人のための】Azureの基礎第2部(後編)【Azureにおけるストレージ・データベースサービス】

AzureについてMS Learnで勉強される場合、第2部は2時間40分のラーニングパスになっています。
ここでは、自身の勉強の復習も兼ねて、MS Learn Azureの基礎第2部の要点をまとめておきますので、Azureの情報を素早く知りたいという方の参考になれば幸いです。
自身の勉強の力点を踏まえて記述するので、詳細な情報を得たい方はMS Learnにアクセスください。

本家様

https://docs.microsoft.com/ja-jp/learn/paths/az-900-describe-core-azure-services/

第2部前編はこちら


https://qiita.com/enurinri/items/1dcb08a546059954f986

第3部はこちら

https://qiita.com/enurinri/items/960e2fd90e5d5a896d10

# Azureストレージサービス
## Azure Storage
Azure Storageは、ファイル、メッセージ、テーブル、およびその他の種類の情報を格納するために使用するサービス。
ストレージアカウントを作成すると、BLOB、ファイル、ディスクなどのすべてのAzure Storageデータオブジェクトを格納可能で、ストレージアカウントに保存可能なデータ数は無限、最大容量は500TB.
ストレージアカウント内のデータは、セキュリティで保護され、可用性が高く、耐久性があり、高度にスケーラブル。

## Disk Storage
Disk Storageは、Azure VMのディスク。
サイズとパフォーマンスは多様な種類が存在。

## Azure Blob Storage
Azure Blob Storageは、クラウド向けのオブジェクトストレージソリューション。
大量のデータを格納可能で、リカバリ用のデータを格納することにも適する。
保存するデータファイルの形式に制限が無く、開発者はディスクについての考慮や管理を行う必要がない。
Blob Storageに対してファイルを保存する時はコンテナが必要。

### Blob Storage用のアクセス層
#### ホットアクセス層
頻繁にアクセスするデータを格納することを最適化。

#### クールアクセス層
アクセス頻度は低いが30日以上格納したいデータを格納することに最適。
30日以内にデータを削除するときは追加課金が必要。

#### アーカイブアクセス層
ほとんどアクセスされず180日以上格納したいデータを格納することに最適。
180日以内にデータを削除するときは追加課金が必要。
データの読み取りはアクセスリクエストを出してから最長で数時間必要。

## Azure Files
Azure Filesは、クラウドで、業界標準のサーバメッセージブロックとネットワークファイルシステムの各プロトコルを介してアクセスできる、フルマネージドなファイル共有を提供。
任意のOSに同時にマウント可能。
任意の数のAzure VMが同時にマウントしてアクセス可能。
異なる地域間でAzure Filesによりデータを共有する際は、データを暗号化して転送。
ファイルはURLにより任意の場所からアクセス可能。

# Azureデータベース及び分析サービス
## Azure Cosmos DB
Azure Cosmos DBはNOSQL型のグローバル分散型マルチモデルデータベースサービス。
スループット、待機時間、可用性、整合性を保証する包括的なSLAを提供。
データは抽象化され、データベースを作成するためのAPIとして投影されるので、企業のデータベースがAzure Cosmos DBに移行されても開発者の使い慣れたAPIを使い続けることが可能。

## Azure SQL Database
Azure SQL Databaseは、Microsoft SQL Serverデータベースエンジンの最新バージョンに基づくPaaSでのリレーショナルデータベースエンジン。
高パフォーマンスで99.99%の可用性があり、セキュリティで保護されたフルマネージドのデータベース。
インフラの管理なしに選択したプログラミング言語でアプリやサイトを構築可能。

## Azure Database for MySQL
Azure Database for MySQLは、MySQLのデータベースエンジンに基づくクラウドのリレーショナルデータベース。
アプリの実行は24時間365日継続可能、サーバを35日遡ってリセット可能。
次のような特徴を管理と追加費用なしに利用可能

* 99.99%の可用性
* 従量課金制
* 高々数秒程度で可能なスケーリング
* 機密データの保護
* 自動バックアップ
* 企業レベルのグレードによるセキュリティとコンプライアンス

## Azure Database for PostgreSQL
Azure Database for PostgreSQLは、PostgreSQLデータベース エンジンのコミュニティ版を基盤としたクラウドのリレーショナルデータベース。
特徴は大半がAzure Database for MySQLと一致。
デプロイのオプションは単一サーバかHyperscaleを選択可能。

## Azure SQL Managed Instance
Azure SQL Managed Instanceは、Azure SQL DatabaseではSQL Serverとの互換性得られなかった機能についても、互換性を確保したPaaS。
VMを占有するため、SQL Databaseより利用料は高価。
これ以上SQL Serverとの互換性を求める場合は、IaaSとしてのAzure VM上で標準のSQL Serverを利用する必要がある。

## Azureでのビックデータの分析
### Azure Synapse Analytics
企業向けの**データウェアハウス**とビックデータ分析を組み合わせた高速無制限の分析サービス。
データウェアハウスとは、企業の業務で発生した大量のデータを時系列順に保管したもの。
BI及び機械学習のニーズに合わせてデータを取り込み、管理・提供。

### Azure HDInsight
フルマネージドでエンタープライズ向けで、オープンソースであるビックデータ分析システムApache Hadoopをマイクロソフトにより実装したクラウド分析サービス。
大量のデータを、一括処理し、高いコスト効率を実現可能。

### Azure Databricks
オープンソースであるビックデータ分析システムApache Sparkをマイクロソフトにより実装したクラウド分析サービス。
リアルタイム処理に適し、全てのデータから分析情報を引き出してAIソリューションを構築するのに役立つ。

### Azure Data Lake Analytics
ビッグデータを簡略化するオンデマンド分析ジョブサービス。
クエリを作成してデータを変換し、価値のある考察を引き出すことが可能。
ExcelVBA 1次元配列内に指定した要素が含まれるか調べる関数

配列内に指定した要素が存在するかどうか調べます。
要素が存在すればTrue、そうでなければFalseを返します。

```
'--- 配列内に要素が存在するか調べる ---
Private Function Is_Exist_In_Array(ByVal Item As Variant, ByRef TargetArray As Variant)

    Dim i As Long

    For i = LBound(TargetArray) To UBound(TargetArray)
        If TargetArray(i) = Item Then
            Is_Exist_In_Array = True
            Exit Function
        End If
    Next i

    Is_Exist_In_Array = False

End Function
```
webpack-dev-serverのオプションからcontentBaseが消えた

## 前置き
`webpack-dev-server`のlatest versionがv4になったのを知らずにv3の構成で`webpack.config.js`を書いたところ、`contentBase`オプションが見つからないエラーが起きました。

```javascript:webpack.config.js
module.exports = {
  ...
  // devServer設定
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    ...
  },
};
```

```bash
[webpack-cli] Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'contentBase'. These properties are valid:
   object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, setupExitSignals?, static?, watchFiles?, webSocketServer? }
```

エラーを見たところ、どうやらv3にはあった`contentBase`オプションは
v4ではvalid propertiesから無くなっているようなので書き直す必要がありそうです。

## 修正内容

公式のマイグレーションドキュメント[migration-v4](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md)を参考に修正していきます。

上記ドキュメントによるとv3の`contentBase`オプションは
v4では`static{}`配下の`directory`オプションに変更されたので
以下のように書くことでコンテンツベースを指定することができます。

```javascript
module.exports = {
  // devServer設定
  devServer: {
    static: {
      directory: path.join(__dirname, "dist"),
    },
    ...
  },
};
```

この他にも以下のオプションが`static{}`配下に移動されているため、同様のエラーが出たら確認してみましょう。
>`contentBase`/`contentBasePublicPath`/`serveIndex`/`watchContentBase`/`watchOptions`/`staticOptions` options were moved to `static` option:

## 参考
https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md
AzureADでSAML認証を試す

# 目的と概要
SAML認証の動作確認や属性値の追加や確認を目的とします。
そのために、簡単に認証と属性値の取得ができないか調査したところ、Python3-samlというライブラリにFlaskで動作させるサンプルがあったので、IdPをAzureADとして動作確認した。

## AzureAD(IdP)
AzureのサブスクリプションまたはOffice365のサブスクリプションを作成すると割り当てられるAzureAD Freeが必要です。

1. AzurePortalからAzureADに入ります。
1. エンタープライズアプリケーション
1. 新しいアプリケーション
1. 独自のアプリケーションの作成
1. 任意のアプリケーションの名前を入力
1. ギャラリーに見つからないその他のアプリケーションを統合します（ギャラリー以外）にチェック
1. 作成をクリック
1. エンタープライズアプリケーションとして登録されるのでクリックする
1. シングルサインオンまたは「シングルサインオンの設定 作業開始」ボタンをクリックする
1. SAMLボタンをクリックする
1. 識別子(エンティティID)をhttp://localhost:5000/metadata/ を設定
1. 応答URL(AssertionConsumerServiceURL)をhttp://localhost:5000/?acs を設定
1. ログインURLはSP側のsetting.json内のidpのsingleSignOnServiceのURL値として使用するためメモする
1. AzureAD識別子も同じくidpのentityIdの値として使用するためメモする
1. ログアウトURLも同じくidpのsingleLogoutServiceの値として使用するためメモする
1. 証明書(Base64)をダウンロードする
1. ダウンロードしたファイルをエディタで開き、BEGINとEND行以外の文字列をメモする。この文字列はx509certで使用する
 
## クライアントWebサーバー(SP)
SPは以下の環境で動作確認しました。

* Windows10
* Python3.9
* Flask
* Python3-saml

Python3-samlは[公式サイト](https://github.com/pitbulk/python3-saml)からダウンロードしました。

### SP側のSAMLの設定
python3-saml\demo-flask\samlフォルダのsettings.jsonを編集します。AzureADの設定の際に作成したメモを使用します。

```json
{
    "strict": true,
    "debug": true,
    "sp": {
        "entityId": "http://localhost:5000/metadata/",
        "assertionConsumerService": {
            "url": "http://localhost:5000/?acs",
            "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
        },
        "singleLogoutService": {
            "url": "http://localhost:5000/?sls",
            "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        },
        "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
        "x509cert": "",
        "privateKey": ""
    },
    "idp": {
        "entityId": "<AzureAD EntityID >",
        "singleSignOnService": {
            "url": "<AzureAD SSO Service >",
            "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        },
        "singleLogoutService": {
            "url": "<AzureAD SingleLogout Service String >",
            "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        },
        "x509cert": " <AzureAD_X509_String> "
    }
}
```

### Flask起動
次のコマンドで環境変数にモジュールとオブジェクトを設定して、Flask起動です。

```powershell
FLASK_APP="index:app"
py -3 -m flask run
```


## 動作確認
動作確認はブラウザから実行します。

1. http://localhost:5000 にアクセスする
1. ログインボタンをクリックしてログインする
1. MicrosoftのサインインIDとパスワードを入力しAzureADの設定に応じてMFAになります。
1. サインイン後に属性値が表示されればログイン成功です。

# つまづいたこと
* 必ずインターネットからのインバウンド通信があると勘違いして、AzureAppServiceなどが必須だと思っていた
* そのため、クラウド上で実行しようとしていたがうまくいかなかった
* AppService(Linux)のxmlsec1というPythonライブラリがうまく動かないため実行できませんでした
* AzureADでユーザー割当が必要
ExcelVBA 要素名で一次元配列から要素を削除する関数

この関数を利用するためには、関数「Remove_Item_From_Array_By_Index」を参照する必要があります。

```
'--- 要素名を指定して配列から要素を削除する ---
'--- 同一要素名が複数ある場合は最初の要素が削除される ---
'--- Remove_Item_From_Array_By_Indexの参照が必要 ---
Private Function Remove_Item_From_Array_By_Name(ByRef TargetArray As Variant, ByVal Name As Variant)

    Dim i As Long

    For i = LBound(TargetArray) To UBound(TargetArray)
        If TargetArray(i) = Name Then
            TargetArray = Remove_Item_From_Array_By_Index(TargetArray, i)
        Exit For
        End If
    Next i

    Remove_Item_From_Array_By_Name = TargetArray

End Function
```
【JavaScript】配列のメソッド

#はじめに
こんにちは。
今回は、配列のメソッドの中でも「先頭または末尾の要素を追加/削除するメソッド」に絞ってアウトプットしていきます！

<br>

###pushメソッド（末尾に追加）

```javascript:JavaScript
const numbers = [1,2,3,4];

numbers.push(10);
console.log(numbers);  //[1, 2, 3, 4, 10]
```
pushメソッドは、配列の末尾に要素を追加するので、配列の末尾に`10`が追加されて出力される。

###popメソッド（末尾を削除）

```javascript:JavaScript
const numbers = [1,2,3,4];

numbers.pop();
console.log(numbers);  //[1, 2, 3]
```
popメソッドは、配列の末尾を削除するので、配列の末尾の`4`が削除されて出力される。


###unshiftメソッド（先頭に追加）

```javascript:JavaScript
const numbers = [1,2,3,4];

numbers.unshift(10);
console.log(numbers);  //[10, 1, 2, 3, 4]
```
unshiftメソッドは、配列の先頭に要素を追加するので、配列の先頭に`10`が追加される。

###shiftメソッド（先頭を削除）

```javascript:JavaScript
const numbers = [1,2,3,4];

numbers.shift();
console.log(numbers);  //[2, 3, 4]
```
shiftメソッドは、配列の先頭を削除するので、配列の先頭の`1`が削除されて出力される。

<br>

#最後に
ここまで配列の要素を、追加/削除を実行するメソッドについてまとめました。
こういった記述も使いこなせるように学習を進めていきます！
Xcode12系でiOS15のデバックがしたいんじゃ！(iOS Simulator編)

最近の天気の移り変わりの早さは、どうやら地球が怒っているかららしいです。いや、地球が怒るってなんやねん！
どうもこんにちはTOSHです。

# はじめに
iOS15、そろそろ来ますかねぇ〜。皆さんもiOS15対応に向けて準備をしていると思います。
しかし、恐らく、開発に使用しているXcodeは12系で、本格的に、Xcode13系への対応を行なっている方はさほど多くないと思います。
では、しかし、このままでは、iOS15端末でのデバックを行うことができないでしょう。

# 対処法
では一体どのようにしてデバックを行えば良いのでしょうか？

## 実機編
iOS15のbetaを入れたiPhoneが手元にあるのであれば、使用しているXcode12系にiOS15用のDevice Supportを入れるのが一般的なのではないでしょうか？

## simulator編
しかし、実機をたくさん持っている人はこの方法を取ることができますが、みんながみんなそうとは限りませんよね。そこで今回は、Simulatorを使用して、Xcode12系でiOS15のデバックを行う方法を紹介します。

1. Xcode13 betaをインストールしましょう。
2. 先ほど、インストールしたXcode13からsimulatorのアプリを起動しましょう。Pathは以下の通りになります。
`/Applications/Xcode-beta.app/Contents/Developer/Applications/Simulator`
3. simulatorのアプリを起動させたら、そのまま`File/Open Simulators/iOS 15.0/任意のiOSデバイス`を選択して起動しましょう。

![スクリーンショット 2021-09-05 15.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180994/5fcde154-f9a9-8ddc-04cb-82da10e83724.png)
4. この状態で、Xcode12を開きます。するとこの状態で先ほど開いたiOS15のsimulatorが選択可能になっているので、選択して実行してしましましょう！

![スクリーンショット 2021-09-05 15.18.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180994/18a8bdc5-41ea-27c6-f899-f9dec309a5f5.png)

これで問題なく、Xcode12系でもiOS15のsimulatorでデバックを行うことができます。でバッカーに関してももんだなく使用することができるので、デバックも捗ると思います！

# 最後に
先ほどと同様に、iOS 15系のsimulatorを起動した後に、.appでファイルを生成して、そのファイルをsimulatorへとドラッグアンドドロップするという方法もありますが、この方法ではデバッガーを使用することができないので、上記の方法をお勧めします！

それでは、良い、iOS 15ライフを！
TerraformでAmazon Auroraクラスタを自動構築する(カスタムエンドポイント編)

# はじめに
Amazon Aurora記事第4弾。

Auroraは、デフォルトのエンドポイントとしてリーダー用エンドポイントとライター用エンドポイントを用意してくれている。
しかし、実際には用途に応じてOLTP用とOLAP用のエンドポイントを分けて運用したくなることもあるだろう。

今回は、上記のようなケースに対応するためにOLAP用のエンドポイントを作ってみよう。

ただし、カスタムエンドポイントには「インスタンスを動的に追加することができない」という制約がある。
※詳細は[こちら記事](https://qiita.com/tonishy/items/7279b966ce8ba950f64c)の検証結果を確認いただきたい。
OLAPは動的にインスタンスを増やすというケースは少ないと思うが、AutoScalingしたインスタンスを動的に追加できないのはつらすぎるので、OLTP用にカスタムエンドポイントを作るのは難しいのではないかと思う。

今回の記事も第2,3弾同様、以前の記事で作ったTerraformのHCLに付け加える前提であるため、実際に触ってみる場合はまずは以前の記事から読んでいただきたい。

- [TerraformでAmazon Auroraクラスタを自動構築する(基本編)](https://qiita.com/neruneruo/items/a7c5f7fa80fbf9d6a828)

# バッチ用Auroraインスタンスの作成
バッチ用のAuroraインスタンスを以下のように追加する。

なお、カスタムエンドポイントの本題からは少し外れるが、今回、```promotion_tier = 0```を設定している。これに伴い、リーダーインスタンスは```promotion_tier = 1```以上の値にしておくことで、フェイルオーバーのインスタンスを、バッチ用インスタンスに向けることをできる。
ということで、availability_zone を、ライターインスタンスとは異なるAZにしておくことで、AZ障害にも耐えられるようなフェイルオーバーが可能になる。

```HCL
resource "aws_rds_cluster_instance" "batch" {
  cluster_identifier = aws_rds_cluster.example.id
  identifier         = "${local.aurora_cluster_identifier}-batch-instance"

  engine                  = aws_rds_cluster.example.engine
  engine_version          = aws_rds_cluster.example.engine_version
  instance_class          = "db.t3.small"
  db_subnet_group_name    = aws_db_subnet_group.example.name
  db_parameter_group_name = aws_db_parameter_group.example.name
  promotion_tier = 0

  availability_zone = data.aws_subnet.my_subnet[1].availability_zone

  monitoring_role_arn = aws_iam_role.aurora_monitoring.arn
  monitoring_interval = 60

  publicly_accessible = true
}
```

# カスタムエンドポイントの設定
カスタムエンドポイントの設定には、```aws_rds_cluster_endpoint```のリソースを用いる。

エンドポイントは、```cluster_endpoint_identifier```で指定した値と```.cluster-custom-xxxxxxxxxxxx.[リージョン名].rds.amazonaws.com```を連結した文字で作られる。今回のケースで言えば、```batch.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com```だ。

また、```custom_endpoint_type```を```READER```に設定しておくことで、ライターインスタンスに接続して負荷を上げてしまうことを回避できる。

他のリーダーインスタンスに接続しないように、```static_members```で接続先を固定しよう。

```HCL
resource "aws_rds_cluster_endpoint" "batch" {
  cluster_identifier          = aws_rds_cluster.example.id
  cluster_endpoint_identifier = "batch"
  custom_endpoint_type        = "READER"

  static_members = [
    aws_rds_cluster_instance.example[0].id,
    aws_rds_cluster_instance.batch.id,
  ]
}
```

これで```terraform apply```すると、以下のように、今回作成したインスタンスのみ接続先としてチェックされているようになっている(```aurora-example-cluster-instance-1```が表示されていないのは、ライターインスタンスであるため)

![キャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/89ee08c4-1bd9-7d14-644e-866b9de11e33.png)

前述の通り、バッチ用のインスタンスはクラスタのデフォルトのリーダーインスタンスには含まれてしまっているので、あまり高負荷にすると、OLTPにも影響する可能性があるので、使い方には注意が必要だ。この辺りがもう少し柔軟になってくれると良いのだが……。
小さいサイズの辞書は線形探索でいいかも

# これは何？

C++ で辞書（key-value pair）がほしい場合。

とりあえず `std::unordered_map` か `std::map` を使うと思う。

状況によっては `boost::container::flat_map` を使うこともあると思う。

でも、要素数が少ない場合は線形探索のほうが速かったりするんじゃないの？　と思って測ってみた。

# 登場人物

## std::map

中身は赤黒木。ポインタをたどって要素を探す。

## std::unordered_map

中身は Hashテーブル。ハッシュ値でスロットを特定する。スロット内はよく知らない。

## boost::container::flat_map

中身は整列済みの配列のようなもの。二分探索で要素を探す。
挿入は遅いけど、探索は速いという評判。

## 線形探索

中身は `vector`。先頭から普通に探す。

# 調査内容

キーのバイト数 K、コンテナに入れる要素数 E、試行回数 T を決める。
コンテナを 16個、キーを 16個作る。
作ったキーをキー、値を適当な 64bit整数 にしてコンテナに値を入れる。コンテナに入れる要素数は 16個とも E。
以下の操作を行う時間を測る
合計のための変数 `sum` を用意する

* T 回、以下の操作をする
 * 使うキーとコンテナを乱数で決める
 * 上記で決まったコンテナにキーを渡して値を得る。
 * 得られた値を `sum` に加算する
 
コンパイラは、 Apple clang version 12.0.5 (clang-1205.0.22.11) / x86_64-apple-darwin20.6.0。
コンパイルオプションに `-O2 -std=c++17` を入れている。
ハードウェアは手元の MacBook Pro。
 
# 調査結果

以下グラフは、横軸がコンテナサイズ。縦軸が処理時間（秒）。
対数目盛注意。

![key is uint32 × 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/f84a87d8-a439-4b11-f3ed-4ac980690fe0.png)

![key is uint32 × 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/739ce367-077e-acf4-43a2-5069f03fed55.png)

![key is uint32 × 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/f4d9e261-4d61-02bf-fbb7-2c8092821810.png)

![key is uint32 × 16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/4964a339-31c6-f86d-351c-7fb9b240a956.png)

![key is uint32 × 256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/14a0066f-967b-db5c-81a5-18928f30cbfc.png)

試行回数は key のサイズで適当に変えている。例えば key が uint32 × 1 の場合は 4194304回、key が uint32 × 256 の場合、16384回施行している。

## 感想

グラフを見ると分かる通り、キーのサイズで様子が違う。キャッシュに乗るかどうかが勝負なのかな。

`unordered_map` で、要素数が増えると却って速くなる部分があって謎だけど調べていない。

あと

* キーのバイト数が少ないと線形が有利。
* `unordered_map` が速い。`flat_map` は意外と振るわない。
* キーが 32bit ぐらいで `unordered_map` との比較なら、10〜30 個ぐらいまでは線形有利。
* キーが 32bit ぐらいで `map` との比較なら、30〜100 個ぐらいまでは線形有利。

辺り。
もちろん処理系とかキャッスサイズとか色々で変わるのでこの実験結果の汎用性はあまりないと思う。

この調査では `map` がいまいちな感じだけど、比較がハッシュ値の計算より安いケースでは `map` が圧勝したりするので、ケースバイケースということではある。

# まとめ

存在しないキーで探索する割合とか、キャッシュの効き具合とか、時間に影響を与える条件がたくさんあるので、一般的で公平なベンチマークは存在しないと思う。

要素数が少ないとわかっているときは線形も悪くないなと思ったけど、`std::linear_map` みたいなのがないので実装するとしたら手作りになるからめんどくさい。どっかに作っておこうかな。それとももうどっかにあるのかなぁ。

あと、要素数が少ない場合は線形で、要素数が多くなると Hashテーブルになる、みたいな対応をするといつでも速くなるかもとも思った。うまくやる方法はあるのだろうか。

実験に使ったコードを [github](https://github.com/nabetani/cppmapfindbench) に置いた。
Ubuntu bashのディレクトリ（drwxrwxrwx）の色が見づらい

まず、これを見てほしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/ecc1426b-f560-5e81-8825-81e31bccbf3e.png)

fugaとhogeは、パーミッションが777(drxrwxrwx)なのだが、このときのshell上の色のコントラストが低くてものすごく見づらい。おじさんの弱った視力には辛い。(@-@)

そこで、こう。

https://nisshingeppo.com/post-1043/

```bash
$ dircolors -p > ~/.dircolors 
$ vim !$
```


```
OTHER_WRITABLE 34;42
```

を、

```
OTHER_WRITABLE 36
```

に変更して、再接続。すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13513/0e4d479e-b6d8-9fc2-9c47-7a8658d51be8.png)


こうなる。さっきよりは見やすい(<●><●>)

ここまで書いて、念のためqiitaで調べたら、すでにたくさんの人が同じ記事を出していた。orz=3

でも自分で書いて出さないと忘れるのでゴメンやで。
二週間でも取れる！AZ-104(Azure Administrator Associate)勉強方法

こんばんは。torippy1024です。
先日、AZ-104に合格し、Azure Administrator Associateの資格を取得しましたので勉強方法を書いてみます。
すでに何番煎じのネタかわからないのですが。
(というか、半年前に書いた記事が下書きのままだったことに気づいたので今更公開します。恥ずかしい・・・・・・)

#受験のきっかけ#
以前、バウチャーがもらえる無料オンライン研修に参加し、AZ-900(Azure Fundamentals)を取得していました。
今回もMicrosoftのイベントに参加したところ別のバウチャーチケットをもらえたので、とりあえず上位資格を試しに受けておくか〜落ちても別に構わないし。というノリで受験をしようと思っていました。
期限が3月末だったので、2週間前にダメもとで勉強を開始したところ、受かってしまった・・・・・・というのが本音です。
正直、受かるための勉強しかしていないのでちゃんと身についたかは疑問です。これからちゃんと身につけたいと思います。

#結果#
2021/3/20 テストセンターで受験
(オンラインが良かったが休日に受験しようとしたところテストセンターしか空いてなかったため)
一発合格
スコア：830/900(問題数55問くらい。合格ライン700です)

#合格のための勉強方法#
udemyの~~パクリ~~問題集を丸暗記すれば合格できます。以下に500問あります。ただし英語です。問題被りもあります。
https://www.udemy.com/course/microsoft-azure-administrator-practice-tests/
本番では、上記問題週とは問題の表現が異なったり、そもそも問題の選択肢自体に誤記があったので修正された問題などがあるなど対象の差異はありましたが、選択問題は変わらないものが大部分でした。
ただし長文のケーススタディ問題はあてになりませんでした。ケーススタディは5問程度なので捨ててもたぶん合格できます。
以前の試験であるAZ-103ではラボ試験もあったようですが、私がAZ-104を受験した時は出題されませんでした。(トラブルが多かったようなので廃止されたのかも？？)
2021/3/26に問題のアップデートが行われるらしいので、私が受験したときとは傾向が変わるったかもしれません。効率的な資格取得が目的であれば、その傾向を吸収して問題集がアップデートされた後に勉強するのがいいかもしれません。

#思ったことつれづれ#
英語で試験をやるのは二度目ですが、英語で勉強して、英語で試験を受けるのが受かるだけであれば最も効率がよいです。(日本語で試験を受けると、日本語と英語のAzure用語を両方覚えなければいけなくなる。ただ実務で使う場合は両方知っておくべきなのかも・・・・・・)


『NSGって何だっけ？なんとかセキュリティグループだったような？？』というレベルで勉強を初めて、2週間で合格できてしまいました。(udemy問題集は5回以上やって、正答率は90%後半になっていましたが)実務に活かせるかはとても疑問ですが、資格を取得してAzureに対する興味は増したので時間を作れる方はチャレンジしてみてはいかがでしょうか。
[awk] awkコマンド備忘録(随時更新)

# はじめに
業務でnginx等のログを分析する必要があり、その際に使用したawkコマンドのまとめ


# オプション
## -F:区切り文字の指定
```
-F" " //スペース区切り
-F"\t" //タブ区切り
-F","  //カンマ区切り
```



# 一般的なユースケース

### ログのn列目を出力する
nには実施は$14のように数値を入れる。

```sh
awk -F" " '{print $n}' access.log
```

eg.スペース区切りのログの14列目を出力する

```sh
awk -F" " '{print $14}' access.log
```


### 特定の条件を満たす場合のみ出力する

```sh
awk -F" " '{if(条件式) print 出力内容}' access.log
```

eg.14列目の数値の大きさが0.2を越える時のみ、その列を出力する

```sh
awk -F" " '{if($14>0.2) print $14 }' access.log
```

### 各行の先頭にカウントを付けて出力する
$0は全列表示

```sh
awk -F" " '{count++;print count " " $0 }' access.log
```

### 出力の最後に行数を出力する

```sh
awk -F" " '{count++} END{ print count }' access.log
```

### 特定の日時範囲のログを出力する

```sh
awk -F" " '{
  date = $日付情報を持つ列の番号
  if ( date >= $開始時刻 && date <= $終了時刻) {
      print $0
  }
}' access.log
```

- ログ上で日付と時刻が別の列に出力されている場合

```sh
awk -F" " '{
  date = $日付の列番号" "$時刻の列番号
  if ( date >= $開始時刻 && date <= $終了時刻) {
      print $0
  }
}' access.log
```

- 時刻にミリ秒が含まれるがHH: mm:ssにしたい時(例 14:09:23,187)

```sh
awk -F" " '{
  split($時刻の列番号, arr, ",") #時刻を指定した区切り文字で分割して配列arrに格納する
  date = $日付の列番号" "arr[1] 
  if ( date >= $開始時刻 && date <= $終了時刻) {
      print $0
  }
}' access.log
```

eg.YYYY-MM-DD HH: mm:ss形式で日付範囲を指定した時

```sh
awk -F" " '{
  split($2, arr, ",")
  date = $1" "arr[1]
  if ( date >= "2021-09-03 14:09:00" && date <= "2021-09-04 00:00:00") {
      print $0
  }
}' sample.log
```


# nginx特化のユースケース

## アクセスログのrequest_timeが特定の値を越えている時のみ、行数カウント付きでtailして出力する.(今回は200ms)
※nginx.confで設定されている出力項目の数によってrequest_timeが何列目になるかは変わるので注意。自分の場合は14列目

request_timeは秒単位で出力されるため、200msは0.2。
$4は今回は日付列を指定している。

```sh
tail -F /var2/log/nginx/access.log | awk -F" " '{if($14>0.2) {count++;print count " " $4 " " $14 "s"}} END { print count }'
```
deviseでのストロングパラメータの設定について

そもそもdeviceに誤記しやすい名前ひどいと思う。

#0. なんでこの記事を書いたか
そもそもストロングパラメータがややこしくてよくわからないのに、deviseを用いると余計にややこしくなるので、頭の中の整理のために書きました。

#1. 設定の方法について
deviseを使わないリクエストの場合では、ストロングパラメータはコントローラに記述していた。したがってdeviseを用いる場合でもコントローラに記述すればいいやと思いきや、deviseの処理を行うコントローラはGem内に記載されているので編集不可能。

じゃあどうするべきかとなったら、全てのコントローラーが継承している`application_controller.rb`に記載をすることになる。

#2. deviseにおけるストロングパラメータ
 基本的に通常のストロングパラメータと同じでparamsに対してpermitを指定していく流れになる。が、deviseでのparamsは`devise_parameter_sanitizer`というものが該当する。これを用いてメソッドとして定義すると下記のようになる。

```ruby
def configure_permitted_parameters  # ←deviseの提供元が紹介している名前で、指定ではない
  devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可するキー])
end

# 参考：paramsのやつ
params.require(:モデル名).permit(:許可するキー)
```

permitメソッドの引数がparamsの時のものと異なり、`:deviseの処理名`の記載が必要となる。

この処理名に関しては３つしかないので覚えておきたい。

|処理名|役割|
|:--|:--|
|:sign_in|サインイン処理を行うとき|
|:sign_up|アカウントの新規登録を行うとき|
|:account_update|アカウントの情報を更新するとき　　　　　　|

#3. application_controller.rbの編集について
このストロングパラメータは、deviseに関するコントローラの処理が行われる前に実行されるように設定したい。このため、冒頭にbefore_actionを用いて、事前処理としての設定をする。

```ruby
before_action :configure_permitted_parameters , if: :devise_controller?
             　#↑ストロングパラメータのメソッド名なので任意　↑deviseのヘルパーメソッド
```

`devise_controller?`はdeviseが持つヘルパーメソッドで、deviseに関するコントローラの処理かを判断するもの。
これを用いることによって先に書いたようにdeviseに関する処理の前に事前処理として設定ができる。

#4. まとめ
deviseを用いてユーザー情報の保存などの際に特定のキーのみのやりとりをしたいときにもストロングパラメータを使う。
その際は下記に気をつける。

１）　通常のparamsとは違って`devise_parameter_sanitizer`使って設定する
２）　状況に応じて３つの処理の中から必要な処理を判断する
３）　メソッドの記述はapplication_controller.rbに行う
４）　deviseに関するコントローラの処理の事前に実行されるようにbefore_actionを指定する

これだけ書いてもまだ覚えきらんので、備忘録として。
djangoでウェブアプリを作る(初心者)

# #1 djangoでウェブアプリを作る


## このページの目的

djangoを使って、開発サーバーでhtmlを表示できるようになる
(理解より結果を優先するので、細かい説明は省く)

### 目次

○プロジェクトとアプリとは

・プロジェクトとアプリの作成

○htmlを表示させる

## ○プロジェクトとアプリとは

まずdjangoにおいて、プロジェクトは1つで、アプリは1個～複数個(1つは必須)作ることができる。

・アプリはプロジェクト内の１つの機能のようなもの

・シンプルなプロジェクトならアプリは1つでOK

・プロジェクト(ここでは下の階層のdjango_websiteフォルダ)は全体設定(settings.py、urls.py) 以外はほとんど使わない

### ・プロジェクトとアプリを作る

django_websiteという名前のプロジェクトを作る

```bash
ターミナル
django-admin startproject django_website
```

django_websiteに移動して、websiteという名前のアプリを作る

```bash
ターミナル
cd django_website
python manage.py startapp website
```

websiteあぷり(フォルダ)を登録する

```python:settings.py
#django_website/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'website'
]
```

カッコ内に記述したURLからのアクセスを許可

```python:settings.py
#django_website/settings.py
ALLOWED_HOSTS = ["*"] #「*」は全てという意味
```

## ○htmlを表示させる

まず、websiteアプリにtemplatesフォルダ作成、この中にindex.htmlを作成

```html:index.html
#website/templates/index.html
<h1>Hello World</h1>
```

次にURLを受け取ってから、htmlを表示させるための設定をしていく

index.htmlをユーザーに返すビューを追加

```python:views.py
#website/views.py
from django.views.generic import TemplateView
class IndexView(TemplateView):
    template_name = "index.html"
```

website/urls.pyを作成

ビューとURLを結びつける

```python:urls.py
#website/urls.py
from django.urls import path
from .views import IndexView #同じ階層のview.pyからIndexViewを読み込む
urlpatterns = [
    path('', IndexView.as_view()),
]
```

URLを送られたときに見に行くファイルの指定

```python:urls.py
#django_website/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("website.urls")) #websiteフォルダのurls.pyを読み込む
]
```

---

最後に開発サーバを立ち上げるとindex.htmlが表示される

(ctrl + C で停止)

```python
ターミナル
python manage.py runserver

```
Azure Bot Serviceのみではオウム返しLINE Botが作成できなくなった？

#Azure Bot Serviceの作成
上の検索窓から「Bot Service」と検索し、「サービス」欄から「Bot Service」を選択します。
![search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505689/b92bcdf1-25a6-25e4-512d-4962b781fcf7.png)
「Applied AI Services」画面(下記画像)が開かれます。
上の「作成」ボタン(下記画像の赤枠部分)をクリックします。
![AppliedAIService.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505689/8df7e758-d7e2-d450-4ebf-b7b8a7755145.png)
あれ？「Web App Bot」が無くなってる...
一旦「Azure Bot」(下記画像の赤枠部分)を選択します。
![AzureBotService.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505689/92f60cef-0ee8-6387-1a09-7be7fc795fe9.png)
「作成」ボタン(下記画像の赤枠部分)をクリックします。
![AzureBot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505689/edf273f1-5c4a-c0cd-c450-d6f4a6b9d8e2.png)
以下の項目を入力し、作成します。
あれ？「ボットテンプレート」を選択する欄が無くなっている...

- ボットハンドル
- サブスクリプション
- リソースグループ
- 場所
- 価格レベル
- Microsoft アプリID

作成後の画面でも、「ボットテンプレート」を選択する欄は見当たらない。
つまり、Bot Service単体では、LINE Botが作成できなくなってしまったのではないか？
現状、Web上には解決策は見当たらないため、FunctionsやLogic Appsなどを使用した方が良さそうだ
【超基本データベースの話】PDOクラスとは

#はじめに#
　バックエンドエンジニアを目指されている方にとっては、データベースは必須の知識になります。今回はデータベースの超基本的なお話とPHPで使われるPDOクラスというものについてまとめていきたいと思います。


#データベースとは#
　データベースとはさまざまなデータを保存し、必要な時にすぐに使えるように整理したものです。例えば、ログイン認証や商品情報登録などで使われます。データベースを用いることで、膨大なデータを保存できる上、それらを並べ替えたりグループ化したり必要な形式に加工して取り出すこともできます。

　データベースにも色々種類があるようですが、ここではRDB(リレーショナルデータベース）を取り上げていきます。RDBとは表形式のデータベースで、エクセルのように列と行から成り立っています。列には、どんなデータが保存されてるかを表す”カラム”と呼ばれるものが設定されており、それぞれの行に対応したデータが保存されています。これらの列と行のまとまりを**テーブル**と言います。データベースは通常、複数のテーブルから成り立っています。

##使用例##
　例えば、ショッピングサイトを想像してみましょう。ショッピングサイトにはどのようなデータが必要でしょうか。
　まず、商品のデータを保存しておく必要があるので、**商品テーブル**は必要でしょう。また、買い物をするには会員登録やログインが必要ですので、ユーザーテーブルも必要になると思われます。
　その他にも、購入履歴を保存するテーブルやカートの情報を保存するテーブルなど、さまざまなデータが必要になります。

#RDBMS(Relational Database Management System)#
　RDBMSとは、RDBを実際に操作する際に使われるシステムです。SQLと呼ばれる言語を使って操作します。
　基本的な操作については、以前記事にした[こちら](https://qiita.com/kt103/items/42878f30236364ad2f66)を参考にどうぞ。
　SQLさえ覚えておけば、どんなRDBでも操作できます。

　また、RDBMSにもいくつか種類があります。
・MySQL
・Oracle
・PostgreSQL
・MariaDB
などが挙げられます。

　このようにRDBMSの種類は多岐にわたります。これらがそれぞれ異なる操作方法だとするとどうでしょうか。データベースを変える必要が出てきたときなんかだと結構めんどくさいですよね。
　それを防ぐためにPHPには便利なクラスが用意されています。

#PDOクラスとは#
　それがPDOクラスと呼ばれるものです。
>PHP Data Object (PDO) とはPHPに拡張モジュールとして標準で提供されているデータベース抽象化レイヤであり、各種データベース(DBMS、RDBMS)への接続を抽象化する。

↑(Wikipediaより引用)
　要は、どんなRDBMSでもいい感じに操作してくれるのがPDOだということです。実際にどのように使っていくのか、流れを見てみたいと思います。
　
　PDOを使ってデータベースに接続する際はこのように書きます。

```db_connect.php
 $host = 'localhost';
 $charset = 'utf-8';
 $dbname = 'データベース名';
 $username = 'ユーザー名';
 $password = 'パスワード';
 $dsn ='mysql:dbname='.$dbname.';host='.$host.';charset='.$charset;
 
 try{
   $dbh = new PDO($dsn,$username,$password);
   echo '接続成功';
 }catch(PDOException $e){
   echo '接続失敗' . $e->getMessage();
   exit();
 }
```

　これでデータベースへの接続ができました。PDOクラスをインスタンス化することで接続ができます。クラスとインスタンスについて分からない方は[こちら](https://qiita.com/kt103/items/f4f116d5d8fa13524397)をご覧ください。
　try〜catch構文はデータベース接続処理中に何か異常が発生した際に処理を中断することができます。これを「例外処理」と言います。大切なデータに何かあっては大変ですので、データベース接続をする際は必ず例外処理を行いましょう。接続ができたら次のように書きます。

```db_connect.php
 $sql = 'SELECT * FROM table';
 $stmt = $dbh->prepare($sql);
 $stmt->execute();
 $rows = $stmt->fetchAll();
```

　これも例外処理の中に含めて書いてください。prepareでSQLを準備してexecuteで実行します。fetchAllで取り出した値を$rowsに代入している、という流れになります。こうすることでtableテーブルから全てのデータを取り出すことができます。

　無事にデータベースからデータをとってくることができました。
他にもオプションの設定などができますが、また機会があればまとめていきます。

#まとめ#
　今回は超基本的なデータベースのお話をしてきました。
・データベースとはアプリケーションに必要な様々なデータが保管されている。
・データベースからデータ操作をするのにPHPではPDOクラスというものが用意されている。
バックエンドでは必須の知識になりますのでしっかり覚えておきましょう！
Amazon ES とは

## 勉強前イメージ

ESだとエントリーシートしかわからん・・・

## 調査

### Amazon ES とは

Amazon Elasticsearch Service の略で、
Elasticsearchを簡単にデプロイできるサービスです。
以下が、Elasticserchです。

Amazon ESを利用すると特に構築・運用等に関する箇所が省略可されています。
マネジメントコンソールから数クリックでデプロイ出来ます。
また、OSの準備やアプリケーションのインストール、設定が不要になります。

### Elasticserch とは

`Elasticsearch` とは Elastic社が提供しているLuceneベースのOSSの検索・分析ソフトウェアです。
大容量のデータの中から必要なデータを高速で取り出すことができます。

- 高拡張性

データはshardという単位でデータを保持し、shardごとに複数のノードに分散処理をしています。

- 高可用性

shardはレプリカを持つことができ、リードレプリカに保持することでノードがダウンしても
アプリケーションを継続することが出来ます。

- RESTful API

RESTful APIでの操作が可能です。

- 特徴

RDBMSやデータウェアハウス、NoSQLと比べると複雑な検索ができ、
また高速で実行することが可能です。
ログ集約・監視としては、Cloudwatch Logsとの連携をすることで実施が可能です。

## 勉強後イメージ

初めて知ったサービス。
Elasticsearchもほぼ聞いたことなかったからよくわからんかったけど、
RDSより複雑な検索ができるっていうのが特徴な気がする。

## 参考

- [AWS再入門 Amazon Elasticsearch Service編](https://dev.classmethod.jp/articles/cm-advent-calendar-2015-getting-started-again-amazon-es/)
- [Elasticsearchとは](https://www.designet.co.jp/faq/term/?id=RWxhc3RpY3NlYXJjaA)
PythonでFASTA形式ファイルの配列行折返しを削除する

# やりたいこと

配列行に折返しを含む下記のようなFASTA形式ファイルを

```text:multi-line.fasta
>AAA98665.1 TCP1-beta
SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEAAEVLLRVDNIIRARP
RTANRQHM
>AAA98666.1 Axl2p
MTQLQISLLLTATISLLHLVVATPYEAYPIGKQYPPVARVNESFTFQISNDTYKSSVDK
TAQITYNCFDLPSWLSFDSSSRTFSGEPSSDLLSDANTTLYFNVILEGTDSADSTSLNN
TYQFVVTNRPSISLSSDFNLLALLKNYGYTNGKNALKLDPNEVFNVTFDRSMFTNEESI
VSYYGRSQLYNAPLPNWLFFDSGELKFTGTAPVINSAIAPETSYSFVIIATDIEGFSAV
EVEFELVIGAHQLTTSIQNSLIINVTDTGNVSYDLPLNYVYLDDDPISSDKLGSINLLD
APDWVALDNATISGSVPDELLGKNSNPANFSVSIYDTYGDVIYFNFEVVSTTDLFAISS
LPNINATRGEWFSYYFLPSQFTDYVNTNVSLEFTNSSQDHDWVKFQSSNLTLAGEVPKN
FDKLSLGLKANQGSQSQELYFNIIGMDSKITHSNHSANATSTRSSHHSTSTSSYTSSTY
TAKISSTSAAATSSAPAALPAANKTSSHNKKAVAIACGVAIPLGVILVALICFLIFWRR
RRENPDDENLPHAISGPDLNNPANKPNQENATPLNNPFDDDASSYDDTSIARRLAALNT
LKLDNHSATESDISSVDEKRDSLSGMNTYNDQFQSQSKEELLAKPPVQPPESPFFDPQN
RSSSVYMDSEPAVNKSWRYTGNLSPVSDIVRDSYGSQKTVDTEKLFDLEAPEKEKRTSR
DVTMSSLDPWNSNISPSPVRKSVTPSPYNVTKHRNRHLQNIQDSQSGKNGITPTTMSTS
SSDDFVPVKDGENFCWVHSMEPDRRPSKKRLVDFSNKSNVNVGQVKDIHGRIPEML
>AAA98667.1 Rev7p
MNRWVEKWLRVYLKCYINLILFYRNVYPPQSFDYTTYQSFNLPQFVPINRHPALIDYIE
ELILDVLSKLTHVYRFSICIINKKNDLCIEKYVLDFSELQHVDKDDQIITETEVFDEFR
SSLNSLIMHLEKLPKVNDDTITFEAVINAIELELGHKLDRNRRVDSLEEKAEIERDSNW
VKCQEDENLPDNNGFQPPKIKLTSLVGSDVGPLIIHQFSEKLISGDDKILNGVYSQYEE
GESIFGSLF
```

このように単一行に整形したいだけ

```text:single-line.fasta
>AAA98665.1 TCP1-beta
SSIYNGISTSGLDLNNGTIADMRQLGIVESYKLKRAVVSSASEAAEVLLRVDNIIRARPRTANRQHM
>AAA98666.1 Axl2p
MTQLQISLLLTATISLLHLVVATPYEAYPIGKQYPPVARVNESFTFQISNDTYKSSVDKTAQITYNCFDLPSWLSFDSSSRTFSGEPSSDLLSDANTTLYFNVILEGTDSADSTSLNNTYQFVVTNRPSISLSSDFNLLALLKNYGYTNGKNALKLDPNEVFNVTFDRSMFTNEESIVSYYGRSQLYNAPLPNWLFFDSGELKFTGTAPVINSAIAPETSYSFVIIATDIEGFSAVEVEFELVIGAHQLTTSIQNSLIINVTDTGNVSYDLPLNYVYLDDDPISSDKLGSINLLDAPDWVALDNATISGSVPDELLGKNSNPANFSVSIYDTYGDVIYFNFEVVSTTDLFAISSLPNINATRGEWFSYYFLPSQFTDYVNTNVSLEFTNSSQDHDWVKFQSSNLTLAGEVPKNFDKLSLGLKANQGSQSQELYFNIIGMDSKITHSNHSANATSTRSSHHSTSTSSYTSSTYTAKISSTSAAATSSAPAALPAANKTSSHNKKAVAIACGVAIPLGVILVALICFLIFWRRRRENPDDENLPHAISGPDLNNPANKPNQENATPLNNPFDDDASSYDDTSIARRLAALNTLKLDNHSATESDISSVDEKRDSLSGMNTYNDQFQSQSKEELLAKPPVQPPESPFFDPQNRSSSVYMDSEPAVNKSWRYTGNLSPVSDIVRDSYGSQKTVDTEKLFDLEAPEKEKRTSRDVTMSSLDPWNSNISPSPVRKSVTPSPYNVTKHRNRHLQNIQDSQSGKNGITPTTMSTSSSDDFVPVKDGENFCWVHSMEPDRRPSKKRLVDFSNKSNVNVGQVKDIHGRIPEML
>AAA98667.1 Rev7p
MNRWVEKWLRVYLKCYINLILFYRNVYPPQSFDYTTYQSFNLPQFVPINRHPALIDYIEELILDVLSKLTHVYRFSICIINKKNDLCIEKYVLDFSELQHVDKDDQIITETEVFDEFRSSLNSLIMHLEKLPKVNDDTITFEAVINAIELELGHKLDRNRRVDSLEEKAEIERDSNWVKCQEDENLPDNNGFQPPKIKLTSLVGSDVGPLIIHQFSEKLISGDDKILNGVYSQYEEGESIFGSLF
```

# 実行コード

Biopythonを利用してさくっと整形できる (**pip install biopython**)。
FASTA形式ファイルを`SeqIO.parse()`で読み込み後、`SeqIO.write()`でフォーマット指定を**fasta-2line**として出力するだけ。簡単。

```python:multi2single_line.py
from Bio import SeqIO

multi_line_fasta_infile = "multi-line.fasta"
multi_line_seq = SeqIO.parse(multi_line_fasta_infile, format="fasta")

single_line_fasta_outfile = "single-line.fasta"
SeqIO.write(multi_line_seq, single_line_fasta_outfile, format="fasta-2line")
```
画像投稿で413エラーが出た時

サイズ6.2Mの画像を投稿しようとすると413エラーが発生
![20200526235206.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551832/4218e14f-e5ce-c397-4e51-43e8335b328e.jpeg)

##原因
アップロードしようとしているファイルの大きさが、nginxで設定している最大アップロードサイズを超えているため。

確認すると・・・

```
[ec2-user@ip-**-*-*-*** ~]$ sudo vi /etc/nginx/nginx.conf
```

自分は何故かアップロードサイズの設定をしていませんでした

```
http {
　省略

    server {
　　　省略
    }
}
```

##解決
以下で最大10Mのサイズまで画像を投稿できるようになりました:clap:

```
http {
  client_max_body_size 10M; #ここを記述
　省略

    server {
　　　省略
    }
}
```

再起動して設定を反映させる

```
[ec2-user@ip-**-*-*-*** ~]$sudo nginx -s reload
```
それ、クローラーを作らなければいけないよ？

アプリケーションを開発するときに、どこかからあるデータを取得しなければいけないことがある。
その際の手段のひとつにスクレイピングというものがある。

## スクレイピングとは
スクレイピングとは、簡単にいうと``HTMLを抽出・加工すること``と言える。
英単語のScrape（表面をこする、こすり落とす）から来ているらしい。
ほかのWEBサイトなどから、ある情報を取得したいときなどにこのスクレイピングというものを行うことがある。
![laptop-1031224_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/f1e8f1c9-a4af-9e14-ca0d-3cd7e54c2b06.jpeg)


## スクレイピングをする際に考えるべきこと
ただ、スクレイピングで情報を取得・抽出・加工したいといっても、本当にそれはスクレイピングで実現できるのかをまず判断しなければならない。

そのためには、以下のようなことを調査したり考えなければならない。

- 取得したい情報は、1ページにまとまっているのか？複数ページにあるのか？
- そもそもその取得した情報はどうしたいのか？excelファイルにする、アプリのDBに保存したいとか

多分、ほかにも山ほどある。

## クローラーが必要なとき
もし、取得したい情報はあるWEBページの１つのページにまとまっているのであればスクレイピンをして純粋に情報を取得すればいい。しかし、その情報が複数のページにまたがっていたりすると、クローラーを作成する必要がある。

## クローラーとは
クローラーとはWebページのリンクをたどって複数のWebサイトを巡回しページの情報をデータベースに複製・登録するプログラムのこと。このプログラムを動かすことをクローリングと呼んだりする。

## クローラーでできること
基本的には、僕たち人間がWEBページ、WEbアプリケーションを操作することと同じようなことができるというのがイメージしやすいと思う。例えば、「このリンクをクリックして、このカテゴリーのページに飛んで、病院の情報を取得する」というようなことがクローラーで実現することができる。

うえの例でいくと、``病院の情報を取得する``ということはスクレイピングで実現できる。
このリンクをクリックして、このカテゴリーのページに飛んでというように``カテゴリーごとの情報を取得したい``そんな時には、クローラーのプログラムを組む必要がでてくる。
![google-76517_1280.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/8b7a7535-cdc9-0f1c-5474-8fc821eca797.png)
【MAC】postgreSQL環境構築


#１.Homebrew


https://brew.sh/index_ja


1.　インストール。

```ruby:コマンド
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
2.　`Password:` と出たらmacのパスワード入力。

3.　`Press RETURN to continue or any other key to abort` と出たら `Enter`

4.　確認。

```ruby:確認コマンド
brew -v
```
▶︎ 完了
Homebrew 3.2.10
Homebrew/homebrew-core (git revision 26570f077b; last commit 2021-09-04)出ました。

:::note info
 パスが通ってないよ
:::

```ruby:内容
Warning: /opt/homebrew/bin is not in your PATH.
```

```ruby:解決
export PATH="$PATH:/opt/homebrew/bin"
```

#2 . postgreSQL


https://www.postgresql.org/

1.　インストール。

```ruby:コマンド
brew install postgresql
```
2.　確認。   

```ruby:確認コマンド
psql --version
```

▶︎ 完了
psql (PostgreSQL) 13.4

:::note info
 キーチェーンログインパスワードって
:::

デフォルトだと、キーチェーンのパスワードはコンピュータのログインパスワードと同じ。


# 3 . pgadomin

https://www.pgadmin.org/

1.　インストール。

```ruby:コマンド
brew install pgadmin4
```
2.　確認。   

```ruby:確認コマンド
psql --version
```
DXに求められるデジタルリテラシについて

# デジタルとビジネスの類似性

日本はDXから周回遅れ、と言われている。様々な業務において、コミュニケーションやフローの方法が旧いままで、大幅な改定・刷新といえる社会的な転換や、そういった製品なかった状況を言い表している。

大幅な改定・刷新というと、何かものすごいチャレンジングな事の様に思える。現状を否定し、真新しい概念を提示したうえで、それを体現する高い生産性を生み出す仕組みや、チームを創出する、そんなイメージだろう。

しかし、エンジニアの立場からするとそれは絵に描いた餅だと思う。

エンジニアが新しい機能を実装するとき、まず最初にプロトタイピングを行う。まず目的があって、それを実現する必要最小限のコードを書く。あるいは、既存のコードが無いか、その目的とする機能のキーワードを頭の中から捻りだし、検索して、他者の公開しているコードを流用する。そうしてベースとなるプロトタイプコードを生み出す。誤解を避けるために言及すると、プロトタイピングとはいっても、機能を求めている人にとってはこの段階で満足するレベルのものである。リリースしようと思えばこの時点でリリースして使った頂く事は可能だ。

実際プロであっても、ここで手を止めてしまうエンジニアは沢山存在すると思う。

そのあとは改善の繰り返しである。たとえば、コードの中に埋め込まれたマジックナンバーをまずは定数化し、その次にはコマンドオプションにしたり、ファイルで永続化したり。

そのあとは、プログラムやデータ構造の見直しになる。同じ種類のデータを使う機能群でグループ化してクラス分割したり、あるいは、規格化できそうなデータ構造を新たに型定義して、どのモジュールからも安全にデータアクセスできるようにする。

つまり、表面的には1日で実現できる機能であったとしても、実際完成するのはその3倍、10倍ほどの時間を要する事が当たり前だ。

エンジニアの世界ではこれをリファクタリングと呼ぶ。表面上の機能的には何も変化はなく、嬉しさはない。したがって誰も望まない作業である。しかしエンジニアは進んでこれに何十倍も時間と手間を費やすのである。

なぜこんなムダな事を行うのか。それは、そのソフトウェアにそのあと追加される機能や仕組みを組み合わせやすくするためである。

一般の事務仕事の現場を考えてみたい。例えば、お客様から商品の見積依頼が来て、それを各商品のメーカ毎に仕入れ価格と納期を問い合わせて、自社の売値基準に照らし合わせ販売価格を決定し、見積書を作成する、というフローがあったとする。

規模の小さなスタートアップであれば、このフローを独りで対応するだろう。依頼された品目毎に納品価格を調べ、売値をどうするかBossに相談しながら決めて、見積回答する、そんな流れである。

実際、それだけで顧客からは満足したアウトプットが得られるのである。

しかし、その顧客が1日に1000件見積対応しなければならないとすれば、とたんに破綻する。都度Bossの判断が求められると、Bossとしての役割は果たせなくなる。何も意思決定が進まないまま、組織は弱体化する。

つまり、見積担当者は見積業務に、Bossは価格の適正化に対する意思決定、という役割をしっかり果たせるようにする業務フローの再構築が必要になる。そのためには以下が必要だ。

* 売値を決めるルール（原価、販管費に対する利益率）に基づいた売値の計算式を決める。
* 原価、販管費の実績を統計的視点で損益分岐点を見える化する。これに基づいて定期的に売値を更新する。
* 見積額はこのデータベースから自動的に出力されるようにする。

こうして見積業務、と呼ばれる販売費工数を極小化し、能力に基づいて適切に役割を定義し、その役割に応じたタスクを割り当てる、といった、業務フローの「リファクタリング」をまず行ってから、適切な業務量に応じた作業者のインスタンスを起ち上げる。これがビジネスにおける変革である。

つまりは、ソフトウェアにおけるリファクタリングと、ビジネスフローにおけるリファクタリングはほとんど似ていると思う。

顧客体験に基づいたDXの理論であるが、実のところ、こうした土台の大幅な改変無しには、その次の *大幅な顧客体験の向上* は見込めないのである。

# DXに求められるデジタルスキルとは

ひとことで言えば、「リファクタリングこそコアバリュー（革新的価値である）」という共通認識ではないだろうか。上述の様に、リファクタリングはプログラムコードだけではなく、あらゆる場面で必要とされる。これらすべてが顧客体験に直結するのである。

しかし、この感覚・センスを持つのは残念ながらリファクタリングの恩恵を体験しているエンジニア特有なのである。それが問題の核心だ。

いつまでもビジネス現場ではハンコ、稟議書で意思決定が行われ、過去の業務ログはExcelで情報のサイロ化が起こる。全くリファクタリングが行われないまま数十年を過ごす。壮大な機会損失が行われているのである。

その状態を平然と受け入れていることが、センスやリテラシーを持ち合わせていない事の証左ではないだろうか。エンジニアはその状況を苦々しく見つめている状況である。

# リファクタリングは新たな概念を生み出す

リファクタリングという作業は、やった方が良い、程度の改善ではない。業務の流れ、処理（役割）の分析、データの整理、など日本が得意としている5S（整理、整頓、清掃、清潔、躾）を目指すものと同じだ。

これは普段何気なくやっている事を、点検によって新たな本質に「気づく」効果がある。この気付きは最も大きな価値を生み出す可能性がある。なぜなら、新たな商品、仕組みというのはこういった日々の業務の点検作業の中から生まれているからだ。いままでなぜこのようなやり方してたんだろう？ということを掘り下げる事で、「要するにこういう事だよね」を再定義する事だ。

リファクタリングで大事なことは、プロタイプレベルのコードを積み重ねたあと、まとめて行うのではなく、都度都度行う事が避けられない。なぜなら、人間の記憶や規模の大きな仕組みを一度に把握する能力には限界がある。鉄は熱いうちに打て、の世界である。

DXで最も求められるのは、新たなテクノロジーや仕組みを導入する、というよりも、その現場にいる人々が求める機能を素早く提供しつつ、継続的にリファクタリングを行い、常に最適化されたボリュームとシステムをメンテナンスし続けるスキルである。
厚生労働省のウェブサイトに掲載を希望した無痛分娩取扱施設の一覧をCSVに変換

変換済み

https://docs.google.com/spreadsheets/d/1-MzkvdMYiJGveJ_obAXE86CQXIpTZsbeN8LzUGbU8eo/edit?usp=sharing

PDFから変換しただけで内容は未確認、都道府県別の施設数は確認済み

下記プログラムで変換後以下手作業で修正

+ 聖路加国際病院のURLが一部枠外だったので手で修正
+ 聖路加国際病院のすぐ下の行が空行だったので削除
+ 連番ふり直し

```
!apt install python3-tk ghostscript
!pip install camelot-py[cv]
```

```python
import pathlib
from urllib.parse import urljoin

import camelot
import pandas as pd
import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}


def fetch_soup(url, parser="html.parser"):

    r = requests.get(url, headers=headers)
    r.raise_for_status()

    soup = BeautifulSoup(r.content, parser)

    return soup


def fetch_file(url, name, dir="."):

    p = pathlib.Path(dir, f"{name}.pdf")
    p.parent.mkdir(parents=True, exist_ok=True)

    r = requests.get(url)
    r.raise_for_status()

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p


url = "https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000186912.html"

soup = fetch_soup(url)

dfs = []

for i in soup.select("ul.m-listLink--hCol2 > li > a"):

    pref = i.get_text()

    link = urljoin(url, i.get("href"))

    p = fetch_file(link, pref)

    tables = camelot.read_pdf(str(p), pages="all", split_text=True, strip_text=" \n")

    for table in tables:

        tmp = pd.DataFrame(table.data[2:], columns=table.data[1])
        tmp["都道府県"] = pref

        dfs.append(tmp)

df0 = pd.concat(dfs).reset_index(drop=True)
df0

df1 = df0.copy()

df1.columns

df1[~df1["医師の人数"].str.isnumeric()]

df1["ウェブサイトURL"] = df1["ウェブサイトURL"].mask(
    df1["ウェブサイトURL"].str.startswith("www."), "http://" + df1["ウェブサイトURL"]
)

df1["ウェブサイトURL"] = df1["ウェブサイトURL"].mask(df1["ウェブサイトURL"].str.endswith("なし"))

df1["ウェブサイトURL"] = df1["ウェブサイトURL"].str.replace(",", ".")

df1.to_csv("list.csv", encoding="utf_8_sig")
```
Hello World

#qiita始めました
一つのルールを設けて、qiitaにこれから記事を書いていこうと思う。
そのルールとはできるだけ毎日一トピックを書くことである。
理由は主に二つあって、
自分がYouTubeで見たくもない動画を長時間見ているなぁと思って、
それを打開するためにも暇つぶしで書くことが一つ。
もう一つは僕はラジオを聴くことが趣味で一日に2時間ほど聞いている。
特にいつも聞いているのは、[樋口聖典の世界](https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9kODA3MzkwL3BvZGNhc3QvcnNz)をよく聞いている。
その中で取り組まれていることとして毎日ブログを1本更新している。
残念ながら僕はまだそのブログを見ていない。
この取り組みが続いたら、いつか見たいと思う。
普段からよく触れている方に憧れて、そのマネをしながら取り組みたいと思い始めていきます。

Hello World
まるで自分だけの小さなインターネット、オレオレブックマーク管理術

# はじめに
こんにちは、普段は機械学習エンジニアをしている[fkubota](https://twitter.com/fkubota_)です。
今回は僕が普段行っているブックマーク管理術を紹介したいと思います。
ブラウザは`chrome`や`vivaldi`などの **chrome拡張** が使える環境を想定しています。

記事を読むモチベーションをあげるために僕がブックマークにアクセスしている様子をここで一度見てほしいです。
1. 以前書いたQiitaの記事
2. portfolio 
3. wifiの速度測定
という順番で開いています。
めちゃ早いというのがわかっていただけるとウレシイです。
![bookmark.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/868744/3dee32fc-9a77-715a-8984-716cc17cc7fd.gif)


# ブックマーク管理がしんどかった時
過去にブックマークの管理がとてもしんどかった時期がありました。  
すぐにアクセスできるブックマークバーが便利でどんどん追加していくと量がすごくなってしまいました。
フォルダ管理を始めました。フォルダ管理で構造化すると今度はアクセスが遅くなりました。
どのフォルダに有るかわからないときがありフォルダをいくつか開いて探してみるなどしていました。これは時間がかかりますし、管理が大変でした。

更に言うと、僕の場合はフォルダ管理はかならず破綻する傾向にあります。
`データ分析`, `R`, `Python`, `Linux` というフォルダを作った場合、 

- 「Pythonでデータ分析を行う記事」はどこに入れるべきでしょうか？
- 「LinuxにPythonをインストールする記事」はどこに入れるべきでしょうか？

このような曖昧な状況が重なると僕の場合はうんざりして管理を諦めて複雑なブックマークを漁って探すのではなく結局ググるという選択肢を取っていました。
結局の所、僕はブックマークを増やすことで満足しブックマークを使うことはほとんどできていませんでした。  

そんなこんなでいろいろ試行錯誤を行って今に至ります。
**今は、200以上のブックマークをほとんど管理していないにも関わらず高速にアクセスできています。**
この記事ではその方法を紹介したいと思います。
これは全人類真似すべきだという意図はなく、世の中に多くあるであろうブックマークマネジメント術の一つだという意識で読んでください。

# なにをしているのか
基本的には以下を行っています

- フォルダ管理は行わず **ラベル管理**　を行う
- 検索で絞り込む(リアルタイムあいまい検索)
- あるフォルダにすべてのブックマークを保存する  
(僕の場合、`その他のブックマーク` に200以上のすべてのブックマークが入っています。)  
(とても管理できている状況ではありませんが、そもそも管理する必要がないという事です。)

**メリデメ**

- メリット
    - 早い
    - 管理の必要ない
    - 楽しい
    - マウスを使わなくていい(vimiumユーザの場合)
 
- デメリット
    - 今の所ない(と思っている)


# 方法
それではその実現方法についてです。
かなり簡単です。  
## 1. ブックマークを保存するフォルダを決める
僕の場合は`その他のブックマーク`。
## 2. 保存名にラベルを付与する
- wifiの速度を測定するFastというサイトであれば `#wifi` `#fast` のようにブックマークの保存名に追加します。ブックマーク検索時にこれがあるだけで格段にヒットしやすくなります。日本語を入れてもいいです。
- ポイントは、**そのサイトをググって探すときのキーワードをラベルに設定すること**です。macの音楽に関係することであれば `#mac` `#music` `#sound` などでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/868744/f016e265-dd47-9cfd-6f11-6645b3c85bb2.png)
## 3. 検索する
検索するために拡張を使います。`vimium` というchrome拡張を持っているかどうかで方法が変わります。
vimiumユーザであれば**検索時のマウスは不要です**。

### 一般ユーザの場合
[ブックマーク検索](https://chrome.google.com/webstore/detail/search-on-bookmark/ebalpcfngdhkpndfognjoffolfpiilnm/related)というchrome拡張を追加します。  
星のようなアイコンが`ブックマーク検索`です。
これをクリックし検索するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/868744/7021cd57-4fd2-fde2-9aa4-f095d98009f1.png)


### vimiumユーザの場合
コマンドの`b`を使うだけです。冒頭の検索の様子を映したgifはvimiumの`b`コマンドを使っています。
ブックマークを別タブで開きたい場合は、`shift+b` を使うと良いです。  

# 終わり
あとは上記で書いた方法を使って`ラベルが付与されたブックマーク`をどんどん溜めていくだけです。
しかもそれはある一つのフォルダに無造作に追加されていきます。
10, 100, 300, 1000と増えていくことでしょう。
しかしそれでも問題ありません。
検索するときにまず`python`と入力してしまえば`python`に関係するブックマークが表示されます。これは`python`フォルダを見ていることと同じです。
`linux`と入力すればそれは`linux`フォルダを見ていることになります。
`linux python` と入力すれば linux と python が関係するブックマークのみ表示されます。

アクセスしたいページがあればなんでもブックマークしちゃうのがおすすめです。 

- githubのあるリポジトリであれば、 `#repo #hoge #foo` 
- google driveのあるディレクトリであれば `#gdrive #hoge`
- 会社とプライベートのgmailも分けることができます。 `#gmail #work`, `#gmail #pri`


この方法を長く運用して**これはまるで自分だけの小さなインターネットだ**と感じました。
とても快適です。管理せずとも情報に高速にアクセスできるのです。

以上です。
気に入った人は是非真似してみてください:)　
                  [fkubota](https://twitter.com/fkubota_)
AWS Certified Advanced Networking - Specialty を取得した

# 前回のお話

https://qiita.com/morio1101/items/0c3038da53f3f11ad2e7

# はじめに

## AWS Certified Advanced Networking - Specialty について

https://aws.amazon.com/jp/certification/certified-advanced-networking-specialty/

# 学習について

## 学習期間

2週間（9/4 に取得した）

## 学習資材

### aws WEB問題集で学習しよう

模擬試験も存在しないので、本問題集をやりこむぐらいし手段がなかった

## 学習方法

WEB問題集を4、5週実施した
（終盤は9割強は正解できるレベルになっていた）

1周目は間違った問題も、正解した問題も解説をしっかり読み込んだ
2周目以降は正解だったが自身のないもの、不正解だったものの解説を読みながら問題を解いていた

試験当日、問題集が使えなくなっていたので、BlackBelt の Amazon CloudFront の概要と AWS Direct Connect を流し見していた
~~役だったかはよくわからない~~

# 試験結果について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532289/b3457679-8a53-9079-6a26-9f94300f5586.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532289/c2f57996-316d-009b-2bad-6ecb06e9a426.png)

自己採点では65問中

* 採点ボタンを押すまでの感覚
    * 26問フラグを立てて、その中で半分ぐらいは勝算があると感じていた
    * 上記から55問は運も多少絡むが解けている勝算があった
        * 結果は904点と想定以上に解けていた

# 感想

WEB 問題集と近しい・ほぼほぼ即答できるような問題が2割、学習した知識があれば解ける問題が3割、知識を応用したら解けそうな問題が2割ぐらいあった

逆にカバーできていない問題として、ネットワーク計算関連の問題が3問ほど出てきた
知識を総動員して無理くり解答したが、合っている自信はない…

私が試験を受けたタイミングでは Transit VPC 関連の問題は出題されなかった
こればかりは運次第という感じかな？

WEB問題集をやりこんでおくことが合格の第一歩になると今回の試験についてはそう感じた

# 今後について

気付くとAWSの試験も残り4つとなりました（プロフェッショナル2種、スペシャリティー2種（DB・機械学習））
飽き性の私が継続して取り続けたものだと思う

さて、WEB問題集の有料プランが試験日前日で終了となりました

再度契約して、プロフェッショナル2種を狙うか
それとも、Udemy関連の教材を用いて、データベースか機械学習を狙うかは結構ターニングポイントのような気がしている

皆どうやってロードマップを作っていったんだろう:sweat_smile:
主成分分析をnumpyで実装

## 主成分分析とは
次元削減手法の一つ。

データセットに対して、最大分散を取る方向に軸を生成、
それに直行する方向に最大分散軸を取る...ということを繰り返すことで、
データを少ない特徴量で表現する。


##必要ライブラリのimport

```python
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
```

##データセット
```python
# 乱数でデータを生成
data = np.random.multivariate_normal(mean=[0,0],
                                     cov=[[1.0,0.7],[0.7,1.0]],
                                     size=200)
pop = data.shape[0]
dv = data.shape[1]
```
二次元正規分布に従って2変数のサンプルを生成する。

##主成分分析
```python
# 共分散行列(covariance matrix)
covmatrix = np.cov(data.T)

# 固有値, 固有ベクトルを求める
eig = np.linalg.eig(covmatrix)[0]
eigvec = np.linalg.eig(covmatrix)[1]

# 昇順に並べ替え
idx = np.argsort(eig)[::-1]
eig = eig[idx]
eigvec = eigvec[idx]

# 主成分得点
pcacor = np.dot(data, eigvec)

# 寄与率
cr = eig/sum(eig)
```

##累積寄与率のプロット
```python
## 累積寄与率をプロット
ccr = np.cumsum(cr)
lb = ["PC{}".format(i+1) for i in range(dv)]

fig = plt.figure(figsize=(6,3),dpi=320)
ax = fig.add_subplot(111)
ax.bar(lb, ccr, label="累積寄与率")
plt.ylabel("cumulative contribution rate")
```

今回は2変数のサンプルなので、第2主成分で累積寄与率1になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578196/2ee67113-08d5-05e1-bd98-139eca97a9d2.png)

##データ空間の可視化
```python
# データ中心と主成分軸を計算
ave = np.mean(data, axis=0)
dpt = ave + eigvec

# プロット
fig = plt.figure(figsize=(4,4),dpi=320)
ax = fig.add_subplot(111)
plt.xlim(-4,4)
plt.ylim(-4,4)
plt.xlabel("x1")
plt.ylabel("x2")

ax.scatter(data[:,0], data[:,1], alpha=0.4)
ax.scatter(ave[0], ave[1], marker="*", color="red")
for i in range(2):
    ax.plot([ave[0], dpt[0,i]], [ave[1], dpt[1,i]],
            color="red", linewidth=1)
    ax.text(dpt[0,i], dpt[1,i], "pc{}".format(i+1))
```

データの分散が大きくなる方向に、主成分軸PC1、PC2が現れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578196/cd9cdc25-ed58-4b4e-40ec-a721aba3427f.png)

##データの再構築
```python
resamplept = np.array([np.dot(eigvec, pcacor[i]) for i in [0,1,2,3,4]])
ax.scatter(resamplept[:,0], resamplept[:,1], 
           s=10, marker="*", color="blue")
```
index 0~4までのデータを再構成する。
下図の青*マーカーの点。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578196/66e6a793-0269-9ff4-2f2f-38f38ad1eef8.png)


## 主成分空間に投影
```python
# 主成分空間にプロット
fig = plt.figure(figsize=(4,4),dpi=320)
ax = fig.add_subplot(111)
plt.xlim(-4,4)
plt.ylim(-4,4)
plt.xlabel("pc1")
plt.ylabel("pc2")

# 全データ
ax.scatter(pcacor[:,0], pcacor[:,1], alpha=0.4)
# 0~4までのデータ
ax.scatter(pcacor[0:5,0], pcacor[0:5,1], 
           s=10, marker="*", color="blue")

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578196/ebf80ff5-7288-74f5-9d96-956d4a190062.png)


## まとめ
例えば、pc1だけでこのデータセットを表現する場合、
1変数のみでデータ全体の8割程度の説明が可能、ということになる。

実際は主成分と累積寄与率の関係を見ながら、採用する主成分数を決める。
Pythonで一次元配列と二次元配列の変換(numpyなし)

たまに忘れて1から考えるのでメモ．

```python:sample.py
In [1]: a = [ chr(x) for x in range(65,65+16) ]

In [2]: print(a)
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']

In [3]: b = [ a[x:x+4] for x in range(0,len(a),4) ]

In [4]: print(b)
[['A', 'B', 'C', 'D'], ['E', 'F', 'G', 'H'], ['I', 'J', 'K', 'L'], ['M', 'N', 'O', 'P']]

In [5]: from itertools import chain

In [6]: c = [ x for x in chain.from_iterable(b) ]

In [7]: print(c)
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']

In [8]:
```

よくみかけるのはnumpyを使うパターンですが，このくらいの単純なリストなら組込みの範囲でできますしね．
【Linux】/と~の違い（ルートディレクトリとホームディレクトリの違い）

ルートディレクトリ配下にある、一つがホームディレクトリだよ

## 「/」（ルートディレクトリ）とは？

- `Linux OS`にとって１つしか存在しない最上位のディレクトリ（Windowsの場合、ドライブから始まるよ）
- 他のディレクトリも全て先祖を辿っていくとルートディレクトリに繋がっているよ
- ルートディレクトにディレクトリを繋げることをマウントと呼ぶよ

## 「~」（ホームディレクトリ）とは？

- /(ルートディレクトリ）の配下にある`/home`ディレクトリのこと
- Linuxのユーザーごとに、割り当てられる個人用のディレクトリ
- ユーザーは、ホームディレクトリ内に自由にファイルやディレクトリを作成できる（だから`cd ~`でここに色々作るんだね！）

## イメージ図

```terminal
🗂/(ルートディレクトリ）
　  　∟🗂/home（今回取り上げたのがこのディレクトリ）
  　　∟🗂/bin(一般ユーザー及び管理者ユーザー向けのLinux動作に最低限必要なコマンドの実行ファイル置き場）
  　　∟🗂/dev（ディスクやキーボードなどハードウェアをファイルとして扱えるようにしたファイル置き場）
　  　∟🗂/etc(アプリケーションの設定ファイルやLinuxの自体の設定ファイル置き場（非常にセンシティブで重要なディレクトリ）)
　  　∟🗂/sbin（管理者ユーザー向けのコマンド実行ファイル置き場）
　  　∟🗂/tmp（一時的なファイルの置き場（消されたら困るファイルここ置いたらダメだよ））
　  　∟🗂/usr（アプリケーションとそれに付随するファイルの置き場（アプリ追加するとここへ置かれる））
　  　∟🗂/var(ログなど変化するデータの置き場)
```