OmniAICreator/Qiita-1.07M huggingface dataset:
Fargateのスケジュールされたタスクで常に最新のタスク定義を使用する方法

## 結論
cloud watch eventsのAPIを叩いて直接実行したいコマンドを登録するしかない模様
下記のような感じでタスクを登録する

```rb
        cron_job_addition_command = <<"CRON_JOB_ADDITION_COMMAND"
        aws events put-rule --name "#{name}" --schedule-expression "#{schedule_expression}" --description "Don't edit directly."
        aws events put-targets \
          --rule #{name} \
          --targets='[
                {
                    "Id": "#{name}",
                    "Arn": "arn:aws:ecs:ap-northeast-1:#{account_id}:cluster/#{cluster_name}",
                    "RoleArn": "arn:aws:iam::#{account_id}:role/#{role_name}",
                    "Input": "{\\"containerOverrides\\":[{\\"name\\":\\"app\\",\\"command\\":[#{cmd}]}]}",
                    "EcsParameters": {
                        "TaskDefinitionArn": "arn:aws:ecs:ap-northeast-1:#{account_id}:task-definition/#{task_id}",
                        "TaskCount": 1,
                        "LaunchType": "FARGATE",
                        "NetworkConfiguration": {
                            "awsvpcConfiguration": {
                                "Subnets": [
                                    "subnet-hogehoge",
                                    "subnet-fugafuga"
                                ],
                                "SecurityGroups": [
                                    "sg-hogehoge"
                                ],
                                "AssignPublicIp": "DISABLED"
                            }
                        },
                        "PlatformVersion": "LATEST"
                    }
                }
            ]'
CRON_JOB_ADDITION_COMMAND
```

