OmniAICreator/Qiita-1.07M huggingface dataset:
AWS CloudFrontについて


#CloudFrount

HTMLファイルやCSS、画像、動画といった静的コンテンツをキャッシュし、オリジンサーバーの代わりに配信するCDN（Contents Delivery Network）サービスです。サーバーの負荷を下げながら安定したサービス提供ができる。
提供者・利用者のにもメリットになる。

・世界中に１２０のエッジロケーションがある。
・利用者から最も近いエッジロケーションからコンテンツを高速に配信することができる。
・オンプレミスサーバーにも使用が可能で、今のシステム構成を変更することなくCloudFrontを導入することで、イベントなどによる一時的なアクセス増加に備えることができる。
・URLの指定をすることで、１つのドメインで複数のサービスを統一して使用もできる。

##キャッシュを使用する

拡張子やURLパスごとにキャッシュ期間を指定できる。
静的にはキャッシュ期間を短くし、動的には長くする設定が可能。

キャッシュとは・・・訪問した “ ウェブページの情報 ” を一時的に保存する仕組み（またはその一時的なデータそのもの）のことで、よく訪問するページの表示スピードが上がるというメリットがある。


##言語表示方法
グローバルに展開する上で、その国に合わせた言語表記を設定できる。
クエリ文字列パラメーター値に基づくキャッシュ設定を行うことでHTTPフィールド内の言語表示に基づいて配信方法を切り替えることができます。

##料金が発生する場合
**・トラフィックの分散
データ転送とリクエストの価格はリージョンによって異なり、価格はコンテンツが配信されるエッジの場所によっても異なる。** 

**・リクエスト
リクエスト（HTTPまたはHTTPS）の数と種類、およびリクエストが行われた地域。** 

**・データ転送アウト
Amazon CloudFrontエッジロケーションから転送された。**

**・データを圧縮することでコストを安くすることも可能！！！！**

##CloudFrontを利用したサービス

###・S3 Transfer Acceleration
クライアントと S3 バケットの間で、高速、簡単、安全にファイルを長距離転送できるようになります。Transfer Acceleration では、Amazon CloudFront の世界中に分散したエッジロケーションを利用しています。エッジロケーションに到着したデータは、最適化されたネットワークパスで Amazon S3 にルーティングされます。これによりグローバルに効果的なファイル転送が可能となります。


###・WAF
CloudFront に転送される HTTP および HTTPS リクエストをモニタリングして、コンテンツへのアクセスを制御可能にするウェブアプリケーションファイアウォール。 
S3にCloudFrontによるコンテンツ配信を構成して、AWS WAFを利用してReferer制限を実装することができます。

###・S3バケットから配信するコンテンツへのアクセスを制限
CloudFrontの 署名付き URL または署名付き Cookie を作成してオブジェクトURLの閲覧権限を特定ユーザーに限定します。また、オリジンアクセスアイデンティティ (OAI) という特別な CloudFront ユーザーを作成してS3バケットへの直接的なアクセスを制限します。これにより、ユーザーは S3 バケットへの直接 URL を使用してファイルにアクセスすることはできなくなり、CloudFront を通じて提供するファイルへの安全なアクセスを維持することが可能となります。

####-次のような場合は署名付きURLを使用
**・アプリケーションのインストールダウンロードなど、個々のファイルへのアクセスを制限したい。
・ユーザーがクッキーをサポートしていないクライアントを使用している。**

####-次のような場合は署名付きcookieを使用
**・HLS形式の動画のすべてのファイル、またはWebサイトの購読者領域のすべてのファイルなど、制限のある複数のファイルへのアクセスを提供したい。
・現在のオブジェクトURLを変更したくない。**

###・Route53　ALIASコード
CloudFrontを構成することで、
Route53にCloudFrontを設定してドメインを関連付けることができます。
app builder上追加属性，自定义传给component的参数

1.aura的情况

 使用design:attribute

2.lwc的情况
在属性文件xxx.xml里面使用targetConfigs

```
<targetConfigs>
        <targetConfig targets="lightning__RecordPage,lightning__AppPage,lightning__HomePage">
            <property name="currentStep" type="String" datasource="step-1,step-2,step-3,step-4,step-5" />
            <property name="type" type="String" datasource="base,path" />
            <property name="variant" type="String" datasource="base,shaded" />
        </targetConfig>
    </targetConfigs>
```

当你追加一个property 时候，app builder 的右侧就会出现一个属性
而datasource可以提前给他赋值，既可以是静态的，也可以引用一个apex，实现动态赋值


参照link
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_config_for_app_builder_dynamic_picklists.htm
FlutterでFirebaseを初期化する時のエラー解消方法「Firebase has not been correctly initialized. 」

# Firebase初期化

firebaseがアプデしててハマったけど、一旦解決したので残しときます。

```Dart
//main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();//２行目だけだとエラーになるので追加
  await Firebase.initializeApp(); // ここ大事！Firebase使うのに初期化しないとエラーになる
  runApp(MyApp());
}
```

# エラー

実際は、上記のように書いても以下のようなエラーが出ました。

```
[core/not-initialized] Firebase has not been correctly initialized. Have you added the "GoogleService-Info.plist" file to the pr
```
# 解決方法

"GoogleService-Info.plist" をXcodeにドラッグアンドドロップで設定していましたが、
Xcode内でRunnerフォルダを選択して "Add files"から"GoogleService-Info.plist"を置くと何故か成功しました。
参考：https://stackoverflow.com/questions/45317777/could-not-find-a-valid-googleservice-info-plist-in-your-project
Jetson nanoにROS(Melodic)をインストール

#目的
手元にあるJetson nanoにROSを入れて試してみて、ROSの理解を深める。

#環境
- Jetson nano
- Jetpack 4.4
- Ubuntu 18.04

#手順
#### 準備
```
sudo apt-add-repository universe
sudo apt-add-repository multiverse
sudo apt-add-repository restricted
```
上の3つはすでにenableになっていた。

```
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
```

#### インストール作業

```
sudo apt update
sudo apt install ros-melodic-desktop-full
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
```

次にROSのソフトウェアパッケージのインストールに必要なrosinstallをインストール。

```
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
```

そしてソースコンパイル時の依存パッケージのインストールするのに使われるrosdepのインストール。

```
sudo apt install python-rosdep
sudo rosdep init
rosdep update
```

#### ワークスペースの作成

```
mkdir -p ~/workspace/catkin_ws/src
cd ~/workspace/catkin_ws
catkin_make

sudo sh -c 'echo "source ~/workspace/catkin_ws/devel/setup.bash" &gt;&gt; ~/.bashrc'
```

#### ROSの起動と確認
いよいよROSを立ち上げてみる。

```
roscore
```
![Screenshot from 2021-05-16 22-03-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1503757/b2ddf8e6-5401-0afb-9bdc-bac6de6e51f0.png)

別のTerminalを開いて、rvizとgazeboを起動。

```
rviz
```
![Screenshot from 2021-05-16 22-05-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1503757/3e210082-0da4-b465-4e2f-21f895c80a7e.png)

```
gazebo
```
![Screenshot from 2021-05-16 22-06-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1503757/9e240581-d708-f3b9-6c13-14b4290ae9aa.png)

環境構築完了！
Jetson nanoのSetupが終了している段階から始めて、他作業もしながらで、だいたい1時間半ぐらい。

#参考
以下の記事を参考に構築。
http://kazuki-room.com/how_to_install_ros_on_jetson_nano_and_run_jetbot/
http://wiki.ros.org/melodic/Installation/Ubuntu
JupyterLabのインストール

#JupyterLabのインストールと使用

