OmniAICreator/Qiita-1.07M huggingface dataset:
Quiztime 2nd February 2022: A mysterious straw man

#概要

皆さん、お久しぶりです。
ニャンダウです♪

今回のOSINTクイズは単純で、あまり書くことはないのですが、逆画像検索では決して見つからず、
約6時間も時間を費やしてしまいました。

以下、問題のツイートです。

https://twitter.com/bayer_julia/status/1488249011169640453?s=20&t=y0v0L5-6C7Fk8KkndgkbKA

#思考作為

内容は単純に、この写真を撮った場所を突き止めるだけ。

当初、この問題に取り組んだときは、最近はGoogleレンズで簡単に解ける問題ばかりでうんざりしていたこともあり、
すぐに終わるだろうと思っていた。

まずはGoogleレンズ。

![スクリーンショット 2022-02-06 21.29.53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/a0180dd4-9fac-16b7-3bba-c8367c184c74.jpeg)

見つからなかったのでFirefoxのSearch by imageを使った。

結果はYandexの逆画像検索だが、ここで1時間ほど探してみたが見つからない。

![スクリーンショット 2022-02-06 21.29.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/bb65125e-a830-dd77-df73-bc382f6bfc4d.jpeg)

画像検索では見つからないことが分かったので、次は画像を分析して検索してみる。

ここで画像をよく観察して分析してみよう。

![FKdSi1zXsAM0V2O.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848369/1286d0da-18d6-8285-951b-1abb1363c24e.jpeg)

#解決策

この画像を分析してみて分かることは３つ:

1: ストロー？を加えている人間、男・もしくは子供かもしれない。
2: ストリート作品である
3: ストローを加えている先に排水溝がある

また、画像から察するに、排水溝から水をすすっている絵、そして「排水溝(gutter)」という単語から、
ここは先進国ではなくどこかの後進国、貧困街かもしれない。

以上３つの観点から、Googleの検索オペレータには３つのオペレータを重視して探した。

Google Oparator: 'straw man' + 'street art' + 'gutter'

そして、４時間近くかけ、以下のオペレータで見つけることができた。

Final Search Result: 'street art' + 'gutter'

https://thenatureofgraffiti.org/2016/01/11/boy-drinking/

答えは **Parking lot in Cape Town, South Africa**

#感想

改めて考えると、単純そうに見えたからこそ難しかったことがわかる。

試しにこの問題の答えの"Woman drinking from a gutter"を検索してみると、出てこなかった。

この問題は、画像をよく分析(文字化)し、特定の単語を入力しないと出てこない、Googleにタグ付けされていない場所を
どう突き止めたらいいのか教えてくれた問題だった。

あと、自分の推論も、答えがアフリカだったこともあり意外と的中していたのでOSINT力が上がっていることも実感できた。

また、結局この問題は特別なスキルを使ったわけでもなく、9割は根性力だったねw
pythonを実行するエディタによって速度が少し異なるって知っていた？

#はじめに

私は普段、Anacondaに標準でついてくるspyderを使用してpythonのプログラムを実行しています。
しかし。ある日コマンドラインを使用してプログラムを実行してみたら、「コマンドライン速くない？」と思いました。
定量的に分析するためにも、各実行ツールでベンチマークを実行することにしました。

結果として、__ちょっとコマンドプロンプトが速い__、でした。
簡単なコードでは特に実行方法について気にしなくてもいいけれど、
複雑なコードで速度を追い求めているなら、コマンドプロンプトをお勧めします。







#計測に使用したプログラム

こちらの記事のプログラムを全面的に使用しました。

https://tech.morikatron.ai/entry/2020/03/20/100000

また、実行方法は多々ありますが、今回は私の環境にある、

* コマンドプロンプト
* Spyder
* PyScripter
* VSCode
* Jupyter Notebook

と使用して比較しました。




#環境
Python 3.8.8
Windows 10
CPU Ryzen 3700x


#1.様々な動作の速度
こちらのプログラムを使用しました。

https://github.com/morikatron/snippet/blob/master/benchmark/simple_python_bench.py

計測に意外と時間がかかってしまったので、
10回平均を5回に減らし、
プリントは10万回から1万回に減らし、
スレッド生成は10万回から1万回に、
プロセス生成は10万回から千回に減らしました。

結果がこちらです。

|   | コマンドプロンプト | Spyder | VSCode | PysSripter | jupyter Notebook |
|:-:|:-:|:-:|:-:|:-:|:-:|
| 空ループを1000万回  |142.32 ms   | 142.12 ms  | 149.73 ms  |145.53 ms   |144.50 ms   |
| 関数を100万回呼出し |93.68 ms   | 96.48 ms  | 98.48 ms  | 96.08 ms  |94.08 ms   |
| print を1万回      |924.70 ms   | 396.53 ms  | 727.52 ms  |21.71 ms   | 404.96 ms  |
|ジュリア集合の計算   |3682.54 ms   | 3696.35 ms  |3847.68 ms   |3695.15 ms   |3698.63 ms   |
| スレッド生成1万回   |172.55 ms   |187.44 ms   |165.39 ms   |196.59 ms   |157.12 ms   |
|プロセス生成千回     |336.70 ms   |350.48 ms   | 347.71 ms  |375.94 ms   |206.58 ms   |

ループ、関数、ジュリア集合の計算といった、普通のプログラムに含まれているような内容はコマンドプロンプトが少し早いみたいです。
なぜか`print`ではPysSripterがとても高速です。
スレッド生成、プロセス生成に関しては、jupyter Notebookが速く、コマンドプロンプトがそれに続くといった形です。

#2.numpyの速度
こちらのプログラムを使用しました。

https://gist.github.com/markus-beuckelmann/8bc25531b11158431a5b09a45abd6276

結果がこちらです。

|   | コマンドプロンプト | Spyder | VSCode | PysSripter | jupyter Notebook |
|:-:|:-:|:-:|:-:|:-:|:-:|
| Dotted two matrices        | 0.49 s   | 0.49 s  |   | 0.49 s  | 0.49 s  |
|Dotted two vectors of length|0.03 ms   | 0.02 ms  |   | 0.02 ms  |0.03 ms   |
|SVD of a matrix             |0.39 s   |0.52 s   |   | 0.41 s  | 0.40 s  |
| Cholesky decomposition     |0.16 s   |0.18 s   |   |0.18 s   | 0.16 s |
| Eigendecomposition	     |4.88 s   | 4.94 s  |   |  4.90 s  |4.90 s   |

(注)vscodeはなぜかnumpyがimportできなかったため、空白

全体的に横並びだけど、後半はコマンドプロンプトがちょっと速いかなという感じです。





#まとめ

今回は、簡単なプログラムでのベンチマークを行いました。
普通の計算でもnumpyを使った計算でも、全体的にコマンドプロンプトがちょっと速いという結果になりました。
今回のテストでは__少し速い__程度でしたが、実際のコードではライブラリ内で複雑な処理が積み重なり、ある程度の速度差にはつながりそうです。
簡単なコードでは特に実行方法について気にしなくてもいいけれど、複雑なコードで速度を追い求めているならコマンドプロンプトをお勧めします。
【Java初心者】Commons emailで日本語添付ファイルの文字化け解消

