OmniAICreator/Qiita-1.07M huggingface dataset:
terraformにおけるAWS Providerの認証あれこれ

terraformでAWS Providerを使用されている方は多いのではないでしょうか？

こちらの記事では、AWS Providerを使用する際に、認証情報の設定方法の選択肢について概要をまとめています。
認証情報の取り扱いは一歩間違えると、重大なインシデントに繋がりかねないため、重要な設計観点となるかと思います。
本記事がみなさんの安全なterraform×AWSの利用に貢献できれば幸いです。

基本的には[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)の情報をかいつまんで説明しつつ、また追記もしつつ、書いたものになります。
説明に誤っている部分などあれば編集リクエストなどいただけると嬉しいです。

# 設定方法
## 1. 認証情報のハードコーディング
AWS providerのブロックに直接記載する方法です。
下記の要領で設定を行います。

```terraform
provider "aws" {
  region     = "us-west-2"
  access_key = "my-access-key"
  secret_key = "my-secret-key"
}
```
ただし、上記のような認証情報自体のハードコーディングは非推奨です。
公開されたバージョン管理システムにコミットしてしまうと、認証情報の流出に繋がり、ひいてはAWSリソースの不正利用を招いてしまいます。

## 2. 環境変数での設定
AWS CLIを普段から使用している方からすると馴染みがあるかと思いますが、環境変数の`AWS_ACCESS_KEY_ID`と`AWS_SECRET_ACCESS_KEY`を使用して認証情報を設定することも可能です。

## 3. 共有認証情報ファイルの使用
共有認証情報ファイルというのは、AWSのクレデンシャル情報を記載したファイルのことです。aws cliにて`aws configure`を実施した際に作成されるファイルですね。
Linux、macOS、またはUnixの場合、デフォルトでは`~/.aws/credentials`に作成されます。
共有認証情報ファイルは下記のような構成になっています。
複数の認証情報がプロファイルとして管理されています。

```
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
[another]
aws_access_key_id = YOUR_ANOTHER_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_ANOTHER_AWS_SECRET_ACCESS_KEY
```

この方法で設定する場合は、共有認証情報ファイルのパスと、使用するプロファイル名をterraformに設定する必要があります。その方法は更に2つに分かれます。
１つは環境変数で指定する方法です。それぞれ、AWS_SHARED_CREDENTIALS_FILEとAWS_PROFILEで設定します。
もう1つはAWS Providerブロックにコーディングする方法です。下記のような形で設定することができます。

```terraform
provider "aws" {
  region                  = "us-west-2"
  shared_credentials_file = "/Users/tf_user/.aws/creds"
  profile                 = "customprofile"
}
```

なお、profileを指定しなかった場合は、defaultプロファイルの認証情報が使用されます。

## 4. IAMロールの使用(CodeBuild, ECS, EKS)
CodeBuild, ECSでterraformを実行する場合、それらのサービス側で実行環境であるコンテナにアタッチするIAM Task Roleを使用した認証を行うことが可能です。
EKSのPodでterraformを実行する場合は、IAM Roles for Service Accounts (IRSA)を設定し、Podに設定したIAMロールを使用して認証することが可能です。

## 5. EC2 Instance Metadata Service (IMDS and IMDSv2)
EC2インスタンスでterraformを実行する場合、IAMロールをアタッチしていると、EC2インスタンスメタデータから該当ロールの認証情報が取得できます。


# 注意点
上記方法で設定されるクレデンシャルのうち、1.及び3.のように、AWS Providerブロックで直接コードで設定を施すタイプのものについては1点注意が必要です。それは、設定した認証情報が、terraformのstateファイルを管理するバックエンドのs3にアクセスする際には自動で使用されないという点です。それらの設定は別物の扱いとなります。
よって、別途backend側のブロックでもコーディングが必要となります(ただ、こちらについても認証情報自体のハードコーディングは非推奨です)。

- 認証情報のハードコーディングの場合

```terraform
terraform {
  backend "s3" {
    bucket     = "mybucket"
    key        = "path/to/my/key"
    region     = "us-east-1"
    access_key = "my-access-key"
    secret_key = "my-secret-key"
  }
}
```

- 共有認証情報ファイルの使用

```terraform
terraform {
  backend "s3" {
    bucket                  = "mybucket"
    key                     = "path/to/my/key"
    region                  = "us-east-1"
    shared_credentials_file = "/Users/tf_user/.aws/creds"
    profile                 = "customprofile"
  }
}
```


# 参考
https://registry.terraform.io/providers/hashicorp/aws/latest/docs

https://www.terraform.io/docs/language/settings/backends/s3.html
AWS Cloudfront + ALB + EC2 + EFS + RDS で ECCUBE

ECCUBE を冗長構成をとりながらAWS上にセットアップしてみたのですが、いくつか工夫が必要だったのでメモしておきます。

とりあえず一般的な構成で Cloudfront + ALB + EC2 + EFS + RDS はセットアップしておきます。

### Cloudfrontのキャッシュ設定

キャッシュは基本は無効化して、下記のディレクトリだけキャッシュ対象にしておきます。

/app
/html

(/app ってどういうときにブラウザから参照されるんだ...?)

### SSLの強制

ECCUBEは X-Forwarded-Proto を考慮してくれないようなので、 index.php の最初の方に

```php
$_SERVER['HTTPS'] = 'on';
```

を追加しておきます。

(本当はウェブサーバーの方で設定したほうがいいのだけど、手っ取り早く動かしたかったので...)

### キャッシュディレクトリをローカルのディスクへ

ECCUBEはキャッシュファイルを大量に作成するようです。

ドキュメントルートをEFS上にしてECCUBEをインストールしますが、そのままだとキャッシュが全部EFS上に置かれてしまい、パフォーマンスが著しく低下します。

シンボリックリンクで var ディレクトリはローカルのディスク上のディレクトリを指すよう変更します。

```
$ cd /path/to/document/root/
$ rm -rf var
$ ln -s /path/to/dir/on/local/disk/ var
```

### セッションの保存先をDBに変更

[EC-CUBE4 セッション情報の出力先をデータベースに変更](https://qiita.com/applexco/items/b9571611d30688a778e7) を参考に設定変更します

-----

#### 負荷が抑えられなくなってきたら考慮すること

* ヘッダー部分のカートに入っている商品の表示とかを辞めればページ類もキャッシュできる(CSRFで問題出る?)
* クエリキャッシュ
* スレーブDBの参照
SIEM とは

## 勉強前イメージ

セキュリティ系第3弾くらい
けど、わからんw
多分これもツールとかやった気がする

## 調査

### SIEM とは

Security Information and Event Management の略で、
日本語では、 セキュリティ情報イベント管理 など言われます。
firewallやIDS/IPSなどの機器やログを一元管理し、脅威を検知・分析して通知を行う仕組みです。

### SIEM の機能

- ログの統合管理

各セキュリティ・ネットワーク機器のログを統合管理することで
ログ同士の分析もしやすくなります。

- インシデントの発見

収集したログを時系列やイベントごとになどに注目して相関分析を行います。
人力ではログの量が膨大で難しいですが、SIEMはルールに則って処理を行うことで
発見することが出来ます。

- 脅威への対策

SIEMで発見されたインシデントはアラートとして管理者へ通知されます。
リアルタイムにログの分析が可能なので脅威の早期発見ができ、
対策を行うことが出来ます。

### SIEM と SOAR との違い

SIEM は [SOAR](https://qiita.com/miyuki_samitani/items/2db60d49378707be0420) と似たような印象を受けますが、
どこが違うのか確認していきます。

- SIEM
	- ログの取り込み、相関分析が得意
- SOAR
	- 脅威情報サービスが外部のデータソースなどの取り込みが得意
	- インシデント管理と自動化も行う

## 勉強後イメージ

セキュリティ系はほぼ言葉知らないから読むのも難しい・・・
SIEMとSOARとか結構似てるから、混じってるツールとかもありそうだね。

## 参考

- [意外と知らない？ITトレンド用語](https://www.ntt.com/bizon/glossary/e-s/siem.html)
- [SIEMとは？概要から仕組み、メリットデメリットまで徹底解説](https://cybersecurity-jp.com/security-measures/33591)
- [SIEMとSOAR、違いは何ですか？](https://ichi.pro/siem-to-soar-chigai-wa-nani-desu-ka-272803306732803)
SQLServer(Linux)のDockerコンテナを作成（2021年）

## 0. 前提条件

- OS：Windows10 
- Docker Desktopがインストール済み。

## 1. マウントするディレクトリ作成

- docker-comopse.ymlと同じ階層に以下のフォルダを作成。

```txt
 docker
    └ sqlserver
      ├ data
      ├ log
      └ secrets
```

## 2. docker-compose.yml作成

- 以下の通り作成。
- imageは、以下のサイトで名前を確認。

  https://hub.docker.com/_/microsoft-mssql-server

- volumesは、前項で作成したディレクトリを設定する。

```yml
version: '3'
services:
    mssql:
      image: mcr.microsoft.com/mssql/server:2019-latest
      container_name: mssqlserver01
      ports:
        - 1433:1433
      environment:
        - ACCEPT_EULA=Y
        - SA_PASSWORD=任意の文字列
        - MSSQL_PID=Express
        - MSSQL_LCID=1041
        - MSSQL_COLLATION=Japanese_CI_AS
      volumes:
        - "./docker/sqlserver/data:/var/opt/mssql/data"
        - "./docker/sqlserver/log:/var/opt/mssql/log"
        - "./docker/sqlserver/secrets:/var/opt/mssql/secrets"
```

## 3. SQLServer Management Studioをインストール

- 以下のサイトからインストーラーをダウンロード。

https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15

- 管理者権限でインストーラーを実行。
- インストール中に、エラーが出た場合は、再起動して再度同じ手順を実行。


## 4. コンテナ作成と起動

- docker-compose.ymlが配置されたディレクトリで、以下を実行。

```sh
docker-compose up
```

## 5. StudioでSQLServerに接続

- 以下のログイン情報で接続。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/d65477dd-8f04-664c-ef1b-a74d562b88c1.png)

- ポイントは以下。

```txt
Service type: Database Engine
Server name: localhost
Authentication: SQL Server Authentication
Login: sa
Password: [docker-composeで定義したパスワード]
```

## 6. StudioでDB作成

- StudioのエクスプローラーのDatabaseを右クリックしてデータベースを新規作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/2f60030d-7762-bf03-b3b9-ae64f698cf80.png)


## 7. テーブル作成、テストデータ投入

- Studioで作成したDBを選択肢、クエリを作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/78c4c2f4-ccd5-38d1-5c59-25cfa7ea6eed.png)

- クエリに以下を貼り付けて、F5か実行ボタンを押す。

```sql

CREATE TABLE clients (
    ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    NAME NVARCHAR(20) NOT NULL,
    UPDATE_AT DATETIME default CURRENT_TIMESTAMP
);

CREATE TABLE crews (
    ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    NAME NVARCHAR(20) NOT NULL,
    UPDATE_AT DATETIME default CURRENT_TIMESTAMP
);


INSERT INTO clients (name) VALUES ('client1');
INSERT INTO clients (name) VALUES ('client2');

INSERT INTO crews (name) VALUES ('crew1');
INSERT INTO crews (name) VALUES ('crew2');

```

テーブルを選択して、データを抽出。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/a15948ba-2b63-d248-183f-e7d36ed14633.png)

以上でコンテナ作成からデータ取得のテストまで。
[Ruby] AtCoder過去問 B - Increment Decrement

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc052/tasks/abc052_b

##B - Increment Decrement

まず入力を受け取ります。

```ruby
n = gets.to_i
s = gets.chars
```

2行目は文字列を一つずつ区切って、配列にしています。
入力例1でいえば、```IIDID```を```["I", "I", "D", "I", "D"]```という配列で受け取っています。

次にxを用意して、一回一回のxの結果を記録していく配列x_aryを用意します。この配列には0（xの初期値）を代入しておきます。

```ruby
n = gets.to_i
s = gets.chars

x = 0
x_ary = [0]
```

準備は完了したので、配列sをeach文で回してIだったら+1、Dだったら-1という作業を行い、それぞれの結果のxの値をx_aryに記録（追加)していきます。

