OmniAICreator/Qiita-1.07M huggingface dataset:
DVCでのデータの登録を複数人で行う場合の注意　ー 手順を間違えるとデータを失える ー



## DVC(Data Version Control)とは
- 大量のデータをバージョン管理するツール
- この記事では、複数人でデータの登録を行う場合の注意を述べます。

### 特徴
- 個別のファイル単位に差分を明示してバージョン管理するツールではない。
- 大量のデータが含まれたフォルダをありのままで管理するツール。
- 対象のフォルダのmd5の値で、その時点のそのフォルダの状況を管理している。
-  *.dvc は、その状態を記載している。
- dvc のコマンドは、dvc管理対象下のフォルダを登録したり、特定版のデータを取り出すこと行っている。
- dvcでの管理データはgit と連携している。
- *.dvc　ファイルはgitでのバージョン管理の対象になっている。
### DVCに関する記事
　
DVC の本家
https://dvc.org/

qiitaの記事の例
https://qiita.com/meow_noisy/items/a644547930e6f2dea12d

### DVCにデータを追加するとは
dvc へのデータの追加

```
dvc add ${対象のファイル・フォルダ}
```

このとき除外したいファイルパターンは
`.dvcignore` ファイルに記載しておく。

dvc push で反映する。

```
git add *.dvc
git commit -m "commit message"
git push
```

### DVC で登録してあるデータを利用するには
以下の手順をふんでいけば、DVCに登録されたデータを利用するには十分だ。

```
$ git checkout main
$ git pull
$ dvc pull
```

#### dvc pull に失敗する場合
ケース１：　DVCのデータのリモートストレージにアクセス権限がない。
対応策：　リポジトリのメンテナンス担当者に問い合わせください。Google Cloud Stoage やAmazone S3などのアクセス権限をつけてもらってください。
ケース２：　dvc pull で以下のエラーがでる。DVCで登録した版に比べて、dvc pullをしている側のDVCの版が古い。
対応策：　新しい版のdvcをインストールして、dvc pull を実行してください。

## git の複数のPRの場合
### A さんの作業
```
$ git checkout -b feature/some1
# file1 へのある変更をする。
$ git add file1
$ git commit -m "メッセージ" 
$ git push
```
### B さんの作業
```
$ git checkout -b feature/some2
# file1 への別の変更をする。
$ git add file1
$ git commit -m "メッセージ" 
$ git push
```

### 例：githubでのPRの承認とマージ
- git では、同一のファイルにそれぞれ別の変更が入っていても、自動で解消できる部分は、解消してくる。
- 自動で解決できないconflictを発生した場合には、利用者の側にconflictが生じていることを告げ、conflict の解消を求めてくる。
- 利用者は、conflictを解消してcommit を行い、git psush し、PRを更新して、マージを行う。
- そのため、git自体では、異なるPRを同時に作っていても、問題なく作業を続けられる。

## dvc を複数人で登録作業するときに何が起こりやすいか
- dvc pullがすること
- *.dvc にある情報を元に、フォルダに対するmd5sum の情報から、dvc管理下のフォルダの中身を再現します。
- 中身を再現するということは、.dvcignoreに書かれていないファイルについての状況は一致させるということを意味します。
- つまり、余分なファイルがあれば削除することも実施します。

### 失敗する方法（やっちゃダメ）
1. AさんがDVCでデータを登録するためにfeature/byA のブランチを作った。
1. Aさんは、変更点を作ってそのブランチに登録した。
1. しかし、まだブランチのPRのマージは完了していない
1. BさんがDVCでデータを登録するためにfeature/byB のブランチを作った。
1. Bさんは、変更点を作ってそのブランチに登録した。
1. BさんのPRは承認され、その変更点はmain(もしくは master) に反映された。
1. Aさんは、Bさんによる反映を取り入れようと思って、以下の処理をする。
    まずは、main を更新しておこうと思って、` git checkout main; git pull ` を実行する。
    そして、`dvc pull` を実行する。
1. この時点でDVC管理下のフォルダを見る。
1. 自分がDVC管理下のフォルダに追加した改変がことごとく消えていることに気づく。

### 起こったこと
- git pull した時点での *.dvc のmd5sumを生じたときのファイル構成になるように改変される。
- その結果、DVC管理下のフォルダにあった未登録の改変が失われる。
### 教訓
- DVC には、conflictを楽に避ける仕組みがない（らしい）。
## どうすればいいのか
- ファイルを追加だけの場合：
    - 追加予定のデータをDVC管理下のフォルダの外に退避する。
    - 作りかけていたbranch　は放置する。
```
# 以下の手続きで、mainの最新の状況にする。
$ git checkout main
$ git pull
$ dvc pull

$ git checkout -b feature/remake
# 対比していたデータを、DVC管理下の目的の場所におく
$ dvc add 追加したデータのあるフォルダ
# リモートの保存先に反映する。
$ dvc push
$ git commit -m "コミットメッセージ"
$ git push

```

## 運用への提案
- DVCでバージョン管理するデータ管理者は１名になるようにするのがのぞましい。
- 別々に改変をする場合には、conflictを生じないように、改変の変更の順序を複数のデータ管理者で調整して行ってください。


ー---
DVC のドキュメントには以下の記述があった。
適切な運用をすればなんとかなるらしい。
しかし、まだ十分確かめていない。

