OmniAICreator/Qiita-1.07M huggingface dataset:
p5.playをやる記事#08_当たったら跳ね返る

[前回の記事](https://qiita.com/sdkfz181tiger/items/83685adaeaa426cea7bd) | [次回の記事](https://qiita.com/sdkfz181tiger/items/1ac1a9f4f966e6c52ab0)

p5.playの使い方を解説しております。
[第1回の記事](https://qiita.com/sdkfz181tiger/items/c424b0777f7d7fe2203a)はこちらにありますのでご参照ください。

## 当たったら跳ね返る
今回は衝突判定のお話です。
スプライト同士の衝突を判定し、跳ね返りをさせてみましょう。

今回は2枚の画像を用意しました。(お使いください)

![t_tanu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/c39333ca-47ba-49bc-998f-7038734689b1.png)

![t_ninja.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/ba01e71e-9c1c-8178-7a72-c443eaf008d2.png)

先ずは2つのスプライトを用意します。(1つじゃ意味ないですからね)
両方のスプライトは、debugモードをtrueにしてありますが、
これは当たり判定をするエリアを表示するものです。(それっぽく見えます)

```JavaScript
スプライト.debug = true;
```

全体のコードは下記の通りです。

```JavaScript
let imgA, imgB;// 1-1, スプライトで使う画像データを格納する変数(2つ)
let sprA, sprB;// 1-2, スプライトを格納する変数(2つ)

function preload() {
	imgA = loadImage("t_tanu.png");// 2-1, タヌキ
	imgB = loadImage("t_ninja.png");// 2-2, ニンジャ
}

function setup() {
	createCanvas(windowWidth, windowHeight);
	frameRate(32);
	noSmooth();
	angleMode(DEGREES);
	// 3-1, スプライトA(タヌキ)
	sprA = createSprite(width/2-200, height/2);
	sprA.addImage(imgA);
	sprA.debug = true;// デバッグ用表示
	// 3-2, スプライトB(ニンジャ)
	sprB = createSprite(width/2+200, height/2);
	sprB.addImage(imgB);
	sprB.debug = true;// デバッグ用表示
}

function draw() {
	background(33);
	drawSprites();
}
```

ちょうど良い距離に2つのスプライトが並んでいますね。

![Screen Shot 2021-08-07 at 18.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/1378083e-75b8-946a-640b-202b1a1ea937.png)

## 衝突をさせてみる

2つのスプライトを衝突させ、跳ね返す処理の流れは下記の通りです。

1. sprAを右に動かします
2. sprBを固定します(衝突されても動きません)
3. bouce関数を使って衝突判定をします

sprA(タヌキ)をsprB(ニンジャ)の方向へ動かします。

```JavaScript
スプライト.setSpeed(速度, 角度);
```

sprBは、immovableをtrueにしておく事で固定させる事ができます。

```JavaScript
スプライト.immovable = true;
```

draw関数の中でbounce関数を使い、両者の当たり判定をします。

```JavaScript
スプライトA.bounce(スプライトB);
```

全体のコードは下記の通りです。

```JavaScript
let imgA, imgB;
let sprA, sprB;

function preload() {
	imgA = loadImage("t_tanu.png");
	imgB = loadImage("t_ninja.png");
}

function setup() {
	createCanvas(windowWidth, windowHeight);
	frameRate(32);
	noSmooth();
	angleMode(DEGREES);
	// スプライトA(タヌキ)
	sprA = createSprite(width/2-200, height/2);
	sprA.addImage(imgA);
	sprA.debug = true;
	sprA.setSpeed(4, 0);// 1, sprAを右に動かします
	// 3-2, スプライトB(ニンジャ)
	sprB = createSprite(width/2+200, height/2);
	sprB.addImage(imgB);
	sprB.debug = true;
	sprB.immovable = true;// 2, sprBを固定します
}

function draw() {
	background(33);
	drawSprites();
	sprA.bounce(sprB);// 3, bouce関数を使って衝突判定をします
}
```

見事に跳ね返りました。
debug表示(緑の枠がそうです)があるのでわかりやすいですね。

![mov2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/0b604348-23de-dad1-ebac-d172e6233f53.gif)

次回は沢山のスプライト同士における衝突判定のお話になります。

[前回の記事](https://qiita.com/sdkfz181tiger/items/83685adaeaa426cea7bd) | [次回の記事](https://qiita.com/sdkfz181tiger/items/1ac1a9f4f966e6c52ab0)

## おまけ動画(こちらもよろしくお願いします)

<iframe width="560" height="315" src="https://www.youtube.com/embed/bHtS5tgRmFY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Dockerでボリュームを作成して、コンテナにマウントする方法（ボリュームマウント）

今回はDocker上でボリュームを作成し、作成したコンテナにマウントする方法について記載する。

# Docker 2種類のマウント
まずDockerには2種類のマウント方法がある。
①ボリュームマウント
②バインドマウント

①は今回説明するもので、Docker Engine上に新しくボリュームを切って、それをコンテナにマウントする方法
<イメージ>
![ボリュームマウント.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640437/8556a798-7658-f483-6d85-f3c43996700f.jpeg)



②はDockerをインストールしているマシンの特定のディレクトリを、コンテナにマウントする方法（NASみたいイメージ）


#ボリュームの作成

まずボリュームを作成していこう。

```
docker volume create testvolume01
```



```
> docker volume ls
(省略)
***
***
local     testvolume01
```
他にもコンテナを作成している分、ボリュームが作成されている。


#ボリュームの詳細表示

```
> docker inspect volume01

[
    {
        "CreatedAt": "2021-08-07T09:01:56Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/testvolume01/_data",
        "Name": "testvolume01",
        "Options": {},
        "Scope": "local"
    }
]
```
マウントポイントは、docker内となっている。



# Apacheコンテナを作成しつつ、ボリュームをマウント

```
docker run -d --name=httpd_volume01 -p 8080:80 --mount type=volume,src=testvolume01,dst=/usr/local/apache2/htdocs/ httpd
```

/usr/local/apache2/htdocs/　このフォルダにはindex.htmlが入っている。

```
> docker ps -a
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS                    PORTS                                   NAMES
0bdd01904904   httpd        "httpd-foreground"       About a minute ago   Up About a minute         0.0.0.0:8080->80/tcp, :::8080->80/tcp   httpd_volume01
```
httpd_volume01というコンテナが作成されている。

ブラウザに「http://localhost:8080/」と入力すれば、『IT works!』と表示されるはず。


## 事前作成したボリュームがマウントされてるかの確認

「httpd_volume01」コンテナの詳細を見てみよう。

```
 > docker container inspect httpd_volume01

（省略）
            "Mounts": [
                {
                    "Type": "volume",
                    "Source": "testvolume01",
                    "Target": "/usr/local/apache2/htdocs/"
                }
            ],

（省略）

```
Sourceが作成した「testvolume01」であることがわかる。



## コンテナの中に入ってindex.htmlを更新する

```
docker exec -it httpd_volume01 /bin/bash
# cd /usr/local/apache2/htdocs/
# ls
index.html

<viを使えるように>
# apt-get update   ←パッケージの更新
# apt-get install vim
# vi index.html

<「IT works!」を適当な文字に変更>
:wq 保存
```

先ほどのブラウザで「http://localhost:8080/」と入力すれば、変更した文字列が表示される。



## 別のコンテナを作成し、変更した文字列が表示されるかの確認
これだけじゃ本当にマウントされてるかわからない、という方は別のコンテナを作成して確認してみてください。


```
docker run -d --rm --name=httpd_after_volume01 -p 8081:80 --mount type=volume,src=testvolume01,dst=/usr/local/apache2/htdocs/ httpd
```

新しいブラウザで「http://localhost:8081/」と入力。
変更後の文字列が表示されれば、無事にボリューム内を共有できていることがわかる。


# 最後に
今回はDockerでボリュームを作成し、マウントをやってきました。
次回はDockerのホストOSのディレクトリとマウントする「バインドマウント」を紹介したいと思います。
【機械学習】過学習を防ぐ正則化手法比較まとめ

# はじめに

この記事では機械学習における各種の正則化手法の概要とシンプルな問題設定で使用してみた結果をまとめています。

記事対象者として、

- 正則化手法としてどのようなものがあるかざっと見てみたい人
- どの正則化手法を採用するか検討してる人
- 機械学習初学者

などを想定してます。
使用したコードは以下のJupyter Notebookに全て載せています。pytorchを用いた実装。
https://colab.research.google.com/drive/1Po5OsyBSxaVECpgMBoTiUfSvx1kAWe4j?usp=sharing

# 正則化(Normalization)とは
ニューラルネットを学習する際に訓練データに対する性能(損失関数、分類正答率)が良い一方、テストデータに対する評価指標が悪いことを過学習と呼ぶ。機械学習において過学習を抑制し、訓練データに対する性能とテストデータに対する性能の乖離を小さくすることで汎化性能を高めるための方法は正則化手法と呼ばれる。

### 本記事で紹介する正則化手法
- L2正則化 (L2 normalization)
- ドロップアウト (Dropout)
- ラベル平滑化 (Label smoothing)
- バッチ正則化 (Batch normalization)

各手法の概要とCNNによるCIFAR-10画像分類タスクに対して各種正則化手法を導入してみた結果を紹介する。

## 性能評価
CNNによるCIFAR-10画像分類モデルの学習を行う。
![カテゴリー一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/f7adfd64-4fdf-183f-aca2-e46f853287d1.png)

![Digraph.gv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/56b4230a-de0a-5b29-acd9-ce8bac1ca357.png)



## 正則化手法無し
###概要
毎Epoch終了時に検証用データを用いて性能を評価し、最も性能が良かったモデルを採用する。
###使用結果
![history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/04924f71-c49b-3712-8086-4da40bab38bb.png)
191epochで検証データでの正答率が最大になり、テストデータでの正答率は64.4%であった。
## L2正則化 (L2 normalization)
###概要
各層における重みパラメータの２乗を損失関数に加算する。線形回帰問題などでよく用いられるが今回扱うような多層ニューラルネットの正則化ではあまり使われていない印象。
参考: https://toeming.hatenablog.com/entry/2020/04/03/000925
###使用結果
![history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/d6d0fcd0-3905-e368-a008-01871b14b44c.png)
276epochで検証データでの正答率が最大になり、テストデータでの正答率は63.9%であった。正則化無しと比較すると訓練データと検証データの乖離が小さく過学習が抑制されているのがわかるが、テストデータにおける正答率は0.5%下がってしまった。
## ドロップアウト (Dropout)
概要
一定割合の前方伝播を消去する (0にする)。
参考: https://qiita.com/shu_marubo/items/70b20c3a6c172aaeb8de
###使用結果
![history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/0f732b4e-8d65-814a-43e3-ab418e43497b.png)
2番目の全結合層の前方伝播の20%をドロップアウトした結果、236epochでテストデータ正解率64.9%となった。正答率は0.5%ほどの改善であり、過学習が抑制されている。

## ラベル平滑化(Label Smoothing)
###概要
多クラス分類において訓練データの正解出力として与えるone-hotベクトルに変更を加え、正解ラベルと不正解ラベルの差を少し緩和する。
参考: https://build-medical-ai.com/2021/02/21/label-smoothing%EF%BC%88%E3%83%A9%E3%83%99%E3%83%AB%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%B8%E3%83%B3%E3%82%B0%EF%BC%89%E3%82%92pytorch%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B/
###使用結果
![history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/f57be9be-ad39-18db-ee55-fc322b06f5d8.png)
eps=0.03として学習を行なった結果、170epochでテストデータ正答率63.0%となり、改善率は-1.4%となった。今回の検証では過学習の抑制は確認できなかった。epsの設定をもう少し大きくすると変わるかも知れない。

## バッチ正則化 (Batch normalization)
###概要
前方伝播の際に各ノード出力のバッチ分布が平均0分散1になるように正規化を行う。
参考: https://yaakublog.com/batch-normalization
###使用結果
![history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723352/e35ab117-b403-9526-2051-24c8f40448ea.png)
２つの畳み込み層の後にバッチ正則化層を入れ学習を行なった。236epochでテストデータ正答率64.9%となり、改善率は0.5%ほどであった。また、0~50epochの学習初期では学習が比較的速く進んでいることが確認できた。

# まとめ
今回の問題設定ではドロップアウト、バッチ正則化により汎化性能の改善が見られた。多層ニューラルネットの正則化を行う場合はまずこれらを試すと良さそうだなと感じた。
【 エラー解消法 】RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd


###これだと解決しなかった

- https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10204544165

```bash:Terminal
pip install numpy --upgrade
pip3 install numpy --upgrade
```


###これで解決した

- https://stackoverflow.com/questions/33859531/runtimeerror-module-compiled-against-api-version-a-but-this-version-of-numpy-is

> ```text:
>9
>This worked for me:
>
>sudo pip install numpy --upgrade --ignore-installed
>```

```bash:Terminal
sudo pip install numpy --upgrade --ignore-installed
```
情報セキュリティの3要素

<h1>この三つを理解しておこう<h1>
<li>・機密性<li>
<p>アクセスを認められたものだけがその情報（サーバー）にアクセスできる状態を確立させること<p>
<li>・完全性<li>
<p>情報が改ざんされていない状態を確立させること<p>
<li>・可用性<li>
<p>必要なときにどんなときでもサーバーにアクセスできる状態を確立させること<p>
Can't delete ...... because its pathname is too long. の対処法

Xcodeの操作ミスで、フォルダの中に同じ名前のフォルダが無限に作成されてしまい、ゴミ箱から削除しようとしても表題のエラーメッセージが出て、削除できなかったことがあります。

ターミナルから削除コマンドを使っても、消去不能でした。

しかし、ある時、特別なツールやコマンドを使わなくても簡単にフォルダを削除できる方法を思いつき無事に削除できたので、情報共有します。

1. 削除したいフォルダの最上層のフォルダ名を「a」など、適当な名前に変更する。

2. 別のフォルダ内に「a」など、同じ名前の空のフォルダを作成する。

3. 空のフォルダを、消したいフォルダと同じフォルダ内に移動する。

4. 「上書きしますか？」というメッセージが出たら「OK」を選択する。

5. 交換された「a」という名前の空のフォルダを削除する。

以上です。
AtCoderログ：0060 - ABC 156 C

# 問題

https://atcoder.jp/contests/abc156/tasks/abc156_c

## 問題文
> 数直線上に $N$ 人の人が住んでいます。
> $i$ 番目の人が住んでいるのは座標 $X_i$ です。
> あなたは $N$ 人全員が参加する集会を開くことを考えています。
> 集会は数直線上の任意の 整数値の座標 で開くことができ、座標 $P$ で集会を開くとき、$i$ 番目の人は集会に参加するために $(X_i−P)^2$ の体力を消費します。
> $N$ 人が消費する体力の総和としてありえる値の最小値を求めてください。

## 制約
> ・入力は全て整数である。
> ・$1 \le N \le 100$
> ・$1 \le X_i \le 100$

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #002 

# 回答
# 回答1 (AC)
考えられる全ての $P$ の値に対して $\sum_{i=1}^N (X_i-P)^2$ を求め、その最小値を求めれば良いでしょう。ここで $1 \le X_i \le 100$ より $1 \le P \le 100$ となる (例えば $P=0$ は $P=1$ に比べ全員にとって遠くなるので、$P=0$ で最小値になることはない。同様にして $P<0$, $100<P$ で最小値になることはない)。コードは以下のようになりました。

```C++:abc156c-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;

  vector<int> x(n);
  for ( int i=0; i<n; i++ ) {
    cin >> x.at(i);
  }

  int dmin = INT_MAX;
  for ( int p=1; p<=100; p++ ) {
    int sum = 0;
    for ( int i=0; i<n; i++ ) {
      sum += pow(x.at(i)-p,2);
    }
    dmin = min(dmin,sum);
  }

  cout << dmin << endl;
}
```

計算量を考えると、$P$ の値は 100 通りで、それぞれの $P$ の値に対して $N$ 回の繰り返しを行うので、全体の計算量は $O(100N)=O(N)$ となります。

## 回答2 (AC)
少し数学的に考察すると、最小値となる $P$ の値を直接求めることができます。$X_1,X_2,\dots,X_N$ が与えられたとき、設問は、関数
$$
 D(P) = \sum_{i=1}^N (X_i-P)^2
$$
の最小値を求めよというものでした。ここで式変形をすると

```math
\begin{align}
 D(P) &= \sum_{i=1}^N (X_i-P)^2 \\
      &= (X_1^2+\dots+X_N^2)-2(X_1+\dots+X_N)P+NP^2 \\
      &= N\biggl(P-\frac{X_1+\dots+X_N}{N}\biggr)^2 + A
\end{align}
```

となります。ここで $A=(X_1^2+\dots+X_N^2)-\frac{(X_1+\dots+X_N)^2}{N^2}$ は $P$ とは無関係な値です。つまり関数 $D(P)$ は $P$ に関する二次関数で、$P=\frac{X_1+\dots+X_N}{N}$ のときに最小値 $A$ をとることがわかります。これは、最小値になる $P$ は $N$ 人の家の座標の平均、つまり全員の家の重心になることを意味していて、自然な結果になっています。

設問では $P$ は整数値に限定されているので、関数 $D(P)$ が最小値をとるのは $P=\frac{X_1+\dots+X_N}{N}$ に最も近い整数値となります。よって、(小数として) $(X_1+\dots+X_N)/N$ を四捨五入した値が求める $P$ の値となります。
なお、小数 $x$ を四捨五入した値を $\lceil x \rfloor$ とかくことがあります (Round 関数)。このとき $\lceil x \rfloor = \lfloor x+0.5 \rfloor$ という関係式が成立するので、Round 関数は床関数 (小数点以下を切り捨てる関数) で表すことができます。 

コードは以下のようになりました。$X_i$ の値を受け取る際に、2種類の和 ${\rm Sum}_1=X_1+...+X_N$ と ${\rm Sum}_2=X_1^2+...+X_N^2$ を計算しておくと、$N$ に関するループは1回で済みます。

```C++:abc156c-2.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;

  vector<int> x(n);
  int sum1 = 0, sum2 = 0;
  for ( int i=0; i<n; i++ ) {
    cin >> x.at(i);
    sum1 += x.at(i);
    sum2 += x.at(i)*x.at(i);
  }

  int p = floor((float)sum1/n+0.5);
  int dmin = sum2 - 2*sum1*p + n*p*p;

  cout << dmin << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc156/tasks/abc156_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2020/02/24/091829)
回答1と同じ方針でした。
9
## [AtCoder の解説](https://atcoder.jp/contests/abc156/tasks/abc156_c/editorial) → [全体の解説](https://img.atcoder.jp/abc156/editorial.pdf)
こちらも回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0059 - AGC 027 A](https://qiita.com/RoadLynton/items/15ca251f738b15e80efa)
- 次の記事 → [AtCoderログ：0061 - AGC 012 A](https://qiita.com/RoadLynton/items/8ed2a55a001e9e4d2ff2)
チャット系の既読APIをまとめて叩きたい

こちらの記事では外部フレームワーク（Rxswiftなど）を使用しません。
不備やもっとこうすればいいなどのご意見があれば、ぜひコメントお願いします。
# 参考
フロントエンドの記事ですが、やりたいことと実装は大体同じになります。
まずはこちらを読んでいただきたいです。
[ユーザーが画面内のコンテンツを見たかどうかを判定する一歩上の仕組み、サービスでの活用事例](https://qiita.com/endam/items/1d03d3c8cfc6f6aa8067)

# やりたいこと（上の記事にある内容と同じです）
1. チャット読んだら既読にしたい
1. サーバー負荷を上げたくない

#前提
・叩く既読API等が複数のチャットをまとめて叩けるものであること
（一つ一つidを指定して既読にするようなものだと、そもそも無理です。）
・UITableViewを使用していること

#実装
###・各セルがセルの下まで表示された判定
あるセルが表示され始める時にはその前のセルが表示され終わっているという判定。
willDisplayのdelegateメソッドを使い、最後の行以外の表示判定を行う。
最後の行の表示されきっているか判定としては、
UITableViewの末尾までスクロールしたかを取得すれば良い（[こちらの実装を参考にしてみてください](https://www.it-swarm-ja.com/ja/ios/uitableview%E3%81%8C%E4%B8%80%E7%95%AA%E4%B8%8B%E3%81%BE%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%97%E3%81%9F%E3%81%93%E3%81%A8%E3%82%92%E6%A4%9C%E5%87%BA/826808112/)）

```swift:UITableViewDelegate
// セルが表示される時に呼ばれる
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // 最初のセルについては、その前のセルが存在しないため弾く
    guard indexPath.row > 0 else {
        return
    }
    // reloadDataをすると全てが構築・破棄されることで全ての行分呼ばれるので、表示されているセル以外は弾く
    guard let indexPathsForVisibleRows = tableView.indexPathsForVisibleRows,
          indexPathsForVisibleRows.contains(indexPath) else {
        return
    }
    presenter?.didDisplayMessageCell(row: indexPath.row - 1)
}
```

###・サーバー負荷を考慮しまとめてAPIを叩きたい
上記の実装で既読にするチャットの情報をスクロールの都度取得できるようになったかと思います。
これをそのまま取得するたびに既読APIを叩いてしまうとサーバーの負担が大きくなってしまいます。
そのためある程度まとめて叩くようにします。
具体的にはTimerのscheduleを使います

```swift:Timer
var readTimer: Timer?
func setupTimer() {
    // 1秒間隔でクロージャーの処理が走るタイマーを設定
    readTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
        // 既読にするチャットの数が0より大きいことを判定
        // 既読のAPIを叩く
    }
    // タイマー起動させ、定期実行をさせる
    readTimer.fire()
}
```
タイマーは起動し続けると常に処理が走り続けてしまうため、私が実際に実装した時は
viewWillAppearでタイマーを起動させ、
viewDidDisappearでタイマーを削除しています。

```swift:Timer
// タイマーの停止・削除
readTimer?.invalidate()
```

あとはタイマーの中の処理や、すでに既読のものを叩かないようにするなどの制御を入れてみてください。
PlantUML 備忘

# シーケンス図

## ループ

```
@startuml
loop 2 minutes
  Prometheus -> Exporter: メトリクス取得
end
@enduml
```

```plantuml
@startuml
loop 2 minutes
  Prometheus -> Exporter: メトリクス取得
end
@enduml
```

# 配置図

## 入れ子をまたいで矢印でつなぐ

```
@startuml
actor クライアント
node ノード {
  component Docker {
    agent NGINX as nginx
  }
}
クライアント -> nginx: HTTPリクエスト
@enduml
```

```plantuml
@startuml
actor クライアント
node ノード {
  component Docker {
    agent NGINX as nginx
  }
}
クライアント -> nginx: HTTPリクエスト
@enduml
```

## 配置

参考：<https://zenn.dev/kitabatake/articles/plantuml-layout>

### `-`で結ぶ

横並びになる。

```
@startuml
agent A
agent B
A -> B
@enduml
```

```plantuml
@startuml
agent A
agent B
A -> B
@enduml
```

### `--`で結ぶ

縦並びになる。

```
@startuml
agent A
agent B
A --> B
@enduml
```

```plantuml
@startuml
agent A
agent B
A --> B
@enduml
```
[シリーズ 全3回] tmux 2.6で emacs 風のキーバインドにする


# はじめに

Linux 上であれば Emacs でシェルを操作したいが、
各種事情により Emacs を導入できない場合の代替手段として tmux 2.6 を使う.

tmux はバージョンが更新されると、過去の設定が動かなくなるので、
私は 2.6 で固定して使っている.

色々と参考にさせてもらった御礼の意味をこめて、次の emacs 操作風の設定を記しておく.

|コンテンツ|使用時期|
|:--|:--|
|[[03] tmux 2.6 で emacs 風のキーバインドにする ... 現在の状態](https://qiita.com/robozushi10/items/27e436aac631d513847a)|2019/12|
|[[02] tmux 2.6 で emacs 風のキーバインドにする ... Emacs風キー割り当て](https://qiita.com/robozushi10/items/810c1047c2e9e088cca6)|2019/12|
|[[01] tmux 2.6 で emacs 風のキーバインドにする ... tmux 2.6 のインストール](https://qiita.com/robozushi10/items/aca60bdd2fb4eb93c65f)|2019/12|
macOSでiOSデバイスのUDIDを確認する方法

# はじめに
アプリの実機デバッグなどをする際のデバイスの登録，その際に必要となるUDIDの調べ方です．
この記事以外にも方法の書いてある記事はあるのですが，iTunesを使用した古い方法だったり広告が多かったりしたのでこの記事にまとめます．

# UDIDを確認する方法
デバイスをPCに接続し，Finderで開いてください．その後デバイス名の下にある機種名などの情報が書いてある場所をクリックしてください．
![スクリーンショット 2021-08-07 17.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135508/47eb59d5-d964-997d-5731-506239114345.png)
そしたらこのようにUDIDが表示されるようになります．
![スクリーンショット 2021-08-07 17.37.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135508/b5bf95c7-7b7f-562a-ea27-4722f7b2d4ae.png)
また，右クリックをすることでコピーできます．
![スクリーンショット 2021-08-07 17.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135508/6e376cd5-e9e8-3d90-70c1-07bc51186817.png)
確認方法は以上です．お疲れ様でした．
【Ruby】【Java】特定の文字列を数える

　新しく「Java」を勉強するにあたり、これまで「Ruby」を勉強する過程で作っていたプログラムを「Java」で作ってみることにしました。

　今回作るプログラムはこちらです。

```ruby
def count_hi(str)
  puts str.scan("hi").length
end

count_hi('abc hi ho')
count_hi('ABChi hi')
count_hi('hihi')
```

　「Ruby」で作っていた　「hi」という文字列を数えるプログラムです。出力結果は以下のようになります。


```
1
2
2
```

##Javaで作ると
　「Java」で作るとこのようになりました。初めに自分で作ったコードは無駄が多かったため、下記の記事を参考にして書き直しました。

　[文字列の中から特定の文字を数える](https://teratail.com/questions/210227)

- メソッドを定義したクラス

```java
package example;

public class Count {
	
	void countHi(String str) {
		int index = 0;
		int count = 0;
		while(true) {
		    index = str.indexOf("hi", index) + 1;
		    if (index == 0) break;
		    count++;
		}
		System.out.println(count);
	}

}
```

- メソッドを呼び出すクラス


```java
package example;

public class UseCountHi {

	public static void main(String[] args) {
		Count str1 = new Count();
		str1.countHi("abc hi ho");
		
		Count str2 = new Count();
		str2.countHi("ABChi hi");
		
		Count str3 = new Count();
		str3.countHi("hihi");
	}

}
```

　まだまだ書き直す余地はあると考えられますのでご意見いただけるとありがたいです。「Ruby」で用いた「scan」と同じようなメソッドは「Java」にはありますでしょうか?
AtCoderログ：0059 - AGC 027 A

# 問題

https://atcoder.jp/contests/agc027/tasks/agc027_a

## 問題文
> $N$ 人の子供がいます。 子供たちには $1,2,\ldots,N$ と番号が振られています。
> すぬけ君は、$x$ 個のお菓子を子供たちに配ることにしました。 このとき、すぬけ君は $x$ 個のお菓子をすべて配り切らなければなりません。 なお、お菓子を貰わない子供がいても構いません。
> 各 $i~(1 \le i \le N)$ について、子供 $i$ はちょうど $a_i$ 個のお菓子を貰うと喜びます。すぬけ君は、お菓子を配る方法を工夫し、喜ぶ子供の人数を最大化しようとしています。喜ぶ子供の人数の最大値を求めてください。

## 制約
> ・入力はすべて整数である。
> ・$2 \le N \le 100$
> ・$1 \le x \le 10^9$
> ・$1 \le a_i \le 10^9$

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) [[第06問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-6-%E5%95%8F--abc-088-b---card-game-for-two-200-%E7%82%B9)]

- [AtCoder Problems Boot camp for beginners Easy 100](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) [#022]

# 回答
# 回答1 (AC)
喜ぶ子供の人数を最大になるのは、喜ぶお菓子の個数が少ない子供から順番に配ったときです。処理としては、喜ぶお菓子の個数を配列 a() に受け取った後、小さい順 (昇順) にソートし、小さい順に配っていけば良いでしょう。お菓子を配って喜んだ子供の人数を child 人(初期値 0)、そのとき残っているお菓子を x 個とすると、次の子供を喜ばせられるかどうかは x >= a.at(child) で判定できます。気をつけないといけないのは最後の子供のときで、最後まで残ったお菓子は最後の子供に全てあげる必要があるので、最後の子供が喜ぶ個数かどうかをチェックする必要が生じます。コードは以下のようになりました。

```C++:agc027a-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, x;
  cin >> n >> x;

  vector<int> a(n);
  for ( int i=0; i<n; i++ ) {
    cin >> a.at(i);
  }
 
  sort( a.begin(), a.end() );

  int child = 0;
  while ( x>0 ) {
    if ( x>=a.at(child) && child<n-1 ) {
      x -= a.at(child);
      child += 1;
    } else if ( x==a.at(child) && child==n-1 ) { 
      child += 1;
      break;
    } else {
      break;
    }
  }

  cout << child << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/agc027/tasks/agc027_a/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/agc027/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0058 - ABC 139 B](https://qiita.com/RoadLynton/items/a3073ddfe4029dd46fa5)
【無料】全てのギタリスト（弦楽器奏者）のためにアプリを作った【指板の可視化ツール】


弦楽器の指板を、設定したスケールやコードの情報に基づいて色付け・可視化するアプリを作りました！

https://o-to.khufrudamonotes.com/o-to-fingerboard

https://twitter.com/khufrudamonotes/status/1423870961116336133?s=20

# 想定している用途
- 運指の選定
- 作曲
- レッスン教材

など幅広く使えるはずです。

# 可視化のメリット
弦楽器は、直観的に音名とポジションを把握しづらいです。
同じ音が複数の場所にあり、チューニングによって音のポジションが異なるためです。

もちろん、主要なコードやスケールのポジションなら暗記している奏者も多いと思います。

しかし、一般的な人間の記憶力には限度があります。

たとえば、今すぐ指板上に**Fダブル・ハーモニック・スケール**のポジションをイメージできますか？


…僕は無理です。笑

でも、このアプリを使えば簡単です。

![ScreenShot-202187_171219.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/c5180cad-2ed6-ee37-97ca-efae508af7dc.png)

ちなみに、色付けはトニック（ルート音）に対して、移動ド的な視点で行われています。

たとえば、トニック（ルート音）は「青」、それに対して完全5度は「黄色」です。

## 主な切り替え項目
### 音名の表記
英・米式、イタリア式、日本式、ドイツ式の4種類の中から選べます。
初学者の方はイタリア式（ドレミ…）にすると、馴染みやすいかもしれません。

![ScreenShot-202187_17627.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/cc7de130-d424-f506-66bd-c854a5269655.png)

### フレットの数
基本的に**24フレット**で表示される設定にしています。
しかし、必要に応じてユーザー側で1~30フレットまで指定できます。

### コードやスケールの情報
選択したコードやスケールの情報も表示されます。
(これは、O-TOの別機能「①コード」や「②スケール」でも表示されるテキストです。)
指定したコードやスケールをどう使うべきかの参考になるはずです。

### チューニングの詳細設定
ドロップダウンリストに無いチューニングを試したい場合は、「チューニングの詳細設定」から独自の設定もできます。

# さいごに

僕自身、ギターを10年以上やっていますけど…
我ながら…このアプリは**めちゃくちゃ便利**だと思います。笑

ぜひ使ってみてください。

https://o-to.khufrudamonotes.com/o-to-fingerboard
AWSでの仮想サーバVPCの構築

#概要

AWSを使用した基本的な仮想サーバVPCの構築方法です。
VPCとはユーザー専用のプライベートなクラウド環境のことを指します。

#使用PC
MacBook Air(2019)

#1.EC2を選択

コンソールにログイン後、画面右上のリージョンを選択します。(今回は東京)
マネジメントコンソールにて「仮想マシンの起動」を選択します。
![スクリーンショット 2021-08-07 15.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/17a2bde2-36cc-83a6-77a2-43636cf1cd66.png)


#2.Amazon マシンイメージ (AMI)の選択

AMI は、インスタンスの作成に必要なソフトウェア構成を含むテンプレートです。
Amazon Linux2を使用します。

CPUの種類をx86とArmが選択できますがx86で問題ないと思います。
Armの方がパフォーマンスが高いとのことですが、
付随する機能をArm用に対応させる必要があるようです。
![スクリーンショット 2021-08-07 15.50.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/abaf526f-8846-2536-b4fb-6c64e389d3a6.png)


#3.インスタンスタイプの選択

インスタンスとは、アプリケーションを実行できる仮想サーバーです。
CPU、メモリ、ストレージ等を使用するアプリケーションに合わせて組み合わせます。
今回は無料枠のt2．microを選択します。
![スクリーンショット 2021-08-07 16.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/32bbacdc-4466-895f-9cbc-f8f8aac962f8.png)

#4.インスタンスの詳細の設定

ネットワークやシャットダウン時の設定ができますが、今回は特に何も変更しません。
![スクリーンショット 2021-08-07 16.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/f48c1c78-4c7f-0b5b-ee21-4d5afd342f34.png)

#5.ストレージの追加

ストレージサイズが変更できます。
無料利用枠の場合は30GBまで選択できますが、デフォルトの8GBのままにしておきます。
![スクリーンショット 2021-08-07 16.25.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/4dbb7632-bf96-13de-ac73-0ebe30e1513d.png)

#6.タグの追加

インスタンスを区別するためのタグを追加します。
今回は名前(Name)、用途(job)、停止時間(StopTime)の3つを追加しました。
![スクリーンショット 2021-08-07 16.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/09e90296-3516-3350-085b-43110900a8ce.png)

#7.セキュリティグループの設定

セキュリティの設定を行うことができます。
今回はインスタンスの新規作成なのでセキュリティグループも新たに作成します。
とは言っても「新しいセキュリティグループを作成」を選択するだけでOKです。
特定のIPアドレスからのみアクセスするという人はソースを変更しましょう。
![スクリーンショット 2021-08-07 16.33.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/bf99f40d-348a-a773-6973-fa76a7a98dfc.png)

#8.インスタンス作成の確認

設定の確認を行います。
セキュリティグループを特段設定していないので警告が出ています。
個人の練習として使う分にはいいですが、仕事等で使用する場合は設定を見直しましょう。
![スクリーンショット 2021-08-07 16.39.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/8bd7feb0-8005-9065-25bb-eb2e8aeabbcf.png)

#9.キーペアの作成

ターミナルからEC2にログインする際の鍵を作成します。
名前をつけて自分がわかる場所へ保存しましょう。
ログインする際にPC上のどこにあるかという道筋を記入する必要がありますが、
Finder使用時に画面上部の「表示」から「パスバーを表示」に変更すると見えます。
「パスバーを非表示」になっていれば表示がONになっています。(画像白下線部参照)
![スクリーンショット 2021-08-07 16.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/a21e8f39-a5cf-f1b3-2f7e-b53256d41400.png)
確認後、「インスタンスを作成」を押してください。


#10.作成したインスタンスの確認

構築作業は以上で終了となります。
実際のログインは次の記事に書きます。

画面下部の「インスタンスの表示」を押すと作成したインスタンスの一覧が表示されます。
![スクリーンショット 2021-08-07 17.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/3e63f50a-f171-9ebc-6c60-f4ed77f25a2e.png)

ステータスやIPアドレス等を確認することができます。
![スクリーンショット 2021-08-07 17.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1860147/720a5737-610e-23d6-9bbb-910d04d68a74.png)



#最後に

ご覧頂き、ありがとうございました。
間違いなどがあれば教えて頂けると幸いです。

ono
小さなDX①：python BeautifulSoupでニュースのトピックスを表示

#ニュースのトピックス一覧をすぐに表示させ、毎日のクリック回数を減らす
プログラミングでyahooニュースのトピックス一覧のタイトルとそのURLを表示することで、日々のニュースサイトを開くクリック作業を減らす
##コードの流れ
①　import
②　ニューストピックスのURLの指定
③　指定したURLページのhtmlデータを取得
④　欲しいデータの取得（タイトルとそのURL）
###① import

```python:import
from bs4 import BeautifulSoup
import requests
```
###② ニューストピックスのURLの指定
```python:URL指定
#取得したいデータが異なる場合は変更
url = "https://news.yahoo.co.jp/topics/top-picks"
```
###③指定したURLページのhtmlデータを取得
```python:BeautifulSoup
response = requests.get(url)
soup = BeautifulSoup(response.content,'html.parser')
```
###④欲しいデータの取得（タイトルとそのURL）
```python:htmlテキスト、リンクデータ取得
#欲しいタイトルはclassを指定して取得
#.textで文字列を取得
topic = soup.find_all(class_="newsFeed_item_title")
topics = [i.text for i in topic]

#欲しいリンク先はclassを指定して取得
#.get（"href")でリンク先のURLを取得
link = soup.find_all(class_="newsFeed_item_link")
links = [i.get("href") for i in link]

#printでタイトルとリンクを出力
#見やすさは個別で調整(printの出力結果）
for i in range(len(topics)):
    print(topics[i],"     ",links[i])
    print("")
```
参考：find_all()の使い方
https://gammasoft.jp/blog/difference-find-and-select-in-beautiful-soup-of-python/

効率化としては小さいですが、ニュースサイトを開いてそのままネットサーフィンに興じる可能性が少し減り、勉強などに使える時間が増えるのではと考えてます。
小さなDX①でした。
[01] tmux 2.6 で emacs 風のキーバインドにする ... tmux 2.6 のインストール


# はじめに

Linux 上であれば Emacs でシェルを操作したいが、
各種事情により Emacs を導入できない場合の代替手段として tmux 2.6 を使う.

tmux はバージョンが更新されると、過去の設定が動かなくなるので、
私は 2.6 で固定して使っている.

tmux の操作は Vi キーバンディングが多いので、色々と参考にさせてもらった御礼の意味をこめて、
emacs 操作風の設定を記しておく

本項では「tmux 2.6」のインストール方法を記す
　

# 環境

```bash
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
```


# tmux 2.6 のインストール

公式サイトに従う

## 1. tmux 2.6 のソースコードをダウンロードする

```bash
git clone -b 2.6 git@github.com:tmux/tmux.git
```

## 2. ビルドをして tmux を作成する

```bash
$ cd tmux
$ sh autogen.sh
$ ./configure && make
```


## 3. ローカルに作成した tmux を実行してみる

次のように Version が表示されればOK

```bash
$ ./tmux -V
tmux 2.6
```

なお README を見る感じだと、make install をすれば
/usr/local/bin/. に tmux が配置されそうである (が、私には不要な操作なので未確認である)
AWS Athena でクエリ実行した時に出るエラー No output location provided. 　

# はじめに
[AWS Athena](https://aws.amazon.com/jp/athena/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc)で elb_logsというテーブルがあったので、試しにSELECTしましたが、下記のエラー文が表示されました。

```
クエリには次のエラーがあります。

No output location provided. An output location is required either through the Workgroup result configuration setting or as an API input. (Service: AmazonAthena; Status Code: 400; Error Code: InvalidRequestException; Request ID: 3db40425-2c5b-417f-80c9-cc103727faf2; Proxy: null)
```

# 解決法
AthenaはS3に格納してあるデータから実行したクエリ結果をS3に再保存するようになってるので、どのBucketのどのパスに保存するかという設定が必要なようです。

あとで気付いたんですが、灯台下暗しというか、クエリ実行画面の上部にバリバリ書いてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/65191ffa-c274-9253-a0d1-efe3870177ab.png)

（必要な方は）適当なBucketを作成した後、上記の「Amazon S3でクエリ結果の場所を設定する」から、保存先を設定します。
今回はdatalake-non-projectというバケットのdevフォルダを選択します。お好みや要件に合わせて暗号化などを行って下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/9c04c51f-7d83-e4d7-af63-ad0f8b656f11.png)

