OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】 SpriteKit 入門 ⑤

SpriteKitの使い方を解説します。
[SpriteKit 入門 ④](https://qiita.com/tosssy/items/86b854ec71f221ff08a7)で敵を表示して衝突判定を実装することができました。今回は、一度に発射する弾の数を増やしてみようと思います。
（環境：Xcode12.4 　Swift5.3）

## `repeatShoots`メソッドの修正

前回はMySceneクラスのプロパティとして弾用のSKShapeNodeを用意していました。しかし特にクラスのプロパティとして宣言しておく必要もなかったため、これを削除しておきましょう。
次に、`repeatShoots`メソッドを修正していきます。前回は一つだけSKShapeNodeのインスタンスを作成して`self.addChild(shoot)`で画面に表示させていましたが、この処理をfor文を使って繰り返し実行するように変更します。また、弾の発射方向も少しずつずらすようにしましょう。以下にコードを示します。

```swift:MyScene.swift
//自機から発射する弾
    func repeatShoots(){
        for i in -1...1{
            let shoot:SKShapeNode = SKShapeNode.init(rectOf: CGSize.init(width: 30, height: 30), cornerRadius: 3)
            shoot.name = "shoot"
            shoot.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 30, height: 30))
            shoot.physicsBody?.affectedByGravity = false
            shoot.physicsBody?.categoryBitMask = 0b0001
            shoot.physicsBody?.collisionBitMask = 0b0000
            shoot.physicsBody?.contactTestBitMask = 0b0001
            shoot.position = image.position
            shoot.fillColor = SKColor.red
            shoot.lineWidth = 3
            shoot.strokeColor = SKColor.white
            shoot.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat(Double.pi), duration: 1)))
            let p:CGFloat = CGFloat(i*100)
            let vector1: CGVector = CGVector(dx: p, dy: self.size.height)
            shoot.run(SKAction.sequence([SKAction.move(by: vector1, duration: 3),SKAction.removeFromParent()]))
            self.addChild(shoot)
        }
    }
```

## 衝突判定の修正

発射する弾を増やすことはできましたが、このままだと発射した瞬間の弾同士での衝突が発生してしまいます。弾同士の衝突は無視したいので、if文の条件をそうなるように修正していきます。(※現時点では敵同士での衝突は考慮していません。)

```swift:MyScene.swift
   func didBegin(_ contact: SKPhysicsContact) {
        let t1 = contact.bodyA.categoryBitMask == self.enemy?.physicsBody!.categoryBitMask
        let t2 = contact.bodyB.categoryBitMask == self.enemy?.physicsBody!.categoryBitMask
        let notEmpty = contact.bodyA.node != nil && contact.bodyB.node != nil
        if (t1 || t2) && notEmpty{
            if contact.bodyA.node!.name == "shoot" && contact.bodyB.node!.name != "shoot" {
                self.removeChildren(in: [contact.bodyA.node!,contact.bodyB.node!])
            }else if contact.bodyB.node?.name == "shoot" && contact.bodyA.node!.name != "shoot" {
                self.removeChildren(in: [contact.bodyA.node!,contact.bodyB.node!])
            }
        }
    }

```
CCNA試験学習(忘備録)〜VLAN〜

#はじめに

内容が飛び飛びでゴメンなさい。
引き続きがんばっていきましょう〜〜。

#VLAN(Virtual Local Area Network)
・レイヤ２、スイッチのお話。
・１台のスイッチ上で仮想的に複数のネットワークを作成することができる。

#VLANを使うメリット
・ネットワークを仮想的に分けることができ、端末の物理的な配置に依存しないネットワークを構築できるようになる。
・会社で言えば部署ごとに仮想的にネットワークを分けられるので、他部署から見られたくないデータも制限できる。
・ブロードキャストドメインを分割できる。

#用語説明

##アクセスポート

>1つのVLANに所属しているポートのこと。

##アクセスリンク

>アクセスポートに繋がっているリンクのこと。

##トランクポート

>複数のVLANに所属しているポートのこと。

##トランクリンク

>トランクポートに繋がっているリンクのこと。

##ISLフレーム

>トランクポートの設定をすると、１つのリンクで複数のVLANが行き来するので、スイッチどのVLAN情報化を識別する必要がある。
その識別に必要な目じるしのようなもの。
Cisco独自のプロトコルで、フレームの前後に目じるしをくっつける。

##IEEE 802.1Qフレーム

>こちらもISLフレーム同様、スイッチのための目じるし。
ただし、こちらは標準化されたプロトコルで、フレームのMACアドレスとタイプの間にVLANタグを挿入する。というもの。
最大フレームのサイズは1522。

##ネイティブVLAN

>IEEE 802.1Qで一つだけ選択でき、ネイティブVLANだけはVLANタグを付けずに送信しても識別される。
ただし、通信する両スイッチでネイティブVLANは合わせておかなければならない。

##VTP(VLAN Trunking Protocol)

>VLAN名の不一致が起こったときなど、同期してくれるCisco独自のプロトコル。
VLANの管理を簡易化できる。
リビジョン番号が大きいスイッチに合わせて他のスイッチが同期する。
VTPには**サーバーモード、クライアントモード、トランスペアレントモード**という３つの動作がある。

>>サーバーモード
VLANの作成、変更、削除可能。デフォルトはこちら。自身の情報を他にも広める。

>>クライアントモード
VLANの作成、変更、削除不可。クライアントモードでリビジョン番号が大きい場合は他のスイッチが同期してくれる。

>>トランスペアレントモード
VLANの作成、変更、削除可能。しかし自身の情報を他に広めない。かつ、他のスイッチの情報も同期しない。
リビジョン番号は０に固定。

##VLAN間ルーティング

>VLAN番号が違っても通信を可能にすること。
**ルータ**と**スイッチ**が必要。

##セキュアMACアドレス

>スイッチに登録されているMACアドレスのこと。

##音声VLAN

>IPネットワーク上でも音声通話ができるようになるIPテレフォニーでも
使用できるVLANのこと。

>>CoS(Class of Service)
フレームの優先順位を表す値。

>>QoS(Quality of Service)
パケットに優先順位をつけて通信の保証をする技術のこと。

#VLAN設定コマンド

①VLANの作成
(config)#vlan [vlan番号]

②アクセスポートの設定
・モードをアクセスに設定
(config-if)#switchport mode access
・VLANの指定
(config-if)#switchport access vlan [vlan番号]

■VLAN間ルーティング
①サブインターフェイスの作成
(config)#interface [インターフェイス.論理番号]

②サブインターフェイスのトランキングプロトコルの選択
(config-subif)#encapsulation dot1q [VLAN番号]
PythonでAthenaにクエリする

#はじめに
今回、PythonでAthenaを使ってデータ取得する機会がありましたので、
その時に利用した[awswrangler](https://github.com/awslabs/aws-data-wrangler)を使ったAthenaへのクエリ実行方法を紹介したいと思います。
※この記事ではAWS接続用のプロファイルの設定やAthenaへのデータ登録は既に済んでいることを前提にしています

#インストール

```
pip install awswrangler
```

#使い方
```python
import awswrangler as wr

# クエリリクエスト
df = wr.athena.read_sql_query(
    ql='SELECT * FROM test_table',
    database='db_name'
)
# 結果を出力
print(df)
```
[ドキュメント](https://aws-data-wrangler.readthedocs.io/en/stable/stubs/awswrangler.athena.read_sql_query.html)

### 接続情報
awswranglerがプロファイルの情報を取得して接続するので、スクリプト側で特に指定する必要はありません。
プロファイルが複数ある場合は環境変数に以下を追加すれば、指定したプロファイルを利用して接続を行います

```
AWS_DEFAULT_PROFILE=profile_name
```

### リトライ処理
athenaに接続を試みて失敗した場合の最大リトライ回数を指定できます

```python
import awswrangler as wr
import botocore

wr.config.botocore_config = botocore.config.Config(
    retries={"max_attempts": 5},
)
```
[ドキュメント](https://aws-data-wrangler.readthedocs.io/en/stable/tutorials/021%20-%20Global%20Configurations.html#wr.config)

ただし、待ち時間が以下のように短いため長めに設定したいのであればリトライ用のライブラリを利用して対応した方が良さそうです

```
2021-06-01 11:34:43 sleeping for 0.6901632031039504 seconds
2021-06-01 11:34:44 sleeping for 0.7869570857297759 seconds
2021-06-01 11:34:45 sleeping for 1.955833391490407 seconds
2021-06-01 11:34:47 sleeping for 2.6080917647958914 seconds
```

### まとめ
[boto3](https://aws.amazon.com/jp/sdk-for-python/)のみでも今回の処理は実現できますが、athenaへのクエリ実行を実装する場合は自前で実行状況を確認する処理を実装して状況に応じてデータを取得するようにしないといけなくなる為、すごい手間を要します。
しかし、今回紹介した[awswrangler](https://github.com/awslabs/aws-data-wrangler)を使えば全てやってくれるので、おすすめです。

また、Athenaへのクエリ実行だけでなくRedshiftやS3など他のAWSサービスに関する機能も提供しているので、これがあればいろいろな箇所で実装の手間が省けそうです。
SQL PLUS・LINUXコマンドの知識習得

# 今週の学習課題
・SQL PLUSについて知識習得
・LINUXコマンドの知識習得

# 学習内容・結果
#### 1. SQL PLUS
　　　　・インストール手順
　　　　・コマンド入力と実行
　　　　・表定義の表示について
　　　　・PL/SQL定義の表示について
　　　　・SQLコマンドの実行

#### 2. LINUXコマンド
　　　　・使用頻度高コマンド

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
　　
#### **《SQL PLUS：インストール手順》**
1．初めに"Oracle Database 18c Express Edition"をPCにダウンロードする
2．SQL PLUSのパッケージをインストール

#### **《SQL PLUS：コマンド入力と実行》**
SQL*Plusプロンプトでコマンドを入力し、[Return]を押して実行します。
(WindowsのCMDと要領は大体似ている。)
コマンド内の単語と単語を区切るには、空白かタブを使用し、コマンドを読みやすくするために単語と単語の間に空白またはタブを追加することも可能。
また、以下3つのタイプのコマンドを入力できます。

●データベース内の情報を処理するためのSQLコマンド
●データベース内の情報を処理するためのPL/SQLブロック
●問合せ結果の書式設定、オプションの設定、SQLコマンドとPL/SQLブロックの編集および格納を行うためのSQL*Plusコマンド

#### **《SQL PLUS：表定義の表示について》**
指定された表またはビューの各列の定義を表示するには、SQL*Plusの**DESCRIBE**
コマンドを使用する。

#### **《SQL PLUS：PL/SQL定義の表示について》**
ファンクションまたはプロシージャの定義を表示するには、SQL*Plusの**DESCRIBE**
コマンドを使用する。

**プロシージャ**：コンピュータプログラム内で複数の命令や処理などを一つにまとめ、外部から呼び出し可能にしたもの

#### **《SQL PLUS：PL/SQLコマンドの実行》**
コマンド・プロンプトで、コマンドの1行目を以下のように入力する。

**SELECT FOOD_ID, FOOD_NAME, PRODUCT_ID, PRICE**

誤って入力した場合は、"Back Space"を使用して消去し、再度入力し
入力終了後、"Return"を押して次の行へ移動する。

その後、2行目の入力を求める「2」が表示される。コマンドの2行目を以下のように入力する。

FROM FOOD_DETAILS_VIEW WHERE PRICE > 200;

セミコロン(;)は、コマンドの終わりを意味し、"Return"を押すか「実行」を押下。
コマンドが処理され、結果が表示される。

    FOOD_ID      FOOD_NAME                PRODUCT_ID PRICE           
    ----------- ------------------------- ---------- --------------
    100         Peach Jerry               P_JRY      $240
    101         Takoyaki                  T_HBL      $800
    102         Curry                     C_RIC      $1000
    
結果および取得した行数が表示された後、SQL*Plusコマンドラインに再度コマンド・プロンプトが表示され、入力に誤りがあって結果が表示されなかった場合は、コマンドを再入力する。

#### **《LINUXコマンド》**

・**ls**
ディレクトリ情報の表示

・**cd**
ディレクトリの移動

・**cp**
ファイルのコピー

・**mv**
ファイルの移動

・**rm**
ファイルの削除

・**cat**
テキストファイルの内容表示

・**touch**
ファイルのタイムスタンプ変更

・**whatis**
コマンドの簡単な説明表示

etc....


# 来週の目標
SQLの復習・学習
LINUXコマンドの習得
SQL PLUSの続き(土日含む)
【LeetCode】就活に向けたコーディングテスト対策 #13

#はじめに
こんばんは．
M1就活生が[LeetCode](https://leetcode.com/)から，easy問題を中心に**Python**を用いて解いていきます．

https://leetcode.com/

↓では，解いた問題のまとめを随時更新しています．
[まとめ記事](https://qiita.com/halpi/items/43761b89a1873dcc9a5c)

https://qiita.com/halpi/items/43761b89a1873dcc9a5c

#問題
今回解いたのは，難易度easyから [問題58のLength of Last Word](https://leetcode.com/problems/length-of-last-word/) です．
問題としては，スペースで区切られた単語からなる文字列`s`に含まれる，最後の単語の文字列長を返すというもの．なお，最後の単語が存在したん場合は0を返します．

入力例と出力例は以下の通りです．

Example 1:

```python
Input: s = "Hello World"
Output: 5
```

Example 2:

```python
Input: s = " "
Output: 0
```

#書いたコード
書いたコードが以下になります．まず，文字列`s`を，`split()`を用いて単語からなるリストにします．`split()`では，引数に区切り文字を指定することができますが，引数に何も渡さない場合，スペースでの区切りになります．リスト内に何も存在しない（単語が存在しない）場合，0を返します．最後は，スライスを用いてリストの最後の単語を取り出し，その長さを返します．

```python
class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        s_words_list = s.split()
        if not s_words_list:
            return 0
        last_word = s_words_list[-1]
        return len(last_word)
```

#おわりに
今回解いた問題は2〜3行でも記述できると思います（その場合は可読性が落ちるけど...）．
また，今回の問題は英語での入力が想定されており，Pythonを使うと簡単に解くことができました．英語はスペースで区切って文章を書きますが，日本語など分かち書きされていない言語でチャレンジするのも面白いと思います．

今回書いたコードはGitHubにもあげておきます．

https://github.com/halpi17/LeetCodeStudy/blob/master/058/lengthOfLastWord.py

[前回](https://qiita.com/halpi/items/f7af9573982c417a159e)　[次回](https://qiita.com/halpi/items/d82ce980a10829455748)
【Rails】Railsアプリの雛形を作成するには



新規でアプリケーションを実行するコードは下記の通り
ターミナルのカレントディレクトリを確認の上実行する

`````````
$ rails new アプリケーション名
```

実行するとRailsの基本的なアプリが自動で作成されます。



誤ってアプリケーションを作った時は以下のコマンドをターミナルに入力して削除する

`````````
 $ rm -rf アプリケーション名
`````````````
STM32G031と温度,S-5851で液晶温度計 (Arduino)(AQM0802A)


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

i2cの初期設定がUNOと違う



```c++


  //i2cの初期化
  //Wire.begin(); // initialise the connection //767 UNO
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6


```


プログラム



```c++


#include <Wire.h> //I2C library

//STM32G031J6M6
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

// I2C temperature sensor - see table 1 of data sheet.  Resistor selects address. 
#define S5851A  0x48
#define I2Cadr  0x3e  // 固定

int     tempval;                //温度
char    data_read[2]={'@','t'}; //i2cバッファー
int     ii;                     //ループカウンター

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

void i2c_led_w(char *buff1){
  Wire.beginTransmission(I2Cadr);
  Wire.write(buff1[0]);
  Wire.write(buff1[1]);
  Wire.endTransmission();
  delay(2);
}//i2c_led_w

void setup()
{  
  delay(3000); //not delete  //031

  //i2cの初期化
  //Wire.begin(); // initialise the connection //767 UNO
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

  //液晶の初期化
  for(ii=0;ii<11;ii++){
    i2c_led_w(&INIT_com[ii*2]);
  } //for

} //end setup

void loop()
{

  //画面のクリア
  i2c_led_w(INIT_cls);

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  tempval = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    tempval = (int)Wire.read(); // 1バイトを受信
  }//while

  //液晶に表示
  data_read[1] = '0' + (tempval / 10);
  i2c_led_w(data_read);
  data_read[1] = '0' + (tempval % 10);
  i2c_led_w(data_read);

  delay(1000); //1秒待つ
}//loop



```

![i2c_lcd_s5851_031_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/db5675d0-1c4f-95cc-5268-4c4c96852f3e.jpeg)
【GCP】フォルダ管理の権限に関する注意

すでに情報があったりするのですが、フォルダを作成するときは、フォルダ管理に関する権限を別途付与する必要があったみたいです。
https://mikunet.biz/2021/05/30/gcp_folder/

しかも、最初は組織管理者じゃないとこの権限も付与できない。

フォルダに関する権限は以下の公式ドキュメント参照。
https://cloud.google.com/resource-manager/docs/access-control-folders?hl=ja

IAMで個別に権限付与もできますし、ドメイン単位で付与もできます。
階層構造で考えれば納得できるのですが、忘れてしまいますね。。
DockerでビルドしたPJをECS上にデプロイするまで【イメージをECS上で動かす】

1. [導入](https://qiita.com/Ohtak/items/06adcb1ca981c0f652f3)
2. [PJのDocker化](https://qiita.com/Ohtak/items/d05b864c1bd8f10df3bb)
3. イメージをECS上で動かす <=ｲﾏｺｺ
4. [CodePipelineを使った自動デプロイ](https://qiita.com/Ohtak/items/ab78dc4431ae2e8d1b6b)

さて、いよいよECS上にイメージをアップして動かすところです。
大きな手順は下記

1. ECRにリポジトリを作成し、イメージをそこにプッシュ
1. プッシュされたイメージをもとにECS上で動作するクラスターを作成
1. URLからそこにアクセスできるようにする

構成としては、タスクをFARGATEで起動させALBを介してアクセスする形です
クライアント=>ELB=>タスク（コンテナ）
みたいな

#ECRにリポジトリを作成
基本[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/repository-create.html)通りにすれば行けるのですが、実はいけないところがあったりします。

##Dockerfileの指定が必要
ドキュメントには「リポジトリを作成し、プッシュコマンドを表示してその通りに打てばプッシュできます」とありますが、このコマンドにはDockerfileを指定しているところがありません。
AWSで指示されるコマンドは

1. AWSへのログイン
1. イメージにタグをつけてビルド
1. ビルドしたイメージのタグにリポジトリURLを加える
1. そのタグを指定してpush

の手順ですが、この「2. イメージにタグをつけてビルド」の時点でDockerfileを指定する必要があります。

指示されるコマンドは下記

```
$ docker build -t {ECRのリポジトリ名} .
```

このまま打つとデフォルトのDockerfileが使用され、場合によっては失敗します。
（私の環境が悪い可能性もありますが未検証。確実なのは明示的にDockerfileを指定することかと。。）
Dockerfileを指定するためには、

```
$ docker build -t {ECRのリポジトリ名} -f {Dockerfileへのパス} .
```

の形式で打つ必要があります。

#ELB作成
実はECSのクラスターを作る際にELBを指定するところがあります。
なので使う場合はあらかじめ作っておくと楽。
普通の手順で作ればいいですが、タスクへの接続はIPで行われるため、ターゲットグループの「Target Type」に「IP」を指定する必要があります。

#ECS上に動作環境を作成
ECSは登場人物が多い。。
下記の順に作ります。

1. クラスターを作成
1. タスク定義を作成
1. １で作ったクラスターの中に、２で作ったタスク定義を使用するサービスを作成

ざっくりコンテナ＝タスクみたいなもので、それを立ち上げるのが「サービス」、そのサービスをまとめるのが「クラスター」という関係になってます。
「サービスの作成」はクラスター内でないとできない仕様なので一番初めにクラスターを作る必要があります。

##クラスターを作成
難しい設定はないのでさくっと行って大丈夫です。
迷うのはクラスターテンプレートの指定くらい？

##タスク定義の作成
ここで
・起動元のイメージをECRリポジトリで指定
・コンテナメモリの割り当て
・.envに指定する変数の指定
を行います。
これも決まっていればぽちぽち打ち込むだけ。

##サービスの作成
ここでは
・使用するタスク定義の指定
・クラスターの指定
・オートスケールの指定
・ヘルスチェックの猶予時間
・タスクを配置するサブネットの指定
を行います。
さらにロードバランサーを使用するなら、ロードバランサーの指定も必要。
一応あらかじめサブネットを複数作成したので、それらを指定してマルチAZにしました。

##タスクが立ち上がるか確認
ここまでできたら自動でタスクが立ち上がるはず。
いけるかどうか見守りましょう。

##立ち上がらない時
起動時に何かしらのエラーがあると自動停止し、ステータスがRUNNING=>STOPPEDに変わります。
今回多かった原因は

・ヘルスチェックの失敗
・nginxの設定周りのエラー

STOPPEDになったタスクのIDをクリックすると落ちた原因がみれるのでそれをみて対処します。
必要に応じて「Logs」タブからログも確認します。

###ヘルスチェックの失敗
まず真っ先に確認するのはセキュリティグループの設定。
ELBが弾かれていると落ち続けます。

許可しており、たまに成功するくらいならUnHealthyになる条件が厳しすぎる可能性があるので少し緩めてみます。

###nginxの設定周りのエラー
今回一番ハマった原因。
イメージ指定を間違っていたために変なconfファイルが使われたようでひたすらエラーが出てました。

#インターネットでのアクセス確認
ここまで来たらあとはRoute53か何かのDNSで、ECSに紐づけたELBを指定します。
これでECSにアクセスできるはず。

#まとめ
コンソールでの設定事項が非常に多い。。
これが一番疲れました。
下記注意点です。

- コンソールでの設定事項が非常に多いのでよくセッション切れになります。
    - 予め作成できるものは作っとくこと。
- タスクが立ち上がらない時は先に原因を切り分けること。関係する要素が多すぎて全部見ると終わりません。
Couchbase Server 機能解説 XDCR(Xross Data Center Replication) 入門編

### XDCRは、何故必要か？

XDCRは、Couchbase　Serverクラスター間でデータを複製するために使用されるテクノロジーです。
XDCRを使用すると、ベアメタル、VM、プライベートクラウド、パブリッククラウド、ハイブリッド、コンテナなどのプラットフォームに関係なく、任意のCouchbase Serverクラスター間でデータを複製できます。


### XDCRは、どのように動作するか？

XDCRは非同期レプリケーションによる結果整合性を介して、サイト間でデータの一貫性を維持します。

XDCRは、クラスター内部の構成変更に対して透過的に動作します。計画的ないし障害によるノードの追加・削除（トポロジー変更）中であっても、マニュアルの対応は不要であり、継続して動作し続けます。

Couchbase　Serverは、「データベース変更プロトコル（DCP）」と呼ばれるストリーミングプロトコルを持ち、順序付けられたキューを使用してデータの変更を通信します。XDCRはDCPのコンシューマーであり、DCPに依存しています。


### 機能ハイライト

#### チェックポイントによるレプリケーション中断・再実行制御

XDCRは、レプリケーション実行中、一定の間隔で、チェックポイントを更新します。レプリケーションの中断後、XDCRは最後のチェックポイントからレプリケーションを再開します。これには、ユーザーによる計画的な実行、または障害からの回復のケースが考えられます。

チェックポイント更新の間隔が短いほど、チェックポイントの精度が高くなり、レプリケーションの再開に必要な作業量が少なくなります。一方、頻繁なチェックポイントの更新はシステムリソースを使用し、パフォーマンスに影響を与える可能性があります。


#### 複数のレプリケーション間の優先度設定

（あるバケットについて）レプリケーションが実行されている環境で、新しく（別のバケットのために）新規レプリケーションを追加するようなケースでは、新規レプリケーションの実行が、既存のレプリケーションのスループットに悪影響を与える場合が考えられます（例えば、既存レプリケーションでは差分データ更新が行われているのに対して、新規レプリケーションでは全件データのレプリケーションが一斉に実行されることにより）。XDCRでは、レプリケーションに対して優先度を設定することができ、このようなケースにおいても、優先度に基づいて適切なリソース配分を実現することが可能です。

#### ネットワーク帯域幅節約のための最適化

XDCRは、データ圧縮のような内部機構や、ユーザーにより設定（例えば、高度な設定として提供されている「オプティミスティックレプリケーション」）を介して、ネットワークの帯域幅を節約するために高度に最適化されています。


#### レプリケーション対象データのフィルタリング

Couchbase Serverのエンタープライズエディションでは、レプリケーションの対象とするデータを、ユーザがデータの内容などに応じてフィルタリングするための方法（レプリケーションフィルター）が用意されています。

注意：コミュニティエディションでは、この機能は利用できません。

### 運用上の注意

XDCR処理は、Dataサービスが稼働しているノードで実行されるため、多かれ少なかれDataサービスに対する性能影響があります。適切にリソース見積もりが行われることが重要ですが、特に既存のサービス運用中のクラスターで、新たにXDCRを利用する要件が生まれた際には注意が必要です。典型的なケースとして、データセンターのマイグレーションが考えられます。状況に応じて、マイグレーションのためにデータのレプリケーションを行う期間、一時的にノードを追加し、クラスターを拡張するといった対応も考えられます。

**参考情報**

[Understanding Cross Datacenter Replication (XDCR) – Part 1](https://blog.couchbase.com/understanding-xdcr-part-1/)


[XDCR Advanced Settings](https://docs.couchbase.com/server/current/xdcr-reference/xdcr-advanced-settings.html)
システム環境設定の省エネルギーのディスプレイをオフにするまでの時間を変更する

MACのシステム環境設定の省エネルギーで、
ディスプレイをオフにするまでの時間を変更する方法

オプション：-a (バッテリー駆動、電源駆動のどちらに対しても)
設定項目：displaysleep
設定値：60（分）

```
echo 'ここはSudoパスワードを設定' | sudo pmset -a displaysleep 60 2>/dev/null
```
STM32F103C8と温度,S-5851で液晶温度計 (Arduino)(AQM0802A)


x プログラムは、unoと同じ
x ハードは、BluePill 設定は、BluePillF103C8 


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

I2C1 SDA-PB7-B7 -> SDA
I2C1 SCL-PB6-B6 -> SCL



```c++


#include <Wire.h> //I2C library

//STM32G031J6M6
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

// I2C temperature sensor - see table 1 of data sheet.  Resistor selects address. 
#define S5851A  0x48
#define I2Cadr  0x3e  // 固定

int     tempval;                //温度
char    data_read[2]={'@','t'}; //i2cバッファー
int     ii;                     //ループカウンター

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

void i2c_led_w(char *buff1){
  Wire.beginTransmission(I2Cadr);
  Wire.write(buff1[0]);
  Wire.write(buff1[1]);
  Wire.endTransmission();
  delay(2);
}//i2c_led_w

void setup()
{  
  delay(3000); //not delete  //031

  //i2cの初期化
  Wire.begin(); // initialise the connection //767 UNO
  //Wire.begin(sdaPin,sclPin); //STM32G031J6M6

  //液晶の初期化
  for(ii=0;ii<11;ii++){
    i2c_led_w(&INIT_com[ii*2]);
  } //for

} //end setup

void loop()
{

  //画面のクリア
  i2c_led_w(INIT_cls);

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  tempval = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    tempval = (int)Wire.read(); // 1バイトを受信
  }//while

  //液晶に表示
  data_read[1] = '0' + (tempval / 10);
  i2c_led_w(data_read);
  data_read[1] = '0' + (tempval % 10);
  i2c_led_w(data_read);

  delay(1000); //1秒待つ
}//loop




```
[暫定]WindowsUpdateのエラー解消

# [暫定]WindowsUpdateのエラー解消

## 背景

社有PCをテレワーク用として貸与していただいていました。
ところが、WindowsUpdateで「一部の設定は組織によって管理されています」となり、実行できません。

とある検証のためにWSL2(Windows Subsystem Linux 2)をインストールしたかったのですが、WSL2はWindows10をバージョン 1903 以降、ビルド 18362にしなければならないのです。

ですが、WindowsUpdateが動かないのでは．．．

## 目標

設定を変更し、なんとかWindowsUpdateを実行可能にする。

## 手順

WSUSの設定がイントラネット上のサーバを指している可能性があります。
グループポリシーにそれらしい設定がありそうですが、何故か未構成の状態でした。
おそらくレジストリのどこかにWSUSの設定がされていると思われますが、闇雲にいじるのも怖いので、今回はこのグループポリシーを弄って解決させました。

スタートメニューを右クリック
　　└ファイル名を指定し実行
 　　　　└gpedit.msc

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/a881faa7-ece4-e952-1d3e-22134830ca8e.png)

ローカルコンピューターポリシー
　　└コンピューターの構成
　　　　└管理用テンプレート
　　　　　　└Windowsコンポーネント
　　　　　　　　└WindowsUpdate

以下の二つのポリシーが怪しいと思ったのですが、残念ながら未構成でした。
しかし今回はこの設定を意図的に「無効」に変更しました。

・イントラネットのMicrosoft更新サービスの場所を指定する
・インターネット上のWindowsUpdateに接続しない

その後、WindowsUpdateを確認したところ、エラーは解消され、実行し始めました。

## おわりに

正規の手順ではなかったかもしれませんが、なんとかWindowsUpdateが実行されました。
現在のバージョンが1809だったので、更新が適用されるまでかなり掛かりそうです。
気長に放置し適用します。

このPCはいずれは社に返却しなければならないので、WSL2の構築が終わったらこのポリシーはもとに戻しておこうと思います。
本当はUbuntuとのデュアルブートにしてしまいたかったのですが．．．
流石にそれはやりすぎかと思い今回はやめておきました。
現実世界で完全な削除(DELETE)は存在しない

Webアプリケーションの概念の1つのCRUD処理
### CRUD処理
| -    | - | - |
| ---- | ------ | ------------------ |
| C    | CREATE | タレントを作成する |
| R    | READ   | タレントを閲覧する |
| U    | UPDATE | タレントを更新する |
| D    | DELETE | タレントを削除する |

今回、着目したいのはDELETE、削除する処理。

**注意しないといけないのは、完全に削除することは現実世界ではありえない**
例えば、タレントが退会したという処理をおこなうときに安易にタレントをDELETEして完全に削除してしまうと、退会したという情報は取得できない。

現実を抽象化したデータを忠実に再現するためにはDELETEは実行しない方がいい。
タレントを安易に削除するというのは、タレントが複業クラウドを使っていたという事実を削除することに値する。

ではどうやって実装するか？

### **論理削除**
データベースから直接データを削除せず、削除フラグまたは削除日時を更新して退会を表現。

**users**

|  id  | name　　   |
| ---- | ------ |
| 1    | たなか |
| 2    | さとう |
| 3    | おだ   |



```sql
-- 通常の削除(物理削除)
DELETE users  WHERE users.id = 3

-- 論理削除
UPDATE users SET deleted_at = '2021-06-25 06:43:21' WHERE users.id = 3
```
**通常の削除(物理削除)**

|  id  | name　　   |
| ---- | ------ |
| 1    | たなか |
| 2    | さとう |


**論理削除**

| id   | name   | deleted_at           |
| ---- | ------ | ------------------- |
| 1    | たなか |                     |
| 2    | さとう |                     |
| 3    | おだ   | 2021-06-25 06:43:21 |


#### メリット

- 退会したユーザを取得するのが簡単

```sql
SELECT * FROM users WHERE deleted_at IS NOT NULL;
```

#### デメリット

- 表示時にWHERE句にフラグの確認が必要になる(バグの原因。アクティブなユーザを取得したい)

```sql
-- 削除したユーザまで取得してしまう、、、。
SELECT * FROM users;
```

- データが肥大化するため、パフォーマンスが落ちる



### 削除のタイミングで履歴テーブルに移す


```sql
INSERT INTO deleted_users SELECT users WHERE users.id = 3
DELETE users WHERE users.id = 3
```

**deleted_users**

|  id  | name　　   |
| ---- | ------ |
| 3    | おだ |


**users** 

|  id  | name　　   |
| ---- | ------ |
| 1    | たなか |
| 2    | さとう |


#### メリット

- SELECTで論理削除を意識しなくてよくなる

```sql
-- ユーザだけ取れる
SELECT * FROM users;
```

#### デメリット

- 2つのテーブルを行ったり来たりする必要がある(めんどくさい、、。)
- 関係テーブルも履歴を作る必要があり、複雑になる


### 結論
正解はない。
削除(完全消滅)というのは現実世界に存在しない概念なので、DELETE処理を実装する際は注意！！
メリット・デメリットを考慮して実装する必要がある。



▼複業でスキルを活かしてみませんか？複業クラウドの登録はこちら！
https://talent.aw-anotherworks.com/?login_type=none
【覚書】Laravelでファサードを作る方法

毎度忘れては調べて作っている上に、なかなか正解に辿り着けないので覚書です。

# 手順

## 準備

適当にクラス作ります

```php:app/Http/Controllers/hoge.php
class hoge
{
    public function byTen($num)
    {
        return $num * 10;
    }
}
```

## ファサードの派生クラス作成

```php:app/Facades/hoge.php
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class hoge extends Facade
{
    protected static function getFacadeAccessor(){
        return 'hoge';
    }
}
```

## サービスプロバイダ作成

```php:app/Providers/hogeServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class hogeServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
      //
      $this->app->bind(
        'hoge',
          'App\Http\Controllers\hoge'
      );
    }
}
```

## Configに登録

```php:config/app.php
（略）
'providers' => [
    App\Providers\hogeServiceProvider::class,
]
（略）
'aliases' => [
    'hoge' => App\Facades\hoge::class,
]
```

## キャッシュクリア

```console:console
php artisan optimize:clear
```
俺のFigma

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E4%BF%BA%E3%81%AEFigma/)をご覧ください😀


figma初心者向けのメモ。

オートレイアウトを駆使するのがとにかくおすすめ。

1. グループ化
2. オートレイアウト
3. オートレイアウトで位置調整

を繰り返していくとよさげ。

# Tips

## グループの中の要素を選択したい
command押しながらクリック

## グループ化
command + g

## グループ化＆オートレイアウト
shift + a

## コンポーネント化
option + command + k

※コンポーネントをコピペして親をいじると子も変わる

## 複製
command + d
コピペ（command + c → command + v）と同様

## 横中央揃え
option + h

## 縦中央揃え
option + v

## shift + カーソル による移動量を変更する

Small nudge: 1
Big nudge: 8
がおすすめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/d705b0f5-5c31-96bc-00b8-d28392f47674.png)

# FAQ
## コピペすると同じ場所に重なる問題

レイヤー選択してペーストすると、そのレイヤーの中に貼り付けれる

## なぜオートレイアウトがおすすめなのか

例えば中のコンポーネントを一部消したいとなったときに、非表示にすれば自動でレイアウトをきれいにしてくれる。

例）縦に8px間隔あけるよ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/b8c364df-2f03-7f8f-169e-48736ef4e852.png)

## frameのサイズを変更すると中身の要素つぶれる問題

command押しながらだとつぶれない
shift押しながらだと中身も拡大縮小

## 要素のmarginとか知りたい
option押しながらカーソルのせると見れる

## 共通パーツ、１箇所変えたら全部に反映させたい

コンポーネントを使う
親を変更すると子も変わる。子を編集していた場合その箇所は変わらない。

## 上下にラインがあるコンポーネントを並べる時
重なる部分はラインが２重になるので太くなっちゃう。
ので子は上のラインだけ削除してあげるとよい。
ちなみに子で要素を削除しても非表示になってるだけで実際は残っている。（論理削除的な感じ）

## 表作るとヘッダーと中身の行で頭が揃わずガタガタになる

オートレイアウト使っていても、中身の文字数によってガタガタしてしまう。
そんなときは項目の横幅を決めてやる。
Yarnでerror Command failed with exit code 127. が出たときの対処法

## 状況
git cloneでNuxtのリポジトリを持ってきたのでyarn devでテストサーバーを立てようとしたら以下のようなエラーが発生

```
/bin/sh: 1: nuxt: Permission denied
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command
```

##　解決法

```
yarn install
```


すれば動きました。パッケージのインストールを忘れてたみたいです。Gitのをcloneして動かす場合は忘れがち
【Docker】開発環境のみをDockeriseする。no.18

![パンプキン カフェ (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4c0af6a3-5233-dc43-c727-bc6eff6934d5.png)


こんにちは。まゆみです。

Dockerについての記事をシリーズで書いています。

今までの記事では、Webアプリのソースコードや、コードの実行に必要な開発環境を<font color="Red">含めて</font>Dockerizeする方法を書いてきました。(下の図で言えば、左側のようなContainer)

![Container (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/80eef285-9e11-a14a-3b62-1829223bba86.png)


今回の記事では、『必要な開発環境<font color="Red">のみ</font>』 をDockerizeする方法を書いていきます。



また、そのように開発環境のみを整えるContainerを作ることがどのような場面で役立つのかということも合わせて書いていきます


今回の記事では、『node.js』を使った環境構築を例に出して記事を書いていますが、node.js以外でアプリを作る時も応用できる内容になっていると思います。

私自身、Laravelは使った事がないのですが、Laravelって環境構築だけでも色んな工程があってかなり面倒くさいみたいですね。


色々なところに応用していただければ嬉しいです。


ではさっそく始めていきますね。

#どうして開発環境のみのContainerを作るのか？

Containerの最大のメリットの1つは、あなたが作ったDockerfileを人に渡すことができ、<font color="Red">人それぞれどんな環境を使っていたとしてもすぐに開発環境が整うこと</font>ですよね。

ローカル環境にnodeがインストールされていない人もすぐに開発環境が整うように、ローカルではなく、Contianerで開発環境を整える方法があれば、何かと便利ですよね。


#Containerの中でnpm を初期化する方法

では、ローカルではなく、『Containerの中』でnpm を初期化して、package.json を作ってみます。

２つやり方があるので順番に説明していきますね。

##①初回Containerを実行するとき

まだrunしたことがない、初めてのイメージをrunする時は、実行するときに下記のようなコマンドで実行してみてください。

```
docker run -it <Image> <上書きしたいコマンド>
```

コマンドの最後に<上書きしたいコマンド>をつけて実行する事で、<font color="Red"><Imageのデフォルトのコマンドの代わりに <上書きしたいコマンド> の方が代わりに実行/font>されます。


今回は、『node』というイメージのデフォルトのコマンドを<font color="Red">『npm init』に上書きし</font>て実行してみましょう。

ローカル環境でnpm initをする時を思い出してもらえば分かると思いますが、npm init と打ち込むと、package.jsonに書き込む内容に沿った質問(?)がされますよね。


<font color="Red">質問の答えをターミナルに書いて返したいので『-itオプション』もつけて実行</font>します(-itオプションを付けて実行するとターミナルにコマンドなどを打ちこむことができます)


具体的なコマンドは下記のようになります

```
docker run -it node npm init
```

実行結果は下のようになります

![2021-06-25_9-03-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3e265df4-6d06-cab6-086e-1e8a4461609d.png)

##実行中のContainerに重ねてコマンドを実行したいとき

今、イメージnodeでrunさせた<font color="Red">実行中のContainer</font>があるとします(docker ps -aで表示させた時STATUSがUPになっているContainerのことです。)

そのContainerに『後から』コマンドを上書きして実行させたい時はrun の代わりに『exec』を使います。


```
docker exec -it <ContainerID or Name> npm init
```

![2021-06-25_9-17-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/29e8fc9f-e7f0-6901-4fbb-f46b7418d638.png)

#Dockerfile を書く

では、次にあなた自身のイメージを作るためのDockerfileを書いていきましょう

```
FROM node:14-alpine

WORKDIR /app
```

ベースとなるイメージは、nodeのイメージのなかの軽量のバージョンの物を選びます

その後WORKDIR /appを書き、Container内のどこでコマンドを実行するのか指定します



#バインドマウントをする

Dockerfileを上記のように書いた後、バインドマウントをしてContainerを実行してみます


```
docker run -it -v $(pwd):/app <Image> npm init
```

バインドマウントをして実行する事で、Container内で作ったものが、ローカルホストに反映されます。


![2021-06-25_9-54-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3c65afd1-0eb2-8062-2a82-997bf6a0fdeb.png)

上記のように実行した後に、ローカル側を見てみるとpackage.jsonを見ることができます


![2021-06-25_9-56-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/5ff04af6-0eb4-828a-4df3-d27b143c941e.png)

このように、Dockerにnodeの開発環境を整えることで、

>ローカルホスト側にnodeがインストールされていなくても

ローカル側で開発を進めていくことができます。

#まとめ

今回の記事はこの辺で締めくくらせていただきます。

お役に立てれば幸いです。
【AWS小技】CognitoのFORCE_CHANGE_PASSWORDをマネジメントコンソールだけでCONFIRMEDに変える

Cognitoのユーザーを作成すると、初期状態でFORCE_CHANGE_PASSWORDになっていますよね。
これをCONFIRMEDにするには、AWS CLIが必要で少々面倒です。

実はマネジメントコンソールだけでCognitoのFORCE_CHANGE_PASSWORDをCONFIRMEDに変えることができますので方法を紹介します。

# 前提
- マネジメントコンソールにログインできること
- Cognitoユーザープールがあること

# 方法
## ユーザーの作成
Cognitoでユーザーを作成します。FORCE_CHANGE_PASSWORDになっていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/28147a4b-7e94-a047-1a14-d0024a0df0c4.png)

## アプリクライアントの作成
アプリクライアントを作成します。
アプリクライアント名を入力して、クライアントシークレットを生成はオフにしておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/f9dc83bb-d3ff-9455-cf72-9035d7d7cd28.png)


## AppSyncの作成
おもむろにAppSyncをひとつ作成します。
「一から構築」を選んでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/d2d3c777-30d0-374e-365c-448d56755ba3.png)

## デフォルトの認証モードの変更
AppSyncのデフォルトの認証モードで、作成したユーザーの存在するユーザープールを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/0466dfc0-9c11-7c07-5ada-fe083c1ac287.png)

選択したあとは右下の保存ボタンを押します。

## クエリ画面でログインする
クエリ画面に遷移して、「ユーザープールでログインする」ボタンを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/e34120f8-648f-d259-a28b-9a22e3feb8e2.png)

そのあと、先程作成したアプリクライアントIDを選択して、ユーザーのIDと初期パスワードを入力してログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/956e8950-c1f8-3f35-4bf5-73f5568b5dc9.png)

## パスワードを変更する
ログインが成功するとパスワードを変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/47842b4a-47e5-fc23-1347-e5b91fff8e8e.png)

## 確認
再度Cognito画面をリロードしてみてみるとCONFIRMEDになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/dd27b933-fe76-b56e-3b74-9b9c1ec72ff0.png)

#CLIとどちらが面倒かどうかは…。
よいAWSライフを。
カウントソート（Counting Sort）

カウントソート（Counting Sort）の中核は、入力データ値をキーに変換し、それらを追加の配列スペースに格納することです。 一種の線形時間計算量として、カウントソートでは、入力データが特定の範囲の整数である必要があります。

カウントソートは、安定したソートアルゴリズムです。 カウントソートでは、追加の配列Cが使用されます。ここで、i番目の要素は、値がiに等しいソートされる配列A内の要素の数です。 次に、配列Cに従って、Aの要素を正しい位置に配置します。 整数のみをソートできます。

## 8.1 アルゴリズムの説明
* 並べ替える配列内の最大要素と最小要素を見つける。
* 配列内の値iを持つ各要素の出現回数をカウントし、配列Cのi番目の項目に格納する。
* すべてのカウントを累積する（Cの最初の要素から開始して、各アイテムが前のアイテムに追加される）。
* ターゲット配列を埋め戻す：各要素iを新しい配列のC（i）アイテムに配置し、要素を配置するたびにC（i）から1を減算する。

## 8.2 可視化デモ
![CountingSort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/f1502069-644c-5889-54ca-85176a847f8b.gif)

## 8.3 実装

```java
    /**
     * Counting Sort
     *
     * @param array
     * @return
     */
    public static int[] CountingSort(int[] array) {
        if (array.length == 0) return array;
        int bias, min = array[0], max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max)
                max = array[i];
            if (array[i] < min)
                min = array[i];
        }
        bias = 0 - min;
        int[] bucket = new int[max - min + 1];
        Arrays.fill(bucket, 0);
        for (int i = 0; i < array.length; i++) {
            bucket[array[i] + bias]++;
        }
        int index = 0, i = 0;
        while (index < array.length) {
            if (bucket[i] != 0) {
                array[index] = i - bias;
                bucket[i]--;
                index++;
            } else
                i++;
        }
        return array;
    }

```

## 8.4 性能評価
入力要素は[0, k]のn個の整数の場合、その実行時間はO（n + k）です。 カウントソートは比較ソートではなく、ソートの速度はどの比較ソートアルゴリズムよりも高速です。 カウントに使用される配列Cの長さは、ソートされる配列内のデータの範囲（ソートされる配列の最大値と最小値の差に1を加えたものに等しい）に依存するため、これによりカウントソートが行われます。広範囲のデータを持つ配列には大量の時間とメモリが必要です。

* 最良時間計算量：T(n) = O(n+k)  
* 最悪時間計算量：T(n) = O(n+k)  
* 平均時間計算量：T(n) = O(n+k)

***
バケットソート（Bucket Sort）

バケットソートは、カウントソートのアップグレードバージョンです。 関数のマッピング関係を利用しており、高効率の秘訣はマッピング関数の決定にあります。 バケットソートの動作原理：入力データが均一に分散されていると仮定すると、データは限られた数のバケットに分割され、各バケットは個別にソートされます（別のソートアルゴリズムを使用することも、再帰的に使用し続けることもできます）。バケットソートが実行される方法）。

## 9.1 アルゴリズムの説明

* 定長の配列を空バケットとして用意する。
* 入力データをトラバースし、データを1つずつ対応するバケットに入れる。
* 空でないすべてのバケットを並べ替える。
* 空ではないバケットからソートされたデータを連結する。

> バケットソートを再帰的に使用して各バケットをソートする場合は、バケット数が1のときに手動でBucketSizeを減らし、次のサイクルでバケット数を増やす必要があります。そうしないと、無限ループに陥り、メモリオーバーフローが発生します。

## 9.2 動作例
![bucketSort.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/5a2ad5fc-94f3-39ab-77f3-3c2de619d64f.png)

## 9.3 実装

```java
    public static ArrayList<Integer> BucketSort(ArrayList<Integer> array, int bucketSize) {
        if (array == null || array.size() < 2)
            return array;
        int max = array.get(0), min = array.get(0);
        // Find the maximum and minimum values
        for (int i = 0; i < array.size(); i++) {
            if (array.get(i) > max)
                max = array.get(i);
            if (array.get(i) < min)
                min = array.get(i);
        }
        int bucketCount = (max - min) / bucketSize + 1;
        ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
        ArrayList<Integer> resultArr = new ArrayList<>();
        for (int i = 0; i < bucketCount; i++) {
            bucketArr.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < array.size(); i++) {
            bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
        }
        for (int i = 0; i < bucketCount; i++) {
            // If there are duplicate numbers in the sorted array
            if (bucketSize == 1) {
                for (int j = 0; j < bucketArr.get(i).size(); j++)
                    resultArr.add(bucketArr.get(i).get(j));
            } else {
                if (bucketCount == 1)
                    bucketSize--;
                ArrayList<Integer> temp = BucketSort(bucketArr.get(i), bucketSize);
                for (int j = 0; j < temp.size(); j++)
                    resultArr.add(temp.get(j));
            }
        }
        return resultArr;
    }
```

## 9.4 性能評価

バケットソートの最良の場合は線形時間O（n）です。バケットソートの時間計算量は、他の部分の時間計算量がO（n）であるため、各バケット間のデータのソートの時間計算量に依存します。 明らかに、分割されるバケットが小さいほど、各バケット間のデータが少なくなり、並べ替えにかかる時間が短くなります。 ただし、対応する空間（メモリ）消費量は増加します。

* 最良時間計算量：T(n) = O(n+k)   
* 最悪時間計算量：T(n) = O(n+k)   
* 平均時間計算量：T(n) = O(n2)　　

* * *
基数ソート（Radix Sort）

基数ソートは非比較ソートアルゴリズムであり、各ビットを最下位ビットから順にソートします。複雑さは配列の長さであるO（kn）であり、kは配列の最大桁数です。

基数の並べ替えでは、最初に下位順に並べ替えてから収集し、次に上位に応じて並べ替えてから収集し、以下同様に上位に並べ替えます。 一部の属性には優先順位があり、最初に低優先度で並べ替えられ、次に高優先度で並べ替えられます。 最後の順序は、高い優先度が最初であり、同じ高い優先度を持つ低い優先度が最初です。 基数ソートは、個別のソートと個別の収集に基づいているため、安定しています。

## 10.1 アルゴリズムの説明
* 配列の最大数を取得し、桁数を取得します。
* arrは元の配列であり、各ビットは最下位ビットから取得されて基数配列を形成します。
* 基数のカウントとソート（小さな範囲の数値のカウントとソートの特性を使用）。

## 10.2  可視化デモ
![RadixSort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/90879807-fef0-f925-727c-dcbd4ebd7019.gif)

## 10.3 実装

```java
　　/**
     * Radix Sort
     * @param array
     * @return
     */
    public static int[] RadixSort(int[] array) {
        if (array == null || array.length < 2)
            return array;
        // 1.配列の最大数を取得し、桁数を取得します。
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            max = Math.max(max, array[i]);
        }
        int maxDigit = 0;
        while (max != 0) {
            max /= 10;
            maxDigit++;
        }
        int mod = 10, div = 1;
        ArrayList<ArrayList<Integer>> bucketList = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i < 10; i++)
            bucketList.add(new ArrayList<Integer>());
        for (int i = 0; i < maxDigit; i++, mod *= 10, div *= 10) {
            for (int j = 0; j < array.length; j++) {
                int num = (array[j] % mod) / div;
                bucketList.get(num).add(array[j]);
            }
            int index = 0;
            for (int j = 0; j < bucketList.size(); j++) {
                for (int k = 0; k < bucketList.get(j).size(); k++)
                    array[index++] = bucketList.get(j).get(k);
                bucketList.get(j).clear();
            }
        }
        return array;
    }

```

## 10.4 性能評価
* 最良時間計算量：T(n) = O(n * k)   
* 最悪時間計算量：T(n) = O(n * k)   
* 平均時間計算量：T(n) = O(n * k)

**基数で並べ替えるには2つの方法があります：**

* MSD 上位から並べ替え
* LSD 下位から並べ替え

## 基数ソート vs カウントソート vs バケットソート

これらの3つの並べ替えアルゴリズムはすべてバケットの概念を使用していますが、バケットの使用には明らかな違いがあります。

* 基数ソート：キー値の各桁に従ってバケットを割り当てます
* カウントソート：各バケットは単一のキー値のみを格納します
* バケットソート：各バケットは特定の範囲の値を格納します

***
Oracle プランスタビリティ アウトライン

今更ながら、アウトライン についてメモ

SQLを発行しているアプリを修正できないときでも SQL文に HINT句をつけたい場合に利用

ほとんどこちらのページのコピー
　http://ooltcloud.sakura.ne.jp/blog/201301/article_11220615.html
　ありがたく使わせていただきます。


## HINT なし SQL を登録

```sql
	alter session set create_stored_outlines = true;
	SELECT ～ FROM ～ ;
	alter session set create_stored_outlines = false;
```

既に実行済みのSQLを登録する場合は。。
SQL_ID から HASH_VALUE と CHILD_NUMBER を確認して、DBMS_OUTLN.CREATE_OUTLINE で登録する。
https://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_outln.htm

```sql
select SQL_ID, HASH_VALUE, CHILD_NUMBER from V$SQL WHERE SQL_ID = '12345abcdefgh';

SQL_ID        HASH_VALUE CHILD_NUMBER
------------- ---------- ------------
12345abcdefgh 1234567890            0
12345abcdefgh 1234567890            1


execute dbms_OUTLN.CREATE_OUTLINE ( 1234567890, 1 );
```



## HINT あり SQL を登録

```sql
	alter session set create_stored_outlines = true;
	SELECT /*+ ？？ */ ～ FROM ～ ;
	alter session set create_stored_outlines = false;
```

## アウトラインを確認

```sql
	select NAME, OWNER, USED, ENABLED, SQL_TEXT from dba_outlines; 
```

## アウトラインを入れ替え

```sql
	update outln.ol$hints
	   set ol_name = decode(ol_name,'HINTありのNAME','HINTなしのNAME','HINTなしのNAME','HINTありのNAME')
	 where ol_name in ('HINTありのNAME','HINTなしのNAME') ;
	commit;
```

## アウトラインを有効化

```sql
	alter system set USE_STORED_OUTLINES=TRUE;
```

## HINT なし SQL を実行して有効化を確認

```sql
	set autot on
	SELECT ～ FROM ～ ;
	set autot off
```	
結果の note 欄に outline の結果があること
	例）
		Note
		-----
		   - outline "HINTなしのNAME" used for this statement


# おまけ

直前に実行したSQLのSQL_ID を調べるときは

```sql
SELECT  *  FROM  TABLE( DBMS_XPLAN.DISPLAY_CURSOR() );
```

とすれば、SQL_ID を確認できる


-------
古いシステムだと色々使えなくて困る・・
さらに standard edition だとさらに困る・・:frowning2:
【Dr.Sum Datalizer】年月の項目「202004」⇒「2020/04」と表示したい


#目標
テーブルに「年月」がある、中身は YYYYMM の文字列（例：202105）。
Datalizerで「2021/05」って表示したい。
見せ方を変えるだけで、データは変わらない。

#前提
Datalizerの接続先はDr.Sumのテーブル／ビューです。

#経緯
「202105」でもまぁ悪くはないけど、より人にわかりやすいのは「2021/05」ということで、ちょいちょいご要望頂きます。

#手順
####データ書式に以下のように書けばOK
<font color="DeepPink">[FUNCTION:LEFT(4)||'/'||RIGHT(2)]</font>

意味：この項目、「左側から4文字　＋ '/' ＋右側から2文字」で表示します

####設定は複数の方法あり
（1）項目一覧 → フィールド詳細設定 から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/784da20b-532a-c4ba-aa3f-8a6101ebb142.png)

（2）集計項目設定 から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/a2bb93d1-cc01-869a-35ed-a61aac58b292.png)

####実例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/b770170f-53d4-e8d8-c62c-8336976d8e0b.png)

#つぶやき
よく使うのにすぐ忘れます･･･

以上
ダイエット＋食品管理アプリ構築の道程（２）

前回書きました上下で送るべきViewのフォームですが
簡単にまずシンプルに作ってみて挙動を確認してからしっかりと作り込んでいくこととします。

手順①frigeモデルを作る（子モデル）

```rb
rails g model fridge(モデルは単数形）
```

手順②frigesコントローラーを作る

```rb
rails g controller friges（コントローラーは複数形）
```

手順③cookingモデルを作る（親モデル）

```rb
rails g model cooking
```
手順④cookingsコントローラーを作る

```rb
rails g controller cookings
```

![20210625-130848.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/7ae195d2-3608-bddf-0f40-2780866f8cb5.png)

![20210625-130907.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/3d1492b0-ba37-3072-3e67-8aeeae378380.png)

手順⑤

```rb:(訂正前)cooking.rb
class Cooking < ApplicationRecord
  has_many  :fridge, dependent: :destroy

  accepts_nested_attributes_for :fridge
end
```

dependent：　：destroyで親が削除されると子も削除と行きたいが、
食材は買ってきたものは別に利用できるのでこのオプションは付けない。

```rb:(訂正後)cooking.rb
class Cooking < ApplicationRecord
  has_many  :fridge

  accepts_nested_attributes_for :fridge
end
```

~~acccept_nested_attributes_forの使用は断念~~
理由は非推奨のため
>https://moneyforward.com/engineers_blog/2018/12/15/formobject/
>https://tech.recruit-mp.co.jp/server-side/rails-development-policy/

次回からFormオブジェクトでいきます。
Railsにおける真偽判定いろいろ（present? / blank? / empty? / nil? / any? / all? / zero? / ActiveRecord::Type::Boolean）

Ruby, Railsにはnilやブランク、その他ブロック条件の真偽値判定を行うメソッドがかなりあります。ついつい無思考に present?やblank?を使ってしまいがちですが、使い分けることでより明示的になるかなと思ってます。

## 真偽判定いろいろ

- present?（Railsのみ）
- blank?（Railsのみ）
- empty?
- nil?
- any?
- all?
- zero?
- ActiveRecord::Type::Boolean.new.cast

### present? と blank?
`present?`は`！blank?`と同じ。
https://github.com/rails/rails/blob/d66e7835bea9505f7003e5038aa19b6ea95ceea1/activesupport/lib/active_support/core_ext/object/blank.rb#L23

```ruby
"".present? #=> false
[].present? #=> false
{}.present? #=> false
nil.present? #=> false

# 配列の要素はnilでも存在してると判定される
[nil].present? #=> true
```

`present?`が true の時はレシーバを返し、falseの時はnilを返したい時は`presence`が使える。

```ruby
a = "hoge"
b = a.presence
# これと同じ
b = a.present? ? a : nil
```

### empty? と nil?
~~`blank? = empty? + nil?`のこと。~~ 訂正。blank?のtrue判定はより広く、これはよくある誤解なので注意。詳しくはコメント参照。@scivolaさんありがとうございますm 
`empty?`はnilには呼べない。nilのハンドリングはちゃんとやれってことか。それが面倒なら blank?を使えと。ちなみに、`nil?`は Object#nil?なので、全クラスのインスタンスで使える。

```ruby
"".empty? #=> true
[].empty? #=> true
{}.empty? #=> true
nil.empty? #=> NoMethodError

nil.nil? #=> true
```

### any? と all?
`any?`は配列やハッシュに対して、条件一致する要素が**少なくとも一つはあるか**判定する。基本的にはブロックを渡して使う（正規表現も渡せる）。`all?`は**全部条件を満たすか**判定する。

```ruby
[1, 2, 3].any? { |i| i > 3 } #=> false
[1, 2, 3, 4].any? { |i| i > 3 } #=> true
[1, 2, 3, 4].all? { |i| i > 3 } #=> false
[1, 2, 3, 4].all? { |i| i < 5 } #=> true

{ name: "taro", age: 20 }.any? { |k, v| k == :name } #=> true
```

### zero?

0 かどうか判定するメソッドまであったりする。Numeric#zero?なので、IntegerやFloatなどのNumeric以外には使えない。

```ruby
0.zero? #=> true
```

### ActiveRecord::Type::Boolean.new.cast
true / false 判定は、`"true" / "false"`のように文字列になると正しく行われない。`ActiveRecord::Type::Boolean`を使うとこの辺もよしなにやってくれる。もちろん Rails だけ。

```ruby
ActiveRecord::Type::Boolean.new.cast("false") #=> false
```

全部 boolean になるわけではなく、戻り値は true/false/nil。

```ruby
# false判定されるもの
false, 0, "0", :"0", "f", :f, "F", :F, "false", :false, "FALSE", :FALSE, "off", :off, "OFF", :OFF

# nil判定されるもの
nil, ""
```

https://github.com/rails/rails/blob/main/activemodel/lib/active_model/type/boolean.rb#L16

## おまけ

### ||= と &.

`||=`は nil ガードと呼ばれ、左辺が falsy な値だった場合だけ右辺が評価される。

```ruby
a = nil # falseでも同じ
a ||= "hoge"
p a #=> "hoge"

a ||= "foo"
p a #=> "hoge" 再代入されない
```

`&.`はぼっち演算子と呼ばれ、続けてメソッドを呼び出して使う。レシーバが nil だった場合、強制的に nil を返す。

```ruby
nil.upcase #=> NoMethodError
nil&.upcase #=> nil
```

## 感想

個人的にはこれらのメソッドはあんまり好きじゃなくて、`==`とかで明示的に書く方が好きだけど、確かにシンプルに書けるので、使い所は選んでいきたいですね！
【SharePointOnline】"はい/いいえ" 列の表示を「選択薬(Choice pills)」にする

列の種類の「選択肢 (メニューから選択)」型の書式設定にある「選択薬(Choice pills)」の表示を真似した JSON です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/5f93ee9a-7852-a952-ba84-451b6df3a1e1.png)

```json
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "style": {
    "flex-wrap": "wrap",
    "display": "flex"
  },
  "children": [
    {
      "elmType": "div",
      "style": {
        "box-sizing": "border-box",
        "padding": "4px 8px 5px 8px",
        "display": "flex",
        "border-radius": "16px",
        "height": "24px",
        "align-items": "center",
        "white-space": "nowrap",
        "overflow": "hidden",
        "margin": "4px 4px 4px 4px"
      },
      "attributes": {
        "class": "=if(@currentField, 'sp-css-backgroundColor-BgMintGreen', 'sp-css-backgroundColor-BgCoral sp-css-borderColor-CoralFont')"
      },
      "children": [
        {
          "elmType": "span",
          "style": {
            "font-size": "12px"
          },
          "customRowAction": {
            "action": "setValue",
            "actionInput": {
              "<列の内部名を指定>": "=if(@currentField, '0', '1')"
            }
          },
          "attributes": {
            "iconName": "=if(@currentField, 'CheckboxComposite', 'Checkbox')",
            "class": "=if(@currentField, 'sp-css-color-MintGreenFont', 'sp-css-color-CoralFont')"
          }
        },
        {
          "elmType": "span",
          "style": {
            "overflow": "hidden",
            "text-overflow": "ellipsis",
            "padding": "0 3px"
          },
          "txtContent": "=if(@currentField, 'はい', 'いいえ')",
          "attributes": {
            "class": "=if(@currentField, 'sp-css-color-MintGreenFont', 'sp-css-color-CoralFont')"
          }
        }
      ]
    }
  ]
}
```
siim-covid19-detectionコンペの画像読込方法

#背景
kaggleのsiim-covid19-detectionコンペの画像読み込み方法がよくわからなかったので、調べたログです。環境はGoogle Colaboratoryを使用しています。
また、データをkaggle APIで取得する部分は以下の記事にまとめています。
記事名：kaggleコンペのデータ取得 (Google Colaboratory)

#実施内容

```bash
#pydicomのインストール
!pip install pydicom
```

```py
指定ファイルの読込
import pydicom
%cd /content/drive/My Drive/data/kaggle/siim-covid19-detection/
example_file = pydicom.dcmread("3fadf4b48db3.dcm")
example_image = example_file.pixel_array
```
```py
データの表示
from matplotlib import pyplot as plt
plt.imshow(example_file.pixel_array)
```
OBS用Agoraプラグインのビルド方法

##はじめに
OBS用のAgoraプラグインが[Github](https://github.com/AgoraIO/OBS/tree/agora-tool-ui-3.3.0)に公開されています。

**従来はOBSに組み込む形でのサンプルコードが提供されていましたが、プラグイン方式に方向転換されました。
これにより、既存のOBSがインストールされているPCにカジュアルに導入することができます。
又、ビルド済みのインストーラーも公開されているので、カスタマイズが不要な場合はそのまま利用できます。**

この記事ではビルド方法について解説します。

##前提
フォルダ構成は以下をベースにしています。
C:¥OBS
　 |-¥obs-studio //OBS
　 |-¥OBS-agora-tool-ui-3.3.0 //Agoraプラグイン

##OBSのビルド
事前準備としてOBSのビルド作業が必要になります。
ビルド方法は[OBS公式](https://obsproject.com/wiki/install-instructions#windows-build-directions)を参照ください。

##Agoraプラグインのビルド


1.ソースコードの入手
[こちら](https://github.com/AgoraIO/OBS/tree/agora-tool-ui-3.3.0)からソースコードを入手します。

2.不足ファイルのコピー
Configureの際、そのままだとエラーが発生するので不足ファイルをコピーします。
¥obs-studio¥¥cmake¥externalを¥OBS-agora-tool-ui-3.3.0直下にコピーします。
パスは以下のようになります。
¥OBS-agora-tool-ui-3.3.0¥external
また、AgoraSDK等の依存ファイルも[こちら](https://github.com/AgoraIO/OBS/releases/download/3.3.0/deps.zip)からダウンロードしてdepsフォルダに上書きします。
¥OBS-agora-tool-ui-3.3.0¥deps


3.CMakeLists.txtの修正
デフォルトのままだと、VisualStudioでビルドする際にエラーが発生するので
¥OBS-agora-tool-ui-3.3.0¥CMakeLists.txtを修正します。

```text:CMakeLists.txt
if (WIN32)
	include_directories(
			"${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api"
			${Qt5Core_INCLUDES}
			${Qt5Widgets_INCLUDES}
			"${CMAKE_SOURCE_DIR}/deps/Agora/include"
			"${CMAKE_SOURCE_DIR}/deps/libyuv/include"
			"${CMAKE_SOURCE_DIR}/deps/curl/include") //追記
//中略
		"${CMAKE_SOURCE_DIR}/deps/Agora/${AGORA_ARCH}/agora_rtc_sdk.lib"
		"${CMAKE_SOURCE_DIR}/deps/libyuv/${AGORA_ARCH}/yuv.lib"
		"${CMAKE_SOURCE_DIR}/deps/curl/${AGORA_ARCH}/libcurl.lib") //追記

```

4.Cmake GUIでConfigureを実行
以下の4つのパスを指定します。
QTDIR：QTのパス
（例：C:¥Qt2015_64¥5.15.2¥msvc2019_64)
LIBOBS_INCLUDE_DIR：OBSのソースディレクトリ直下のlibobsフォルダのパス
（例：C:¥OBS¥obs-studio¥libobs）
LIBOBS_LIB：OBSをビルドしたディレクトリ直下のlibobsフォルダのバス
（例：C:¥OBS¥obs-studio¥build¥libobs）
OBS_FRONTEND_LIB：OBSをビルドしたディレクトリUI以下のobs-frontend-apiフォルダのバス
（例：C:¥OBS¥obs-studio¥build¥UI¥obs-frontend-api）

5.１回目のConfigureでエラーが発生するので再度設定し実行
LibObs_DIRの項目にC:¥OBS¥obs-studio¥libobsを指定します。

6.Generateを実行し、OpenProjectでVisualStudioを起動

7.VisualSatudioでソリューションのビルドを実行
ビルドが成功したら以下のフォルダにプラグインが生成されます。
¥OBS-agora-tool-ui-3.3.0¥release
 |-¥bin
 |-¥data
 |-¥obs-plugins
これらのファイルを既存のOBSフォルダにコピーするとAgoraへの配信機能が利用できます。
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/dcec354b-69e7-3035-b730-b5d7f2b11376.png)


##最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=6b46c18787179ad59b2e)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=6b46c18787179ad59b2e)
使えると便利！Swiftでmap,filter,reduceを使えるようになろう！

# 使えると便利！Swiftでmap,filter,reduceを使えるようになろう！
チュートリアルで```map```  ```filter``` ```reduce``` が使われていて、その瞬間わからなくなったことないですか？
僕はチュートリアルでこれらの関数が出てきて、わからなくなりました。
しかし、どんどん勉強していくと ```map```  ```filter``` ```reduce``` って意外と使えるんじゃない？と思い始めます(実体験)。
そして、次の段階になると、無理矢理でも ```map```  ```filter``` ```reduce``` を使いたくなります(笑)

今回は僕が最初に ```map```  ```filter``` ```reduce``` に関する記事を見たときに、この情報だけほしいと思ったことをシンプルに書きます。
そのため、もっと説明が欲しい方は別の詳しく書かれている記事を探してください。

## map: 配列の各要素に、何らかの処理を適用したいときに使おう(戻り値あり)
```map``` は配列の各要素に、何らかの処理を適用し、さらにその各要素の配列を返してくます。

```
let numbers = [1, 2, 3, 4, 5]
let doubleNumbers = numbers.map { $0 * 2 }
doubleNumbers // [2, 4, 6, 8, 10]
```

このように配列の各要素に、何らかの処理を適用し、さらにその各要素の配列を返してくます。
しかし、注意点として戻り値が必要です。
上記の場合、```1``` が入った場合に```1 * 2 = 2```という戻り値があります。
ただ、戻り値がなく、配列の各要素に処理を適用したい場合は、```forEach```　と検索してみてください。

## filter: 配列内で条件にあった要素だけを取り出したいときに使おう
```filter``` は日本語でも使われているため、今回紹介するなかで最も理解しやすい、すでに理解できているものでしょう。

```
let numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
evenNumbers // [2, 4, 6, 8, 10]
```
このように ```filter``` は、単語の通り、配列内で条件にあった要素だけを取り出したいときに使えます。
上記では、numbersという配列から偶数だけ取り出しています。
チュートリアルでよくあるのは、検索機能で、Firebase Firestoreから取得した全てのユーザーの配列を性別や都道府県別で絞り込むときなどです。

## reduce: 配列の要素を1つにまとめたいときに使おう
正直、```reduce```　に関しては使った覚えがありません。
チュートリアルでも　```reduce```　を出している教材は少ないと思います。
しかし、何か使う機会があるかもしれないので、紹介しておきます。

```
let numbers = [1,3,6,8]
let total = numbers.reduce(0) { (num1, num2) -> Int in
    num1 + num2
}
total // 18
```

少しコードの説明をすると、```reduce(0)```の(初期値)の中にあるには初期値です。
そして、最初 ```num1```に初期値の```0``` が入り、```num2``` には配列の1番目の```1```が入ります。
次に ```num1``` には1つ前の```0 + 1``` の結果の ```1```が入り、```num2``` には配列の2番目の```3```が入ります。
このように ```num1``` には初期値、もしくは1つ前の処理の結果、```num2```には配列の各要素が入ります。
もしもっと知りたい人は、他の記事を検索したり、処理をもっと複雑にしてみたりしてください！

また、これぞ ```reduce``` の出番というものがあれば、教えてください。

## 他にもcompactMapやflatMapなどがある
実は他にも ```compactMap```や ```flatMap``` などがありますが、今回は省略します(別の記事で書くかも)。
僕のように```map```  ```filter``` ```reduce```をあまり使う機会がない人は、なおさら```compactMap```や ```flatMap```　は使う機会がないと思います。