[How to Resolve Merge Conflicts in DVC Metafiles](https://dvc.org/doc/user-guide/how-to/resolve-merge-conflicts)
【Rails】カラムにNOT NULL制約を追加する方法

カラムにNOT NULL制約を追加するにはマイグレーションファイルに以下のように記述します。

```rb

def change
  change_column_null :テーブル名, :カラム名, false
end

```

`users`テーブルの`is_sample`カラムにNOT NULL制約を追加する場合は以下のようになります。

```rb

def change
  change_column_null :users, :is_sample, false
end

```
AWS SAA 模試直し④

# 現状
Udemyの講座をすべて視聴完了（約１ヶ月半かかった）
AWS-CLI取得済

# 今回の模試の結果
![スクリーンショット (89).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/7eb6cc45-567f-d579-e56b-d0747368dedf.png)

あと7問答えられれば、、、
各章をまとめたので、知らない単語は減ったものの、細かい部分まで覚えきれておらず、どっちだったかな？となることが多かったイメージだ。
見直しマークも35問つけていたので、それが半分外れていたというイメージである。

# 直し
## Amazon Athena
Amazon S3 バケットに保存されているデータに対して直接にクエリ処理を実施するサーバレスなデータ分析サービス

## S3
#### 暗号化の復号
S3側で自動的に復号

#### 暗号化の対象
S3バケットに保存されるアクティビティログなどのログも自動で暗号化される

#### クロスリージョンレプリケーションの挙動
S3バケットにオブジェクトが作成・更新・削除された際のイベントをトリガーとして、別のS3バケットに対してオブジェクトデータのレプリ ケーションが実行

#### One Zone-IA
ログファイルのコピーを保存するためのストレージ(マスターではない)

## EBS
#### バックアップ
バックアップの有効化だけでは、定期的なライフサイクルポリシーの設定不可

#### IOPS
汎用：16000IOPS

## Cloudwatch
#### CloudwatchとEC2
EC2インスタンスに対してOSレベルの詳細なログ情報を取得するためには、CloudWatchエージェントとCloudWatch Logsを設定する必要有
EC2内部にCloudWatchエージェントをインストール→ログをCloudWatch Logsに転送する
※フローログはネットワークトラフィック！！

#### CloudwatchとRDS
CPU使用率などの基本的なメトリクス→デフォルト
メモリなどの一部のメトリクス→拡張モニタリングの有効化

## DynamoDB
#### DAXとAutoscalingのユースケース
DAX:インメモリ型のキャッシュで高速処理、高コスト
Autoscaling：一時的に負荷が高まる場合、低コスト

## Kenesis
#### Amazon Kinesis Data Firehose
AWS Lambda関数と連携して、データ変換とデータ配信を実施するサービス

#### Amazon Kinesis Data StreamsとKinesis Data Firehose
Amazon Kinesis Data Streams：1秒以下でのデータロード向けに設計されており、ストリーミングデータをリアルタイムに処理したり、表示させたい場合に利用
Kinesis Data Firehose：データロードまで60秒必要となり、リアルタイムな処理には向いていませんが、データ変換・配信

#### Amazon Managed Service for Apache Flinkアプリケーション
データ分割などのクエリ処理を実行できる、S3に直接保存可能（Kinesis Data Firehoseいらない）

## ECS
Auto ScalingはECSクラスターにアタッチ
Auto ScalingグループにALBをアタッチ

## CloudFront
オンプレミス環境のサーバーにも適用可能なコンテンツ配信サービス
オンプレミスサーバーをCloudFrontのカスタムオリジンとして設定することで、Amazon CloudFrontを介してエッジロケーションにキャッシュを蓄積して、WEBサイトの配信を高速化することができます。

#### 署名付きURLと署名付きCookie
現在のオブジェクトURLを変更しない場合は署名付きCookie

#### Cache-Controlのmax-ageディレクティブ
低い値に設定されている→キャッシュ保持期間が非常に短くなってしまいキャッシュの期限切れが頻発

## DNS hostnames
VPCのオプション

## AWS Data Pipeline
様々なAWSデータベースやストレージ間のデータの移動と変換を自動化するサービス
定期的なデータ取得タスクを設定できる

## IAM認証方式
EC2からRDSへの認証
通常：パスワードとユーザ名
IAMデータベース認証：認証トークンを使用

## NLBを構成したWEBアプリケーションに対するHTTPエラーを検出した場合
UnhealthyHostCountメトリクスをモニタリングするAmazon CloudWatchアラームを作成して、このアラームがALARM状態になった場合には異常状態のインスタンスを置換するように、Auto 
Scalingアクションを構成
※レイヤー４ロードバランサーであるため、アプリケーションのURLを指定して、NLBのHTTPヘルスチェックを有効化する設定不可

## オンプレミス環境で保有しているIPアドレス移行
ROA (Route Origin Authorization)は、 BGP (Border Gateway Protocol）で使われるAS (Autonomous System)番号と、 IPアドレスの組み合わせが正しいことを示す電子署名が施されたデータ
ROAには Amazon が特定の AS 番号のアドレス範囲を公開することを承認
ROAを利用して、パブリックにルーティング可能な IPv4 または IPv6 アドレス範囲の一部または全部を、オンプレミスのネットワークから AWS アカウントに移行する

## シングルサインオンの構成を実現
AWS IAM Identity CenterでSAMLフェデレーションを設定してMS Active Directoryの認証情報とIAM認証情報を連携させる

## EC2
#### ストレージ最適化インスタンス　l3en
SSDボリュームストレージを選択した上で低レイテンシーと高いランダム I/O パフォーマンスを達成することができるインスタンスタイプ
ローカルストレージ上のTB規模のデータセットに対して順次、読み込みと書き込みアクセスを必要とするワークロードを実施するための最適


## AWS Transit Gateway
マルチキャストを有効にすると、特定のTransit Gatewayをマルチキャストルーターとして動作させることができます。VPC上でのマルチキャストを有効化できる

## Lambda関数
#### エラー原因
課金対象：実行数や実行時間に応じて支払いが発生→Lambda関数が無期限に実行されないようにタイムアウトが設定
デフォルト：3分
MAX：15分

## RDS
#### フェールオーバー
フェイルオーバーが実行されると、Amazon RDSはDBインスタンスのCNAMEレコードをスタンバイから切り替えて、新しいプライマリに昇格
セカンダリーDBは最初から実行できる状態で待機されているホットスタンバイとなっています。
Ctrl+I で使用できる GitHub Copilot のインラインチャットが便利

## 概要
最近GitHub Copilotを使用し始めました。
拡張機能のGitHub Copilot Chatで使用できるインラインチャット機能が便利でしたので共有させていただきます。

## 使用方法
VS Code の拡張機能のGitHub Copilot Chatをインストールした状態で`Ctrl+I`キーを押すと、ChatGPTの様な対話形式での入力画面が表示されます。
![スクリーンショット 2023-10-14 155514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/d7913a4c-2e10-c824-3a1a-702678cee3cb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/5cc155c2-eba4-bd41-7a0b-4cc58fefef6d.png)

サンプルコードを実装してくださいと入力しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/3f30dfb8-3165-5b66-4214-e64945d6f4e5.png)

しかし、指示が曖昧だったので詳細を求められました。
今回はババ抜きを実装してもらうことにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/29989f35-d137-fe26-c4d1-a9a2e0796a23.png)

ババ抜きっぽいコードが生成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/f1dfaf27-6b51-f546-603d-fd977d8251cb.png)


## コードにコメントを追加する
`/doc`でクイックアクション的にコメントを追加することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/9276a3fd-5a94-9602-5208-254db80c0da9.png)

コメントが追加されました。(ついでに関数化されています。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/30fcf492-050c-865b-3b5c-c84ade28844c.png)

もし英語のコメントが読めない場合は`/doc 日本語で`などの入力で日本語で生成することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/1a1f6b91-7273-bb3b-8109-3d1cc8dffc58.png)

日本語でコメントが生成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/9106f107-719b-58bf-77be-d46a5db0ce14.png)

## コードについて説明してほしいとき
誰かのコードを読みたいときは`/explain`のクイックアクションを使用すると左枠のchat欄でChatGPTの様にコードの説明をしてもらえます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/6f793c49-c110-e656-9a5d-4ea6414ce919.png)

## テストを実装する
`/test`で新しいファイルを作成し、テストを作成してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833294/4620d0ff-74be-8546-9a86-fef5b87cf455.png)



## 終わりに
この後UIを追加して下さいなどのメッセージを入力するとpythonの場合Tkinterを使って実際に使用できるようなコードを作成してくれます。
コードの説明をしてもらったり、コメントを追加してもらうのはかなり便利だと思いました。

ただコードの生成に関しては生成AIあるあるだとは思いますが、具体的な指示をしないとコードの品質にかなりムラが出やすいので精査する必要があるというのも感想です。
Imgur APIで画像をアップロードしてみた

<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="qBLGEKM" data-user="04" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/qBLGEKM">
  Imgur API Upload</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

簡単にアップロードできます

```javascript
await fetch("https://api.imgur.com/3/upload", {
    method: "POST",
    headers: {
        Authorization: "Client-ID aca6d2502f5bfd8",
    },
    body: new FormData(document.forms[0]),
});
```

API仕様書

https://apidocs.imgur.com/#c85c9dfc-7487-4de2-9ecd-66f727cf3139

<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="JjwqdKz" data-user="04" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/JjwqdKz">
  Imgur API Upload</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

https://dash.deno.com/playground/imgur-api
githubでNew pull requestができない

ローカルブランチからpushしたものがgithub上で表示ができなくてすごく困ったので
ここに記します。

経緯
-
Udemyの講座を参考に、Inertia.js用のローカルブランチに「sec2_Inertia_vurjs」と名付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/63e11dc9-db59-289e-0f87-eee3104f44c9.png)
VSCodeで該当ブランチからコミットしたあとに、github上に該当のリモートブランチが表示されていないことに気づきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/e0af7348-f0eb-7c78-5ccc-3ea68750ffad.png)
github上の右上の方に「New branch」のボタンがあるので、そこからブランチを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/6af84a6a-c350-b70c-0b12-987c49a0b238.png)
無事表示されたので、「さぁpull requestしよう」と一覧を見てみるも、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/6edea87c-6cae-dac6-857c-af9caef22c1f.png)
ない…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/0bd9b08c-2b09-1054-2ea2-ff23e4bf710f.png)
「New pull request」の一覧に行ってもない…！（すみません、スクショ忘れました。）

状態確認
-
とんでもなくパニックに陥りました。「私の今までの作業どこに行ったの…！？」と…
他の人の記事では「New pull request」の一覧に行けば見つけられるとの事ですが、
私の場合はそこにもない状態です。
でも、こんな時は落ち着いて現在の状態を確認するしかありません。

#### ブランチの確認
まず、自分のいるブランチを再度確認します。

```:git branch コマンド実行
  main
* sec2_Inertia_vuejs
```
このアスタリスクがついているブランチが今いるブランチです。mainから上げたわけではないようです。

#### リモートリポジトリの確認
次に、「あ！そもそも、リモートリポジトリを勘違いしている可能性はないか！？」と思い、接続されているリモートリポジトリを確認しました。
```:git remote -v コマンド実行
origin  https://github.com/*********.git (fetch)
origin  https://github.com/*********.git (push)
```
伏せていますが、目的のリモートリポジトリのリンクが表示されています。ここも問題なし。

:::note info
ちなみに、このgithubでよく見かける「__origin__」は、リモートリポジトリのリンクをgithubがそう名付けているからこのように表示されます。

`git push origin master`や`git push origin main`というのは、「origin（リモートリポジトリ）にあるmasterブランチ(もしくはmainブランチ)にpushするよ！」という意味になるんですね。
__origin = リモートリポジトリ__ と覚えてもらえればOKです。
:::

解決方法
-
リモートリポジトリもローカルブランチも問題ない…でもリモートブランチにはpushした内容が表示されない…
どうしたら…と困っていたところに出会ったのがこちらの記事 ↓

https://tech.kurojica.com/archives/15240/