```ruby
n = gets.to_i
s = gets.chars

x = 0
x_ary = [0]

s.each do |str|
  if str == "I"
    x_ary << x += 1
  elsif str == "D"
    x_ary << x -= 1
  end
end

puts x_ary.max
```

最後にx_aryの中で一番大きかった数字をmaxメソッドで出力して完成です。
[CentOS7]ログ出力場所まとめ

# ログ出力場所まとめ

毎回調べてるので備忘です。

すべてデフォルト設定を記載しています。

| 項目 | パス | 備考 |
| --- | --- | --- |
| firewall | /var/log/messages | firewall-cmd --set-log-denied=all |
| selinux | /var/log/audit/audit.log | |
| http | /var/log/httpd/access_log | アクセスログ |
| http | /var/log/httpd/error_log | エラーログ |
| 認証系 | /var/log/secure | ssh, telnet, sudo, etc. |
| cron | /var/log/cron | |
| yum | /var/log/yum.log | yum historyで良い |

自分がよく見るとこはここまで

P.S.
追加希望あればコメントください
PixelShiftとはどんな技術かという話

PixelShiftという技術に関してめちゃくちゃざっくりと備忘録がてら解説をしてみる。
(暇があれば図も後で追加します。LGMTとかストックしてくれるとモチベーション上がります。)

#デモザイク処理の課題
まず、PixelShiftのバックグラウンドとして一般的なデジタルカメラがどのように我々の目にする画像を生成しているのかという大前提があるのだが、これについてザックリと説明をする。

カメラにはご存じの通りレンズがあり、そこを通った光がフィルターを通してセンサーに当たってその光の強度により信号をA/D変換してデジタルデータとして保存している。この時に光の成分をRGBに分けるためにカラーフィルタを使うのだが、このカラーフィルタをベイヤーフィルタと呼ぶ。(正確にはメーカーによっていろんなフィルタがあるけど、一般的なものを想定しているためベイヤーフィルタで統一することにする。)
ここでフィルタを通して得られたデータは各画素のRGBの値を示しているわけだが、Rの情報がある画素にはG、Bの色情報は存在しない。(これは当たり前の話ではあるが、ここがPixelShiftの話のミソとなる。)

我々が画像を目にするとき、1画素にR,G,Bの3chの情報が合わさって初めて一般的な画像情報となるが、例えばRの情報しかない画素からほかのG,Bの情報はどうやって手に入れるのか、というとここでデモザイクという処理が登場する。
このデモザイクという処理はいわば色の補間を行うわけだが、いろんなアルゴリズムがあるので詳細は省く。
一番簡単に実装できるデモザイクアルゴリズムとしてはBiLinear補間法かと思う。
デモザイクの詳細は省くとしても、ポイントとしては補間している、つまり存在しない値を使っているということだ。
存在しない値を補間すると何が起こるのかというと、モアレやアーティファクトと呼ばれる画像特有のエイリアシング現象が起こる。
これらは、本来存在しない模様や色が画像中に出てくることを指すのだが、これらの影響をいかに小さくするのかというのがデモザイクアルゴリズムの課題でもあった。

では、これらの影響を無視するためにはどのような方法があるのかというと答えはシンプルだ。
1画素に含まれるR,G,Bすべての情報を入手できればいい。しかし、一度の撮影ではそれは不可能であることは簡単に想像がつくと思うが、どうにかして1画素のRGBすべての情報が欲しい、ということでいろんな方法が編み出されていく中で登場したのがこのPixelShiftである。

というわけでこのPixelShiftが何をやっているのかやっと本題に入れる。


#PixelShiftとは何なのか
先ほどまでの説明でPixelShiftがなにを目的としているのかは分かったと思うが、ではこの技術は何をしているのか。
PixelShiftとは、ずばりセンサを直接動かして高速で複数枚撮影する技術である。
何とも原始的な発想ではあるが、この技術のすごいところはセンサを制御する際にきっちり1ピクセル分だけ動かすというところだろう。
PixelをセンサがShiftしているからPixelShiftと、まぁそのままではあるがこれがこの技術である。
この時のGの値に関しては使用するソフトウェアでどのように取り扱うかが変わってくるかと思うが、補間を一切していないため偽色などがなくなるというのがこの技術のおいしいところである。
PixelShift撮影を行うのに適している環境としては動かないものを撮影する時である。風景なども撮影可能だが、風が強い環境下などに撮影しようと思うとゴーストなどが発生する可能性がある。

#結論
PixelShiftとはデモザイクフリーとなるセンサー制御システムのことであると言えるだろう。

何か間違った部分などがあればご指摘いただくと幸いです。
Neurotech(Braintech)のブログをやっています

