OmniAICreator/Qiita-1.07M huggingface dataset:
PHP Laravel 開発環境構築 mac


### 目的
PHP Laravelの開発環境を作ってみる。

### ゴール
新規プロジェクトを作って開発サーバをrunする

### php のinstallをしたい
とりあえずターゲットを知りたいのでコマンドを叩く
```
~ $ brew search php
Error: Permission denied @ rb_sysopen - /private/tmp/github_api_headers20220426-3375-wye0ru
```

む？？、権限。。。設定しなおして再実行
でけた
```
~ $ brew search php
brew-php-switcher   php@7.2             phplint             pcp
php                 php@7.3             phpmd               pup
php-code-sniffer    php@7.4             phpmyadmin
php-cs-fixer        php@8.0             phpstan
php-cs-fixer@2      phpbrew             phpunit

```

ふむ。参照させていただいているページにあわせて 7.2 でいってみる
```
~ $ brew install php@7.2
Error: php@7.2 has been disabled because it is deprecated upstream!
```
むむ？？　無効。。。

ほんじゃ、8.0で
```
~ $ brew install php@8.0
・・・省略・・・

~ $ php -v
-bash: php: command not found
```

むむむ？　PATHか。~/.bash_profile を書き換えて

```
~ $ php -v
PHP 8.0.18 (cli) (built: Apr 15 2022 09:41:02) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.18, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.18, Copyright (c), by Zend Technologies
```

ok

## composer(パッケージ管理システム)のinstall

```
~ $ composer --version
Composer version 2.3.5 2022-04-13 16:43:00
```

ok

## laravel project の作成
```
php-sample $ composer create-project laravel/laravel .
Creating a "laravel/laravel" project at "./"
・・・省略・・・
Publishing complete.
> @php artisan key:generate --ansi
Application key set successfully.
```

ok

## アプリケーション起動確認
```
php-sample $ php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
```

![スクリーンショット 2022-04-27 15.28.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1870907/0338d001-94ca-4ba1-6ea8-5894b851d5c2.png)

でけた。