どうやらリモートリポジトリが正しく設定されていても、pushが届かない場合があるようです！
今回は記事を参考に「originにあるsec2_Inertia_vuejsリモートブランチにsec2_Inertia_vuejsローカルブランチの情報をpushして」という意味になるように、下記コマンドに変更して実行しました。
```
git push origin sec2_Inertia_vuejs:sec2_Inertia_vuejs
```
無事成功しました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/40c8be30-9396-9659-5e3e-b5b65d51a07f.png)

まとめ
-
:::note info
・リモートリポジトリが正しく設定されていても、pushが届かないことがある
・そんなときはgit pushコマンドを実行してみる
:::
Vim

<!--
2023/10/21
-->
[picoCTF][Forensics][who is it]

## Writeup
* emlファイルをKaliでダブルクリックすると、Mousepadで開く。
でもvimを使う。少しだけ色分けしてくれてる。
![screenshot 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/ef5590df-72e3-46c5-8e88-1a2aab68a5b1.png)
<br>

* ドメインとIPアドレスを`whois`コマンドで、確認。
ドメインにそれらしい情報はないけど、IPアドレスには名前があった。
![screenshot 8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/8ca46bae-1ddc-a89f-9ea9-73d1c69875a6.png)
<br>

* 以上です。
ABC324をPythonで（A~E）

日本レジストリサービス（JPRS）プログラミングコンテスト2023（AtCoder Beginner Contest 324）

https://atcoder.jp/contests/abc324

# A問題
setに入れて確認
```python:A
input()
s = list(map(int, input().split()))
print("YNeos"[len(set(s))>1::2])
```
# B問題
2と3で割れるだけ割る
```python:B
n = int(input())
while n % 2 == 0:n //= 2
while n % 3 == 0:n //= 3
print("YNeos"[n>1::2])
```
# C問題
各Sに対して調べる。
1文字差があるときは、1つ以外違うか確認
同じ文字数のときは、同じ場所の違う文字の数が1以下か調べる
```python:C
n, t = input().split()

def check(s, t):
    if len(s) + 1 != len(t):return False
    i = 0
    while i < len(s) and s[i] == t[i]:
        i += 1
    while i < len(s) and s[i] == t[i + 1]:
        i += 1

    return i == len(s)

ans = []
for i in range(int(n)):
    s = input()
    if abs(len(s) - len(t)) == 1:
        if check(s, t) or check(t, s):
            ans.append(i + 1)
    elif len(s) == len(t):
        cnt = sum(s_i != t_i for s_i, t_i in zip(s, t))
        if cnt <= 1:
            ans.append(i + 1)

print(len(ans))
print(*ans)
```
# D問題
10^13未満の平方数は10^7個未満なので
それぞれの平方数について、Sから作れるか調べる。
```python:D
n = int(input())
S = input()
s = [0] * 10
for s_i in S:s[int(s_i)] += 1

i = 0
ans = 0
while i ** 2 < 10 ** n:
    t = [0] * 10
    for t_i in str(i ** 2):
        t[int(t_i)] += 1
    if s[1:] == t[1:]:
        ans += 1
    i += 1

print(ans)
```
# E問題
各Sについて
tを先頭からx文字、後ろからy文字を含んでるとする
この時、すでに見たものの中で
後ろからlen(t)-x文字以上含んでいるもの　+　前からlen(t)-y文字以上含んでいるものの総和
```python:E
class BinaryIndexTree:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def range_sum(self, i, j):
        if i == 0:
            return self.sum(j)
        return self.sum(j) - self.sum(i - 1)


n, t = input().split()
front = BinaryIndexTree(len(t) + 10)
back = BinaryIndexTree(len(t) + 10)
ans = 0
for i in range(int(n)):
    s = input()
    x = 0
    for s_i in s:
        if s_i == t[x]:
            x += 1
        if x == len(t):break
    y = 0
    for s_i in s[::-1]:
        if s_i == t[-y - 1]:
            y += 1
        if y == len(t):break

    # 0だとバグるので+1
    ans += i - front.sum(len(t) - y) + i - back.sum(len(t) - x)
    front.add(x + 1, 1)
    back.add(y + 1, 1)

    i = 0
    for s_i in s + s:
        if i < len(t) and t[i] == s_i:
            i += 1
    if i == len(t):
        ans += 1

print(ans)
```
gormやgooseでDBスキーマを指定したいとき

gormでDMスキーマを指定する方法を調べると
```
db, err = gorm.Open(postgres.New(postgres.Config{
        DSN:                  `user=test password=test dbname=DB-NAME port=5432 sslmode=disable`,
        PreferSimpleProtocol: true,
    }), &gorm.Config{
        NamingStrategy: schema.NamingStrategy{
            TablePrefix:   "YOUR_SCHEMA_NAME.", // schema name
            SingularTable: false,
        }})
```
このconfigで指定するやり方が出てきたがうまくできなかった
単純に、DB説情報にsearch_pathを指定すればいいだけだった

```
"user=test password=test dbname=DB-NAME host=localhost search_path=YOUR_SCHEMA_NAME port=5432 sslmode=disable"
```
gooseも同様
firebase deployで画面が表示できない

# 初めに
ReactのプロジェクトをFirebaseでデプロイしようとしたんですが、
時間が掛かってしまったのでメモを残しておきます。


# 問題
firebase deployで表示されたURLを見ると、以下の画面が表示されました。

![スクリーンショット 2023-10-14 18.28.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/8b173826-660b-f3df-16fb-c1023ad3fc64.png)

# 解決方法

firebase init hostingで聞かれた下記の質問「dist配下に存在する、index.htmlを上書きしますか？」に「No」と答えるだけで解決しました。

File dist/index.html already exists. Overwrite?

「Yes」と答えていたことで、npm run buildで生成したindex.htmlファイルをfirebaseが自動で生成したindex.htmlファイルで上書きしてしまったことが原因です。

npm run buid → firebase init hosting


# 終わりに
firebase init hostingで表示される質問に適当に答えてデプロイを進めていたので、質問の意味を理解しながら次回のデプロイで気を付けていきたいです。
EC2のコストを抑える観点を考えてみた

## EC2利用料を節約したい
AWSを利用する上で、EC2を使う機会はとても多いと思います。
最近は円安傾向ということもあり、とにかくコストを抑えたい！というニーズはビジネスシーンでも個人利用でも高まっているかと思います。

そこで、コスト削減の観点に着目してポイントを整理していきます。

## インスタンスタイプ
まずインスタンスタイプです。
そうですね。Tシリーズを利用することで節約可能です。
でも一つ注意してください。

>T4g、T3a、および T3 インスタンスは (デフォルトを変更しない限り) デフォルトで unlimited として起動します。

T3インスタンス等では、unlimitedモードでの起動がデフォルトになっています。
unlimitedモードでインスタンスに負荷をかけ続けると、M6iインスタンス等と同等以上のコストが発生してしまいます。デフォルトから変更していない（意図せず利用している）ケースもちらほらみかけますので、ご注意ください。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-performance-instances-unlimited-mode.html

もしくは、T4gのようなインスタンスタイプはどうでしょうか？
こちらもコスト削減に効果はありますが、注意点があります。

"g"がつくインスタンスタイプはGravitonプロセッサで動作するためアーキテクチャがARMです。
例えばですが、本番ワークロードでは選択するインスタンスがx86_64 アーキテクチャとします。
本番ワークロードのテスト用として選択するならば、CPUのアーキテクチャは統一すべきですので安いと理由だけでの選択は控えてください。
また、T4g等のインスタンスはWindowsインスタンスに非対応であることも覚えておいてください。


## EBS
コストを抑えたいならgp3を選択してください。gp3のデフォルト（3000IOPS、125Mib/s）であれば、gp2と比較し約20%コスト削減が可能です。

https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-plan-storage-compare-volume-types.html

また基本ではありますが、以下を行うことも効果が見込めます。
- システム領域以外は、st1やsc1の採用を検討する。
- プロビジョニングするボリュームサイズは極力最小限に留めて、適宜拡張する運用をする。

## 稼働管理
コストを抑えたいならば、EC2を極力停止する運用はとても効果的です。
しかし、あまりにも細かく起動停止を繰り返すような場合は注意してください。
インスタンスの課金は、秒（最低60秒）課金と時間課金のタイプの2種類が存在します。
>料金は、インスタンスが起動されてから、終了または停止されるまでの、各インスタンスで使用されたインスタンス時間で請求されます。1 時間未満の各インスタンス時間については、Linux、Windows、SQL Enterprise を使用する Windows、SQL Standard を使用する Windows、SQL Webインスタンスを使用する Windows のインスタンスの場合、秒単位で請求されます。その他すべてのインスタンスタイプでは、1 時間として請求されます。

https://aws.amazon.com/jp/ec2/pricing/on-demand/

つまり、時間課金タイプのインスタンス（例えばRHEL）を1時間以内の尺でこまめに起動停止しても、節約できるコストは限定的です。