**イーロンマスクが率いるNeuralinkが大きな話題を生んでいるNeurotechnology業界ですが、
そんな業界の最新情報を発信するインタビューメディア[NeurotechJP](https://neurotechjp.com)を始めました。**

![Screen Shot 2021-09-24 at 17.22.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557811/3e043d5f-1e4d-6f71-b1c3-e237ac4ced05.jpeg)


### NeurotechJPとは
https://neurotechjp.com

Neurotechnology(ニューロテクノロジー)分野の世界最先端で活躍する起業家や研究者へのインタビュー、トレンド、コラムなどを発信していきます。

最近では、[NeuroskyのCEO Stanleyさんにインタビュー](https://neurotechjp.com/jp/blog/yang-neurosky/)をしました。

是非興味あればご覧ください！
備忘録的Djangoの始め方その1

ターミナルにて
pip install pipenv
//仮想環境を構築するpipenvをインストール


cd mkdir プロジェクト名
//プロジェクト名 のフォルダを作る


cd プロジェクト名　　　　　　　　　　
//プロジェクトフォルダに移動


pipenv shell
//仮想環境構築する。仮想環境をぬける時はexit


pipenv install django
//仮想環境にdjangoをインストールする


django-admin startproject  config . 
//djangoのプロジェクトを作る。configにしとくと分かりやすい
（プロジェクト名やアプリケーション名にするとごちゃごちゃする）


configのsetting を編集
【command + f 探したり移動するvscodeのショートカット 】

TIME_ZONE ='Asia/Tokyo'
LANGUAGE_CODE='ja'
に設定する

さらに
STATIC_ROOT= os.path.join(BASE_DIR, 'static')
//staticはcssなど静的ファイルの場所でありこれの場所を明示する

ターミナルに戻り
cd  プロジェクト名　mkdir static
//上で記述したstaticフォルダを作る


ターミナルにて
仮想環境化のプロジェクトフォルダで
python manage.py startapp アプリ名　
//プロジェクトを構成するアプリケーションを作る


新しいアプリケーションを作成したら、
setting.pyのINSTALLD_APPSの配列に
アプリケーション名を追加する。

理由：djangoのテンプレート機能がそのアプリケーション内にあるtemplatesフォルダを検索できるようにするため。
テンプレートはプロジェクトフォルダ内のアプリケーションフォルダの中にtemplatesフォルダを作りその中にアプリケーションと同名のフォルダを作る。
その同名フォルダにhtmファイルを作りhtmlを記述する。
新PASMO　ICコード

#はじめに
nfcpy（version 1.0.3)でよくあるサンプル
print('  ' + '\n  '.join(tag.dump()))
でPASMOの内容を表示させようとすると
  This is not an NFC Forum Tag.
というエラーで失敗することがあります。
古いPASMOでは成功するのに比較的新しいPASMOで失敗します。
これは新しいPASMOに搭載されているICコードを
nfcpyが認識していないために発生します。

#nfcpyへのパッチ
新しいPASMOのICコードは0x31です。ICコードテーブルは
nfcpyのインストール先（~/anaconda3/envs/pasori/lib/python3.8/site-packages/nfc/など）のtag/tt3_sony.pyのFelicaStandardクラスにあります。

```python
 60     IC_CODE_MAP = {
 61         # IC    IC-NAME    NBR NBW
 62         0x00: ("RC-S830",    8,  8),  # RC-S831/833
 63         0x01: ("RC-S915",   12,  8),  # RC-S860/862/863/864/891
 64         0x02: ("RC-S919",    1,  1),  # RC-S890
 65         0x08: ("RC-S952",   12,  8),
 66         0x09: ("RC-S953",   12,  8),
 67         0x0B: ("RC-S???",    1,  1),  # new suica
 68         0x0C: ("RC-S954",   12,  8),
 69         0x0D: ("RC-S960",   12, 10),  # RC-S880/889
 70         0x20: ("RC-S962",   12, 10),  # RC-S885/888/892/893
 71         0x31: ("RC-??? new pasmo",     1,  1),  # new PASMO 
 72         0x32: ("RC-SA00/1",  1,  1),  # AES chip
 73         0x35: ("RC-SA00/2",  1,  1),
 74     }
```
上記のように0x31の行を追加します。NBRとNBW（一回で読み書きできるブロック数）は不明なので１にしておきました。
#検証
同じカードで、こんどはダンプできました。

```
Type3Tag 'FeliCa Standard (RC-??? new pasmo)' ID=00000000000000000 PMM=053143454682B7FF SYS=0003
  System 0003 (Suica)
  Area 0000--FFFE
    Area 0040--07FF
      Random Service 1: write with key & read with key (0x0048 0x004A)
      Random Service 2: write with key & read w/o key (0x0088 0x008B)
       0000: 00 00 00 00 00 00 00 00 20 00 00 ce 06 00 00 08 |........ .......|
      Area 00C0--00FF
iPhone買い替え時にやること

iPhoneを買い替えるたびにやる作業なのでまとめておきます。

**前提**
iCloud の有料プランを使っています
（クイックスタートを使い新旧 iPhone で直接データ移行をすれば iCloud の有料プランに入っていなくても大丈夫だと思いますが念のため）


---
# データ移行前にやっておくこと

## iCloud の設定調整

**iCloud の「iPhoneを探す」を OFF にする**
設定/Apple ID/iCloud/ から「iPhoneを探す」を OFF にする

**iCloud の共有設定が ON になっていることを確認**
全てのアプリ（「iPhoneを探す」以外）がONになっていることを確認する
（こう見るとiCloud対応しているアプリは案外少ないな）

## 不要なアプリの削除
データ移行が早く終わるように不要なアプリやデータは削除しておく
（個人的には、写真アプリのデータ容量が多いので「iCoud写真」共有をオフにして、データ移行の容量を減らしたいが、ここではそのままONにしている）

## 設定の見直し
設定/一般/iPhoneストレージ/ から削除できそうなデータとアプリを選別
「非使用のAppを取り除く」をONにすると少しだけ容量を削減できた
これを機に他の設定（「通知」や「Appのバックグラウンド更新」など）も見直し

## iCloudバックアップ
設定/Apple ID/iCloud/iCloudバックアップ/ から「今すぐバックアップを作成」


---
# データ移行方法

## クイックスタート
新旧iPhoneをかざして直接データ移行する（iOS12.4以降で利用可能）
案内に従って各種設定をしていきますが、途中でSiriの音声登録があります（少し音量が大きいです）
データ移行は 23GB で 5分以内には終わってました（早いな）
移行後は iPhone が自動で再起動され、2, 3分で iPhone が起動します

**参考**
[機種変更時にiPhoneをかざすだけでデータ移行！『クイックスタート』の手順と注意点｜TIME＆SPACE by KDDI](https://time-space.kddi.com/mobile/20200107/2812)

## SIMカードの挿し替え+APN設定（LINEモバイル）
SIMカードを挿し替えて、APN設定をする

**参考**
[機種変更時の初期設定（iPhone）｜LINEモバイル【公式】選ばれる格安スマホ・SIM](https://mobile.line.me/support/switch-device/setting/ios/)

## ソフトウェア・アップデート
データ移行が終わったら早めにソフトウェア・アップデートをしておく
（今回は既に新しいソフトウェア・アップデートが公開されている）


---
# データ移行後にやること

## 端末名を新しいものにする
設定/一般/情報/名前/ を開くと旧端末の名前になっているので、新しい名前に変更する

## 各種アプリの再ログイン

基本的には入っているアプリを全て開き直して、再ログインが必要なものはどんどんログインし直す
（iCloudキーチェーンを有効にしてないと大変苦痛な作業になる）

以下のアプリは別途作業が必要

### LINE
**旧端末**
ホーム/設定/アカウント引き継ぎ/「アカウントを引き継ぐ」をONにする

**新端末**
LINEアプリを開いたら、案内に従って再ログインしておく

**参考**
[【最新版】 LINEのアカウントを引き継ぐ方法 : LINE公式ブログ](https://official-blog-ja.line.me/archives/53494977.html)

### Suica
**旧端末**
以下の手順で「カードを削除」する

1. 旧端末の「ウォレット」アプリで Suica カードを選択
1. 右上の設定ボタンから設定画面を開く
1. 設定画面を下までスクロールして「カードを削除」をタップ

**新端末**
新端末の「ウォレット」アプリで Suica を呼び出す
（あれ、残高の横に「チャージ」ボタンがある。前からあったのかな？iOS15から「ウォレット」アプリからチャージ出来るようになったのかな）

**参考**
[残高も維持。Suicaを新しいiPhoneに移行する方法 | ギズモード・ジャパン](https://www.gizmodo.jp/2017/11/how-to-move-suica-to-new-iphone.html)

### 三菱UFJ銀行
生体認証とワンタイムパスワードの設定をやり直し

生体認証は顔をかざして、Face ID で認証するだけですぐに終わった
ワンタイムパスワードは電話でパスコードの案内が流れるので、そのパスコードを入力する（メモ帳を用意しておく）

### dポイント、d払い周り
**dアカウント設定**
先に「dアカウント設定」アプリでログインをしてから、生体認証もやり直し

**d払い、dポイント、マクドナルド**
「dアカウント設定」アプリを使えるようにしたら、dポイントを利用しているアプリでも再認証しておく

<!-- ### 楽天ペイ
こちらも再度設定が必要になるようだが、パッと見でどこから再認証するのか分からない
最近は使ってないし、調べるのが面倒なので、これを機会に使うのをやめておこう -->

---
# 旧端末のリセット

## iCloud からサインアウト
**（重要）必ず「iPhoneを探す」をオフにしておく**

## すべてのコンテンツと設定を消去
設定/一般/リセット/ から「すべてのコンテンツと設定を消去」を選択する


---
# おわりに
一連の移行作業は（この記事を書きながらでも）1時間もかからずに終わり、すぐに現役のiPhoneとして使用可能になりました。順調にいけば30分以内に終わると思います。
昔はデータ移行をするのに一晩中寝かせていた記憶がありますが、本当に早くなりましたね。

ちなみに、移行する前に新しいiPhoneケースとカバーは買っておくことをお勧めします。
私はいつも忘れてしまうので、次からは忘れないようにしよう。
Alveo U250 にて error could not acquire CU となるときの対処法

Alveo U250 にて Vitis Aiのexample が実行できなかったのでメモです

https://www.xilinx.com/support/answers/75975.html

>For DFX-2RP platforms, it is necessary to not only flash the base partition, but also to program the shell partition prior to running an application.

なのでshellを焼けばいいみたいです
もう逃げない。基礎から学ぶDocker入門 / Dockerfileを使用したサーバー構築（座学編）（4/9）

## はじめに

今まで、全然理解できていなくて逃げてたDockerに関して、しっかり理解していこうと思います。

https://www.docker.com/

コレまで、便利なんだろうなと思いながらも、逃げてました。

なので、開発環境では使いこなせるスキルにまでは理解したいと思います。

あと、暗記してたDockerコマンドを１つ１つ理解していきます。

以下のような順番で勉強していきます。

- [Dockerの概要（1/9）](https://qiita.com/ryosuketter/items/d7833182dced67713d27)
- [Dockerの基本操作（イメージの作成, コンテナの起動, 停止, 削除）（2/9）
](https://qiita.com/ryosuketter/items/c53352f1143366d8b9a9)
- [Dockerの基本操作（ログの出力, コンテナの中でプロセスを実行する方法, 使用していない Docker オブジェクトの削除）（3/9）](https://qiita.com/ryosuketter/items/5fd73b7311175a691dfe)
- [Dockerfileを使用したサーバー構築（座学編）（4/9）](https://qiita.com/ryosuketter/items/d9c3420be7da586225e8) :point_left_tone1: 今ここ
- [Dockerfileを使用したサーバー構築（実践編）（5/9）](https://qiita.com/ryosuketter/items/716a4c5e49795d494600)
- [Docker Composeの概要（座学編）（6/9）](https://qiita.com/ryosuketter/items/104a4eb38f8824eb6de9)
- [Docker Composeのよく使う基本操作（7/9）](https://qiita.com/ryosuketter/items/8bbd2c60392f443cfe23)
- [Docker Composeを使ってRailsの環境を構築する（8/9）](https://qiita.com/ryosuketter/items/91cd107794c1cbe358c6)
- [Docker上に構築したRailsをHeroku（本番環境）にデプロイ（公開）する（9/9）](https://qiita.com/ryosuketter/items/e3e68ce6ec572dc8905e)

## 学ぼう「Dockerfileを使用したサーバー構築」

Dockerでは、インフラの構成を記述したファイルのことを**Dockerfile**と呼びます。

本記事では、Dockerfileの詳細について説明していきます。

### Dockerfileとは

これまでは、主にコマンドを使ってDockerイメージの操作とコンテナを作成してきました（一応、簡単にDockerファイルも作りましたけどね）。

コマンド操作以外にも、Dockerfileを使うことで、ダウンロードしたベースのイメージに加えて、OSの設定やミドルウェアのインストールなどもできます。

![IMG_9E9800844768-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/c7b88d2d-9a72-1b28-c1a7-7430b2e340ad.jpeg)

Dockerfileには主に、以下のような内容を記述します。

```
- ベースになるDockerイメージ
- Dockerコンテナ内で行う操作（コマンド）
- 環境変数
- インストールするライブラリ
- Dockerコンテナ内で動作させておくデーモン
```

### Dockerfileの基本構文

Dockerfileはテキスト形式のファイルになります。

なので、VScodeなどのテキストエディタで作成・編集が可能です。

拡張子は必要なく、「Dockerfile」という名前のファイルに、インフラの構成情報を書いていきます。

「Dockerfile」という名前じゃなくてもいいそうです（ややこしいので、Dockerfileにした方がいいと思います）。

Dockerfileの基本構文は以下のようになっています。

```
命令 引数
```

Dockerfileでの主な命令文は以下の表の通りです。

命令          | 説明            
----------- | --------------
FROM        | ベースイメージの設定
WORKDIR     | 作業ディレクトリ
COPY        | ファイルのコピー
RUN         | コマンド実行        
CMD         | コンテナの実行コマンド   
LABEL       | ラベルを設定        
EXPOSE      | ポートのエクスポート    
ENV         | 環境変数          
ADD         | ファイル/ディレクトリの追加
ENTRYPOINT  | コンテナの実行コマンド   
VOLUME      | ボリュームのマウント    
USER        | ユーザーの指定       
ARG         | Dockerfile内の変数
ONBUILD     | ビルド完了後に実行される命令
STOPSIGNAL  | システムコールシグナルの設定
HEALTHCHECK | コンテナのヘルスチェック  
SHELL       | デフォルトシェルの設定   

https://hackerdemy.com/2019/09/09/docker-build/

### Dockerfileの作成

Dockerfileでは、「どんなDockerイメージからDockerコンテナを生成するか」の情報を、必ず記述する必要があります。

このイメージをベースイメージと呼びます。

ベースイメージの書き方は以下のような感じです。

```
FROM [イメージ名]
FROM [イメージ名]:[タグ名]
```

FROMは必須項目になります。

例えば、

CentOSのバージョン７をベースイメージにしたい場合

以下のような書き方になります。

```
FROM centos:centos7
```

タグ名を省略した場合は、ベースイメージの最新バージョン（latest）が適用されます。

これで、サーバー構築（座学編）はおしまいです。

次回は、Rubyをベースイメージにして、

それを元にSinatora（Ruby製のWebアプリケーションフレームワーク）を導入して、

webサーバーを動かす環境をDockerfileで作る方法を学んでいきます。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
バグゼロのプログラミングは可能か

# バグとは
開発者の意図しない動作をすることの総称である

# バグをゼロにすることができるのか
結論ほぼほぼ不可能である。特定の状況で意図しない動作を回避することは可能であるが、どんな入力があるかわからないので、無理である。開発者としてはバグを出さないようにするためにいろいろなパターンを網羅したりすることによって回避しているようではあるが、結局のところ、バグは残ってしまう。

# バグをゼロにできないのであればどうする
バグをゼロに出来ないのであればどうする？
それは簡単なことである。バグの解消に優先度をつけて優先的に解消すべきバグがどうかを判断するだけである。

# リリース後のバグの統計がシステムの改善につながる
どんなシステムでも良いのだが、まずはリリースしてみる。リリース後に上げられたバグを利用者や利用端末に基づき改善していけばいいと思う。特に、WEB関係の開発の場合、どんなプラウザでシステム利用されるかどうか分からないし。
無理に上げたバグが実はそんなに使われないのであれば、運用による回避などの方法も考えるべきであろう。

# 運用の仕事をかんがてみる
最近運用の仕事をする機会が多くなったため、開発の仕事とわけて考えた時にそんなことを思った。また、利用者目線になれる運用の仕事は開発者も一度は経験しておいたほうがよいと思われる。

# とある出向先での出来事
開発でとある企業に出向したときの出来事ではあるが、「今、このシステムはバグゼロなんだよね」といったシステムがあったわけなんだが、一日触っているだけでへんな挙動をするのがボロボロあったのにもも関われず、それは入力されないとかいって見向きもされなかった。まったく、あの会社はほんと駄目だと思いつつも、。。
Azure subscriptionの確認と切り替え

いつもAzureを操作する際にコマンドを忘れてしまうため、自分用の備忘録です。
徐々に増えていくかも。

Azureにログイン

```
az login
```


Azureサブスクリプションを指定

```
az account set --subscription "サブスクリプション名"
```
現在のサブスクリプションを確認

```
az account show --output table
```
サブスクリプションの一覧を表示

```
az account list --output table
```
AWS認定試験のバウチャーが紙屑になった話

# あらすじ

シアトルからのプレゼントで AWS認定試験 のバウチャーをもらいました。
バウチャーとはAWS認定試験を無料で受験できるチケットのようなものです。
有効期限前日、これが紙屑になった話。


# バウチャー利用はお早めに

バウチャーには有効期限があります。
自分は有効期限内に試験の申し込みをすれば良いと思っていました。
ところが違った。


# バウチャーの有効期限は試験最終日

だったのです。
来週の試験を申し込もうとすると…

```
バウチャーの有効期限を過ぎています
```

と出て申し込めません。
有効期限は明日ですから仕方ない、明日の申し込みを試みます。
しかしこれまた出来ませんでした。。


# AWS認定は24時間以上前に申し込み要

だったのです。
AWS認定サイトでの申込時に `事前承認済み試験` というメニューから試験を選択しますね。
事前承認とは事前承認が必要な試験という意味だったのでしょうか、夕方の段階で翌日の試験は申し込めません。
かくして33000円相当のAWS認定試験バウチャーは紙屑になったのでした。


# まとめ

- AWS認定は試験日時の24時間以上前までに申し込みが必要
- バウチャーの有効期限は受験可能な試験最終日
- バウチャー利用はお早めに

いやはや参りました。
Microsoft認定ではこのような制限は有りませんでしたからね…


------

みなさんはこうならないよう、お気を付け下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/7e024a40-85c1-eaba-59da-caf542373cbf.png)
ホームページ作成をしよう！（HTML、CSS編part1）

<h1>概要</h1>
一からコーディングしてホームページのデザインをしたい人向けに書いていきます。

<h2>目次</h2>
<ol>
<li>HTMLとCSSについて</li>
<li>WEB作成の準備</li>
<li>HTMLの基本構造</li>


<h2>HTMLとCSSについて</h2>
HTMLとは、HyperTextMarkupLanguageの略です。
つまりは、ハイパーテキストのための、文章に目印をつける方法を定めた文法上の約束だよ。

CSSとは、Cascading Style Sheetsの略です。
HTMLで作られたページをスタイルして（服を着せて）あげるための言語。

<h2>WEB作成の準備</h2>
初めにサイトを作るために専用のフォルダーを作ってあげよう。
作成ができたら、専用のツールかメモ帳で〇〇〇.htmlのファイルを作成しよう。
メモで作る場合は新規作成から保存時に文字コードはUTF-8に設定して、フィル名.htmlにし保存してみよう。

<h2>HTMLの基本構造</h2>

```

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ようこそ</title>
    <meta name="description" content="">
    <meta name="keywords" content="">
</head>
<body>
   <h2>はじめまして</h2>
   <p>今日から始めるHTML</p>
</body>
</html>
```

次回はタグについて詳しく書いていきます


<h2>
PHPでお手軽にサーバリソースをモニタリング

Webサービスなどを運用するにあたり、障害発生を未然に防ぐためにサーバ監視ツールを導入している方も多いかと思います。
検索すると多様なツールがあって選定に悩むところですが、高性能である必要性がなければ自作でいいじゃん！
ということで、PHPでお手軽にサーバリソースのモニタリングをやってみます。

## 環境
- CentOS 8
- PHP 8
- Apache（prefork MPM）
- MySQL

## ロードアベレージ
```php
// 過去1分間のロードアベレージを取得
$loadAverage = sys_getloadavg()[0];
if ($loadAverage > 1) {
	// ロードアベレージが１を超えてたらアラートを飛ばす処理
}
```

## ディスク
```php
$diskFree = (int) disk_free_space('/') / 1024 / 1024; // 空き（MB）
$diskTotal = (int) disk_total_space('/') / 1024 / 1024; // 合計（MB）
if ($diskFree / $diskTotal < 0.1) {
	// ディスク使用率が90%を超えてたらアラートを飛ばす処理
}
```

## メモリ
```php
// freeコマンドでtotal（メモリ合計）とavailable（利用可能な空きメモリ）の値を取得
[$memoryTotal, $memoryAvailable] = explode(' ', chop(`free -m | grep Mem | awk '{ print $2,$7 }'`));
if ($memoryAvailable / $memoryTotal < 0.1) {
	// メモリ使用率が90%を超えてたらアラートを飛ばす処理
}
```
上記はfreeコマンドでavailableの項目がある事を前提としてます。
たとえばCentOS 6などは空きメモリを取得する方法が違ってきますが、ここでは割愛します。

## メモリ（MySQL）
```php
// psコマンドでMySQLプロセスのRSS (Resident Set Size)を取得
$mysqlRss = chop(`ps -u mysql uh | awk '{ print $6 }'`) ?: 0;
$mysqlRss = round($mysqlRss / 1024, 1); // MB
```

## メモリ（Apache）
```php
// psコマンドでApache親プロセスのRSSを取得
$apacheRss = chop(`ps -u root uh | grep httpd | grep -v grep | awk '{ print $6 }'`) ?: 0;
$apacheRss = round($apacheRss / 1024, 1); // MB

// pgrepコマンドでApache子プロセス数とUSS（Unique Set Size）合計を取得
exec('pgrep httpd -U apache | while read p; do cat /proc/$p/smaps | awk \'BEGIN { a = 0 } /Private/ { a += $2 } END { print a }\'; done', $apacheProcesses);
$apacheCount = count($apacheProcesses);
$apacheUss = round(array_sum($apacheProcesses) / 1024, 1); // MB
$apacheAverage = round($apacheUss / $apacheCount / 1024, 1); // MB
```

上記はMPMがpreforkである事を前提としてます。
他のMPMやnginxなどの場合は、それに合わせて作るようにしてください。


## メモリ（slab）
```php
// meminfoからslabのメモリ使用量を取得
$slab = chop(`cat /proc/meminfo | grep Slab | awk '{ print $2 }'`);
$slab = round($slab / 1024, 1); // MB
```

## メモリ（tmpfs）
```php
// dfコマンドからtmpfsのメモリ使用量を取得
$tmpfs = chop(`df -k | grep tmpfs | awk '{ a += $3 } END { print a }'`);
$tmpfs = round($tmpfs / 1024, 1); // MB
```

## cronでログ保存
上記のようなスクリプトをcronで毎分実行してログファイルに保存。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1519519/dad74620-2c03-b649-c7b9-034905e4daed.png)

今回はCSV形式でログを残しておいて、Google Chart Toolsを使用してグラフ化してみました。
ついでにCPU使用率や転送量なども表示できるようにしています。
CPU使用率などはvmstatコマンドから算出、
転送量は/proc/net/devの情報をログに残しつつ、前回ログとの差分から毎分の転送量を算出してます。

## さいごに
OSSの監視ツールなどには到底かないませんが、お手軽＆超軽量なので、興味ありましたらぜひご参考ください。
ループ内での非同期処理(async/await)の備忘録

ループ内での非同期処理の備忘録

簡単なメモ書き

`for(... of ...)`か、`.map(await () => {})`内だと使えるが、
`.forReach`内だと`await`で同期できない（ステップを実行した時点で同期するみたい）
mavenにproxy経由でアクセス

``` bash
$ cd ~/.m2 #.m2ディレクトリに移動
$ touch settings.xml #.m2の下にsettings.xmlがなければ作成
$ vi settings.xml #公式サイトを参考にしてsettings.xmlを記述（Proxiesのところ）

$ cat settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
   <proxies>
    <proxy>
      <id>proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>プロキシサーバのアドレス</host>
      <port>プロキシサーバのポート番号</port>
      <username></username> # 今回はなかったが必要に応じて記述
      <password></password> # 今回はなかったが必要に応じて記述
      <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
    </proxy>
  </proxies>
</settings>
```

### 参考
http://maven.apache.org/settings.html
[Ktor]CSVファイルをDLさせる

## やりたいこと

こんな感じのデータがあったとして

```kotlin
data class Sale (
    val date: String = "",
    var price: Int = 0
)

val saleList: MutableList<Sale>> = mutableListOf(
  Sale("2021-01-10", 500),
  Sale("2021-03-20", 500),
  Sale("2021-02-15", 300)
)
```

以下のようなCSVにしてDLさせます

```java
"日付","売上"
"2021-01-10", "500"
"2021-03-20", "500"
"2021-02-15", "300"
```

## やり方
data classの方に、ヘッダー名の定義を設定します。

```kotlin
data class Sale (
    @CsvBindByName(column = "日付", required = true)
    val date: String = "",

    @CsvBindByName(column = "売上金額", required = true)
    var price: Int = 0
)
```

CSVにして返却します。やり方は色々あると思いますが、自分は一時ファイルに書き出して返却するようにしました。

```kotlin
// 一時CSVに内容を書き出す
val writer: Writer = FileWriter("tmp.csv")
val beanWriter = StatefulBeanToCsvBuilder<Sale>(writer).build()
saleList.map {
    beanWriter.write(it)
}
writer.close()

val file = File("tmp.csv")

// DL可能にする
call.response.header(HttpHeaders.ContentDisposition, ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, URLEncoder.encode("売上データ.csv", "UTF-8")).toString())