### 参考URL
[【Mac】Laravelの環境構築手順書(メモ)](https://qiita.com/YutakaYamasaki/items/96ab3f20a71d6c825b5d)
[composerとは](https://qiita.com/atwata/items/d6f1cf95ce96ebe58010)
[pkgist](https://packagist.org/packages/laravel/laravel)
[PHP開発でComposerを使わないなんてありえない！基礎編](https://qiita.com/niisan-tokyo/items/8cccec88d45f38171c94)
[composer.org](https://getcomposer.org/doc/03-cli.md#create-project)
Raspberry PiとiPhoneをBluetooth経由でPAN接続する

# ラズパイ側の設定
## 環境
+ Raspberry3B+
+ raspian 64bit
インストール時の設定として
国は日本を選び「use English」オプションを有効にしています。

## Bluemanの導入
bluetoothでNAP(Network Access Point)を使うためにbluemanを導入します。

```
sudo apt-get install blueman
```
今回は、blueman v2.1.4がインストールされました。

## DHCPサーバーの導入
isc-dhcp-serverをインストールします。
iptablesがインストールされていないとエラーになるので、こちらも併せて導入しておきます。
```
sudo apt-get install isc-dhcp-server
sudo apt-get install iptables
```
isc-dhcp-serverのインストール中にエラーが出ていますが、大丈夫みたいです。

## Bluemanの起動
ラズパイのスタートメニューから
Preference->Bluetooth Manager
を起動すると、右上に新しいBluetoothアイコンが追加されます（青背景に白文字のアイコン）
このアイコンをクリックし、表示されたメニューの「Local Services」
を開きます。
1. 「Network Access Point」のチェックボックスを選択
1. 「DHCP server type」をdhcpdに変更

以上の作業を行ったのち、Applyボタンを押すと、PAN接続の準備は完了です。

## 確認
ifconfigコマンドでpan1にipが割り振られているか確認します。
今回は10.189.101.1に割り振られていました。今後はラズパイ側のIPを10.189.101.1として進めるので、必要に応じて読み替えてください。

## サーバーの導入
PAN接続されたか確認するためにWEBサーバーを立てておきましょう。
今回はapacheサーバーを立てます。
```
sudo apt-get install apache2
sudo systemctl status apache2
```
statusがactive(running)になっていれば大丈夫です。
ブラウザを立ち上げ、10.189.101.1にアクセスしてみます。
apache2のトップページが表示されればOKです。

# iphone側
## bluetooth接続

iphoneの設定->Bluetooth
と進み、BluetoothがONになっていることを確認します。

次に、ラズパイとiphoneのペアリングを行います。
ラズパイ側の右上のタスクバーからBluemanのアイコンをクリックし
表示されたメニュー内の「Make Discoverable」をクリックすると、ラズパイ側はペアリング待機中になります。
iphone側からraspverrypiを探索できるようになるのでそのままペアリングします。
ペアリング後に「Bluetooth Authentication」というウィンドウが表示されるので、
「Always accept」を選択します（ここでacceptしないと、PAN接続できません)

## 確認
safariで10.189.101.1にアクセスしてみます。
Apache2サーバーのトップページが表示されれば成功です。
Path.GetInvalidPathChars と Path.GetInvalidFileNameChars の違い

ディレクトリ名に不正な文字が存在するか調べる際に
`Path.GetInvalidPathChars` と `Path.GetInvalidFileNameChars` のどちらを使えばいいのか、
そしてどのような違いがあるのか分からなくなったので備忘録。

## 実際に返してくる配列を見てみる

コンソールアプリを使用して、次のようなコードを実行する。

```C#:
using System;
using System.IO;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Path.GetInvalidPathChars()");
            foreach (char invalidChar in Path.GetInvalidPathChars())
            {
                Console.WriteLine(invalidChar);
            }
            Console.WriteLine("Path.GetInvalidFileNameChars()");
            foreach (char invalidChar in Path.GetInvalidFileNameChars())
            {
                Console.WriteLine(invalidChar);
            }
            Console.ReadKey();
        }
    }
}
```

結果はいくつか読めない(null文字など(?))文字も出力されたので、見ることのできた文字をここに羅列しよう。

```
Path.GetInvalidPathChars()
"
<
>
|
Path.GetInvalidFileNameChars()
"
<
>
|
:
*
?
\
/
```

ここから分かるのは、`Path.GetInvalidFileNameChars`は名前に`FileName`があるが、ディレクトリの命名に使用できない文字の一覧でもある。

また、`Path.GetInvalidFileNameChars`は`Path.GetInvalidPathChars`を含んでいると断言しても問題なさそうだが、念のため調べる。

## (文字コードで見る)実際に返す値

こーど (一部省略)

```diff_c_sharp
static void Main(string[] args)
{
    Console.WriteLine("Path.GetInvalidPathChars()");
    foreach (char invalidChar in Path.GetInvalidPathChars())
    {
-        Console.WriteLine(invalidChar);
+        Console.WriteLine((int)invalidChar);
    }
    Console.WriteLine("Path.GetInvalidFileNameChars()");
    foreach (char invalidChar in Path.GetInvalidFileNameChars())
    {
-        Console.WriteLine(invalidChar);
+        Console.WriteLine((int)invalidChar);
    }
    Console.ReadKey();
}
```

結果 (連番は省略)

```
Path.GetInvalidPathChars()
34
60
62
124
0 ~ 31
Path.GetInvalidFileNameChars()
34
60
62
124
0 ~ 31
58
42
63
92
47
```

`Path.GetInvalidFileNameChars`は`Path.GetInvalidPathChars`を含んでいる。

## まとめ

+ `Path.GetInvalidFileNameChars()`は`Path.GetInvalidPathChars()`を含んでいる。
+ `Path.GetInvalidFileNameChars()`のみ`:`、`*`、`?`、`\`、`/`を含んでいる。
+ 上記２つより、`Path.GetInvalidPathChars()`と`Path.GetInvalidFileNameChars()`の違いは`:`、`*`、`?`、`\`、`/`を含んでいるかいないか。
+ **ディレクトリ名を調べたい時も`Path.GetInvalidFileNameChars()`を使用しなければならない。**

## ちなみに...

ファイル/ディレクトリ名は他にも、
+ `CON`、`PRN`、`AUX`、`NUL`、`COM1 ~ COM9`(連番)、`LPT1 ~ LPT9`(連番)と言う名前 &nbsp;&nbsp;&nbsp;&nbsp;(拡張子除く)
+ 長すぎる

であるとエラーが発生する。(もちろんファイル/ディレクトリが既に存在する/存在しないも)

https://docs.microsoft.com/ja-jp/windows/win32/fileio/naming-a-file#file-and-directory-names

~~正直めんどくさいので、一番手っ取り早い(?)方法は次にようになる。~~

```C#:あくまで１例
public bool IsInvalidFileName(string path, bool isDir = false)
{
    bool anyError = false;
    try
    {
        if (isDir)
        {
            Directory.CreateDirectory(path);
        }
        else
        {
            File.WriteAllText(path, "");
        }
    }
    catch (Exception ex)
    {
        anyError = true;
        // エラーメッセージ取得など
    }
    /* もしくは
    catch (ArgumentException) { }
    catch (PathTooLongException) { }
    catch (NotSupportedException) { }
    みたいな */
    // 確認だけなら消したり...?
    return anyError;
}
```

~~作って確認してしまえば絶対大丈夫~~
【Windows Terminal】新規タブを開くときにカレントディレクトリを引き継ぐ

## 環境
+ Microsoft Windows 10.0.22000.613（21H2）
+ Windows Terminal 1.12.10983.0

## 現象
コンテキストメニューから Windows Terminal を開くとカレントディレクトリで開かれるが、その横に新しいタブを開くと、カレントディレクトリが継承されず `C:\Users\username` で開かれる。

## 原因
開始ディレクトリの設定が `%USERPROFILE%` になっている。

## 設定方法

<details><summary><code>settings.json</code> を編集する場合</summary>

`"startingDirectory"` に `null` を設定する。
</details>

`Ctrl+,` で設定を開く。対象のシェルの設定を開いて「開始ディレクトリ」で「親プロセス ディレクトリの使用」にチェックを入れて保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/8a07432d-81ae-ff6f-2340-86b3be23267e.png)
【初心者】AWS Lambda Function URLs (関数URL) を使ってみる

# 1. 目的
- たまには新機能のキャッチアップもしないといけないと思い、ちょっと便利そうなAWS Lambda Function URLs(関数URL) を使ってみることにした。

# 2. やったこと
- 「[PokeAPI](https://pokeapi.co/)」(ポケモンデータの検索ができる公開API)にアクセスしてデータを取得するLambda関数を作成し、関数URLの機能を有効にして、インターネットからアクセス可能なURL(関数URL)を設定する。
- 上記のURLに対してブラウザからアクセスする。Lambda関数が実行されて、ポケモンデータの取得が行われ、結果が表示できることを確認する。

# 3. AWS Lambda Functions URLs とは（自分の理解）
- インターネット上にエンドポイント(関数URL)を作成し、そこをたたくことでインターネット経由(https経由)でLambda関数の実行が可能な仕組み。
- 従来は同様のことをやりたい場合、API Gatewayが必要だったが、場合によっては省略することができる。

# 4. 構成図

![functionurls構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/1fab078b-2bec-f70b-d02c-6c57967d5736.png)

# 5. 手順

## 関数の作成

- マネージメントコンソールから、新規にLambda関数の作成を行う。
- 「関数URLを有効化」にチェックを入れる。また、認証タイプは「NONE」を選択する（インターネット上から制限なしにアクセス可能になる）。

![function01a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/afaf5199-b262-e147-b162-ec7ce9d83544.png)
![function02a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c078cf74-190d-6850-09b5-9fbda731750a.png)

- このLambda関数を呼び出すための「関数URL」が作成されていることを確認する。

![function03a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/3038fb1c-8bcd-e811-58de-b0d2aa1d5696.png)

- 関数の内容は以下。requestsライブラリを使用するため、別途Layerを用いて追加している。

``` mksamba-qiita-pokemonapi.py
import json
import requests

def lambda_handler(event, context):
    
    #ポケモンの番号をパラメータでもらう
    param = event.get('queryStringParameters')
    number = param['number']
    
    #該当の番号のポケモンをpokeapiで検索する
    baseurl = "https://pokeapi.co/api/v2/pokemon/"
    targeturl = baseurl + str(number)
    
    r = requests.get(targeturl)
    r = r.json()

    #JSONのデータ内から、名前と画像だけ使用する
    name  = r['name']
    image = r['sprites']['front_default']
    
    #名前と画像を返すhtmlを作成し、ブラウザに返却する
    html = "<html><body>" + name + "<br><img src=" + image + "></body></html>"

    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/html',
        },
        'body': html,
    }
```

## ブラウザからアクセス
- ポケモンの番号を指定するパラメータを付けて、関数URLにアクセスする。該当のポケモンの名前と画像が表示されることを確認する。

![function04a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ce245334-3e0d-f956-5930-9b06aeca128c.png)
![function05a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/dcd64ef2-e0fa-00a0-3a90-c8ff5b02a14e.png)

# 6. 所感
- ちょっとした機能を作るのには便利なのかなと思ったが、今回の設定だとURLを知られた場合に誰でもアクセスできてしまうため、アクセス制限なども試してみたい。


# 7. 参考URL
- [【AWS】LambdaにrequestsライブラリをLayerで追加する](https://sebenkyo.com/2021/05/21/post-1979/)
    - requestsライブラリをLayer化する手順あり。

- [PokeAPIの使い方【初心者向け】](https://taiyosite.com/pokeapi-elementary/)
    - PokeAPIでのデータ取得手順あり。ポケモンの名前と画像を取得するPythonコードはこちらを参照。

- [[アップデート]LambdaがHTTPSエンドポイントから実行可能になる、AWS Lambda Function URLsの機能が追加されました！](https://dev.classmethod.jp/articles/aws-lambda-function-urls-built-in-https-endpoints/
)
    - cookie, CORSなど、細かい機能まで実機確認されており、公式マニュアルより機能の内容が理解しやすい。

- [AWS LambdaのqueryStringParametersとmultiValueQueryStringParametersの違いについて](https://qiita.com/shimajiri/items/2639e9da4a1a77dce1d0)
    - queryStringParameters の使い方を参考にさせていただいた。リクエストのURL例とデータの取得方法がセットになっており理解しやすい。
タワーディフェンスゲームのゲームバランス（ゲーム研究）

　糞ゲーをしていてゲームバランスがめちゃくちゃなタワーディフェンスゲーがあったので自作タワーディフェンスを作るうえで気になったので調べたり、計算した。


・ステージに対してのNPCの移動速度と自分のキャラ
　　![a.psd @ 71.29 % (RGB_プレビュー)  2022_09_07 13_51_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634667/ee3a3d06-5d5a-a2e0-029a-18b80c515749.png)
　NPCは赤い場所から青い場所に進むとする。
　NPC１は１マス進むのに１秒かかるとする。この場合NPC１が城に到達するのに２０秒かかる。
　自分のキャラを出すためにコストを消費する。コストは1秒に1増える。
　キャラ１のコストを３とする。キャラはＮＰＣの進行マスには置けない。
　キャラ１は１秒間に２回前方１マスに１ダメージを与える。キャラ１を出した時前方にすでにNPCがいた場合、攻撃判定がないものとする。NPC１のHPを10とすると、倒すために必要なキャラは5体。
　スタートしてすぐにNPC１が出てきた場合キャラ１を1体を出すときにはＮＰＣ１は3マス目にいる。NPC進行マス4マス目の上下どちらかにキャラ１を置いて初めて攻撃が成功する。最初のキャラ１は4マス目だが、次からは3マスおきにキャラ１を置ける。16マス目でようやくNPC１を倒せる。

・様々なNPCに様々なキャラ
　
　ずっと同じキャラに同じNPCだとマンネリが起き糞ゲーになってしまう。キャラを増やしたりNPCを増やしたりしてみる。
　トラップと1秒で2マス動くNPC２を増やす。
　トラップはNPC進行マス上に置き、そのマスを踏んだNPCを３秒間動けなくする。コスト２。
　NPC2は１秒で2マス動くためキャラ１の攻撃が１回しか当たらない。HP10だとして先ほどのステージだと倒すのは不可能。トラップを使っても無理。
　HP5にしてみる。倒すのに必要なキャラ１は５体。トラップも使う。
　

　倒せない。なら、進行マスを変える。


![a.psd @ 100% (レイヤー 6, RGB_8#) _ 2022_09_07 15_26_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634667/24bd9d9f-d1b9-8188-e8a1-53e598ac9b1f.png)
　これならいける。HP10に戻す。倒すのに必要なコストは８。キャラ１を２体とトラップを１つ。コスト８が貯まる頃には２個目の下凹凸の終わりにいる![a.psd @ 100% (レイヤー 6, RGB_8#) _ 2022_09_07 15_40_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634667/dc35d237-d792-9364-1634-414ad0df9c4c.png)
　黄色い丸がNPC２、水色の丸がトラップ、紫矢印がキャラ１。
　NPC2がトラップにかかると３秒間動きが止まる。その間にキャラ１が２体で攻撃を開始する。
　
　　　　３(秒数)×２(１秒間のダメージ)×２(キャラの数)＝１２(NPC2に対するダメージ)
　見事倒すことに成功。トラップにかかるまでで１４秒、トラップにかかって倒されるのに３秒、合計１７秒で起きミスせず安全に倒せる。思ったよりぎりぎり。

　まだ記事が増えるかもしれない。

・まとめ
　まだ研究しきれてないがタワーディフェンスゲーは時間と進行マスとコストのバランスを数学で計算できる。

・余談
　数学のテストで時速何キロで車が走行しています。何キロ地点で何時間止まりました。また動き出し何キロ進んでゴールしました。１度止まってからゴールまで時速何キロで走ったとしたら、出発からゴールまで何時間経ちましたか？という問題とか出す数学教師絶対タワーディフェンスゲーやってる。
簡単4ステップ！Mapbox Studioでグロー(発光)エフェクトを適用する 

「グロー(発光)エフェクト」とは、カートグラフィー(地図製作)の手法のひとつで、マッピングしたデータを発光しているかのように表現するテクニックです。
データをより効果的に表現できるグローエフェクトですが、[Mapbox Studio](https://www.mapbox.jp/mapbox-studio)ではこのテクニックを簡単に適用することができます。本記事では、マップ上に可視化するデータにグローエフェクトを適用するための[Mapbox Studio](https://www.mapbox.jp/mapbox-studio)を使った方法やコツを紹介します。
![61558de85fdacc5b4a734800_picture_pc_6a7b3f38e7df233c41d33a46a0150978.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/79b70e36-da8f-a9da-eed9-47f72139c552.png)
![61558de9071619c28eaa6096_picture_pc_57636fd3f2bbeb61f3c0752477ba9df3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/0728c480-0f82-3fc9-7046-74e1a4608e9e.png)
▲ アメリカ南海岸に生息するカッショクペリカンの飛行経路を可視化したマップにグローエフェクトを適用したもの
![61558de96c19de5adb4040ea_picture_pc_254c33def0733e55ecd46c4e9b231d43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/51fd7eb6-a355-ae6f-b253-873f4b05a561.png)
▲ 主要な海底通信ケーブルを可視化したマップにグローエフェクトを適用したもの。データの値に応じてスタイルを調整することでより効果的なグローエフェクトに。

## Mapbox Studioを使ったグローエフェクトの適用方法
このテクニックの背後にある原理はとてもシンプルなものですが、適切な文脈で適用することで、とても効果的な表現方法となります。今回の例では、3つのCircle（円）レイヤーを使用し、スタイルのプロパティであるRadius（半径）、Blur（ぼかし）、Color（色）、Opacity（不透明度）をそれぞれ調整して重ねることでグローエフェクトを表現しています。以下、Mapbox Studioでの手順です。

### ステップ1‍
Mapbox Studioの新規レイヤーに適当なデータをアップロードし、データタイプをCircle（円）に設定します。以下の画像は、オーストラリアの南東部に白い円をマッピングしたものです。
![61558de9a6b311ad0a392217_picture_pc_e9dfecec05d870dc8d63dddb186ab2da.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/2fd96c84-4125-cb5e-41e7-37401076c3fd.png)
### ステップ2‍
ステップ1で作成したレイヤーを「Glowy things 1」と名付けました。このレイヤーのスタイルでは、Radiusを10px、Colorを鮮やかなネオングリーン、Blurを3、Opacityを0.4とします。
![61558de8fa0f165242f08444_picture_pc_f510e32d4f4e08c1403cb8d39017de6a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/c90f85a2-548f-c8f9-a81b-7be4825fd01f.png)
### ステップ3‍
次に、このレイヤーを複製して「Glowy things 2」と名付けます。今度は、Radiusを5pxに、Colorをより明るいネオングリーンに、Blurを3に、Opacityを0.4に変更します。
![61558de88d87a9ea0e27c0b5_picture_pc_7c1bf103960840856f8d58dc1f995251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/d4392cd4-06bb-8dc4-7fcb-4140838e1073.png)
### ステップ4‍
このステップがこのテクニックのポイントです。再度レイヤーを複製し、名前を「Glowy things 3」とします。このレイヤーではRadiusを1、Colorを白、Blurを0、Opacityを1にします。これにより、円の中心点がとても明るく、鮮やかな白になりました。
![61558de96c19de02544040eb_picture_pc_785366b30c755bc25c59f66761b5e973.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/cb9fd142-a529-7e8a-aae6-43da42ea7af5.png)
好みに応じて、さらにレイヤーを重ねてRadiusを変えたり、Blurを大きくしたり、Opacityを下げたりして、輝きを強調することも可能です。実際に試した上で、より光り輝いて見えるように調整してみてください。
![61558de994d84d4ea225baea_picture_pc_3d2c2685a4146e1b9ea83881a733603c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/d625ae1b-743e-7d09-6095-009262a1135b.png)
## Line（線）レイヤーのスタイルにも適用可能
このテクニックは、データタイプがLine（線）であっても適用可能です。同じく複数のレイヤーを、WidthやOpacityを調整した上で重ねます。このとき、レイヤー階層の一番上に細くて白い線を持ってくることを忘れずに！
ISCHANGED


# 新規作成の時には機能しない？

+[ISCHANGED in flow trigger stops the trigger firing for new record](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Py5I7)

:::note
IsChanged does not work on creation, so you'd have to find another criteria for creation.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Cf8mrSAB


IsChanged は作成時には機能しないため、作成には別の基準を見つける必要があります。

これについては、「ISCHANGED」セクションに記載されています。

https://help.salesforce.com/s/articleView?id=sf.customize_functions_i_z.htm&type=5

「この関数は、新しく作成されたレコードのフィールドを評価するときに FALSE を返します。」
:::


# ISCHANGEDは、次の場合にのみ使用できます。

1.割り当てルール
2.入力規則
3.フィールドの更新
4.評価基準が「レコードが作成されたとき、およびレコードが編集されるたびにルールを評価する」に設定されている場合のワークフロールール。
5.プロセスビルダーでアクションを実行するための式の基準。

ワークフロールールでISCHANGEDを​​使用するには、「次の数式がtrueと評価されたとき」オプションを使用します。

https://salesforce.stackexchange.com/questions/163067/error-function-ischanged-may-not-be-used-in-this-type-of-formula
スクリーンフローにおける参照コンポーネントのエラー


Looks like you don't have access to this object, or the object API name is not valid on this Lookup component. Contact your Salesforce admin for help.

意味はよく分からんけど、今後も質問には出てきそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ebc99550-4dad-a974-5b83-6e5f9950178d.png)


ルックアップコンポーネントでは、ルックアップ関係を最初から作成することはできません。  

基本的には、既存のルックアップ（Quoteでの連絡先のルックアップなど）を再利用して、組織のすべての連絡先を表示できます-  

これを使用してください。組織内のすべての連絡先が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/943b8580-2f0f-cc0f-2b4c-51de46b8b84b.png)
もう1つのオプションは、表示する連絡先をフィルターで絞り込むことができるドロップダウンリストを使用することです。 


何が違うんだ？ますます分からん。

[Screen flow lookup component error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000GhXEq)


+ [Screen Flows - How to get Opportunity as a selection for Lookup component](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UvhCr)

:::note
Thanks you but above only partially relevant. Does not answer why on the challenge only select a field and not an object can be selected.  Perhaps I need to do a permission set for access or create the lookup on the object first.  

Add a Lookup component to the Opp Fields screen:
+ API Name: screenAccount
+ Field API Name: AccountId
+ Label: Account
+ Object API Name: Opportunity
+ Required: $GlobalConstant.True
:::

# この項目へのアクセス権がないか、このルックアップコンポーネントのオブジェクトまたは項目 API 参照名が有効でないようです。Salesforce システム管理者にお問い合わせください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e0aa446b-9682-95dd-11b2-a249f46ba1c9.png)

AccountオブジェクトにはContactIdはないからだろうな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9cc70c28-6395-c2e7-5bdf-d132c42b3669.png)

AccountからOpportunityに変えると表示できますね。
どうも参照関係の例題を示す必要あがるのかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3c4f3951-fbf9-3768-5f05-55d8c85579b9.png)


# このルックアップコンポーネントでエラーが発生しました。Salesforce システム管理者にお問い合わせください。

+ [【画面フロー】Contact情報を参照するルックアップコンポーネントを作成する。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epz8iSAA)
Git資料

# Git資料
今更ながらGitを触り始めようと思う。
わからないことだらけでまとめ資料を作成した。

SourceTreeとVisualSouceCodeを利用するところまで書きました。

## Git基礎
いまさらだけどGitを基本から分かりやすくまとめてみた
https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0?msclkid=3b8eaea2c52111ec92a9aa431b137dc3
■ブランチ（理想）
| ブランチ名 | 説明 |
| -------- | -------- |
| master   | リリース可能な完全品質保証するブランチ     |
| develop  | 開発用ブランチ     |
| release  | リリース作業用ブランチ masterにマージする際tagを打つ    |
| feature  |  機能追加および修正用ブランチ。作業完了したらdevelopへマージ。ブランチ名はどのような機能を追加したかわかるようにする    |
| hotfix  |  リリース済みのもの緊急修正の作業を行うブランチ   |
| support | 旧バージョンをサポート用ブランチ。 |

■少人数用
| ブランチ名 | 説明 |
| -------- | -------- |
| master   | masterとdevelopを兼任する     |
| topic   | 機能追加やバグ修正を行う     |

HEADとは
https://qiita.com/mzmz__02/items/2c7324a468ed1bbe5c7d?msclkid=e9bb5c7cc52211ec9ba1b54ff91c0658

## githubでﾘﾓｰﾄリポジトリの作成
https://www.sejuku.net/blog/70775?msclkid=996917adc53111ec91d457f1b142a18d

## VScodeでのGit利用
https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be?msclkid=6f90f37fc52511eca64c9bd8bcf453e7


## SourceTreeでのGit利用（VScodeで十分だがあると視覚的にわかりやすい）
https://proengineer.internous.co.jp/content/columnfeature/6983?msclkid=836fb316c52511ecb7041ca4818a9819

## Git for Windowsインストール(WindowsのみMacはインストールされています)
https://it-kyujin.jp/article/detail/263/

## github
https://github.com/yaso-qwerty/ShoreHouse
以下参考まで
### Issues
https://atmarkit.itmedia.co.jp/ait/articles/1703/29/news021.html?msclkid=001188cac53511ecb10f86c2b02f5e71
### Pull requests
https://onl.la/SQn1KLq

### リポジトリ初期化
https://qumeru.com/magazine/526?msclkid=408239d5c5e411ec94559586da282603
インポートウィザードの制限

+ [セールスフォースのデータインポートウィザードを使用して商談をインポートできないのはなぜですか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000E92pS)
+ [インポートするデータのリストから標準オブジェクトが欠落している理由を誰かが助けてくれますか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GztnvSAB)


仕様だから仕方ないと思うのだが、納得してないみたいですね。　Bulk APIを使えば制限はほぼないと思うけど。

[Introduction to the Data Import Wizard for Salesforce](https://www.salesforceben.com/introduction-to-the-data-import-wizard-for-salesforce/)

上記の説明ではこの4つが対象みたい。

+ Leads
+ Solutions
+ Campaign Members
+ Person Accounts (if enabled)


# インポートウィザード実行時にワークフローとプロセスの実行オプションをデフォルトで☑にする方法はありますでしょうか。

+ [インポートウィザード実行時のレコードトリガーフローについて](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UvMgG)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/38ea899f-4bdf-19b2-fc70-e8fee072c909.png)
Rangeを引数として受け取る

`impl Iterator<Item = usize>`型として受け取る
```rust
fn func(range:impl Iterator<Item = usize>){
    for i in range{
        todo!();
    }
}

fn main(){
    func(0..10);
    func(0..=9);
}
```

`0..10`と`0..=9`で型が違うので単純に`Range<usize>`で受け取ろうとすると`0..=9`が受け取れなくなる。
ただ、このやり方だと当然`Iterator<Item = usize>`を実装してる型はなんでも受け取れてしまう(それが問題になることは無いと思うが)。

# その他
ググって一番上に出てきたこれが思ってたのと違ったので。
https://qiita.com/hystcs/items/ed7911a1a0e6443ae40d
iOSのリッチプッシュが動かないときに確認すること

# はじめに
リッチプッシュの実装がうまく動かない！できない！そんなときに確認すると良いところを紹介します。僕はかなり長い時間悩まされました。
おそらく同じ悩みを抱える人がいると思うので記事にしておきます！
証明書関係の設定や、具体的なプッシュ通知の実装方法は記載していないので別の記事を参考にしていただければと思います。 


# 確認ポイント
## ①iOSのバージョン
Extensionファイルの対応iOSバージョン（以下の画像の矢印の部分）が、アプリの対応iOSバージョンと同じでないとリッチプッシュは届きません！（僕はここでめちゃくちゃハマりました。）
![スクリーンショット 2022-04-2713.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/fc7050f6-9027-b85f-dd1f-2adf8fa33414.png)

## ②ペイロード内に"mutable-content"
他の記事でもこれに関してはほぼ書かれているので大丈夫かと思いますが、リッチプッシュはペイロードの"aps"内に特定の値を追加しなくてはいけません。

- 追加する値
```
"mutable-content": 1
```

- ペイロードサンプル
aps内に`mutable-content: 1`が含まれていれば`data`の部分には好きな値を入れてOKです

```
{
  "aps": {
    "alert": "リッチプッシュ",
    "mutable-content": 1
  },
  "data": {
    "imageURL": "画像のURL"
  }
}
```

## リッチプッシュが届いているかの確認方法
リッチプッシュ用のファイルで以下のようにtitleやbodyに任意の文言を入れて、テストをすると、リッチプッシュが正しく実装されているかを確かめることができます！
``` Swift
final class NotificationService: UNNotificationServiceExtension {

    private var contentHandler: ((UNNotificationContent) -> Void)?
    private var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        guard let bestAttemptContent = bestAttemptContent else {
            return
        }
        bestAttemptContent.title = "test: リッチプッシュ"
        bestAttemptContent.body = "test: リッチプッシュ"
        contentHandler(bestAttemptContent)
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}
```


## まとめ
おそらく②はいろいろな記事に書かれているので追加しているかと思いますが、①のiOSバージョンを揃えておかなければいけないという部分で嵌まっている人は多いんではないでしょうか？
参考になっていれば嬉しいです！
ではでは！
CloudformationでSecurityGroupを記述するときはIngress/EgressとSecurityGroupリソースを分離する

# はじめに
初心者向けのメモです。

# 内容
![スクリーンショット 2022-04-27 14.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/bf1a6acb-0158-9faf-1b20-34e40117d960.png)
上図のような相互通信を許可する場合、`AWS::EC2::SecurityGroup`のみを使うと循環参照となりデプロイできないため、`AWS::EC2::SecurityGroup`と`AWS::EC2::SecurityGroupIngress`に分けて書く。

また、分けることで、SecurityGroupのIDを変えずに`AWS::EC2::SecurityGroupIngress`のみを追加することができるため、ID参照する他リソースに影響しない。


```悪い例.yml
Resources:
  SecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref SecurityGroup2

  SecurityGroup2:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref SecurityGroup1
```

```良い例.yml
Resources:
  SecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VpcId

  SecurityGroup1Ingress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      GroupId: !Ref SecurityGroup1
      SourceSecurityGroupId: !Ref SecurityGroup2


  SecurityGroup2:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VpcId

  SecurityGroup2Ingress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      GroupId: !Ref SecurityGroup2
      SourceSecurityGroupId: !Ref SecurityGroup1

```

# 参考
https://aws.amazon.com/blogs/infrastructure-and-automation/handling-circular-dependency-errors-in-aws-cloudformation/

https://stackoverflow.com/questions/54968683/updating-dependent-stacks
pymupdfを使ってpdfのwidthとheightを取得する

# 使用バージョン
> python==3.8
> PyMuPDF==1.19.6

# やり方

```python

import fitz

target_path = "xxx/yyy.pdf"
# pathlibを用いたパスでも良い

doc = fitz.open(target_path)

page_num = 0
page = doc.load_page(page_num)

pdf_width = page.rect.width
pdf_height = page.rect.height
```

# 参考文献

[PyMuPDF公式ドキュメント](https://pymupdf.readthedocs.io/en/latest/page.html#Page.rect)
【容量そのままでOK！】Macの容量不足でXcodeがダウンロードできない！！！を解決

<h4>Xcodeに容量持っていかれすぎる</h4>
時に、皆様こんな状況ありませんか。<br>
実機でのビルドができなくなった。<br>
「あー、iOSバージョン変わったもんね、Xcodeもアップデートしようか」<br>

iOS開発者にとって、バージョン把握は日常茶飯事。

しかーし！↓
![スクリーンショット 2022-04-27 14.09.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/57f3dcca-d7e3-ca62-bf99-6f6c13397b4b.png)


圧倒的FU○K！！！
ストレージには20GB以上余裕があるというのに！！！

![スクリーンショット 2022-04-27 14.10.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/d7d074ef-8237-f2ff-fcdd-d87c539d32f1.png)

なけなしの資料、音楽、動画。全て削除しても
Updateできない・・・・そんなときありませんか？



<h4>公式サイトで解決</h4>
そんな時はApple Developerの公式サイトに行きましょう。

https://developer.apple.com/download/more/

同じアプリがApp Store経由でなくてもダウンロードすることができます。↓
（しかも11GBで！・・・にしても多いけど。）
![スクリーンショット 2022-04-27 14.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/ef0638fa-1bae-7835-6bea-dcebccd23bb5.png)

11GBなのでちょっと時間はかかりますけどね。

<h4>開封しましょう</h4>
Xip形式でダウンロードされるので、これを解凍してインストールをおこないます。<br>
XipファイルはSSDなどに入れたままでも解凍作業ができるので、容量が不足するようであればSSDに移してから解凍するなどしましょう！
※サイズ大きめのSSD持っていないと厳しいかもしれません・・・・


解決できましたでしょうか？
参考サイト：https://it.fuwafuwasky.com/entry/2021/swift/xcode-yoryo/

ではでは。
【小ネタ】PowerAppsでギャラリーのソート機能と検索条件機能を追加してみた

SharePointリストから自動生成したPowerAppsアプリのギャラリーにソート機能と検索条件機能を追加します。
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/bc06e76d-2038-e212-1a1d-518a10e39cef.jpeg)
## 設定ダイアログを追加する
まず四角アイコンや×アイコン、テキストラベル、ラジオボタンを挿入して以下画像の通り設定ダイアログを配置します。
配置に特にこだわりは無いのでラジオボタンで選択できれば問題なし。
背景の画面が暗くなっているのは四角アイコンを画面と同じ大きさにして透明度を変更。
選択されてない状態にしないようにするため、ラジオボタンのDefaultプロパティを設定。
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/42218bc8-6c2b-e45a-09a0-eb4bfa45f7ee.jpeg)
ダイアログの配置ができたら、追加したアイコンやラベル、ラジオボタンを全て選択してグループ化します。
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/87aa8021-1804-2621-ce11-9eb2fe8ee667.jpeg)
グループ化したら、グループのVisibleを適当に設定します。
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/f34e448e-ac14-59be-82ec-7a7b6f41d28c.jpeg)
あとは設定ボタンとダイアログの×アイコンのOnSelectでtrue/falseを切り替えできるようすることでダイアログは完成です。
```
設定ボタン⇒
UpdateContext({grp:true})
ダイアログの×アイコン⇒
UpdateContext({grp:false})
```
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/2178020e-62f7-81f8-12f4-c5a9bdcc65a1.jpeg)
## ギャラリーにソート機能と検索条件機能を追加
それではダイアログのラジオボタンで選択された項目を元にソート機能と検索条件機能を追加します。
結論から言うとギャラリーのItemsプロパティを以下の通りにします。
```
SortByColumns(
    Filter(
        [@備品一覧],
        Switch(Radio1_1.Selected.Value,
            "備品名",TextSearchBox1.Text in Title,
            "貸出状況",TextSearchBox1.Text in 貸出状況,
            "全て", Or(
                TextSearchBox1.Text in Title,
                TextSearchBox1.Text in 貸出状況
            )
        )
    ),
    Switch(Radio1.Selected.Value,
        "備品名","Title",
        "貸出状況","OData__x8cb8__x51fa__x72b6__x6cc1_"
    ),
    If(SortDescending1,Descending,Ascending)
)
```
![007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/59d213a1-b8ff-cd54-35cf-81787373ec82.jpeg)
オリジナルで変更できるようにするため説明します。
ラジオボタンで選択した値によりSwitch分岐していて、
Filter()内のSwitchが検索条件機能で、下のSwitchはソート機能となります。
検索は部分一致検索となっているが、StartsWithやEndsWith関数を使うことで前方一致、後方一致の検索にできます。
ソートの部分は列名を入力する必要があり、列名が日本語になっている場合は以下の記事を参照。

https://qiita.com/ssc-ksakamaki/items/83e40f0d3e7487793a36

ギャラリーの設定をいじることで自由にできるので必要に応じて変更してみてください。
C言語でリスト逆順プログラム

※追記：2022/4/27
構造体の名前はnodeにするのが一般的であるというご指摘を頂きました。
nodeに修正して、プログラムを多少改良したので追記します。

C言語でリスト逆順プログラムを作りました。
以下、コードです。

```c:リスト逆順プログラム
#include <stdio.h>
#include <stdlib.h>

struct node{
	int data;
	struct node* next;
};

typedef struct node Node;

Node* create_node();
Node* list_reverse(Node*,Node*);
void print_list(Node*);
int scan_data();

int main(){
	
	Node* list = NULL;
	Node* next_node;
	Node* tmp_node = NULL;
	int input;
	
	list = create_node();
	list->data = -1;
	list->next = NULL;
	next_node = list;
	
	while( ( input = scan_data() ) != -1 ) {
		next_node->data = input;
		next_node->next = create_node();
		tmp_node = next_node;
		next_node = next_node->next;
	}
	
	if( tmp_node != NULL ) tmp_node->next = NULL;
	if( list->data == -1 ) list = NULL;
	
	print_list(list);
	
	list = list_reverse(list, NULL);
	
	print_list(list);
	
	return 0;
}

Node* create_node() {
	return calloc(1,sizeof(Node));
}

Node* list_reverse( Node* now_node , Node* pre_node ) {
	
	Node* tmp_node;
	
	if( now_node != NULL ) {
		tmp_node = list_reverse(now_node->next,now_node);
		now_node->next = pre_node;
		return tmp_node;
	}else{
		return pre_node;
	}
}

void print_list(Node* now_node) {
	
	while( now_node != NULL ) {
		printf("%d ",now_node->data);
		now_node = now_node->next;
	}
	printf("\n");
	
}

int scan_data() {
	int input;
	scanf("%d",&input);
	return input;
}
```

コマンドラインで整数を入力していって、入力し終わったら-1を入力してください。
リストのデータを順番に表示して、逆順にしたリストを表示します。

![リスト逆順並び替え.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615735/6e851bf0-4cb2-4419-6aac-be4ff76b2433.png)
PHPのクラス名の付け方について（メンターの人に指摘を受けたこと）

プログラミングスクールでデータベースのモデルを作る際、クラス名にアンダーバーを付けたのですが、メンター（講師の人）に見てもらったとき通例PHPではクラス名にアンダーバーはつけないと言われました。

```php_faulse.php
class Sample_Class
```

```php_true.php
class SampleClass
```

# 調べたら
自分で調べたらアンダーバーを付けるのは間違いではないと出ていましたし、ドキュメントでもアンダーバーを付けることに対して間違いであるという言及はされていませんでした。

# 結局
結局、自分でつけたアンダーバーは外し、頭文字大文字で表記するようにしました。

# どっちがいいかわからない
釈然としませんが、アンダーバーはつけてもいいのかどうか迷うところです。

皆さんはどう思うでしょうか？
4.11 (難) 二次元確率変数の変数変換6

## 方針

(X,Y)と(W,Z)の関係が一対一に定まらないことに気をつける．略解の方法は初見では思いつかないのでナイーブに以下のように解く．

## 答案

![4.-12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/df4acd3e-7eda-3810-8935-7838ee830b4d.jpeg)


## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
月の平均日数は？

# 結論

30.436875日

# 計算

平年 = 4で割り切れない年 または 100で割り切れて400で割り切れない年
閏年 = 平年ではない年

```math
\eqalign{
&平年である割合 = \frac{3}{4} + \left(\frac{1}{100} - \frac{1}{400}\right) = \frac{303}{400}
\cr
&閏年である割合 = 1 - \frac{303}{400} = \frac{97}{400}
\cr
&月の平均日数 = \left(365 \times \frac{303}{400} + 366 \times \frac{97}{400}\right) \times \frac{1}{12} = 30.436875
}
```

## 関連

https://www.quora.com/What-is-the-average-number-of-days-in-a-month
ライトハウスを使ってサイトを改善する！_01

サイト改善のプロジェクト第一弾と、その備忘録。

# 課題
ライトハウスの点数を計測して、改善し、点数を上げて、制作者もクライアントもユーザーもHAPPYになるサイトを作る

# 今回の手順
1、ライトハウスについて
2、実際に計測してみる

#### ライトハウスについて
Lighthouse（ライトハウス）とは、Webアプリを監査するためのツールです。特にPWA（プログレッシブウェブアプリ）を中心としたサイトの評価を簡単に確認することができます。
LighthouseはもともとGoogleが公式で運営していたツールであり、GoogleChromeの拡張機能を使って使用します。
Lighthouseの主な項目は、PWAに必要な品質項目を満たしているかどうかや、ページスピードに関する内容です。いずれもサイトの改善にも役に立つ内容ですが、新たにSEOの項目が追加されたため、検索順位を上げたい場合にはぜひ活用したいツールです。
参考：https://service.plan-b.co.jp/blog/seo/10123/

#### 実際に計測してみる
導入方法は、
①拡張機能としてライトハウスを入れて確認
②Chromeの検証ツールで確認
やり方は2パターンありますが、個人的には検証ツールでの確認の方が、計測結果が安定しているように思いました。
【Chromeの検証ツールで確認の方の手順】
拡張機能を開く→Lighthouseのタブの選択
![スクリーンショット 2022-04-27 13.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2583836/c8f7b3b9-aa57-cbed-c5b8-33b2d5c573db.png)

結果が出たら、三角黒丸●より「open in viewer」を選択するとより見やすいレポートが作成されます。
ベーシック認証がかかったままでやると、うまく計測できない場合があるようです。。

![スクリーンショット 2022-04-27 13.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2583836/a08e1c5a-0936-5d82-f563-bf693a56855f.png)

次は改善策を洗い出して、実際にサイトを編集後に再度結果を見てみようと思います。
ではまた
git ブランチワークその1 - git flow

# 前置き
ソースコード管理に git を使うにあたってブランチ戦略はどうしていますか。

![huniki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/92a05461-ef27-30e8-90ef-1485ef8c56f6.png)

プロジェクト間で作法が大きく違ったり、プロジェクト内でも良く見ると微妙に個々人で操作に癖があったり。

前者は良い。プロジェクト規模などで気分の良いブランチ戦略は異なってくるだろう。
でもあまりに我流のブランチワークだとプロジェクトを移動したときに混乱したりするかも。

後者は良くない。あの人の開発ブランチに必要な開発済み機能が入っていないとか、逆に余計なものが混入しているとか、タグを打つ場所が間違っているとか変な問題を生むかもしれない。


というわけで市井に存在するブランチワークを調べてみる。

今回は **git flow**

- git flow ← ココ
- [github flow](https://qiita.com/Takayuki_Nakano/items/cce7f0118ef0be927759)
- [gitlab flow](https://qiita.com/Takayuki_Nakano/items/008e07e9d805d56553fa)

***

# git flow(A successful Git branching model)
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3133313331362f38656665313062622d666663352d366161642d363533342d6635366362333061396538322e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/efbd01ff-ed09-1465-9c69-daec5dc0d8e4.png)

いきなり図を見るといささか複雑。
それぞれのブランチに集中して見てみる。

***

## 登場するブランチ

|名称|役割|分岐元|マージ先|備考|
|:-:|:-:|:-:|:-:|:-:|
|master(main)|デプロイ可能な環境を保持する。|-|-|削除しない。|
|develop|次のリリースに向けた開発用|master|-|削除しない。|
|feature|機能ごとの開発用|develop|develop|develop へのマージ時には *git merge --no-ff* が推奨される。|
|release|バージョン番号の準備やマイナーなバグフィックスなど、開発タスク外のリリースの準備を行う。|develop|master, develop||
|hotfix|リリース済みバージョンに対する緊急度の高い修正を行う。|master|master, develop||
|(bugfix)|緊急度の低いバグフィックスを行う|develop|develop||
|(support)|旧バージョンの保守とリリースを行う。|master|-|同時に複数のメジャーバージョンを管理する場合必要になってくる。|

bugfix と support はオリジナルの図には存在しない。
一部のブランチには命名規則がある。(追記対象)

***

## 概要
1. 開発開始時(プロジェクト開始時)に master から develop を作成する。
1. develop から機能ごとに feature を作成し、ここで個々人が開発作業を行う。
1. 機能開発完了後、次のリリースにすぐ含める場合は develop へマージする。(feature は削除)
1. 次回リリース機能がすべて develop へ合流し、バージョン番号がプロジェクトで決定したら develop から release を作成する。
1. release で機能開発以外に当該バージョンのリリースに必要な準備を行う。
1. release の整理が終わったら develop と master へマージする。(release は不要であれば削除)
1. master からデプロイを行う。
1. master へバージョンタグを打つ。(必要であれば support を master から分岐)

***

## 長所
- 各ブランチの役割が明確
 - リリース済みリソースと開発中リソースがしっかり分離している
 - 複数のバージョンの開発や修正を同時並行して進行しやすい
 - 将来的にリリースや開発単位での内容の確認がしやすい

## 短所
- 一見してわかる通り、他のブランチ戦略と比べて明らかに複雑
- git 管理に一定の工数がかかる。デプロイ速度を重視しており、毎日デプロイを行いたいようなプロジェクトの場合無視できない。
- 個人開発や小規模プロジェクトなど複数の機能・バージョンの開発が平行しにくい場合、享受できるメリットが減る。

***

[原文](https://nvie.com/posts/a-successful-git-branching-model/)にはさらに多くの図や文章を使って、各ブランチの説明や運用方法が記載されています。
ここに記載した内容はまだまだ一部でしょう。
ですが、これで一応の基本を押さえた運用は可能な程度の情報を押さえていると思います。

***
# 参考
[A successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model/)
[[日本語訳]A successful Git branching model](https://qiita.com/homhom44/items/9f13c646fa2619ae63d0)
[A successful Git branching model を翻訳しました](https://keijinsonyaban.blogspot.com/2010/10/a-successful-git-branching-model.html)
私のコード開発環境とGitのアップデート方法

<details><summary>更新履歴</summary>

- "git commit"の コメント(コードをどう変更したかを簡潔に) に""をつけ忘れていたので修正。
- jupyter notebookをJupyterLabに訂正(現在は完全に乗り換えたため)。

</details>

これまで使用していたコードをいじる必要が出てきたので、現在のコード開発環境を記しておこうと思う。
あくまで一個人の一例であり、合う合わないはあると思う。
私のスタイルも今後変わる可能性がある。

以下のことについて記そうと思う。

- エディタ(Atom)
- バージョン管理(Git)
- 研究ノート
- ファイル管理
- バックアップ

GitはHomebrewでアップデートも行ったので、その方法も記しておく。

# はじめに

前提知識は以下の通りである。

- 使用している言語はC, python
- メインで使っている計算コードはfortranだったものをCに書き換えたもの
- pythonはアウトプットデータの解析に使う
- 図は~~jupyter notebook~~JupyterLabで作っている
- コードを書くのはmacOSのノートパソコン
- コードのコンパイルはcentOSの計算機

# エディタの話

現在は[Atom](https://atom.io/)を使っている。
昔は[Emacs](https://www.gnu.org/software/emacs/)を使っていたし、今でもcentOSの計算機上で少しコードをいじりたいときには、ターミナル上でEmacsを動かしている。

# バージョン管理の話

[Git](https://git-scm.com/)を使っている。
インストールはされている前提である。
新しいフォルダの場合、まずは初期化をする。

~~~
% cd <コードが置いてあるフォルダ>
% git init
~~~

あとは基本的に「ステータスの確認」→「ファイルの追加」→「コメントを付けてコミット」するだけである。

~~~
% git status
% git add <追加したいファイル>
% git commit -m "<コメント(コードをどう変更したかを簡潔に)>"
~~~

## Gitのアップデート

随分としていなかった気がするので、この機会にしてみた。
なお、手探りでやっているのでこの順序が正しいとは思っていない。

~~~
% git --version
git version 2.13.0
~~~

[最新バージョン](https://git-scm.com/)は2.36.0らしい。
私は[Homebrew](https://brew.sh/)を使っているので、以下のコマンドを入力。

~~~
% brew install git
~~~

無事できたみたいなので、バージョンを確認。

~~~
% git --version
git version 2.35.1
~~~

…最新バージョンになっていない？

### Homebrewのアップデート

これを先にしなければいけなかったかも。

~~~
% brew --version
Homebrew 3.3.14
% brew update
~~~

時間がかかるので放置。

~~~
% brew upgrade
~~~

これもまた時間がかかるので放置。

~~~
% brew --version
Homebrew 3.4.9
~~~

### Gitのアップデート(再)

~~~
% brew upgrade git
~~~

終わったらバージョンを確認。

~~~
% git --version
git version 2.36.0
~~~

### Gitのグラフィカルインターフェース

前から[gitk](https://git-scm.com/book/ja/v2/%E4%BB%98%E9%8C%B2-A%3A-%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AEGit-%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%82%AB%E3%83%AB%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)を使っている。

~~~
% gitk
zsh: command not found: gitk
~~~

…あれ？
ということでインストールした。

~~~
% brew install git-gui
~~~

これで、以下のコマンドでウィンドウが出てきて、コミットや変更箇所が非常にわかりやすく把握できる。

~~~
% gitk
~~~

# 研究ノート的なメモの話

紙のノートは無くしそう、検索できない、文字が汚い等の理由で全てノートパソコン上のtxtファイルに記している。
研究テーマごとに"memo.txt"を作っている。

# ファイル管理の話

デバックを含めパラメータサーチをたくさんするので、アウトプットファイルは"case1", "case2"のようなフォルダにそれぞれ入れている。
"case100"は超えているので、それぞれで使ったパラメータなどを"memo.txt"にまとめている。
アウトプットデータから作った図のファイル名には"case"のあとの数字を入れるようにして、どのデータを使ったのかわかるようにしている。
例えば"mass_density_50.pdf", "mass_density_50-51-52.pdf"という感じである。

# バックアップの話

大きく分けて、日々のバックアップ、ノートパソコン全体のバックアップの2種類に分けている。

### 日々のバックアップ

Dropboxの無料分(2GB)を使っている。
重要なものだけをピックアップしている。
少し面倒だが、お金がかけられないのでしょうがない。

### ノートパソコン全体のバックアップ

HDDで定期的にバックアップを取っている。
1-2週間ごとにケーブルを繋いでTime machineを使ってバックアップを取っている。
D論前はもっと頻繁にバックアップを取っていた。

### 計算機のバックアップ

良くないと思うが取っていない。

# おわりに

ノートパソコンを新しくすると、データは移行できるけど環境はもう一度整えないといけない。
ついでにアップデートもしていると本業の研究がなかなか進まない気がしてくる。
しかし必要な作業なので頑張るしかないのである。
AWS Certified Solutions Architect - Associateの合格記と振り返り

# はじめに
エンジニア歴3年目にしてようやく取得することができましたので、同じ資格を目指す人の参考になればと、直近で行った勉強法などをまとめておきます。これから記載する勉強方法などを試せばこれぐらいは狙えるという目安のため、まずは結果報告から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1700794/88df0d5e-9625-042a-2e53-3a4ecea42592.png)

720点が合格ラインなので、ギリギリ気味ですがまあ及第点っていう感じかなと個人的には思っています。

# 勉強期間と勉強法
## 勉強期間
2021/11月～2022/4月の受験日まで大体半年弱
※これより前の勉強として~2021年の夏前ぐらいまで半年程度は勉強してましたが、少し期間が開いているので省略します
　詳しく知りたい方は先に同期入社の方が記事にしているのでこちらを確認ください、やってることは大体同じですが、当時は業務で全く違う未経験分野を扱っていたこともあり、ここまで追い込めなかった。。。

https://qiita.com/takuya_677/items/863db7629be08f61e0c9

## 勉強方法
* koiwaclub

https://aws.koiwaclub.com/

基本的にはこちらの問題集を使用しました。
1回7問セットの問題集が、2022年4月時点で160回分あるのでそのまま使ってもスマホで短時間で学習できるのでお勧めです。
ただ、こちらの問題集サイトのいいところは本番形式で問題が解ける本試験モードがあるところだと個人的には思っています。
僕は主に
①本試験モードでテストを受ける
②わからない用語が出てきたときにメモする
③テスト後にわからなかった用語を調べる
このサイクルを（特に年明けからは毎週末）行いました。

* 上記サイクルをやり始めた当初の本試験モードの点数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1700794/58714991-da82-00af-9085-c122fdbb76a7.png)

* 本試験前最後に受けた点数の本試験モードの点数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1700794/1542be7c-90be-5403-5166-97c30232ab4d.png)

もちろん、本試験モードだけで全く問題集を解いていないわけではないですが、毎日～時間以上は問題集解く！みたいなことはしてません。
せいぜい昼休憩などに気が向いた分だけ問題を解いてわからない単語が出てきたら都度調べるを繰り返しました。
あとは本番と同じような点数結果が表示されるので、それが上がっていくのは自信につながります。
ただ、本番と同じでミスした問題がどれかや正解を教えてくれないのが難点でした。

* AWS Skill Builder

https://explore.skillbuilder.aws/pages/16/learner-dashboard

無料で使えて20問のテストができます。
また、こちらは解答後に正解と解説を見ることができるので僕はテスト前日に試して、間違えた範囲を半日ぐらいで用語説明などを読み込みました。
ただ、20問同じ問題固定だったので、やはり最後の確認程度で実施するのがいいかなと思います。

## 受験時の感想と個人的な解き方
個人的な感想ですが、問題の出題傾向として
* 文章がすごく短く簡潔な問題
* 質問文も選択肢文も長くて文章がややこしい問題
の２パターンで両極端だった気がします。

僕は夏休みの宿題の中でめんどくさい作文とかは後回しにする派だったので、さらっと前者を解いてから後者をじっくり解く、という方法で３０分ぐらい余りました。
すぐ解ける問題を探して解くということは、「前半ですべての問題に目を通すことができる」＋「難しい問題が後何問残っているかが把握できる」ので、後の時間配分もしやすかったと思っています。


# おわりに
クラウド技術が今後必須スキルになってきつつある中、僕自身どちらかというとフロント側メインのスキル構成になっていたため、今回の受験はそのあたりを補うきっかけになったと思いました。以前にとあるプレゼンで「資格取得がはじめの一歩で、資格を取得した後で実践を積み重ねてスキルを磨いていくという順番が正しいと思う」という旨の言葉をいただいたので、今後実践も通して技術を身に着けたいと思います。
Dahua VTH / VTO + Asterisk + Homebridge でセキュアなインターホン環境を構築 Vol. 1

# 背景
コロナ禍で非対面受け取り、置き配が一般的になった。
現在も置き配のサービスは継続しているものの、一部（というかAmazon/ヤマトのEasy以外）は在宅確認後の置き配に限定されている。
一方でPostコロナにおいて外出する機会も多くなり、置き配希望にもかかわらず受け取れない機会が増えてきた。

外出中でもインターホンを受け取れるようなシステムを構築する。
ただし、セキュリティ性を重視し、DahuaのApp並びに中国サーバへの通信は一切発生させないように考慮する。

# 必要なもの
* Dahua IP Indoor Monitor VTH (VTH2421FW-Pを利用)
* Dahua Door Station VTO（VTO1201G-Pを利用）
* Asterisk pbx
* Homebridge
* Zoiper Lite(iPhone用App)

# 前提（この記事では触れないもの）
* セットアップ済みのHomebridge
* コンパイル済みのAsterisk 

# Dahua初期セットアップ中のハマりポイント
* Dahua VTOの中にはSIPサーバ機能を持っている機種と、持っていない機種があり、私が買ったものはSIPサーバ機能がない機種だった。それに気が付かず設定を進めて、VTO～VTH間で疎通が取れないこと1日。箱をよく見ると "SUB DOOR" STATIONと書かれていた。。
Asterisk pbxを利用したのはそのような理由からだが、SIPサーバ機能を持つVTOを追加購入したので届いたら追記します。
* Dahua VTHはDHCPによるIP取得が可能だが、VTOはなぜかstatic設定のみ。デフォルトは192.168.1.0/24のセグメントに設定されているようなので、PC側で同セグにIPを設定し、通常利用セグメントのIPを振る必要がある。
* Dahua社製のconfig toolはあってもなくてもどちらでもよい。機種判定が甘いのか、実機で実装されていない機能でも設定ができてしまうので、設定はconfig toolではなく実機でやったほうが良さそう。

# VTH設定メモ
* Settingには2画面あり、Settingを短押し/長押し+パスワード。前者(以下表画面)は着信設定系、後者(以下裏画面)はIP等の設定
* SSHも許可できるようだが、情報取得のみで各種設定ができるようには見えなかった。
* 各項目の説明
    * 表画面
        * Ring
            * VTO/VTH/Alarm Ring：着信音。SDカードを取り出しmp3を配置することで追加できるとの情報あり
            * Other：着信時間、マイク、スピーカーのボリューム
        * Alarm
            * よくわからない
        * Mode
            * Home Away Sleep Customのモードが設定できるが、設定すると何がおきるのかが不明
            Away だったらiPhoneに転送する、というのを実現したいがいまのところできず。
        * Forward
            * Always：常に転送する。ONにすると転送されることが確認できた。
            * Busy：応答できなかった場合に転送する、だと理解しているが転送されなかった。
            * No Answer：応答できなかった場合に転送する、だと理解しているが転送されなかった。
            BusyとNo Answerの違いがよくわかっていない。
        * General
            * Time：ntp設定
            * DND：マニュアルを読んだ感じだと、非通知時間の設定？
        * Other
            * Auto Capture：着信時にVTOの映像を3枚取得してくれる
    * 裏画面
        * 後ほど記載

# VTO設定メモ
http://IP で管理画面にアクセス可能
* Local Setting
    * Basic
        * Device Type：Second Confirmationだと2台目以降の設定になり、SIPサーバの機能が無効化される。機種によってはこの値から変更ができない（変更できない＝SIP機能はない機種ということ）
        * Villa CallNo：ボタンを押下したときの通話先番号。通常はVTHにする。
        * No：自身の番号
    * Video & Audio
        * Audio Control
            * Voice Pronpt Sound：ボタンを押下したときの英語音声のON/OFF
            * Alarm：電源ON時のビープ音 うるさいのでDisableにした

長くなったので一旦ここまで。
初心者は面倒くさくてもprint系関数で挙動を確認しようね


# print系関数使っていますか？
C言語なら `printf()` 、Pythonなら `print()`、どんな言語を学ぶ際にも「Hellow World!」を出力する関数をまず学びますよね？
（本記事ではそれらを **print系関数** と呼びます）

それから多くの関数やループ処理を学んだあと、もしあなたのプログラムが思った通りに動かなかったら、それは最初に学んだ `print` 系の関数を使いこなしていないからではないでしょうか？

## 頭の中で何回シミュレートしても、実際コードを走らせると思った結果が出なくて悩んでませんか？
以下はPythonで `openpyxl` ライブラリを使って、Excelのシートをリストに従って並べ替える自作関数の一部です。

リストを `reversed()` で逆順に読んだり、任意の位置以降に並べ替えたシートを配置するためにシートの移動距離 `offset=` を数式で表現したりと少しテクいことをしています。

慣れた人でないとパッと見このコードが何をしているかわかりにくいのではないでしょうか？

~~~python
import openpyxl
sl = 3

(中略)

    print("シートを並べ替えています\n")

    for e in reversed(slist):
        
        if e in wb.sheetnames:
            print(e + " exists in sheets.")
            ws = wb[e]
            print("sheet index of " + e + " is " + str(wb.index(ws)))
            print(e + " is moving by offset=" + str( sl - wb.index(ws)))
            wb.move_sheet(ws, offset= sl - wb.index(ws))
            print("sheet index of " + e + " is " + str(wb.index(ws)) + "\n")
            wb.save(savename)
        else:
            continue
    print("完了")
~~~

やたらと入っている `print()` は何をしているのでしょうか？
コードを読んだ人に意味を伝えるならコメント機能を使えば良いのでは？

**コードが正しいならね**

`print()` は何をしているのか？
それはコードが正しくないかもしれない（思った通りに動いてくれないかもしれない）ときに、いまプログラムがやっていることを、コードを書いているあなた自身に伝えているのです。

## エラーと戦うためのprint系関数
上述のプログラムを走らせると、コンソールに次のようにログが表示されていきます。

> シートを並べ替えています
>
> りんご exists in sheets.
> sheet index of りんご is 3
> りんご is moving by offset=0
> sheet index of りんご is 3
>
> みかん exists in sheets.
> sheet index of みかん is 4
> みかん is moving by offset=-1
> sheet index of みかん is 3
>
> 完了

ログのおかげで、プログラムが想定通り動いて終了したこと、リストが想定通りの順で読まれたこと、並べ替えの開始位置が想定通りindex[3]から開始されていることが確認できます。

そもそも初心者のプログラムは、まずエラーなくすんなり動くことはありません。

エラー文を見ればどこにエラーがありそうか分かります。
特に構文エラーの修正は簡単です。
一見では原因が見抜けないエラーもたくさんあります。
そんなエラー文との戦いの心強い味方が **print系関数です** 。

**しかし、そもそもエラー箇所までの処理は本当に想定通り動いてますか？**

- 自作関数の出力は、次の処理に渡せる型になってますか？
- 入れ子になった `if` や `for` のどこをいま処理していますか？
- その処理の結果は想定した通りですか？

こういった不安や疑問、とりあえず **print系関数** で出力すれば解決します。

## print系関数を使うコツ
**print系関数** を使うコツは2つです。
1. 不安な処理の前後に入れる。
1. 変数や関数を使って結果をそのまま出力する。

#### 不安な処理の前後に入れる
ある処理がうまくいっているか知りたくて **print系関数** を入れているのですから、その前後に入れるべきでしょう。
前に入れることで処理前の状態を、後に入れることで処理後の状態を出力できます。

#### 変数や関数を使う
出力文字列に変数や関数を使うことで、変数の代入値の変化や変数の型のチェックができます。（例： `type()` や `is*()` を使って、処理が上手くいっていることを確認しよう）

# 以上
**print系関数** を使うとエラー箇所やプログラムが上手く回っていない部分が分かりやすくなるので、初心者は積極的に `print` して自分のコードを確かめよう、というお話でした。
Dockerの基本的な仕組み

# Dockerとは？
Dockerとはアプリケーションを開発・転送・実行するためのオープンなプラットフォームです
もっと噛み砕くとアプリケーションを基盤となるハードウェアに依存しないため、**インフラがアプリケーションを扱っているかのように管理できる**ため便利かつ容易にサービス開発を行うのに役立ちます
インフラが管理できるということは他のチームメンバーに同様の環境を転送することも可能となります
より詳しく知りたいなら[公式ドキュメント](https://docs.docker.jp/engine/introduction/understanding-docker.html)を参照してみてください

## 基礎的な概念
最も基本的な概念が
**イメージからコンテナが作られる**
ということです
コンテナが作成されることによって、僕らの実行環境(OS&ライブラリ&アプリケーション)が作られます

ではどうやって起動させるのでしょうか？
例えば
```
% docker run hello-world
```
というコマンドを打ってみると

```
Hello from Docker!
```
と出力されます

## Dockerのアーキテクチャー
Dockerは**クライアント・サーバ型のアーキテクチャ**です
これは使う側である僕らのコマンドを処理するクライアントとその後の複雑な処理をするサーバが別になってる(分散してる)ということです

先ほどのコマンドを詳しく見ていく前にDockerの内部を3つに分けると以下のようになります
* **Dockerクライアント(client)**
* **Dockerデーモン(daemon)**
* **Dockerレジストリ(registry)**

### Dockerクライアント
**Dockerクライアント**は僕らが打ったコマンドを処理してDockerデーモンに情報を伝える窓口のようなものです
クライアント・サーバ型のクライアントに当たります
この際Dockerデーモンへは[RESTful API](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)を通して通信を行なっています
人に例えるなら耳や目のような外部の情報を受け取るところといった感じでしょうか

### Dockerデーモン
**Dockerデーモン**はDockerクライアントから届いたコマンドを元にDockerレジストリからイメージを取得しコンテナを作り出します
Dockerを使う際の脳みそと考えるといいかもしれません
ちなみにデーモンは"**demon(悪魔)**"ではなく"**daemon(守護神)**"であることに注意が必要です

### Dockerレジストリ
**Dockerレジストリ**とはイメージの貯蔵庫でパブリックとプライベートの2種類があります
つまりコンテナを作るときの仕様書をレジストリに保存していると考えると良いと思います
自分が使いたいイメージや他の人が作ったイメージをアップロードしておき、使いたい時にダウンロードするという仕組みで、例えるなら脳みその中でも海馬に近いと思います

## コマンドを打ったときの流れ
先ほどコマンドを打ったとき以下のメッセージが帰ってきたと思います

```
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
これは以下の流れを示しています
* **クライアント**が**デーモン**に「"hello-world"イメージ下さいというリクエストが来ましたよ」と伝える
* **デーモン**は「ローカルの**レジストリ**を調べたけど"hello-world"なんてイメージないよ」とクライアントに伝える
* **デーモン**が[Docker Hub](https://hub.docker.com/)というパブリックな**レジストリ**にあるか調べる➡︎これが**libraryディレクトリ**のこと
* "hello-world"のイメージが**レジストリ**にあるのでダウンロードする
* **デーモン**が取得したイメージをもとにコンテナを作る
* コンテナを作った結果を**クライアント**に伝える
* "Hello from Docker!"と表示される

# まとめ
基本的な流れを理解することでその後のコマンドやエラー文を読めるようになるためこの記事でまとめたことは最低限の知識として理解しておきましょう
[ドキュメント](https://docs.docker.jp/engine/introduction/understanding-docker.html)が日本語で書かれているので読みやすいです
【JavaScript】【jquery】指定した回数だけ回す。$.each([...Array(num).keys()]を使う

# コード

連番数値の配列を作る

```javascript

const num = 15;

console.log([...Array(num).keys()]);

// １から始めたいなら
console.log([...Array(num).keys()].map(n => ++n));

$.each([...Array(fields.length).keys()], function(_,i) {
    console.log(i);
})

```

# 結果 


```
[
   0,  1,  2, 3,  4,  5,
   6,  7,  8, 9, 10, 11,
  12, 13, 14
]


[
   1,  2,  3,  4,  5,  6,
   7,  8,  9, 10, 11, 12,
  13, 14, 15
]

```