利用するインスタンスタイプが秒課金であるか時間課金であるか、必ず確認しましょう。
余談ですが、Windowsは過去時間課金でしたが、2021/6からは秒課金になっています。

https://aws.amazon.com/jp/about-aws/whats-new/2021/06/announcing-per-second-billing-for-ec2-windows-server-and-sql-server-instances/


## リザーブドインスタンス/Savings Plans
なかなか個人環境ですと利用されるケースは少ないかと思いますが、コスト削減へ一定の効果があります。
この記事では、リザーブドインスタンスとSavings Plansの比較や使いどころについては割愛しますが、1年以上の長期間、24時間EC2を稼働させる場合、検討する価値は高いです。

ただ、検討する前に知っておいてほしい点があります。
よく、以下のような文言を見かけるかと思います。実際に私も過去、お客様から問い合わせ頂いたこともあります。
>EC2 Instance Savings Plans は料金が最も低く、リージョン内の個々のインスタンスファミリーの契約 (例: バージニア北部で M5 の使用量) と引き換えに、最大 72% の節約を提供します。

でも72%も安くなるのって、本当に一部のOSとインスタンスタイプの組み合わせだけなのです。
例えば添付画像のようなWindowsインスタンスで3年分全額前払いをする条件としても、コスト削減効果は32%です。感覚としては、月曜から金曜まで常時稼働させ、土日は停止する運用をした場合と同等のコスト削減効果になります。

個人の意見となりますが、為替レートの影響や、常時稼働の必要がないならばオンデマンドの方が安く抑えられるケースもあるかと思うので、採用する際は充分な検討が必要かと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490859/797f192a-7c62-ab98-f230-9234d235a1d6.png)

## 番外編：利用料を試算したい
実際に利用料を試算したい場合、以下を利用しましょう。
https://calculator.aws/#/

一部サービス（例：Red Hat OpenShift Service on AWS）は非対応となります。
また作成した見積は、作成日から1年間アクセス可能という点はご注意ください。
https://aws.amazon.com/jp/about-aws/whats-new/2023/05/aws-pricing-calculator-point-in-time-cost-estimations/

## 終わりに
いかがでしたでしょうか？
今回ご紹介した方法を、AWS利用料の見積りやコスト最適化に活用いただければ幸いです。
Android Studioでビルドのときに「Run」タブが開かないようにする

Android Studioではデフォルトでビルドが完了するたびに「Run」タブが開きます。「Logcat」など他のタブを同じエリアで開いている場合閉じてしまうので、少し不便でした。ということで自動で「Run」タブを開かないようにする設定方法のメモです。

### 「Edit Configurations..」を開く

<img width="300" alt="Edit Configurations.." src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2130833/086c8c8a-ff6d-23aa-da1b-b2ddadf721fc.png">

### 「Activate tool window」のチェックを外す
「General」などどのタブを選択中でも表示されますが、Windowサイズによっては下方向にスクロールしないと表示されないかもしれません。
<img width="700" alt="Activate tool window" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2130833/f3b05c60-84fe-4e76-430a-b61953afb888.png">

以上、簡単なAndroid Studioのtipsでした。


# 参考
https://stackoverflow.com/questions/21237561/dont-show-run-tab-after-launch-in-android-studio
テストの概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/0574b34e-176d-8b71-32ec-ef30d27a9fce.png)
　テストの目的は、システムやプログラムに潜むエラーを検出することです。テストは、単体テスト、統合テスト（結合テスト）、システムテスト、運用テストの順で部分から全体へ向けて行います。

１：単体テスト
　モジュール単体が正しく動作するかをテストします。アルゴリズムやデータ構造について詳細にチェックします。プログラミング工程での誤りの発見を行います。

２：統合テスト（結合テスト）
　モジュールを組み合わせて動作させたときに正しく動作するかをテストします。モジュール間でやり取りするデータの整合性、すなわち、モジュール間インターフェースの生合成について詳細にチェックします。統合テスト（結合テスト）には、下記の技法があります。
①トップダウンテスト：上位モジュールから順にテストを行う。仮の下位モジュール（スタブ）を用いる。
②ボトムアップテスト：下位モジュールから順にテストを行う。仮の上位モジュール（ドライバ）を用いる。
③サンドイッチテスト：トップダウンテストとボトムアップテスを同時に行う。
④ビッグバンテスト：単体テストを終えたモジュールを一度に結合する。
⑤一斉テスト：単体テストを省略して、モジュールを一度に結合する。
ヤフオクの仕様にはトラップがある

## 自動延長機能
ヤフオクには、スナイプを防ぎ、適正な価格で落札されるように、自動延長という機能があります。
ところが、この機能には抜け漏れがあり、うまく働かないケースがあります。


## 機能しているように見えてしまう
数量2で出品されていて、自動延長「あり」のケースを考えます。

1位　Aさん　1000円
2位　自分　1000円

この状況で、Bさんが入札してくるとこうなります。

1位　Bさん　1100円
2位　Aさん　1000円
~~3位　自分　1000円~~

自分は落札できなくなり、終了時間は<font color="Red">**5分延長**</font>されます。
この現象により、あたかも
「落札できる状態から、落札できない状態に変化したとき、自動延長される」？
と勘違いしてしまいます。


## 自動延長の本当の仕様はこう
数量2で出品されていて、自動延長「あり」の同様のケースです。

1位　Aさん　1100円
2位　自分　1000円

この状況で、Bさんが入札してくるとこうなります。

1位　Aさん　1100円
2位　Bさん　1100円
~~3位　自分　1000円~~

この場合、なぜか<font color="Red">**終了時間は自動延長されない**</font>のです。
どういうことかというと、1位が変化していないからです。

つまり、2位に対しては<font color="Red">**終了5秒前にスナイプすることが可能**</font>です。


## まとめると
・自動延長による再入札のチャンスが与えられるのは<font color="Red">**1位のみ**</font>です。
・2位以下の入札者は、落札できない状態になっても自動延長されません。

数量1の場合は、こんなことを考える必要はないのですが、
数量2以上のときは、このようにトラップに嵌められる可能性があるので注意です。
【AWS】ネットワーク接続基本アーキパターンまとめ【ネットワーク】

## 初めに
オンプレミスからAWSへの接続、AWSのVPC同士の接続、さらには接続するVPCの数や予算によってなどのネットワーク接続に関してはさまざまなアーキテクチャのパターンが考えられる。
この記事ではAWSのネットワークに関する基本的なアーキテクチャをいくつか紹介し、その用途や違いをまとめた。


## ネットワーク構成パターン
### とにかくAWSに接続したい
・インターネットゲートウェイ(IGW)を使用する
![IGW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/456d527a-de48-1dd3-b1c4-18b82863e65d.png)
(アーキテクチャのポイント)
・インターネット経由でAWSのリソースと通信できれば良い(通信内容を保護する必要がない)という場合
・運用コストを抑えたい場合

### 安全にAWSに接続したい
・VPNを使用する
![VPN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/04a4b8ce-79b2-96d3-1d79-fe57a35220dd.png)
(アーキテクチャのポイント)
・通信内容を保護したい場合
・頻繁に大量のデータを短時間に送受信する必要などがない場合にオススメ
・運用コストを抑えたい場合

### いつも安定した接続でAWSに接続したい
・DirectConnect(DX)を使用する + 可用性の確保にVPN接続を併用する
![DX+VPN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/c3c98d2f-5b6b-4f16-a4ee-c9f245171ba7.png)
(アーキテクチャのポイント)
・常に安定した通信が求められる場合や、頻繁に大量のデータを短時間に送受信する必要がある場合に構築される
・DirectConnect単独でも通信は可能だが、DirectConnectの接続ができなくなった場合に備えて、VPN接続を行っておくことがある
※コスト増を許容できるのであればもう一本DirectConnectを接続するとなおよい
・接続したいVPCが1つだけの場合
・AWS側での設定作業が必要になるため、ユーザによってリクエストで即開通はできず、開通まで少なくとも1週間以上はかかる


### 複数のVPCに接続したい
・DirectConnectGateway(DXGW)を使う
![DXGW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/dc66f7e0-e3eb-d923-c106-b38410b47891.png)
(アーキテクチャのポイント)
・接続したいVPNが複数ある場合
・VPC同士の通信が不要である場合
・DirectConnectやVPNを書くVPCの数だけ用意すれば複数のVPCに接続することが可能だが、それぞれの接続を設定するのには多大な労力や保守工数が必要になるDirectConnectGatewayで複数のVPCへの接続をまとめることが可能
・図に示したアーキテクチャではDirectConnectGatewayに接続したDirectConnectが1本だが、これも可用性を意識した場合は追加でもう一本DirectConnectを用意するなどしたほうが良い