// ファイルを返却する
call.respondFile(file)
```

公式ドキュメントのやり方流用しているので、詳しくはこちら
https://jp.ktor.work/servers/calls/responses.html#content-negotiation
Ruby on Rails とは

webアプリ制作のフレームワーク

環境構築

・エディタ
　(VS codeなど)
・ターミナル
・SQLite
・Ruby

MVCモデルとは

・Model
　DB関連の処理を担当
・View
　画面表示(HTML)を担当
・Controller
　リクエスト受付＆レスポンス返却


migrateというファイルはcreatテーブルなどテータベースの テーブル構成を定義するためのファイル

rails db:creat ———データベースが作成
rails db:migrate ———マイグレートファイルに書かれたcreatファイルが実行
npmでモジュールインストール時にPermission deniedが出たときの対応

Serverless Frameworkやnode-gypをインストールする際に、Permission Deniedというエラーが出力され、モジュールのインストールに失敗する場合があります。

```
prebuild-install WARN install EACCES: permission denied, access '/root/.npm'
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/serverless/node_modules/snappy/build'
gyp ERR! System Linux 5.4.0-86-generic
gyp ERR! command "/usr/bin/node" "/usr/bin/node-gyp" "rebuild"
gyp ERR! cwd /usr/local/lib/node_modules/serverless/node_modules/snappy
gyp ERR! node -v v10.19.0
gyp ERR! node-gyp -v v6.1.0
gyp ERR! not ok

