OmniAICreator/Qiita-1.07M huggingface dataset:
githubのpushに苦戦、、プログラミング勉強32日目

プログラミング初心者はgithubにpushするだけでも一苦労です。

途中までは下記の記事どうりに行きましたが、エラーが、、、！
https://gist.github.com/KosukeGit/8bdab3f9d2d63334ffa178c628ded087

error: failed to push some refs to 'git@github.com:name/app.git'

調べたところどうやら２つREADME.mdがあり、それがぶつかってるとのこと。

#README.mdをvimにて取り除けば解決しました
viにて下記の記事どおりにしたあと,git add .　をしてコミットしたら、pushできるはず
下記の記事が参考になります
https://yu8mada.com/2018/06/13/how-to-resolve-a-merge-conflict-in-git/

ここら辺はよく使いますね
**git status**
**git remote -v**
**git pull origin master --allow-unrelated-histories**
GuzzleHttpで401が返却されても例外をスローさせない

Laravelから外部APIを呼ぶときにGuzzleHttpを使ってみた。
401エラーが返却されたときの情報を使って正常処理を続ける必要があったので、例外をスローさせない方法を調べてみたところ、[http_errors]パラメータにfalseを指定すると出来たので、メモ。

```
            $httpClient = new GuzzleHttp\Client();
            $response = $httpClient->request(
                'POST',
                $url,
                [
                    'headers' => $headers,
                    'json' => $params,
                    'http_errors' => false  // 401が返却されても例外をスローしない
                ]);

```
SPSS Modeler BatchでPythonスクリプトに引数を渡す方法

# SPSS Modeler BatchでPythonスクリプトに引数を渡す方法
*本記事の内容はSPSS Modeler 18.2.1で動作確認しています。バージョンが異なっても基本的には動作すると思いますが、念のため実機でも動作確認を行って下さい。*

## SPSS Modeler Batchとは？
　SPSS Modelerで作成したストリームをで定期的な処理を行う場合、CaDSを利用するのがよいですが、そこまで細やかな管理が必要でなかったり、規模が大きくない場合は、SPSS Modeler Batchもよくつかわれます。
　SPSS Modeler Batchはコマンドからの実行でSPSS Modeler Serverに接続しストリームを実行します。SPSS Modeler ClientのようなGUIは立ち上がりません。基本はストリームに配置されたターミナルノードをすべて実行します。SQLプッシュバックやストリームに設定したキャッシュなども有効に機能します。
　使い方の例として、ある業務の売り上げ予測を毎日実施するとか、その予測モデルを毎週更新するといったような処理があった場合、その処理を行うストリームを作成し、SPSS Modeler Batchのバッチコマンド(clemb)を、ほかのスケジューラー(UNIX系ならCRONなど)から指定した時刻に実行すれば実現できます。

