OmniAICreator/Qiita-1.07M huggingface dataset:
SQLのSUM関数内で(a - b)とさせたときの挙動

SQL実践入門を読んでいて、挙動があまりイメージできなかったため調べたことを記載します。

内容は[SQL実践入門](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-PRESS-plus/dp/4774173010/ref=sr_1_4?adgrpid=117859502103&hvadid=506541752353&hvdev=c&hvqmt=e&hvtargid=kwd-1397494344633&hydadcr=15819_11201267&jp-ad-ap=0&keywords=sql+%E5%AE%9F%E8%B7%B5+%E5%85%A5%E9%96%80&qid=1644098165&sr=8-4)を参考にさせていただいています。
サンプルコードは[こちら](https://gihyo.jp/book/2015/978-4-7741-7301-6/support)で公開されています。

## 最初に結論
SUM関数内に複数列からなる式を入れると、各行の式で得られた結果を合計しているようでした。
### 以降で実際に試してみます

### 実行環境
* Windows10 Home
* Microsoft SQL Server 2019 

## テーブル作成
サンプルテーブルを作成します。

```.sql
CREATE TABLE PriceByAge
(product_id VARCHAR(32) NOT NULL,
 low_age    INTEGER NOT NULL,
 high_age   INTEGER NOT NULL,
 price      INTEGER NOT NULL,
 PRIMARY KEY (product_id, low_age),
   CHECK (low_age < high_age));
```

データを作成します。

```.sql
INSERT INTO PriceByAge VALUES('製品1',  0  ,  50  ,  2000);
INSERT INTO PriceByAge VALUES('製品1',  51 ,  100 ,  3000);
INSERT INTO PriceByAge VALUES('製品2',  0  ,  100 ,  4200);
INSERT INTO PriceByAge VALUES('製品3',  0  ,  20  ,  500);
INSERT INTO PriceByAge VALUES('製品3',  31 ,  70  ,  800);
INSERT INTO PriceByAge VALUES('製品3',  71 ,  100 ,  1000);
INSERT INTO PriceByAge VALUES('製品4',  0  ,  99  ,  8900);
```

## SUM(a - b)を実行してみる
以下のコードでは、low_age ～ high_ageの値が0 ～ 100の連続になっている製品を取得しています。

```.sql
SELECT product_id
  FROM PriceByAge
 GROUP BY product_id
HAVING SUM(high_age - low_age + 1) = 101;
```

※0から100までなので、値の数は101個あります

実行した結果はこちらです。
<img width="160" alt="image.png (1.6 kB)" src="https://img.esa.io/uploads/production/attachments/18909/2022/02/06/119184/5893dd71-62ce-4866-a696-76888798b837.png">

## 何が疑問だったのか
SUM関数内で計算式を渡したときは、どういう順序で計算されているんだろう？
ということでした。
## サンプルコードを元に試してみる
### 改めてテーブルの全行を確認

```.sql
SELECT * FROM PriceByAge;
```

実行結果
<img width="285" alt="image.png (3.5 kB)" src="https://img.esa.io/uploads/production/attachments/18909/2022/02/06/119184/d98aabdf-5a1b-4932-8308-44c4eb7a5c4a.png">

### 各行ごと計算結果と製品ごとの合計値を両方出してみる
```.sql
SELECT product_id,low_age,high_age,(high_age - low_age + 1) AS 行の計算結果,
  SUM(high_age - low_age + 1)OVER( PARTITION BY PRODUCT_ID) AS SUM関数の結果
FROM PriceByAge
;
```
実行結果
<img width="423" alt="image.png (4.5 kB)" src="https://img.esa.io/uploads/production/attachments/18909/2022/02/06/119184/d2a73999-4714-4b7f-884c-7530818ac37a.png">

## 実行結果から理解できたこと
それぞれの実行結果を見ると以下の計算順序になっていることがわかります。

1. 各行の(high_age - low_age + 1)が計算されている

1. 括弧内の計算の後に、GROUP BY product_idによる集約が行われる

1. product_idごとにSUM関数による合計値の計算が行われる


### 感想
実際に調べてみると普通の四則演算と同じだなという感じで、
むしろなんで疑問に思ったのか不思議なレベルでした。
でも実際に動かしてみて腑に落ちたので良かったです。
(Rails)モデル作成〜マイグレーションファイルの実行まで

Railsにおけるモデル作成〜マイグレーションファイルの実行までをちゃちゃっと箇条書きで記していきます。

Railsプロジェクトを作成してからの基本の流れになるので、できれば指が覚えるところまで行きたいです(笑)
<br>
①モデルを作る
例：movieモデルを作る場合

```
$ rails g model movie
```

もし間違えて作成した場合は

```
$ rails d model movie
```

で削除して再度作り直します。

↓成功すると以下のように表示されます

```
  invoke  active_record
  create    db/migrate/20220130060030_create_movies.rb
  create    app/models/movie.rb
```

これでモデルが作成できました。

次にマイグレーションファイルです。
<br>

②マイグレーションファイルを編集する

モデルを作成したときにマイグレーションファイルも一緒に作成されます。
↓
create    db/migrate/20220130060030_create_movies.rb
マイグレーションファイルとは、テーブルの中身のカラムを作成するファイルです。

db/migrate/20220130060030_create_movies.rbを開いてみると下記のように書かれています。

```
class CreateMovies < ActiveRecord::Migration[6.1]
  def change
    create_table :movies do |t|
      
      t.timestamps
    end
  end
end
```

上のままのコードだとテーブルの中にはレコードが作成された日時を保存するためのcreated_atというカラムとレコードが上書きされた日時を保存するためのupdated_atというカラムしか作成されません。
※「t.timestamps」の記述により作成されます

カラムを作成するにはマイグレーションファイル内に下記の記述をします。

```
class CreateMovies < ActiveRecord::Migration[6.1]
  def change
    create_table :movies do |t|
      t.カラムの型  :カラム名
      t.timestamps
    end
  end
end
```


カラムの型というのはどういう状態でデータを保存するかという指定です。
文字として保存するのか数値として保存するのかといったような指定をすることができます。

カラムに指定できる型は、よく使われるものとして次のようなものがあります。


string型
255文字までの文字を保存したいときに指定します。
名前やemailアドレスなど、255文字以上にならないときはstring型を使います。

text型
255文字以上になることが予想されるときに指定します。
string型より読み込む際時間がかかるので、明らかに255文字以内で収まることが予想できるのであればstring型を使います。

integer型
整数として保存したいときに指定します。
-2,147,483,648から+2,147,483,647の整数を保存できます。
基本的に整数として保存したい場合はinteger型にしておくのが良いです。

datetime型
日時を保存したいときに指定します。
「2001-01-01 01:01:00」の形で保存されます。

references型
外部キーを追加するときに指定します。
例えばt.references :userと指定するとuser_idというカラムが追加されます。
ただしこれだけでは外部キー制約がつかないので下記のようにforeign_key: trueを記述します。

```
t.references :user, foreign_key: true
```
<br>

それでは実際にカラムを書き足していきます。今回moviesテーブルに足すのは以下の通りです。
↓
title(タイトル)
image(画像)
released_year(公開年)
country(作成国)
screening_time(上映時間)
review(レビュー)
synposis(あらすじ)

titleカラムはタイトルを保存します。
タイトルは文字として保存するのでstring型かtext型になりまが、映画のタイトルはまず255文字以上にはならないのでstring型にします。

reviewカラムも文字として保存しますが、255文字以上になることも考えられるのでtext型で作成することにします。

imageカラムは一般的にstringで作成します。

それらを踏まえた結果、今回のマイグレーションファイルの記述は下記のようになります。


```
class CreateMovies < ActiveRecord::Migration[6.1]
  def change
    create_table :movies do |t|
      t.string      :title
      t.string      :image
      t.string      :released_year
      t.string      :country
      t.string      :screening_time
      t.text        :review
      t.text        :synposis
      
      t.timestamps
    end
  end
end
```



<br>
③マイグレーションファイルを実行する
マイグレーションファイル内にカラムを記載しただけでは、データベースには反映されていません。これをデータベースに反映させるために、以下のコマンドを打ってマイグレーションファイルを実行する必要があります。

```
$ rails db:migrate
```

※ rails4までは「rake」コマンド
マイグレーションファイルを実行したら、中に記載したカラム情報がデータベースに反映されます。

<br>

あとがき…
今回はモデルを作成した際に作られるマイグレーションファイルに対する記述でした。では、今作成したmoviesテーブルに新たにカラムを追加したい場合はどうすれば良いのかというと、新たにマイグレーションファイルを作成する必要があります。データベースを編集したい場合は全てマイグレーションファイルから行います。

その部分についてはこれ以上は長くなるので他の記事で書いていきます。
※記事ができたらリンクを記載します。

　参考記事
https://qiita.com/daisuke19840125/items/b052292c51eb7e537231
https://pikawaka.com/rails/migration
PaloaltoVM(10.0.4) ウィルス対策プロファイル/セキュリティポリシー

今回はアンチウィルス機能のテストをしたいと思います。検証構成は前回と同じです。

https://qiita.com/nw-engineer/items/1d4a1988983151f86bdb

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/933cdc9c-f1fb-98a5-beae-6b72f3824059.png)