こちらの記事は[改良版](https://qiita.com/sev01/items/6077a501770d1f886a6e)があります。そちらをご覧ください。

# Commons-emailで簡単メール送信

Javaでメール送信するとなるとJavaMailですが、結構設定が多くて面倒になります。

私が利用しているのはcommons-email (https://commons.apache.org/proper/commons-email/ ) 。

ただ、日本語の添付ファイルをどうやったら文字化けしないように送信できるかにはまりました。

# 解決案

```java
package mailrectest;

import javax.mail.internet.MimeUtility;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.MultiPartEmail;

public class SendMailWithAttachFile {

    public static void main(String[] args) {
        try {
            // System.setProperty("mail.mime.encodefilename", "true");
            // System.setProperty("mail.mime.charset", "ISO-2022-JP");

            // 添付1
            EmailAttachment attach1 = new EmailAttachment();
            String name = "/home/XXXXXX/日本語のファイル名.pdf";
            attach1.setPath(name);
            attach1.setDisposition(EmailAttachment.ATTACHMENT);
            String name1 = MimeUtility.encodeText("日本語のファイル名.pdf");
            attach1.setName(name1);

            //添付2
            EmailAttachment attach2 = new EmailAttachment();
            attach2.setPath("/home/XXXXXX/次のファイル.pdf");
            attach2.setDisposition(EmailAttachment.ATTACHMENT);
            attach2.setName("次のファイル.pdf");

            MultiPartEmail email = new MultiPartEmail();
            email.setHostName("<SMTPサーバー>");
            email.setSmtpPort(<SMTPサーバーのポート>);
            email.setStartTLSEnabled(true);
            email.setAuthentication("<SMTPのID>", "<SMTPパスワード>");

            email.setFrom("<差出人>");
            String subject = MimeUtility.encodeText("<タイトル>".strip(), "iso-2022-jp", "B");
            subject = MimeUtility.unfold(subject);
            email.setSubject(subject);
            email.setMsg("<本文>");

            String[] listTOs = {"<送信先1>","<送信先2>"};
            for (String listTO : listTOs) {
                email.addTo(listTO);
            }
            //ファイルを添付
            email.attach(attach1);
            email.attach(attach2);

            // email.setDebug(true);
            email.send();

        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}
```
VirtualBoxでVERR_SSM_INTEGRITY_DECOMPRESSION

VirtualBoxで仮想マシンを起動しようとしたら、
「Failed to load unit 'pgm' (VERR_SSM_INTEGRITY_DECOMPRESSION)」
が出て起動できない。
↓
マネージャで「保存状態を破棄」を選択すると解決できる。

#
VERR_SSM_INTEGRITY_DECOMPRESSION は、VirtualBox で発生するエラーコードの一つです。
このエラーは、仮想マシンの保存状態（SSM: Saved State Machine）の整合性チェックが、解凍処理中に失敗した ことを意味します。

# 考えられる原因
- 保存状態の破損
仮想マシンのスナップショットや保存された状態が破損している可能性があります。
- ディスクの不良
仮想マシンの保存データが格納されているディスクにエラーが発生している可能性があります。
- VirtualBox のバージョン不一致
古いバージョンの VirtualBox で保存された状態を、新しいバージョンで復元しようとした際に問題が発生することがあります。
- 圧縮・展開の問題
VirtualBox は仮想マシンの保存状態を圧縮することがありますが、その展開時にエラーが発生する場合があります。
# 解決策
1. 保存状態を削除する
VBoxManage discardstate "VM名" を実行するか、GUI で「保存状態の削除」を実行する。
2. 仮想マシンを再起動する
一度 VirtualBox を完全に終了し、再度起動して仮想マシンを起動する。
3. VirtualBox を最新版に更新する
VirtualBox の公式サイトから最新バージョンをダウンロードして更新する。
4. 仮想マシンのバックアップを作成し、再インストールする
破損した仮想マシンを削除し、バックアップから復元する。

#
もし詳細なエラーログ（VBox.log）がある場合、それを確認すると原因が特定しやすくなります。
matplotlibで軸の文字サイズを変更する

# 1. 背景
pythonのmatplotlibを使ってグラフを描いたとき、何も設定していないと軸の文字が小さい。（思ってるのが私だけかもしれませんが...）

```python
import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot([1,2],[1,2],label="line")
plt.xlabel("x_label")
plt.ylabel("y_label")
plt.legend()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/ddca4d69-1b0d-540a-c9bf-30159a6154c4.png)

# 2. 結論
この一行を追加するのが一番手っ取り早い。私は15が一番見やすい大きさかなって思います。
`plt.rcParams["font.size"] = 15`

```python
plt.rcParams["font.size"] = 15
fig = plt.figure()
plt.plot([1,2],[1,2],label="line")
plt.xlabel("x_label")
plt.ylabel("y_label")
plt.legend()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/eeead9dc-673b-8070-e637-ba2375da0f20.png)

# 3. 詳細

## 3.1. 一律変更
以下の一行を追加すると一律に図中の文字の大きさを変更できる。
`plt.rcParams["font.size"] = 15`

## 3.2 個別変更
個別に変更する方法もある。fontsizeやlabelsizeを設定すると各文字サイズを変更できる。

```python
fig = plt.figure()
plt.plot([1,2],[1,2],label="line")

#fontsizeでx軸の文字サイズ変更
plt.xlabel("x_label",fontsize=15)

#fontsizeでy軸の文字サイズ変更
plt.ylabel("y_label",fontsize=15)

#labelsizeで軸の数字の文字サイズ変更
plt.tick_params(labelsize=15)

#fontsizeで凡例の文字サイズ変更
plt.legend(fontsize=15)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/eeead9dc-673b-8070-e637-ba2375da0f20.png)

## 3.3 軸の数字の文字サイズだけ小さくする
バランス的にこれがいい感じな気がする。

```python
plt.rcParams["font.size"] = 15
fig = plt.figure()
plt.plot([1,2],[1,2],label="line")
plt.xlabel("x_label")
plt.ylabel("y_label")
plt.tick_params(labelsize=12)
plt.legend()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521553/ebc3995b-fada-565e-129e-1279a53485cf.png)

# 4. 参考
https://matplotlib.org/stable/tutorials/introductory/pyplot.html?highlight=xlabel%20fontsize

https://matplotlib.org/stable/api/legend_api.html?highlight=fontsize
WordPress REST APIを試す

WordPress REST APIを試してみたのでメモとして記事に残します。
Headless CMSと呼ばれるようです。

https://www.wantedly.com/companies/commude/post_articles/357815

# 環境
Windows10 Pro: 20H2
Docker Desktop 4.4.4
Wordpres: 5.9

事前にDocker DesktopのインストールとWSL2を有効化する必要がある。
手順は以下の記事参照。

https://qiita.com/tks-hsmt/items/c0d422a0ace67afe74f9

# 手順
1. docker-compose.ymlを作成 & 起動
2. 動作確認 & Wordpres初期設定
3. Talend API Testerで記事一覧を取得 

# 1. docker-compose.ymlを作成 & 起動
任意のディレクトリに`docker-compose.yml`を作成する。
構成は最低限で、利用するイメージは以下。
- worepress:latest (Wordpress最新バージョン。執筆時5.9)
- mysql:5.7

```yml
version: '3.1'

services:
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: wp_db_pass
      WORDPRESS_DB_NAME: wpdb
    volumes:
      - ./wordpress:/var/www/html
      - ./wp-content/themes:/var/www/html/wp-content/themes
      - ./wp-content/plugins:/var/www/html/wp-content/plugins
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: wpdb
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_db_pass
      MYSQL_RANDOM_ROOT_PASSWORD: "1"
    volumes:
      - ./db:/var/lib/mysql
```

`docker-compose.yml`を配置したディレクトリに移動し、コンテナを起動する。

```bash
$ docker-compose up -d
```

# 2. 動作確認 & Wordpres初期設定

ブラウザでlocalhost:8080にアクセスし、Wordpressの初期設定画面が表示されれば成功。

初期設定を済ませたら、パーマリンクの設定を「投稿名」に変更する。
![スクリーンショット 2022-02-06 161107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325666/b46db5af-21db-5ad4-78e1-a80780c6a173.png)

# 3. Talend API Testerで記事一覧を取得

Talend API Testで以下のリソースパスを指定する。メソッドはGET。

`http://[ドメイン]/wp-json/wp/v2/posts`

`Send`ボタンを押すと記事一覧情報のレスポンスが返却される。

## Request
![スクリーンショット 2022-02-06 162223.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325666/418303d6-021a-2d5c-35f2-a1b39996acc6.png)

## Response
記事の著者、コンテンツ、タグ、カテゴリなどが返却される。
![スクリーンショット 2022-02-06 162251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325666/69e1412b-92fe-0a68-1fc1-acd3775d1b7f.png)

エンドポイントは公式ドキュメントがまとまっていて見やすい。

https://developer.wordpress.org/rest-api/reference/

#まとめ
WordPress REST APIはわりと昔からある印象ですが、以前はプラグインをいくつか導入する必要があったりと面倒なイメージがありましたが設定が非常に簡単になっていました。
リッチな管理画面付きのAPIサーバとして利用できそうですね。
WordPress REST API + React or Angular のような構成もありな気がします。
AWSのストレージのコスト比較

気になったので。
リクエスト数とかスループットとかはいったん無視。
感覚で把握しておきたい感じ。
サービスの特性とかは、他の方の記事をご参照ください。

100GB*720時間（1か月）

| サービス | USD |
|:-:|:-:|
|EBS(汎用SSD(gp2))|11.80|
|EFS|9.38|
|FSx|13.8|
|S3|2.5|
|S3 Glacier Instant Retrieval|0.5|
|S3 Glacier Deep Archive|0.2|
|消す！|0|

# 感想
EBSとそれ以外のストレージサービスはコストで比較してもしょうがない感じ。
シングルAZでよければ、EBSだしマルチAZにしたければそれ以外。
EFS or FSxはOSで決まる。

とにかくS3が安いので、コスト圧縮のポイント。

* 
新システムならS3を最初から利用
- オンプレから引っ越したシステムは、なる早でS3にファイルを移動

<dl>
<dt>WEBサーバー</dt>
<dd>IISログとかはCloudWatchに異動して、その後S3。</dd>
<dt>バッチサーバー</dt>
<dd>バッチの最後でEBSのボリュームまるごとスナップショットを取って日単位か月単位でS3に退避がシンプルっぽい。個人的には日単位かな。</dd>
</dl>

S3 Glacierも積極活用したい。
ゴミ箱感覚でS3 Glacier Deep Archiveは使うんだろうな。。。
本当は、削除がいいんでしょうけど、なかなか削除の判断って誰もしてくれないので。
とりあえず、残しておきたい。その気持ちはわかる。
[RxSwift6.0] withUnretained(_: )オペレータについて

##はじめに

本記事ではRxSwift6.0から追加された`withUnretained(_:)`オペレータについてどんなものか追求していこうという記事です。
ぜひ最後まで読んでいただければと思います！

##前提

RxSwiftを使用しているとき、subscribe(onNext:)などを使い強参照を防ぐことを目的にしたキャプチャリスト`[weak self]`や`[hoge]`で弱参照にしていることが多いと思います。
その場合、`guard let`で毎回アンラップして。。と本質の部分とは関係が薄い記述を含んでしまい、冗長なコードになりがちです。
今回紹介する`withUnretained(_:)`はそんなオブジェクトの参照を楽にしてくれます。