## 参考文献
* [Add container overrides to put-targets for ECS tasks](https://github.com/aws/aws-cli/issues/2760)
今年の言語はRust その７


# 今年の言語はRust その７

Rustを学びます

勉強ページは日本語ドキュメント

[プログラミング言語Rust](https://doc.rust-jp.rs/)

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル
https://doc.rust-lang.org/book/



## 5. 構造体

### 5.1 構造体を定義し、インスタンス化する

```rust
fn main() {
    
 
    
    let mut user1 = User{
        email: String::from("someone@exmaple.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    }; // <- 文なので;を忘れずに
    
    user1.email = String::from("anothermail@example.com");
    
    let user2 = build_user(String::from("some@mail.com"), String::from("yourname123"));
}


struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn build_user(email: String, username: String) -> User {
    
    let user = User{
        username: username,
        email: email,
        active: true,
        sign_in_count: 1,
    };
    
    user
}


```

変数名が同じなら省略できる！！

```rust

fn build_user(email: String, username: String) -> User {
    
    let user = User{
        username,
        email,
        active: true,
        sign_in_count: 1,
    };
    
    user
}
```

残りをすべてコピーなんて便利!!!



```rust
fn main() {
    
    let mut user1 = User{
        email: String::from("someone@exmaple.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    }; // <- 文なので;を忘れずに
    
    user1.email = String::from("anothermail@example.com"); // mutabuleなら可変
    
    let user2 = build_user(String::from("some@mail.com"), String::from("yourname123"));
  
    // 残りのフィールドをコピー
    let user3 = User{
        email: String::from("another123@mail.com"),
        username: String::from("anotherusername567"),
        ..user1
    };
}

```

#### タプル構造体

```rust
fn main() {
    
    // タプル構造体
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);
    
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
    
    let r = black.0;
    let g = black.1;
    let b = black.2;

	// 一切フィールドのない構造体
    struct Blank ();
    
}
```

#### ライフタイムの予見

```rust
struct User {
    username: &str,
    email: &str,
    sign_in_count: u64,
    active: bool,
}

fn main() {
    let user1 = User {
        email: "someone@example.com",
        username: "someusername123",
        active: true,
        sign_in_count: 1,
    };
}
```

上の構造体はライフタイムに関したエラーが起きる
これは、構造体にスライスを保持させるためには、ライフタイムという機能を使わないといけないから。


構造体のインスタンスにはデータを保持させておきたいので、前の例では「意図的にString型を使用していた」



理解した！

次回！


イエス！
scale_color_manualで指定した色が欠損値でズレる場合の対処

ggplot2は、通常自動的に色を決めてプロットするが、
scale_color_manualを使えば、ユーザーが指定した通りの色でプロットすることができる。
例えば、以下のような5色でプロットしたいとする。

```{R}
# パッケージロード
library("ggplot2")

# 色指定関数
ggdefault_cols <- function(n){
    hcl(h=seq(15, 375-360/n, length=n)%%360, c=100, l=65)
}

# 独自に色を指定
# 赤、黄色、緑、青、紫になる
mycolor <- ggdefault_cols(5)
```

この色を使って、以下のような５つの手法のスコアの分布を、ビースウォームでプロットしてみる。

```{R}
# テストデータ1（欠損値なし）
input1 = rbind(
	data.frame(Method="A", Score=runif(10)),
	data.frame(Method="B", Score=runif(10)),
	data.frame(Method="C", Score=runif(10)),
	data.frame(Method="E", Score=runif(10)),
	data.frame(Method="F", Score=runif(10))
)

# テストデータ1をまずプロット
g1 <- ggplot(input1, aes(x=Method, y=Score, color=Method))
g1 <- g1 + geom_quasirandom(dodge.width = 0.7, cex=4)
g1 <- g1 + ylim(0, ymax)
g1 <- g1 + ylab("") + xlab("")
g1 <- g1 + theme(text = element_text(size=50))
g1 <- g1 + theme(legend.position = 'none') + scale_color_manual(values = mycolor)
# 赤、黄色、緑、青、紫で出力される
g1
```

![スクリーンショット 2019-04-13 14.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/929a5b6d-cffd-6910-7194-dc1ecf8619a1.png)


次に、似たようなデータだが、Cのスコアが何らかの理由により、得られなかったデータで同様にプロットする。

```{R}
# テストデータ2（Cがまるまる欠損している）
input2 = rbind(
	data.frame(Method="A", Score=runif(10)),
	data.frame(Method="B", Score=runif(10)),
	data.frame(Method="C", Score=rep(NA, 10)),
	data.frame(Method="E", Score=runif(10)),
	data.frame(Method="F", Score=runif(10))
)

g2 <- ggplot(input2, aes(x=Method, y=Score, color=Method))
g2 <- g2 + geom_quasirandom(dodge.width = 0.7, cex=4)
g2 <- g2 + ylim(0, ymax)
g2 <- g2 + ylab("") + xlab("")
g2 <- g2 + theme(text = element_text(size=50))
g2 <- g2 + theme(legend.position = 'none') + scale_color_manual(values = mycolor)
g2
```

![スクリーンショット 2019-04-13 14.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/742858e7-fa86-ec56-9739-1eb1fc776247.png)

この場合、Cが欠損していることにより、Cに対応する緑はCでは使われず、D、Eに緑、青が指定され最後の紫は使われない。
つまり、欠損したC以降の色が全てずれてしまう。

これは、scale_color_manualに**drop=FALSE**というオプションを指定すると解決される。

```{R}
g2_2 <- ggplot(input2, aes(x=Method, y=Score, color=Method))
g2_2 <- g2_2 + geom_quasirandom(dodge.width = 0.7, cex=4)
g2_2 <- g2_2 + ylim(0, ymax)
g2_2 <- g2_2 + ylab("") + xlab("")
g2_2 <- g2_2 + theme(text = element_text(size=50))
g2_2 <- g2_2 + theme(legend.position = 'none') + scale_color_manual(values = mycolor, drop=FALSE)
g2_2
```

![スクリーンショット 2019-04-13 14.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/9b6d493e-b65b-22fe-b44e-098caaa76461.png)

# 参考
- https://ggplot2.tidyverse.org/reference/scale_manual.html
- https://qiita.com/hoxo_b/items/c569da6dbf568032e04a
HTML要素のデータの保存方法

#Abstract
HTMLドキュメントやJavaScript上で作成したHTML要素のデータ（各属性値など）をファイルやデータベースに保存する方法について覚書を記す。
#方法
###・WeakMapを使う
WeakMapとは、オブジェクト作成用のオブジェクトである。
普通のオブジェクトはkeyに文字列しか使えないのに対し、WeakMapで作ったオブジェクトには**オブジェクトをkeyに使える。**

あるHTML要素－例えばdiv要素－のデータを保存するにはkeyに以下のようなオブジェクトを作って指定すればよい：

**まず、WeakMapでオブジェクトmyDivを作成する
→keyに「DOMのdiv要素オブジェクト」を設定する。
→**
ABC - 117 - A&B&C

#AtCoder ABC 117 A&B&C
[AtCoder - 117](https://atcoder.jp/contests/abc117)

[解説放送](https://www.youtube.com/watch?v=OOtz0Lx_mRk&t=1752s)

#A問題

 - BigDecimalで四捨五入

```java
	private static void solveA() {

		try (Scanner scanner = new Scanner(System.in)) {
			String numT = "";
			String numX = "";

			numT = scanner.next();
			numX = scanner.next();

			BigDecimal result = new BigDecimal(numT).divide(
					new BigDecimal(numX), 6, RoundingMode.HALF_UP);
			System.out.println(result.floatValue());

		}
	}
```

#B問題

 - 定理 : 一番長い辺が他の N−1 辺の長さの合計よりも真に短い場合に限り、条件を満たす N 角形が描ける。

 - 定理を満たすかどうかは
    - 入力値をソートする
    - ソートした入力値を一番長い辺（ソート後に一番最後となった値）を除いて合算
    - 合算値とソート後の最後の値を比較

```java
	private static void solveB() {

		try (Scanner scanner = new Scanner(System.in)) {
			int numN = 0;
			numN = scanner.nextInt();
			int[] wkArray = new int[numN];
			for (int i = 0; i < numN; i++) {
				wkArray[i] = scanner.nextInt();
			}

			Arrays.sort(wkArray);

			int max = 0;
			int others = 0;
			for (int i = numN - 1; i >= 0; i--) {
				if (i == numN - 1) {
					max = wkArray[i];
				} else {
					others += wkArray[i];
				}

			}
			System.out.println(max < others ? "Yes" : "No");

		}
	}
```

#C問題

- 入力値
    - $3, 7$
    - $-10, -3, 0, 9, -100, 2, 17$

- 駒を置くべき場所
    - 座標間の移動距離が大きいところ
        - 移動距離が大きい=移動せずに済ませたい距離
    - 座標間の移動距離を算出しソートすれば、行かずに駒を置くだけで済ました居場所が判別できる
        - コード中にインラインでコメントを記述

- サンプルについて
    - 3を置いた箇所が-10なら9まで移動、9に置いたら-10まで移動

|||||||||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|座標|-100||-10||-3||0||2||9||17|
|座標間の差分||90||7||3||2||7||8||
|駒位置(3はどちらでも可)|↑1||↑3||||||||↑3||↑2|

```java
	private static void solveC2() {

		try (Scanner scanner = new Scanner(System.in)) {
			int numN = 0;
			int numM = 0;
			numN = scanner.nextInt();
			numM = scanner.nextInt();
			if (numM == 1 && numN >= numM) {
				System.out.println(0);
				return;
			}
			/*
			 * 各地点を取り込む
			 */
			int[] distArray = new int[numM];
			for (int i = 0; i < numM; i++) {
				distArray[i] = scanner.nextInt();
			}
			/*
			 * 地点を座標順に並び替える
			 */
			Arrays.sort(distArray);
			/*
			 * 座標間の距離を取得
			 */
			int[] sabunArray = new int[distArray.length - 1];
			for (int i = 0; i < sabunArray.length; i++) {
				sabunArray[i] = distArray[i + 1] - distArray[i];
			}

			/*
			 * 座標間の距離を並び替える
			 */
			Arrays.sort(sabunArray);

			int result = 0;
			/*
			 * 移動量が大きいところには駒を置いてしまうので
			 * 小さいところから合算すると移動しないといけない量を算出できる
			 */
			for (int i = 0; i < numM - numN; i++) {
				result += sabunArray[i];
			}

			System.out.println(result);

		}
	}

```
Cognitoのプールごとの役割を5分で確認する

## ユーザプール
* ユーザ情報の保持とそのユーザの認証まで。
* 各種トークン（ID、アクセス、更新）の払い出し。
* API Gateway側はオーソライザーを設定することで、ユーザプールでの認証が通っているかどうかによるアクセス許可・拒否が可能。
* AWSリソースを操作したい場合、IDトークンから一時クレデンシャルを発行してもらう必要あり。  
  ※IDプールにIDトークンを渡すことで、"認証されたユーザ" として扱われる

## ID プール (フェデレーティッドアイデンティティ)
* ユーザに対してCognitoID（`GetId`で取得しレスポンスの`IdentityID`=CognitoID）を払い出す 
  * プロバイダ毎に認証済みの場合、`GetId`の`Logins`にプロバイダと識別情報を指定すれことが可能  
    ※プロバイダ＝`Logins`の中のkey部分、識別情報＝`Logins`の中のvalue部分（大体、IDトークン）  
    ※この時、ユーザプールはあくまでプロバイダの1つである（対象プロバイダは [ここ](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html) の`Logins`参照）  
    ※対象プロバイダは独自認証を対象にすることが可能なので実質何でもあり
* AWSリソースへの権限（ロール）を付与する。※一時クレデンシャルが貰える
* ロールは、認証されたユーザ、認証されていないユーザで別々に付与できる。
* 認証プロバイダとして、ユーザプールを指定することが可能。※ユーザプール以外も指定可能
* ユーザプールと密接な関係があるように見えてそういうわけではなく、IDプールからするとユーザプールもIDプールにIDを貰いに来たプロバイダーの1つに過ぎない
* 独自認証に対して、Coginito発のIDトークンを発行できる（`GetOpenIdTokenForDeveloperIdentity`）
pythonでAtCoder -ABC009-

# 対象
- AtCoder初心者（緑よりもランクが下の人、ABCのCD問題が解けない人）
- pythonがそれなりにかける人
- 数学やプログラミングに対する深い理解を持っていない人
    - Ex) DP, 深さ優先探索, メモ化再帰の実装ができない

# 動機
AtCoderは全ての問題に対して解説が存在しますが
ざっくり説明を読んでわかった気になっても独力で実装ができないといった経験が多くありました。
参考のために他人の提出を見ても解説と綺麗にリンクした解答が簡単には見つからず
理解を実装に落とすことに苦労しました。

そこで、公式の解答とある程度リンクした実装を見ながら
アルゴリズムや数学的な理解とソースコードを紐付けたいと思ったことが本記事を寄稿した動機です。

いるかわかりませんが同様の苦労をしている人のためにも何らかの参考になればと思い
私の回答とそれに対する簡単なコメントを付与したコードを記載します。

# 実行環境
- python3

## 実装
AB → 何も見ずに実装
CD → 解説を見て実装

# A
```python:A.py
import math
print(math.ceil(int(input()) / 2))
```
# B
```python:B.py
N = int(input())
A = list(set([int(input()) for _ in range(N)]))
A.sort()
print(A[-2])
```

# C
```python:C.py
from collections import Counter

N, K = map(int, input().split(' '))
S = input()
R = sorted(S)
T = ''
diff = 0

for i in range(N):
    # 各文字の出現回数をカウント
    counter = Counter(S[:i+1]) - Counter(T)
    for r in R:
        # 確定済み文字のdiff + みている文字のdiff
        diff1 = diff + (r != S[i])
        # 確定していない文字のdiff
        diff2 = sum(counter.values()) - (counter[r] > 0)
        if diff1 + diff2 <= K:
            T += r
            R.remove(r)
            diff = diff1
            break
print(T)
```

# D
```python:D.py
def matrix_pow(a, b):
    ret = [[0] * len(b[0]) for _ in range(len(b))]
    for x in range(len(b)):
        for y in range(len(b[0])):
            for z in range(len(b)):
                ret[x][y] ^= a[x][z] & b[z][y]
    return ret


K, M = map(int, input().split(' '))
A = list(map(int, input().split(' ')))
C = list(map(int, input().split(' ')))

if K >= M:
    print(A[M-1])
    exit()


# 漸化式計算用の行列を作成
A.reverse()
matrix = [[0] * len(C) for _ in range(len(C) - 1)]
for i in range(len(C) - 1):
    for j in range(len(C)):
        matrix[i][j] = (1 << 32) - 1 if i == j else 0
matrix.insert(0, C)

# 行列の累乗計算結果をスタック
matrix_list = [[[0] * len(C) for _ in range(len(C))] for _ in range(len(format(M-K, 'b')))]
for i in range(len(matrix_list)):
    mat = matrix if i == 0 else matrix_pow(matrix_list[i-1], matrix_list[i-1])
    for j in range(len(matrix_list[0])):
        for k in range(len(matrix_list[0][0])):
            matrix_list[i][j][k] = mat[j][k]

# フラグが立っている部分で累乗計算を適用
ans = [[a] for a in A]
for m, bit in zip(matrix_list, reversed(format(M-K, 'b'))):
    ans = matrix_pow(m, ans) if bit == '1' else ans
print(ans[0][0])
```
解説を見て実装をしましたが、TLEになりひたすら苦しめられました。
最終的にPypyなら通る可能性があるとの記事を発見したため、Pypyで提出したら通りました。

## 終わりに
D問題をpython3でACしている人が10人もおらず驚きました。(Pypyでも1ページ程度)
あまり過去問解いていく人はいないのでしょうか。。

以上です。
Cognitoのユーザプールでの認証するところまでを最速でやる

## 概要
cognitoのユーザプール認証をやる。

* AWSコンソールでCognitoユーザプールへ登録したユーザを認証する。
* Amplify使うと色々速い気がするけど、一旦、AWSの公式にに記載されている方法で。。
* ※実質、Githubに書かれてる手順をなぞるだけになるけど。。

## 手順

### Amazon Cognito Identity SDK for JavaScript をローカルに落とす

どこかのCDNに上がってない？ので、npmで自分でinstallする。
[※元ネタ＠SDK公式]
(https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js#using-npm-and-webpack)

#### package.jsonを用意

```json-doc:package.json
{
  "private": true
}
```

#### npm install する

```bash
npm install --save-dev webpack json-loader
npm install --save amazon-cognito-identity-js
```

`node_modules\amazon-cognito-identity-js\dist` の中の `amazon-cognito-identity.js` を後で使う。

### ユーザプールの認証をするためのjsの用意

[公式](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-javascript-examples.html)の **ユーザの認証** 項に記載されているjavascriptをjsファイルにコピペする。
ここでは `test.js` というファイル名で保存することにする。

下記注意。

* username, password をユーザプールにユーザを登録した時のものに書き換える。
* UserPoolId, ClientId も書き換える。

* UserPoolIdに入力する値はユーザプールの管理画面の↓の赤枠部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299475/7a4fd4d4-7ca2-b1b2-436b-b359dfa860b6.png)

* ClientIdに入力する値は、画面下の方にある **アプリクライアント** の右の方にあるエンピツボタンを押し、表示される画面の中の **アプリクライアント ID** の値。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299475/9995acf3-2376-cb59-5924-547538601856.png)

### 認証を実行する

適当なhtmlを作成し、javascriptとして、`amazon-cognito-identity.js` と `test.js` をhtml内で読み込む。

```html
<script src="amazon-cognito-identity.js"></script>
<script src="test.js"></script>
```

htmlをブラウザで表示し、公式からコピペしたjs内の `authenticateUser()` の `onSuccess()` の `result` の内の `accessToken`, `IdToken`, `refreshToken` に値が入っていれば成功。

### 認証できない時

↓のようなエラーが出る場合

```
TypeError: callback.newPasswordRequired is not a function
```

コンソールからユーザを登録した場合、初回認証時に強制的にパスワードを変える必要がある。
ので、`test.js` の `authenticateUser` に↓のメソッドを追加する。

※パスワードが `password` になるのでそこは任意で。
※追加してもエラーが出る場合、リクエストへのレスポンスの内容を見ると何が悪いか書いてあるのでそれ見ながら修正する。
※[公式の元ネタ](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/using-amazon-cognito-identity-user-pools-javascript-example-authenticating-admin-created-user.html)

```javascript
newPasswordRequired: function (userAttributes, requiredAttributes) {
    cognitoUser.completeNewPasswordChallenge("password", {}, this)
}
```

## IDプールを使って一時クレデンシャルを取得する
[こっち](https://qiita.com/k_hoso/items/d2bbb2340a56a0f4d365)
[WIP] nginx とは？ ~ 初心者が調べた時の記事まとめ ~

# 概要

nginx についてわからなかったので、いろいろ調べた時のまとめ

# 記事一覧

## nginxの概要

- [nginx - Wikipedia](https://ja.wikipedia.org/wiki/Nginx)

## 設定系

- [nginxについてまとめ(設定編)](https://qiita.com/morrr/items/7c97f0d2e46f7a8ec967)
- [Nginxのrewrite機能でURLの書き換えをしてみる](https://komeiy.hatenablog.com/entry/2014/12/10/231714)
- [nginxについてまとめ(導入編)](https://qiita.com/morrr/items/929e9cb35914a7f3a652)
- [@IT - これから始める人のためのNginx](http://www.atmarkit.co.jp/ait/articles/1406/17/news013.html)

### Dockerに関わる系の設定

- [周回遅れのDocker 2: Docker による PHP サーバ](https://qiita.com/kumatch/items/7ea3bd4f87237980a399)


## リバーシプロキシ、冗長化

- [リバースプロキシって何？触りだけ学んだサーバー/インフラ入門](https://qiita.com/growsic/items/fead30272a5fa374ac7b)
- [Nginxによるリバースプロキシの設定方法](https://qiita.com/schwarz471/items/9b44adfbec006eab60b0)

## Dockerコンテナの際の設定

## Apache との比較

- [Qiita - Apacheとnginxどちらを採用すべきかメリット・デメリット比較](http://qiita.com/pink/items/7709218310b5cf11eabe)
- [Qiita - apacheとnginxの比較表とベンチマーク](http://qiita.com/sion_cojp/items/edb20a6b87f10e186c23)
- [金沢ではたらく新米エンジニアの日記 nginxってよく聞くけどApacheとどう違うかよくわからないので調べてみる。](http://hayatan.hatenablog.com/entry/2015/01/28/001658)
今年の言語はRust その６


# 今年の言語はRust その６

Rustを学びます

勉強ページは日本語ドキュメント

[プログラミング言語Rust](https://doc.rust-jp.rs/)

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル
https://doc.rust-lang.org/book/



## 4. 所有権を理解する

### 4.3 スライス

```rust
fn main(){
    
    let s = String::from("hello world");
    
    let hello = &s[0..5];
    let world = &s[6..11];
    
    let hello = &s[..5];
    let world = &s[6..s.len()];

    let hello_world = &s[..s.len()];
    
}

```


スライスを返す関数

```rust
fn main(){
    
    let s = String::from("hello world");
    
    let w = first_word(&s);
    
    println!("'{}': first word = {}", s,  w);

    
}


fn first_word(s: &String) -> &str{
    let bytes = s.as_bytes();
    
    for (i, &item) in bytes.iter().enumerate(){
        if item ==  b' '{
            return &s[0..i];
        }
    }
    
    &s[..]
}
```


実用？で考えてみる
関数の引数はスライス参照にしておけばOK!!
これで、文字列リテラルも文字列も受け取れる!

```rust
fn main() {
    
    
    // 「String型」の場合
    let my_string = String::from("hello world");
    
    let word = first_word(&my_string[..]); // <- スライスして渡す
    
    // 「文字列リテラル」の場合
    let my_string_literal = "hello world";
    
    let word = first_word(&my_string_literal[..]); // <- スライスして渡す
    
    let word = first_word(my_string_literal); // スライスなのでそのまま渡してoK
    
    
}

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

```

配列もスライスできる!

```rust
fn main() {
    
    let a = [1, 2, 3, 4, 5];
    
    let slice = &a[1..4];
    
    
}

```

スライスはPython等では標準実装されているので理解できた。
文字列と文字列リテラルの違いと関数の受け方はRust的。

理解した！

次回！


イエス！
jupyterでマークダウン記法を使ったときに文章と混ぜたい

jupyterでMarkdown記法を書くときにハマったので忘備録

＄{数式}＄で囲むだけで数式が展開されて文字と一緒に書き込める
＄＄{数式}＄＄だと改行されて中央に表示される。
データサイエンスのJulia言語

データサイエンスに分析するツール・言語として、R、Pythonはとても有名ですが、
2012年OpenSource化されたJuliaも選択肢になります。

Julia：https://julialang.org/

ページに書いてあるようにいつくかの特徴があります。
速度早い、使いやすいなどなど

日本語などのUnicodeが使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/5947c8fa-6808-40e7-91d0-78ccf315d7eb.png)

πの入力は、「\pi」を入力し、tabを押すと、πになります。

詳しい説明は、下記にページに記載があります。
https://docs.julialang.org/en/v1/manual/unicode-input/

型もほかの言語にあるものは基本持っています。
下記はtypemin,typemax関数でIntなどの最小値、最大値を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/ec50afd2-7778-4fc1-558d-9cb99eca1478.png)


ただし、下記のような計算式はわかりにくいかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/e8442a33-955c-3688-d083-d8b0706be7da.png)

数字と変数名を連結する場合は、掛け算となります。
2y^3y で（）を使うと理解しやすいです。


2 * y^(3 * y) = 2 * 3 ^ 9 = 2 * 19683 = 39366


ランダム配列の例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/cd0b1f78-b6ae-fabb-7e7e-bb6595f4be65.png)

今後の業務に利用できるかなと期待します。

以上
Firestoreメモ

## データモデル
* ドキュメントを削除してもサブコレクションは削除されない

>サブコレクションが関連付けられているドキュメントを削除しても、そのサブコレクションは削除されません。その後もサブコレクションには、リファレンスによるアクセスが可能です。


## インデックス
* 複合インデックスは自動で作成されない

>Cloud Firestore では、可能なフィールドの組み合わせの数が多くなるため、単一フィールド インデックスの場合とは異なり、複合インデックスの自動作成は行いません。

* [インデックスのベストプラクティス](https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja#indexing_best_practices)があるので目を通しておいた方が良い


## クエリ
* 等価演算子と範囲比較を組み合わせる場合はカスタムインデックスを作成する必要がある

> 等価演算子（==）と範囲比較（<、<=、>、>=）を組み合わせる場合は、必ずカスタム インデックスを作成してください。


* whereに続くorderByに異なるフィールドを使用することはできない

> 無効: 範囲フィルタと最初の orderBy を異なるフィールドに使用する

* [クエリの制限事項](https://firebase.google.com/docs/firestore/query-data/queries?hl=ja#query_limitations)に目を通しておいた方が良い

## ページネーション
* [クエリカーソル](https://firebase.google.com/docs/firestore/query-data/query-cursors?hl=ja)を使う

## 検索
* [全文検索](https://firebase.google.com/docs/firestore/solutions/search?hl=ja)を参考にする

## セキュリティ
* フロントエンドからのアクセスを行う場合には[セキュリティルール](https://firebase.google.com/docs/firestore/security/overview?hl=ja)を設定する

## 参考文献
* [Cloud Firestore データモデル] (https://firebase.google.com/docs/firestore/data-model?hl=ja)
* [Cloud Firestore のインデックスの種類] (https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja)
* [複合クエリ](https://firebase.google.com/docs/firestore/query-data/queries?hl=ja#compound_queries)
* [データの並べ替えと制限](https://firebase.google.com/docs/firestore/query-data/order-limit-data?hl=ja)
ABC - 116 - A&B&C

#AtCoder ABC 116 A&B&C
[AtCoder - 116](https://atcoder.jp/contests/abc116)

#A問題

 - $底辺 \times 高さ \div 2$
 - CAは使わない

```java
	private static void solveA() {
		try (Scanner scanner = new Scanner(System.in)) {
			int lineAB = 0;
			int lineBC = 0;
			int lineCA = 0;

			lineAB = scanner.nextInt();
			lineBC = scanner.nextInt();
			lineCA = scanner.nextInt();

			int result = lineAB * lineBC / 2;
			System.out.println(result);

		}
	}

```

#B問題

 -  $f(n) $
    -  n が偶数なら $f(n)=n/2$
    -  n が奇数なら $f(n)=3n+1$
 -  $i=1 のとき a_i=s、i>1 のとき a_i=f(a_{i−1}) $

 - $a_1=8$
 - $a_2=f(a_{2-1})=f(a_1)=f(8)$
 - $a_3=f(a_{3-1})=f(a_2)=f(4)$

```java
	private static void solveB() {

		try (Scanner scanner = new Scanner(System.in)) {

			int numS = 0;
			numS = scanner.nextInt();

			int wkResult = 0;

			List<Integer> wkList = new ArrayList<Integer>();
			int cnt = 0;
			while (true) {
				if (cnt != 0) {
					/*
					 * isResultNum()でf(n)を計算する
					 */
					wkResult = isResultNum(wkList.get(cnt - 1));
					/*
					 * am=an(m>n)
					 * 現時点のcntの値より前に同じwkResultが出てきているのかをチェック
					 * 既におなじwkResultが既出ならcnt++してbreak（indexが0スタートなので1スタートに合わせる）
					 */
					if (wkList.contains(wkResult)) {
						cnt++;
						break;
					}
					wkList.add(wkResult);
				} else {
					wkResult = numS;
					wkList.add(numS);
				}
				cnt++;
			}
			System.out.println(cnt);
		}
	}

	private static int isResultNum(int numS) {
		if (numS % 2 == 0) {
			return numS / 2;
		} else {
			return 3 * numS + 1;
		}
	}
```

#C問題

 **方針**

 - 「0からスタートして入力値に合わせる」
    
 よりは

 - 「入力値を0にしていくためにどうすればよいのか？」の方が考えやすいので入力値を0にする操作回数を求める

```java
	private static void solveC() {

		try (Scanner scanner = new Scanner(System.in)) {
			int numN = 0;
			numN = scanner.nextInt();
			int[] arrayH = new int[numN];
			for (int i = 0; i < arrayH.length; i++) {
				arrayH[i] = scanner.nextInt();
			}

			int cnt = 0;
			/*
			 * 入力値がすべて0になるまで繰り返す
			 */
			while (isNotExit(arrayH)) {
				cnt++;
				boolean notZeroCnt = false;
				/*
				 * 水やり作業
				 */
				for (int i = 0; i < arrayH.length; i++) {
					/*
					 * 0に達したものはそれ以上水をやれないので、
					 * 0を見つけたら水やりの切れ目
					 */
					if (arrayH[i] != 0) {
						arrayH[i]--;
						notZeroCnt = true;
					} else {
						/*
						 * 0の箇所があるので水やりの切れ目なのだが、
						 * まだ1度も水を挙げていない場合
						 * |0|0|1|0|
						 * ↑みたいな場合、1,2個目は無視しないといけない
						 * notZeroCntはそのために利用している。
						 * もっとうまいやり方。。。
						 */
						if (notZeroCnt) {
							break;
						}
					}

				}
			}
			System.out.println(cnt);
		}
	}

	/*
	 * 高さ0より大きい入力値が存在するのかを確認する
	 */
	private static boolean isNotExit(int[] arrayH) {
		for (int i = 0; i < arrayH.length; i++) {
			if (arrayH[i] != 0) {
				return true;
			}
		}
		return false;
	}
```
Appleの配送修理で修理後の追跡伝票番号を確認する方法

Apple 製品を配送修理して、修理後の発送完了メールには「配達伝票番号：」とありますが、番号が書かれていません。メール内の URL を開いても番号はありません。
<img width="375" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155587/988baf44-d9f5-5d59-66ce-4bf03c8645a6.jpeg">

↓

**Apple ID でログイン**することで詳細情報を見られるようになります。
https://mysupport.apple.com/?selectedLocale=ja_JP
<img width="375" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155587/791099b3-fdda-7cda-5c27-ccaeaf4514b8.jpeg">
プログラミング学習への心得

#目次
+ 【超重要】環境を整える
+ まず、言語の概要を知ること
+ とにかくコードを書くこと
+ エラーを経験しまくること
+ まずは一つの言語に集中すること
+ 全てを覚えることは不可能

##【超重要】環境を整える
何か目標を達成するには、一番大事なのが「やるしかない環境」を作ることです。
プログラミングを本気でやるなら、
Macbook AirかProを買う。プログラミングスクールに通う。
をおすすめします。金額は高額になりますが、これを道具や環境への投資と思い元を取る気持ちでやると非常に頑張れます。

あのヒカキンさんも動画編集のパソコンには売れていないときからかなり投資していたそうです。

今は、とても安くで学習できたりするのですが、月数百円かけるよりも費用対効果はいいと思います。

ちなみに私は、筋トレがあまり好きではなかったのですが、パーソナルジムに高額な費用を投資したことで、スイッチが入り「食事」「運動」の改善ができて健康でとても毎日が楽しいです。
##まず、言語の概要を知ること
一概にプログラミングと言っても、何ができるのかを知った上で学習を進めるというのは非常に大切なことです。
例えば、
サッカー選手になりたいのに「バットの素振りの練習」を始める人はいないですよね。
国内旅行に行きたいのに「パスポートを取る」人はいないですよね。

WEBデザイナーになりたい → HTML CSS Javascript
WEBエンジニアになりたい → PHP Laravel か Ruby on Rails か Go
アップル系スマホアプリエンジニアになりたい → Swift
機械学習エンジニアになりたい → Python

HTML CSSは、どの言語の学習を始める上でも必要な知識になりますので、まずはここから始めるのが良いでしょう。
2019年4月現在では、このような言語になりますが流行り廃りがありますので、最新の情報を参考にしていきましょう。
##とにかくコードを書くこと
プログラミング学習は、スポーツやゲームと同じようにとにかくやること以外には、力はつきません。
スポーツの本やゲームの攻略本を読んだだけではうまくなりませんよね？
やりたいことが決まればとにかくその言語で、ポートフォリオを作ったりすることが上達への道となります。
##エラーを経験しまくる
まず、エラーはでて当たり前だと考えます。例えば、サッカーではシュートを打って100%決められる人はいないし、ロールプレイングゲームで一度も死なずに全てのゲームをクリアしてしまった人はいないと思います。
より多くのシュートが決まるように練習したり、ゲームでは同じステージでレベルをあげて強くなっていく、そんなイメージでやればエラーと出くわすのが楽しくなってきます。
##まずは一つの言語に集中する
言語はたくさんあります。ただ、なりたい方向を決めれば学習しなければいけない言語は絞られます。一つの言語とフレームワークで、ものづくりができるようになれば他の言語でも応用できるようになります。

私は、学習を始めた頃いろんな言語に手を出しまくったことがあります。その結果、、、一度やったことはほとんど忘れているなんてこともありますので、一つの言語と一つのフレームワークをまずは極めることが、重要です。
goplsでnet/http系のパッケージを入れると動かなくなるバグ(Mac)

goplsで快適にプログラムを書いていたんですが、net/http系のライブラリを使うと何故か補完等の全機能が使えなくなるというバグに見舞われて、かなり苦労したのでもし他にもそういう方がいたときのために解決方法等を載せておきます。


## どのようなバグか

僕はgolangでweb系のプログラムを書いていたので、[gin-gonic/gin](https://github.com/gin-gonic/gin)のようなライブラリを使っていたのですが、そのライブラリをimportするとgoplsが動かなくなるというバグでした。


## 原因

様々な場所でログを出力してデバッグしていたところ。
`$GOPATH/src/golang.org/x/tools/go/packages/packages.go`の`Load`という関数でエラーが起きていたようでした。

```
exit status 2: # runtime/cgo","_cgo_export.c:3:10: fatal error: 'stdlib.h' file not found
```

というエラー文が出てきました。
goplsはcgoを使っているらしくC系の動作がちゃんとしていないと動かないようです。
このエラーについてググるとMacOSのアップデート時にxcodeがstdlib.hを見失ってしまう？ことがあるらしいです。

もし、これと同じエラーかどうかを試したければ、stdlib.hをimportしたC++の簡単なプログラムを書いて、ちゃんと動くかを試してみるといいと思います。

## 解決方法

僕の場合は以下のようにして、pkgをインストールしたら治りました。

```
$ open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```

参考： https://stackoverflow.com/questions/51761599/cannot-find-stdio-h
CriptZombie１章ポイント解説

##イーサリアムとは
イーサリアムとはスマートコントラクトを実現するためのプラットフォームです。
スマートコントラクトとは、、、？？日本語に訳すと「賢い契約」
賢いというのは自動という意味です。
つまりある条件を満たすと自動で契約を実行するという仕組みを実現するのがイーサリアムなのです。
あらゆるアプリケーションがイーサリアム上で動作可能でスマートコントラクトを実現しています。
スマートコントラクトを実装する場合は、Solidityというプログラミング言語で実装します。

イーサリアムは、分散型のコンピューター、分散型のアプリケーション、分散型の計算をする仕組みにより、「スマートコントラクト」を実現するためのプラットフォームです。特定のアプリケーションだけに適用するブロックチェーンではなく、あらゆるアプリケーションがイーサリアムのプラットフォーム上で動作可能になるサービスのため、
「スマートな契約（contract）」という意味です。
ブロックチェーン分野においては「決められたある条件を満たすと自動的に契約を実行する」ということが記述されたコードのことを指します。
スマートコントラクトを実装する場合は、Solidityというプログラミング言語で実装します。SolidityはJavaScriptの文法に似たプログラミング言語で、コンパイル後、Ethereum（イーサリアム）上で実行可能です。
BitcoinとEthereumの違う点は、ブロックチェーン上に「取引と一緒に契約も残せる」ことです。

https://www.tdi.co.jp/miso/blockchain-ethereum-solidity-remix

##Contractとは
コントラクトとはイーサリアムアプリケーションの基本ブロックのことです。
変数や関数は全てコントラクトに属しています。
コントラクトは以下のように書きます。
Ethereumで動作させるために作成する
処理の塊
イーサリアムアプリケーションの基本ブロックのこと
コントラクトが呼び出されることで処理が実行される
コントラクトとは、一言で表すと「ブロックチェーン上で動作するアプリケーション」です。なんらかの処理を書いたプログラム（ビジネスロジック）を「コントラクト」と呼んでいる、と思って良いでしょう。
solidityにおけるコントラクトはオブジェクト指向言語におけるクラスのようなものである。コントラクトはトランザクションもしくは他のコントラクトを通して作られる。
クリプトゾンビではZombieFactoryというコントラクトを作りますが、とてもいい例です。ゾンビを作成する一連の処理が詰まったブロックです。工場というコントラクトがブロックチェーン上で呼び出されるたびにゾンビが生まれるのです。

```
contract Factory {
 //一体のゾンビを作り出すための一連の処理
}
```

##状態変数とは

コントラクト内に永遠に保管され続けるもの
イーサリアムのブロックチェーン上に記載されます。

```
contract Factory {
  // この部分がブロックチェーン上に記載される
  uint dna = 100fjakd348901;
}
```


##構造体とは(Struct)
複数のデータ型を保存するための容器
ゾンビはname(string)やage(int)複雑なデータをたくさん持っている。
それらをstructにまとめて保存するのである。
<img width="175" alt="Screen Shot 2019-04-13 at 12.19.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294829/2c1e0434-cdad-e0c3-6588-665b88ad3980.png">
##配列の種類
solidityでは２種類の配列があります

```
uint[2] fixedArray;　　　// 2つの要素が入る固定長配列
uint[] dynamicArray;　　//可変長配列
```

固定長配列＝＞配列の要素数が決定してる
可変長配列
ブロックチェーン上における可変長配列の場合、いくらでも格納できるためデータベースのように扱うこともできる。仮想通過では取引されるたびに取引が有効かどうかを判断する暗号が追加されていく。こういった半無限に増えていくデータを保存するのに適している。

##構造体と可変長配列の関係６
ゾンビっていう構造体がある＝＞いろんなデータを集めたもの（name age Kao color height 声のトーンなど、体の凹凸）＝＞ゾンビ軍団というグループ＝＞可変長配列＝＞ゾンビは無限に増やしたいから可変にしよう

```
Zombie[] public zombies;

    function createZombie(string _name, uint _dna) {

    }
```

<img width="503" alt="Screen Shot 2019-04-13 at 12.23.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294829/546937d4-8a2e-f64a-53db-6ed6af6c2b1e.png">


##関数
関数とは処理の塊＝＞動詞である
引数とは目的語である
例えば、食べる行為（関数）を赤ちゃんに覚えさせるとする
しかし何を食べるかをいちいち教えていたらキリがない。

```baby.
　　eatcake = フォークを使って
```

##関数と引数



##戻り値
処理を実行した結果、返ってくる値のこと
走るという行為を実行しても戻り値はなにも返ってこない
しかし料理するという処理の場合、結果としてできあがった料理を返してもらわないと意味がない。
この処理は戻り値が必要なのかどうか常に意識しよう

##View
関数が動作しても、データの保存や変更は一切行わず、データの閲覧のみを行うと宣言します。
view修飾子がある関数は、状態の変更を行いません。そして、状態変数の参照が可能です。

##Pure
 view と同じように、関数が動作してもデータの保存や変更を行わないだけでなく、読み取りすらも行わないことを宣言します。
pure修飾子がある関数は、状態の変更も参照も行いません。受け取った値しか使いません。

##keccak256とは
EthereumにはSHA-3の一つであるハッシュ関数keccak256が組み込まれています。ランダムな256ビットの16進数へマッピングします。
つまり暗号してくれるようなもの
Scalaでfor式とFutureを一緒に使うときは注意！！


# 結論
**for式は変換を直列化するので、Futureをfor式の中で使うと並列化されない**

# 実装から理解する
以下の二点を実装し、実行時間を比較しながら確認していく

- for式の**中**でFutureを使った場合
- for式の**外**でFutureを使った場合

## for式の中でFutureを使った場合

```scala
package hoge

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object test {
  def main(args: Array[String]): Unit = {
    val start = System.currentTimeMillis
    val result = for {
      h <- Future{Thread.sleep(1000); "hello "}
      s <- Future{Thread.sleep(1000); "scala"}
    }yield h + s
    Await.ready(result,Duration.Inf)
    println(result)
    println("処理時間： " + (System.currentTimeMillis - start) + " ミリ秒")
  }
}
//Future(Success(hello scala))
//処理時間： 2620 ミリ秒
```

for式の中で直列化されるので、```Future{Thread.sleep(1000); "hello "}```が終わった後に、
```Future{Thread.sleep(1000); "scala"}```が呼ばれる。
なので、結果的に**処理時間：　2620 ミリ秒**になる。


## for式の**外**でFutureを使った場合


```scala
package hoge

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object test {
  def main(args: Array[String]): Unit = {
    val start = System.currentTimeMillis

    val f1 = Future{Thread.sleep(1000); "hello "}
    val f2 = Future{Thread.sleep(1000); "scala"}
    Await.ready(f1,Duration.Inf)
    Await.ready(f2,Duration.Inf)
    val result = for {
      h <- f1
      s <- f2
    }yield h + s
    println(result)
    println("処理時間： " + (System.currentTimeMillis - start) + " ミリ秒")
  }
}
//Future(Success(hello scala))
//処理時間： 1522 ミリ秒
```

以下のFutureはmainスレッドと別のスレッドで動くため、非同期に実行される。

```scala
    val f1 = Future{Thread.sleep(1000); "hello "}
    val f2 = Future{Thread.sleep(1000); "scala"}
```

for式の中では、別スレッドで実行されたFutureの結果を用いて処理が行われる。
なので、結果的に**処理時間： 1522 ミリ秒**になる。
【Swift】Swift5.0のABI StabilityとSwift5.1のModule Stabilityと その先のLibrary Evolution Support

2019年3月18日に
Swift5.1のfinal branchingがアナウンスされてから
１ヶ月ほど経過しました。

リリース日はまだ出ていませんが
Appleのブログを見ている限り短いスパンでのリリースを考えており
次のバージョンについても学び始める時期なのかと思っています。
(WWDCに合わせるのかもしれませんが)

https://swift.org/blog/5-1-release-process/

Swift5.0ではABI Stabilityが達成されましたが、
Swift5.1はModule Stabilityを主な目的としています。

今回はSwift5.0で実現したABI Stability
そして5.1で達成されるModule Stability
さらに今後実現される予定のLibrary Evolution Support
について簡単にまとめてみたいと思います。

もし何か間違いなどごさいましたら教えていただけますとうれしいです:bow_tone1:

# ABI Stability

ABI StabilityはSwiftのバイナリの互換性を確保することによって
Swiftのバージョンが異なっても
他のバージョンのstandard libraryやruntime libraryでアプリの実行が可能になります。

メリットとして下記のようなものがあります。

## アプリサイズの削減

今まではアプリを使用する時に同じバージョンのstandard libraryやruntime libraryが必要になるため
これらをアプリのバンドルに含めなければならず容量が増えてしまっていました。(約5MB)

今後はObjective-Cのruntimeと同様にOSと一緒に同梱されるため
アプリのバンドルサイズを削減することができます。

## パフォーマンスの向上

ホストのOSとより統合することができるため

- 起動時間の短縮
- runtime時の処理の最適化
- 使用メモリの削減

が期待できます。

## Appleが将来のOSバージョンでSwiftを使ったPlatformのFrameworkを提供可能になる

ブログに書かれていたのですが、具体的にどういうメリットがあるのかがわかっていません。

FrameworkがSwiftで書かれることで
Swiftで書かれたアプリとの連携が向上してパフォーマンスが良くなるということでしょうか:thinking:

※ 
ABI Stabilityは
2019年4月現在 Appleプラットフォームで実現していますが
LinuxやWindowsはまだのようです。

https://swift.org/blog/abi-stability-and-more/
https://swift.org/blog/abi-stability-and-apple/


# Module Stability

ABI Stabilityは実行時のSwiftのバージョン差異を吸収してくれる一方、
Module Stabilityはコンパイル時のSwiftのバージョンの違いを吸収してくれます。

Swiftでは「swiftmodule」というアーカイブフォーマットでライブラリのinterfaceを定義していますが、
このファイルの内容が現在のコンパイラのバージョン(実質Swiftのバージョン)と密接に結びついているために
別のバージョンでビルドされたライブラリをimportとしようとしてもコンパイラがエラーにしてしまいます。

これによってバイナリフレームワークを提供しているライブラリで、
バージョンに合わせてビルドされたライブラリを用意する必要が毎回あり
クライアント側でも
ライブラリが対応していないからSwiftのバージョンを上げることができない
ということが起きていました。

これをModule Stabilityが実現されると
どのコンパイラのバージョンで実装されたかを気にする必要がなくなります。

※ 実はObjective-CでWrapすればできるということをInstabugの方がブログで書かれていました。
https://instabug.com/blog/swift-5-module-stability-workaround-for-binary-frameworks/

詳細は下記のSwift Forumの中で話されています。
https://forums.swift.org/t/plan-for-module-stability/14551


# Library Evolution Support

これはまだ最終決定がされていないものですが
AppleのブログではすでにStandard Libraryなどで実装されているようです。

Swift4.2で導入された@inlinableもこれの一つです。
https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md

今まではSwift(コンパイラ)のバージョンが上がった時の話をしていましたが、
今度はアプリで使用しているライブラリのバージョンが上がった時の話です。

現在ですと
ライブラリのバージョンが変わるたびに
アプリの再コンパイルが必要になります。

ブログによると
この動きにはメリットがあり
コンパイラがどのバージョンを使用しているのかがわかるので
最適化ができると書いてあります。
しかし
ライブラリのバージョンが違うと
この最適化が正しい最適化ではなくなる可能性があります。
そのため再コンパイルが必要になってくるようです。

Library Evolution Supportを達成すると
この再コンパイルが不要になります。

例えば
あるライブラリの更新が
他のライブラリの更新を引き起こすことがなくなります。

AとBのライブラリのbinary frameworkを使用している。
↓
AはBのライブラリに依存している。
↓
Bのライブラリを上げる
↓
~~Aも再コンパイルしなければならなくなる~~

# まとめ

Swiftは表だけではなく
裏側の仕組みもどんどん進化していっています。

普段はあまり目に見えないことに関しても
気がつかないところで恩恵を受けていたり
逆に何か影響を受けているかもしれないので
こういう裏側に仕組みを学ぶことも大事だなと思っています。

これからもSwiftがどう進化していくのかを追っていくのが楽しみです:smiley:
settings of pyenv

# install
install build tools

```
sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git boost-devil
```

install pyenv

```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
## Do the following commands at once. Not immutable. 
cat << 'EOF' >> ~/.bashrc
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
EOF

(logout and re-login)

pyenv
```

result

```
pyenv 1.2.6
Usage: pyenv <command> [<args>]

Some useful pye
nv commands are:
   commands    List all available pyenv commands
   local       Set or show the local application-specific Python version
   global      Set or show the global Python version
   shell       Set or show the shell-specific Python version
   install     Install a Python version using python-build
   uninstall   Uninstall a specific Python version
   rehash      Rehash pyenv shims (run this after installing executables)
   version     Show the current Python version and its origin
   versions    List all Python versions available to pyenv
   which       Display the full path to an executable
   whence      List all Python versions that contain the given executable

See `pyenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/pyenv/pyenv#readme
```

virtualenv

```
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
cat << 'EOF' >> ~/.bashrc
eval "$(pyenv virtualenv-init -)"
EOF

(logout and re-login)

pyenv virtualenv -h
```

result

```
Usage: pyenv virtualenv [-f|--force] [VIRTUALENV_OPTIONS] [version] <virtualenv-name>
       pyenv virtualenv --version
       pyenv virtualenv --help

  -f/--force       Install even if the version appears to be installed already
```


ref

* https://qiita.com/Kodaira_/items/feadfef9add468e3a85b
* https://enomotodev.hatenablog.com/entry/2016/12/29/142900

# how to use
install specific version

```
pyenv install -list
pyenv install 2.7.15
```

switch version

```
pyenv shell 2.7.15
(instant)
```

use virtualenv

```
pyenv virtualenv 2.7.15 kenji2.7.15
(require: you have to install 2.7.15 before)
pyenv shell kenji2.7.15
```
MスプラインとIスプラインをNumpyで

monotone（単調増加 or 単調減少）なスプライン、それがIスプライン。

Iスプラインを作るために使う、負にならないスプライン、それがMスプライン。

Iスプラインは、monotoneなはずのデータの回帰分析やスムージングに使えそうに見える。しかしどちらも、どうも世の中でほとんど使われていないようなので、数式をコードに起こすのに苦労した。

```python
import numpy as np
import matplotlib.pyplot as plt

def main():
    K = 3 # 次数
    L = 4 # ノットの数
    x_min = 0.1
    x_max = 1.0
    ts = np.concatenate([
        np.full(K, x_min),
        np.linspace(x_min, x_max, L + 2)[1:-1], # ノットをuniformに配置。non-uniformでもいい
        np.full(K + 1, x_max)
    ])

    xs = np.linspace(x_min, x_max - 1e-5, 100)

    def function_m(k, i, where=np.ones_like(xs, np.bool)):
        lxs = xs[where]
        ys = np.zeros_like(lxs)
        if k == 1:
            hit = (ts[i] <= lxs) & (lxs < ts[i + 1])
            ys[hit] = 1. / (ts[i + 1] - ts[i])
        elif ts[i + k] - ts[i] != 0.:
            _a = (k - 1) * (ts[i + k] - ts[i])
            _b = lxs - ts[i]
            _c = function_m(k - 1, i, where)
            _d = ts[i + k] - lxs
            _e = function_m(k - 1, i + 1, where)
            ys = k * (_b * _c + _d * _e) / _a
        return ys

    for i in np.arange(K + L):
        plt.plot(xs, function_m(K, i), label=str(i))
    plt.legend(bbox_to_anchor=(1,1), loc='upper right')
    plt.title('M-spline')
    plt.show()

    def function_i(i):
        hit = (ts[:-1,np.newaxis] <= xs) & (xs < ts[1:,np.newaxis])
        js = np.argmax(hit, axis=0)
        def f_a(m):
            mask = js >= m
            _a = K + 1
            _b = ts[m + K + 1] - ts[m]
            _c = function_m(K + 1, m, where=mask)
            ys = np.zeros_like(xs)
            ys[mask] = _b * _c / _a
            return ys
        ufunc_a = np.vectorize(f_a, signature='()->(n)')
        yss = ufunc_a(np.arange(i, K + L))
        return yss.sum(axis=0)

    for i in np.arange(K + L):
        plt.plot(xs, function_i(i), label=str(i))
    plt.legend(bbox_to_anchor=(1,1), loc='upper right')
    plt.title('I-spline')
    plt.show()

if __name__=='__main__':
    main()
```

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325885/75926be5-43d3-3a70-eb95-7416eba95c5b.png)

![Figure_1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325885/d50069de-4d3d-6be7-89c0-533c7fb3a111.png)

参考：
[Wikipedia I-spline](https://en.wikipedia.org/wiki/I-spline)
[spline](http://www.fon.hum.uva.nl/praat/manual/spline.html)
[INFERENCE USING SHAPE-RESTRICTED REGRESSION SPLINES](https://arxiv.org/pdf/0811.1705.pdf)
phpdotenvが複数行に対応

[phpdotenv](https://github.com/vlucas/phpdotenv)がV3から

```
NAME="VALUE
VALUE
VALUE"
```

に対応しました。

.env

```
TEXT="aaa
bbb
ccc"
```

```php:phpdotenv2.php
<pre>
<?php
include('autoload.php');
use Dotenv\Dotenv;

$dotenv = new Dotenv(__DIR__);
$dotenv->load();
var_dump($_ENV);
?>

/*
array(1) {
  ["TEXT"]=>
  string(3) "aaa"
}
*/
```

```php:phpdotenv3.php
<pre>
<?php
include('autoload.php');
use Dotenv\Dotenv;

$dotenv = Dotenv::create(__DIR__);
$dotenv->load();
var_dump($_ENV);
?>

/*
array(1) {
  ["TEXT"]=>
  string(11) "aaa
bbb
ccc"
}
*/
```

ちなみに.envが

```
TEXT="aaa
```

だと上記コードの出力は

```
V2
array(1) {
  ["TEXT"]=>
  string(3) "aaa"
}

V3
array(0) {
}
```
【Javascript】連想配列の中身の確認方法。

#配列と連想配列の違い
まずは配列から。

##配列
```main.js
var array = [];
    array.push('あ'); //console.log(array[0]); あ
    array.push('い'); //console.log(array[1]); い
    array.push('う'); //console.log(array[2]); う
    array.push('え'); //console.log(array[3]); え
    array.push('お'); //console.log(array[4]); お

　　array['あ','い','う','え','お']; //配列の中身
```
これが一般的な配列ですね。
[0]を一番左としインデックス番号で取得できます。
もちろん、番号ではなく値を指定して取得することも可能です。
ちなみに配列の中身はこんな感じになっています。

なんとなく配列はわかりました。
##連想配列
次は連想配列です。

```main.js
    var ARRAY = [];
        ARRAY['名前'] = '太郎'; //console.log(ARRAY['名前']); 太朗
        ARRAY['年齢'] = '30'; //console.log(ARRAY['年齡']); 30
        ARRAY['住所'] = '東京'; //console.log(ARRAY['住所']); 東京

       //中身　[名前: "太朗", 年齢: "30", 住所: "東京"];

```
こんな感じです。
何が違うのかというのは見た感じわかりますが、何がどう違うのか。
配列ではarray[値, 値,・・・]だったのに対し、連想配列はARRAY[キー:値, キー:値・・・]といった中身になっています。

違いはこんな感じです。

##要素数の確認方法
  次は配列と連想配列の要素数の確認方法です。
配列は**.length**で取得できます。

```main.js
 var array = [];
        array.push('あ'); //console.log(array[0]); あ
        array.push('い'); //console.log(array[1]); い
        array.push('う'); //console.log(array[2]); う
        array.push('え'); //console.log(array[3]); え
        array.push('お'); //console.log(array[4]); お

        console.log(array.length); //5

```
連想配列では違うプロパティを使用します。
それが、**Object.keys(配列名).length;**です。
何故、配列ではlengthが使えて連想配列では使えないのかというと、配列とオブジェクトの違いです。
どう違うのかと言うと、配列はインデックス番号（添字とも言う）で管理されているのに対し、オブジェクトはプロパティで管理されている（キー:値）と言う違いがあります。

そして.lengthは添字を数えるものなんですね。
一方でObject.keys(配列名).lengthはプロパティを数えます。

これを知らずに.lengthで連想配列（オブジェクト）の要素を取得しようとしても、いつまでたっても０のままなので、気を付けて下さい。

##まとめ
・配列はインデックス番号で取得する
・連想配列（オブジェクト）はキーで取得する
・配列とオブジェクトの違いは添字で管理されているのが配列。プロパティで管理されているのがオブジェクト。
・配列には.lengthを使用し、オブジェクトにはObject.keys(配列名).lengthを使う。
CentOSにPosgreSQLの環境構築

# PostgreSQL

## ■ インストール
やはり便利なのでyumを使ってインストールします。

yumのベースリポジトリにあるpostgreSQLはバージョンが古かったです。

```bash:ターミナル(仮想マシン)
$ yum list | grep postgresql-server
postgresql-server.x86_64                 9.2.24-1.el7_5                  base
```

なので最新のバージョンのリポジトリを追加してインストールします。

```bash:ターミナル(仮想マシン)
# pgdg96リポジトリを追加する
$ sudo yum install -y https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-redhat96-9.6-3.noarch.rpm

# PostgreSQLサーバーをインストールする
$ sudo yum install -y postgresql96-server postgresql96-contrib

# バージョンの確認
$ psql -V
psql (PostgreSQL) 9.6.12
```

参考：[CentOS7.3にPostgreSQL9.6.3をインストールしてみた](https://qiita.com/uhooi/items/44ed9370740c7521dce4)

## ■ データベース作成と起動

### スーパーユーザの作成

データベースの管理をすることになるスーパーユーザの作成を行います。

```bash:ターミナル(仮想マシン)
# ユーザの追加
$ sudo useradd postgres
$ sudo passwd postgres
```

### データベースクラスタの作成

データベースの格納領域であるデータベースクラスタを作成します。
`/home/postgres/data`はデータベースクラスタを作成するディレクトリです。

#### 方法①

```bash:ターミナル(仮想マシン)
# postageユーザに切り替え
$ su postage
# データベースクラスタの作成
$ initdb -D /home/postgres/data --encoding=UTF8 --no-locale
```

※`initdb`を実行したユーザがデータベースクラスタの管理ユーザとして設定(ディレクトリの権限・所有者も変更されます)され、また同名のデータベースユーザが初期ユーザとして作成されます。

#### 方法②

この作業は実は下記コマンドでも行うことができます。その方がディレクトリの準備とかしなくて良いしラクかもしれません。

```bash:ターミナル(仮想マシン)
# データベースの初期化処理を行う
$ sudo /usr/pgsql-9.6/bin/postgresql96-setup initdb
```

※この場合、データベースクラスタのディレクトリはデフォルトで`/var/lib/pgsql/9.6/data`になっているので注意してください。

※この方法でデータベースクラスタを作成した場合は、データベースの初期ユーザとして`postgres`が作成されています。

### PATHを通す

1. 環境変数`PATH`に`/usr/pgsql-9.6/bin`を追加します。 
2. 環境変数`LD_LIBRARY_PATH`に`/usr/pgsql-9.6/lib`を定義します。
3. 環境変数`PGDATA`に`/home/postgres/data`を定義。※これをすることで、毎回`-D /home/postgres/data`とデータベースクラスタのディレクトリを指定しなくても良くなります。

### PostgreSQLサーバの起動

#### 方法①

pg_ctlコマンドを使ってPostgreSQLを管理します。

```bash:ターミナル(仮想マシン)
# PostgreSQLサーバの起動
$ pg_ctl start -w

# PostgreSQLサーバの終了
$ pg_ctl stop
```

※自動起動設定をするには、スクリプトを書く必要があるようです。

参考：[PostgreSQL 8.1.4 起動と自動起動設定](https://kazmax.zpp.jp/pgsql/pgsql2.html#ah_4)

#### 方法②

mysqlと同じようにsystemdを使ってPostgreSQLの起動・終了を行うことができます。
systemdを利用することにより自動起動設定も超ラクに出来るので、使わない手は無いと思います。

```bash:ターミナル(仮想マシン)
# 起動
$ systemctl start postgresql-9.6.service

# 自動起動設定
$ systemctl enable postgresql-9.6.service

# 終了
$ systemctl stop postgresql-9.6.service
```

mysqlと完全に一緒ですね。

## ■ データベース接続とデータの作成

### データベースユーザの作成

データベース一覧を表示する`psql -l`を実行したところ、roleが存在しないのでアクセスできませんでした。

```bash:ターミナル(仮想マシン)
# データベース一覧を表示
$ psql -l
psql: FATAL:  role "vagrant" does not exist
```

#### 方法①

```bash:ターミナル(仮想マシン)
# postgresユーザに切り替え
$ su postgres

# ユーザの作成
$ createuser -d -U postgres -P {ユーザ名}
```

※`createuser`は対話式でもユーザの作成が出来るらしいんですけど、上手く実行できませんでした…

#### 方法②

`postgres`ユーザでデータベースにログインしてユーザを作成する場合は下記で行う。

```bash:ターミナル(仮想マシン)
$ psql
psql (9.6.12)

postgres=# create role vagrant login createdb password 'vagrant';
```

### データベースへのログイン

続く…
Google検索のスピードテストと fast.com の違い

最近回線測定で、ブラウザ経由のスピードテストをたくさんしているので、両者の違いメモ。環境は東京からのアクセスで、 Mac Chrome での観測。

# Google検索のスピードテスト

Google検索でスピードテストと検索すると画面上部に出てくるスピートテスト。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5330/d7a08115-9581-14d0-9b76-a8207ddd1cd1.png)

ダウンロードでアクセスするのは

- wss://ndt-iupui-mlab1-hnd{N}.measurement-lab.org:ポート/ndt_protocol

に2並列での2アクセスのみ。レスポンスヘッダの `Sec-WebSocket-Protocol` の内容が s2c と ndt と違いがあるので、並列アクセスごとの内容は違ってそう。ストリーム(WebSocket)でコネクションを保ちつつ、ダウンロードして速度を測定。ホスト名は `hnd{N}` なので、東京地域のサーバ経由経由で返してそう。

アップロードもほぼ同じで、ストリームでずっとアップロードし続けてる。

# fast.com のスピードテスト

- https://fast.com/

のスピードテスト。Netflix 社が提供している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5330/3981e9c4-0e2f-bdac-8fd0-fcf4e9906573.png)


ダウンロードテストでは、
- https://ipv4-c{N}-tyo{N}-ix.1.oca.nflxvideo.net/speedtest/range/...
- https://ipv4-c{N}-osa{N}-ix.1.oca.nflxvideo.net/speedtest/range/...
へ、トータルで数十から数百アクセスを行っての速度測定。ホスト名から、東京と大阪のサーバに測定を行っている。

なお、fast.com は最初に表示される「お使いのインターネット速度」はダウンロード速度のみで、「詳細を表示」すると、裏側ではダウンロードテストが終わったらアップロードテストが自動で走っていて、完了すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5330/76d04058-2b1f-7c12-058c-3f61d9e4b629.png)



のように、アップロード速度も表示される。また詳細ではどのサーバ経由で測定されたかが解る。

# 二つの違い

Google は WebSocket のストリームで、fast.com は XHR での大量のダウンロードとアップロードで測定している。1ファイルのダウンロード・アップロード速度ならGoogleが、Webブラウジングのような並列で多量のリクエストが発生するようなダウンロード速度なら fast.com の計測方法が実態と近そう。
Angularの覚書

Angularのrootはangular.jsonのファイルに記載されている

```
"projects": {
    "sample": { ##プロジェクト名
      "root": "",
      "sourceRoot": "src",　##ここがルートディレクトリ
      "projectType": "application",
      "prefix": "app",
      "schematics": {
        "@schematics/angular:component": {
          "styleext": "scss"
        }
```

inportやscssのimage-urlのなども"src/..."ってかかないと怒られる
ansible-playbookでサーバーを構築する時のssh接続に関するメモ

# ansible-playbookの際のssh接続の設定

ansible-playbookでサーバーを構築するときに、パスワードやら秘密鍵やらを使って接続すると思いますが、そのときの設定方法についてのメモです。

# ansible関係なしの普通のssh接続

###パスワードでssh接続する場合

```
ssh [接続先のサーバー(ホスト名かIPアドレス)]
```

このコマンドを実行するとパスワードを聞かれるので入力してください。

### 鍵認証でssh接続をする場合（鍵は作成されていることを前提とする）

[サーバー側]
公開鍵(authorized_keys)の権限：600
公開鍵の.sshディレクトリの権限：700
[クライアント側]
秘密鍵の権限：600

クライアント側も設定しないと以下のようなエラーが出るので設定しといてください

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
```

```
ssh -l [接続先のユーザー名] -i [秘密鍵] [接続先のサーバー]
```
これで接続できると思います。
鍵の生成に関してはOSによって便利なツールがあるのでググってください。


# ansible-playbookでのssh接続

## inventory_fileにsshの設定を記述する場合

```:inventory_file
[webservers]
(ホスト名 or IPアドレス)

[webservers:vars]
ansible_port=(sshのポート番号、デフォルト22)
ansible_user=(ssh接続先のユーザー名)
ansible_ssh_pass=(パスワード)
ansible_ssh_private_key_file=(秘密鍵のパス (~/.ssh/id_rsa など))
```

これで以下のコマンドを実行すればssh接続が通り、`playbook.yml`の設定どおりに構築されるはず

```
ansible-playbook -i inventory_file playbook.yml
```

inventory_fileの変数は[公式のドキュメント]("https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#list-of-behavioral-inventory-parameters")を見てください


## sshの設定ファイルに記述する場合

```:~/.ssh/config
Host (何でもよい)
  HostName (接続先のホスト名 or IPアドレス)
  User (接続先のユーザー名)
  Port (sshのポート番号)
  IdentityFile ~/.ssh/(秘密鍵)
```

`~/.ssh/config`権限を600にしといたほうがよい
設定が完了すると以下のコマンドでssh接続できるようになる

```
ssh [HOSTに記述した名称]
```

inventory_fileが以下のようになっている確認

```:inventory_file
[webservers]
(~/.ssh/configでHOSTに記述した名称)
```

これで以下のコマンドを実行すればssh接続が通り、`playbook.yml`の設定どおりに構築されるはず

```
ansible-playbook -i inventory_file playbook.yml
```