```:コマンド例
clemb -stream "/XXX/.../XXX.str" -execute -server -hostname XXX -username XXX -password XXX -Pmth=Jan
```
　SPSS Modeler Batch実行時に -P オプションで引数をストリームに渡すことができます。
　次のマニュアルにもあるように、例えば条件抽出ノードに  Month = '\\$P-mth' と記述しておき、モデラーバッチでの実行時に、-Pmth=Jan という引数をつけて実行すると、mth=Jan がストリームに引き継がれます。Month = '\\$P-mth' は Month = 'Jan' となり、これにより、Month = 'Jan' に該当するデータのみを抽出することができます。バッチ実行において-Pmth= に続く文字列を変更することで、 Month = 'Feb' など異なる条件でデータを抽出することも可能です。
>["バッチ・モードでのパラメーターの使用"](https://www.ibm.com/support/knowledgecenter/ja/SS3RA7_18.2.1/modeler_mainhelp_client_ddita/clementine/batchmodeparameters.html)
（マニュアル上は等式が == となっていますが、= と同等です。）

　この方法を使って、1つのストリームに引数として支店名を与えて実行すれば、支店ごとに売り上げ予測やモデル更新もできるようになります。

## Pythonスクリプトへの引数取り込み
　SPSS Modeler Batchは前述したように指定したストリームにあるターミナルノードはすべて実行してしまいますが、特定のターミナルノードだけ実行したい場合や、ターミナルノードを実行する順番を指定したい、モデルを更新したいといった場合、付随するPythonスクリプトで制御します。
　上記のマニュアルリンクで示した方法は、引数をストリームのノード内に設定したCLEM式に取り込んでいましたが、ストリームに付随するPythonスクリプトに引数を取り込む方法についても紹介したいと思います。
　例えば、支店名をBranchというオプションで渡す場合、下記のように、-PBranch= で設定します。

```:コマンド記入例
clemb -stream ...(中略)... -PBranch=GINZA
```
　Pythonスクリプトに取り込むには、session()またはstream()インスタンスの、 getParameterValue()メソッドを使います。stream()は対象のストリームに対して、session()は開いているすべてのストリームに対して有効といった違いがありますが、Modeler Batchで取得したパラメータは、session()とstream()どちらからでも取得できます。
　session()およびstream()について、Pythonスクリプトにはそれぞれ次の例のように記載します。

```python:session()の場合
session = modeler.script.session()
Branch_Name = session.getParameters().getParameterValue('Branch')
```
```python:stream()の場合
stream = modeler.script.stream()
Branch_Name = stream.getParameterValue('Branch')
```
　これでバッチを実行すれば、先ほどの例であればBranch_Name変数に’GINZA’が代入されます。あとは、Pythonスクリプト内でノードのCLEM式に代入するなど自由に扱えます。
　変数は文字列として取り込まれますので、数字として扱いたい場合はint()などの型変換が必要です。

　パラメータからPythonスクリプトへの取り込みについて、下記マニュアルにも記載があります。（少しわかりにくいです。）
>["ストリーム、セッション、およびスーパーノード・パラメーター"](https://www.ibm.com/support/knowledgecenter/ja/SS3RA7_18.2.1/modeler_mainhelp_client_ddita/clementine/jython/clementine/python_globalparameters.html)
VCでの文字、ロケールについて数点

__作成ツールの概要と技術的選定理由__

目下何処の会社でも話題沸騰中であろう(若しくはもう過ぎているかも)Win7からWin10への移行で、簡単な物で良いのでデータの移行ツールを作るよう指令を受けた。だいたいマイドキュメント配下ぐらい拾えたらいいらしい(よって特殊フォルダがチョイスして移行の対象を選ぶことになる)。
安請け合いしてそのうちやろうかと軽く思っていたが実はWin7とWin10ではデフォルトの.NET Frameworkのバージョンに互換性がないので双方で間違いなく動くものとなるとネイティブコードしかないと今日気付いた。このような場合選択枝としてはVCしかない。それも現実的な方法はMFCで作ってスタティックリンクでコンパイルというパターン。
VCなんてもう何年もまともに触っていないし、その間にC++もMFCも化け物みたいなものになっているということらしい。厄介なことに手を出したかなぁと思いつつ、今日はメンタル的にダメだったので有給。じっくり自宅作業として不慣れな環境での当該ツールの作成の日としました。
本エントリはその過程で調べたことのメモ。

__文字列のコピーについて__

Cで文字列をコピーしようとすると普通は_strcpy_となる。オーバーフローしないように_strcpy_s_というのも最近はあるらしい。しかしどちらを使ってもエラーとなった。
VCではMSが独自に作成した文字コードに配慮した_lstrcpy_という関数を使うのが正解とのこと。引数の型からしてMSである。
「_l_」から始まる文字列用の関数はこちらに。

[String Functions](https://docs.microsoft.com/en-us/windows/win32/menurc/string-functions)


__ロケールについて__
ファイルを収集したその結果をテスト的にテキストに出力してみると、日本語が出ていない。調べた結果

```
setlocale(LC_CTYPE, "jpn");
```
とロケールの設定をしてやらないといけない、とのこと。そしてこの関数を呼ぶため

```
#include <locale.h>
```
とヘッダも読み込む必要がある。そういえばMFCでプロジェクト作るとき英語しか選べていなかったような。

上記テキスト出力の箇所と、パスの組み立ての部分にもこのロケールの設定は影響していた。

```
TCHAR fullpath[MAX_PATH];
```
としていたところでオーバーフローする可能性があるとしてコンパイルエラーとなっていた(確かワーニングではなかったはず)。
暫定的、雑に _MAX_PATH*4_ としてコンパイルを通していたが、ロケールの設定を行ったら元の_MAX_PATH_のままでコンパイルが通った。裏付けとして調べるとUNICODEを使うんだからそりゃロケールの設定は必要でしょうと。言われてみたら全くその通りなのですが。

言わなきゃ(書かなきゃ)やってくれない、この融通の利かなさが僕がVC好きな理由でもあるんですけどね。いい勉強になりました♪

__おまけ__

特殊フォルダの取得について。
関数としては_SHGetSpecialFolderPath_を使えばOK。
肝心の特殊フォルダの一覧ですが、このようにまとめて下さっている方が居られたのでありがたく使わせて戴きました。
[SHGetSpecialFolderPathに設定できるCSIDL](http://yamatyuu.net/computer/program/sdk/base/SHGetSpecialFolderPath/csidl.html)
これをそのままヘッダとして取り込んで、サンプルのように

```
SPath* p = spath;
p = p + (使いたい位置)
```
という風にポインタズラして欲しいものが簡単に取れますね。
UE4 RenderTargetから任意の座標のRGBA値を取得する

調べてもそう簡単にはわからない内容。C++を使用する。
英語ができるUnreal C++の使い手なら調べて分かるかもしれんが、BP勢は死ぬ。
ちなみに僕はC++を使えないも同然の初心者。4、5日ざっと勉強した程度。
ここではC++が使える人に向けた説明をする。僕は使えないけど。

使えない人のための記事もおいおい書く。
そのときはちょっと複雑なものを実装しながら色々とカバーしようかな。

##ヘッダーファイル
当然レンダーターゲットのヘッダーファイルはインクルードする。
```#include "Engine/TextureRenderTarget2D.h"```
で、適当に関数を宣言する。
```UFUNCTION(BlueprintCallable, Category = "任意")
変数型 関数の名前(UTextureRenderTarget2D* RenderTarget, 以降任意);```
##Cppでする処理
###レンダーターゲットリソース
レンダーターゲットのピクセルの情報はUTextureRenderTarget2Dではなく、
FTextureRenderTarget2DResourceというものに格納されている。
したがって適当に変数を宣言して、引数からそいつを呼びだして格納する。
作った関数に以下のコードを記載することでそれができる。
```FTextureRenderTarget2DResource* Resource;
Resource = (FTextureRenderTarget2DResource*)RenderTarget->GameThread_GetRenderTargetResource();```
###RGBA値の取得
テクスチャの各ピクセルは配列のインデックスで、色の情報なんかはその配列の要素として格納されている。
それを取り出すために、まずこっちの方で色だけの配列を宣言する。
```TArray<FLinearColor> Color;```
その配列にRenderTargetResourceのRGB値をそのまま流し込むには以下のコードなどを使う。
```Resource->ReadLinearColorPixels(Color);```
レンダーターゲットリソースの関数にこういうのがあって、引数にFLinearColorのTArrayを入れるとその配列に色を代入していく。
色は今回FLinearColorを使ったが、FColorでも同様にいける。

Colorは一次元の配列なわけだが、これは左上のピクセルから順に色情報が格納されているので、
例えば(X, Y)のピクセルの色が欲しければ、
```float HogeHoge = Color[X + Y * Resource->GetSizeX()]```
でいける。

あとは適当に色を処理して出力すればいい。
僕はDepthを取得してそれを利用して「目に見えている空間(ヴォイド)の体積」を算出した。
AWSクラウドプラクティショナー学習ポイント

##はじめに

他業界の営業マンから　2019/9〜　IT業界で働かせて頂けることになりました。
その中で、AWSクラウドプラクティショナーを勉強がてら試験を受けてとなったので勉強を開始しました。
全くの未経験で50時間ほどの勉強期間で、結果874/1000点で合格できましたので、それまでの過程を今後受験される方のお役に立てばと思い共有させて頂きます。


##勉強方法

1.　主にこちらの参考書を使用：
[AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/gp/product/4797397403/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797397403&linkCode=as2&tag=ikr81-22&linkId=5385607fbd72bcab8a8e331160d7c32d)

　1周目：わからないワードを調べながらサクッと読んでみる。
　2周目：AWSのHPと照らし合わせながら、細かい理解が足りないので
　　　　自分なりに書き出してまとめつつ読む。

　その他のサービスとして括られているものも結構重要であったので、
　AWSのHPでサービスの特徴等について確認しておくことが良いと思います。


2.　Udemy で模擬試験5回分(325問)を購入し、解く。
　・クラウドプラクティショナーの範囲内ではない内容もあるが、
   　　アウトプットにすごくよかった。
　・だいたい正答率は45%くらいしか取れなかったが、
　　問われ方が分かりよかった。
　
　
3.　AWSデジタルコンテンツの章末問題を解く（30問)
　　　[デジタルコンテンツ](https://www.aws.training/Details/Curriculum?id=34408)
　　試験前日に見つけて解いてみたとき27/30問の正答率。
　　あまり捻られてはいない印象だった。


4.　そのほかに見たサイト
　　・[AWSサポートプランの比較](https://aws.amazon.com/jp/premiumsupport/compare-plans/)：参考書より詳しく載っている




##学習期間
１日6時間程度を7日間程度

##試験当日
　・14時からの受験
　・SPIのように、テストセンターにてPCを使って受験
　・終了後すぐ合格か不合格かの通知がすぐ表示
　・身分証明書は2種類必要
　・見直しも含めてゆっくり解いて50分くらいかかった
　・90分で65問だった

##感想
・初めてのIT関連の試験だったので勝手がわからず自分の勉強方法で
大丈夫なのか不安だったが、Udemy などで問題を解いてみると主にどこらへんが狙われるのかがなんとなくわかった。

・AWSのデジタルコンテンツは時間がかかるので特に見なかった。（参考書と結構かぶった）
・ホワイトペーパーも参考書と結構かぶった。
・参考書とAWSのHPでEC2などと検索して照らし合わせることで主に事足りた。


##試験を終えてのアドバイス

・AWSの責任共有モデルにおいて、お客様側の責任なのかAWS側なのかについての理解
・セキュリティや信頼性など、アーキテクチャ設計原則についての理解
・利用料金のコスパをよくするために適切なサービスはどれなのか
・ハイブリッドクラウド構成についての理解

上記が結構引っかかったポイントでした。

最初は暗記しないとダメかなと思いましたが、なんども参考書を読んでいるうちに
なんとなく理解してきました。
まだAWSをちゃんと触ったことがないので今後触っての理解を深めたいと思います。

お読みいただいてありがとうございました。
今後受験される方、頑張ってください！
UE4、RandomFloatの計算値がなんか変なとき

![P1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531299/83b7585b-c495-53d8-a65c-8fa9c4a74959.png)
最初のFloatの値は0.378582である。100倍したら37.8582なのだが、なぜか83.913696と表示される。
おかしくね？？？　俺は思った。（その後のClampの数値まで違うし）

結論から言うと、RandomFloatが取得されるたびに、新しい値を生成するためである。
（回避するには変数に入れよう）

分かりづらいので、可視化してみる。
![P2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531299/a38e6bd7-42e2-5807-80ba-516297977774.png)
そう、この場合3つそれぞれ計算されているのである！（な、なんだってーAA
いやー、知らなくて丸一日ハマってしまった。
で、対策したものがこちら。
![P3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531299/91c8e8ef-60eb-ec7e-5f45-5fa2f9870876.png)
期待通りの動きをしてくれた。

参考元
https://answers.unrealengine.com/questions/432068/view.html
クエリで Project Euler Problem 5

## 【お題】
[Problem 5](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%205 "Problem 5 - PukiWiki")。
> Problem 5 「最小の倍数」 †
> 2520 は 1 から 10 の数字の全ての整数で割り切れる数字であり, そのような数字の中では最小の値である.
> 
> では, 1 から 20 までの整数全てで割り切れる数字の中で最小の正の数はいくらになるか.

## 【環境】
| SQLServer | SQLCMD |
| ---- | ---- |
| 2017 | 14.0.1000.169 |
設定はデフォルト。

## 【クエリ】
要は最小公倍数。最小公倍数の基本的な知識は以下。

- 3個以上の最小公倍数を求める場合はまず最初の 2項の最小公倍数を求め、更にそれと3番目の最小公倍数を求め……を繰り返す
- 最大公約数から最小公倍数を得ることができる。a、b の最小公倍数 = a * b / (a、bの最大公約数)
- 最大公約数は [ユークリッドの互除法](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E3%81%AE%E4%BA%92%E9%99%A4%E6%B3%95 "ユークリッドの互除法 - Wikipedia") が鉄板

……なんだけど、今回に限っては単純な試し割法の方がアルゴリズムとしてすっきりする。実装例は以下。

```SQL
;WITH CTE_LCM(a, b, c) AS (
    SELECT 1, 1, 2
    UNION ALL
    SELECT
          IIF(b % c = 0, b, a)      -- 割り切れたら最小公倍数で置き換える
        , IIF(b % c = 0, b, b + a)  -- 割り切れたら最小公倍数、割り切れなければ 2倍、3倍...としていく
        , IIF(b % c = 0, c + 1, c)  -- 割り切れたら次の値(1加算)
    FROM CTE_LCM WHERE c <= 20
)
SELECT MAX(b) FROM CTE_LCM;
GO

-----------
  232792560

(1 行処理されました)
```
一瞬で返ってくるし、これで良いのでは。以下答え合わせ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/6ad42cab-1d62-ebb8-d405-4e29cc64c2b5.png" width=20%>
ブロック要素 インラインブロック要素 インライン要素 違い

いつも忘れてしまうので書いた。

# ブロック要素

* width,height,margin,padding が指定できる。
* 縦に並ぶ。

# インラインブロック要素

* width,height,margin,padding が指定できる。
* 縦に並ぶ。


# インライン要素
* width,height　が指定できない。
* margin,padding は左右のみ指定できる。
* 横に並ぶ。
ストリームとパラレルストリーム

##違い
並列かそうじゃないか。
順番注意。


今回は処理順がどうの の計測ではなく、性能の計測です

##計測
```計測.java
package test1;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Test3 {
	
	public static void main(String[] args) {
		Long start1 = System.nanoTime();
		normal();
		Long end1 = System.nanoTime();
		System.out.println("stream\r\n" + (end1 - start1) + "ns\r\n");
		Long start2 = System.nanoTime();
		parallel();
		Long end2 = System.nanoTime();
		System.out.println("parallelStream\r\n" + (end2 - start2) + "ns");
	}
	
	private static void normal() {
		generate().stream().filter(filter).map(v -> v + 1).forEachOrdered(qwe);
	}
	
	private static void parallel() {
		generate().parallelStream().filter(filter).map(v -> v + 1).forEachOrdered(qwe);
	}
	
	private static List<String> generate() {
		return IntStream.range(0, 9999).boxed().map(String::valueOf).collect(Collectors.toList());
	}
	
	private static final Predicate<String> filter = v -> v.length() == 3;
	private static final Consumer<String> qwe = v -> {};
}

```

##結果
```結果
stream
13381900ns

parallelStream
8380600ns
```

結構違うんですね

##ただし...
マルチスレッドなので
スレッドセーフではなくなります。

下手なことをすればnullとかInterruptedException出るので
しっかり同期化制御をしておきましょう
rails 初心者によるrails 6.0.1で新しくプロジェクトを立ち上げ

#途中までは下記の記事を参考に
https://qiita.com/yuitnnn/items/b45bba658d86eabdbb26
https://webird-programming.tech/archives/194

途中までは問題なく進めることはできたのですが、
bundle install --path vendor/bundle

の段階で躓きました。そんな時は下記のコードを入力してからもう一度トライ！
$bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"


##Webpackerのダウンロードも忘れずに！
bundle exec rails webpacker:install

webpackerをインストールしないとrails 6はどうやらうまくいかないようです。
あとは

bundle exec rails db:createをしてmysqlを使えるようにしましょう！
cronで実行時の言語設定について

# cronで実行時の言語設定

環境変数LANGが反映されない。
LANG=C
ぽい？

# どうするか

```
* * * * * export LANG=ja_JP.UTF-8; スクリプトのパス
```

# 参考URL

https://orebibou.com/2014/12/cron%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9A%E6%9C%9F%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AB%E6%B3%A8%E6%84%8F%E3%81%97%E3%81%9F/#3LANG

https://gomi.blog.so-net.ne.jp/2006-09-22
自己紹介

#自己紹介

何故描こうと思ったのか？
それは、はじめの一歩として、自分のことを誰かに知ってもらいたい。
そして自分の決意表明として、これからプログラミングを本気で学びたいと思ったことがきっかけです。

#プロフィール
豊田俊成(Toyota　Toshinari)　１９８９年6月２７日生(３０歳)
趣味：読書、マラソン（年４回フルマラソン完走）→現在はプログラミング勉強
好きな食べ物：チーズケーキ（よくファミレスで勉強前に食べてます）
家族構成：自分と妻、息子三人（小学3年生、小学1年生、1歳）

#仕事内容は？
タイヤ会社にて設備の点検、メンテナンス業務

#プログラミングを勉強するきっかけは？
現在、働き方改革と叫ばれている中で、グローバル化が進み、テクノロジーの変化が物凄い勢いで変化している現代において、自分の市場価値をあげ、将来、会社がなくなってもお金を稼げるスキルを身に付けたいと思ったことがきっかけ。会社が10年生き延びる確率は６.４％というデータもある。
プログラミングを学び、将来は世界中に幸せなサービスを届ける会社を作りたい。そのためには、まずはプログラミングスキルを身に付け、AI、IoT等の知識を身に付けていきたいと思い、プログラミングを学びはじめました。


#勉強のはじめ方
10月初めにMacBookpro１３インチを購入、インターネット環境整備。
書店の本（HTML、CSS）の購入、学習し、タグの種類、コードの書き方などの基礎知識を学ぶのと並行してProgateにて学習。
11月11日よりgacco、 Aidemyにて学習をはじめました。

#将来のプラン
まずは、web制作にて副収入を得ることからスタート。
そこからAI、IoT、機械学習の勉強を開始。
Python、競技プログラミングに挑戦し、レベルアップを図る。
（期限：２０２０年の6月末）
その後、転職活動を開始、さらにスキルアップします。
33歳に起業予定。

#起業の知識を学ぶために
何故起業を目指すのか？
それは、世界中の人々を幸せにするため、世界一のサービスを作りたいから。
そのため、福岡で開催するスタートアップ研修に11月から参加。

#英語学習
隙間時間にYoutubeの動画にて無料で学習中。
英会話、英単語、英語の歌、英語のドラマ等。
（英語が大の苦手で中学、高校の記憶が少し残っている程度しかない・・・）

#Qiitaの使い方
学んだことのアウトプット、自分の勉強記録として使っていきたいと考えてます。
よろしくお願いいたします。
【学習ノート】AWS SAA取得に向けて(Lambda)

# Lambda
AWSのサーバレスアーキテクチャの中枢を担い、以下のような特徴を持ち、結果として、インフラ管理の大部分をクラウドに任せることができる。

## 特徴

- プログラム実行環境を提供し、インフラの構築/管理にかかる時間を減らせる
- リクエスト量に応じて自動的にスケールする
- リクエスト量や処理時間に応じた課金モデルが採用されている

## 利用方法

Lambdaを利用するには***Lambda関数***を設定する必要がある

- Lambda関数の設定
    - 実行プログラム
        - 言語
            - 特に推奨される開発言語はない
        - 必要な定義
            - 割り当てるメモリ量
                - CPUパワーは割り当てたメモリ量によって決まる
            - タイムアウトまでの時間
            - Lambdaに割り当てるIAMロール
            - VPC内で実行するかVPCの外で実行するか
    - 実行トリガー
        - 実行トリガーの例
            - S3バケットにファイルが追加された時
            - SNS通知が発行された時
            - API　GatewayへのHTTPSリクエストがあった時
            - CloudWatch Eventsによって定義されたスケジューリング実行

## 課金体系

lambdaの課金体系は下記2点を基準に求める

- Lambda関数の実行回数
    - 0.20USD/1,000,000件
- Lambda関数の実行時間
    - Lambda関数ごとに割り当てたメモリ量によって単位課金額が決まる
- 無料利用枠
    - AWS 無料利用枠の期間が終了しても期限切れになることはない。　恒常的な無料利用枠。
    - 1,000,000 件のリクエスト/月
    - 400 GB-秒/月

参考図書:AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト[アソシエイト]
AWSのすべてのサービスにReadOnly権限を与えたいときのTips

手っ取り早くアカウントへのログイン権限を与えたいけど、変更権限は一切与えたくないというときってありませんか？最小権限にすべきというのはわかっていても、一から権限ポリシーを作るのは大変です。
そんなときは、AWS管理ポリシーのReadOnlyAccessをあてておけば、とりあえず変更されることを防げます。すべてのサービスに対して読み取り権限のみがAllowされています。

![コメント 2019-11-11 165832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285150/72122c77-f593-df2f-3f76-756543f1c3d9.png)


似たようなポリシーにViewOnlyAccessという管理ポリシーもありますが、2018年10月を最後に更新が止まっているようなので、ReadOnlyAccessを使うのが無難と思われます。
UICollectionViewのヘッダー(header)の数の関数でハマった(numberOfSections)[Swift 5]

## 現状
CollectionViewの`header`の数を増やしたい時にはまったのでメモ
`header`を2つに増やしたいだけなのに

これはダメ(breakpoint通らない)

```swift
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 2
}
```

これもダメ(breakpoint通らない)

```swift
func numberOfSections(collectionView: UICollectionView) -> Int {
        return 2
}
```

## 注意点
CollectionViewの`header`(つまりsection)の数を増やすには
`numberOfSections(in collectionView)` ->**ヘッダーの数**
`collectionView(_ collectionView, numberOfItemsInSection)`->**セクションごとのcellの数**
`collectionView(_ collectionView, cellForItemAt)`->**セクションごとのcellの内容**
この3つを変更する必要がある。

**※`override`するわけではないので関数名や引数名が間違っているとDelegateではなく独自関数として扱われ(多分)
buildが通ってしまうので要注意**(Delegateは関数名, 引数名は要確認)

## 対策

この通りに書けばいけます

```swift
func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
}
```

## 参考
**・[【Swift】UICollectionReusableViewの使い方。ヘッダー、フッターのセクションに使われる部品 | はじはじアプリ体験記](https://hajihaji-lemon.com/smartphone/swift/collection-reusable-view/)**
->めちゃくちゃ参考になったんですが、情報が古いのかheaderの数のところだけ間違っていました

**・[UICollectionViewのHeaderカスタマイズいろいろ - Qiita](https://qiita.com/akatsuki174/items/626fe4d71990694f946f)**
**・[【Swift】UICollectionViewをコードで実装する - Swift・iOS](https://www.hfoasi8fje3.work/entry/2019/02/14/000000)**
ProcessingとSQLiteを連携する

Processing3上からSQLiteを使ってデータベース操作する方法のまとめ。

以下のサイトを参考にしています。
http://mslabo.sakura.ne.jp/WordPress/make/processing%E3%80%80%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/sqlite%E3%82%92%E4%BD%BF%E3%81%86-db%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3/

## sqlite-jdbcをスケッチフォルダ内に保存する。

まずはProcessingを開いて、ファイルを保存する。するとスケッチのフォルダが作成される。(今回は、DB_test_1.pdeとして保存してみる)

次に、ProcessingからSQLiteを操作するのに必要なJDBCをスケッチフォルダに保存する。

JDBCはSQL言語ごとに様々なものがあるが、SQLite用JDBCは以下のサイトから入手できる
https://github.com/xerial/sqlite-jdbc

入手したJDBCはスケッチフォルダ内に新たにcodeフォルダを作成し、その中に保存しよう。
![スクリーンショット 2019-11-11 16.31.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329378/79c9ad30-c5f1-3a35-401b-200c0d54cb94.png)

これで事前準備完了。

## JavaのSQLパッケージを利用したコードを記述する

ProcessingはJava環境なので、Javaのパッケージを利用することができる。JavaからSQLを利用する際には、java.sqlパッケージを利用しよう。

このjava.sqlパッケージ内には、DBMS(DataBase Management System)への接続・切断やSQL文を送信する際に利用できるクラスが含まれている。

今回は、DBMSへの接続準備を行うためのDriverManagerクラス、DBMSへの接続を行うConnectionクラス、SQL文を送信するためのStatementクラスを利用する。

最終的なコードは以下の通り。

```Java:DB_test_1.pde
import java.sql.*; // パッケージのインポート
Connection connection = null; // 接続のためのクラスを宣言

void setup(){
  // DBファイルをスケッチフォルダに生成するため、絶対パスを指定。もしtest.dbが存在しない場合はスケッチ実行時に、test.dbが新たに作成される
  String dbName = sketchPath("test.db");
  
  // OPEN DB
  try{
    connection = DriverManager.getConnection("jdbc:sqlite:" + dbName); 
    Statement statement = connection.createStatement();
    statement.setQueryTimeout(30); // set timeout to 30 sec
    
    statement.executeUpdate("drop table if exists person");
    // 新たにTableを作成するためのSQL文を送信
    statement.executeUpdate("create table person(id integer, name)");

    // 作成したTableにデータをInsertしてみる
    statement.executeUpdate("insert into person values(1, 'leo')");
    statement.executeUpdate("insert into person values(2, 'yui')");

    // Tableの中身をすべてSelectし、Resultsetクラスに読み込む
    ResultSet rs = statement.executeQuery("select * from person");
    while(rs.next()){ // ResultSetに読み込まれたデータを表示する
      // read the result set
      String format = "name: %4s, id: %4d";
      println(String.format(format, rs.getString("name"), rs.getInt("id")));
      //print("name: " + rs.getString("name"));
      //println(", id: " + rs.getInt("id"));
    }
  } catch( SQLException e ){
    println(e.getMessage());
  } finally{
    dbClose();
  }
}

// データベース終了時の例外処理をまとめただけの関数
void dbClose(){
  try{
    if(connection != null){
      connection.close();
    }
  } catch (SQLException e){
    e.printStackTrace();
  }
}
```

上記コードを実行すると、test_dbファイルが新規作成され、Processingのコンソールに挿入したデータが表示されます。

以上が簡単なデータベースの利用方法の説明となります。
apps/assetsディレクトリを消したらassets以下のディレクトリ使っていないのにExpected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)になって困った人へ

## 方法1: sprockets/railtieをロードしない

`require 'rails/all'`ではなく以下のような感じで個別にロードする。

```ruby
require "rails"
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
# require "sprockets/railtie"
```

参考：[Railsガイドの「2.1 railties/lib/rails/all.rb」に、rails/allによって読み込まれるモジュールの解説がある](https://railsguides.jp/initialization.html#railties-lib-rails-all-rb)

ただ、これをやるとRailsのバージョンアップデート時に毎回差分が発生してめんどい感じにはなる。

## 方法2: 空のmainfest.jsを置いておく

```
mkdir -p app/assets/config && echo '{}' > app/assets/config/manifest.js
```

消極的だがmanifest.jsが空なら何もしないので、まずまずな方法かなと。
【学習ノート】AWS SAA取得に向けて(ECSと他コンテナ関連サービス)

# ECS(Elastic Container Service)

Docker環境を提供するサービス
ECSはDocker環境に必要な設定が含まれたEC2インスタンス(cluster)を起動し、その管理をサポートします

## 特徴

1つのCluster上では複数のコンテナ(Task)を実行することができる
Cluster上で動作するTaskの定義は***Task Definition***で行う
Taskの役割毎にTask Definitionを用意し、それをもとにCluster上でTaskが起動する
また同じTaskを複数用意したい時など、Serviceを利用すれば「Webサーバ用のTaskDefinitionを2つ起動する」ということが可能になる

セキュリティ面での特徴としては

- TaskごとにIAMロールを割り当て可能
    - EC2ではインスタンス単位でしか割り当てられない

## AWS上の他のコンテナサービス

- AWS Fargate
    - EC2を利用しないでコンテナを動かすサービス
        - インスタンスの管理が不要になる
- Amazon Elastic Container Service for Kubernetes(EKS)
    - OSSのKubernetesを利用する
    - コンテナ管理の自動化のためのオープンソースプラットフォーム
    - EC2を利用せず、マスターをサービスとして提供する
        - 従来はマスター用のEC2インスタンスを複数用意しての管理が必要だった
- Amazon Elastic Container Registry(ECR)
    - コンテナイメージをレジストリ[^1]で管理する
    - レジストリへのpush/pull権限をIAMで管理することもできる

### 用語

- Cluster
    - EC2インスタンス
- Task
    - EC2インスタンス上で呼ばれるコンテナ
- Task Definition
    - Taskの設定ファイル(タスク定義)
- Service
    - タスク定義の指定した数 (「必要数」) の同時インスタンスを ECS クラスターで実行する

[^1]: ストレージとコンテント配送サービス

参考図書:AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト[アソシエイト]
Ruby on Rails 操作を元に戻す方法

#操作を元に戻す方法
　この記事では、railsでコントローラーなどを作成した後などに、その操作を取り消す方法について説明する。

```ruby
$ rails generate controller StaticPages home help
```
　操作を元に戻したいケースとは、生成したコードに変更を加えたい場合などである。例えば、コントローラを生成した後で、もっといいコントローラ名を思い付き、生成したコードを削除したくなった場合などである。上記のようにStaticPagesコントローラーを生成すると、コントローラーファイルだけでなく、configのroutesファイルやviewのhome,helpファイルなどの関連ファイルが大量に生成されてしまい、コントローラーファイルを削除するだけでは操作を元に戻すことができない。そこで、下記のようにgenerateコマンドと対をなすdestroyコマンドを用いれば、関連するファイルをすべて削除することができる。

```ruby
$ rails destroy  controller StaticPages home help
```
なおコントローラだけでなく、モデルについて同様の方法で元に戻すことができる。

```ruby
$ rails destroy model User
```
TypeScript 3.7のリリースノートを確認しながら試す

TypeScript 3.7のリリースノートに乗っている内容を色々試していきます。
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions


#Optional Chaining

C#ではかなり前から導入されていたOptional chainingが実装されましたというアナウンス。
とても大きな変更ですね。

2014年くらいから要望事態は上がっていた模様。
https://github.com/microsoft/TypeScript/issues/16

以下の様なコードを書いた場合、

```typescript:opch.ts
var x = { y: { z: null, q: undefined } };
console.log(x?.y.z)
```
生成されるコードは以下となります。

```javascript:opch.js
var x = { y: { z: null, q: undefined } };
console.log((_a = x) === null || _a === void 0 ? void 0 : _a.y.z);
```

生成されたコードを見ると分かりやすいですが、?を変数の後ろに書くと、変数がnullの場合後続の処理を行わない様にしてくれる機能ですね。
便利。

# Nullish Coalescing

C#ではかなり前から導入されていたNullish Coalescingが実装されましたというアナウンス。

以下の様なコードを書いた場合、

```typescript:nullish.ts
var test = x.y.z ?? "Nullish Coalescing"
console.log(test)
```
生成されるコードは以下となります。

```javascript:nullish.js
var test = (_b = x.y.z, (_b !== null && _b !== void 0 ? _b : "Nullish Coalescing"));
console.log(test);
```

??の左がnulまたはundefinedなら右が有効になります。
三項演算子がトレンドになる世界線の人に、この変更は好ましいか聞いてみたい物です。

#Assertion Functions

この方の記事が大変参考になるので、詳細は割愛します。
https://qiita.com/uhyo/items/b8d2ea6fbf6214fc4194

リリースノートでも、node.jsの例を出しながらTypeScriptの落とし所を探る過程が書かれています。

issueからも結構な議論が行われているのが分かります。
https://github.com/microsoft/TypeScript/pull/32695

# Better Support for never-Returning Functions

関数が戻り値を持たないケースのより良いアプローチとして、以下の通り終了結果もreturn出来る様になりました。

```javascript:nullish.js
function dispatch(x: string | number): SomeType {
    if (typeof x === "string") {
        return doThingWithString(x);
    }
    else if (typeof x === "number") {
        return doThingWithNumber(x);
    }
    return process.exit(1);
}
```

Exception発生時の調査が少しだけ楽になるのではないでしょうか。

# The useDefineForClassFields Flag and The declare Property Modifier

破壊的変更の項目に、この変更が原因となった物が含まれていたので紹介します。
TypeScript3.7は.d.tsファイルでget/setアクセサーを発行するため、3.5以前のコードではエラーになるケースがあるとの事です。

この項目には、二つに大きな変更があると記載されています。

```
The two biggest changes are the following:

Declarations are initialized with Object.defineProperty.
Declarations are always initialized to undefined, even if they have no initializer.
```

コード例がこちら。親クラスのsetterが無視される形ですね。

```typescript:a.ts
class Base {
    set data(value: string) {
        console.log("data changed to " + value);
    }
}
class Derived extends Base {
    // No longer triggers a 'console.log' 
    // when using 'useDefineForClassFields'.
    data = "10";
}
```

# まとめ

今回のアップデートはTypeScriptをより安全に使えるという観点というよりは
よりスマートなコーディング体験にしてくれるといった内容なのかなと思います。

まだまだ伸び代のある、未来のある言語だと思うので引き続き追う価値十分な言語だと思います。
Route53でダイナミックDNS

# Elastic IP をケチりたい

たまにしか起動しないインスタンスに Elastic IP をアタッチするのはもったいない。といって、起動するたびにIPアドレスが変わるとホスト名でアクセスできなくて面倒くさい。

……と思ったので Route 53 でIPアドレスを自動設定してくれるスクリプトを書いた。

**2019年11月21追記**
一段と自動化した Lambda を作りました：
[[AWS]インスタンス起動時にIPアドレスを自動でRoute53に登録する](https://qiita.com/keys/items/43adf968d366e80f0003)

## 用意するもの

* 登録したい Route 53 のホストゾーンID

## ホスト名

対象のOSでホスト名を設定する。この名前が Route 53 に登録される。ドメイン名がホストゾーンIDと一致していることを確認する。

Amazon Linux 2 では次のような感じでホスト名を設定できる。

```
hostnamectl set-hostname route53test.example.com
```

## IAMポリシー

このポリシーをアタッチしたロールを、インスタンスにアタッチする。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "route53dynamic",
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/Z123456789ABCD"
        }
    ]
}
```

## スクリプト本体

これを `/usr/local/sbin` に置く。

```shell:set-dns-record.sh
#!/bin/bash

HOSTZONE_ID=$1

host_addr=`curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
host_name=`hostname`
tmp_file=`mktemp`

cat <<EOS > $tmp_file
{
  "Comment": "optional comment about the changes in this change batch request",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "${host_name}.",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "${host_addr}"
          }
        ]
      }
    }
  ]
}
EOS

aws route53 change-resource-record-sets --hosted-zone-id $HOSTZONE_ID --change-batch file://$tmp_file

rm $tmp_file
```

## ユーザーデータ

毎起動時に実行したいので、このあたりを参考にしてユーザーデータを書く。ちょっと面倒くさい。

[Amazon EC2 インスタンスを再起動するたびにユーザーデータを実行して自動的にファイルを作成する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/execute-user-data-ec2/)

```
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
/usr/local/sbin/set-dns-record.sh Z123456789ABCD
--//
```

ユーザーデータに直接スクリプトを書くのもあり、なのかも……？
Amazon Cognito に入門してみる 〜 1


全く無知なので、ちょっと調べてみました。

## 何ができる？

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/what-is-amazon-cognito.html

### ユーザープール機能

ログインを提供する機能です。

- AWS内にユーザディレクトリ(**ユーザープール**)を作成できる機能のこと
    - ユーザパスワード、メールアドレス、電話番号、カスタム属性などを格納可能　ユーザにまつわるデータベースの構築ですね
    - LDAPみたいなものだと思ってます
- 上記ユーザプールを利用して認証・および認証済みをあらわすトークン(**ユーザープールトークン**)を取得できる
- ユーザーはグループにまとめることも可能
- [ソーシャルサインインを用いて、Googleなど他プロバイダからもログイン可能](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-configuring-federation-with-social-idp.html) (Identity Provider機能)
    - この場合でも、ユーザープールにユーザのエントリは残る
- ログインページをAWS上で作成することが可能
- JWT発行まわりだけを丸投げすることも可能
    - リフレッシュトークンとアクセストークンを発行してくれます
    - APIサーバはアクセストークンを検証して、問題なければユーザログイン済みとして扱えばOK
        - AWSが発行するアクセストークンは公開鍵暗号形式(RS256)
        - APIサーバがログイン機能を持つ必要はありません。

### アイデンティティプール機能

ログイン後のAWSサービスへのアクセスを提供する機能です。

- ユーザープールからユーザ認証成功時に発行されるトークンを使って、AWSのサービスに対するアクセス権を得ることができる機能のこと
    - e.g. S3, AppSync, DynamoDB, Lambda
- 別にユーザープールからのトークンだけはなく、他のOAuthプロバイダからのログインも使える。　(**Federated Identity**)

## 何に使える？

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-scenarios.html

- ログイン
    - 要するにユーザ認証プロバイダ
    - 作成したサービスのログインまわりをAmazon Cognitoに投げられる
- サーバレスアプリ
    - SPA + AWSのマネージドサービスで構成する
    - ログインは他のOAuthプロバイダ、あるいはAWS上のユーザープールを用いる
    - ログイン済みユーザには、アイデンティティプールを使って、AWS上に用意したLambdaや、マネージドサービスに直接アクセスしてもらう
    - ここらへんのクラウドスタックをすぐに構築できるようになっている[AWS Amplify](https://aws.amazon.com/jp/amplify/)はCognitoを中心にしたスタックを見据えていると思います

## 料金

https://aws.amazon.com/jp/cognito/pricing/

ユーザープールについて、月ごとのアクティブユーザ（サインインなどが生じたユーザ）の数で、今（2019/11/11）のところ、 50,000ユーザまで無料、そこから 0.00550 USD / ユーザ、もっといくとスケールメリットで安くなる、となっています。

| 月間ユーザ(MAU) | 料金(USD) | 料金(JPY 110円換算) | MAUあたりの料金増分 |
|----|----|----|----|
| 50,000 | 0 | 0 | ここから先は 0.00550USD |
| 60,000 | 55 | 6,050 |  |
| 70,000 | 110 | 12,100 |  |
| 80,000 | 165 | 18,150 |  |
| 90,000 | 220 | 24,200 |  |
| 100,000 | 275 | 30,250 | ここから先は 0.00460USD |
| 110,000 | 321 | 35,310 |  |
| 200,000 | 735 | 80,850 |  |
| 400,000 | 1,655 | 182,050 |  |
| 800,000 | 3,495 | 384,450 |  |
| 1,000,000 | 4,415 | 485,650 | ここから先は 0.00325USD |
| 2,000,000 | 7,665 | 843,150 |  |
| 4,000,000 | 14,165 | 1,558,150 |  |
| 8,000,000 | 27,165 | 2,988,150 |  |
| 10,00,0000 | 33,665 | 3,703,150 | ここから先は 0.00250USD |
| 20,000,000 | 58,665 | 6,453,150 |  |
| 40,000,000 | 108,665 | 11,953,150 |  |
| 120,000,000 | 308,665 | 33,953,150 |  |

(※実際にサービス利用する際は自分で計算してください）

小規模サービスだと無料、全国民が使うサービスを作ると3千万円ぐらいかかるそうです。（ただし、その前にアカウントごとのリミットあり）

また、上記はプレーンなユーザープールの使い方に対して課金されており、TOTPやSAMLなど使うともっと高いレートがMAUごとに適用されます。

## 次回

実際になにか構築してみたい
postfixでメール受信時にパイプしてプログラムを動かす

# よくあるやり方

/etc/aliases
でパイプするやり方

```
# php@example.comにメールが来た場合、mail-exec.phpを起動する
php: "| /usr/bin/php -f /var/www/mail-exec.php > /dev/null 2>&1"
```

# 共通してる注意点

おそらくroot権限のプログラムは起動できない（検証するとそんな感じだった）。
上記のよくあるやり方で/rootにあるphpが起動できなかった（パーミッションとか変えても）。

# よくあるやり方の問題点

http://www.omakase.org/mail/aliasenobody.html
によると、あまりよろしくないそうです。

また、いちいち変更がある場合に/etc/aliasesを書き換えるのはめんどくさいです。

# おすすめのやり方

## postfixの設定

/etc/aliases
でプログラムの処理やらが書いてあるファイルを指定できます。

```
# メールが来たら、rootへ転送と/home/user/postfix_testに書いてあることを実行する
apache:         root, :include:/home/user/postfix_test
```
/etc/aliasesを変更したら

```
newaliases
```
を実行してください。

:include:を使用するには
/etc/postfix/main.cf
に

```
allow_mail_to_commands = alias,forward,include
```
を追加する必要があります。
追加したらpostfixを再起動してください。

## includeするファイルの中身

よくあるやり方で書く内容をそのまま記述してください。
プログラムはクォーテーションでかこってください。

```
"|/bin/php -f /home/user/mail_test.php > /home/user/test.log"
```

## 効果

- 実行ユーザがincludeするファイルのユーザ（/home/user/postfix_testの場合user）になるらしいです。
- 変更がある場合に/etc/aliasesを触る必要がありません。
Macで開発に必要なものを入れる手順メモ

# はじめに
Macをもらって色々インストールしようとしたら情報が散ってて悲しくなったのでまとめておく。
なお、個別のものは個別の人たちが書いているので基本はまとめるだけ。

## インストールしたい人たち
xcode
homebrew
git/gitflow
php/phpbrew

## 手順
### homebrew
homebrew を入れるのにxcodeがいるのでAPP Store よりインストールしておく。
やり方は以下
[MacにHomebrewを導入する方法](https://qiita.com/balius_1064/items/ac7dff5ef10eaf69996f)

### git
多分macに入っているけど個人的にはbrewで一括管理したいので入れておく。
[HomebrewでGitをインストールする](https://qiita.com/micheleno13/items/133aee005ae37c28960e)

補完およびブランチ名の表示
[bashでgitのブランチ名を表示](https://qiita.com/tanishi/items/2adb71024d675bc43177)

### git flow
~~brew install git-flow~~
→下のコマンドで入れないと、finishしたブランチがリモートに残ってうざい

```bash
brew install git-flow-avh
```


タブ補完

```bash
brew install git bash-completion
```


```vim
# ~/.bash_profile
. /usr/local/etc/profile.d/bash_completion.sh
```

### phpbrew
https://github.com/phpbrew/phpbrew/blob/master/README.ja.md

エラーでまくるので必要なものはbrewでインストールしましょう。
突っかかりそうなのはbzip2とzlibですのでとりあえずこれ置いときます

```bash
phpbrew install 5.6.38 +default +bz2="$(brew --prefix bzip2)" +zlib="$(brew --prefix zlib)"
```
ListのEnumeratorが構造体ではまった話

# `List<T>`を`GetEnumerator()`して得られる`Enumerator`は、クラスじゃなくて構造体！！！

[入れ子集合モデルから木構造を作る](https://qiita.com/ShTair/items/9447cb053afa2761c582)のプログラムを書いてるときに、思ったとおりに動かなくて困ったので、そのメモ。

**型を、`List<T>`にするか`IList<T>`にするかで挙動がガラッと変わる話**です。

## やりたかったこと

いろんな**メソッドをまたいで**、リストの要素を順番に使う必要があった。
→そうだ、`IEnumerator`を渡せばいいじゃん！
（インタフェースは参照型なので、メソッド呼び出し先での変更が呼び出し元に反映される）
**→呼び出し先で値を消費しても、呼び出し元で反映されない…**

```C#
void Function1(List<int> data)
{
    var dataEnumerator = data.GetEnumerator();
    while (dataEnumerator.MoveNext())
    {
        Console.WriteLine($"Function1: {dataEnumerator.Current}");

        // 別の関数でもリストの値を使いたい。
        Function2(dataEnumerator);
    }
}

void Function2(IEnumerator<int> dataEnumerator)
{
    // この中でも、dataEnumerator.MoveNext()を呼び出して、値をいくつか消費する。
    for (int i = 0; i < 2; i++)
    {
        if (!dataEnumerator.MoveNext()) break;
        Console.WriteLine($"--Function2: {dataEnumerator.Current}");
    }
}
```

実行する。

```C#
Function1(new List<int> { 1, 2, 3 });
```

```
↓望む結果
Function1: 1
--Function2: 2
--Function2: 3

↓実際の結果
Function1: 1
--Function2: 2
--Function2: 3
Function1: 2
--Function2: 3
Function1: 3
```

### `List<T>`の`GetEnumerator`、特殊な実装がされていた…
速度のため、ですね？
`IEnumerable<T>`の`GetEnumerator`は`IEnumerator`を返すけど、`List<T>`とか`Stack<T>`とかは、独自の`Enumerator`（構造体）を返すようになっていた。同じ関数名だから引っかかった…

```C#
var dataEnumerator = data.GetEnumerator();
```

これで、返ってくる型が`IEnumerator<T>`だと思い込んでた失敗でもある。

## 解決方法
すなわち、先に`List<T>`を`IEnumerable<T>`に変換しておくとか、構造体の`Enumerator`を`IEnumerator<T>`の変数で受けるとかすれば、ボクシングされてうまくいく。
[入れ子集合モデルから木構造を作る](https://qiita.com/ShTair/items/9447cb053afa2761c582)では、前者の方法、仮引数で`List<T>`じゃなくて`IEnumerable<T>`を受け取るようにした。実際に欲しい機能は、`IEnumerable<T>`インタフェースだからね。

今回は`IEnumerable<T>`にすることで解決したんだけど、インタフェースであればいいので、`IEnumerable<T>`じゃなくて`IList<T>`にしてもちゃんと思った通りに動く。
`List<T>`にするか`IList<T>`にするかで変わっちゃうのは、なかなかですね…
リストビューで選択したレコードに対して Apex を実行する方法

今回は Salesforce オブジェクトのリストビューで複数選択したレコードに対して、 Visualforce ページを呼び出し Apex で処理する方法をご紹介します。

##動作イメージ
1. 商談のリストビューで、レコードを複数選択
2. リストボタンで VF ページを開き、選択されている商談レコードを確認
3. 選択された商談レコードに対して Apex 処理を実行し、前の画面に戻る

![ezgif-3-b2cfd7098a56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26378/b8ec9714-3428-64f1-20c8-0964f8f6ef12.gif)


##設定方法
#### 1. Visualforce ページと Apex を作成

```java:CustomOpportunitySetController.apxc
public with sharing class CustomOpportunitySetController {
    public List<Opportunity> selectedOpportunities {get;set;}

    // コンストラクター
    public CustomOpportunitySetController(ApexPages.StandardSetController controller) {
        List<Opportunity> opportunities = controller.getSelected();
        this.selectedOpportunities = [SELECT Id, Name FROM Opportunity WHERE Id IN :(new Map<Id, Opportunity>(opportunities)).keySet()];
    }
    public void execute() {
        // this.selectedOpportunities に対し必要なの処理をする
    }
}
```

```html:VisualforcePageForOpportunityListButton.vfp
<apex:page standardController="Opportunity" recordSetvar="opportunities" extensions="CustomOpportunitySetController">
    <apex:form>
        <apex:pageBlock title="現在選択されている商談" >
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton action="{!execute}" value="処理を実行" oncomplete="history.back();" />
            </apex:pageBlockButtons>
            <apex:pageBlockTable value="{!selectedOpportunities}" var="opportunity">
                <apex:column value="{!opportunity.Name}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>
```

#### 2. リストボタンの作成と表示
`設定 > オブジェクトマネージャー > 商談 > ボタン、リンク、およびアクション > 新規ボタンまたはリンク` から、以下の要領で作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26378/530df281-a4ba-61c2-6da8-b23f2b6ac413.png" width="480" />

`設定 > オブジェクトマネージャー > 商談 > Salesforce Classic の検索レイアウト > リストビューのドロップダウンメニューから編集 ` から、以下の要領で作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26378/00d70ea2-dc8d-f0bd-a0a9-dfe8e7f1eaf4.png" width="480" />
UE4 HUDに使う、体力ゲージなどのマテリアルのおいしい作り方 

Texture Coordinateノードは基本的にテクスチャの「UV」っていうピンにつなげて使うか、
もしくはそれ自体をテクスチャみたいにして使うこともあるが、
今回はちょっと変わった使い方を発見したので、それを紹介する。

UIによく使われるバー(体力ゲージなど)のマテリアルをこれを用いて作る。
Content Exampleにもそのアセットがあり、それをカンニングすれば作れるが、
その方法は少し面倒くさい。
なので別の方法を探して、このような実装方法を発見した。

![201709012308214d0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531371/61e5f9fb-d468-40c0-12a9-a3eda2defa2a.png)

Parameterをいじるだけでおっけー。
iOS13+のSafariでdevicemotionやdeviceorientationイベントの許可を取得する方法

iOS 13〜 の モバイル Safari では、端末の傾きや加速度などの情報を提供する DeviceMotionEvent や DeviceOrientationEvent を取得する際、ユーザーの許可が必要になりました。

実装に少し手間取ったのでまとめておきます。

## 注意点
### HTTPSであること
HTTPS通信であることが求められます。
開発環境の準備が面倒な場合は、Chromeで開発を進めるといいかもしれません。

### ユーザーのアクションが必要
ページ表示直後にいきなり許可を取得することはできません。
ボタンなどを設置してユーザーにクリックしてもらってonClickなどを発火させてから許可を得る必要があります。

### iOS 12.2 ではこの方法は使えない
iOS 12.2 ではユーザーがSafariの設定を変更しない限りイベントを取得できないという悲しい仕様です。

設定 ＞ Safari ＞ 「モーションと画面の向きのアクセス」の設定項目が追加されており、デフォルトでOFFになっています。

そのため iOS 12.2 では、ユーザーにこの設定をONに変えてもらうほかに devicemotion や deviceorientation イベントを取得する方法はありません。

## コード

### DeviceMotionEvent 用のコード

```sample.js
const requestDeviceMotionPermission = () => {
  if (
    DeviceMotionEvent &&
    typeof DeviceMotionEvent.requestPermission === 'function'
  ) {
    // iOS 13+ の Safari
    // 許可を取得
    DeviceMotionEvent.requestPermission()
    .then(permissionState => {
      if (permissionState === 'granted') {
        // 許可を得られた場合、devicemotionをイベントリスナーに追加
        window.addEventListener('devicemotion', e => {
          // devicemotionのイベント処理
        }）
      } else {
        // 許可を得られなかった場合の処理
      }
    })
    .catch(console.error) // https通信でない場合などで許可を取得できなかった場合
  } else {
    // 上記以外のブラウザ
  }
}

// ボタンクリックでrequestDeviceMotionPermission実行
const startButton = document.getElementById("start-button")
startButton.addEventListener('click', requestDeviceMotionPermission, false)
```

### DeviceOrientationEvent 用のコード
上記の devicemotion 用のコードと同様です。

```sample.js
const requestDeviceOrientationPermission = () => {
  if (
    DeviceOrientationEvent &&
    typeof DeviceOrientationEvent.requestPermission === 'function'
  ) {
    // iOS 13+ の Safari
    // 許可を取得
    DeviceOrientationEvent.requestPermission()
    .then(permissionState => {
      if (permissionState === 'granted') {
        // 許可を得られた場合、deviceorientationをイベントリスナーに追加
        window.addEventListener('deviceorientation', e => {
          // deviceorientationのイベント処理
        }）
      } else {
        // 許可を得られなかった場合の処理
      }
    })
    .catch(console.error) // https通信でない場合などで許可を取得できなかった場合
  } else {
    // 上記以外のブラウザ
  }
}

// ボタンクリックでrequestDeviceOrientationPermission実行
const startButton = document.getElementById("start-button")
startButton.addEventListener('click', requestDeviceOrientationPermission, false)
```

### 参考
[How to Request Device Motion and Orientation Permission in iOS 13](https://medium.com/flawless-app-stories/how-to-request-device-motion-and-orientation-permission-in-ios-13-74fc9d6cd140)
機能仕様書の書き方

今回は機能仕様書について述べていこうと思う。

##テンプレート
会社の機能仕様書は見せられないが、機能仕様書のテンプレートはネット上に沢山あるのでそちらを参照していただきたい。例えば以下のリンクが参考になりそうだ。
https://biz.trans-suite.jp/9158

##ポイント
機能仕様書は「ユーザから見た仕様」について書く。プログラムなど詳細については次工程「詳細設計書」で書く。


##記入事項
大きく分けて以下の8つの項目がある。
1. 表紙
2. 改訂履歴
3. 目次
4. 用語説明
5. システム
6. 機能策定方針
7. 機能概要
8. 機能仕様
9. 非機能仕様
10.データ仕様 

それぞれの項目ごとに説明していく。

###表紙
表紙には「○○システム機能仕様書 ver1.0」と「所属部署や名前等の出どころ」を書く。

###改訂履歴
改訂履歴には「日付」「版（ver）」「改訂者の名前」「内容」を書く。
文字通り、いつ誰が改訂したのか履歴を残す。

###目次
説明するまでもないが、各項目とページ数を書く。

###用語説明
機能仕様書で使う用語の定義を綴る。

###システム
システムの概要や構成、環境を書く。
　・概要　システムがどのようなシステムなのかを大まかに書く。
　・構成　クライアントやサーバなどについて、どのように構成されているのか書く。
　・環境　動作保証環境（OSのバージョンなど）や対応言語（python、java …）について書く。

###機能策定方針
エラーの扱い方について書く。例えば、どのエラーは処理を続行して、どのエラーは続行しないのかといったことである。（エラー以外にも記載事項はあると思うが、今回は触れない）

###機能概要
システムがどのような機能を持っているのか書く。

###機能仕様
機能概要で触れた機能などについて、より具体的な説明を行う。

###非機能仕様
機能仕様以外の仕様を書く。例えば性能や性能測定条件についてである。

##まとめ
機能仕様書は組織や人によって書き方が違うので、どれが正しいとは言えないが、
一例としてこの記事を参考にして頂きたい。
以上。
最大値を探そう Python 

まだまだ初心者なのでアドバイスがもらえたら嬉しいです。
さて、本題に入ります。ここではpythonを使ったn個の数字の中から最大値を探すアルゴリズムを作成していきます。アルゴリズムはできるだけ自分で考えました。意外と最大値を探すアルゴリズムを作るだけでも一苦労です。。。アルゴリズム難しい！！！

以下が私が作ったアルゴリズムです(コード雑ですみません！)

```python:max.py
num = int(input("何個数値を代入しますか?"))
i = 0
value_list = [] #数値を格納する配列を用意する
while i < num:
    value = int(input("数値を代入して下さい"))
    value_list.append(value) #用意したリストに値を追加していく
    i += 1

max_value = 0 #最大値を0で初期化
i = 0
while i < num:
    if value_list[i] >= max_value: #格納した数値を順番に比較していく
        max_value = value_list[i]
    i += 1

print(max_value) #最大値を出力

```

フローを説明していきます

```python 
num = int(input("何個数値を代入しますか?"))
i = 0
value_list = [] #数値を格納する配列を用意する
while i < num:
    value = int(input("数値を代入して下さい"))
    value_list.append(value) #用意したリストに値を追加していく
    i += 1
```
ここでn個(比較する数値の個数)を入れていきます。まとめて数値を扱うためにリストを使いました。これでn個の値を格納することができます。append()はpythonのデフォルトで入っているメソッドです。これでからの配列に数値を加えていくことができます。
※タプルをつかってしまうとタプルで組まれたイテラブル(配列みたいなもの)は変更加えれないので、要素の使いができなくなってしまうので注意

```python
max_value = 0 #最大値を0で初期化
i = 0
while i < num:
    if value_list[i] >= max_value: #格納した数値を順番に比較していく
        max_value = value_list[i]
    i += 1
```

ここでは、リストに格納された数値を順番に取り出し比較していくのですが、先に最大値を0で初期化しておきます。そして、順番に比較して最大値候補よりも大きい値が見つかればその数値は最大値の候補に再設定します。そして、最後に最大値を出力して終わりです。

いかがでしたか？意外にも最大値を探すアルゴリズムはプログラミング初心者にとっては難しいものでした。ほんとにエンジニアの方々はすごいと思います。尊敬です。
smartyの定数の文頭にスペースが入るときの対処方法【PHP】


## 結論

```smarty:stripで空白を削除する
{$smarty.const.HOGE|strip:null}
```

## 状況

```:動作環境
PHP 7.3.11
Smarty 3.1.34
```
smartyでPHPの定数を呼び出して直接利用したいときに、なぜか文頭に1スペースが入ってしまっていた。

```php
<?php
define("HOGE", "https://fuga.co.jp");
```

```smarty
<div><a href="https://sample.co.jp/?nexturl={$smarty.const.HOGE}">リンク先</a></div>
```

```:〇のようになってほしかったが、なぜか×のように1スペース入る
〇 https://sample.co.jp/?nexturl=https://fuga.co.jp
×  https://sample.co.jp/?nexturl= https://fuga.co.jp
```


結局理由はよくわからなかったが、smartyに用意されているstripを利用することで、無事に解決しました。
なぜスペースが入り込んでしまうのか分かる方はぜひ教えてください。

```smarty:stripで空白を削除する
<div><a href="https://sample.co.jp/?nexturl={$smarty.const.HOGE|strip:null}">リンク先</a></div>

 https://sample.co.jp/?nexturl=https://fuga.co.jp
```
ラズベリーパイでNeoPixelを使う


ラズベリーパイ３BでフルカラーシリアルLED NeoPixel(ws2812B)を以前使えたはずだが
Raspbian（Buster）に代えてからつまずいたことがあったのでメモしておきます。



# 配線
https://learn.adafruit.com/neopixels-on-raspberry-pi/raspberry-pi-wiring
ラズパイは3.3V信号 　Neopixelは5V信号のため
74AHCT125レベルコンバータを使う方法とダイオードを使う方法が紹介されている
ダイオードを使う方法で試してみる。信号線はGPIO18（PWM0)
**Raspberry Piの5V出力から数個を超えるNeoPixelsに電力を供給しない**
守らないと壊れます（壊しました）

# Raspberry Pi　ライブラリ
**https://github.com/jgarff/rpi_ws281x
Userspace Raspberry Pi PWM library for WS281X LEDs**

`git clone https://github.com/jgarff/rpi_ws281x`
scons が要るというのでインストール（makeの代わりのようなものらしい）
`sudo apt-get install scons`
`cd rpi_ws281x`
`scons`

~~でいいはずだが~~
~~‘makedev’が定義されてないとエラーが出た~~
~~://www.raspberrypi.org/forums/viewtopic.php?t=250220~~

~~mailbox.c を編集して **\#include \<sys/sysmacros.h>**を追加~~
~~`nano mailbox.c`~~
~~再び~~
~~`scons`~~（不要でした）
成功!

# python　ライブラリ
**https://github.com/rpi-ws281x/rpi-ws281x-python
Python library wrapping for the rpi-ws281x library**
`
sudo pip3 install rpi_ws281x
git clone https://github.com/rpi-ws281x/rpi-ws281x-python
cd rpi-ws281x-python/example
chmod 755 *.py
sudo python3 strandtest.py
`
成功!（sudo が必要）

# PWMを使う場合はAudioを無効に

以下を読んで適宜　/boot/config.txt の内容を書き換えて
https://github.com/jgarff/rpi_ws281x#pwm

dtparam=audio=on　をコメントアウトしたら動きました
AtCoder Beginner Contest 020 C - 壁抜け (二次元平面の探索)

# AtCoder Beginner Contest 020 C - 壁抜け
https://atcoder.jp/contests/abc020/tasks/abc020_c

これもよくあるパターンなので。

```python
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


h, w, t  = LI()
grid = SR(h)
for y in range(h):
    for x in range(w):
        if grid[y][x] == 'S':
            sy, sx = y, x
        elif grid[y][x] == 'G':
            gy, gx = y, x


def solve(x):
    min_cost = [[INF] * w for _ in range(h)]
    min_cost[sy][sx] = 0
    que = deque([(sy, sx)])
    while que:
        cy, cx = que.popleft()
        for i, j in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            ny = cy + i
            nx = cx + j
            if 0 <= ny < h and 0 <= nx < w:
                if grid[ny][nx] == '#':
                    if min_cost[cy][cx] + x < min_cost[ny][nx]:
                        min_cost[ny][nx] = min_cost[cy][cx] + x
                        que += [(ny, nx)]
                else:
                    if min_cost[cy][cx] + 1 < min_cost[ny][nx]:
                        min_cost[ny][nx] = min_cost[cy][cx] + 1
                        que += [(ny, nx)]
    return t >= min_cost[gy][gx]


ok = 0
ng = t
while ng > ok + 1:
    mid = (ng + ok) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid


print(ok)
ApacheのeventMPMとphp-fpmで運用

# 環境

CentOS Linux release 7.6.1810 (Core)

# 参考サイト

https://www.rem-system.com/httpd-php-fpm/

# 手順

サイトを見ながらやればおｋでした。

## ApacheのeventMPM

```
cd /etc/httpd/conf.modules.d/
cp -p 00-mpm.conf 00-mpm.conf.20190304.bak
vi 00-mpm.conf

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
をコメントアウトして
LoadModule mpm_event_module modules/mod_mpm_event.so
のコメントを外す

systemctl restart httpd
httpd -M | grep mpm
 mpm_event_module (shared)
```

## php-fpm

```
yum -y install --enablerepo=remi,remi-php73 php-fpm
cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.20190304.bak
vi /etc/php-fpm.d/www.conf

適宜変更（運用してみて調整するっぽい）

systemctl start php-fpm
systemctl enable php-fpm
```

## PHPをCGIで動かす

```
vi /etc/httpd/conf/httpd.conf

最後に追記
# event MPM setting
<IfModule mpm_event_module>
        StartServers             2
        MinSpareThreads         25
        MaxSpareThreads         50
        ThreadsPerChild         50
        MaxRequestWorkers       50
        MaxConnectionsPerChild   0
       <FilesMatch \.php$>
                SetHandler "proxy:fcgi://127.0.0.1:9000"
       </FilesMatch>
</IfModule>

モジュール版PHPの設定を読み込まないようにする
mv /etc/httpd/conf.modules.d/15-php.conf /etc/httpd/conf.modules.d/15-php.conf.20190304.bak

systemctl restart httpd
```

# 気になるところ

- 各サイトのエラーログが別々のファイルにできない？

バーチャルホストの設定にて

```
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /home/example/public_html
    ErrorLog /home/example/logs/error_log
    CustomLog /home/example/logs/access_log common
    <Directory /home/example/public_html>
        AllowOverride All
        Options All -Indexes
        Order allow,deny
        Allow from all
        SetEnv PHP_VALUE "error_log = /home/example/logs/error_log"
    </Directory>
</VirtualHost>
```
とすると、設定を上書きできるので、エラーログを個別に設定可能

- 運用してみて調整が必要
【学習ノート】AWS SAA取得に向けて(ELB)

# ELB

## ELBの種類

ELBには3種類のバランシングタイプがある

1. CLB(Classic Load Balancer)
    - L4/L7レイヤーで負荷分散を行う 
    - 初期に提供された機能であり複雑な設定はできない
2. ALB(Application Load Balancer)
    - L7レイヤで負荷分散を行う
    - CLBより後発であり、機能も豊富に提供されている
        - WebSocketに対応、HTTPS/2に対応、***URLパターンで振り分けるパスベースルーティングを提供***
3. NLB(Network Load Balancer)
    - L4レイヤーで負荷分散を行う
    - HTTP/HTTPS以外のプロトコル通信を負荷分散したい時に利用する
    - NLB自体が固定IPアドレスを持つ

## ELBの特徴

ELBを利用するメリット

- ELB自体のスケーリングが可能
    - EC2上にLBを導入する場合、そのEC2インスタンスが単一障害点にならないよう設計する必要がある
    - ELBを利用していれば、負荷に応じて自動でスケーリングする設計になっている
        - 急激な負担増(スパイク)が予想できる場合も、ELBのプレウォーミング申請で対応が可能
- ヘルスチェックが利用可能
    - 設定された間隔でEC2インスタンスの状態をチェックする
        - 設定項目：対象ファイル、ヘルスチェックの間隔、何回連続でリクエストが失敗したらインスタンスを切り離すか

# Auto Scaling

下記のような設定を事前に行っておくことで、システムの利用状況に応じて自動的にELBに紐づくインスタンスの台数を増減させる
適切な設定を行うと自動で、繁忙期はインスタンスを増やし、閑散期はインスタンスを減少するような動作が可能

- 設定項目
    - 最小のインスタンス数
    - 最大のインスタンス数
    - インスタンスを増やす条件と増やす数
    - インスタンスを減らす条件と減らす数
        - どのインスタンスから削除するか

#　ELBとAuto Scalingを利用する際の設計ポイント

1. サーバをステートレスに設計する
    2. インスタンス上にファイルを保持すると、別インスタンスから参照できなくなる可能性がある
3. AZをまたがってインスタンスを配置するよう設計する
    4. AZ全体の障害が発生することもあるのでマルチAZ構成にして単一障害点をなくす

参考図書:AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト[アソシエイト]