##RxSwift6.0で追加
`withUnretained(_:)`はRxSwift6.0から追加されたオペレータです。

https://github.com/ReactiveX/RxSwift/releases/tag/6.0.0

実際に使ってみます。

```swift
// 従来のweak selfを使う場合

hoge
   .subscribe(onNext: { [weak self] _ in
        guard let me = self else { return }
        me.foo.accept(())
}).disposed(by: disposeBag)
```


```swift
// withUnretainedを使う場合

hoge
   .withUnretained(self)
   .subscribe(onNext: { me, _ in
        me.foo.accept(())
}).disposed(by: disposeBag)
```

このオペレータを使用すると引数で渡したオブジェクトが弱参照のオブジェクトとしてタプル型に追加されます。
こうすることによって`guard let ~`の部分がそのまま消えスッキリ書くことができるようになります。

withUnretained内部のコードはこちらになっています。↓

```swift
    public func withUnretained<Object: AnyObject, Out>(
        _ obj: Object,
        resultSelector: @escaping (Object, Element) -> Out
    ) -> Observable<Out> {
        map { [weak obj] element -> Out in
            guard let obj = obj else { throw UnretainedError.failedRetaining }

            return resultSelector(obj, element)
        }
        .catch{ error -> Observable<Out> in
            guard let unretainedError = error as? UnretainedError,
                  unretainedError == .failedRetaining else {
                return .error(error)
            }

            return .empty()
        }
    }
```

error処理を内部で書いてくれているので、自分でelse { return 〇〇 }の型を考える必要も無くなりそうですね！
AZ-104 Microsoft Azure Administrator受験体験記

2022年頭に表題のAZ-104 Microsoft Azure Administratorに合格しました。
反省と振り返りを込めて記載しておきます。
## 受験者の経験
- Azure歴：1年程度。準備されたVMやDBを使用する機会が多く、仕組みや構築は経験が少ない。
- 他の資格：AZ-900は2019年に取得済み。
- クラウドサービスの経験：AWSはもっと知らない。
- 普段の仕事：プログラマから上流工程担当になったエンジニア。
- 得意：プログラム、DB設計などのアプリケーション。
- 苦手：インフラ系。特にネットワーク。
- 内実：本当はAZ-204を受験する予定だったのに間違って104の本を買ってしまったのでとりあえず受けることにしました。

## 実施内容
### Microsoft Learn
https://docs.microsoft.com/ja-jp/learn/
Microsoftが提供しているオンライン教材です。
試験内容と合致するもので網羅率も高いと思いますが、固有名詞同然のサービス名も無理矢理日本語化していたりして読みづらく、混乱しやすい文章でした。
演習が含まれていてAzure Portalやスクリプトを触る機会もあり、紙面や文章では理解が追い付かないところを実践で学べたのはよかったです。
### テキスト
下記を購入しました。