```

そのような場合は、以下のように `--unsafe-perm` をオプションに追加することで、インストールが可能になります。

```
sudo npm install -g serverless --unsafe-perm
```

ちなみに、上記のようなエラーが発生するケースとして、rootで `npm install -g` を実行した場合が挙げられます。rootでnpmを実行することはセキュリティやOSを含めたシステム全体の安定性の観点から出来れば避けたいものですが、しかし、モジュールの制約など、事情によりrootでパッケージをインストールせざるを得ないケースもあると思います。

npmでモジュールをインストールする際にPermission deniedになって困っている方は、必要性を判断のうえ、お試しください。
jsonファイルの読み書き Python



jsonファイルを読む方法です。

よく使うのでメモ

まずjsonファイルを作成

```json:test.json
{
  "a":"1",
  "b":"2",
  "c":"3",
  "d":"4",
  "e":"5"
}
```

次に,jsonファイルを読み書きするプログラムです。

```python:json_read_write.py
import json

def read_json_file(file_name):
  with open(file_name, 'r') as f:
    json_load = json.load(f)
    return json_load

def write_json_file(file_name, dict_data):
  with open(file_name, 'w') as f:
    json.dump(dict_data, f, indent=2)

if __name__ == '__main__':

  f_name = "test.json"
  data = read_json_file(f_name)

  new_data = {"a":"10"}
  data.update(new_data)

  new_data = {"f":"6"}
  data.update(new_data)

  f_name = "test2.json"

  write_json_file(f_name, data)