## 1. アンチウィルスプロファイル作成
管理画面にログイン後、画面上の「OBJECTS」タブから画面左の「アンチウィルス」をクリックして、画面下の「追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/6cacc51e-bba5-7cd9-a5c9-5efcf60365fd.png)

名前を「Antivirus-Test」とし「パケットキャプチャの有効化」のチェックを入れ「プロトコル」httpの「SIGNATURE ACTION」のプルダウンから「reset-server」を選択して「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/2a2805b3-49c5-1e3e-47bd-366cff43d966.png)


## 2. セキュリティポリシーへの適用
次にセキュリティポリシーに適用します。前回作成したポリシーのcloneを作成してみましょう。最上部のセキュリティポリシーが選択されている状態で、画面下の「コピー」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/f70c2bdd-5240-7b4e-9be8-7d7c6ecdfe01.png)

ルール順序から「最上部へ」として「OK」をクリックします。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/547e0c40-7edb-fbae-72bc-f6cf2ddc3e4f.png">

次に、コピー元のルールを選択して、画面下の「無効化」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/e4a4276f-20a0-ea0e-64f9-88fce4e281c4.png)

対象のルールが灰色/斜体になったのが確認できます。このように同じようなポリシーを作成する場合、コピーや無効化/有効化など状況に合わせて使い分けていくと便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/717faa83-a83a-3dfe-c02e-fc5381ea4b8b.png)

では、コピーしたルールにアンチウィルスプロファイルを適用しましょう。アクションタブを開き、プロファイル設定のアンチウィルスのプルダウンから先ほど作成した「Antivirus-Test」を選択して、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/3fc0e8d2-76c6-524e-e101-a1b07054db94.png)

セキュリティポリシーのプロファイル欄にアンチウィルスプロファイルのマークが反映されたことが分かります。コミットしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/5a17deb5-ea75-1bf7-2d2b-3c1a49e2e40e.png)


## 3. 動作確認
アンチウィルスプロファイルが正しく動作するかどうか確認するために、Webサーバにテスト用のEicarファイルを配置します。WebサーバのSSHログイン後に下記のコマンドを実行しておきましょう。

```bash
cd /var/www/html/
wget https://secure.eicar.org/eicar.com.txt
``` 


では、クライアント端末からアクセスしてみましょう。
http://*ipaddress*/eicar.com.txt

画面上は何やらブロックされた旨の画面が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/64211810-009c-5dab-4c94-bb4c90cbc87a.png)

パロアルト側のログを確認してみましょう。管理画面にログイン後、画面上の「MONITOR」タブから画面左の「脅威」をクリックします。脅威ログとしてエントリーされているのが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/8222eb54-02fc-0dc7-2724-c52db20e14f2.png)

エントリーされているログの下向き矢印をクリックします。
<img width="20" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/c6c52102-674b-2a4f-1c5d-5ed1a02774bc.png">

パケットキャプチャの内容を閲覧する事が出来ます。エクスポートしてワイヤシャークなどで確認することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/a814e6b3-6b99-020b-14dc-9a297486d306.png)

★ワイヤシャークで閲覧した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/0a4f078d-c6e9-5b43-a597-685d62dc5d49.png)

## 4. その他
次回は脆弱性保護プロファイルを使用してみたいと思いますが、残念ながらここから先の操作は評価ライセンスでは厳しい状況です。次回からはAWS環境を利用して脆弱性保護プロファイルを試したいと思います。
sudo -i をパスワードなしで実行する方法

## TL;DR
`sudo -i -u <実行するユーザ> <実行するコマンド>`（例：`sudo -i -u hoge /path/to/tool.sh`）でコマンド実行する場合、sudoersのコマンド部分は`<実行するユーザのログインシェル> -c <実行するコマンド>`（例：`/bin/bash -c /path/to/tool.sh`）の形式で指定する必要があるよ、という話。

## sudo -i について
`sudo -i`は、指定したユーザのログインシェルを評価してから、コマンドを実行するオプションで、簡単に言うと指定したユーザでログインしてコマンドを実行するため、環境変数やカレントディレクトリ等もそのユーザのログインした時の状態でコマンドが実行される。

通常、sudoersにはユーザに実行を許可するコマンドを指定するが、`sudo -i`で実行する場合はログインシェルでコマンド実行する形で指定する必要がある。

例えば、userA が userB で `/path/to/tool.sh` をパスワードなしで実行できるようにする場合、以下のように設定する。

```bash:コマンド実行
[userA ]$ sudo -i -u userB /path/to/tool.sh 
```

```diff:/etc/sudoersの設定例
- userA   ALL=(userB) NOPASSWD: /path/to/tool.sh
+ userA   ALL=(userB) NOPASSWD: /bin/bash -c /path/to/tool.sh
```
AWS Certified Solutions Architect - Associate 合格体験記



AWS Certified Solutions Architect - Associateに合格したので、勉強方法や受検の所感を書き残します。

なるべく時間とお金をかけずに合格できるよう工夫しました．

# 筆者について
- 新卒1年目(バックエンドエンジニアとして開発経験5ヶ月)
- 9月にAWS Certified Cloud Practitionerを取得
- その他IT知識レベルは応用情報技術者試験合格程度

# 資格取得の動機
- 以前にAWS Certified Cloud Practitionerを取得したが、そのステップアップとして。
- 資格に関する情報が十分であったから。

# 勉強期間
1ヶ月
平日休日問わず30分から2時間

# 勉強方法

Udemy の模擬問題集を購入し、反復して演習した。

https://www.udemy.com/course/aws-knan/

Udemyのサービス構成上、1セット65問連続で解答する必要がある。
これは問題演習効率としてはいささか悪いので、少々工夫すべき点だろう。
私の場合、1度解き終えた後の復習として、再び通しで問題演習を行うのではなく、問題の解説をひたすら読み込んだ。
あくまでも本教材の位置付けとしては、アウトプットというよりはインプットの意味合いが強いと私は考えていたため，なるべく高い回転率でインプットすることを心掛けた。

ちなみに得点率は以下のような具合であった。

- 演習テスト1: 72%
- 演習テスト2: 56%
- 演習テスト3: 63%
- 演習テスト4: 60%
- 演習テスト5: 61%
- 演習テスト6: 60%

----

初回演習時は50〜60%程度の得点率であったが、2回目演習時は90％程度まで持っていった。

上記の他に用いた教材は以下の2つ。
主にアウトプット目的で利用した。

- CloudTech

200題もの問題が無料で公開されている．

https://kws-cloud-tech.com/courses/%e3%83%86%e3%82%b9%e3%83%88%e3%82%b3%e3%83%bc%e3%82%b9

- AWS認定資格 無料WEB問題集＆徹底解説

180題もの問題が無料で公開されている．

運営母体がよくわからなかったため会員登録は行なっていないが演習は可能．
問題・解答・解説の質は良いとは言えないが，無料なので目を瞑った．

https://aws-exam.net/saa/

# 受検後所感

Udemy の模擬問題集は実際の試験よりも難易度が高いと言われている。
しかし、私が受けた試験はそれよりも難易度が高いと感じた。

私はこの一回きりしか受検をしていないので多くは語ることはできないが、問題のあたりが悪かったのかもしれない。
はたまた実力不足か…

結果は773点で合格であった。

---

引き続き努力します。
ECSについてまとめてみました。

#はじめに
こんにちは、山田です。
今回は、ECSについて調べたので記載していきます。

#ECSとは
クラウドでコンテナを本番環境利用するためのオーケストレーターであり、フルマネージド型のコントロールプレーンである。

##コンテナオーケストレーターの基本動作
管理者とサーバの間には、オーケストレーターと呼ばれる仕組みがある。
オーケストレーターの基本動作を以下に記載する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/0144f1d8-cbf6-e3f7-d7f9-c8b7f47880ef.png)

**①：管理者はオーケストレーターに指示を出す。
②：オーケストレーターはサーバの中で動作している、エージェントに対してコマンドを送る。
③：エージェントは、Dockerエンジンにdocker runなどのコマンドを送り出す。
④：イメージレジストリにコマンド送る。
⑤：イメージレジストリよりイメージをダウンロードする。
⑥：サーバ上でコンテナを実行する。**

各コンテナの状態を確認して、あるべき状態、設定状態であることを維持すること、管理することも大事な役割である。

#ECSの構成要素
ECSの構成要素について以下に記載する。