ちなみに暗号化はセキュリティ、パフォーマンス、可用性・耐久性を両立させるために、SSE-KMS（サーバーサイド暗号化）がお勧めです。
参考=>[データレイク構築における成功の秘訣 ～マインドと進め方、設計ベストプラクティス～](https://pages.awscloud.com/rs/112-TZM-766/images/A2-04.pdf)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/d665d5c6-12a7-01da-ae90-30dd641a2d19.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/af436f3f-9f96-2f1c-bb88-956a7dc730f2.png)


今度は実行できました！実行時間や結果のデータサイズ、クエリ結果などが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/d023e756-5129-a64f-a16b-b6716e3b344b.png)

S3を確認すると、Apatch Hive形式で、年月日で[パーティション分割](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html)されたフォルダ（ない場合は新規作成される）の配下に、結果のCSVファイルおよびメタデータのファイルが保存されており、データ分析のしやすい形となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/6affd4a9-bb23-e948-0955-d927e7bb3a37.png)
自作のnode.jsのアプリをGoogleCloudPlatformにデプロイする方法

今回はGCP（GoogleCloudPlatform）に自作のアプリをデプロイする方法についてまとめていきます。

#記事を書こうと思った背景
業務としてAzure、GCPについて、調査をしたため、備忘録としてGCPへのデプロイの仕方をまとめることにした。