#### さらにVPC間で通信したい(全部のVPC)
・TransitGateway(TGW)
![TGW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/8c851ea0-cd29-65f7-a69c-1c9e341f166e.png)
(アーキテクチャのポイント)
・接続したいVPNが複数ある場合
・VPC同士の通信が必要である場合
・VPC同士の接続にはVPCピアリングが手段としてあるが、その場合は全VPCに他のVPC全てに対する接続を設定する必要が出てきてしまう。複数のVPCがある場合はTransitGatewayを使うことで(リージョン内では)1つのTransitGatewayで接続されたすべてのVPCの相互通信が可能となる

#### さらにVPC間で通信したい(一部のVPCだけ通信させる)
・TransitGateway(TGW) + DirectConnectGateway(DXGW)
![TGW+DXGW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/9ed3672d-39a6-cb0d-6c06-25b05d433003.png)
(アーキテクチャのポイント)
・接続したいVPNが複数ある場合
・VPC同士の通信が必要である場合であり、なおかつそれが一部のVPCのみで通信したい場合
※図で示したアーキテクチャではVPC A,B,Cは通信できるが、AとC,CとDなどTGWと接続されていないVPC間の接続はできない

## 最後に一言
AWSのベストプラクティスの重要なキーワードに可用性がありますが、どんなプロジェクトでも通用する1つのパーフェクトなアーキテクチャは存在しないと思います。
そのプロジェクトの予算だったり、扱うデータの性質によって選ぶべきアーキテクチャは変わってきます。
プロのエンジニアとして、様々なアーキテクチャのパターンを知り、理解し、状況に応じたアーキテクチャを提案できるようにしていきたい。
【学習メモ】DynamoDB APIのまとめ

# テーブル関連

CreateTable 

DescribeTable 

ListTables 

UpdateTable 

DeleteTable 

# PartiQL関連
（両方とも複数の項目を読み込み、書き込み、更新、ができる）

ExecuteStatement：一つか複数

BatchExecuteStatement：複数、ExecuteStatement よりも効率的、1 回のネットワークラウンドトリップのみで済む

# データ作成
PutItem 

BatchWriteItem ：最大25個

# データ取得
GetItem 

BatchGetItem：最大100個（大量のデータを呼び出すときに使う、BatchGetItemを複数回分けて実行するとか）

Query：特定のパーティションキーがあるすべての項目（条件を満たしてるデータのみ取る）

Scan：指定されたテーブルまたはインデックスのすべての項目（条件を問わず全部取る）

# データ更新
（複数個更新できないらしい。。。）

UpdateItem 

# データ削除
DeleteItem 

BatchWriteItem：最大25個

# DynamoDB Streams関連
ListStreams 

DescribeStream：ARNなどを返す

GetShardIterator ： 特定のストリーミングに関する詳細情報を返す

GetRecords：特定のシャード内の場所を表すシャードイテレーターを返す。GetShardIterator リクエストから返されたシャードイテレーターを指定する必要がある

# トランザクション関連
（PartiQLを使用するか、各オペレーションを個別の API コールに分離する DynamoDB の従来の CRUD API を使用か、二つのやり方があるようです。。。）

ExecuteTransaction：（PartiQLを使用）テーブル内または複数のテーブル間の複数の項目に対して、オールオアナッシングの結果が保証された CRUD オペレーションを実行できるバッチ操作

TransactWriteItems 

TransactGetItems 

# 参考サイト
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.API.html

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.html
Databricks AutoMLの時系列予測で各国の休日がサポートされてました

昨日アップデートを見逃していました。

![Screenshot 2023-10-14 at 21.30.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/03a93f70-9d57-a8ac-d0d2-dbc4c3437866.png)

Databricksランタイム12.0以降であれば、各国の休日を指定できるようになってました。これまでは米国しか指定できなかったのでした。

せっかくですので、[先日試したunerry様のデータ](https://qiita.com/taka_yayoi/items/af35659038f8d77a59a9)を使います。AutoMLで予測する際には、目的変数のカラムがfloat型である必要がありますので、型変換をして新規にテーブルを作成します。

```sql:SQL
CREATE TABLE main.default.visitor_automl AS
SELECT
  date,
  cast(total_visitor as FLOAT) as total_visitor 
FROM
  unerry_catalog.default.sample_st_daily_visitor;
```

このテーブルを指定します。
![Screenshot 2023-10-14 at 21.27.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/07505e1b-1082-3045-05ee-41d2f5bb43bf.png)

さらに**国の祝日**で`Japan`を選択します。
![Screenshot 2023-10-14 at 21.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6c45c6ef-1c9d-9a05-cac6-c4c9c8fbafea.png)

AutoMLを実行します。
![Screenshot 2023-10-14 at 21.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7689ebda-85aa-c7fd-f872-0ee0ef57effa.png)

**View notebook for best model**のリンクをクリックすることで予測結果も確認できます。黒い点は実績値で、点がない部分が予測結果です。
![Screenshot 2023-10-14 at 21.35.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/69266a61-d80b-db23-72b0-de366ec9b66e.png)

7/1からの10日間の予測なので休日が入ってませんので休日の影響を確認できませんでしたが、これまでより実用性は高まっていると思います。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
NginxによるTCP Proxy

# はじめに

NginxによるTCP Proxyを構築した際の備忘録。

# 環境

- Docker version 20.10.14
- Docker Compose version v2.20.3

# Nginxコンテナの設定

client --> Nginx --> clickhouse という経路でアクセスを試みます。

```yaml:compose.yaml
services:
  nginx:
    container_name: nginx
    hostname: nginx
    image: nginx:latest
    ports:
      - '9000:9000'
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf

  clickhouse:
    image: clickhouse/clickhouse-server:23.3.8.21
    container_name: clickhouse
    hostname: clickhouse
    restart: always
    ipc: host
```

`nginx.conf` の設定は以下の通り。

```conf:nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    upstream clickhouse-server {
        # コンテナサービス名を指定
        server clickhouse:9000;
    }
    server {
        # リッスンポート
        listen   9000;
        proxy_pass clickhouse-server;
        # allow {許可IP};
        # deny all;
    }
}
```

# コンテナ構築

`compose.yaml` があるディレクトリで以下を実行する。

```shell
docker-compose up -d
```
もしくは、

```shell
docker compose up -d
```

# アクセス確認

```
curl localhost:9000
```

とりあえず、繋がっている様子。

```
Port 9000 is for clickhouse-client program
You must use port 8123 for HTTP.
```
緯度,経度およびZoomからOpenStreetMapのタイルを得る

緯度,経度およびZoomからOpenStreetMapのタイルを得るサービスを作りました。
https://elix.jp/app/geotilefinder/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/aa8f8806-7568-80a0-f973-f42cba07a044.png)

緯度経度は[GoogleMaps](https://www.google.co.jp/maps/)の任意の場所で右クリックするとコピーできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/94122363-67ff-2016-7335-f6a489c09929.png)

また、providerを変更できるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/93bf480c-6376-4c4f-7ac1-76de2261470d.png)


緯度経度およびzoomからタイルを得る処理はこんな感じです。

```
function latLngToTileXY(lat, lng, zoom) {
    var lat_rad = lat * Math.PI / 180;
    var n = Math.pow(2, zoom);
    var xtile = parseInt((lng + 180.0) / 360.0 * n);
    var ytile = parseInt((1.0 - Math.log(Math.tan(lat_rad) + 1.0 / Math.cos(lat_rad)) / Math.PI) / 2.0 * n);
    return [xtile, ytile, zoom];
}
```

追記：
ついでにタイルの範囲を出力するようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f9166643-d5f9-4551-b546-e6274ef36259.png)

ソースコードはほとんどGithub copilotが書いてくれました
```
// タイル座標とズームからタイル左下と右上の緯度経度を求める
function tileXYToLatLng(xtile, ytile, zoom) {
    var n = Math.pow(2, zoom);
    var lng_deg = xtile / n * 360.0 - 180.0;
    var lat_rad = Math.atan(Math.sinh(Math.PI * (1 - 2 * (ytile+1) / n)));
    var lat_deg = lat_rad * 180.0 / Math.PI;
    var lng_deg2 = (xtile+1) / n * 360.0 - 180.0;
    var lat_rad2 = Math.atan(Math.sinh(Math.PI * (1 - 2 * ytile / n)));
    var lat_deg2 = lat_rad2 * 180.0 / Math.PI;
    iResultSW.value = lat_deg + "," + lng_deg;
    iResultNE.value = lat_deg2 + "," + lng_deg2;
    return [lat_deg, lng_deg, lat_deg2, lng_deg2];
}
```

Github copilotに「ありがとう」を伝えるすべはないものか・・・。
chatGPTやAlexaなら直接「ありがとう」でつたわるんだけどなー。
自分だけのBookNotionを爆誕させた

# まえおき

こちら参照