|構成要素|説明|
|-------|--------|
|**タスク**|・タスク定義に基づいて起動されるコンテナ群 <br>・タスク内コンテナは同一ホスト上で実行される|
|**タスク定義**|この設定情報をもとに、イメージレジストリのコンテナイメージを用いてコンテナが実行など、タスクを構成するコンテナ群の定義 <br> ・コンテナのイメージ場所 <br> ・要求CPUとメモリ <br> ・タスクに割り当てるIAMロール <br> ・ネットワークモード　など|
|**サービス**|・複数のタスクを束ねる単位 <br> ・あるサーバでタスクが落ちてしまった場合、このサービスの定義に基づいて必要な数のタスクが実行されていることを維持しようとする。|
|**クラスター**|それぞれのコンテナホストを束ねる。 <br> ・実行環境の境界 <br> ・スケジュールされたタスクの実行を設定可能|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/46fdd012-5a39-fc26-1699-0feb7968a278.png)

#AWS Fargateについて
Fargateは、コンテナ実行環境をサーバーレスで提供する。
アプリケーションコンテナ以外はAWSが提供するレイヤーになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/2cb1b6bb-ba7c-ed90-cec8-21dd4953a66c.png)

##AWS Fargateの特徴
Fargateの特徴を以下に記載する。

|特徴|
|----|
|**Fargateを用いることで、アプリケーションコンテナを集中的に管理することができる。**|
|**クラスターの中ではAWS Fargateが動作するため、ホスト、エージェントの管理が必要ない。**|
|**AWS Fagateの中でタスクが複数動作する。**|
|**AWS Fagateでタスクを実行する場合、それぞれのタスクに割り当てるCPU,メモリについては多数のパターンから選択して実行する。**|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/6c088a78-3c57-c6f1-1cbf-997bd2fe779f.png)
SFTPでClear Linuxに外部からセキュアに（？）アクセス

#やりたいこと
リモートから仕事をしていると、息抜きにリモートロケーション（別宅）からベース（本宅）に置いたClear Linuxにはいってごちゃごちゃいじりたいと思い、外部からSSHでファイル転送できるまでのいきさつを書きます。

参照リンク：
https://docs.01.org/clearlinux/latest/guides/network/openssh-server.html

##前提条件
OpenSSHがインストールされていること

```
sudo swupd bundle-add openssh-server
```
参考にした文にはデフォルトのポートを変えましょう、と出ていますが、ポートはFirewallのポートフォワーディングでマッピングしているので今回はそのままにします。（Port=22）

##sFTPをEnableする
SSHの設定ファイルに以下のステートメントを加えるだけ。ちなみにリモートデスクトップも使えるようにしたいのでそれも書き込んでいます。ｓFTPだけなら最初のsusbysytemだけでいいみたいです。

```
clear~ $ cat /etc/ssh/sshd_config 
subsystem sftp /usr/libexec/sftp-server
AllowTcpForwarding yes
X11UseLocalhost yes
X11DisplayOffset 10
X11Forwarding yes
```

##肝心のFTPサーバ
SFTPでいいですね。Configも特に要らないし。

参照リンク：
https://clearlinux.org/software/bundle/lftp

```
clear~ $ sudo swupd bundle-add lftp
Loading required manifests...
Downloading packs for:
 - lftp
 [100%]
...

sftp -P ${port-at-your-fw} hoge@yourd-dns-domain.mydns.jp
Password: 
Connected to yourd-dns-domain.mydns.jp.
sftp> ls
Desktop      Documents    Downloads    Music        Pictures     Public       Templates    Videos        
sftp> 
```

MyDNSさんのダイナミックDNSのサービスのおかげでドメイン名でアクセス出来るのはらくですね。（セキュリティーには注意ですが）

以上
CSS 中央寄せ

CSSで要素を中央に持ってきたいとき、
簡単なプロパティでは

_コード_

```
margin:0 auto;
```
もしくは

_コード_

```
text-align:center;
```
があります。この違いとしては
「margin:0 auto;」はブロック要素に適用されるのに対し、
「text-align:center;」はインライン要素、インラインブロック要素に対して適用されます。
ただしインライン要素に対してのmargin:auto;が適用できないのであって、
インライン要素にmargin:pixel値;は適用できるので注意です。
StyleGAN2 TensorFlowの重みをPytorchに変換する

#PytorchのStyleGANで顔画像を生成する方法です

#そろそろStyleGANをいじってみたい
StyleGAN2の公式リポジトリはTensorFlow1。
Pytorchに変換して使ってみます。

#stylegan2-pytorch

公式リポジトリとpytorchバージョンのリポジトリをクローンします。

https://github.com/NVlabs/stylegan2

https://github.com/rosinality/stylegan2-pytorch

オリジナルのチェックポイントファイルpklをpytorch形式に変換します。
事前トレーニング済みの重みは、アニメなどいろいろあります。

https://github.com/justinpinkney/awesome-pretrained-stylegan2

```shell
python convert_weight.py --repo ../stylegan2 {path_to_checkpoint.pkl}
```

Pytorchの重みptファイルと、オリジナルとpytorchバージョンの画像生成比較pngファイルが保存されます。

オリジナルと変換バージョンで同じ出力がされています。

![8d032710-11a2-44b3-b9d9-83dd7d672cd0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/4ee45df7-fd44-a6d2-524d-5a99e159eb97.png)

変換された重みptで画像を生成します。

```shell
python generate.py --sample 1 --pics 1 --ckpt {converted_checkpoint_path.pt}
```

![9ad3e037-03fd-4ccd-a32b-d6e24a23ba50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/7b84d892-0704-24c4-22c8-08b6245703cb.png)

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Flutterでスプラッシュ画面を作る

Flutterでスプラッシュ画面を作成しようと思い調べたところ下記の記事が見つかった。

https://yaba-blog.com/flutter-splash-screen/

# flutter_native_splashをインストール

最新のバージョンをインストールしたいと思い下記のように記載し`Pub get`を行ったところエラーが発生した。
開発環境のDartのバージョンは2.14.3だが、このパッケージで必要なバージョンは2.15.1であるためのインストールできないらしい。

```pubspec.yaml
dependencies:
　flutter_native_splash: ^2.0.1+1
```

```
The current Dart SDK version is 2.14.3.

Because [プロジェクト名] depends on flutter_native_splash >=1.3.3 which requires SDK version >=2.15.1 <3.0.0, version solving failed.
pub get failed (1; Because tra_english_mobile depends on flutter_native_splash >=1.3.3 which requires SDK version >=2.15.1 <3.0.0, version solving failed.)
```

利用するパッケージのバージョンを下げたところ無事にインストールが完了した。

```pubspec.yaml
dependencies:
  flutter_native_splash: ^1.1.5+1
```

# スプラッシュ画面の作成

スプラッシュ画面に表示したい画像と背景の色を設定する。

```pubspec.yaml
flutter_native_splash:
  image: "images/ToraChan.png"
  color: "FFFFFF"
```

下記のコマンドを実行してスプラッシュ画面を生成する。

```
flutter pub pub run flutter_native_splash:create
```


```
[Android] Creating splash images
[Android] Updating launch background(s) with splash image path...
[Android]    - android/app/src/main/res/drawable/launch_background.xml
[Android]    - android/app/src/main/res/drawable-v21/launch_background.xml
[Android] Updating styles...
[Android]    - android/app/src/main/res/values/styles.xml
[iOS] Creating splash images
[iOS] Updating LaunchScreen.storyboard with width, and height
[iOS] Updating ios/Runner/Info.plist for status bar hidden/visible
Web folder not found, skipping web splash update...

Native splash complete. �
Now go finish building something awesome! � You rock! ��


```

無事にスプラッシュ画面を作ることができた。

![163ov-od7uz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2458996/7a6b97bf-e873-b41f-26e9-38ed74904ce7.gif)


コードを書かなくてもスプラッシュ画面が作れるのは便利ですね。
CT再構成ライブラリのTomoPyが使えるようになるまで

CTのアライメントや再構成法を色々試せる`python`ライブラリの`TomoPy`というののをみつけた。

https://tomopy.readthedocs.io/en/latest/index.html

`Anaconda`なら簡単そうだが、`Anaconda`にアレルギーを持っているので、セルフビルドした。
オフィシャルのやり方は、下記にある。
https://tomopy.readthedocs.io/en/latest/devguide.html

なお、等方の環境は以下の通り。
・Ubuntu 20.04
・python 3.8
・cuda 11.3 (RTX3080)

# cloning

```
git clone https://github.com/tomopy/tomopy.git
```

https://github.com/tomopy/tomopy

# 依存ソフトのインストール&build

乱暴だが、`setup.py`を走らせながら必要なのを入れていった--> 失敗
きちんと依存ライブラリを先に入れましょう。
`apt`でいれた`cmake`では古いらしいので、

```
sudo apt remove cmake
```
してから、公式からダウンロード&インストール
`cmake`のパスをきちんと通しておくこと。


また、ファイル変換のモジュール`dxchange`をいれる。
`pip`だとかなり古いので、最新を公式に従っていれること。
https://dxchange.readthedocs.io/en/latest/source/install.html


ほかにも、`MKL`

```
sudo apt intel-mkl
```