#前提条件
①Googleアカウントは作成済（クレジットカードの情報も登録済み)
・・・無料期間は基本無料で使用できるが、GCPの登録には人間であることの証明？のためにクレジットカードの登録が必要となる。

②npmはインストール済み

③Node.jsによるアプリケーションを作成済みであること。


##1 プロジェクトを作成
GCPのコンソール画面へログイン後新しいプロジェクトを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/f6a159ae-21d9-cc73-8848-b44bf5cc46ae.png)

赤い部分を押下後、右上より新しいプロジェクトを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/3334adc4-8ac3-ef35-c5ee-483952f5fb1a.png)

作成後、プロジェクトを選択画面に作成したプロジェクトが表示されていれば作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/1b5030dd-bb5c-d15b-6329-8dcdafa1b761.png)

#2 対象プロジェクトに対して請求先アカウントのリンクを有効化する
デプロイした時にエラーが発生し、調べてみたところこの設定をしないとデプロイ時にエラーが発生するようです。
有効化するには対象のプロジェクトの左のメニューから赤いところを選択して行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/91f14ea6-a8f4-3db8-6b76-6ff285683599.png)

#3 app.yamlファイルの作成
app.yamlファイルでは、App Engineサービスのランタイム環境の設定を指定する。
このファイルがないとサービスはデプロイされないとのこと。