Python面倒くさいなぁ（中かっこでなくインデントではバグなくコードを書く自信がなかったのです）と思ってほとんど勉強してなかったのですが、iPad上で動くCarnetsが優秀すぎて寝っ転がりながらでも練習などができるとあり、少しやる気になりました。業務用PCにもJupyterNotebookを入れようと思ったのですが、ディスコン予定とのことで、その先のJupyterLabを入れることにしました。

まぁ、初心者ってことです。

とりあえず、参考記事
全般について：
https://qiita.com/kirikei/items/a1639954ce5ccaf7ac3c
JupyterLabインストールについての注意
https://qiita.com/cqe01604/items/5123b40749379c72a248

## Anaconda インストール

https://www.anaconda.com/products/individual
より、"Windows 64-Bit Graphical Installer (Anaconda3-2021.05-Windows-x86_64.exe, 477 MB)"をダウンロード
(2021/05/17現在、Pythonバージョンは3.8)

インストール時はhttps://qiita.com/cqe01604/items/5123b40749379c72a248にあるよう、"Add Anaconda to my PATH environment variable"のチェックを入れました（後で環境変数見たけど、たしかに複雑で、これを手動で入れるのはちょっといやだ）。

その後、「Anaconda Prompt」管理者モードで上げて、
```
akaasata
```

<pre>
conda install anaconda
conda update --all         #（何もしなかったか）
conda --version
conda 4.10.1
python --version
Python 3.8.8               
</pre>
## JupyterLabの起動
スタートメニューから Anaconda Navigator を起動して、「JupyterLab 3.0.14」を確認。
起動してコードを書いてみる（numbyも問題なく使えた）。→めでたい。


※次：JupyterLabでの .py ファイルのエクスポート／インポート
2つの系列データの平均＋標準偏差の幅を表示してプロットする


何度も得られる系列データの比較において，平均に対する標準の幅がわかるようにプロットすることが多い．

このような図を作りたい．

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44835/57cf354b-37b4-e4d2-059d-af9ca0116ae2.png)



- 準備

```python
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from numpy.random import randn
from scipy.stats.mstats import mquantiles
```


- データの生成

適当に2つのダミーデータを用意する．

```python
x = np.arange(0, 30)
data1 = randn(100, 30) * 0.1 * x + x
data2 = randn(100, 30) * 0.2 * x + 0.2 * x + 5
```

- とりあえずプロット

2種類の系列データが，それぞれ100回分あるため，alphaを小さくして重ねてプロットしてもわかりにくい．

```python
for d in data1:
    plt.plot(d, alpha=0.1, c='gray')
plt.show()
for d in data2:
    plt.plot(d, alpha=0.1, c='gray')
plt.show()
```


![download-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44835/a0a8bfcc-e933-0fa8-8e1b-47b85c153c7a.png)
![download-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44835/b1bdacb2-0017-d070-dff0-beb7bb2c6c09.png)


- 平均と標準偏差の計算

0軸方向で平均と標準偏差を計算する．

```python
m1 = data1.mean(axis=0)
std1 = data1.std(axis=0)
m2 = data2.mean(axis=0)
std2 = data2.std(axis=0)
```

- プロット

通常はplt.plotを用いて平均だけをプロットすることが多いが，平均±標準偏差をプロットするために`plt.fill_between`を利用する．

```python
plt.fill_between(x, m1 + std1, m1 - std1, alpha=0.2, color='gray')
plt.plot(x, m1, color='gray')

plt.fill_between(x, m2 + std2, m2 - std2, alpha=0.2, color='red')
plt.plot(x, m2, color='red')

plt.show()
```

表示結果がこれ．

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44835/57cf354b-37b4-e4d2-059d-af9ca0116ae2.png)
mac のキーチェーンで「証明書は信頼されていません」と表示された時の対処法（Apple のデベセン周り）

# はじめに
iOS 端末の実機転送のために証明書登録（キーチェーンを使って認証局から証明書を取得し、Apple のデベセンに登録するといういつもの流れ）をやって、デベセンの Certificates から各種開発用の証明書を作成したところ、なぜか「証明書は信頼されていません」と表示されており実機転送が失敗したため、解決方法を調べました。

# やったこと
ぐぐったところフォーラムに答えが書いてありました。
https://www.google.com/search?q=ios+developer+Certificate+is+not+trusted&rlz=1C5CHFA_enJP830JP830&oq=ios+developer+Certificate+is+not+trusted&aqs=chrome..69i57.3320j0j7&sourceid=chrome&ie=UTF-8

どうも私の環境に入っている中間証明書（AppleWorldwide Developer Relations）は有効期限内ではあるものの古く、2021年1月28日以降に新たに証明書を発行するにはより新しい中間証明書を利用しないといけないということでした。（詳細は以下の公式情報を参照のこと）
https://developer.apple.com/support/expiration/
https://www.apple.com/certificateauthority/

上記ページから最新の中間証明書をダウンロード・インストールすることで「証明書は信頼されていません」の表示がなくなり、実機転送が成功しました。
Laravel 8.x 「No tests executed!」解決方法

LaravelでphpUnitを実行しようとしたところ「No tests executed!」のエラーが発生した。
公式ドキュメントの**artisan**コマンドを使用する方法も試したが、同様のエラーが発生。

##### 実行コマンド

```php:
vendor/bin/phpunit
```
```php:
php artisan test
```
##### 実行結果

```php:artisanの場合
No tests executed! 
```

# 原因
`vondor/bin/phpunit --help`で確認したところ、テスト対象のファイルまたはディレクトリの引数が必須とのこと。
引数が不足していたので、エラーが発生した。

# 解決方法
対象のディレクトリを引数に渡せばOK

##### 実行コマンド

```
vendor/bin/phpunit tests
```

```php:artisanの場合
php artisan test tests
```
Power Automate Desktopのフロー一覧が認証プロキシ下では表示されない

# 概要

認証プロキシ環境下でPower Automate Desktopを使う際は `C:\Program Files (x86)\Power Automate Desktop` にある `PAD.Designer.Host.exe.config` と `PAD.Console.Host.exe.config` のルートノード（ `Configuration` ）直下に以下のプロキシ設定を追加する必要があります。

```xml
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true"> 
    </defaultProxy> 
  </system.net>
```

# 詳細

認証が必要なプロキシ環境内でPower Automate Desktopコンソールを開くと、フロー一覧が読込中のクルクルを続けたまま、フローが表示されなませんでした。以下のページにこの問題と解消方法が説明されています。

* [PAD Console does not show any flows - support.microsoft.com](https://support.microsoft.com/en-us/topic/pad-console-does-not-show-any-flows-e8001bb2-b4ec-4ca2-aceb-7f9c9d10734f)

この問題に該当する（少なくともフローが表示されず、認証プロキシ環境内で使用している）時は、以下を行います。

1. このWindows環境の管理者権限があることを確認する。
2. Power Automate Desktopのインストールフォルダー（ `C:\Program Files (x86)\Power Automate Desktop` ）に移動する。
3. なにかあった時に復旧できるように `PAD.Console.Host.exe.config` と `PAD.Designer.Host.exe.config` の2ファイルをバックアップする。
4. 両ファイルのルートXMLノード（ `<configuration>` ）の直下に以下の子XMLノードを追加する。

最後のステップは「ファイル先頭の`<configuration>` 行の直下に以下の4行を追加」します。

```xml
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true"> 
    </defaultProxy> 
  </system.net>
```

設定が終わったら、Power Automate Desktopコンソールを閉じ、タスクトレイのPower Automate Desktopアイコンから「終了」を行います。その後、WindowsメニューからPower Automate Desktopを起動しなおし、タスクトレイのアイコンからコンソールを開きます。

フローが表示されれば問題解消です。

# 参考

* [PAD Console does not show any flows - support.microsoft.com](https://support.microsoft.com/en-us/topic/pad-console-does-not-show-any-flows-e8001bb2-b4ec-4ca2-aceb-7f9c9d10734f)

以下も参考にしました。フロー一覧以外の機能について言及しているので、認証プロキシ環境下で他の問題が起きた時には参照するとよいかもしれません（まだ私は実施しておらずどのような効果/影響があるか分かりません）。

* [PROXY環境下でのPower Automate Desktopの利用方法 - Qiita](https://qiita.com/hazigin/items/2a676005a954bd05fe2d)
Update procedure for the iRIC software

# 1. For updates only (To add/delete new solvers or grid generation tools, go to 2.

- 1) Start iRIC.
- 2) Click "Menu bar > Options > Maintenance
- 3) Click "Close iRIC and lauch iRIC Maintainance".