https://qiita.com/termoshtt/items/6fb0f81c876de3ed1617
(Ryzenにいれても高速化するらしい、、、）

https://qiita.com/f0o0o/items/69d9b766008091a6e698#numpy-scipy-%E3%81%A7-mkl-%E3%82%92%E4%BD%BF%E3%81%86

最後に、

```
cd tomopy
python3 setup.py
```

当方の環境では、

```
python3 setup.py install --enable-cuda --enable-nvtx --enable-mkl --cuda-arch 86
```

としてみた。


# install

```
python3 setup.py install
```

で行けると思いきや

```
[Errno 13] Permission denied: '/usr/local/lib/python3.8/dist-packages/test-easy-install-385127.write-test'
```

ここからしばらく試行錯誤したが、結局`root`して入れることに。
但し、`root`からはローカルにある`site-package`が読まれないので、`root`に入ってから環境変数`PYTHONPATH`にきちんと渡しすこと。

また、ローカルとrootで`python`が同じか`which python`などで確かめておくこと。

当方は`csh`環境なので、以下のようにした。

```shell
sudo su
set path = ($path /home/hogehoge/cmake-path)
setenv PYTHONPATH /home/hogehoge/.local/lib/python3.8/site-packages
python setup.py install
exit
```

# test run

```
pip install py.test
py.test test/test_tomopy/test_recon/test_rotation.py
```

とりあえず、お疲れさまでした。

# demoscript

https://tomopy.readthedocs.io/en/1.10.1/ipynb/tomopy.html
をやってみる。ただし、等方は`jupyter`があんまりわかっていないので、コマンドラインでやってみる。

デモデータ`tooth.h5`をダウンロードし、

```
cd hogehoge
wget https://tomopy.readthedocs.io/en/1.4.2/_downloads/f2a49e30ca902adc40a6e66950a9b348/tooth.h5
```


で`python`に入って、、

```python
import tomopy
import dxchange
import matplotlib.pyplot as plt

fname = './tooth.h5'

start = 0
end = 2

proj, flat, dark, theta = dxchange.read_aps_32id(fname, sino=(start, end))
plt.imshow(proj[:, 0, :], cmap='Greys_r')
plt.show()


proj = tomopy.normalize(proj, flat, dark)

rot_center = tomopy.find_center(proj, theta, init=290, ind=0, tol=0.5)

proj = tomopy.minus_log(proj)

recon = tomopy.recon(proj, theta, center=rot_center, algorithm='gridrec')
recon = tomopy.circ_mask(recon, axis=0, ratio=0.95)
plt.imshow(recon[0, :,:], cmap='Greys_r')
plt.show()
```
AWS ソリューションアーキテクト アソシエイト (SAA) 合格体験記

# はじめに

2021年12月にAWSの初級者向け資格の「ソリューションアーキテクト アソシエイト（SAA）」に合格したので、その時の勉強法などをまとめてみました。

# 受験したきっかけ

* 以前に合格したクラウドプラクティショナーの資格の有効期限が、合格から3年後の2022年1月に迫ってきていました。
* 資格の有効期限が切れるのを防ぐ（有効期限を延長する）には、クラウドプラクティショナーに再度合格するか、上位資格に合格するかのいずれかが条件となるため、思い切って上位資格を受験することにしました。

# 受験までの大まかな流れ

|実施したこと|実施日|
|---|---|
|受験を思い立った時期|2021年10月頃|
|試験に関する情報収集の開始|2021年11月上旬|
|[オンライン問題集](https://www.crammedia.com/SAA-C02-AWS-Certified-Solutions-Architect-Associate/p/436/269)の購入|2021/11/17|
|[参考書](https://www.amazon.co.jp/gp/product/B08SGSD479/)の購入|2021/11/18|
|[問題集](https://www.amazon.co.jp/gp/product/B09F2Q7HHF/)の購入|2021/12/14|
|受験申込日|2021年12月中旬|
|模擬試験(1回目)|2021/12/23|
|試験日|2021/12/25|

* 受験を思い立った後、しばらくボンヤリとして何もしませんでしたが、11月中旬にCrammediaのオンライン問題集を買ってからは毎日少しずつ勉強しました。
 * 特に自分が使ったことのないサービスを中心に勉強を進めました。
* 模擬試験は本試験の2日前...
 * 年末でバタバタしていて模擬試験を中々受験できませんでしたが、どうにか合格水準の点数を取れました。
* 結果的に一発で合格できたものの、上記の「受験までの流れ」はあまり参考にならないと思います。

# 勉強に使ったもの

|種類|役立ち度|
|---|---|
|[改訂新版 徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書［SAA-C02］対応 徹底攻略シリーズ](https://www.amazon.co.jp/gp/product/B08SGSD479/)|★★★|
|[CramMediaの問題集](https://www.crammedia.com/SAA-C02-AWS-Certified-Solutions-Architect-Associate/p/436/269)|★|
|[AWS認定ソリューションアーキテクト－アソシエイト問題集](https://www.amazon.co.jp/gp/product/B09F2Q7HHF/)|★★★|

* 最初にCramMediaのオンライン問題集を買ったのですが、問題文の和訳に意味不明なものがある上、回答（正答）に誤りが余りにも多かったので、途中で使うのをやめました。
 * ただし掲載されている問題そのものは、実際の試験問題と同じ、もしくはかなり近いものがありました。
* 参考書の「改訂新版 徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書」は、AWSのサービスを広く学べる良書です。
 * 俗に「黒本」と呼ばれる本で、Amazonでの書籍レビューも中々高評価です。
 * ただし章末の問題はかなり簡単なので、この本だけでは合格するのが難しいと思います。
* 試験の10日ほど前に買った問題集の「AWS認定ソリューションアーキテクト－アソシエイト問題集」は、前半がサービスや用語の説明、中盤から後半にかけて問題集となっているため、問題を解いた後に分からなかった部分をこの本の前半で復習することができます。
 * Crammediaのオンライン問題集と同じく、掲載されている問題は実際の試験問題と同じ、もしくはかなり近いものがありました。

# その他

* AWS認定のアカウントにログインするまでがやっぱり一仕事。
 * 前回の試験時にAmazonのアカウントでログインしたことは覚えていましたが、Amazon.com（グローバル）とAmazon.co.jp（日本）でアカウントが違っていることを忘れていて、何度かログインに失敗しました。
* Pearson VUEの試験会場はユニーク。
 * 前回のクラウドプラクティショナー試験もPearson VUEで受験したので、前回同様だと思っていましたが...
 * 今回は何とメガネのチェックも受けました。おそらくスマートグラスでのカンニングを防ぐためだと思われます。

# 関連URL

* [AWS 認定クラウドプラクティショナー試験 合格体験記](https://qiita.com/nkojima/items/7927a7a17a271ab8d04a)
Express MongoDB コネクションプール

# MongoDBの定義
データベース=test_db
collection=user
※userドキュメントに2つデータがある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/73b4c93f-e6c7-59d4-33d6-d6080595696d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/ec4f38b5-2373-1427-be94-e0f510239f7b.png)

# ソース
``` index.js
var express = require("express");
var app = express();

const MongoClient = require('mongodb').MongoClient;

const testRouter = require('./routers/test');

MongoClient.connect('mongodb://db', { minPoolSize: 20, maxPoolSize: 20 }, async (error, client) => {
  if (error) {
    console.log('error :', error);
  } else {
    // req.app.locals.dbでアクセスできるように設定
    app.locals.db = client.db('test_db');
    // add Router
    app.use('/test', testRouter);
    // start express server
    var server = app.listen(3000, function(){
      console.log("Node.js is listening to PORT:" + server.address().port);
    });
  }
})
```
``` routers/test.js
var express = require('express')
var router = express.Router()

router.get('/', async (req, res) => {
  // connection poolを使いまわし
  const result = await res.app.locals.db.collection('user').find().toArray();
  res.send(result.map(row => row.name).join(','));
})
module.exports = router
```

# 起動確認
localhost:3000/testにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/2536c3fa-7a61-30a0-2083-5050422946df.png)

# Connectionをクローズしていないけど問題ないか確認

1. アプリ起動前のmongoのプロセス数を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/d4b4d007-a9c8-d0eb-8cc8-0bf3b0f5d9fd.png)

2. アプリ起動後のプロセス数を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/83631513-fabd-596c-a65c-dfa51203f14b.png)
※poolのサイズを20に設定しているが、なぜか22作られるのはなぞ。

3. localhost:3000/testに複数回アクセス後のmongoプロセスを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/e605fe24-6b09-b7c6-4b2b-6720ae30586a.png)

4. nodeのプロセス終了後のmongoプロセスを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/35efebc5-6d30-99f8-19a5-14ea5ef5c628.png)

:::note info
info
nodeのプロセスが切れると、close()関数を呼んでいなくても自動で解放されるっぽい
※公式でもcloseしてないので問題ないと思います。
:::
https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#mongoclient-connection-pooling

# github
https://github.com/kyosuke12345/express-mongo-connection-pool
【jupyterlab】コード非表示でhtml出力する方法

#背景
・jupyterlabでデータ解析をした結果をコード非表示で共有したい。
（プラグラムをしない人にデータ解析結果を共有する際にコードがない方がみやすい）
・jupyterlab（3.1.1）については、コード非表示で出力するための日本語記事が見つからなかった。

#環境
windows10
jupyterlab（3.1.1）
nbconvert（6.1.0）


#はじめに
jupyterlabのhtml出力は、下記画像のようなGUI操作しか知らなかった。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522967/2ffdde32-b006-f78a-9c01-bb5667f63ed7.png)

#調べてみた1
下記URLにそれらしきやり方があった。
https://nbconvert.readthedocs.io/en/latest/changelog.html?highlight=hide#new-command-line-flags
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522967/b7e65f59-920c-baeb-bd01-746b8d97e5bd.png)