なので、デプロイ対象のアプリのフォルダに以下の内容のapp.yamlファイルを作成する。

```
runtime: nodejs14
```

#4 いよいよデプロイしていく
最低限の準備は整ったので、これからデプロイをしていきます。
公式の以下のドキュメントを参考にしながら作業を進めていきます。
https://cloud.google.com/appengine/docs/standard/nodejs/building-app/deploying-web-service?hl=ja

さきほど作成したapp.yamlファイルがあるフォルダでコマンドプロンプトを開く。
以下のコマンドを実行する。

```
gcloud app deploy
```
実行後、ソースファイルがGoogleCloudStorageにアップロードされ、Cloud Buildがアプリをビルドし、App Engineにデプロイする。(公式より引用)

最後にnpm startでプロジェクトを実行する。

#まとめ
今回は業務の一環でGCP、Azureの調査をしていく中で学んだことを簡単にとりあえずまとめてみました。
思い出しながら書いたので、漏れているところがあれば今後追記していく予定です。
Docker コンテナ内のファイルのGitHub への保存方法

#対象

Dockerでの作業でGitHub を初めて使う方に向けて書いております。
本当に初歩的な内容になりますのでご了承ください。


#背景

私自身ローカルで開発したプロジェクト内容をGitHub にプッシュすることは少し慣れてきたのですが、docker-compose にて開発中のプロジェクトのプッシュはどうすればいいのかと悩んでおりました。