[合格対策 Microsoft認定試験AZ-104:Microsoft Azure Administratorテキスト＆演習問題](https://www.amazon.co.jp/%E5%90%88%E6%A0%BC%E5%AF%BE%E7%AD%96-Microsoft%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93AZ-104-Microsoft-Azure-Administrator%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%EF%BC%86%E6%BC%94%E7%BF%92%E5%95%8F%E9%A1%8C-ebook/dp/B09HT3HX8W)

内容はあっさりめですが簡潔で分かりやすく、Learnのくどいのによくわからない日本語に四苦八苦した身には大変ありがたい書籍でした。
章末問題、巻末の模擬試験もあってお得感もあります。
### Udemy
問題集を2件購入して実施しました。
テキストの問題集と合わせて3回ずつくらいやって最終的に9割以上得点できるようになりました。

  [AZ-104: Microsoft Azure Administrator 模擬問題集](https://www.udemy.com/course/az-104-microsoft-azure-administrator-practice-test-jp/)
  [AZ-104:Microsoft Azure Administrator模擬試験問題](https://www.udemy.com/course/az-104azure-administrator-associate/)

選択式のみなので実際の出題形式すべてには対応しきれていません。
またで解説などはMicrosoft公式ドキュメントへのリンクで済ませているものもあり、ここから知識を得ると言うより「最後の仕上げ」で使用するのがよいと考えます。
またモバイルで閲覧できるので出先の空き時間などを有効利用できるのはよかったです。

### その他
教材が複数に渡っていて
「これってどこに載っていたっけかな？」
が分からなくなる事態が多発したため、新しく知ったことをEvernoteにノートにしてまとめていました。
見返したり振り返るのも便利でしたし、書いて覚えるタイプなのもあって役に立ちました。

また管理の業務経験があまりなかったので「Azure Portalを実際に見てみる」「VMを作ってみる」などの実践も理解の助けになりました。

## 当日の試験内容
### 試験の構成
全部で62問でした。
下記3セクション構成です。
質問数は記憶が曖昧のため目安です。
#### 選択式など(約52問)
「択一式」「選択→順序設定」「複数選択」などがあります。
複数選択は部分点が出ます。
模試などではこの形式に沿った出題が多いです。
#### シナリオ(約5問)
「○○の問題があります。××で対応する予定です。解決できますか？」
と言う形式の問題です。
正誤式で見直しが出来ません。
サービス名と内容を正しく覚えていないと答えるのがつらいです。
#### ケーススタディ(約5問)
架空の会社にAzureを導入する計画に関する出題です。
会社の特性や現在の事業内容なども加味して回答する必要があるため丸暗記では厳しいのではないかと思います。
また「会社の概要」「現在の事業内容と課題」「Azureの何を導入してどうしたいか」などが別ページで切り替えないと参照できず、
「何を導入するんだったっけ？」
「何の事業をしているんだっけ？」
を見返すために何度もページを切り替えて思わぬ時間を食いました。

なお問題形式ごとにセクションが分かれていて、セクションごとに回答が締め切られます。
シナリオ問題に着手した後で選択式のセクションに戻ることは出来ず、見直しもセクションごとに行うことになります。
セクションの存在を忘れていて選択式に念を入れ過ぎて時間を使い切るとまだ問題が続いていてえらいことになります。
また先述の通りシナリオ問題は後からの見直しが出来ません。

### 内容の印象
「管理者向け」だからなのか、
「○○の課題を解決するためにはどうしたらいいのか」
「××の要望を実現するにはどうしたらいいのか」
などの運用との絡みを問う問題が多かったです。
またVPNやAzure ADのアカウント同期等、オンプレミスからの移行や併用に関する問題も多かったように思います。
サービスの内容を丸暗記するだけ、だと厳しいように感じました。

## 結果
752点で合格しました。
(1000点満点で700点で合格です)
当日ですが、時間配分を忘れて選択式セクションでかなりの時間を使い、後続のシナリオやケーススタディでかなり焦りました。
また上記の状態でケーススタディの画面切り替えで集中力がもたず、スコア低めですが合格出来たので御の字です。
かけた期間は1ヶ月でしたが年末年始の休暇が間にあったので勉強に割けた時間は多めでした。

## 余談
従来のCBTは勤務先近くのテストセンターで受験していたのですが、今回はコロナ禍で地元のテストセンターに初めて行きました。
テストルームが１つしかない上狭く、入り口で受験者に受講規定を説明する声がルーム内にまで聞こえてきてうるさかったです。。

## 総評
振り返ると当日の状況があまりよくなく、それでも受かったのは事前準備はそこそこ気合を入れた結果なのかと思います。
クラウドサービスについていろいろ勉強になって興味も沸いたので、他のAzure資格やAWSにも視野を向けたいなと思いました。
cloudwatchのアラームをslackに通知

#SNSでトピック作る
#CloudWatchでアラートを設定
説明にアラート出た理由書いとく
通知先を作ったSNSのやつにする
#slackのincomming webhookを発行
#lambdaで関数作成
トリガーを作ったSNSのやつにする
環境変数に以下追加
hookurl #slackのincomming webhookのurl
slackchannel #通知したいslackのチャンネル名
コードに以下入れる
必要であればtextの部分を編集する

'text': "<!here> \nアラーム名: %s\nステータス: %s\nアラーム理由: %s\n説明: %s" % (alarm_name, new_state, reason, alarm_description)

```
import boto3
import json
import logging
import os

from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

HOOK_URL = os.environ['hookurl']
SLACK_CHANNEL = os.environ['slackchannel']

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message))

    alarm_name = message['AlarmName']
    #old_state = message['OldStateValue']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']
    alarm_description = message['AlarmDescription']

    slack_message = {
        'channel': SLACK_CHANNEL,
        'text': "<!here> \nアラーム名: %s\nステータス: %s\nアラーム理由: %s\n説明: %s" % (alarm_name, new_state, reason, alarm_description)
    }

    req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
    try:
        response = urlopen(req)
        response.read()
        logger.info("Message posted to %s", slack_message['channel'])
    except HTTPError as e:
        logger.error("Request failed: %d %s", e.code, e.reason)
    except URLError as e:
        logger.error("Server connection failed: %s", e.reason)
```

#awscliで作ったアラームを強制的にアラーム状態にする
--alarm-name "作ったアラーム名"
--state-value ALARM　#ALAEM or OK
--state-reason "test"　#本来は～minimum 2 datapoints for OK -> ALARM transitionが出力される
--profile "Profile名" #profile設定している場合は入れる

state-reasonをちゃんと見たい場合はcloudwatchのアラーム設定で適当に閾値下げる

```
aws cloudwatch set-alarm-state --alarm-name "作ったアラーム名" --state-value ALARM --state-reason "test" --profile "Profile名"
```

lambdaの環境変数で指定したチャンネルに通知されればOK
たぶんawschatbotのほうが楽
macOS MontereyでXcode12が動く


####手順

######1. Xcode旧バージョンのファイル名を「Xcode_12.x.app」にしてApplicationsに格納する。

######2. コマンド

```
/Applications/Xcode_12.x.app/Contents/MacOS/Xcode
```

######3. コマンド実行中Xcode_12.x.appをクリック


参考：https://stackoverflow.com/questions/69994916/how-can-i-run-xcode-12-5-1-on-monterey
KeybaseにGPG Keyを登録しようとしたら、ERROR key generation error: Unknown signature subpacket: 34 (error 905)

:::note warn
記事中に出てくる GPG Key は、エラー発生時の鍵を再現してこの記事用に作成したものであって、有効なものではないです。
:::

## Keybase に GPG Key が登録できない

Keybase に自身の GPG Key を登録しようとした際に、うまく登録ができなかった。

```
$ keybase pgp select

▶ ERROR key generation error: Unknown signature subpacket: 34 (error 905)
```

（鍵が生成できない？なんで生成する必要があるのだろう？）

エラー発生時の自身の GPG Key は以下。

```
$ gpg --list-secret-keys

sec   ed25519 2022-02-06 [SC] [有効期限: 2023-02-06]
      E979BAF662EFB6AAB1E26955658D0C1407BAED3C
uid           [  究極  ] ohakutsu <dev@ohakutsu.com>
ssb   rsa4096 2022-02-06 [E] [有効期限: 2023-02-06]
ssb   rsa4096 2022-02-06 [S] [有効期限: 2023-02-06]
```

## preferences を書き換えることでうまくいった

[ERROR key generation error: Unknown signature subpacket: 34 (error 905), gpg (GnuPG) 2.3.1 libgcrypt 1.9.3 · Issue #4025 · keybase/keybase-issues](https://github.com/keybase/keybase-issues/issues/4025)の[コメント](https://github.com/keybase/keybase-issues/issues/4025#issuecomment-853933127)で AEAD を変更することでうまくいったとのこと。

### `keybase pgp gen`で作成された鍵を確認

```
$ keybase pgp gen
# 鍵を作成

$ gpg --edit-key [作成されたGPG KeyのID]

gpg> showpref
[  不明  ] (1). ohakutsu <dev@ohakutsu.com>
     暗号方式: AES, AES256, CAST5, 3DES
     AEAD:
     ダイジェスト: SHA256, SHA512, SHA1, RIPEMD160
     圧縮: 無圧縮, ZIP, ZLIB

gpg> quit
```

確かにAEADがない。

### 自分の GPG Key の preferences を変更

```
$ gpg --full-gen-key
# 鍵を作成

$ gpg --edit-key [作成したGPG KeyのID]

gpg> showpref
[  究極  ] (1). ohakutsu <dev@ohakutsu.com>
     暗号方式: AES256, AES192, AES, 3DES
     AEAD: OCB, EAX
     ダイジェスト: SHA512, SHA384, SHA256, SHA224, SHA1
     圧縮: ZLIB, BZIP2, ZIP, 無圧縮
     機能: MDC, AEAD, 鍵サーバ 修正しない

gpg> setpref AES256 AES192 AES 3DES SHA512 SHA384 SHA256 SHA224 SHA1 ZLIB, BZIP2, ZIP, Uncompressed

gpg> showpref
[  不明  ] (1). ohakutsu <dev@ohakutsu.com>
     暗号方式: AES256, AES192, AES, 3DES
     AEAD:
     ダイジェスト: SHA512, SHA384, SHA256, SHA224, SHA1
     圧縮: ZLIB, BZIP2, ZIP, 無圧縮
     機能: MDC, AEAD, 鍵サーバ 修正しない

gpg> save
```

### `keybase pgp select`

`keybase pgp select`で選択して完了

## ちなみに`ED25519`→`RSA`にしてもだめだった

[ERROR key generation error: Unknown signature subpacket: 34 (error 905), gpg (GnuPG) 2.3.1 libgcrypt 1.9.3 · Issue #4025 · keybase/keybase-issues](https://github.com/keybase/keybase-issues/issues/4025) によると、Keybase では GPG Key の暗号化方式が`ED25519`は使えないとあったので、とりあえず master key を`RSA`でつくり直してみた。

```
$ gpg --list-secret-keys

sec   rsa4096 2022-02-06 [SC] [有効期限: 2023-02-06]
      8E2954574BF9BF85064FFD0ECCC0DF51662B4571
uid           [  究極  ] ohakutsu <dev@ohakutsu.com>
ssb   rsa4096 2022-02-06 [E] [有効期限: 2023-02-06]
ssb   rsa4096 2022-02-06 [S] [有効期限: 2023-02-06]
```

再度、Keybase にあげようとしましたが、エラーになった。

```
$ keybase pgp select

▶ ERROR key generation error: Unknown signature subpacket: 34 (error 905)
```

## Ref

- [ERROR key generation error: Unknown signature subpacket: 34 (error 905), gpg (GnuPG) 2.3.1 libgcrypt 1.9.3 · Issue #4025 · keybase/keybase-issues](https://github.com/keybase/keybase-issues/issues/4025)
Google Colaboratoryのテキストで画像を埋め込む方法

GoogleDriveに格納した画像をGoogle Colaboratoryのテキストに埋め込む方法について説明する。
方法は以下。詳細は各章に記載。

1.埋め込みたい画像のリンクを取得
2.URLの整形
3. `![画像名](画像URL)`の"画像URL"部分に2.のURLをコピペ

## 1.埋め込みたい画像のリンクを取得
GoodleDriveに入れた画像を右クリック→リンクを取得→リンクをコピー
`https://drive.google.com/file/d/<画像ID>/view?usp=sharing`

### 例：
`https://drive.google.com/file/d/1exNkk_91H7fNdUl3lMqe5ggd3jXZJme2/view?usp=sharing`

※ 1exNkk_91H7fNdUl3lMqe5ggd3jXZJme2が\<画像ID\>に該当する。

## 2.URLの整形
1.で取得したURLの\<画像ID\>をコピーし、下記URLの\<画像ID\>部分に貼り付け。
`https://drive.google.com/uc?id=<画像ID>`


### 例：
1.で取得したURLの赤色部分をコピー
`https://drive.google.com/file/d/`<font color = "red">1exNkk_91H7fNdUl3lMqe5ggd3jXZJme2</font>`/view?usp=sharing`


下記URLの青色部分(URLの~id=以降)にペースト
`https://drive.google.com/uc?id=`<font color = "blue">1exNkk_91H7fNdUl3lMqe5ggd3jXZJme2</font>



# 3.`![画像名](画像URL)`の"画像URL"部分に2.のURLをコピペ
2.でできたURLを`![画像名](画像URL)`にコピぺ
`![任意の画像名を付ける](https://drive.google.com/uc?id=<画像ID>)`


### 例：
`![任意の画像名を付ける](https://drive.google.com/uc?id=1exNkk_91H7fNdUl3lMqe5ggd3jXZJme2)`


# 参考
https://medium.com/analytics-vidhya/embedding-your-image-in-google-colab-markdown-3998d5ac2684
未経験がLPIC101に合格した方法

![Something went wrong]()

頭の悪い私でもLPIC101に２ヶ月で合格できました！

学習期間は２ヶ月で特別早いわけではありませんがLPICを受けてみたい方や
学習中だけどなかなか捗らない方に少しでも参考になれば幸いです。

最後に反省点とLPIC102の学習の進め方についても記載したいと思いますので
ぜひ最後まで見ていってください。


[学習前の知識]
今まで製造業で働いており、excelの関数を少し使える程度

[1日の学習時間]
平日：2時間
休日：5時間

[使用した教材]
・LPICレベル１教科書(あずき本)　※以下 あずき本
・ping-t
・Udemyの模擬試験
・kindle版　LPICレベル１スピードマスター(白本) ※以下 スピマス

[私の学習手順]

あずき本 → ping-t → Udemy模擬試験 → スピマス

<12/8 ~ 12/20>
あずき本を2周する(問題は無視してとにかくインプット)

https://www.amazon.co.jp/Linux教科書-LPICレベル1-Version5-0対応-中島-能和/dp/4798160490/ref=sr_1_3?__mk_ja_JP=カタカナ&crid=27ALPOD6EZ0YE&keywords=lpic&qid=1644137850&sprefix=lp%2Caps%2C1233&sr=8-3

<12/20 ~ 2/4>
ping-tの最強web問題集を周回(２周目からは各項目ごとに30問ずつで回した)

<1/5 ~ 2/4>
Udemyの模擬試験を周回

https://www.udemy.com/course/lpic101102-lpic-level16360/

<1/20 ~ 2/4>
スピマスを周回
ping-tのコマ門を１周

https://www.amazon.co.jp/Linux教科書-LPIC-レベル1-スピードマスター問題集-Version5-0対応-ebook/dp/B07TVTKW2C/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1644137850&sr=8-4

[教材の優先度について]
①ping-t

こちらはwebサイトになりますが、LPIC101に関しては無料で使用することができます。
基本的に最強web問題集を周回していました。他にもコマ門という実際にコマンドを入力する形式の問題があり、こちらは１周くらいしかしていません。理由としては実際の試験に入力問題があまり出ないためで、本試験時も５問くらいしか出ませんでした。なので選択式の問題やあずき本などのインプットがしっかりできていればそこまで重要ではないと感じます。

②あずき本

こちらは値段が少し高いですが、かなりおすすめです。
最初にインプットで１周しましたが正直わけがわからなかったですw
しかし、上記のping-tと合わせて読むことで理解が深まりました。最終的に辞書のような使い方になっていきました。

③スピマス(kindle版)

上記の問題で物足りなかったり、周回するうちに答えを覚えてしまった際に有効な書籍となります。
内容は少し難しくなりますが、試験に不安がある方はおすすめです。

※ちなみに本試験ではこちらに掲載されている問題が体感で７割くらい出題されたような気がします。
 若干文言が変わっていたりしますがちゃんと理解していれば解けます。

④Udemyの模擬試験

優先度は最下位となっておりますが、私はスピマスを購入する前にこちらを解いていました。
問題の難易度はスピマスと同じくらいで、あずき本をしっかり理解していないと解けない問題が多いです
個人的には購入してよかったと思いますが、これから学習を始める方でスピマスまでやって他の問題も解いてみたい人は購入すると理解がかなり深まるのでおすすめです。


[反省点]
まずあずき本でのインプットで理解があまりできていないまま2周してしまい、半月くらい効率の悪い学習をしてしまいました。なので次回のLPIC102では分野ごとにインプット+アウトプットを繰り返しながら理解を深めていきたいと思っています。

[目標]
次回のLPIC102は、1ヶ月から1ヶ月半で取得できるようにできるだけ効率の良い学習方法で進めてまいりたいと思っています

[最後に]
今回IT系の資格にトライしたのは初めてで、これまで大した勉強もしてこず学歴も低いような私でも２ヶ月で１歩進むことができました。LPIClevel1の認定を受けるにはLPIC102の取得も必要なので目標通りの達成を目指し、他の資格にもチャレンジしていきたいと思っています。
ESP32をJavascriptでLチカする：最終系

これまで何回かの投稿で、ESP32をJavascriptで動かしていましたが、そろそろ最終系にしようと思います。
前回からの違いは、JavascriptをESP32にあるEEPROMに保存するところです。
Javascriptの更新は、HTTP Postのファイル添付で行います。アップロードするWebページも用意します。

ソースコードもろもろは、以下のGitHubに上げておきました。

poruruba/QuickJS_ESP32

https://github.com/poruruba/QuickJS_ESP32

#準備

以下のGitHubからZIPでダウロードして、Visual Studio CodeのPlatformIOから書き込むだけです。
ただし、以下の追加の作業が必要です。

①M5StickCかM5Core2か選択します。

Visual Studio Codeの一番下のところをクリックして、選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ddf28eee-6317-8f5a-29d0-514bc1f9b403.png)

②platformio.iniのCOMポート番号をESP32デバイスに合わせて変更します。

M5StickC用とM5Core2用の2か所がありますので、使う方を変更します。

upload_port = COM4
monitor_port = COM4

③EEPROMをErase＋書き込みします。

dataフォルダに、ブラウザから表示するWebページがあります。それをEEPROMに書き込みます。以下の順番に実行します。

・Erase Flash
・Build Filesystem Image
・Upload Filesystem Image

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f342702f-c189-f3fa-b701-70ba86b9b514.png)

④プログラムを書き込みます。

いつもの通り、下の方にある「→」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/8ef0c5ad-1332-3431-faa9-fc515479d9ce.png)

#ESP32起動直後

事前に、TeraTermなどのターミナルをCOMポートにつないでおくととよいです。
ESP32をリセットして起動します。

ESP32の初回起動直後は、WiFiアクセスポイントのSSIDやパスワードが設定されていません。
WiFi接続に失敗した後、COMポートにつないだコンソール（TeraTermなど）からSSIDとパスワードを聞かれるので入力します。
接続が完了すると、ESP32のIPアドレスが表示されます。次回からは入力不要です。

#Javascriptプログラムの書き込み

ブラウザから、ESP32のIPアドレスを開きます。

http://[ESP32のIPアドレス]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/385de562-8bbf-e960-1ff9-f4e0a15f6616.png)

テキストエリアに以下を入力して、アップロードボタンを押します。

```js
import * as gpio from "gpio";

var led = gpio.LOW;
var counter = 0;

async function setup(){
	var ipaddress = esp32.getIpAddress();
	console.log("ipaddress=" + ((ipaddress >> 24) & 0xff) + "." + ((ipaddress >> 16) & 0xff) + "." + ((ipaddress >> 8) & 0xff) + "." + (ipaddress & 0xff));

    gpio.pinMode(10, gpio.OUTPUT);
    gpio.digitalWrite(10, led);
}

async function loop(){
	console.warn('hello ' + counter++);
        led = (led == gpio.LOW) ? gpio.HIGH : gpio.LOW;
        gpio.digitalWrite(10, led);
	delay(1000);
}
```

そうすると、プログラムが書き込まれ、LEDがちかちかするはずです。
EEPROMに保存しているので、電源Off/Onした後も継続します。

M5StickCを想定し、LEDがGPIO 10にある前提です。

もし、CLIで更新したい場合は、ファイルにJavascriptを書き込み、Curlで送ってあげるとよいです。

```
> curl -X POST -F upfile=@main.js http://[ESP32のIPアドレス]/upload_js
```

どんなJavascriptのAPIがあるかは以下を参照してください。

https://github.com/poruruba/QuickJS_ESP32/tree/main/doc

以上
AWS DBまとめ

#AWSで用意されているDBの種類
* RDS
* DynamoDB
* RedShift
* ElastiCache
* Neptune
* Athena

## RDS
* リレーショナルデータベース（RDB）
* 以下のDBエンジンをサポートしている
    * Amazon Aurora
    * PostgreSQL
    * MySQL
    * MariaDB
    * Oracle Database
    * Microsoft SQL Server

### Amazon Aurora
* AWSが開発したRDB
* PostgreSQL,MySQLと互換性がある<br>⇒アプリを変更することなくAuroraにデータ移行でき、さらにこれらのDBエンジンより高スループットらしい。
* 構成
    * 3ヶ所のAZにある
    * SQL処理を担う**データベースインスタンス**（図上側）
    * ストレージを担う**クラスターボリューム**（図下側）
    * データベースインスタンスのうち1つ(図のAZa上)は、**プライマリデータベースインスタンス**と言い、読み取り・書き込みを行う。
    * 残り2つ(図のAZb,c上)は**Auroraレプリカ**と言い、読み取りのみを行う。
    * 一つのAZにつき2か所のディスクに書き込まれるため、データは合計で6か所に保存される。<br>⇒**障害時のダウンタイムはほぼ無い。**
* 図<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/3ac9ff64-45ff-60b7-2346-23535d9e30a8.png)

画像引用：[AWS公式 Amazon Aurora DB クラスター](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.html)

### マルチAZ
* 説明<br>複数のAZにRDSを構築すること。
* 機能<br>有効にすると、マスターのDBインスタンスを自動で作成し、異なるAZにあるインスタンスにデータを複製する。<br>⇒耐久性と可用性が向上
* 構築方法
[[AWS_22]RDSを冗長構成にする](https://qiita.com/yoshiki_mbp/items/5e03496d9c4dfef2dd1d)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/19b5e179-471b-23fc-7ade-15d5a168b5bf.png)

### リードレプリカ
* 説明
    * マスターDBと同じDBを構築し、読み取り専用としてRDSを構築したもの。<br>⇒読み取りスループット向上
    * マルチAZやリージョン間で構築できる
    * 同期処理は非同期<br>**マルチAZは同期レプリケーションだが、リードレプリカは非同期レプリケーション**
* 図<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/e836edb2-4aa2-9020-084d-3fe5cdd13993.png)
<br>画像引用：[AWS公式 リードレプリカの使用](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ReadRepl.html)

## DynamoDB
* NoSQL型のデータベース。（NoSQL：非RDBMSの総称）<br>非構造・半構造データを扱う。
    * 半構造データ<br>ログ、センサーデータ、位置情報、設定ファイルなど
    * 非構造データ<br>テキストファイル(メモ書き)、音声データ
* キーバリュー型データモデル
    * NoSQLの代表的なデータモデル
    * データはキーとバリューから構成される<br>⇒RDBのような数値や文字列ではなく、JSONのようなデータもバリューとして格納できる
* マルチAZ<br>DynamoDBでは、**自動で3ヶ所のAZに保存**される
* 結果整合性モデル<br>マルチAZにより、3ヶ所への書きこみ完了に時間がかかる。そのため書き込みは時間が経てば反映されるが、**読み取りのタイミングによっては書き込んだデータが反映されていない**ことがある。<br>その対策として**「Consistent Read」**というオプションがある。このオプションにより、書き込みが反映された最新データを読み取ることができる。

## RedShift
* データウェアハウス
* BIツールを利用した大量データの集計・分析ができる
* 実体は**ノード**と呼ばれるコンピューティングリソースの集まり<br>**リーダーノード**が処理を受け、**コンピューターノード**に処理を依頼する。これらの集まりを**クラスター**という。
* 図<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/607a9a94-30c5-0dc0-9b91-2fdd67211705.png)<br>
画像引用：[データウェアハウスシステムのアーキテクチャ](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_high_level_system_architecture.html)
* **クロスリージョンスナップショット**<br>スナップショットを別のリージョンにコピーするように設定すること。<br>⇒リージョン障害時に復元できる。

## ElastiCache
* インメモリデータベース
* メモリ上で処理を実行する<br>⇒高スループット＆低レイテンシー
* キャッシュを利用しない一般的なWebサーバでは常にDBにクエリを投げるため負荷がかかる。ElastiCacheを挟むことで、DBの負荷軽減ができる。
* 図<br>【一般的なWebサーバーのDBクエリ】<br>Webアプリ→DB<br>【ElastiCacheのアーキテクチャ】<br>EC2→ElastiCache→RDS
【メモ】reshapeについてjuliaとpythonの違い


# reshapeについてjuliaとpythonで違うところまとめ
reshapeを使うときに、juliaとpythonで違う点があったので、その違いについて紹介する。

## 一次元配列を二次元配列にするとき

### Julia

例えば、一次元配列を2×3の行列になおしてみる。

```julia
a = [1,2,3,4,5,6]
b = reshape(1:6, 2,3)
```
結果は、

```
2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:
 1  3  5
 2  4  6
```


1,2の配置を見てわかるように、juliaでは行が最初に変わることになるので、行列の行が優先して変わることになる。

### python

```python
import numpy as np
a = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
b = a.reshape(2,3)
```

結果は

```
array([[1., 2., 3.],
       [4., 5., 6.]])
```

juliaの場合と結果が異なる。pythonでは1,2,3の配置を見てわかるように、列が最初に変わっているので、行列の列が優先して値が変わることになる。

## 二次元配列を一次元にする

### Julia

```julia
A = Vector(1:16) # 16-element Vector{Int64}:
b = reshape(A, 2, :)
2×8 Matrix{Int64}:
 1  3  5  7   9  11  13  15
 2  4  6  8  10  12  14  16

reshape(b, 1, :)
1×16 Matrix{Int64}:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16
```

このとき、reshapeの内部で大体行われていることは

```julia
c = []
for j in 1:8
    for i in 1:2
        push!(c, b[i,j])
    end
end
```

このように行列の足bijの内、juliaではiのループが先に走ることになる。これはメモリ空間で行優先であることに対応がつく。

### python

```python
a = np.arange(6).reshape(2, 3)
a

===== 結果=========
array([[0, 1, 2],
       [3, 4, 5]])
==================

a.reshape(-1)

=======結果==========
array([0, 1, 2, 3, 4, 5])
==================
```

reshapeの内部では以下のようなことが行われている。

```python
a = np.arange(6).reshape(2, 3)
l = []
for i in range(2):
    for j in range(3):
        l.append(a[i,j])
np.array(l)
```

このようにjのループが先に走ることになる。これはメモリ空間では列優先であることに対応する。

## 多次元配列
以下はおまけです。
最後に突然だが、物性物理に出てくる2サイトハバードモデルのハミルトニアンを作ってみる。

### python

```python
import numpy as np

nsites = 2
up = 0
down = 1
t = 1.0
tij = np.zeros((nsites, 2, nsites, 2))
for isite in range(nsites-1):
    tij[isite, up, isite+1, up] = t
    tij[isite+1, up, isite, up] = t 
    tij[isite, down, isite+1, down] = t
    tij[isite+1, down, isite, down] = t

tij = np.reshape(tij, (2*nsites, 2*nsites)) 

```

確認

```
print(tij[0, 2]) #1サイト目のup 2サイト目のupのホッピング
print(tij[2, 0]) #上の1<->2をした場合
print(tij[1,3])  #1サイト目のdown 2サイト目のdownのホッピング
print(tij[3,1])  #上の1<->2をした場合
```

クーロン相互作用の項は、

```
nsites = 2
up = 0
down = 1
U = 1.0
Uijlk = np.zeros((nsites, 2, nsites, 2, nsites, 2, nsites, 2))
for isite in range(nsites):
    Uijlk[isite, up,   isite, down , isite, up,   isite, down] = U
    Uijlk[isite, down, isite, up,    isite, down, isite, up]   = U
    
#print(Uijlk)
Uijlk = np.reshape(Uijlk, (2*nsites, 2*nsites, 2*nsites, 2*nsites));
print(Uijlk)
```

結果

```
print(Uijlk[0, 1, 0, 1]) 
#1サイト目のupの生成, 1サイト目のdown生成, 1サイトめのupの消滅, 1サイトめのdownの消滅演算子 
print(Uijlk[2, 3, 2, 3])
#2サイト目のupの生成, 2サイト目のdownの生成, 2サイトめのupの消滅, 2サイトめのdownの消滅演算子 
```

欲しい結果が得られた。

### Julia
上のpythonコードのtij,Uijlkをisite先ではなく、up or down　を先に書くようにコードを変えれば良いです。

# まとめ

juliaとpythonでreshapeの違いについて理解を深めました。
Gemfuryでaptリポジトリ作成してCIでpush

# 概要

- Gemfuryは無料で複数の形式のパッケージをアップロード・公開できる
- Debian/Ubuntuだとdeb形式のパッケージを使うが、これもアップロード・公開できる→aptリポジトリ
- それをCIでやる方法を記載する

## 準備

- Gemfuryでアカウントを取得する https://gemfury.com/
- アップロードするdebファイルを作成する
- Gemfuryにログインし、`Profile > Tokens > FullAccessToken` をコピー
  - 個人用なのでFullAccessTokenを使いますが、仕事とかの場合はpush tokenにしたほうがいいかな？

- CIの方の設定で以下のプロセスを追加(debianの例)
  - fury-cliのインストール

```shell
echo "deb [trusted=yes] https://apt.fury.io/cli/ * *" > /etc/apt/sources.list.d/fury-cli.list
apt-get update -y
apt-get install -y fury-cli
```
  - .netrcの追加(rootユーザで実行する場合の例)

```shell
echo "machine api.fury.io"                > /root/.netrc
echo "  login <gemfuryで使うメールアドレス>" >> /root/.netrc
echo "  password <Token>"                 >> /root/.netrc
```

  - パッケージの更新処理

```shell
if [ $(fury versions <パッケージ名> --api-token <Token> | grep <バージョン> | wc -l) -gt 0 ]; then
    # アップロード済みのパッケージがあれば削除
    fury yank <パッケージ名> -v <バージョン> --api-token <Token> ;
fi
fury push <アップロードしたい.deb> --api-token <Token>
```

トークンは秘密情報として扱いましょう, CircleCI, Travis, GitHub Action等々credentialを秘密の変数として使う方法はあるのでそれを使う。

## Debian/UbuntuでGemfuryにアップロードしたパッケージを使う方法

- Gemfuryで発行されるトークンを使用して, `/etc/apt/auth.conf.d/` 以下にconfファイルを作成する
- 参考: [APT_AUTH.CONF(5)](https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html)

```shell
$ sudo cat /etc/apt/sources.list.d/fury.list
deb [trusted=yes] https://cli.gemfury.com/apt/ /
deb [trusted=yes] https://apt.fury.io/<Gemfury上のユーザー名>/ /
```

```shell
$ sudo cat /etc/apt/auth.conf.d/fury.io.conf
machine apt.fury.io
login <Gemfury上のユーザー名>
password <Gemfuryで発行されるトークン>
```

準備ができたら `sudo apt-get update -y` すればパッケージが取得可能になるはず


## 備考

- fury-cliが内部で.netrcファイルを見ており、それの設定に手間取った
自動微分で与えられた行列を再現

# 自動微分を使って、与えられたテンソルを再現

簡単のため以下の例題を考えます。


Aという3×3行列を与える。ゴールは適当なテンソル（ここでは行列）Xと自動微分を使って、この行列Aを再現すること。
具体的な手順
step1　Xという3×3正方行列を与える。Xの行列要素は適当なパラメータを振る。`
step2　C＝|A - X|^2 という値を計算する。この量は行列の各要素の引き算の二乗である。（A＿11ーX＿11）＾２＋（A＿12ーX＿12）＾２＋、、、となる。
step3　Xの行列要素に含まれるパラメータに関してCを自動微分をすることで最適化を行う。
step4　Cの最適化が終わったら、行列XはAを再現している。



## 例題の実装

```julia
using Zygote

θ = π/6

const B = [
           cos(θ) -sin(θ) 0
           sin(θ) cos(θ) 0
           0. 0. 1
           ]


square(x) = x^2

metric(X, B) = sum(square, X.-B) #ここでブロードキャストを使う。わざわざ一次元配列に直さなくて良い。

f(X) = metric(X, B)
∂f(X) = gradient(f, X)[begin] #fをXの各成分で微分せよという意味

X_init = rand(3, 3)

X = X_init
η = 0.1

for _ in 1:100
    X .-= η .* ∂f(X)
end

```

結果

```julia
@show metric(X, B)
X #これはBという与えられた行列を再現している。

```

より高次元の配列にも適用可能である。

## まとめ
ブロードキャストと自動微分を使って、与えられた行列を再現してみました。より一般のテンソルの再現にも適用可能です。
Ubuntu Server 20.04.3 LTS 構築#10 セキュリティ設定5-3

実施日:2022/01/22～

<<今回の内容>>
シェルスクリプトで実行したスキャンのエラー解消

`Total errors:65433
/etc/clamav/clamscan.sh:行　18:構文エラー:予期しないファイル終了(EOF)です。`

まずは
`Total errors:65433`
このエラーから解消していきます。

スキャンした際にどこかのディレクトリで発生している。

`less /home/ユーザー名/Documents/ログファイル名.log | grep error`

ログを確認すると、①/proc/ ②/usr/ ③/sys/
上記、3ディレクトリの中のファイルでエラーが出ていました。
除外設定は--exclude-dir=以下に対象のディレクトリを記述すれば除外出来ます。
しかし、これらを除外していいものなのかそれぞれのディレクトリの役割を確認してみます。

:::note
/proc
カーネル内部の情報にアクセスするための仮想的なファイルシステム。
実際はディスク上に存在しない。
:::

:::note
/usr
コマンドやユーティリティなどが配置されている
その下層は細分化されている/usr/binや/usr/sbinなど
:::

:::note
/sys(/sysfs)
/proc同様に仮想的なファイルシステム
:::

/procと/sysはスキャン対象から除外して良さそうなので、除外対象にします。

再度、スキャンを実行。
表示されていたTotal errosの項目は表示がされていませんでした。

また、予期しない構文エラーは該当行にif構文を記載していました。
この箇所は次回の記事で準備していたものを事前に記述していました。
if構文を削除したところ、エラーは消えました。

本日はここまで
【laravel】configフォルダを使用したプルダウンの作り方

##【概要】
プルダウンを作成する際viewをスッキリさせたかったので、configフォルダにプルダウンで表示したい項目を記述し、viewに引っ張ってくる方法で作成しました！

完成図はこんな感じになります。
（今回は都道府県のプルダウンを作成します！）

![プルダウン検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1046420/dd465466-2a4d-0aae-2bce-8be08ded9255.png)

![プルダウン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1046420/2bb253d4-d505-0c47-6519-4117e62592ce.png)


##①プロジェクトのconfigフォルダにPrefectures.phpを作成
configフォルダにPrefectures.phpを作成し、47都道府県を連想配列で記述します。

```php:Prefectures.php
<?php 

return [
    '0' => '未選択',
    '1' => '北海道', 
    '2' => '青森県', 
    '3' => '岩手県', 
    '4' => '宮城県',
    '5' => '秋田県', 
    '6' => '山形県', 
    '7' => '福島県', 
    '8' => '茨城県',
    '9' => '栃木県', 
    '10' => '群馬県', 
    '11' => '埼玉県', 
    '12' => '千葉県',
    '13' => '東京都', 
    '14' => '神奈川県', 
    '15' => '新潟県', 
    '16' => '富山県',
    '17' => '石川県', 
    '18' => '福井県', 
    '19' => '山梨県', 
    '20' => '長野県', 
    '21' => '岐阜県', 
    '22' => '静岡県', 
    '23' => '愛知県', 
    '24' => '三重県',
    '25' => '滋賀県', 
    '26' => '京都府', 
    '27' => '大阪府', 
    '28' => '兵庫県',
    '29' => '奈良県', 
    '30' => '和歌山県', 
    '31' => '鳥取県', 
    '32' => '島根県',
    '33' => '岡山県', 
    '34' => '広島県', 
    '35' => '山口県', 
    '36' => '徳島県',
    '37' => '香川県',
    '38' => '愛媛県',
    '39' => '高知県', 
    '40' => '福岡県',
    '41' => '佐賀県', 
    '42' => '長崎県', 
    '43' => '熊本県', 
    '44' => '大分県',
    '45' => '宮崎県', 
    '46' => '鹿児島県', 
    '47' => '沖縄県'
];

```

'0'に'未選択'を設定することで、上の画像のようにプルダウンが閉じた状態の時に'未選択'が表示されるようになります。

##②controllerに追記
※今回は検索機能でプルダウンを使用したのでsearchInputメソッドに記述しています

```php:××××Controller.php
    public function searchInput(Request $request)
    {

      //省略

      //configのPrefectures.phpの情報を$prefecturesに代入
      $prefectures = config('Prefectures');   //追記

      //viewに　$prefectures　を渡す
      return view('search_input', [
            "prefectures" => $prefectures,    //追記
        ]);

```
##②viewに追記

```php:search_input.blade.php

<form method="get" action="/search" class="search-form">
                
        @csrf

            <div class="form-group">
                <div class="font-weight-bold"><label for="prefectures">勤務地</label></div>
                <select class="form-control" name="prefectures">

                    /*
                    viewでは、foreachを使用し$prefecturesをkey($key)とvalue（$prefecture）で取り出しています。
                    ＄keyはoptionタグのvalueに指定しておきます。   
                    */
                    @foreach($prefecturs as $key => $prefecture)
                        <option value="{{ $key }}">
                            {{ $prefecture }}
                        </option>
                    @endforeach
                </select>
            </div>

        //省略
```

これでうまく表示できているかと思います！


##最後に
この書き方をすることで、プルダウンの内容に変更や追加があった場合configのファイルをいじるだけで修正ができ、また、viewのコードがすっきりするので何かと便利かと思います。
プルダウンを使う際、参考になれば幸いです！
Gitコマンドまとめ

#はじめに
この度、Gitの学習を始めるにあたって簡単に学習内容やGitコマンドをまとめています。


# ローカルからgitにアップするまでの流れ

#####・新規プロジェクトから始める場合・
```python
#1. GitのHPに新規リポジトリを作成する。（githubのHPから作成）
#2. ローカルリポジトリを作成する。（対象ファイルに移動し実行）
$ git init

#3. リモートリポジトリを追加する。
$ git remote add origin (HPで作成したURL)

#4. ステージングエリアにフォルダをアップする。
$ git add .

#5. リモートリポジトリにファイルをプッシュする。
$ git push -u origin master
```

<br>
#####・既存のプロジェクトから始る・
1. 既存のGitHub上のプロジェクトのURLをコピーする
1. 任意の場所にディレクトリを用意・移動する
1. Git cloneコマンドでリモートリポジトリから情報をコピーする

Gitのデータの持ち方
・圧縮ファイル（ファイル）
・ツリー（コミットしたときのスナップショット?）（ファイル、圧縮ファイル）
・コミット（ツリー、作成者、日付、コミットメッセージ、（親コミット））


####リポジトリについて
・リモートリポジトリは複数登録することができる





### Gitの準備をする
#####ローカルリポジトリを新規作成する。
```
$ git init
```
「.git」ディレクトリ（gitで必要なデータ）が作成される。

#####既存のプロジェクトから始める場合の始め方
リポジトリをコピーする
① Gitの該当PJのページにある「Clone or download」をクリックし、URLをコピーする。
② 任意のディレクトリ内で以下のコマンドを入力する。
　※リモートリポジトリから、ワークツリーと.gitディレクトリがローカルにコピーされる。

```
$ git clone <リポジトリ名(URL)>
```


---
###X. Gitの変更を取り消す・やり直す

#####ファイルへの変更を取り消す
ワークツリーの状態をステージの情報で上書きし、変更前の状態にする。

```
$git checkout -- <ファイル名>
$git checkout -- <ディレクトリ名>

# 全ファイルの変更を取り消す
$git checkout -- .
```

#####ステージした変更前を取り消す

```
$git reset HEAD <ファイル名>
$git reset HEAD <ディレクトリ名>
# 全変更を取り消す
$git reset HEAD .
```

#####直前のコミットをやり直す
直前のコミットを上書きし、コミットをやり直す。

```
$git command --amend
```



#####リモートリポジトリとは

#####設定しているリモートリポジトリを表示する

```
$ git remote

#対応するURLを表示
$ git remote -v

# より詳細に情報を表示する
$ git remote show <リモート名（origin）>
```

#####リモートリポジトリを新規追加する

```
$ git remote add <リモート名>　<リモートURL>

# sampleとういうショートカットでurlのリポジトリを登録
$ git remote add sample　https://github.com/user/repo.git

```

#####リモートを変更・削除する

```
#変更する
$ git remote rename <旧リモート名> <新リモート名>

#削除する
$ git remote rm <リモート名>
```



####リモートリポジトリから情報を取得する
リモートリポジトリから情報を取得する方法は2つあります。

・git fetch
 → リモートリポジトリからローカルリポジトリに情報を撮ってくる（ワークツリーには反映されないため、git mergeが必要）

・git pull
 → リモートか情報を取得、マージを一気に行う（処理的にはgit fetch、git mergeを一度に行っている）

＜使い分け＞
結論：fetchを使いましょう

pullを実行すると、pullしたブランチはすべてmasterブランチにマージされてしまう。（統合する気はなくても誤ってブランチが統合されてしまう。）

####ブランチについて

#####ブランチとマージについて
ブランチ：コミットを指したポインタ
・並行して複数機能を開発する仕組み　
・ブランチを分岐させることで、他の開発の影響を受けない

HEAD現在自分がいるブランチを指す

#####ブランチを新規作成する（作成しいても移動はしない）

```
$ git branch <ブランチ名>

#ブランチの一覧を表示する
$ git branch

#全てのブランチを表示する
$ git branch -a
```

#####ブランチを切り替える

```
$ git chceckout <既存のブランチ名>

#ブランチを新規作成して切り替える
$ git chceckout -b <新しいブランチ名>

```


マージ：他の変内容更を取り込むこと
マージには以下の３種理が存在する
・Fast Foward(早送りになるマージ)
・Auto Marge（基本的なマージ）
・confrict（同じファイル同じ場所に対して変更を行ったとき）


#####変更履歴をマージする

```
$ git merge <（リモート名）/（ブランチ名）>
```


#####ブランチを変更・削除する

```
#ブランチの名前を変更する
$ git branch -m <ブランチ名>

#ブランチを削除する（masterにマージされていないものがある場合、削除されない）
$ git branch -d <ブランチ名>
#強制削除する
$ git branch -D <ブランチ名>
```

####ブランチの利用方法について
masterブランチをリリース用のブランチ、開発はトピックブランチを作成して進める
→masterブランチはあくまでもリリース用として利用し、
機能の開発ごとに最新のmasterブランチからブランチを切って、トピックブランチを作成し、
そこで開発を行う。
conda installでインストールできなかった場合の対応

ここでは筆者が直面したパッケージのインストール失敗の際に行なった解消方法についてまとめる。




解消方法
channelを追加し、再度インストールを実行する
ANACONDA.ORGのページからパッケージを検索し、指定コマンドを実行する
https://anaconda.org/

以下を実行

```
$ conda skeleton pypi pycodestyle_magic
$ conda build pycodestyle_magic
$ conda install --use-local pycodestyle_magic
```

参考：https://analytics-note.xyz/mac/conda-skeleton-pypi/
【Javaの基本①】クラスの構造

## はじめに
オラクル認定資格教科書 Javaプログラマ Silver SE８
第一章　Javaの基本　←　ｲﾏｺｺ！！
第二章　Javaのデータ型の操作
第三章　演算子と判定構造の使用
第四章　配列の作成と使用
第五章　ループ構造の使用
第六章　メソッドとカプセル化の操作
第七章　継承の操作
第八章　例外の処理
第九章　Java APIの主要なクラスの操作

## クラスとは
どんなデータを扱っているのかやどのような処理を行うのかを
**フィールド**と**メソッド**で書いていくが、それらを機能や種類等でまとめて置くのがクラスである。
Javaのプログラムは複数のクラスが組み合わさって作られている。

## クラス宣言
クラス宣言はフィールドとメソッドの２つで構成されている。

・フィールドとは
 フィールドはクラスの中でデータの値を保管するために使用するもの。

```
class クラス名{
  データ型 フィールド名;
}
```
・メソッドとは
 メソッドはクラスの中で特定の処理を行うために必要なプログラムをまとめたもの。

```
class クラス名{
  void メソッド名(){
    [メソッドでやりたい処理]
  }
}
```
特別なメソッドでコンストラクタというものも
・コンストラクタ
　クラスからインスタンスを作る時、最初に実行される処理のこと。
　　→クラス名と同じ名前を持つ
　　→メソッドとしての戻り値を持たない(途中でのreturnもできない)
　　→インスタンスが作られる時には必ず実行される

```
class クラス名{
  クラス名(){
	[コンストラクタでやりたい処理]
  }
}

```

## リンク集
[【Javaの基本①】クラスの構造](https://qiita.com/vitamin_b12/items/3f920cd223fd3cc1ceae)
[【Javaの基本②】パッケージとインポート](https://qiita.com/vitamin_b12/items/be766c8c3ef2366d9fea)
[【継承の操作②】インターフェース](https://qiita.com/vitamin_b12/items/cdc76298d7f6a494dff2)
[【Javaのデータ型の操作①】プリミティブ型のデータ・参照型](https://qiita.com/vitamin_b12/items/f922ab56e4d8b6580f49)
[【演算子と判定構造の使用①】論理演算子(&&、||)、同一性（==）、同値性(equals)](https://qiita.com/vitamin_b12/items/9feb89e8fb1bc67a8d6d)
[【演算子と判定構造の使用②】分岐処理(if、swich)](https://qiita.com/vitamin_b12/items/523467908e683474eac7)
[【配列の作成と使用】](https://qiita.com/vitamin_b12/items/2fc45588640c479e1f4d)
[【ループ構造の使用】while文、do-while文、for文、拡張for文](https://qiita.com/vitamin_b12/items/23d853dda9baf727e4ac)
[【メソッドとカプセル化の操作①】メソッドの概要](https://qiita.com/vitamin_b12/items/215ad731221c2691c441)
[【メソッドとカプセル化の操作②】オーバーロード、コンストラクタ](https://qiita.com/vitamin_b12/items/e4fd3d51a35bb6a5566c)
[【継承の操作①】クラスの継承](https://qiita.com/vitamin_b12/items/19f8ad6f9801ac8f6a8f)
[【例外の処理】](https://qiita.com/vitamin_b12/items/f7ebf2c1106a7dcbdb41)
[【Java APIの主要なクラスの操作】](https://qiita.com/vitamin_b12/items/dcd3edfe2273e5a09231)
Tableauで人流オープンデータを月ごとに可視化する

# はじめに

https://qiita.com/ppt_msdg_maas/items/19d0946ec46551dec88f

この記事を参考にさせていただきながら、
Tableauで人流オープンデータを月ごとに可視化する方法をまとめます。

完成イメージはこちら
![スクリーンショット 2022-02-06 17.06.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/b17c675f-5208-6267-1e59-71c430df6ddc.png)


# 使用するデータ
G空間情報センターが公開している、「全国の人流オープンデータ（1kmメッシュ）」
を使用します。2021年4月に、2019・2020の2年分の人流データが公開されましたが、
つい最近、2021年分のデータも公開されたため、これで36ヶ月分の人流データを利用できるようになりました(^^)
新規ユーザ登録してログインすると、データをダウンロードできるようになります。

https://www.geospatial.jp/ckan/dataset/mlit-1km-fromto

# 使用するBIツール
Tableau Desktop Professional Edition
Ver.2021.3.6

# データの読み込み・結合
G空間情報センターの人流オープンデータは1ヶ月ごとにcsvファイルで公開されているため、
36ヶ月分のcsvファイルを結合してあげる必要があります。
ダウンロードしたzipファイルを解凍すると、自分は愛知県の人流データを選んだため、「23(都道府県コード)」というフォルダに、
2019年1月から2021年12月までのデータが年月ごとに分かれて格納されています。
![スクリーンショット 2022-02-06 17.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/9f6afbc7-df98-4305-21f2-3378c0491937.png)
1ヶ月分のCSVファイルは以下のようになっています。
![スクリーンショット 2022-02-06 17.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/fa5eb25d-9f75-a753-5610-0a5149ac65cb.png)
これを36ヶ月分、縦に結合したいため、TableauにてUNIONを使います。
36ヶ月分のファイルをそれぞれ解凍し、結合しやすいように1つのフォルダにまとめてみました。
この時に、ファイル名に「20190101」のように年月を入れておくと後で[Path]から年月を取り出すことができ、年月ごとの可視化に役立ちます。
![スクリーンショット 2022-02-06 17.39.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/019c2bca-5d0a-9c10-db8e-e3df2aa23270.png)
そしたら、Tableauにて、まずは2019年1月分のcsvファイルだけ読み込み、結合を行います。
「ユニオンの編集...」をクリックし、
![スクリーンショット 2022-02-06 17.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/705d0d3d-6ae2-1d59-c9f2-450c5864251b.png)
ワイルドカード(自動)を使って、`*.csv`と指定し、フォルダ配下の全てのcsvファイルを縦に結合させます。
![union.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/00f65558-841b-2b38-01d8-166140c68f3c.png)

# [Path]から年月ディメンションの作成
結合したファイルを読み込むと、[Path]というディメンションが使えるようになっているので、そこから年月を取り出します。
![スクリーンショット 2022-02-06 17.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/9c2ef71e-2696-b7c4-b457-3d17b9d3249a.png)
年月という計算フィールドを作成し、正規表現で[Path]の8桁の数字を取り出し、日付型に変換しています。

# 月ごとに人流データを可視化
メッシュデータの読み込みやメッシュデータと人流データの結合方法、DayflagおよびTimezoneのフィルター作成については上記記事( https://qiita.com/ppt_msdg_maas/items/19d0946ec46551dec88f ）を参照いただくと良いです。
それができたら、年月のフィルターを作成します。年月ディメンションをフィルターのとこまでドラッグし、フィルター方法は「年/月」を選択して、すべての年月を選択し、OKをクリックします。
![year-month.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/9540e0e6-707d-41a0-e607-ae075154ff08.png)
![all-month.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/fb916cb4-5156-c3ed-e132-8aa69c81e026.png)
最後にフィルターを表示し、「単一値（スライダー）」を選択します。
![slider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/1a1393d2-7d46-381d-5544-03b897d9ff34.png)
すると、スライダーを動かすことで、1ヶ月ごとの人流データを見れるようになりました!
![スクリーンショット 2022-02-06 18.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/f501fdb9-fff1-759d-4b3b-a4fae9b8dda1.png)
何か間違い等ありましたら、ご指摘いただけると嬉しいです。