#調べてみた2
それらしきやり方があったが、GUIではなくCLIでの出力のよう、、、
CLIでどのようにhtml出力するかが、そもそもわからない、、、
調べてみた結果、下記でできた！

パワーシェルを開く
↓
html出力したい.ipynbファイルがあるフォルダへ移動
↓
パワーシュルで下記を実行

```
jupyter nbconvert --to html ファイル名.ipynb
```

#コード非表示でhtml出力をしてみる
上記の「調べてみた1」と「調べてみた2」を合わせて
パワーシェルで下記を実行
（「調べてみた2」のコードの最後に「--no-input」を追記しただけ）

```
jupyter nbconvert --to html ファイル名.ipynb --no-input
```

これでコード非表示のhtml出力が完了


#まとめ
・とりあえずjupyterlabでコード非表示の出力ができた
・マークダウンで各行の説明をしないと見ずらい
・CLIの出力には他にもコマンドがあるようなので、もっと便利なものもあるかも
Ubuntu Server 20.04.3 LTS 構築#9 セキュリティ設定5-2

実施日:2022/01/22～

<<今回の内容>>
シェルスクリプトを使用して、ウイルススキャンを自動で定期的に実施する。

前回はシェルスクリプトを使用してウイルススキャンを行うための条件を検討してました。
今回から実際にシェルスクリプトを作成して、実際に動作させてみます。

:::note info
ファイル名:clamscan.sh

#!bin/bash
#clamav scan script clamscan.sh⇒スクリプトの内容
/usr/bin/clamscan \
     - i \
     - r \
     - -log=/home/ユーザー名/Documents/$(date +\%Y\%m\%d-\%H\%M\%S).log \
     - -exclude-dir=/home/ユーザー名/Documents/virus/ \
     - -move=/home/ユーザー名/Documents/virus/ \
:::

実行すると、スキャンファイル数が少ない。
スキャンオプションの -i \を外してスキャン動作を確認すると/homeの中だけをスキャンしていました。
何故？と思いつつ、.shファイルの中を確認しても判らず。手動で.shファイルを実行すると今度は/usrディレクトリ等を
スキャンしています。益々、判らなくなりその日は作業を中止。翌日に再度、手動ですると/homeの中だけです。
オプションの設定がどこかおかしいと考え、調べてみると -r のあとに /を入れないとシステム全体をスキャンしないようです。

:::note info
　-r / \  にオプション修正
:::
手動で実行すると、/usrなどスキャンしてくれるようになりました。

実行結果が出力されたので、結果を確認

:::note info
Scanned directories:44621
Scanned files:144259
Total errors:65433
/etc/clamav/clamscan.sh:行　18:構文エラー:予期しないファイル終了(EOF)です。
:::

エラー解消は次回になります。
VS Code Server for WSL closed unexpectedly が出たときの対処

# 結論
ログに出力されるページのインストラクションに従いましょう。
https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips

# 環境

- Windows 10
- VSCode 1.64.0
- WSL2
- Remote - WSL 0.64.2
- Ubuntu 20.04(WSLのディストリビューション)

# 事象
VSCodeから Remote WSLに接続しようとすると、以下のエラーが出た。
![fig01_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199887/923d2aa6-f188-7fa7-1c3a-175f2c67a07f.png)

また、以下のログがターミナルに出力された。

```
[2022-02-06 01:46:55.753] Resolving wsl+docker-desktop-data, resolveAttempt: 1
[2022-02-06 01:46:55.855] Starting VS Code Server inside WSL (wsl2)
[2022-02-06 01:46:55.855] Extension version: 0.64.2
[2022-02-06 01:46:55.855] Windows build: 19042. Multi distro support: available. WSL path support: enabled
[2022-02-06 01:46:55.856] No shell environment set or found for current distro.
[2022-02-06 01:46:56.127] WSL daemon log file: 
[2022-02-06 01:46:56.129] Probing if server is already installed: C:\WINDOWS\System32\wsl.exe -d docker-desktop-data -e sh -c "[ -d ~/.vscode-server/bin/5554b12acf27056905806867f251c859323ff7e9 ] && printf found || ([ -f /etc/alpine-release ] && printf alpine-; uname -m)"
[2022-02-06 01:46:56.389] Unable to detect if server is already installed: Error: Command failed: C:\WINDOWS\System32\wsl.exe -d docker-desktop-data -e sh -c "[ -d ~/.vscode-server/bin/5554b12acf27056905806867f251c859323ff7e9 ] && printf found || ([ -f /etc/alpine-release ] && printf alpine-; uname -m)"
[2022-02-06 01:46:56.389] 
[2022-02-06 01:46:56.391] Launching C:\WINDOWS\System32\wsl.exe -d docker-desktop-data sh -c '"$VSCODE_WSL_EXT_LOCATION/scripts/wslServer.sh" 5554b12acf27056905806867f251c859323ff7e9 stable code-server .vscode-server --host=127.0.0.1 --port=0 --connection-token=2221483658-1344409197 --use-host-proxy --without-browser-env-var --disable-websocket-compression --accept-server-license-terms'
[2022-02-06 01:46:56.600] VS Code Server for WSL closed unexpectedly.
[2022-02-06 01:46:56.600] For help with startup problems, go to
[2022-02-06 01:46:56.600] https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips
[2022-02-06 01:46:56.787] WSL Daemon exited with code 0
```

なお、このときWSLの起動はできていて、VSCodeのRemote WSLからの接続が通らない状態であった。

# 解決方法
ログに出ている、https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips を参考にする。

**1.WSL側のターミナルでwgetとca-certificatesを改めてインストールする**

```
$ sudo apt-get update && sudo apt-get install wget ca-certificates
```

**2.windows側のpowershellでWSLの設定を確認する**

```
> wslconfig /l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-20.04 
docker-desktop (既定)
docker-desktop-data
```

**3.既定のディストリビューションをRemote WSLで接続したいものにする**

```
> wslconfig /setdefault Ubuntu-20.04
```

この状態でvscodeを再起動して、Remote WSLを試みる。

# 補足
今回の事象は、既定のディストリビューションと起動しているディストリビューションが食い違っていたために起きていたと思われる。
ログの中にも、`docker-desktop` ディストリビューションに付随する `docker-desktop-data` でどうにかこうにかしようとした形跡がある。

# 参考