At this time, please save and close all running iRIC software. The following screen will appear. Select "Update Components" and click "Next".

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/b2a0ff63-5554-37c5-0e59-8422554aa34e.png" width=75%>
</div>

- 4) the name and version will be displayed, if there is an updated component. Click "Next" to continue.

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/1cd9b98f-569b-9016-76c8-df7fc33e762e.png" width=75%>
</div>


- 5) Click "Update" to update.

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/1535674c-c12a-870b-14f1-1808ca980ee4.png" width=75%>
</div>


- 6) When the update is complete, the completion screen will appear. If you click "Restart", the above screen will appear again. Since this is usually not necessary, click "Finish" to exit and complete the software update.


<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/8839ceff-65e4-b33b-40a8-0a0f72bb36ee.png" width=75%>
</div>



# 2. To add/delete a new solver or grid generation tool

- 1) Start iRIC.
- 2) Click "Menu bar > Options > Maintenance
Click "Close iRIC and Start iRIC Maintainance".

Click "Close iRIC and start iRIC Maintainance". At this time, please save and close all running iRIC software.

- 3) The following screen will appear. Select "Add or Remove Components" and click "Next".


<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/8f834d83-0414-23fc-8669-30319cd29ca1.png" width=75%>
</div>

- 4) On the following screen, items that are checked will be installed, and conversely, items that are unchecked will be uninstalled (or not installed). Check the necessary items and click "Next".


<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/27c67593-c873-2b71-b000-5114e740a303.png" width=75%>
</div>

- 5) When the preparation for the update is complete, the following screen will appear. Click "Update".


<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/53dfffd2-e9c5-a7bb-1aee-403e3c0b57e7.png" width=75%>
</div>

- 6) When the update is complete, the completion screen appears.
If you click "Restart", the screen shown in above section will appear again. Since this is usually not necessary, click "Finish" to exit and complete the software update.

<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/2df20e39-a6f0-4991-fd4a-bcc0925f760f.png" width=75%>
</div>
absoluteUrl の使い方 備忘録

# 環境
Node.js v15.3.0
Next.js v10.2.0

# やりたいこと

* fitch で JSON を読み込み
* 読み込んだデータを画面に表示
* カレントホスト名はハードコードしたくない

# 結論
以下の様にコード化する。

```js
//@see : https://www.npmjs.com/package/next-absolute-url
import absoluteUrl from 'next-absolute-url';

export default function Home() {
    // データソースのURL
    const dataURL = '/data.json';

    // データソースの相対URL
    const relativeURL = '.' + dataURL;

    // Get Request のインスタンス化
    // @see: https://developer.mozilla.org/ja/docs/Web/API/Request
    const request = new Request( relativeURL );

    // Request から、プロトコル｜インターネットホスト名｜オリジンを取得
    // @return {
    //     protocol: string;
    //     host: string;
    //     origin: string;
    //}
    const { origin } = absoluteUrl( request );

    // オリジンとデータソースのURLをくっつける（絶対URL化）
    const url = origin + dataURL;

    // native fitch() を call。
    fitch( url ).then(res => res.json())
    //@TODO: 以下、描画処理
}
```

# 参考リンク

https://www.npmjs.com/package/next-absolute-url

https://developer.mozilla.org/ja/docs/Web/API/Request

https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/fetch
フォルダ内の.mov を gifアニメ に一括変換【Mac】

`FFmpeg`を使い、Macの任意のフォルダ内にある複数の動画ファイル（.mov）を、Gifアニメへ一括変換する方法です。

# 「FFmpeg」のインストール

```terminal:terminal
$ brew install ffmpeg
```
まぁまぁ時間がかかりました。


# シェルスクリプトを組む
* メモ帳（テキストエディタ）を開き、下記のスクリプトをコピペ
* ファイル名`convertGif.sh`で保存（ファイル名は何でもいいけど）

```shell:convertGif.sh
#!/bin/sh
Files=$(find . -type f -iname '*'.mov)
for File in $Files
do
    echo $File
    ffmpeg -i $File -r 10 $File.gif
    printf "\n----------------\n\n"
done
```

* `ffmpeg -i $File -r 10 $File.gif`が変換している箇所です
* `-r 10`は「フレームレートを10」と設定しているオプションです