```

実行するとtest2.jsonというファイルが作成され
中身は次のようになります。

```test2.json
{
  "a": "10",
  "b": "2",
  "c": "3",
  "d": "4",
  "e": "5",
  "f": "6"
}
```

最後に,動作確認済みの環境は次の通りです。

- Python 2.7.18
- Python 3.8.10

# 追記
ちなみに外部プログラムから使用する時は次のようになります。

```python:test.py
from json_read_write import *

if __name__ == '__main__':

  f_name = "test.json"
  data = read_json_file(f_name)

  new_data = {"a":"10"}
  data.update(new_data)

  new_data = {"f":"6"}
  data.update(new_data)

  f_name = "test2.json"

  write_json_file(f_name, data)
```

## github
https://github.com/hoshianaaa/json_util/blob/master/README.md
Locust でBasic認証が必要なエンドポイントへ負荷テストを行う

## はじめに
Locustの公式ページでは[loginのエンドポイントへPOSTリクエストを投げる例](https://docs.locust.io/en/stable/writing-a-locustfile.html#writing-a-locustfile)が示されています。

しかし、エンドポイントへのアクセスにBasic認証な場合にLocustでどのようにすればいいのかは記載されておらず調べる必要があったので、調べた内容をメモしておきます。
 
## コード例
  
```python:locustfile.py
from locust import HttpUser, task, between
from requests.auth import HTTPBasicAuth

class QuickstartUser(HttpUser):

    def on_start(self):
        auth = HTTPBasicAuth(username="hoge", password="hogePass")
        self.client.get("/token", auth=auth)

    @task
        self.client.get("/hoge")
 
```
 
結論としては、上記のように [requestsライブラリ](https://docs.python-requests.org/en/latest/user/quickstart/)の`HTTPBasicAuth`でauthオブジェクトを作成して、`client`に渡すことで認証できました。(ちなみに`client`に利用されている `HttpSession`は`requests.Session`を継承しています。)

 
[requestsのAuthentication](https://docs.python-requests.org/en/latest/api/#authentication)の内容を確認すると、`HTTPProxyAuth `や`HTTPDigestAuth`もあるので、Proxy認証やDigest認証も対応できそうです。
 
## おわり
Locustを使うのは初めてだったのですが、pythonでシナリオが書け、Docker Imageも配布されていて使い勝手が良かったのでこれからも負荷試験する際にはお世話になろうと思います。

それでは、素敵なLocustライフを!

## 参考
* [Installation of Requests](https://docs.python-requests.org/en/latest/user/install/)
* [requests:API/requests.Session](https://docs.python-requests.org/en/latest/api/#requests.Session)
* [Locust: API/locust.clients.HttpSession](https://docs.locust.io/en/stable/api.html#locust.clients.HttpSession)
* [Writing a Locust file](https://docs.locust.io/en/stable/writing-a-locustfile.html)
Unity LTSの公式の呼び方が変わって、「Unity 2020.3 LTS」じゃなくて、「Unity 2020 LTS」になっている


UnityのLTSバージョン表記の話。

Unity公式が使っている「LTSのバージョン名称・表記」が変わっているようです。

---

2020年4月の公式ブログ「[Unity 2017.4 LTS の 2 年間のサポートが 2020 年 4 月で終了します](https://blog.unity.com/ja/technology/the-2-year-support-for-the-first-lts-release-2017-4-ends-in-april-2020)」では、

* Unity 2017.4 LTS
* Unity 2018.4 LTS
* Unity 2019.4 LTS

という表記をしています。自分もこの表記に慣れ親しんでいました。


![スクリーンショット 2021-09-24 14.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/a9b24bbf-3239-90d6-2fe4-25d3cb12b149.png)

---

ところが2021年3月のこちらの公式ブログ「[Unity 2020 LTS と Unity 2021.1 TECH ストリームリリースが公開されました](https://blog.unity.com/ja/technology/unity-2020-lts-and-unity-20211-tech-stream-are-now-available)」では、LTSのバージョンの表記が変わっています。

「Unity 2020.3 LTS」という表記ではなくて、「Unity 2020 LTS」という表記になっています。

![スクリーンショット 2021-09-24 14.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/45cb9d10-8206-044a-c362-e7963230d2d6.png)


なお、Unity 2020からテックリリースが3回から2回になったため、2020.3がLTSバージョンになります。

---

さらにいくつかの公式サイトを見てみます。

本稿執筆時の公式ウェブサイト「[長期サポート（LTS） + TECH ストリーム](https://unity.com/ja/releases/lts-vs-tech-stream)」には、Unity 2020以前、Unity 2019とUnity 2018のLTSにも言及されています。

それをみると

* Unity 2018 LTS
* Unity 2019 LTS

という表記になっています。従来であれば、以下のような表現となっていましたが、上記のような表現に変わっています。

* Unity 2018.4 LTS
* Unity 2019.4 LTS

![スクリーンショット 2021-09-24 14.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/598a424b-3e92-42d6-ff94-272ea4554fb0.png)

---

商業誌や同人誌、硬めのウェブ記事を執筆する際は、「Unity 2020.3 LTS」という表記ではなく、公式も使っている表記である「Unity 2020 LTS」という表記に合わせた方がよいでしょう。
AWS Direct Connect 障害対策を考える

# 0. はじめに
2021年9月2日、AWS Direct Connect (以下DX) に障害が発生しました。
概要は東京リージョンでパケットロスが多く発生するというものでした。
完全に接続が切断されるのではなくパケットロスというのが厄介ですね。
どうすれば対策できたのでしょうか。


# 1. DXの基本

- 必ず２本以上の回線を接続する
- 複数のDirect Connect ロケーションへ
- 異キャリア異ルートで
- インターネットVPNへのバックアップは要注意

## 1.1. 必ず２本以上の回線を接続する

AWS自体がたとえ開発ワークロードであろうと２つ以上の接続を推奨しています。
これはDXがそもそも障害以前に拒否不可能な計画停止が定期的に行われますから、１本では確実にダウンタイムが発生するからです。
また、２つ以上の接続が無いとSLAも適用外となります。（後述）
AWS推奨事項は以下でおさらいを。

https://aws.amazon.com/jp/directconnect/resiliency-recommendation/

## 1.2. 複数のDirect Connect ロケーションへ

これもAWS自体の推奨事項になっており、SLA適用条件の１つです。
これはDirect Connect ロケーションに障害が発生すると、そこへ接続している接続は影響を受けるからです。
以前は日本国内にはエクイニクスの東京TY2しか無く物理的に不可能でしたが、現在はTY2,CC1,OS1と３つもDirect Connect ロケーションがあります。
「専用線接続だから絶対切れない」なんてことはありません。
単一障害点は無くしていきましょう。

## 1.3. 異キャリア異ルートで

同じ回線を複数調達してもあまり意味がありません。
多くの場合、それらは同時に利用不能に陥るからです。
異キャリア（通信事業者）を利用する事で、通信事業者の障害を回避できます。
異ルート（回線が通る地理的な経路）を通す事で、災害や事故などによる障害を回避できます。
災害のみならず工事や事故等でケーブルが破断し、長期間の通信障害になる事もあります。こういった場合、異キャリアであっても同じルートを通る回線は同時に障害を受けますから異ルートが重要になります。


# 2. SLAには条件あり

DXにもSLAがあります。99.9%或99.99%。
しかしよく読むと条件がある事がわかります。

99.9%の条件（主な内容）

- 少なくとも２つのダイレクトコネクトロケーションへ接続
- ワークロードを２以上のAZへ展開
- エンタープライズサポート加入

DXの回線自体のみならず、利用するワークロード（EC2インスタンス等のAWSサービス）も冗長化してサポートに入れということですね。
99.99%の条件は更に厳しいです。SLAの詳細は以下を参照。

https://aws.amazon.com/directconnect/sla/

そしてSLAは99.9%や99.99%の動作を保証するわけではありません。
利用者がSLAを下回った場合に `申請を行う事で` 月額利用料を上限として規定額が利用料から値引きになるだけです。
自動的に値引きにはならず、利用者が申請をしないといけません。


# 3. どうすれば障害を回避できたのか

もう答えは出ていますが、複数のDirect Connect ロケーションへ接続する事です。
東京TY2と大阪OS1へ接続していたところ、OS1のみ利用するよう手動で経路を制御して回避できました。
これはAWS推奨構成図そのものですね。
なお前述の通り通信速度要件がさほど厳しく無い場合は、インターネットVPNによるバックアップも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96018/02044cf9-c4b9-924a-5042-5f5b82d3dbe5.png)

ここで重要になってくるのが、今回のような完全な接続断でなくパケットロスが増えるといった不安定な状態における対処です。


# 4. 明確な接続断でない場合の対応の難しさ

今回のDX障害はまさにこれ。
明確な接続断の場合はBGP接続も切れる為、自動で迂回されますが今回の場合、
TY2とのDX接続は接続されています。BGP経路交換もされ通信可能です。
しかし、パケットロスが多いんですね。
これは一定の閾値を設定して監視ツールからアラートを上げる運用を行うしかありません。自動化も不可能ではありませんが経路がばたつくのはよろしくありません。
閾値を低めにして早めにアラートが上げて、人間が判断して経路を制御するか静観するか決めていく方が影響が少ないと思います。


# 5. まとめ

- AWS推奨事項を守っていれば障害対策が行えた
- ただし通信品質の監視体制と手動による経路制御を行える運用体制が必要

といったところでしょうか。
ベストプラクティスは守りましょうという良い教訓ですね。


------

（参考） AWSJの公式見解はこちら。

https://aws.amazon.com/jp/message/17908/
[Nuxt.js]Nuxt + Typescript + Vuetify + Sass のプロジェクト作成

今回はNuxtの静的なビルド済みSPA(CMSサイトに埋め込むSPA)を生成するプロジェクトの作成を行います。
備忘録として記録しておきます:pencil2: (2021/09/24現在)




### 環境

```
// 使用端末
macOS BigSur v11.3.1