https://qiita.com/Guz9N9KLASTt/items/06dbf9967be9c7155bfd

# 経緯

ソースコード内で本のタイトルを入力してデータベースへアクセスし、突合させることでしかハイライトとコメントを取得できていなかった

外出先でもやりたいな～と思ってましたが、

    🤔「デプロイしても自分だけしかアクセスできなければよいのでは？」

と感じ自分だけのBookNotionを爆誕させた

# 要件
- どこでもハイライトとコメントをページにまとめることができる
- それっぽいデザインで実装する
- 自分だけしか実装させない都合上、ログイン機能を設ける
- 最低限の機能から実装していき、徐々に拡張していく
- 誰でもできるようにはしない(めんどうだから)

# 技術系

## 使用技術
フロントエンド：Next.js
スタイリング：Tailwind CSS
ホスティング：Vercel
認証：JWT


## リポジトリ

https://github.com/Suntory-Y-Water/my-notion-manager

# レイアウト

## ログイン画面

### PC

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/40ce8dd3-95f3-7f54-258f-df469fc29fd8.png)

### SP
![IMG_5621.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/14d57bc3-9bf2-87fd-cfb2-51c345f87f7a.png)

## ページ作成画面

### PC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/d6f78a3f-e8ea-e8cc-4863-cec4d9ac91f7.png)

### SP
![IMG_5622.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/5843b4d8-abaa-d2ed-baaa-85641befdb85.png)

# 実装手順

:::note warn
BookNotionでNotionにハイライトを登録していると前提
:::

## APIキーの設定

https://www.notion.so/my-integrations

まずはNotionAPIを設定しましょう。
1. 新しいインテグレーションを選択
1. 名前を設定
1. 送信でAPIキーを取得
1. 機能を選択し、適切な権限を与える(めんどいんで全部与えてました)
1. 保存

## データベースにNotionAPIを連携する

こちら参照

https://www.notion.so/ja-jp/help/add-and-manage-connections-with-the-api

上で設定したAPIを連携させる必要があります。
連携先はBookNotionで登録したハイライトが格納されているデータベースになります。

## .env.localへの値設定

以下の情報を.env.localにします。
``` 
EMAIL=すきなアドレス
PASSWORD=ハッシュ化したパスワード
JWT_SECRET=秘密鍵
API_KEY=APIキーの設定で取得したAPIキー
DATABASE_ID=BookNotionのデータベースID
PAGE_URL=作成後のページが追加されるページのID
```

データベースIDの確認方法は、BookNotionで追加したデータベースのページURLが以下の場合、`xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`がデータベースIDになります。
`https://www.notion.so/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?v=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy`

ページIDは`https://www.notion.so/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`の場合、`xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`がページIDになります。

## パスワードのハッシュ化

パスワードを平文で保存するのは良くないと怒られたのでハッシュ化します。
このあたりはご自身で調べたものを実行してください。

# 実際にやってみよう

左から、本アプリ、貼り付け先のページ、BookNotionのデータベースがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/b8369a2b-c178-7eab-8769-9cd5018c3692.png)

今回ハイライトとコメントをまとめたいのは`解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の４視点と行動法`という本なので、そのまま送信フォームに入力し`Create a Notion page!`を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/f9c55056-5f28-0c98-7872-78d17197631e.png)

するとページが追加されて中を見るとハイライトが中見出し、コメントが通常のテキスト形式で出力されているのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/ad3fac1e-2c3b-2e41-7dbc-cdbdbaa61845.png)

:::note warn
本の内容を掲載する許可は取っていないため、黄色く塗りつぶしています。
:::

# 感想

- JWTを調べながら実装した
    - なんとなく認証に対する理解が深まった
- NotionAPIすげぇ
    - おもろいもの思いついたらまた何か作りたい
- TailWind CSSは小規模なら良いと思ったけど大規模には向かなそう？
- Web APIに対する理解を深めたい
- App Routerﾅﾝﾓﾜｶﾗﾝから体系的にまとまった教材を探したい

# 今後の方針

- アプリ側から BookNotion で登録したテーブルを項目を削除する機能
- 本の予測表示？機能
- APIの型定義(レスポンスから型定義するのだるくてanyのまま)
- useEffect以外の画面リダイレクト
- ドキュメントの拡張
- ログイン回数の制限(冷静にEmailにしたのは謎)
[リサーチ・メモ] Vuexを使用して画面間でデータを渡す

### 1.ストアを作成する
```
import { createStore } from 'vuex';

export default createStore({
  state: {
    memberInfo: null
  },
  getters: {
    getMemberInfo: state => state.memberInfo
  },
  mutations: {
    setMemberInfo(state, payload) {
      state.memberInfo = payload;
    }
  }
});
```
|定義|内容|
|:--:|:--:|
|state|データを定義する|
|getters|stateのデータを取得する|
|mutations|stateの状態を変更する|

### 2.画面遷移の際に、stateにデータを保存する
```
store.commit('setMemberInfo', memberInfo);
```

### 3.遷移先でstateを取得する
```
const memberInfo = computed(() => {

    if (!store.state.memberInfo) {
        //データ取得不可の為、トップページ等へ遷移させる
    } else {
        return store.state.memberInfo
    }
});
```
※Vuexはリロードするとstateがリセットされる為、「if (!store.state.memberInfo)」などで対応が必要
　「vuex-persistedstate」というプラグインで防ぐこともできる

### 4.遷移先から戻る際にstateを取得する
```
onMounted(() => {
    const storedMemberInfo = store.getters.getMemberInfo;
    if (storedMemberInfo) {
        Object.assign(memberInfo, storedMemberInfo);
    }
});
```
※戻る際にcomputedを使用すると、依存関係が変更される度に実行されてしまう為、onMountedを使用する
　「if (storedMemberInfo)」でstateにデータが存在する場合は、stateのデータをコピーする
Scalpel

<!--
2023/10/20
-->
[picoCTF][Forensics][hideme]

## Writeup
* `file`コマンドで確認すると、PNGの画像っぽい。
* `strings`コマンドで確認すると、`seclet/flag.png`と出力される。
最初は気づかなかったが、zipのpathだったのかな。
![screenshot 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/41c0612a-2396-1d25-2974-631d922128cb.png)
<br>

* `hexeditor`で確認すると、`PK`という文字列が見えた。
![screenshot 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/42931b91-aae3-c9ec-5ce2-6ee6a93131ce.png)
<br>

* ファイルの中のファイルを取り出すには、`scalpel`が便利。
設定ファイルのzipをコメントアウトしても、ファイルが出力されない。
以前の問題と同様かと。
<br>

* コメントアウトだけでなく、flag.pngの末尾に合わせて変更して実行。
無事にzipファイルが出力され、解凍して新たなflag.pngを確認。
![flag_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/23fc2dc1-9c9c-61b3-6b37-1733f7f2602d.png)
<br>

*　以上です。
【HTML・学習ログ１】HTMLの基本

<font color=gray>参考：侍テラコヤ『HTML/CSSの基礎を学ぼう』https://terakoya.sejuku.net/programs/51/chapters</font>

## ■基本構造

《準備》
1. 任意の場所に作成した空フォルダをVisual studio codeで開く。
1. 新規で「.html」ファイルを作成する。

《基本構造》
DOCTYPE宣言⇒head⇒body

```html
<!DOCTYPE html>
<html>

<head>
	<title>天気予報</title>
	<meta name="descriprion" content="毎日の気象情報をお知らせします">
	<meta charset="utf-8">
</head>

<body>
  <header>
  	<h1>天気予報</h1>
  </header>
  <main>
	<h2>今日の天気</h2>
    <p>よく晴れるでしょう</p>
  </main>
　<footer>
    <p>Copyright IITENKI inc. Copyright all right reserved.</p>
　</footer>
</body>

</html>
```
### \<head>～\</head> 
ブラウザには表示されない各種設定。webサイトのタイトルや説明文など。
- title　ページのタイトル
- meta name ="descriprion"　検索時に表示される説明文
- meta charset= "文字コード"　文字コードの設定
### \<body>～\</body>
ブラウザに表示させる各種コンテンツ
- header タイトルやロゴ
- main メインのコンテンツ
- footer コピーライトや連絡先などの基本情報

## ■よく使うタグ
| | |
|-|-|
|\<!--コメント-->|コメントアウト|
|\<p>|段落|
|\<h1>～\<h6>|見出し|
|\<ul>,\<ol>|箇条書き※\<li>と組み合わせて使う|
|\<hr>|水平線|
|\<br>|改行|
|\<div>|グループ化|
|\<table>|表|
※\<tr>,\<th>,\<td>|表の行、見出し、セル|

## ■パス
#### 絶対パス
webサーバー上のどのフォルダにファイルが置かれているかをURLで指定する。
```html
<img src="https://www.～">
```
※画像はimgタグで表示する