> フレームレートはパラパラ漫画みたいなイメージで1秒間あたりのコマ数です。多いとよりなめらかになりますが、その分容量も大きくなります。
> 参考サイト：[動画をgif画像にする](https://fukatsu.tech/how-to-ffmpeg#gif)

シェルスクリプトの解説は、同じ様なことをしている[コチラの記事](https://qiita.com/tomokei5634/items/64b0f0b2246987936c6f)をご覧ください

参考サイト：[cwebpでWebPへフォルダ内のJPG・PNG画像を一括変換するシェルスクリプト](https://qiita.com/tomokei5634/items/64b0f0b2246987936c6f)

# 動画と同じフォルダにいれる
* 組んだシェルスクリプト`convertGif.sh`を、変換したいMOVファイルのあるフォルダに入れる
* そのフォルダをターミナルで開く
* `$ sh convertGif.sh`を実行する
* すると変換が始まります（割とサクサク変換されます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/96da69c4-f7e5-d29f-a9fb-1d12e532e12b.png)

# No such file or directory
変換を実行した際に`No such file or directory`と表示が出た場合についてです。
変換前のファイル名を見直してみてください。
`画面収録 2021-01-01 01.23.45.mov` みたいなファイル名になっていませんか？
ファイル名中のスペースが悪さをしているみたいです。
`test001.mov`みたいにリネームして再トライしてみてください。

もしくは、シェルスクリプトを...[[bash] スペースが入ったファイル名の処理](https://qiita.com/daei/items/76635f9fbf25824b525e)

# 参考サイト
* [.mov を gif に変換【Mac】](https://qiita.com/ntkgcj/items/6ac08a007f24a2de0b36)
* [FFmpeg](https://www.ffmpeg.org/)
* [FFmpegで動画変換！各OSごとのインストール方法と使い方まとめ](https://fukatsu.tech/how-to-ffmpeg)
Pythonをアップグレードしたらvenvが作成できなくなった

# 概要
UbuntuのPython3を3.6から3.8にアップグレードしたらpython3 -m venv <プロジェクト名>を実行したら次のエラーが発生。

```
Error: Command '['/home/works/venv/＜プロジェクト名＞/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
```

# 対処
1. pipなしでvenv環境を作成<pre>python3 -m venv --without-pip ＜プロジェクト名＞</pre>
1. setuptoolsをインストール<pre>sudo apt install python3-setuptools</pre>
1. pipをインストール<pre>sudo apt install python3-pip</pre>
1. 仮想環境からでる<pre>deactivate</pre>
1. 仮想環境に入る<pre>source bin/active</pre>

しかし、仮想環境毎に同じ手順が必要なのでOSから入れ直した方が後々便利でした。

以上
[Laravel]Warning:XML configuration validates against a deprecated schema.

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、PHPUnitを使用したテスト実行時に、``Warning:Your XML configuration validates against a deprecated schema.
Suggestion:    Migrate your XML configuration using "--migrate-configuration"!``という警告が発生しましたので解決策を記録しておきます。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##警告文
```
$ vendor/bin/phpunit tests/Feature/ArticleControllerTest.php
PHPUnit 9.5.2 by Sebastian Bergmann and contributors.

Warning:Your XML configuration validates against a deprecated schema.
Suggestion:Migrate your XML configuration using "--migrate-configuration"!
//略
```

##原因
PHPUnit 9.3.0 では、カバレッジのフィルタリングが``filterタグ``から``coverageタグ``に変更されたらしいです。

``参考`` https://github.com/sebastianbergmann/phpunit/blob/master/phpunit.xml
https://github.com/laravel/dusk/pull/811

確認してみると、laravel6.xのphpunit.xmlでは``filterタグ``が使用されていました。

```laravel6.xのphpunit.xml
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
```

```PHPUnit9.3.0以降のphpunit.xml
 <coverage ignoreDeprecatedCodeUnits="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>

        <exclude>
            <file>src/Framework/Assert/Functions.php</file>
            <file>src/Util/PHP/eval-stdin.php</file>
        </exclude>
    </coverage>

```

これらの違いから警告文が表示されたと思われます。

##解決策

```
<!--
<filter>
    <whitelist processUncoveredFilesFromWhitelist="true">
        <directory suffix=".php">./app</directory>
    </whitelist>
</filter>
-->
<coverage processUncoveredFiles="true">
    <include>
        <directory suffix=".php">./app</directory>
    </include>
</coverage>
```
このように変更したことで、警告文が消えました。
コメントアウトしていますが、削除しても問題ないと思います。

##参考文献
https://github.com/laravel/dusk/issues/810

https://github.com/sebastianbergmann/phpunit/blob/master/phpunit.xml
SwiftUI2 Firebase Phone 認証the uiapplicationdelegate must handle remote notification for phone number authentication to work.


FirebaseのPhone認証で

the UIapplicationdelegate must handle remote notification for phone number authentication to work
が出たdelegateに
@main に

    func application(_ application: UIApplication,
                     didReceiveRemoteNotification notification: [AnyHashable : Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if Auth.auth().canHandleNotification(notification) {
            completionHandler(.noData)
            return
        }
        // This notification is not auth related, developer should handle it.
        //handleNotification(notification)
    }
 を入れればOK
iPhone App AppStore Up

今週、iPhone App [LocationMusic]をアップ予定です
数年前 Obejective-cで作成した版をswiftUI2.0で書き直したものです
機能：自分が「ここらへんに来たらこの音楽を聴きたい」場所を登録してドライブ等で音楽を楽しんで頂けたら良いかなって思ってます、なので一種の地図アプリです
サービスとして実行されているNode-REDのMQTTトピックを環境変数から設定する方法

## どういう時に使う？

> MQTTのInputノードのtopicのフィルターはハードコードしなければならず、動的には変更できません。

とある通り、MQTTのTopicは変数などで定義することはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/09a4322b-fa37-29b5-258d-68487f12e83e.png)


IoT機器を１台しか使わない場合は問題になることはないのですが、**複数のIoT機器を同じソースで扱いたい**場合に厄介です。
例えば、MQTT Input ノードをトリガーにして `raspberry pi` で何らかの操作をする場合、機器ごとにTopicを変えないといけなくなってしまいます。(そうじゃないと全ての機器が一斉に動いてしまします:sweat_smile:)

となると、Gitなどを使ったソース管理や一括変更ができずに機器が増えれば増えるほど変更のハードルが上がってしまうことになります:sob:

## では、Node-REDはどうやって設定する？

> これを回避する方法のひとつは、$(MY_TOPIC) のような環境変数をtopicにセットすることです。 Node-REDのランタイムが開始したとき、ノードのプロパティがその環境変数に置換されます。 これによりtopicの変更ができますが、 環境変数の変化を反映するにはNode-REDの再起動が必要です。

つまり、下記の様に設定すれば良いわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/24a4cf9b-c417-74d6-e38f-8bc64123ebaf.png)

## どうやって環境変数を設定する？
サービスとして実行されている場合は、ユーザーはログインしていないので .bashrc は実行されません。
この様な場合はsystemdスクリプトの/etc/systemd/nodered.service.dで設定できます。ただ、これには Node-REDのアップデートで上書きされてしまうため、より良い方法論としては

```
sudo systemctl edit nodered
```

を使うことの様です。
このコマンドを実行することでエディタが起動されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/4d47ce11-f689-7ed2-b5f0-bc118c771264.png)

あとは

```
[Service]
Environment="TOPIC=test"
```

と書き込むことで環境変数として読み込むことができます。
(上記の例の場合はTOPICという環境変数に`test`という値を設定)

きちんと環境変数を読み込むことができたかを確認するためには `change`ノードを使うのが便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/71b482a5-0820-6f40-bdc8-dc92d0f0b0fc.png)

下記のフローでdebugノードに設定した環境変数が表示されれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/faa85627-56e4-e04f-02fd-081aef267c3f.png)

上記のフロー

```json
[{"id":"bfda43e4.a9b1a","type":"inject","z":"136cfccf.a00ab3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":80,"wires":[["60034503.56516c"]]},{"id":"60034503.56516c","type":"change","z":"136cfccf.a00ab3","name":"環境変数を設定","rules":[{"t":"set","p":"payload","pt":"msg","to":"TOPIC","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":80,"wires":[["ec1ab5ce.8ff598"]]},{"id":"ec1ab5ce.8ff598","type":"debug","z":"136cfccf.a00ab3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":80,"wires":[]}]
```
## 参考
[公式のドキュメント](https://cookbook.nodered.org/mqtt/subscribe-to-topic)が参考になります。
日本語版は[こちら](https://cookbook.nodered.jp/mqtt/subscribe-to-topic)
[ユーザコミュニティでのやりとり(英語)](https://discourse.nodered.org/t/reading-user-environment-variables/45547)
iRICソフトウェアのバージョン番号の付与規則について


# 本記事の概要

本記事はiRICソフトウェア（以降iRIC）のバージョン番号の付与規則に係る覚書です。


# なぜこの記事を書くか？
2018年にiRIC version3.0をリリースして以降、数えきれないほどの機能追加、不具合修正を行ってきました。そして2021年5月現在、iRICの最新バージョンは"3.0.19.6741"です。なんとリリースから3年も経過してまだ"3.0"なのです！！！理由はいろいろあるのですが、番号の付与規則があやふやだったことが原因と認識しています。
内内で共通認識をとる協議はやっていたのですが、その時の資料がどこかにいってしまい。今となっては確認しようがありません。やはり、共通認識を作るためには公開情報とすることが最も適当です。ということでこの記事を書いています。

ここに記載するバージョン番号の付与規則は「iRIC ver.4.0」以降に適用する予定です。

# バージョン表記について
バージョン表記と各数字の呼び名は以下とします。例えば、「iRIC 3.0.19.6741」の場合。

- 3:メジャーバージョン
- 0：マイナーバージョン
- 19：パッチバージョン
- 6741：ビルドバージョン

# 付与規則
## メジャーバージョン
以下の場合に更新します。
　- ソフトウェアの構成を大きく更新する場合
　- 開発以外のプロモーション的な意味合いを持たせたい場合

## マイナーバージョン
以下の場合に更新します。

 - 機能追加を行った場合
 

（※）複数機能を同時にリリースする場合は、マイナーバージョン番号が複数更新されます。この数値を確認すると、ver.4.0のリリースから追加された機能の数を確認することができます。


## パッチバージョン
以下の場合に更新します。

 - メッセージやユーザーインターフェースを変更した場合
 - なんらかの不具合（バグ）を修正した場合

（※）複数のバグを修正したい場合は、パッチバージョン番号が複数更新されます。この数値を確認すると、ver.4.0のリリースから変更、修正された機能の数を確認することができます。

## ビルドバージョン
ソースコードのコミット番号との対応関係を明確にするための番号です。
メモ - scipy デンドログラムのインデックスを取得する

# version
scipy: v1.6.3

# コード

`scipy.cluster.hierarchy.leaves_list()`を使う

以下をリンクより引用
https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.leaves_list.html


```python
from scipy.cluster.hierarchy import ward, dendrogram, leaves_list
from scipy.spatial.distance import pdist
from matplotlib import pyplot as plt
X = [[0, 0], [0, 1], [1, 0],
     [0, 4], [0, 3], [1, 4],
     [4, 0], [3, 0], [4, 1],
     [4, 4], [3, 4], [4, 3]]
Z = ward(pdist(X))
```

```python
leaves_list(Z)
>>> array([ 2,  0,  1,  5,  3,  4,  8,  6,  7, 11,  9, 10], 
    dtype=int32)
```

```python
fig = plt.figure(figsize=(25, 10))
dn = dendrogram(Z)
plt.show()

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186209/255cfdd9-9b25-aadf-55f5-f632d61621d0.png)
PayPalアカウント登録・API認証情報取得


## PayPalビジネスアカウントを作成する

PayPalウェブサイトで[PayPalビジネスアカウントを作成](https://www.paypal.com/jp/webapps/mpp/merchant)してください

## テスト用PayPalアカウントを作成する

PayPal Sandbox環境で取引をシミュレーションできるように、テスト用のバイヤーとマーチャントのアカウントを作成します。(デフォルトで自動作成されているアカウントを使用することもできます。)

#### PayPal Sandboxとは
PayPal Sandbox https://sandbox.paypal.com は、本番のPayPal環境 https://paypal.com のテスト版です。ここでは、本番に入る前にトランザクションをテストし、実装が期待通りに動作していることを確認します。

#### Sandboxアカウントの作成
Sandboxのテストアカウントを作成するには

1. [Dashboard](https://developer.paypal.com/developer/accounts/)にログインします。
1. SandboxでAccountsを選択します。
1. Create Account (アカウントの作成) を選択します。
1. PersonalまたはBusinessを選択し、テストの買い手または売り手の国/地域を選択します。
1. Createを選択します。PayPalの残高、クレジットカード、銀行口座情報などが記載されたSandboxメールアカウントが生成されます。
1. [アドバンストクレジットカード決済](https://qiita.com/PPJP/items/13fa67cbb9dce57b701b)をご利用の場合には、Sandbox > Accountsで作成したビジネスアカウントの右端の「…」からView/Edit Account をクリックします。Profile > Account Type の Upgrade to Pro をクリックします。

Sandboxアカウントのデフォルト設定を変更するには、以下の手順に従います。

1. Manage Accountsで (...) を選択し、View/Edit Accountを選択します。
1. Editを選択し、変更を行います。
1. 完了したら、Saveを選択します。

Sandboxにログインするには

1. https://www.sandbox.paypal.com/ にアクセスします。
2. テスト購入者または販売者のメールアドレスとパスワードを使用してログインします。
3. 実装する際には、テストバイヤーとセラーのアカウントを交互に使用して、本番前に取引が期待通りに動作しているかどうかを確認することができます。

## REST APIアプリの作成

**Live環境用のREST Appを作成するためには、PayPalアカウントのメールアドレスの確認が完了している必要があります。** まだ確認を行っていない場合は、PayPalアカウント作成時にメールが送信されていますのでご確認ください。[確認メールを再送する](https://www.paypal.com/jp/smarthelp/article/%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-faq1485)ことも可能です。

API認証情報を取得する最初のステップは、REST APIアプリを作成することです。アプリは、PayPal APIへの呼び出しを認証するために使用される保存された設定のセットです。アカウントに関連付けられた複数のアプリを持つことができます。

REST APIアプリを作成するには、以下の手順に従います。

1. [ダッシュボード](https://www.paypal.com/signin?returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Fapplications) にログインします。
1. Create appを選択します。
1. App Nameを入力します。
1. Create appを選択します。

## API認証情報を取得する

API 認証情報は、クライアント ID とシークレットで構成されており、サンドボックスとライブ環境で API 呼び出しを行い、トランザクションを処理するために必要となります。

サンドボックス API 認証情報を取得するには、以下の手順に従います。

1. [ダッシュボード](https://www.paypal.com/signin?returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Fapplications) にログインします。
1. My Apps & Credentialsで、リストから REST API アプリを選択します。
1. Client IDをコピーします。
1. SecretでShow を選択して、Secretを表示します。
Kotlin(Android)でJpg画像をCropする

#はじめに
Kotlin（Android）で画像をCropする。


#ソース

https://www.fixes.pub/program/297572.html
上記の3#を参考。

```sample.kt
private fun cropImage(bitmap: Bitmap, x: Int, y: Int, w, Int, h: Int): ByteArray {
        val bitmapFinal= Bitmap.createBitmap(
            bitmap,
            x, y, w, h
        )
        val stream= ByteArrayOutputStream()
        bitmapFinal.compress(
            Bitmap.CompressFormat.JPEG,
            100,
            stream
        ) //100 is the best quality possibe
        return stream.toByteArray()
    }
```

#備考
KotlinはAndroidと同義と思い込んでいたが、そうではなかった。
Javaパッケージと同じように使えるものが多いが、中には使えないものもある。
特にAWTもSwingなどのGUIはほとんど使えない。(ImageIO,BufferedImageなど)
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10147763825

#Androidをサポートしていないらしいライブラリ
https://sksamuel.github.io/scrimage/
https://github.com/coobird/thumbnailator

サポートしているという記述は見当たらなかった。
もしかしたら動かせるかも。

#Androidで使えそうなCropライブラリ
https://github.com/igreenwood/SimpleCropView#download
https://github.com/Yalantis/uCrop

Androidをサポートしている旨が表記されている。
aws lambda で UnauthorizedOperation エラー


aws の lambda で EC2 のリストを生成したく、describe_instances(python3.8/boto3)を実行したら以下のエラー。

```
Response
{
  "errorMessage": "An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.",
  "errorType": "ClientError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 8, in lambda_handler\n    response = ec2client.describe_instances()\n",
    "  File \"/var/runtime/botocore/client.py\", line 357, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 676, in _make_api_call\n    raise error_class(parsed_response, operation_name)\n"
  ]
}
```
DescribeInstances operation をコールするときに、UnauthorizedOperation = 権限無いよ のエラー発生。
とのことなので、IAM のロール設定を見直す。

Lmbda  → 関数 → 対象Lambda関数 → 設定タブ → アクセス権限 → 実行ロール → 
【ポリシーをアタッチします】 → 【AmazonEC2ReadOnlyAccess】 選択

無事、エラーは出なくなりました。

めでたしめでたし。
The getter 'displayName' was called on null. Receiver: null Tried calling: displayNameの解決法

#はじめに
この問題が発生したのは、下記の`my_page_screen.dart`の実装を進めている時

https://qiita.com/kokogento/items/76da17fb51806fbb7ff1

#このエラーの原因は何？

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">データの取得が終わってないのにウィジェットが作成されるからか、Consumerで一瞬エラーが発生する。。。 <a href="https://t.co/y8iJE1VsO9">pic.twitter.com/y8iJE1VsO9</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1394114676556849152?ref_src=twsrc%5Etfw">May 17, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Providerでまだ値の取得が終わっていないのに、Widgetの描画が始まっていることが原因だと思われる:rolling_eyes:

#「null」の場合の条件を追加しよう

```dart
 child: Column(
            children: <Widget>[
              Consumer<UserProvider>(builder: (context, model, child) {
                final userData = model.userModels;
                return userData == null
                    ? Container()
                    : Row(
                        children: <Widget>[
                          Container(
```

このように`?`と`:`を使うことでウィジェットの表示を条件によって切り替えられます！

この場合、
**`userData == null`なら空っぽの`Container()`を表示**
**`userData == null`ではないなら、`userData`を使って値を表示する`Row()`を表示**

```dart
return userData == null ? Container() : Row()
```




#参考
https://yaba-blog.com/flutter-the-getter-length-was-called-on-null/
C++ のバージョンを __cplusplus から得るメモ

コンパイル時に C++11, 14, 17 かどうかなど C++ のバージョンを得たい.

https://blog.techlab-xe.net/__cplusplus-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

ありがとうございます.

`__cplusplus` でバージョンが得られますので基本はこれで判定します.


古い gcc や msvc だと正しくレポートしてくれないケースがありますが, その場合そもそも C++11, 14, 17 に対応していなかったりするので古いコンパイラは考慮外としてよさそうです.
carthage0.38でrxCocoaRuntimeがエラーを起こすので、githubから直接xcFrameworkをダウンロードする。

xcFrameworkを使用したかったため、carthage0.38へと乗り換えた。
rxSwift自体のビルドは成功するけど、アプリ起動時に

dyld: Library not loaded: @rpath/RxCocoaRuntime.framework/RxCocoaRuntime

というエラーが出たのでその解決方法のメモ。

## 解決方法
直接githubからzipファイル形式でxcFrameworkをインストールし、Frameworks, Libraries, and Embded Contentに追加する。
どうやらcarthageは、RxCocoaRuntimeを生成出来ないっぽい？
https://github.com/ReactiveX/RxSwift/releases

# 追記
なぜ、CocoaRuntimeがビルド出来ないかが分かり次第追記したい。
【Twitter】目障りなプロモーションを非表示にするブックマークレット【広告ブロック】

```js
javascript:(()=>{let e;window.addEventListener("scroll",()=>{clearTimeout(e),e=setTimeout(()=>{(()=>{const e=document.querySelectorAll("article");for(let t of e)t.textContent.endsWith("プロモーション")&&t.remove()})()},100)})})();
```

#はじめに
ブラウザ版ツイッターを使っています。ホームのタイムラインに表示されるプロモーションが邪魔だったので、これを見えなくするやつをつくりました。

#解説
上記コードは以下のコードを圧縮したものです。

```js
(
    () => {
// ---------

const remove_ads = () => {
    const art = document.querySelectorAll("article");
    for (let ele of art) {
        if (ele.textContent.endsWith("プロモーション")) {
            ele.remove();
        }
    }
}

let timeoutId;
// スクロール停止してから0.1秒に、remove_ads()を実行
window.addEventListener("scroll", () => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
        remove_ads();
    }, 100);
});

// ---------
    }
)();
```

簡単に説明すると、ざっと次の通り。

1. 前半はremove_ads()関数を定義。articleタグを順に見ていき、「プロモーション」という文字列で終わる記事があれば削除する、というもの。
2. 後半はスクロールイベントの設定。画面がスクロールするたびに、remove_ads()を呼び出す。実行するタイミングはスクロールが止まった直後。回数は1度（ココは重要。無駄な処理をしない）。

#補足
1. twitter.comにいる間は、homeからtwitter.com/exploreなどへ移動してまたhomeへ戻ってきても、このブックマークレットは機能するようです。
2. 広告主がプロモーションにぶら下がるかたちで記事を繋げる場合には対応していません。
2. iPhone Chrome、Mac Chromeで確認しました。

#あとがき
いつもお引き立て頂き深く感謝します。
本日もありがとうございました。

#参考
スクロールイベントに関する親切な記事。

1. https://lab.syncer.jp/Web/JavaScript/Snippet/46/
CakePHP 4.4.15 で HelloWorld

CakePHP 4.4.15 で HelloWorld を行う方法です。

## 事前の準備

Arch Linux で必要なモジュールのインストール方法

```bash
sudo pacman -S php-intl
sudo pacman -S php-sqlite
```

```text:/etc/php/php.ini
(省略)
extension=intl
(省略)
extension=pdo_mysql
(省略)
extension=pdo_sqlite
(省略)
```

## プロジェクトの作成

```bash
composer create-project --prefer-dist cakephp/app hello01
```

## サーバーの起動

```bash
cd hello01
bin/cake server
```

http://localhost:8765
にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f1d6acb7-5a0e-e61f-5fef-d4afa22af929.png)

## プログラムの作成

```bash
mkdir templates/Hello
```

```php:templates/Hello/index.php
<html>
<head>
<title>こんにちは</title>
</head>
<body>
    <h1>こんにちは</h1>
    <p>Hello World!</p>
    <p>こんにちは</p>
<p>Aug/01/2023 PM 15:00</p>
</body>
```

```php:src/Controller/HelloController.php
<?php
declare(strict_types=1);

namespace App\Controller;

class HelloController extends AppController
{
  public function index()
  {
  }
}
```

サーバーの起動

```bash
bin/cake server
```

http://localhost:8765
にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4ec5a126-680f-d0c2-3c62-23756ceab3d3.png)

## 確認したバージョン

```text
$ php --version
PHP 8.2.8 (cli) (built: Jul  5 2023 18:47:24) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.8, Copyright (c) Zend Technologies
```
Laravelをレンサバ等のサブフォルダで動かす

特定のドキュメントルート　`/home/foo`があるとして
`https://xxxxxx/bar`でlaravel設置したい

でも

```
/home/foo
     /bar(public)
     /app
     /config
```

みたいなのを避けたい時用
ググるとapacheのconfいじったりするのは出てきますがレンサバ等では出来ないので
htaccessとプラスアルファで出来る方法の備忘録

まず設置(ディレクトリは省略)

```
/home/foo
     /bar
     　　/app
     　　/config
     　　/public
```

`/home/bar`配下に以下のhtaccess設置

```php5:.htaccess
RewriteEngine on
RewriteBase /bar/
RewriteRule ^$ public/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ public/$1 [L]
```
これだけですが
`route/web.php`に書くときにuriに`/bar`が必要になります

例

```php5:route/web.php
//トップ
Route::match(['get', 'post'],'/bar', 'App\Http\Controllers\TopController@index')->name('top');
//なんか一覧
Route::get('/bar/list', 'App\Http\Controllers\Master\SearchController@list');
```
Next.js(create-next-app) 10.2.1からTypeScriptを利用したブートストラップがちょっとわかりやすくなる

[v10.2.1はまだ正式リリースされていません(2021/5/17現在)](https://github.com/vercel/next.js/releases)が、v10.2.1-canary.3からcreate-next-appコマンドに[--tsオプション](https://github.com/vercel/next.js/pull/24655)が追加されました。

```shell
npx -y create-next-app@10.2.1-canary.8 helloworld-ts --use-npm --ts 
```

試しに10.2.1-canary.8で`--ts`を利用してブートストラップしてみると

![スクリーンショット 2021-05-17 14.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47823/46bf5545-8381-a0ff-a4c4-a3b0084a9d69.png)

ページコンポーネントが最初からtsx、APIはtsで生成され

```json:package.json
  "devDependencies": {
    "@types/next": "9.0.0",
    "@types/react": "17.0.5",
    "error": "10.4.0",
    "typescript": "4.2.4"
  }
```

devDependenciesには型定義やtsが追加され

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
```

tsconfig.jsonもちゃんと生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47823/3d9e1dd2-d164-041c-6501-1f24f6954d16.png)

strictがちゃんとtrueなのも良いですね。もともと`create-next-app -e with-typescript`で[examples](https://github.com/vercel/next.js/tree/canary/examples)から引っ張ってくる事でも似たような事は出来ていたんですが、一級市民としてのTSの地位がより強まったという感じでしょうか。

現状、`create-next-app -e blog --ts`のようにexamplesと組合せた使い方は出来ないので、そもそもデフォルトをtsとして`--ts`オプションではなく`--without-ts`オプションになってほしいというのがTypeScript好きとしては正直なところなのだけれど、そこまで行ったらNext.jsじゃなくてNext.tsになってしまうので無いだろうなまる
ECS Exec を有効化する手順（Fargate/Terraform の場合）

とっくの昔ですが、ECSにECS Exec機能が追加されています。

- <a href="https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-exec.html">デバッグに Amazon ECS Exec を使用する - Amazon Elastic Container Service</a>
- [[アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました | DevelopersIO](https://dev.classmethod.jp/articles/ecs-exec/)


# ECS Execとは？

ECSサービス経由で起動したECSタスクの中でコマンドを実行できる機能です。`docker exec`, `docker-compose exec` と同様です。

なお、単発で実行したECSタスクでは利用できないみたいです。

# ECS Exec を有効化する必要はあるの？

以下に示す通り、ECS Execを有効化するのは難しい作業ではありません。ただ、**ECS Execを使いたくなるのは問題発生時**だと思うので、その時に慌てて設定するより、事前に有効化しておくべきだと思います。

なおECS Execを有効化しても追加料金やセキュリティ懸念といったデメリットはありません。

# 有効化手順

## Terraformのバージョンアップ

一般論ですが、Terraformのバージョンがすごく古い場合は[Upgrade Guides](https://www.terraform.io/upgrade-guides/index.html)に従ってバージョンを上げておきましょう。

## AWS Plugin のバージョンアップ

ECS Execに対応している、 `3.34.0` 以降にバージョンアップします。

providers.tf や versions.tf でバージョン管理している（はずですよね？）ので、そこで最新版を指定します。

```terraform
# versions.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.40.0" # 最新版のバージョンを指定
    }
  }
}
```

```
$ terraform init -upgrade=true
```


## `platform_version` の更新

1.4.0以降を使用します。

```terraform
resource "aws_ecs_service" "api" {
  # ...
  platform_version = "1.4.0"
  # ...
}
```

## `enable_execute_command = true` の追加

```terraform
resource "aws_ecs_service" "api" {
  # ...
  enable_execute_command = true
  # ...
}
```

## IAMポリシーの追加

以下のようなIAMポリシーを作成し、ECSタスクのタスクロール（タスク実行ロールではない）に紐付けます。

```terraform
// ECSのタスクロール
resource "aws_iam_role" "task_role" {
  # ...
}

data "aws_iam_policy_document" "ecs_task_role_ssmmessages" {
  version = "2012-10-17"
  statement {
    actions = [
      "ssmmessages:CreateControlChannel",
      "ssmmessages:CreateDataChannel",
      "ssmmessages:OpenControlChannel",
      "ssmmessages:OpenDataChannel"
    ]
    resources = ["*"]
  }
}

resource "aws_iam_policy" "ecs_task_role_ssmmessages" {
  name_prefix = "${var.app_name}-ecs_task-ssmmessages"
  policy = data.aws_iam_policy_document.ecs_task_role_ssmmessages.json
}

resource "aws_iam_role_policy_attachment" "ecs_task_role_ssmmessages" {
  role       = aws_iam_role.task_role.name
  policy_arn = aws_iam_policy.ecs_task_role_ssmmessages.arn
}
```


## `terraform apply`

`terraform apply` で変更内容を確認しながら、適用します。

```shell
$ terraform apply
```

## ECSタスクの再生成

ECS Execが使えるのは `execute_command = true` の設定以降に作成されたECSタスクのみです。

cliコマンドからは以下のコマンドで、ECSサービスのタスクを再生成できます。

```shell
$ aws ecs update-service --service=【サービス名】 --cluster=【クラスター名】 --force-new-deployment
```

AWSのWEBコンソールからやる場合は、ECSサービスの「更新」で「新しいデプロイの強制」にチェックを入れて更新します。

# ECS Execを使う

```
$ aws ecs execute-command --task=【タスクID】 --interactive --cluster=【クラスター名】 --container=【コンテナ名】 --command /bin/sh
```

ここで【タスクID】は `e11f51133d2540c19cdbd2dc153fbf50` のような英数字のIDで、AWSのWEBコンソールなどで確認できます。
AWS Fargateのプラットフォームバージョンを1.3.0に固定したつもりが失敗したお話

## はじめに
弊社はAWSのリソースをTerraformで管理しているのですが、Fargateのプラットフォームバージョンの固定に失敗したお話を書きます。
将来、v1.5.0が出た時に、同じ轍を踏まないように、同様な事象で困った方のお役に少しでも立てれば良いなと思い、この記事を書きました。

## 環境
- Terraform v0.12.20
- Amazon ECS
  - Fargate v1.3.0
- AWS CodePipelineによるBlue/Greenデプロイ
- バッチ処理時、アプリケーションの方からAWS SDK経由でECSタスクを起動

## 経緯
2021年の3月頃、Fargateのプラットフォームバージョンの`LATEST`が`1.3.0 -> 1.4.0`へ更新されました。

その更新されるというアナウンスが来た時点で、ECSを管理しているTerraformのコードを確認したところ、プラットフォームバージョンは指定されておらず、デフォルト値の`LATEST`で動いている事が判明。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service#platform_version

そこで、対応としては、`LATEST`(この時点ではv1.3.0)で動いている物に関しては、`v1.3.0`に固定するという対応を行いました。

- `aws_ecs_service`の`platform_version`に`1.3.0`を指定

```terraform:main.tf
resource "aws_ecs_service" "api" {
# ... other configuration ...
  launch_type                       = "FARGATE"
  platform_version                  = "1.3.0"
# ... other configuration ...
}
```

そして頃合いを見て、`v1.4.0`の検証を行い、動作に問題無ければ順次`v1.4.0`に上げていく予定でした。


## 問題発覚
ある日、`v1.4.0`で動いているECSタスクを発見!!!

## 原因&対応
### 複数の原因があり、それぞれの対応を行ったところ、無事に`v1.3.0`で起動しました

#### **[原因1] CodePipelineでBlue/Greenデプロイを行っていたので、デプロイ時にCodeDeployの設定で上書きされてしまうが、CodeDeployの設定にはプラットフォームバージョンの記載が漏れていた**
  - **-> [対応] `appspec.yaml`の`PlatformVersion`に`1.3.0`を指定**

```yaml:appspec.yaml
# ... other configuration ...
  PlatformVersion: "1.3.0"
```


https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-resources.html#reference-appspec-file-structure-resources-ecs


#### **[原因2] AWS SDKを使用してECSタスクを起動している箇所への設定が漏れていた**
  - バッチ処理用にアプリケーションから一時的にECSタスクを起動していた
  - **-> [対応] ECSタスク起動時処理の`platform_version`に`1.3.0`を指定**
  
```ruby:ecs.rb
  launch_type: "FARGATE",
  platform_version: "1.3.0",
```
- AWS SDK for Ruby

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ECS/Client.html#run_task-instance_method

#### **[原因3] バージョン指定方法に誤りがあった(番外編)**
  - 誤って`1.3`と指定していた箇所があったが、パッチバージョンまで正確に記述しないと`PlatformUnknownException`が発生する   
  - **-> [対応]  `1.3.0`とパッチバージョンまで指定**

https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html#API_RunTask_Errors


## 終わりに
`v1.4.0`でENI周りの変更があったので、ECSタスク起動時に問題が発生するかと思っていたのですが、恐らく、NATゲートウェイ経由で良い具合に通信ができたいたため(未検証)、不幸中の幸いで障害は起こりませんでした。
しかし、意図せずバージョンが上がり、使用しているアーキテクチャの後方互換性が保たれていない場合に、ある日突然アプリケーションが動かないという事態は十分に起こりえます。
将来、`LATEST`が`v1.5.0`を指した時に、同様な事象で困った方のお役に少しでも立てれば幸いです。
PHP Fatal error: PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...>

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、``composer require "doctrine/dbal:2.*"``を試みた際に、PHP Fatal error: Allowed memory size of 1610612736 bytes exhausted以下略というメモリに関するエラーが発生しましたので解決策を記録しておきます。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##エラー文

```
PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.
```

##解決策

エラー文を読んでみると、どうやら https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors のサイトを読むと解決できるよと教えてくれています。親切ですね。

リンク先のサイトを読んでみると、
Composerは、一部のコマンドで``PHP Fatal error: PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...>
``のようなメッセージを表示して失敗することがあるらしく、このような場合はPHPのmemory_limit を増やす必要があると書かれています。

また、``$ php -r "echo ini_get('memory_limit').PHP_EOL;"``を使うことで、現在のmemory_limitの値を取得することが可能らしく、実際に使用してみると下記のように表示されました。

```
$ php -r "echo ini_get('memory_limit').PHP_EOL;"
256M
```

エラー文で必要とされているメモリ値(1610612736 bytes)と上記に書かれているメモリ上限値を比較すると明らかに不足していたのでエラーが発生したと分かります。

PHPのmemory_limit を増やすには、**php.ini**を修正する必要があり、
修正方法として無制限とする-1 を使うか、2G のように明示的な値を定義します。

```php.ini
memory_limit = -1
or
memory_limit = 2G
```
``補足``
いくつかの PHPディレクティブでは、バイト値をintではなく``G``のように省略形で設定できます。

``参考:``https://www.php.net/manual/ja/faq.using.php#faq.using.shorthandbytes

##おわりに
今回のエラーでは、**php.ini**の``memory_limit``を修正しメモリ上限値を増やし、docker-compose up --build -dを実行して変更を反映することで、``composer require "doctrine/dbal:2.*"``が実行できました。

##参考文献
[Composer Memory limit errors#](https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors)
データ分析に3年従事したうえで目から鱗だったpythonの技法

# バックグラウンド
現在、大学院でシミュレーションをメインに研究しています。

大学時代から、pythonでデータ分析などを行っており、やりたいことはできてきたつもりでしたが、この度[Python 3 エンジニア認定データ分析試験](https://www.pythonic-exam.com/exam/analyist)を受験するために、[教本](https://www.amazon.co.jp/Python%E3%81%AB%E3%82%88%E3%82%8B%E3%81%82%E3%81%9F%E3%82%89%E3%81%97%E3%81%84%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-AI-TECHNOLOGY-%E5%AF%BA%E7%94%B0-%E5%AD%A6/dp/4798158348)を購入しました。

大体は知っている内容でしたが、今まで知らなかったこともあったので、備忘録としてまとめました。**もっとなんかいい書き方とかあるやろ..**と思ってる方向けの内容かなと思います。

包括的・体系的に知りたい方は、下記の本をチェックしてみてください。
![](https://images-na.ssl-images-amazon.com/images/I/518zTovKkwL._SX350_BO1,204,203,200_.jpg)
「Pythonによるあたらしいデータ分析の教科書」（翔泳社）
著者：寺田 学、辻 真吾、鈴木 たかのり、福島 真太朗（敬称略）


# 目から鱗だったpythonの技法
## loggingモジュール
バッチ処理などで``print``を多用すること、あるあるですよね。
代替えの手段としてログを使用します。ポイントはログレベルを変えれることかな？
ログレベルは下記の5段階、下に行くほど重要度が高い。

- debug
- info
- warning
- error
- critical

以下、例文
この例ではinfo以上が出力される。

```python
import  logging 

logging.basicConfig(
    filename = 'test.log' #ログファイル名の指定
    level = logging.INIFO, format = '%(asctime)s:%(levelname)s:%(message)s' #ログレベルの指定
)
```

## コーディング規約
pythonには標準となるコーディング規約があるみたいです。

[PEP 8 - Style for python Code](https://www.python.org/dev/peps/pep-0008/)

例えば、複数モジュールを``import``する際には、別々に書くとのこと。

```python
import sys, os #PEP8 違反
#PEP8に準拠した書き方↓
import sys
import os
```

ここまでは、**なんとなく知ってる..**って感じでしたが、これをチェックしてくれる``pycodestyle``なるものがあるんですね！知らなかった。。

```terminal
pip install pycodestyle
pycodestyle main.py
```

コーディング規約のプログラムを修正できます。

## 定義したけど、この変数使ったっけ..?
表題の通りです。
これをチェックするものに``flake8``なるものがあります。

```terminal
pip install flake8
flake8 sample.py
```

あぁでもない。こうでもない。としているうちに、使っていない変数が増えてしまう時に有効です。

## pandas describe
pandasのDataFrameにおける統計量はまるっとチェックできるものがあるみたいです。
それが、``describe()``メソッド。（メソッドの使い方あっているかな。。）
下記に例を示します。

```python
df.describe() # df : DataFrame
```

これで、平均や最大・最小値を勝手に計算してくれます。


## Jupyter Notebook　マジックコマンド
%%や%ではじまるマジックコマンドがありみたいです。使えそうなのは、``%%timeit```コマンドで、セル全体の計算時間を出力してくれます。
他にも、色々あるみたいです。参考までに下記を列挙します。

- [Jupyter Notebook マジックコマンド自分的まとめ](https://qiita.com/mgsk_2/items/437656b8ce42c03e41a6)

## スクレイピングフレームワーク：Scrapy
pythonでのスクレイピングは、``request``や、``BeautifulSoup4``,``selenium``などがよく使われますが、大量のページをスクレイピングしたい場合など、``Scrapy``がいいみたいです。
If element in list with python3

## test.py
```python
import sys

us = [1, 2, 3, 0, 4]
us2 = []

sa = sys.argv[1]
sai = int(sa)

print(us,us2)
print(sa,sai)

print("==no parenthese==")
if sa in us == True:
    print("aru")
else:
    print("nai")

if sai in us == True:
    print("aru2")
else:
    print("nai2")

if sai in us2 == False:
    print("nai3")
else:
    print("aru3")

if len(us2) > 0 and sai in us2 == True:
    print("aru4")
else:
    print("nai4")

print("==parenthese==")
if (sa in us) == True:
    print("aru")
else:
    print("nai")

if (sai in us) == True:
    print("aru2")
else:
    print("nai2")

if (sai in us2) == False:
    print("nai3")
else:
    print("aru3")

if len(us2) > 0 and (sai in us2) == True:
    print("aru4")
else:
    print("nai4")
```

## execution
```bash
# python3 --version
Python 3.6.8
# python3 test.py 2
[1, 2, 3, 0, 4] []
2 2
==no parenthese==
nai
nai2
aru3
nai4
==parenthese==
nai
aru2
nai3
nai4
```

## memo
* 型が合っていないと意図した結果にならない
* element in list の結果を判定するには括弧で括る必要がある
* 最後のは蛇足