#手順

単純でした。
Docker コンテナに入り、GitHub の初期手順を行うだけでした。


流れは以下の通りです。


１　コンテナに入る

```
Docker exec -it コンテナID シェル(bashなど)
```

２　GitHub にて新規リポジトリを作成する


３　GitHub の初期手順の設定をする

自分の場合、
git push をしようとした時にアカウント名、パスワードの入力を求められました。

```
Username for 'https://github.com':
Password for 'https://**@github.com ': 
```

入力した後無事にプッシュできました。
[06] C言語でコンソールから関数を呼び出す機構の振り返り ...ソースコード全文


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/fc185b5da0509b9a631f|


# はじめに

本記事の趣旨は「[01 概要](https://qiita.com/robozushi10/items/40b3fc1791a1bab51e4a)」に記しているが、
13年前(=2008年) に職場のプログラムの挙動をマネて実装した
「コンソールから関数を呼び出す機構」の振り返りである.

本項ではソースコード全文の置き場を記す

　

下記の「master」ブランチである
https://github.com/robozushi10/qiita-c
SORACOM Harvest でエラーが出た時の対策

Soracom Harvest にデータを送ろうとして次のようなエラーが出ました。

シリアルモニタ

```text
Receive:400 Configuration for SORACOM Harvest is not found
```

Soracom Console のログ
![error_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/db23d516-6978-cad9-6cb3-2fcc1991cbd0.png)

データ送信のプログラムのサンプルはこちら
[Wio LTE for Arduino で SORACOM Harvest にデータを送る](https://qiita.com/ekzemplaro/items/ede65634b03ee8497723)

対策は、

SORACOM コンソールで
SIM グループ -> SORACOM Harvest Data 設定
で、ON にして保存します。
![harvest_aug07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/1e416ff8-092c-f929-add1-5b2af443ce7b.png)

再び実行すると、
シリアルモニタで、次のようになります。


```text
Receive:201
```

SORACOM コンソールの SORACOM Harvest Data でデータも確認できます。
![harvest_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8f7f4eb7-36e8-7947-5eac-69282986b630.png)
【WordPress】ロリポップの自動バックアップ機能を自力で実装する方法

ロリポップが用意しているバックアップ機能は何かとお金がかかります。
https://lolipop.jp/service/specs/backup/

そこで、自力でWordPressのバックアップ機能を実装しました。

※手順通りに行えば実装できると思いますが、あくまで参考程度に認識してください。
※特に、削除処理については内容が理解できる方のみでお願いします。

## 復元に必要なファイル

WordPressの復元に最低限必要なもの。

1. データベース
1. wp-content

もう少し削減できるかもしれませんが、
とりあえずこれら2つのバックアップを考えていきます。

## シェルスクリプト作成

まずはロリポップのサーバーにSSHでアクセスします。
接続方法：https://lolipop.jp/manual/user/ssh/

※以下、CUIでの操作を行いますが、WinSCPなどのGUI操作でも実装可能です。

接続後、バックアップファイルを格納するディレクトリ作成

```Bash:
mkdir ~/web/bkup
```

シェルスクリプトを作成します

```Bash:
vi ~/web/bkup/bkup.sh
```

以下の内容をコピペし、「入力箇所」のダブルコーテーション内を編集してください。

```Bash:~/web/bkup/bkup.sh
#!/bin/bash

# 入力箇所
hostname="データベースホスト名"
user="ユーザ名"
dbname="データベース名"
password="データベースのパスワード"
bkupdir="バックアップ先のフルパス(末尾にスラッシュ不要)"
wpdir="wp-contentのフルパス(末尾にスラッシュ不要)"
shdir="シェルスクリプトを格納しているディレクトリのフルパス(末尾にスラッシュ不要)"
daletenum="バックアップファイルの上限数"

# 基本的に編集不要
date=`date +%Y%m%d%H%M%S`
dumpdir="${bkupdir}/$date"
dbquery="/usr/bin/mysqldump -h $hostname -u $user -p$password --databases $dbname"

# 実行
eval "mkdir $dumpdir"
eval "$dbquery > ${dumpdir}/dbdump.sql"
eval "cp -a $wpdir ${dumpdir}"
eval "cd $bkupdir && zip -rm ${date}.zip ${date}"

# 古い順に削除
eval "cd $shdir && python rm.py $daletenum"
```

実行権限の付与

```Bash:
chmod 755 ~/web/bkup/bkup.sh
```

■■■！！！ここからはソースコードの内容が理解できる方だけでお願いします！！！■■■
■■■！！！削除処理があるため大変危険です！！！！■■■

次に、バックアップファイルが上限数に達した場合、
古い順に削除するという処理をpythonで実装します。
（ロリポップにはデフォルトでpythonが入っています）

※シェルスクリプトと同じディレクトリに配置してください

```Bash:
vi ~/web/bkup/rm.py
```


```Bash:~/web/bkup/rm.py
import os
import sys

MAX_CNT=int(sys.argv[1])

from operator import itemgetter
filelists = []
for file in os.listdir():
    base, ext = os.path.splitext(file)
    if ext == '.zip':
        filelists.append([file, os.path.getctime(file)])

filelists.sort(key=itemgetter(1), reverse=True)

for i,file in enumerate(filelists):
    if i > MAX_CNT - 1:
        print('{}は削除します'.format(file[0]))
        os.remove(file[0])
```

実行権限の付与

```Bash:
chmod 755 ~/web/bkup/rm.py
```

試しに実行し、バックアップできているか確認します。
zipファイルが作成されているはずです。

また、バックアップファイルの上限数を超えた場合、
古い順に削除されているか確認するのも良いかもです。

```Bash:
sh ~/web/bkup/bkup.sh && ls -la ~/web/bkup/
```

## cron設定

1. ロリポップサイトにログインします
1. 次に「サーバーの管理・設定」 > 「cron設定」を押下
1. 実行ファイルパスに先ほど作成したシェルのパスを記入（web/より後ろのパスを記入）

実行スケジュールはお好みで。
※ディスクの容量に注意してください(追記参照)

## 参考資料
バックアップ機能実装
https://matatabisoft.com/114/

古い順に削除の実装
https://tonari-it.com/python-file-remove/

## 追記
2021-08-07
・ダンプをzip圧縮する処理を追記。
・バックアップの古い順に削除する機能を追加。

2021-08-08
・ディスクの容量に注意してください。
私の場合、一つのzipファイルで113MBほどあります。
これを毎月×12ヶ月分保存するとなると、1.4GBほどになります。
人によってはさらに頻度が高く、個数を多く保存すると思います。
その場合、定期的にバックアップファイルを自身のPCなどにダウンロードすることで、サーバのディスクを圧迫せず、長期間分のバックアップが可能です。
ファイルの定期転送についても気が向いたら自動化してみたいと思います。
provisioning profilesが読み込めない時の解決策（物理）

## 問題
Apple Developerからprovisioning profilesをDLして、ダブルクリックでXcodeに読み込ませようとすると、下記エラーによって読み込めない。

```
Failed to install one or more provisioning profiles on the device.

Please ensure the provisioning profile is configured for this device. If not, please try to generate a new profile.
```
![スクリーンショット 2021-08-07 15.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268579/ab74398a-f492-2049-f9c5-1f9e7969c2f2.png)


## 解決策
DLしたprovisioning profilesのファイル名を適切に書き換えて、provisioning profilesを保存するディレクトリに直接ぶちこめばOK。

1. provisioning profilesをエディタなどで開く
1. 開いたファイルの下の方にprovisioning profilesのUUIDが記載されているので、それをコピーして、ファイル名を`fc033375-dde5-413f-9077-2fbcda719d7e.mobileprovision`のように書き換える
1. `/Users/ユーザ名/Library/MobileDevice/Provisioning Profiles`の中に名前を書き換えたprovisioning profilesを保存する。
1. Xcodeを再起動すればprovisioning profilesが新しいものに変わっているはず。


## UUIDの場所
```html
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AppIDName</key>

        ・・・省略
	
	<key>TimeToLive</key>
	<integer>365</integer>
	<key>UUID</key>
	<string>fc033375-dde5-413f-9077-2fbcda719d7e</string>←これ！！！
	<key>Version</key>
	<integer>1</integer>
</dict>
```


## 後書き
[こちらの記事](https://qiita.com/fuwamaki/items/52432b9b1a2efaa64fb8)では上書きができないのが原因だから、同じファイル名のprovisioning profilesを削除すればOKとあるが、自分の場合はそもそも同じファイル名のprovisioning profilesは存在していなかった。
なんとなく想像される原因は、Xcodeのバージョンを複数使うためにXcodeの名前を変えて複数インストールしているとかかもしれない。
今回の手法は根本的な解決策ではないので、provisioning profilesの更新のたびのこの作業を行うのはめんどくさい。
pythonによる幅優先探索

## 概要
atcoderなどで幅優先探索の問題が出た際に、さらっと参照するための記事です。
細かな説明は、[けんちょんさんの記事](https://qiita.com/drken/items/996d80bcae64649a6580#1-4-bfs-%E3%81%AE%E8%A8%88%E7%AE%97%E9%87%8F)などを見た方が良いと思います。
というか、幅優先探索について初めて学ぶ方は、ぜひ上記の記事を先に読み、Pythonの実装部分だけ参考にしてもらえますと幸いです。

## 幅優先探索について
幅優先探索とは、グラフや木構造を探索するアルゴリズムで、探索を開始した点から近い順に探索していく方法です。
（対照的な方法として、深さ優先探索があり、こちらは行き止まりになるまで経路を戻らずに探索する方法です。）
イメージが非常にしやすいアルゴリズムなので、早速実装していきたいと思います。


![幅優先探索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425582/88a1f1bc-3332-f64d-09af-04e11c0cae5a.png)

画像引用元：[Wikipedia](https://ja.wikipedia.org/wiki/%E5%B9%85%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2)

## 実装の方法
まず、グラフを隣接リスト(知らない方は[@ellさんの記事](https://qiita.com/ell/items/2a327fe021fb7dafe07a)などをお読み下さい。)などで受け取ります。

続いて、始点に隣接している頂点から順に探索していくのですが、ここで
1. 頂点を探索したかどうかの管理
2. 探索予定の頂点を格納する配列
の２点が重要になってきます。

１に関しては、管理できていないと同じ点を探索してしまうのでイメージがつきやすいかと思います。
2に関しては、配列などで見つけた順に格納し、先頭から要素を取り出すのが良いでしょう。

ここで、配列の先頭から要素を取り出すときに、通常の配列（pythonではlist）を用いると、**操作１回に対して、配列の長さ分**の処理が必要となってしまいます。
すなわち、長さNのlistに対して、先頭を取り出すpopに必要な計算量は$O(N)$となります。
これは、通常の配列の場合、先頭の要素を取り出すと、他の要素を一つずつずらす必要があることに起因します。

前置きが長くなってしまいましたが、この先頭の要素を取り出すのに適したものが**キュー**というデータ構造です。
このキューを用いて、
1. 探索予定の頂点を管理する
2. 始点から順に探索をし、未探索の点があれば、キューに追加
を繰り返せば、幅優先探索が実装できます。
また、計算量はN個の頂点からM本の辺を調べる時、$O(N+M)$で表すことが出来ます。

それでは、実際に以下の問題を例にコードを見ていきましょう。

### [幅優先探索](https://atcoder.jp/contests/abc007/tasks/abc007_3)
#### 問題概要
スタートからゴールまでの最短距離を出力する。


```python:sample.py 
# キューをインポート
from collections import deque

# 入力を受け取る。座標の調整のため、スタート地点とゴール地点の座標を-1する。
R, C = map(int, input().split())
sy, sx = map(int, input().split())
gy, gx = map(int, input().split())

sy -= 1
sx -= 1
gy -= 1
gx -= 1

# 迷路の情報を配列Gで受け取る
G = [input() for _ in range(R)]

# キューをQに入れ、スタート地点を追加
Q = deque()
Q.append([sy, sx])

# 未訪問と始点からの距離を管理するdistを定義。スタート地点に0を代入。
dist = [[-1]*C for _ in range(R)]
dist[sy][sx] = 0

# 今回は移動する４方向を事前に用意した。
dirc = [(0, 1), (0, -1), (1, 0), (-1, 0)]

# キューの要素がなくなるまで処理を繰り返す。
while len(Q) > 0:
  y, x = Q.popleft()

# 移動先で繰り返し処理
  for dy, dx in dirc:
    y2 = y + dy
    x2 = x + dx

# 移動先が迷路の範囲内でなければ、continue
    if not (0 <= y2 < R and 0 <= x2 < C):
      continue

# 移動先が壁だったら、continue
    if G[y2][x2] == "#":
      continue

# 移動先が未訪問なら移動前の距離＋１をdistに入れて、キューに移動先の座標を追加
    if dist[y2][x2] == -1:
      dist[y2][x2] = dist[y][x] + 1
      Q.append([y2, x2])

# ゴールの距離を出力
print(dist[gy][gx])

```

## 終わりに
幅優先探索は、問題での活用はもちろん、このアルゴリズムを応用したものが多々出題されています。

ぜひ、この記事を読んだ後に他の方の解説記事や、@e869120さんが書かれた[分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)などで練習問題をこなし、活用の幅を広げてみてください。

ここまで、お読みいただきありがとうございました。
Z3Py　例題　制約最適化問題（Constraint Optimization）

# 問題
5つの品物の価格と価値が以下の表に示されるようになっているとする。 価格の合計が 15以下で、価値の合計が最大になる品物の組み合わせを求めよ。

| 品物 | 価格 | 価値 |
|:-:|:-:|:-:|
|品物0|3|4|
|品物1|4|5|
|品物2|5|6|
|品物3|7|8|
|品物4|9|10|

# 回答
```example_constraint_optimization.py
from z3 import *

price = [3, 4, 5, 7, 9]
value = [4, 5, 6, 8, 10]

X = [Int("X%s" % i) for i in range(5)]

for val in range(20):

    s = Solver()
    s.add([And(0 <= X[i], X[i] <= 1) for i in range(5)])
    s.add(Sum([price[i]*X[i] for i in range(5)]) <= 15)
    s.add(Sum([value[i]*X[i] for i in range(5)]) >= val)

    if s.check() == sat:
        print(s.check())
        print(s.model(), val)
    else:
        break
```
出力

```terminal
sat
[X1 = 1, X0 = 1, X4 = 0, X3 = 0, X2 = 1] 0
sat
[X3 = 0, X2 = 1, X1 = 1, X0 = 1, X4 = 0] 1
sat
　………
sat
[X4 = 0, X3 = 1, X2 = 1, X1 = 0, X0 = 1] 18
```

## 解説
価値の条件を変更し、解が存在するかを調べる。
解が存在しなくなる（unsat）まで探索することで、最大を求める。

# 他の例題
[Z3Py個人的ポータル](https://qiita.com/Ganesha/items/7a606ffc8a7c2504c143) へ
【備忘録】ラジオボタンをクリアするメモ

自分用のメモです

マイナポータルで子供に関する申請をしていたところ、誤クリックしたら戻せなくなりました
焦ってしまいとっさに出てこなかったのでコピペ用のメモです

![ラジオボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128663/9b972ca9-e6b9-f51a-2843-a0e9b8657649.png)


1. F12を押して開発者ツールを出す
1. 外したいラジオボタンのIDを調べる
1. もしIDがついていなかったら、IDをつける
1. 開発者ツールのConsoleで下記のコマンドを実行する

```js
document.getElementById("ID").checked=false
```
[要注意] Unixでの相対パス指定における罠

# シェル手品

（ちゃららららら〜♪） 種も仕掛けもありません。ここのテキストファイルとサブディレクトリがあります。

```tcsh:準備するもの
> ls -ld content.txt level1/ level2/
-rw-r--r-- 1 name users  7 Aug  7 14:31 content.txt
drwxr-xr-x 3 name users 51 Aug  7 14:22 level1/
drwxr-xr-x 2 name users 33 Aug  7 14:22 level2/
```
このテキストファイルの中身は普通のテキストです。

```tcsh:テキストファイルの中身
> cat content.txt 
level0
```
このファイルを2つのサブディレクトリを使った相対パスで見てみましょう。

```tcsh:相対バスでファイルを確認。
-rw-r--r-- 1 name users 7 Aug  7 14:31 level1/../content.txt
-rw-r--r-- 1 name users 7 Aug  7 14:31 level2/../content.txt
```
タイムスタンプもファイルサイズも同じです。では2つのファイルの中身を比較してみましょう。

```tcsh:相対バスでファイルを比較。
> diff -c level1/../content.txt level2/../content.txt
*** level1/../content.txt	2021-08-07 14:31:34.373957989 +0900
--- level2/../content.txt	2021-08-07 14:31:34.373957989 +0900
***************
*** 1 ****
! level0
--- 1 ----
! level1
```
**あれ? 中身が違っています。同じパスを指定しているつもりなのに......**

# 種明かし

最初の`ls`コマンドの引数の指定が不自然なのでバレバレという気もしますが、実際にはサブディレクトリの1つはシンボリックリンクです。

```tcsh:ファイル構成(findの出力から抜粋)
> find -ls
0 drwxr-xr-x 3 name users  51 Aug  7 14:22 ./level1
0 drwxr-xr-x 2 name users  33 Aug  7 14:22 ./level1/level2
0 lrwxrwxrwx 1 name users  13 Aug  7 14:22 ./level2 -> level1/level2
4 -rw-r--r-- 1 name users   7 Aug  7 14:31 ./content.txt
4 -rw-r--r-- 1 name users   7 Aug  7 14:31 ./level1/content.txt
```

このようにサイズは同じだが中身の違う`./content.txt`と`./level1/content.txt`を用意し、`ls`で違いが見えないように`touch content.txt level1/content.txt`としてタイムスタンプを揃えておいたというのが種になります。

# どうしてこうなったのか？

ディレクトリへのシンボリックリンクの下でも、`..`**は実体のディレクトリの親ディレクトリを指す**ということが原因と思います。ディレクトリへのシンボリックリンクの近くに同じ名前のファイルが複数ある場合には、思わぬ勘違いがおきそうですね。

# シェルスクリプト等で実際に問題となる例

ファイルの取り違い以外にも気をつけるべき場面は他にもあります。たとえば、シェルスクリプトの中では便宜上相対バスをもちいてファイル情報を取得したりファイルタイプの判定するような場面はあるとおもいますが、期待したものとは違う挙動になることがあり得ます。

- ファイル情報の取得

   ```tcsh:lsの出力
% ls -ld Documents/workspace/opr/var/tmp
drwxr-xr-x 5 name users 213  7月 17 18:31 Documents/workspace/opr/var/tmp
% ls -ld tmp
lrwxrwxrwx 1 name users  31  2月 14  2020 tmp -> Documents/workspace/opr/var/tmp
% ls -ld tmp/../tmp
drwxr-xr-x 5 name users 213  7月 17 18:31 tmp/../tmp
> ( cd tmp ; ls -ld ../tmp )
drwxr-xr-x 5 name users 213  7月 17 18:31 ../tmp
```

- シンボリックリンクかどうかの判定

```tcsh:testの出力
> test -L tmp && echo symblic link
symblic link
> test -L tmp || echo not symblic link
> test -L tmp/../tmp && echo symblic link
> test -L tmp/../tmp || echo not symblic link
not symblic link
> ( cd tmp ; test -L ../tmp && echo symbolic link)
> ( cd tmp ; test -L ../tmp || echo not symbolic link )
not symbolic link
```

確実に期待した動作にするには、親ディレクトリ(`..`)をあらかじめ所望のように展開しておく必要がありそうです。
強く型指定されたViewModelをビューに渡す

# はじめに
Microsoftの公式解説書『プログラミング ASP.NET Core』を読んで強く型指定を行った上でビューにデータを渡す方法を知ったので備忘録としてまとめたいと思います。

## 今までViewDataやViewBagを利用していた
恥ずかしながら今まではViewDataやViewBagを利用してControllerからViewへデータを渡す方法しか知りませんでした。
こんな感じ↓

```csharp:TestController.cs
public IActionResult Create([Bind("Title,Number")] Test test)
{
    ViewData["Title"] = test.Title;
    ViewData["Number"] = test.Number;
    return View(test);
}
```
便利ではあるのですがViewDataのキー（上記のコードでいうと"Title"や"Number"）をtypoして実行時エラーを出したり、（ViewBagなどで）インテリジェンスがなくて効率が落ちるたびに「ぐぬぬ。。。」と思っていました。

## ViewModelを作成してビューに渡す
そこでViewModelを作成してビューにデータを渡していきます。

具体的にASP.NET Core MVCを利用して書いていこうと思います。
VisualStudio 2019を立ち上げて『新しいプロジェクトの作成』>『ASP.NET Core Webアプリ(Model-View-Controller)』を起動します。
ビルドして実行すると以下の画面になるかと思いますが、以下の赤枠部分をテキトーに「Test」と変えてみましょう。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/d06bb0b9-f292-5f36-1a4e-c80294fa12ce.png)

今までの僕だとこんな感じで書いていたでしょう。

```csharp:HomeController.cs
public IActionResult Index()
{
    ViewData["Name"] = "Test";
    return View();
}
```
```csharp:Index.cshtml
<div class="text-center">
    <h1 class="display-4">@ViewData["Name"]</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
```

それを・・・ViewModelを用いるとこんな感じ。
Modelフォルダ内にViewModelフォルダを作成し、HomeViewModel.csを新規作成しています。

```csharp:HomeViewModel.cs
public sealed class HomeViewModel
{
    public string Name { get; set; }
}
```

```csharp:HomeController.cs
public IActionResult Index()
{
    var viewModel = new HomeViewModel()
    {
        Name = "Test"
    };
    return View(viewModel);
}
```
```csharp:Index.cshtml
@model WebApplication1.Models.ViewModels.HomeViewModel
<div class="text-center">
    <h1 class="display-4">@Model.Name</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
```

実行結果↓
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/a913379b-b1fa-d7d4-b90c-06891d8a64e1.png)

ちゃんと変更できましたね！
これなら型が異なっていた際にも実行前にビルドエラーで気づけますし、Viewではインテリジェンスが効いてより書きやすくなります。

#おわりに
もちろんViewDataやViewBagを利用するのは悪いことではありません。
最初に取り上げたMicrosoftの公式解説書『プログラミング ASP.NET Core』でも手っ取り早く実装できる利点があると書かれていますし、実際のところ確かにその通りです。
ただし大きなアプリを作る際にはやはり保守性が微妙になってくるのでViewModelを用いる設計を基本としていきましょ～！
区間和問題 paiza問題集

# はじめに
ここ数カ月、毎日こつこつ仕事終わりに勉強しています（主にpaizaスキルチェック、問題集）
そんな中で、今まであまり気にしていなかった累積和の考え方について自分用に記録する。

# 対象の問題
[Paiza問題集「区間和 PHP編」](https://paiza.jp/works/mondai/query_primer/query_primer__interval_sum)

## 問題・条件・入力値
> 〇問題文
長さ N の数列 A と、K 個の区間 (l_1,r_1) ... (l_K,r_K) が与えられるので、各区間についての A の区間和 A_{l_i} + ... + A_{r_i} (1 ≦ i ≦ K) を求めてください。

>・1 行目では、配列 A の要素数 N と与えられる整数の数 K が与えられます。
・続く N 行では、配列 A の要素が A_1 から順に与えられます。
・続く K 行では、和を求めるのに使う区間の値 l , r が与えられます。


> 〇条件
・1 ≦ N , K ≦ 100,000
・-100 ≦ A_i ≦ 100 (1 ≦ i ≦ N)
・1 ≦ l_i ≦ r_i ≦ N (1 ≦ i ≦ K)


```
//入力値
N K
A_1
...
A_N
l_1 r_1
...
l_K r_K
```

## 入力例と出力例

```
//入力例
4 2
16
88
10
-65
2 4
1 2
```

```
//出力例
33
104
```

# 実装
## 失敗例
この問題は、与えられた区間和を求める問題である。
初めて解いたとき、ただ指定の区間内でループ処理して区間和を求めればいいと思い以下のように実装しました。

```php
list($N, $K) = explode(' ', trim(fgets(STDIN)));

//与えられる要素を配列に格納する
for ($i = 0; $i < $N; $i++) {
    $a[] = trim(fgets(STDIN));
}

for ($j = 0; $j < $K; $j++) {
    list($left, $right) = explode(' ', trim(fgets(STDIN)));
    $result = 0;
    //指定の区間内でループを行い、区間和を求める
    for ($k = $left-1; $k < $right; $k++) {
        $result += $a[$k];
    }
    echo $result."\n";
}
```

しかし処理時間が長く、タイムオーバーとなりました。
なぜ処理時間が長くなってしまったのか？

この実装では、指定区間が与えられたら毎回ループで算出しています。この実装では、計算量が`O(N^2)`となってしまいます。
今回の問題の条件では、`1 ≦ N , K ≦ 100,000`となっているため最大100000×100000もの計算量となってしまいタイムオーバーになってしまった。

## 解説と成功例
そこで、毎回指定の区間和を求めるのではなく、先に各区間の和を計算します。

以下に最初に示した入力例を図に表して考えてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/74dd906b-4766-6cca-2934-c37ecade183b.png)


a0~a3が与えられる要素の値。sが各区間までの和である。
この図を基に計算してみると、各区間和は以下のように求められる。

```math
s_{0} = 0
```

```math
s_{1} = s_{0} + a_{0} = 0 + 16 = 16
```

```math
s_{2} = s_{1} + a_{1} = 16 + 88 = 104
```

```math
s_{3} = s_{2} + a_{2} = 104 + 10 = 114
```

```math
s_{4} = s_{3} + a_{3} = 114 - 65 = 49
```

これらの式は以下のような関係となっている。

```math
s_{i} = s_{i-1} + a_{i-1}
```

この関係を用いて、各区間の累積和sをあらかじめ計算することで計算量を`O(N)`に減らすことが出来る。


```php
list($N, $K) = explode(' ', trim(fgets(STDIN)));

$a = []; //要素を格納する配列
$s = []; //各区間和を格納する配列
$s[0] = 0;

for ($i = 1; $i <= $N; $i++) {
    $a[] = trim(fgets(STDIN));
    $s[$i] = $s[$i-1] + $a[$i-1]; //上記で述べた関係式
}

for ($j = 0; $j < $K; $j++) {
    list($left, $right) = explode(' ', trim(fgets(STDIN)));
    $result = $s[$right] - $s[$left-1];
    echo $result."\n";
}
```

例えば、入力例の最初の指定区間である区間2~区間4までの和であればこのようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/0130830a-86d0-9102-497e-81923012df2a.png)

そのため、

```math
result = s_{4} - s_{1} = 49 - 16 = 33
```

となる。

図で考えてみるとイメージしやすい。

# まとめ
今回は累積和について自分用にまとめた。
今後膨大なデータを扱う際に、このように処理時間を意識した実装を考えられるようになっていきたい。
これを機に様々なアルゴリズムに関しても少しずつ学んでいきたい。