#### 相対パス
現在開いているHTMLファイルを基準にフォルダを指定する。
```html
<img src="../～">
```
※../は１つ上の階層のフォルダに移動することを示す。

多くの場合は相対パスを使うが、外部のwebサイトの画像やリンク先を指定する場合は、絶対パスを使用する。

### imgタグ(画像)
画像を表示するタグ。**src属性**で表示したい画像ファイルのパスを設定する。

### aタグ(ハイパーリンク)
リンク機能をつけるタグ。**href属性**でパスを指定する。

```html
<a href="パス">
    <img src="パス">
</a>
```
※画像クリックで別ページに飛ぶように指定する例

<hr><br>◎簡易メモ

1. 必ず冒頭でDOCTYPE宣言し、ブラウザにHTMLファイルであることを認識させる。
1. 各種設定や表示させたい内容はすべて<html>タグの中に記述する。
CTA試験前の暗記チェックなど（ガバナンス）

ガバナンス:eyes:
・ＷＦ：いつまでに開発が必要など、計画的に進めないといけないもの。
・アジャイル：要件の中に優先度がある。変更が頻繁。ユーザーエクスペリエンスが重要なプロダクト:santa_tone5:

### CoE (Center of Excellence)

CoE（Center of Excellence）は、特定の技術、スキル、領域、または業務プロセスにおいて優れたパフォーマンスと価値を提供するためのチームまたは組織のセンターです。CoEは、ベストプラクティスの共有、知識の蓄積、スキルの向上、イノベーションの推進を目指して活動しています。

CoEの主な役割と機能は以下の通りです。

1. **専門知識の集約**: CoEは、特定の技術や業務プロセスに関する専門知識を集約し、組織全体での利用を促進します。

2. **教育とトレーニング**: CoEは、スキルと知識の向上を支援するために教育とトレーニングのプログラムを提供します。

3. **イノベーションの推進**: CoEは、新しい技術や方法論を評価し、組織のイノベーションを促進します。

4. **ベストプラクティスの開発と共有**: CoEは、効果的な方法とツールを開発し、それを組織全体で共有します。

### アーキテクチャレビューボード (Architecture Review Board)

アーキテクチャレビューボード（Architecture Review Board、ARB）は、組織のITアーキテクチャを評価、承認、そして監視するためのグループまたはコミッティです。ARBは、新しいプロジェクトやイニシアティブが組織のアーキテクチャ基準と方針に従っていることを確保する役割を果たします。

ARBの主な活動は以下の通りです。

1. **アーキテクチャの評価**: ARBは、提案されたITプロジェクトのアーキテクチャを評価し、その適合性と効果性を判断します。

2. **ガイドラインとポリシーの開発**: ARBは、アーキテクチャに関するガイドラインとポリシーを開発し、それを組織全体で適用します。

3. **リスクの管理**: ARBは、アーキテクチャに関連するリスクを識別し、管理策を推奨します。

4. **変更の承認**: ARBは、アーキテクチャに影響を与える変更を承認し、その実装を監視します。

これらの概念は、組織が技術とプロセスを最適化し、リスクを管理し、イノベーションを促進するのに役立つ重要な役割を果たします。

### 変更管理委員会 (Change Control Board, CCB)

変更管理委員会またはChange Control Board (CCB)は、プロジェクトやプログラムの変更を管理、評価、承認、または拒否する責任を持つフォーマルなグループです。CCBは、プロジェクトの範囲、品質、スケジュール、コストなど、プロジェクトの全体的なパフォーマンスに影響を与える可能性のある変更を検討します。

CCBの主な役割は以下の通りです：

1. **変更の評価**: 提案された変更を評価し、それがプロジェクトの目標と整合性があるかどうかを判断します。
  
2. **変更の承認**: 必要に応じて変更を承認し、その実施を監督します。

3. **ドキュメンテーション**: 変更の詳細とその影響をドキュメントとして記録します。

4. **コミュニケーション**: 承認された変更を関係者に通知し、必要に応じて説明します。

### エグゼクティブスポンサー (Executive Sponsor)

エグゼクティブスポンサーは、プロジェクトまたはプログラムのトップレベルの支持者で、その成功に必要なリソース、サポート、および方向を提供する役割を持っています。彼らは、組織のリーダーシップチームの一員であり、プロジェクトの可視性、クレジビリティ、および優先順位を保証するために、その影響と権威を使用します。

エグゼクティブスポンサーの主な責任は以下の通りです：

1. **ビジョンと戦略**: プロジェクトのビジョンと戦略を明確にし、目標を達成するための方針を設定します。

2. **リソースの確保**: プロジェクトに必要な財政、人材、技術などのリソースを確保します。

3. **リスクの管理**: プロジェクトに関連するリスクを管理し、問題が発生した場合には解決策を提供します。

4. **ステークホルダーとのコミュニケーション**: プロジェクトの進捗、課題、成果などをステークホルダーに伝え、サポートと協力を促進します。

これらの役割と責任を持つエグゼクティブスポンサーは、プロジェクトが予定通りに進行し、目標を達成するために不可欠な存在です。
業務中の自分をちょっと気遣ってくれるPowerShellスクリプト

# 0. 動機
下記のQiita記事で「トースト通知」たるものを知って、これを使って何か作ってみようと思ったこと。

今回はテキストを表示するだけの若干お遊びなスクリプトですが、例えばスクリプトの中に「よく使う文字列をClipboardに書き込む」という機能を加えると、Windowsキー + Vで欲しい文字列がすぐに入力できる、という状況を作ることもできるかと思います。

https://qiita.com/relu/items/b7121487a1d5756dfcf9

その他、スクリプト起動したら完了報告にトースト通知が使う、とか便利だと思います。

# 1. スクリプト
1時間毎に「稼働時間」を表示し「休みましょう！」と呼び掛けてくれる心優しい機能となっています。
```PowerShell
#時間に関わる変数の設定
$increTime = 0 #スクリプト起動時を0とカウントした時間
$spentMin = 0 #分数
$spentHour = 0 #時数

#コンソールへの表示(後述の無限ループから抜けるコマンドを表示する目的)
[Console]::Write("Running... press Ctrl + C to stop this program")

#無限ループ
while ($true) {

    #トースト通知生成(詳細は0.動機のところにあるQiita記事参照)
    $bodyText = "勤務開始してから $spentHour" + "時間$spentMin" + "分が経過しました。`n　1時間ごとに5分休憩しましょう！"
    $ToastText01 = [Windows.UI.Notifications.ToastTemplateType, Windows.UI.Notifications, ContentType = WindowsRuntime]::ToastText01
    $TemplateContent = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]::GetTemplateContent($ToastText01)
    $TemplateContent.SelectSingleNode('//text[@id="1"]').InnerText = $bodyText
    $AppId = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
    [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($TemplateContent)

    #変数の更新
    Start-Sleep -Seconds 3600 #1時間毎に表示するので3,600秒。表示間隔を変えるならここを調整。
    $increTime += 3600 #表示間隔を変えるならここも直前の列とあわせて調整。
    $spentHour = [math]::Floor($increTime/3600) #Math.Floorメソッドで小数点以下切り捨て
    $spentMin = [math]::Floor(($increTime-$spentHour*3600)/60)

}