// Node.js
node -v
v14.17.6
```


# Nuxtプロジェクト作成

① 下記コマンドでNuxt新規プロジェクトを作成

```
yarn create nuxt-app <project-name>
```

② 初期設定は下記の通りとする
![スクリーンショット 2021-09-24 12.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415434/19857488-fbad-1b4e-32db-65c8a92a8d5f.png)


:bulb:初期設定ポイント

- Programming Language 
→ Typescript
- UI FrameWork
→ Vuetify.js
- Nuxt.js modules
→ Axios
- Linting Tools
→ Eslint
- Testing framework
→ Jest
- Rendering Mode
→ SPA
- Deployment Target
→ Static

NuxtとTypescript、Vuetifyの最低限使える設定は一旦これで完了！

# Sassをインストールする

① Sassと関連モジュールをインストールする

```
yarn add -D sass sass-loader@10 fibers
```

参考: [Nuxt公式](https://nuxtjs.org/docs/directory-structure/assets#sass)
※現在 (2021/09/24)はfibersはNodeの最新v16.10.0に対応していないのでNodeのバージョンに注意！


かなり簡潔まとめですが、
Typescript、Vuetify、Sassをで使う上での初期設定など別記事にまとめる予定です:point_up:

## Vuetifyの設定

https://qiita.com/kottyan/items/2dc798a7c7b743b45dc2
Debian10のシステム言語を日本語に変更，fcitx-mozcも入れる


研究室の同期のためにPCをセッティングしました．
同期は留学生で，システム言語など諸々英語のほうが良いでしょう！
ってことで英語でインストールしたんですよ．

ところが同期はめちゃくちゃ日本語が上手...
日本語入力できないの？って聞かれる始末...

ということでシステム言語と日本語入力化をしていきます．

## まずはシステム言語を変更する．

dpkg-reconfigureコマンドでロケール(locale)を変更する．

[Debian公式HP](https://webkaru.net/linux/debian-locales/)に変更方法は記載されています．

```
$ dpkg-reconfigure locales
```

上のコマンドでGUI？的なものが立ち上がります．
そこで「ja_JP.UTF-8 UTF-8」を探してアスタリスクを追加して下さい．
※スペースキーで追加/削除可能

## 次にデフォルトのロケールを変更する．

```
$ sudo apt-get install locales
$ sudo vi /etc/locale.gen
>>>ja_JP.UTF-8の行のコメントを解除
$ sudo locale-gen
$ sudo update-locale LANG=ja_JP.UTF-8
```

[参考サイト](https://qiita.com/tailak/items/77b90a4df07e4f6a1fc2)

これでシステム言語の変更はできました．
次は日本語で入力できるようにしましょう．

## fcitx-mozcをインストール
基本的にはインストールして，PCを再起動すれば自動的になります．
USキーボード使ってたらキーマップする必要性ありますね．

```
$ sudo apt-get install fcitx-mozc
$sudo reboot
```

必ず再起動して下さい．そうしないと反映されません．
大切なことなのでもう一回言います．
必ず再起動して下さい．
最後にもう一回言います．
必ず再起動して下さい．

## 再起動しても反映されねぇんだけど？って人は
詳しくは以下のリンクを見て下さい．
コマンドは打つ必要ないです．GUI上で完結します．
[反映されない人向け](https://cloud-work.net/linux/fcitx-mozc/#fcitx-mozc)
paramikoを使うためのscpモジュールをインストールする

前の記事でparamikoを使用した複数ホストに対して実行命令を出す記事を書きました．
ですが，おそらくモジュールのインストールが足りないと思いますので，追加で記載します．

##scpモジュールインストール

```
$ sudo apt-get update
$ sudo apt-get install openssh-clients

#おそらくここまでのコマンドでインストールが完了するはずですが
#なぜか私はエラーが発生したので，同様にエラー吐かれた人は以下のコマンドを実行

$ sudo apt --fix-broken install
$ sudo apt-get install openssh-clients
```

インストールできかた確認するには，python上でimportしてみればOKです．

```
$ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import scp
>>>