- [WSL の基本的なコマンド](https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips)  
記事中で紹介したリファレンス
- [VSCodeでRemote WSLが立ち上がらなくなった](https://blog.freks.jp/vscode-remote-wsl-boot-error/)  
`wsl --shutdown` 後にwsl起動すればうまくいくこともある(今回はだめでした)
トリガー機能の注意点

# はじめに
Automation 360でトリガー機能がうまく起動しないという事がありました。小さいことですが、注意点があるので書いてみます。

#  トリガー機能を使うための注意
（１）トリガーを登録した後に、実行端末で実行IDでコントロールルームにログインすること。
（２）トリガー機能を使う実行端末では、Windowsのログアウト（サインアウト）をしないこと。

※特にこの（１）を忘れがち。


# 少しだけ説明
ここで、実行端末・実行IDはAttended RunnerおよびUnattended Runner用の端末、Autoation 360のIDのこととします。
実行IDでコントロールルームにログインして初めてトリガーの監視機能が走ります。
そのため実行端末がずっと動いているときに、別端末で管理者がトリガーを登録しても実行端末でトリガーは利きません。実行端末で実行IDをコントロールルームからログアウト、再ログインしたらトリガーが動くようになります。

また、トリガーを使っている実行端末でWindowsのログアウトをしてしまうと、Windowsに再ログインしてもトリガーが利きません。Windowsに再ログインしたあとに、コントロールルームへのログインが必要です。

少しややこしいですが、コントロールルームのログアウトはしてもトリガーは利きます。
（時間たてば、コントロールルームからタイムアウトされるので、ここは当たり前ですね）


# おまけ
AA社のページでは以下の最後の部分になります。
https://docs.automationanywhere.com/ja-JP/bundle/enterprise-v2019/page/enterprise-cloud/topics/aae-client/bot-creator/working-with-automation-tasks/associate-trigger-to-bot.html
NextAuthを完全に理解する #1

# はじめに

最近，Next.jsを使ったwebアプリケーションを作り始めました．この中でログイン機能を付けたくてNextAuth.jsの導入をしたのですが，無知すぎて何をしているのかわかりませんでした．そこで，勉強を兼ねてここにドキュメントの内容を日本語訳して記しておきます．

:::note warn
**2023/06/11 追記**
NextAuth.jsはAuth.jsに変わりました．Next.js App Routerの場合の実装も併せて新しく記事を作成したのでそちらをご覧ください．

https://qiita.com/kage1020/items/fca49e9b42b972b70b8c
:::

# この記事の内容

この記事はNextAuthのドキュメントを私なりに解釈して書き留めたものです．いくつか誤りがあると思いますのでコメント等で指摘していただくと幸いです．
ドキュメントを読みたい方は以下からどうぞ．

https://next-auth.js.org

:::note warn
~~2022/02/21現在の最新バージョンは4.2.1であり，この記事はその時のドキュメントを元に書いています．~~
2022/09/25 追記
最新バージョン4.10.3に更新しました．
:::

# NextAuthとは

>NextAuth.js is a complete open-source authentication solution for Next.js applications.
>It is designed from the ground up to support Next.js and Serverless.

Next.jsやSeverlessアプリのための完全なオープンソース認証ライブラリとのこと．
また，以下の3点が特徴のようです．

* フレキシブルで使いやすい
* データベースを必要としないデータの保持
* 初期設定がセキュア

1番目について，OAuthだけでなくSNSでの認証も可能なので柔軟な設計ができるのが魅力です．
2番目について，OAuth+JWTによって個人情報を保持する必要がないので楽に設計できます．もちろん，データベースでの管理も可能です．MySQL,SQLite等多くのデータベースに対応しています．

# NextAuthを始めよう

公式レポジトリにスターターキットがあるのでこちらも参照してください．

https://github.com/nextauthjs/next-auth-example

Next.jsのアプリケーションを既に作成している前提で始めます．インストールから

```bash
npm install next-auth
# or
yarn add next-auth
```

`/pages/api/auth`に`[...nextauth].js`を作成します．Next.jsを触っていればわかると思いますが，ダイナミックルーティングですべての設定がここで反映されます．中身を以下に示しますが，各自適宜変更してください．

```js:[...nextauth].js
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"

export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    // ...add more providers here
  ],
})
```

プロジェクトのルートディレクトリに`.env.local`を作成し，以下のように書きます．あくまで一例ですので内容は適宜変更してください．

```
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=5ZzepQsBemOhhgDBcAA+bhcDFsMTz7AhznIfdZVvMHY=

GITHUB_ID=your_github_id_for_auth
GITHUB_SECRET=your_github_secret_for_auth
```

GithubのIDとsecretは以下でappを作成すると取得できます．clientとprivateを間違えないようにしてください．

https://github.com/settings/apps

認証機能を使えるようにするために，`SessionProvider`を設定します．

```jsx:/pages/_app.js
import { SessionProvider } from "next-auth/react"

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}
```

`<Component/>`以下で`session`が使えるようになります．

```jsx
import { useSession } from "next-auth/react"

export default function AnyComponent() {
  const { data: session } = useSession()
  if (session) return <div>Signed in as {session.user.name}</div>
  else return <div>Not signed in</div>
}
```

***

今回は導入まで．次回以降で内部をじっくり記述していきます．

https://qiita.com/kage1020/items/e5b0053d7046a9b1f628
cargo run single file with cargo-single

```
cargo install cargo-single
```

```
cargo single run random.rs
```

---

Refer：

https://github.com/DanielKeep/cargo-script

https://github.com/inejge/cargo-single/

https://users.rust-lang.org/t/announcing-cargo-single-conveniently-build-and-run-single-file-programs-with-dependencies/45824
yahoo_finance_api2で株価取得



最近いろいろと手を付けていたらおいている場所がいくつかに分散されてしまったのでまとめて可視化したいと思っていろいろとアプリを探したり、AppSheetで自作してみたりしたのだが、どうにもちょい足りない。
ということで、最終的には自作でどうにかできないかなというところの第一歩として単価を取得する処理を書いてみた。

使ったモジュールはyahoo_finance_api2
https://pypi.org/project/yahoo-finance-api2/

レスポンスの形式が若干使いにくいなとは思うが、それでも割と簡単にデータを取得できるなというのが感想。


```
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import datetime as datetime
import pandas as pd

def get_data(code):

  stock = share.Share(code)
  symbol_data = None

  try:
      # get_historical(period_type, period, frequency_type, frequency)
      symbol_data = stock.get_historical(share.PERIOD_TYPE_DAY, 10, share.FREQUENCY_TYPE_DAY, 1)
  except YahooFinanceError as e:
      print(f">>> [{code}] : {e.message}")
      return None

  # 日付処理のためにDataframeに変換
  df_symbol_data = pd.DataFrame(symbol_data)
  # タイムスタンプを変換
  df_symbol_data["datetime"] = pd.to_datetime(df_symbol_data.timestamp, unit="ms")
  # 日本時間へ変換
  df_symbol_data["datetime_jst"] = df_symbol_data["datetime"] + datetime.timedelta(hours=9)
  # 後でキーに使いやすいように日本時間を文字列に変換
  df_symbol_data["datetime_jst_str"] = df_symbol_data["datetime_jst"].apply(lambda x: x.strftime('%Y%m%d'))

  return df_symbol_data

# 日本株については.Tをつける：code + ".T"
stockList = ["AAPL","AMZN","FB","MSFT","sdasd","GOOGL","4661.T"]

# とりあえずの格納先：'code_日付'をキーとし、終値を格納する
# 取得できなかった場合はSKIPする
dic_stock = {}
for code in stockList:
  res = get_data(code)
  if(res is None):
    print(f">>> [{code}] : NoData : SKIP")
    continue

  print(code)
  # 終値
  num = len(res)
  for index in range(len(res)):
    dic_target = res[index:index+1].to_dict()
    dic_stock[code + "_" + dic_target["datetime_jst_str"][index]] = dic_target["close"][index]

print(dic_stock)

```


上記はColabで作ったのだがこれをgithubに簡単に連携して保存しておけるんだなということを知ったのが今日の一番の収穫。
https://github.com/RyoNakamae/finance_getdata
Node.jsでTCP/UDPソケットのIPv4・IPv6両対応は簡単に実装できる

初投稿です。

# 経緯
Node.jsでUDP双方向通信プログラムを書いている上で何故だか急にIPv6対応したくなってきました。

しかし、IPv4の方が未だ多く使用されているため、IPv4を捨てることもできず、IPv6と両方対応できるソケットはないか探してみました。

# TL; DR

## UDP

まずソケットをudp4からudp6にします。

```js
const socket = dgram.createSocket("udp4");
```
```js
const socket = dgram.createSocket("udp6");
```

そして、待受アドレスを`0.0.0.0`から`::`に変更します。

```js
socket.bind(PORT, "0.0.0.0");
```
```js
socket.bind(PORT, "::");
```

これだけです。
こうすることでIPv4・IPv6両対応のソケットを立てることができます。

## TCP

プログラムの書き換えは必要ありません。
接続先アドレスをIPv6に指定するだけで勝手にIPv6で接続してくれます。

# デュアルスタックサポート

全く知らなかったのですが、UDPの`net`モジュールの`server.listen`、`dgram`モジュールの`dgram.createSocket`のオプションには`ipv6Only`というオプションがあり、`true`にするとIPv6のみに対応したソケットができるそうです。

そもそも、IPv6には「デュアルスタックサポート」というものがついており、IPv4とIPv6アドレスを同時に持ち、IPv4とIPv6を共存させることができる機能だそうです。知らなかった

# 注意点

当たり前ですが、IPv6対応ルーター等でなければIPv6は使用できません。
その場合こんなエラーが出ます。

```js
/home/fami/udp_client.js:11
    if (err) throw err;
             ^

Error: send EINVAL xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:50002
    at doSend (node:dgram:714:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:433:18)
    at afterDns (node:dgram:660:5)
    at processTicksAndRejections (node:internal/process/task_queues:84:21) {
  errno: -22,
  code: 'EINVAL',
  syscall: 'send',
  address: 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx',
  port: 50002
}
```

製品で使用するときはIPv6を使用できるか確認し、使えるならIPv6で接続し、使えないのであればIPv4で接続する、という処理を挟めばいいと思いました。

# 最後に

`udp4`とか`udp6`とか紛らわしい名前つけないでください
Google Chat botがメンションするのに必要なUser IDを開発者コンソールに出力するスクリプト

Google Chatのbotがユーザーにメンションするには、そのユーザーの`USER_ID`を調べて、テキストメッセージに次のコマンドを埋め込む必要があります。

```
<users/USER_ID>
```
https://developers.google.com/chat/api/guides/message-formats/basic#messages_that_mention_specific_users

この`USER_ID`を調べる方法を2つご紹介します。

# Admin SDK API + Apps Scriptを使う

https://developers.google.com/apps-script/advanced/admin-sdk-directory

にあるやり方で、スクリプトエディターの左ペイン「サービス」に「Admin SDK API」を追加します。

ちなみに、オプションに `viewType: 'domain_public'` を指定しないと、組織内の情報であっても取得できないのでご注意ください。

```javascript
const email = '探したいユーザーのメールアドレス';
const user = AdminDirectory.Users.get(email, { viewType: 'domain_public' });
console.log(user.id); // Google Chat の USER_ID
```

# ブラウザーの開発者コンソールでスクリプトを実行する

https://chat.google.com で開発者コンソールを開き、次のスクリプトを実行して表示することもできます。

スペースを選択して、メンバー一覧を表示してから、次のスクリプトを実行します。

```javascript
let users = {};
for (let div of document.querySelectorAll('div[data-member-id]')) {
  const name = div.dataset.name;
  const memberId = div.dataset.memberId.split('/')[2];
  if (name && memberId) users[name] = memberId;
}
console.log(users);
```

# おまけ：スペースのメンバーをApps Scriptで取得するのが大変

Apps ScriptからGoogle Chatの[REST API](https://developers.google.com/chat/api)を使うと、botがいるスペースのメンバーを取得できます（Google Chat は個人のアカウントをAPIで操作できないため、bot をスペースに追加しないといけません）。

いろいろと試したのですが、結構手間がかかるんですよね。

- Google ChatのサービスがApps Scriptに用意されていない。つらい。
- `ScriptApp.getOAuthToken()`もつかえない。Google Chat APIのOAuth scope `https://www.googleapis.com/auth/chat.bot` をappsscript.jsonに追記したが、対応していなくて怒られる。
- [サービスアカウントを作って、鍵をダウンロード](https://developers.google.com/chat/how-tos/service-accounts)して、[OAuth2ライブラリー](https://github.com/googleworkspace/apps-script-oauth2/blob/master/dist/OAuth2.gs)を使えばAPIは使える。
  - けど[botを管理者に許可してもらった](https://support.google.com/a/answer/7651360?hl=ja)うえで、そのbotをスペースに追加しないと、メンバーの情報は取得できない。つらい。
docker-compose.yml の設定を.envで外出し

# 概要

- docker-composer.ymlファイル内で使用する定数を.envファイルで外出しする方法をまとめる

# 参考

- 今回の説明に使用したファイル
    - [https://github.com/miriwo0104/mailcatcher_docker](https://github.com/miriwo0104/mailcatcher_docker)

# 方法

- docker-composer.ymlファイルと同階層に.envファイルを作成して設置する。
- 例えば下記のように記載すればmailcatcherのポートは.envで定義されている`MAILCATCHER_PORT`の値で指定されポートフォワーディングされる。
    - docker-compose.yml

        ```docker-compose.yml
        version: "3.0"
        
        services:
          mailcatcher:
            image: "schickling/mailcatcher:latest"
            ports:
              - ${MAILCATCHER_PORT}:1080
        ```

    - .env

        ```
        MAILCATCHER_PORT=1080
        ```

- `$ docker-compose up -d`で当該のコンテナを建てて[http://localhost:1080/](http://localhost:1080/)にアクセスしたところmailcatcherが正常に表示されていた。

# 参考文献

- [https://matsuand.github.io/docs.docker.jp.onthefly/compose/environment-variables/](https://matsuand.github.io/docs.docker.jp.onthefly/compose/environment-variables/)
【Coursera】AI for Medical Diagnosis -Week3 Medical Image Segmentation

全体の俯瞰記事は以下の記事をご覧ください
[【Coursera】AI for Medical Diagnosisレビュー](https://qiita.com/makki_maki04/items/876b31c62cca2a07313d)

# Week3: Medical Image Segmentation
Week2までは、画像データに判定結果を与える問題を考えました。Week3では、これら分類問題に加え、画像中のどこに病原があるかも出力させます。Image segmentationと呼ばれるタスクです。解析データには、MRIと腫瘍画像を用います。

## Image segmentation
MRIデータを扱います。これまでのX線画像とは違い、深さ方向が追加された3Dデータでありより高度な処理が必要になることを学びます。（→詳しくは"coronal view"についてWikiを参照：[リンク](https://ja.wikipedia.org/wiki/%E5%86%A0%E7%8A%B6%E9%9D%A2)）
3軸方向それぞれにスライスされた画像を3チャネルの1枚画像に押し込めた処理について学びますが、3チャネルにする理由は特になく4でも5でもよいという話がありました。
また、あるチャネルの画像がもし傾いてしまっている場合などの前処理はどうするかの概念として、`Image registration`という概念が紹介されています。Image registrationについては講義で詳しく説明されないようです。

## 他
- 2D approach: 2D画像を1枚ごとにsegmentationモデルに通し、最後に3D化する。しかしここで用意したデータは深さ方向のコンテキストを学習できない。
- 3D approach: voxelの塊をモデルのインプットにして、画像深さ方向のコンテキストも学習させる。しかしvoxelは元画像の分割後のデータであるため、空間方向のコンテキストを学習できなくなる。  
- SegmentationモデルにはU-Net（[U-net開発者による解説](https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/)、[論文](https://arxiv.org/pdf/1505.04597.pdf)）を使用。**チュートリアルノートブックがあるが、ちょっとわかりづらいという感想。**
- Data augmentation: segmentation結果も同じようにオーグメンテーションする
- Loss function: soft dice lossについて解説


## Practical considerations
実際の医療現場でこれらが用いられてないのはなぜか？このようなAIアルゴリズムを導入するうえでの課題を考えていく。

`例`

- 問題の一般化の難しさ。たとえば、インドでは結核(tuberculosis)が一般的な病気だがそれを診断するアルゴリズムをそのままアメリカで適用とすると失敗する。
- MRIの画像レゾリューションが先進国と発展途上国で異なる。データレゾリューションを一般化しないといけない。
- External validation
- 実際の現場にAIアルゴリズムを適用することの難しさについて、一般論的な話題を解説



## 課題
### クイズ
省略
### コーディング
- MRI画像で何を判断するか
- MRI画像データセットに対する標準的な前処理方法
- セグメンテーションのメトリックとロス関数
- セグメンテーションモデルの可視化と評価方法

課題のアイテムは以下のような感じでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384231/040549fd-7d55-5dba-43fb-b12d7db3a8ef.png)
MRI特有の前処理から始まり、U-Netをつかったモデル構築、ロス関数の設定、学習から評価まで総合的な問題になってました。

## Summary of AI for Medical Diagnosis
Week2とは違い、Week3はモデル構築に重きが置かれ実務で必要になりそうな事項の基礎を全てカバーした内容でした。モデル実装能力だけではなく、医療現場にAIを導入するのに障壁となっている点の解説もあり、それを克服するために必要な技術および構想のセンスが磨かれると思います。
MacとWinの画面キャプチャ方法

# Winでおすすめの画面キャプチャソフト
Rapture
http://www.knystudio.net/

通称「おにぎり」。
エンジニアになって初めてのシステム保守の仕事で上司から教わったツール。
テスト結果を残しておくのにとても便利だった。

趣味でも活躍している。
楽譜をキャプチャして簡単に上下で連結などできるので見やすい楽譜を簡単に作れる。
保存先の指定でキャプチャした画像をどんどん指定の保存先に保存していくことも可能。

# Macおすすめ方法

元から便利なキャプチャ機能は備わっている。
ただショートカットキーの設定がデフォルトだと使い辛いので
自分で使いやすい設定にするのがおすすめ。

![スクリーンショット 2022-02-06 10.52.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/cd385b0f-8edb-ce0a-5076-5d6dbafc315a.png)
[Python / PyTorch] RuntimeError: "nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Double' の原因

# 概要

PyTorchを使っていたら、
`RuntimeError: "nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Double'`
というエラーが発生して困った。

stackoverflowで[こんな記事](https://stackoverflow.com/questions/69742930/runtimeerror-nll-loss-forward-reduce-cuda-kernel-2d-index-not-implemented-for)を見つけたが、いまいち何言ってるかよくわからない...(；ﾟДﾟ)

という状況下で、原因を特定できたので共有しておこうという記事。
（日本語の記事がなかった）

# 原因

## 言葉で説明

pytorchのデータセットに渡す`目的変数`が、「`本来は整数値`じゃないといけないのに、浮動小数点数になっていた」場合に発生している模様。

## コードで該当箇所を説明

私の場合は、多クラス分類タスクに対するモデルを実装していた。
そして、原因になっていた目的変数の作成箇所はここ。

```python:datasetを作成している部分
x_train_val = torch.tensor(bow_train_val, dtype=torch.float32)
x_test = torch.tensor(bow_test, dtype=torch.float32)

t_tr_val_torch = torch.tensor(t_train_val_ndarray, dtype=torch.float64)  # <- 分類問題なのに float64 を指定している
t_test_torch = torch.tensor(t_test_ndarray, dtype=torch.float64)         # <- 

dataset_train_val = torch.utils.data.TensorDataset(x_train_val, t_tr_val_torch)
dataset_test = torch.utils.data.TensorDataset(x_test, t_test_torch)
```

対策としては、こうするだけでOKでした！\( ˙꒳˙ \三/ ˙꒳˙)/
※該当箇所を、`torch.float64` -> `torch.int64`へと変更。

```python:datasetを作成している部分
x_train_val = torch.tensor(bow_train_val, dtype=torch.float32)
x_test = torch.tensor(bow_test, dtype=torch.float32)

t_tr_val_torch = torch.tensor(t_train_val_ndarray, dtype=torch.int64)  # <- 分類問題なので int64 にした
t_test_torch = torch.tensor(t_test_ndarray, dtype=torch.int64)         # <- 

dataset_train_val = torch.utils.data.TensorDataset(x_train_val, t_tr_val_torch)
dataset_test = torch.utils.data.TensorDataset(x_test, t_test_torch)
```

# 最後に

おそらく、取り扱っているタスクによっては、必ずしもint64が正解ではないと思う。
けれども、少なくとも分類タスクなら、「**目的変数は浮動小数点数ではない**」はず。
そこを見直すと良さそう。（自戒）
rubyでの正規表現問題の解説

rubyシルバーを勉強していくなかで、rubyの正規表現についてわからなかったので、解説していこうとおもいます。

今回は問題をもとにして、解説していこうとおもいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/73888b2b-db40-569c-ce28-830c28ad3642.png)

この問題を解く上で、必要になる知識が
➀破壊的メソッド
➁正規表現

##➀破壊的メソッド
破壊的メソッドとは、オブジェクト自体を変更してしまうメソッドのことです。
破壊的メソッドがあるなら、非破壊的メソッドもあります。
言われてもピンとこないとおもいますので、この2つを比較しながら実際にコードを見ていきましょう

```
##非破壊的メソッド
string = 'abcdefgh'
string.delete('a')
=> "bcdefgh"
p string
=> "abcdefgh"


##破壊的メソッド
string = 'abcdefgh'
string.delete!('a')
=> "bcdefgh"
p string
=> "bcdefgh"
```
この2つからも分かる通り、前者は、aを削除しているのですが、stringを出力すると、aは削除されていないんですよね。
それに対して、後者は、aを削除して、stringを出力すると、a自体も削除されてしまうんです。

破壊的メソッドは原則的にメソッドの最後に「!」がつきます。あくまで原則ですので、気をつけてくださいね。
update,clearメソッドは「!」はついてませんが、破壊的メソッドです。

##➁正規表現
とっつきにくいかもしれませんが、めちゃ大事なので勉強していきましょう。ぼくは[こちら](https://murashun.jp/article/programming/regular-expression.html)のサイトを参考にしているので、こちらをブクマしてみてください！

##今回の問題
実行結果をみたとき、「あー、破壊的メソッドじゃないとだめだなぁ」って思わないといけないですね。
そのため、選択肢➁、➂に絞られることがわかります。
選択肢➂をみていきましょう。
この選択肢での、正規表現の中身は「0と5~9以外の数字と-を削除する」という意味です。
そのため、この選択肢はダメですね

選択肢➁が正解になります。
2,3,4 と 1 と - 『以外を』全て削除するという意味ですので、これが正解になります。

以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。
JARファイルとは

# 「JARファイル」という言葉
SprigでWebAPIを作ろうと参考サイトを見ながら作成を進めていくと
「JARファイル」という言葉が出てきた。

# JARファイルとは
簡単に言うとJavaファイルをzip形式で圧縮したもの。
でも普通の圧縮ファイルが解凍して展開しなければ中身を使えないのに対し、
JARファイルは圧縮ファイルのまま中のJavaファイルを実行できる。
「JAR」の名前の由来は「Java Archive(記録、書庫）」から。

# 使い方
JARファイルの作成から実行までは以下のサイトが参考になります。
https://www.tech-teacher.jp/blog/java-jar/

# 実行までの流れ
適当なテキストエディタでJAVAを書いて、コマンドでクラスファイルにコンパイルします。
さらにjarコマンドでJARファイルに圧縮します。
事項にはマニフェストファイルが必要なのでこれを作成。
最後にjavaコマンドで実行します。

# 調べてみて
１年以上javaに触れているが、実行方法については詳しく知らなかった。
他の言語でも実行方法についてあまり勉強できてないので
もっと調べて詳しくなりたいと思いました。
Vueのhtml要素を参照する方のrefについて気づけなかった挙動について

# はじめに

　前回に引き続きVueのお話。これもまた挙動で悩んでいた問題。

　Composition APIでも引き続き有効なHTML要素自体を参照するref。Option APIの頃と違い、使い方はかなりスッキリしている。

```javascript:test.js
const hogeelement = ref(null);
```

```vue:test.vue
<input type="file" ref="hogeelement" />
```

Option APIの頃は、やれ$refとしなきゃいけないとか少し気をつけないといけなかったが、Composition APIのほうだと他のリアクティブな変数と同様にref()（Vue.ref()）で使いたい名前で定義するだけ。

# 問題

　HTML要素自体を参照するref。なぜか参照できない問題にぶち当たった。
　リアクティブにも気をつけていたし公式のリファレンスを見て使い方間違っていないと確認したはずなのに。
　多数のプロパティといくつか参照が必要な要素があったのでオブジェクトに内包してまとめて管理して使いたかったのだ。

```javascript:test.js
const manageObj = Vue.ref({
  hogeelement: null,
  fooelement: null,
  prop1 : "aiueo",
  prop2 : 123
});
``` 
```vue:test.vue
<input type="file" ref="manageObj.hogeelement" />
<span ref="manageObj.fooelement"></span>
```

いざ他の処理内で `manageObj.hogeelement.value` とか `manageObj.fooelement.scrollLeft = 123;` という感じで使おうとしても、一切使えなかった。コンソールにエラーすら出ていない。しかし想定していたように処理が進まなくて悩んでいた。


# 解決

公式のリファレンスでいうとこのあたりがどうやらポイントなようだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/2f068777-3725-8e5f-53ef-1856da9a17a7.png)

　つまり、あるオブジェクト配下の子プロパティとしてHTML要素の参照を保持しておこうとしてもダメなのだろう。
　やるなら、最初の例の通りに `const hogeelement = ref(null);`として直接的な変数名として定義し、HTML側でもその名称だけで参照しなければいけない。

　ちなみに次のようにしても **ダメ** だった。

```javascript:test.js
//---ダメだった例
const manageObj = {
  hogeelement : reactive(null),
  fooelement : ref(null)
};
```

　親オブジェクト**が**リアクティブなオブジェクトでダメなら、親は普通のオブジェクトにして子をリアクティブにしてどうだ？・・・と考えたが、これでもできなかった。
　当然か。
　refキーがそもそも **foo.bar** と ドット区切りではキー名が一致できないということなんだろう。

# 終わりに

　HTML要素への参照を保持しておきたいなら、ref()関数は単体で定義しよう。自分自身の管理のためにあるオブジェクトの子プロパティに参照を保持して・・・とはできない。
　単体で定義するとごちゃごちゃしてきてわかりづらくなる・・・という問題が出てくるが仕方ない。というかそもそも直接的な参照をしないでも済むようにVueの仕組みが出来ているはずなので、使う機会が少なければそれに越したことはないのだ。
　気をつけたい。
laravel Carbonまとめ

# 目的

- 日付関係の処理で非常に便利なCarbonについてまとめる

# 共通理解

- Carbonを使って日付情報系の処理を実施したいコントローラークラスやサービスクラスのファイルに下記のuse宣言を追記する。

    ```php
    use Carbon\Carbon;
    ```

# 只今の日時情報を取得

- 下記のように記載することで只今の時刻を取得する事ができる。

    ```php
    $date_infos = Carbon::now();
    ```

# 本日の日付情報を取得

- 下記のように記載することで本日の日付情報を取得する事ができる。

    ```php
    $date_infos = Carbon::today();
    ```

# 明日の日付情報を取得

- 下記のように記載することで明日の日付情報を取得する事ができる。

    ```php
    $date_infos = Carbon::tomorrow();
    ```

# 昨日の日付情報を取得

- 下記のように記載することで昨日の日付情報を取得する事ができる。

    ```php
    $date_infos = Carbon::yesterday();
    ```

# タイムゾーンを指定して日付情報を取得

- 下記のように記載することでタイムゾーンを指定して本日の日付情報を取得する事ができる。（本日、明日、昨日どのヘルパメソッドでも可能）

    ```php
    $date_infos = Carbon::today('Europe/London');
    ```

# 

# 参考文献

- [https://carbon.nesbot.com/](https://carbon.nesbot.com/)