```


# 2. 出力

下記のトースト通知が1時間毎に表示されます。(0時間0分の所は徐々に数値が増加していきます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/e954d845-213f-32e3-8372-ddeb6fc6347d.png)


同時に立ち上がるコンソールは下記のような文字が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/be467762-6e6f-5cfe-2c9a-bcfdbeebbdf3.png)


# 3.おわりに
基本自分用メモですがどこかの誰かの役に立てば幸いです。

所定の文字列をClipboardに登録する操作については下記記事をご確認下さい。

https://qiita.com/_Sasaki_/items/4d228e696a4270112a72
化学・材料系の実験データベースを考えよう【⓪:導入編】

## はじめに
化学製品の開発の話です。


## 背景
日本の化学産業における「材料」というのは、だいたいの場合色々な原料の混ぜ物、つまり組成物を指します。
なぜかというと安く作れて高く売れる素材はだいたい高分子材料であり、高分子材料はたいていの場合単体では使わず、混ぜ物をして必要な特性を付与する必要があるためです。混ぜ物のノウハウによって付加価値をつけているということですね。

下の公開公報(適当に検索したやつ)を例にすると、主材料(PBT)と添加物の構成を変えて、印字性や機械強度のトレードオフを評価しています。材料の明細書というのは大体こんな感じで組成表が載っているものです。
> <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/afad8ec2-c410-3681-77c2-a0a29bb3e7a2.png">
>
>特開2023-114412 「樹脂組成物、成形体、および、レーザー溶着体」 (三菱ケミカル)
>https://www.j-platpat.inpit.go.jp/c1800/PU/JP-2023-114412/FCBB365058AE0C100FC595AE6195C81C8D6B659E34B331DC508A2FA77C0DE0E2/11/ja



昔、「実験条件とデータの場所データベース」を職場で作ったとき、すでに「化学とAI」のような記事や書籍は世にあふれていましたが、 **それ以前にデータを集約する仕組みをどのように実装するのか？** に関する情報はぜんぜん出回っておらず、かなり苦労した記憶があります。
多くの化学品の開発が「混ぜ物の構成を変える」というある種共通のフォーマットを通して行われるのにも関わらず、これをデータベース化するためのノウハウが世の中にあまり出回っていないというのは何とも奇妙なコトだと思いました。

前置きが長くなりました。ということで「混ぜ物の開発を集団で行う場合に、効率的(かつ楽な)なデータ管理法を実装するための一般的な方法を考える」というのがこのシリーズのテーマです。


## 目的
そもそもなぜデータを検索可能な状態で集約しないといけないのか、もう少し整理してみましょう。
仮に一人でデータベースを実装する高度な能力があったとしても、ほかのメンバーにその仕組みを強制する必要がある以上、ある程度の論理武装は必要です。

### 適切な判断をするため
データが集約されていないと、実験を設計する技術者の意識にはごく限られた直近のデータしかありません。
したがって、それまでのデータを俯瞰してみる手段が実質的に存在しません。
こうなるとGPSも地図もなしで目的地に着こうとしているようなもので、
**①現在の検討の方向性が正しいのかどうか判断できない
②実験空間の大きさを適切に設定できない
③技術者のバイアスが定量的に検証されることがなく、アドホックな(その場限りの)通説が形成される**
といった問題が起こりがちです。
当然ですが実験の結果は「うまくいった/だめだった」だけでなく、定量的に評価されその後に判断に活かされるのが理想です。データベース化はその強い味方になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/4cda5b4b-9a54-3579-b7a0-35cb37271065.png)


### 本質的なことに時間をつかうため
手分けして検討を進めている場合、会議のほとんどが情報の整理に費やされ、次のアクションが決まらないまま時間が過ぎてしまうことはよくありませんか？情報の整理、確認という研究開発的な価値を生み出さない作業に時間がかかるような状況では、「次に何をすべきか」という本質的な議論になかなか本腰を入れて取り組むことが難しくなります。




## 方針

### 無理なく情報がたまる仕組みにする
「実験のデータベース作りました！使ってください！」といっても(リーダーが協力的でない限り)普通はスルーされます。面倒ですから。
そこで、できるだけ使用者の心理的負担を軽減した形で実装する必要があります。

・実験の起票と同時にデータベースへ登録される仕組み (標準化、自動化)
・結果の解析と同時にデータベースへ登録される仕組み (標準化、自動化)
・痒い所に手が届く集約・検索機能
があるといいでしょう。

### 小さい範囲ではじめるorまず簡単なものを作ってしまう
この種の「仕事のやり方を変える」方法は多くの人を巻き込む必要がありますが、まず間違いなく難航します。いろいろな考えを持った人がいますから、こういうことに不安や反感を持つ人も中にはいます。過去にトライしてみたが、結局破綻しまい懐疑的意見を持つ人もいるかもしれません。
そこで、もし意思決定権を有する人を味方につけられていないのであれば、自分のいるチームだけ等の小さな範囲から始めるのも手です。そこから草の根作戦で徐々にいい評判を広げていけばよいでしょう。

あるいは、フォーマットの統一がある程度できているのであれば、ある程度機能するデータベースをまず作ってしまい、その後普及していくことも考えていいと思います。
私が昔作った実験データベースはこちらのタイプでした。同僚が皆決まったフォーマットの実験計画書をコピペで使いまわしていたので、そこから情報を抽出・整形し、別途作った主原料データベースの情報と合わせ、1件のレコードとしてAccessで作ったデータベースに放り込んでいく形にしました。
このデータベースはかなり好評だったんですが(自画自賛)、同時に「**以前は過去データを検索できる意義がよくわかっていなかったから、何かする手間を要求されていたら素直に従ってなかったかもしれない** 」ともいわれました。確かにこういうものは使ってみて初めてその意義がわかるという側面もあり、それがこういうデータ集約の取り組みが難航する原因でもあります。このように役に立つのだ、というビジョンを早い段階でチームと共有できるのが「まずは作ってしまう」方法のいいところです。

## 概念図
主原料を作る→混ぜ物にする→物性を評価する　のサイクルが混ぜ物開発の基本となりますから、システムの全体像としては次の図のようなものが考えられます。
(ちゃんとしたテーブル設計ではないのは許して)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/8e549bb2-2956-fa52-7adc-a5ec27e7023e.png)



## まとめ
・混ぜ物材料開発ではデータベースを作ったほうがいいが、いばらの道ではある
・データ集約機能と検索UIの作りこみはしっかりして、使用者の心理的負担を減らそう
・すぐに全員に理解してもらうのは難しいので、小さく簡単に始めてみよう

次からは概念図にしたがい構成要素の具体的な例を考えてみたいと思います。
【Swift】CIFilterで画像の色相を調整する

# はじめに
CIFIlter関係の記事3日目です
今回は色相を調整してみます。

https://qiita.com/SNQ-2001/items/bc2206232e551f5b62d4

https://qiita.com/SNQ-2001/items/044f5d9e592dddccd9b2

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-10-14 at 20.49.49.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7e61a089-1361-e4bb-4199-01a8d81988e9.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    private let image = UIImage(named: "sample")!

    @State private var uiImage: UIImage?

    @State private var hue: CGFloat = 0.0

    var body: some View {
        ScrollView {
            VStack {
                if let uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                } else {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit()
                }

                Button {
                    applyHueAdjust()
                } label: {
                    Text("更新")
                }

                VStack(spacing: 0) {
                    Text("hue: \(hue.description)")
                    Slider(value: $hue, in: -1.0...1.0)
                }
            }
            .padding(.horizontal, 20)
        }
    }
    
    func applyHueAdjust() {
        let context = CIContext()
        let inputImage = CIImage(image: image)!
        // 色相を調整
        guard let hueAdjustFilter = CIFilter(name: "CIHueAdjust", parameters: [
            kCIInputImageKey: inputImage,
            kCIInputAngleKey: hue
        ]) else { return }
        // 出力
        guard let outputImage = hueAdjustFilter.outputImage else { print("ここ1"); return }
        guard let cgImage = context.createCGImage(outputImage, from: inputImage.extent) else { print("ここ2"); return }
        self.uiImage = UIImage(cgImage: cgImage)
    }
}
```

# おわり
いい感じにできました
Everyday Rails - RSpecによるRailsテスト入門を読んだ感想

こちらは、初学者が初めて読んだ自動テスト本の感想になります。

## 良かったところ
- 環境構築やgemのバージョンエラーなどで動作しないといった問題に初学者はよく遭遇しがちだと思います。Gitの基本的な操作は不可欠ですが、それさえできれば簡単に始めることができます。
- 各セクションは短く、コード例も提供されています。一緒に動作を確認しながら進められるので何をしているかがわかりやすいです。また、なぜそのテストが必要かという説明も書かれているので、その目的を理解しやすくなっています。
- URLが細かく記載されているので、詳細を知りたい場合にすぐ確認できるようになっています。

## 学んだこと
- テストを書く際のアウトラインの重要性
- Factory、Capybara、LaunchyといったGemの使い方
- テスト駆動開発の一般的なプロセスについて


## 難しかったこと
- 後半に進むにつれて、前章までの内容が積み重なるので整理するのが難しい
- モックとスタブの概念について完全には理解できなかった

１週読んだ内容の理解度は半分程度ですが、初学者にもわかりやすい表現で書かれている本でした。この本を参考に実際にテストを書いて習得したいと思います！
Wireshark

<!--
2023/10/19
-->

[picoCTF][Forensics][PcapPoisoning]

## Writeup
* pcapファイルなので、とりあえずWireshark。
出力できるファイルも無さげ。
仕方がないので、上から見ていく。
IDとパスワードを送ってそうなパケットもある。
メッセージっぽいパケットを発見。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/5e3e484d-d52d-de9b-3077-1d8dc6fa5752.png)
<br>

* `Flag is close` フラグは近くなのか。
上から順に、`Follow` `TCP Stream`
4番目を確認したら、フラグを発見
![screenshot 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/c9c88d8d-326e-1b86-9206-5fd3430fc220.png)
![screenshot 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/5c5d075e-6291-1997-cf5e-eea967c55d0d.png)

## Writeup2
* 大きいパケットなさそうだから、パケットサイズでSort。
一番上のパケットに、フラグを発見。
![screenshot 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/5e88319d-9efd-17f8-cf92-778d54eeaa9b.png)