```

エラー出てないので成功です!
これでparamikoは使えます．
【個人開発】さんまを焼くだけのアプリを作ってみた

# **はじめに**
さんまが食べたいなぁと思いましたが、なかなかさんまを食べる機会がないなぁと思ったので、さんまを焼けるアプリを作成しました。

名前の通り、さんまを焼くだけのアプリです。
就活の息抜きなので約1日で作成しました。

https://gifted-curran-aecac2.netlify.app/


# 構造
HTML、CSS、JavaScriptのみのお手軽実装。
UIフレームワークとしてはbootstrapを使ってます。

# **デプロイ**

netlify

# **作ってみての感想**
m秒を使ってのストップウォッチは初めてだったので、m秒の部分の実装は結構時間かかりました。

色々UI凝ろうかなと色々いじってみましたが、さんまを焼くだけのアプリなので、simple is bestの境地に辿り着きました。

cssでさんまの焼き具合を進行させているので、始まる前のmodal出現時にすでに焼き始めたりしてしまっていたので、そこの制御も意外と手間取り...。

PC対応なので、レスポンシブデザインも追々やらないとなぁと思ってます。

# **おわりに**
暇な時間のお供、またはさんまを食べたくなった時に是非ご活用ください。

↓暇つぶしにこちらもどうぞ。

https://zen-sinoussi-c18c33.netlify.app/
カスタムフォントが本番環境で適用されない

- 初心者かつ初投稿なので読みにくいと思いますが、容赦ください

####デプロイしたがカスタムフォントが適用されていなかった
やったこと
- scssファイル編集
- yarnのインストール
- プリコンパイル

######scssファイルの編集
編集前
_fonts.scss
```@font-face {
  font-family: "Koruri-Semibold";
  src: asset_url('assets/Koruri-Semibold.ttf') format("truetype");
  font-weight: normal;
  font-style: normal;
}
```
編集後
_fonts.scss
```@font-face {
  font-family: "Koruri-Semibold";
  src: asset_url('Koruri-Semibold.ttf') format("truetype");
  font-weight: normal;
  font-style: normal;
}
```
chromeの検証ツールのエラー文を見ると、not foundとなっていたので、ファイルのパスが間違っているのではないかと思った。
調べると、本番環境では画像やフォントのファイルはassetsではなくpublicフォルダの中へ格納されると書いてあったので、パスからassetsをのぞきフォントファイルのみの指定にした。
開発環境でも問題なく適用されるのを確認済み

#####yarnのインストール
プリコンバイルする際、yarnが入ってないよというエラー？がec2のターミナルに表示されていたので、
```sudo npm install yarn -g```
でyarnをインストール

######プリコンパイル
その後改めて 
```bundle exec rails assets:precompile RAILS_ENV=production```
することで無事、本番環境でもカスタムフォントを適用させられました。

######参考にさせていただいた記事
[EC2にてnpm install yarn -gが失敗する](https://qiita.com/tsumita7/items/a40a367088018b5bbe33)
ティラノストーリーで会話に変数を組み込む

#結論

```ティラノスクリプト.js
[eval exp = " f.tmp = '文字列' + f.name + '文字列' "]
[chat_talk pos="left" name="名前" text="&f.tmp" face="chara.png" ]
[p]
```


#使用例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/95ad21a9-99fd-f9dd-e7df-56a286547178.png)

```ティラノスクリプト.js
[eval exp = " f.tmp = 'ありがとう。' + f.name + '君って優しいんだね！' "]
[chat_talk pos="left" name="名前" text="&f.tmp" face="chara/otaku_girl_fashion.png" ]
[p]
```


#手順
プロジェクト→変数管理から変数`name`、`tmp`を作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/e79c01ac-84b6-fcc0-f45c-e51e2ff83c12.png)
コンポーネント→スクリプト→ティラノスクリプトを選択して記入。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/5156e20a-29f0-21a4-1a6f-65304ba9df95.png)


#参考
[chat_talk]タグについての使い方は以下を参照した。

https://story.tyrano.jp/

https://tyrano.jp/story/story_2

https://ameblo.jp/nai10willow/entry-12384211572.html

#引用画像
https://www.irasutoya.com/2020/08/blog-post_594.html

#余談
[chat_task]タグのtextに直接変数名を含んだ文字列を描こうとして失敗したので、
一度別の変数tmpに文字列＋変数を代入し、
変数tmpを[chat_talk]タグで表示させるという方法を取りました。
ティラノビルダーでティラノストーリーのプラグインを用いているけれど、
最初に入力させたプレイヤーの名前を含んだ会話を表示させたいときに用いてください。
THENの起動有無を保存可能な「picoDBIMS」が新たに追加になりました。

#はじめに
ifLinkマイクロサービスを開発している八教と申します。

新たに「THENの起動有無を保存可能なpicoDBIMS」、スタンプラリー等の用途で使用できるIMSが追加されましたので、
紹介させていただきます。

#ifLinkとは
https://iflink.jp/

#picoDBIMSについて
ifLinkではIFで設定した条件を満たすをTHENが動きます。
IF条件は複数設定できAND条件となるため、すべての条件を満たした状態出ないとTHENが動きません。
一度満たした条件を覚えておければ、作成できるレシピのバリーエーションも増えるのではないでしょうか。

例えば
アトラクションの各所にビーコンを設置し、ビーコンに近づくとチェックインする。
すべてのビーコンにチェックインすると、ゴールページが表示され、記念品など
がもらえるなどのイベントに使用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/b2567bfc-e4cc-49a7-b93b-f8e544fe3136.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/e62eef4d-2f86-dbb1-06bd-e047df8b7d85.png)

アトラクションスタンプラリーを実際にルールで作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/ca0a8d43-b55f-e7bf-2a34-4992046437c9.png)

アトラクションスタンプラリーコンプリート判定を実際にルールで作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/2d8294e8-b583-7976-b5d7-f1851e5a2bc7.png)

今回は各所に設定したiBeaconを検知した場合にチェックインするため、BoolKeyとしました。
他にも以下の設定ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/f227b825-2a95-26aa-c893-edc3842966bd.png)

是非お試しいただければと思います。
計算式を評価して結果を送信するフィルターを行える汎用計算IMSが新たに追加になりました。

#はじめに
ifLinkマイクロサービスを開発している八教と申します。

新たに「計算式を評価して結果を送信するフィルターIMS」が追加されましたので、
紹介させていただきます。

#ifLinkとは
https://iflink.jp/

#汎用計算IMSについて
ifLinkでは温度、湿度を取得できるBLE接続デバイスが多くあります。
それぞれのセンサーデータをIF条件とすることができるが、
センサーデータ値を元に計算した値をIF条件に設定することはできません。

そこで「計算式を評価して結果を送信するフィルターIMS」が登場です。
例えば温度が28度、湿度が80％はじめじめして不快かと思いますが、
温度が28度でも湿度が40％であればそれほど不快ではないと思います。
温度、湿度のセンサーデータが取得できる場合、不快指数を計算で出すことができます。

不快指数とは
https://ja.wikipedia.org/wiki/%E4%B8%8D%E5%BF%AB%E6%8C%87%E6%95%B0

ルールイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/11626fda-0159-e086-ed3f-c87bbb066daa.png)

実際にルールを作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/a39785ed-0300-ddf7-f4ef-830a38fe871c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/355972f2-4326-1acc-9bc9-f4e0b7758f3c.png)
不快指数の計算式については以下参照
https://ja.wikipedia.org/wiki/%E4%B8%8D%E5%BF%AB%E6%8C%87%E6%95%B0


ルール上「NiceraCO2センサー」から温度、湿度を取得するような記載がありませんが、
どのように取得しているのかをデバイスサービスXMLで説明いたします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/e99a475d-39f1-ae83-bf3e-4199e1e03138.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/53d9d53c-23d1-ac21-ded4-05502e7448ee.png)


是非お試しいただければと思います。
エッジ検出するフィルターIMSが新たに追加になりました。

#はじめに
ifLinkマイクロサービスを開発している八教と申します。
新たに「エッジ検出するフィルターIMS」が追加されましたので、
紹介させていただきます。

#ifLinkとは
https://iflink.jp/

#エッジ検出IMSについて
ifLinkではIFで設定した条件を満たすをTHENが動きます。
IF条件を満たしたタイミングでTHENが動くため、THENを動かすタイミングを指定することはできません。

そこで「エッジ検出するフィルターIMS」が登場です。
例えばテストボタンでは以下の様な条件を設定できます。
・時間範囲内でテストボタンをはじめて押したら
・時間範囲内で一度もテストボタンが押されなかったら
・時間範囲内でテストボタンを押した回数が、値をこえたら
・時間範囲内でテストボタンを押した回数が、値をこえたら
・時間範囲内でテストボタンを押した回数が、値より少なかったら 
これでTHEN起動に時間を指定できるようになります。

時間内にはじめてボタンを押されたとき、ボタンを押された時間をメールで送信するルールイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/82c20f4a-4941-61e5-faca-72724afc5884.png)

指定時間にボタンが押されなかったとき、ボタンを押されてない旨をメールで送信するルールイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/737b0792-60ec-f9d6-61c4-b0305725c70e.png)


時間内にはじめてボタンを押されたとき、ボタンを押された時間をメールで送信するを実際にルールで作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/d0a76f52-7e02-bacd-e654-a8140abab867.png)

指定時間にボタンが押されなかったとき、ボタンを押されてない旨をメールで送信するを実際にルールで作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/44311451-83f7-4ea7-fc84-a79da84b82b9.png)

今回は時間範囲内にボタンを押されたら、時間範囲内にボタンを押されなかったら場合にメールを通知するルールをご紹介しました。他にも以下の設定ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780474/952c78a4-1c49-f7d0-cf11-80d108821064.png)

是非お試しいただければと思います。
【解決】django.core.exceptions.ImproperlyConfigured: Requested setting SECRET_KEY, but settings are not configured のエラーが出た。

>
django.core.exceptions.ImproperlyConfigured: Requested setting SECRET_KEY, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

というエラー文が出た。

エラー文に書いてあるようにsettingsファイルを指定してやる。
具体的にはrunserverコマンドに`--settings=[メインのアプリケーション名].settings`を追加した。
docker使っているからこんなエラーが出たのかなと思った。よーわからんけどね。。。

```yml:docker-compose.yml
  web:
    container_name: django-docker
    platform: linux/x86_64
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000 --settings=django_docker.settings
    # ↑ここに追加
    working_dir: /code
    ports:
      - 18000:8000
    volumes:
      - ./:/code
    depends_on:
      - db
```
[Kotlin]data classの配列ソート

こんな感じの配列があったとして

```kotlin
data class Sale (
    val date: String,
    var price: Int
)

val saleList: MutableList<Sale>> = mutableListOf(
  Sale("2021-01-10", 500),
  Sale("2021-03-20", 500),
  Sale("2021-02-15", 300)
)
```

dateでソートしたい場合

```kotlin
saleList.sortedWith( compareBy { it.date } )
```
Xcode 13ではNCMB Swift SDKの初期化タイミングを変更しないといけない（かも知れません）

※ 執筆時点（2021年09月現在）で検証中です

2021年09月現在、NCMBのSwift SDKをSwiftUIで利用している場合、初期化処理は次のように行うのが基本となっています。

```swift
import SwiftUI
import NCMB

@main
struct NCMBTestApp: App {
    @Environment(\.scenePhase) var scenePhase
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { scene in
                    switch scene {
                    case .active:
                        print("Initialize NCMB")
                        // APIキーの設定とSDK初期化
                        NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
                    case .background: break
                    case .inactive: break
                    @unknown default: break
                    }
        }
    }
}
```

画面が前面、バックグラウンド、アクティブではなくなったタイミングを使って判定しています。Xcode 12までは特に問題なかったのですが、Xcode 13/Swift 5.5にしたところ、emptyApplicationKeyというエラーが出るようになりました。

## 原因

ContentViewなど、呼び出される画面においてonAppearを使って、そこでデータの取得を行っていました。

```swift
struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
        }.onAppear() {
            query()
        }
    }
    
    func query() {
        print("Execute NCMBQuery")
        let query = NCMBQuery.getQuery(className: "Test")
        let results = query.find()
        if case let .failure(err) = results {
            print(err) // emptyApplicationKey
        }
    }
}
```

これは、初期化処理が行われる前にNCMBのAPIを利用した場合に起こるエラーです。

実際、デバッグメッセージを入れて、処理順番を見ると、NCMBQueryの処理が初期化前に実行されてしまいます。

```
Execute NCMBQuery
emptyApplicationKey // ← エラーメッセージ
Initialize NCMB
```

## 解決策

解決策としては、初期化処理もonAppearで行うことでしょう。

```swift
//
//  NCMBTestApp.swift
//  NCMBTest
//
//  Created by Atsushi on 2021/09/22.
//

import SwiftUI
import NCMB

@main
struct NCMBTestApp: App {
    @Environment(\.scenePhase) var scenePhase
    
    var body: some Scene {
        WindowGroup {
            VStack {
                ContentView()
            }
            .onAppear() {
                print("Initialize NCMB")
                // APIキーの設定とSDK初期化
                NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
            }
        }
    }
}
```

ContentViewのonAppearだと、やはり初期化の方が遅くなってしまうので、ダミーでVStackを定義して、それのonAppearを利用するのが良いようです。こうすることで、初期化処理とNCMBQueryの実行が、予定していた通りに行われるようになります。

## まとめ

Xcode13/Swift 5.5になって、イベントの発火タイミングが変わったのかも知れません。利用されている方はご注意ください。

[ドキュメント : 開発者向けドキュメント | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/#/Swift)