OmniAICreator/Qiita-1.07M huggingface dataset:
大規模なマイクロサービスでなくてもPact CIを導入する理由

## CDCテストとは
CDC(Consumer Driven Contract) テスト、消費者駆動契約テスト。[Pact](https://docs.pact.io/) はCDCテストのフレームワークです。Pactは協定という意味。
高価で脆いE2Eテストを、高速で信頼性が高く、デバッグが容易なユニットテストに置き換えます。

以下、Consumer を FE(FrontEnd)、Provider を BE(BackEnd)とします。

## 何の問題を解決する手法か（なんの効果があるのか）
CDCは大規模なマイクロサービスになって、チーム数やサービス数が増えたときにテストのコストが増大する問題を解決します。テストのコストを低減する効果があります。
E2Eテストを減らし、結合テストをリバランスし、テストピラミッドを縮小することができます。
大規模なマイクロサービスのときに真価を発揮します。
![IMG_6993.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176198/979fb30c-61bf-d5ca-cad0-91767ade1fc1.png)
![IMG_6996.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176198/c4ed2fb8-3686-aeae-39c9-64a0f81b527d.png)

## Pact CIを導入する理由
チーム数やサービス数が少ない場合CDCテストの導入によるテストのコストを低減する効果はあまりないという意見もあります。大規模なマイクロサービスでなくてもPactの**CI**を導入したほうがよいと考える理由は、BEの結合テストでは検証できない、FEとBEのI/Fの整合性を**効率よく**検証できるから　です。Pactを**CI**に導入することで、テストが自動化され、開発効率が向上します。短期的には、大規模なマイクロサービスのときよりもコストを低減する効果は期待できないかもしれません。しかし、長期的には、テスト削減効果を期待できます。また、早期に導入することで、マイクロサービスの開発への対応がスムーズになります。ただし、導入コストはかかります。

FEとBEのAPI I/F の不整合が起きる場合は2つあります。
BEを変更した場合　と　FEを変更した場合　です。
- BEを変更した場合
  - 例えば、GET  /users/123 の項目の削除したとき、FEは 項目が利用できません。FEの対応が必要です。
- FEを変更した場合
  - 例えば、GET  /users/123 の項目の追加したとき、BEは 項目を提供できません。BEの対応が必要になります。

→ このFEとBEのAPI I/Fの不整合をCI実行時に検出できます。

## Pactの基本
[How Pact works](https://pactflow.io/how-pact-works/?utm_source=ossdocs&utm_campaign=getting_started#slide-1)　が参考になります。

Pactの基本は、3つのステップです。
- 契約ファイルの作成
  - FEでモックAPIに対して、リクエストとレスポンスをキャプチャします。 
- 契約ファイルの共有
  - 契約ファイルには、期待するリクエストとレスポンスのインタラクションが記載されます。
- 契約ファイルで検証
  - BEでリアルAPIに対して、リクエストとレスポンスを検証します。 

## Pactのポイント
- FEのニーズをBEが満たしているかを検証します。消費者駆動テストです。契約ファイルが仕様と一致していることが前提です。FEのPactテストは必ず正しく書かなければなりません。これは、不整合の未検出を減らします。
- 契約ファイルを介して、FEとBEを分離してテストします。契約テストです。FEとBEのテストデータを一致させる必要があります。壊れないようにするためです。これは、不整合の誤検出を減らします。

## ツールの紹介
MSWとPactの統合ツールがあります。MSWで、FEチームがBEチームの開発作業と並行して、あるいは先行して作業できるようにすることができます。MSWをPactのモックAPIにすることで、CDCを導入できます。
[pact-msw-adapter](https://docs.pactflow.io/docs/bi-directional-contract-testing/tools/msw)
【React】dangerouslySetInnerHTMLの危険性と安全な使用方法

## dangerouslySetInnerHTMLとは？
`dangerouslySetInnerHTML`はReactのプロパティで、HTML形式の文字列をHTMLとして扱い、そのHTMLをコンポーネント内に直接挿入することができます。
外部から取得したHTMLコンテンツを表示する場合などに使用します。

```jsx
<div dangerouslySetInnerHTML={{ __html: '<p>some html</p>' }} />
```

上記のコードは`<p>some html</p>`というHTMLを`<div>`タグの中に挿入し、結果としてブラウザに"some html"というテキストを表示します。

しかし、`dangerouslySetInnerHTML`は名前にdangerouslyとある通り、使用には危険が伴うため注意が必要です。

公式ドキュメントはこちら↓

https://ja.react.dev/reference/react-dom/components/common#common-props

## dangerouslySetInnerHTMLの危険性
### 1. XSS攻撃のリスク
`dangerouslySetInnerHTML`の最大の危険性は、XSS（クロスサイトスクリプティング）攻撃のリスクがあることです。
攻撃者はHTML文字列に悪意のあるスクリプトを埋め込み、ユーザーがフォームに入力した個人情報を盗んだり、ページを改ざんしたりといったことができてしまう可能性があります。

```jsx
const userInput = '<img src="x" onerror="alert(\'XSS Attack\')" />';
<div dangerouslySetInnerHTML={{ __html: userInput }} />
```

上記のコードでは、ユーザーからの入力をそのまま`dangerouslySetInnerHTML`に渡しています。もしも悪意のあるスクリプトが埋め込まれていたらそれが実行されてしまうかもしれません。

:::note warn
`dangerouslySetInnerHTML`は内部に`innerHTML`と同じ機能を持っているので、scriptタグはデフォルトで無効化されます。しかしイベントハンドラなどは実行できてしまうのでおまけ程度に考えておきましょう。
:::

#### 対策：サニタイズ処理を行う
XSS攻撃を回避するためには、ユーザーからの入力をそのまま表示するのではなくサニタイズをする必要があります。
サニタイズとは「消毒」という意味で、悪意のあるスクリプトを無害なものに変換することです。

また、サニタイズはセキュリティに直結する重要な処理なので、自前で実装するのではなくきちんと整備されたライブラリを使用することが推奨されています。

例えば、`DOMPurify`というライブラリを使用してサニタイズを行う場合は下記のようになります。
https://github.com/cure53/DOMPurify

```jsx
import DOMPurify from 'dompurify';

const sanitizedHTML = DOMPurify.sanitize(userInput);
<div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
```
`DOMPurify.sanitize`関数は入力されたHTML文字列を解析し、悪意のあるスクリプトを取り除きサニタイズします。その結果、安全に表示できるHTML文字列が生成されるのでXSS攻撃を防ぐことができます。

### 2. 直接DOMを操作することになる
Reactは仮想DOMを使って効率的にレンダリングを行いますが、`dangerouslySetInnerHTML`を使うとこの仮想DOMを通らずに直接実際のDOMを変更してしまいます。
これにより仮想DOMと実際のDOMに差分が生まれ、パフォーマンスの低下や、予期しない動作やバグを引き起こしてしまう可能性があります。

しかし、これは`dangerouslySetInnerHTML`で挿入されたHTMLがアプリケーション内で何らかの対話性を持つ場合に発生します。
静的なHTMLコンテンツを表示することだけが目的であればこのリスクは軽減されます。

:::note info
仮想DOMとは実際のDOMの軽量なコピーで、Reactが効率的なレンダリングを行うために使用します。変更がある度に新旧のDOMを比較し、変更箇所だけを実際のDOMに反映します。
:::
 
#### 対策：ライブラリを使用して仮想DOMとして利用する

この問題を解決するためには、HTMLを仮想DOMとして扱うことができるライブラリを使用することが推奨されます。例えば、`html-react-parser`というライブラリを使用すると、HTMLをReactの要素に変換することができます。
https://github.com/remarkablemark/html-react-parser

```jsx
import parse from 'html-react-parser';

const reactElement = parse(userInput);
<div>{reactElement}</div>
```

このコードでは、parse関数を使用してユーザーからの入力をReactの要素に変換してから表示しています。これにより、Reactの仮想DOMを利用することができ、パフォーマンスの低下やバグの発生を防ぐことができます。

:::note warn
仮想DOMとして扱うライブラリを導入することによって`dangerouslySetInnerHTML`を使用しないことになりますが、XSS攻撃の危険性は残っています。なのでサニタイズ処理は別途必要なことに注意しましょう。
:::

## まとめ
取得したHTML文字列が信頼できるもので、`dangerouslySetInnerHTML`によって挿入されるHTMLが静的なコンテンツに限定されている場合、`dangerouslySetInnerHTML`を使用することは概ね安全だと言えるでしょう。

しかし、そうでない場合はサニタイズ処理や仮想DOM化といった適切な対策が必要となってきます。

ただ、外部ライブラリを使用する場合はそのライブラリの更新やセキュリティフィックスに依存することとなり、メンテナンス負荷を増やす可能性があるのでその点は注意が必要です。
【TypeScript】Interfaceについてメモ（更新中）

# 概要
typescriptの`interface`についてよくわからなかったので調べてみる。

# interfaceとは？
`interface`とは、クラスが実装すべきフィールドやメソッドを定義した型。
クラスはインターフェースを実装することで、型のルールを作れて、チェックが可能になる。

JavaやPHPなどで使われているが、JavaScriptにはないため、TypeScriptで可能となった。

TypeScriptでのインターフェースの役割はコンパイル時の型チェックであり、JavaScript実行時には影響がない。

# 名前的型付けと構造的型付け
型の区別や互換性の判定をする型システムには以下二つが存在

| 型付け | 概要 |
|:--|:--|
| 名前的型付け | 型の名前に基づいて型の区別を行う。 |
| 構造的型付け | 型の構造に基づいて型の区別や互換性を判定する。 |

## 名前的型付け
型の名前に基づいて型の区別を行うシステム。
`string`型と`number`型は名前が異なるため、異なる方として扱われる。
クラス`Person`型と`Dog`型も同様に名前が異なるため、異なる方として扱われ、互換性もないものと判断される。

Java, PHP, C#, Swift等で採用されている。

## 構造的型付け
型の名前ではなく、その構造に注目して区別、互換性の判定がされる。
この方法では、型が持つプロパティやメソッドの構造が同一であれば、名前が異なっている型同士でも互換性があるものとみなされる。

以下`Person`クラスと`Dog`クラスでは、共にwalkメソッドを1つ持っているという同一の構造となっている。
この場合、`Person`と`Dog`は互換性があるものとして判定される。
```ts 
class Person {
  walk() {}
}
 
class Dog {
  walk() {}
}
```

## まとめ
|   | 名前的型付け | 構造的型付け |
|:--|:--|:--|
| 型の区別基準 | 型の名前 | 型の構造 |
| 互換性の判定 | 名前が同じであれば互換性あり | 構造が同じであれば互換性あり |
| 主な採用言語 | Java, C#, Swift, PHPなど | TypeScript, Goなど |
Font Awesomeを使ってアイコン配置してみる

初めてFont Awesomeを使ってみる。

https://fontawesome.com/

メールアドレスとパスワードの設定だけしたらこんな感じに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724787/9fddd9be-c2c6-ef3a-e562-621aba53d6e1.png)

ロケットアイコンのSet up icons in a project with 1 line of code.を押して、
表示されたscriptタグをコピーして、htmlファイルのheadタグ内に貼り付ける。

bodyタグ内にアイコン配置してみる。
```
<div class="icons">
    <i class="fa-solid fa-user"></i>
    <i class="fa-solid fa-triangle-exclamation fa-fade"></i>
    <i class="fab fa-youtube"></i>
</div>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724787/5134a824-44f1-4cd1-e91c-6286a79c7ece.png)

アイコン、とてもかわいい😊
Vim が使えなくなった話

## 起こったこと

Mac の OS アップデートとか，ユーザー名変更とか色々やった後に，
Vim の入力をするのに，Ctrl-C をしないといけなくなった．

全然わからないけど，全然わからなかった．

## やったこと

とにかく，何が起きたのかよくわからない．
おそらく，insert するときにだけ stack している雰囲気．
一応，plugin を全部切ったりすると動くけど，そういう話なのか？という感じ．

当たりをつけるために，dtruss を使ってみる．

ふんわりしか見てないけど `nodenv` が動いていて，それが入力待ちになってるのではないか，という予想をする．

### Refs

https://qiita.com/yurakawa/items/2ab084a2f3f0aa0bf0c7

## 解決編

nodenv の ROOT が `$HOME/.nodenv` だったので

```shell-session
$ rm ~/.nodenv/shims
$ nodenv rehash
```

### 説明

最初の行に書いたけど，ユーザー名変更をしていて，
一緒にホームディレクトリも変更していた．

そのため，ファイルの中に絶対パスを書いてあるスクリプトを生成されていると，
それが no such file になっていたりして，色々良くなかった．

```console
$ tail -1 ~/.nodenv/shims/node
exec "/usr/local/Cellar/nodenv/1.4.1/libexec/nodenv" exec "$program" "$@"
```

こんな感じで，exec $program してるので，まあそんな感じ．

### Refs

https://qiita.com/t_kokubo/items/d5d2a6e67be08b7b88a9
innomaker USB-CANトングルを自動接続する

## 背景
接続しても/devで認識されない。しかし、lsusbで探すと出てくる。毎度接続するたびにうまくいったり、いかなかったり一喜一憂している現状を変えようと決断。

## 環境
ubuntu 22.04

## 解決法
```
sudo nano /etc/udev/rules.d/10-canusb.rules
```
して、そのファイルに
```/etc/udev/rules.d/10-canusb.rules
ACTION=="add",\
SUBSYSTEMS=="usb",\
ATTRS{idVendor}=="1d50",\
ATTRS{idProduct}=="606f",\
RUN+="/bin/bash /home/universe/Documents/canusb_setup.sh"
```
と入力。それぞれ、
「刺されたら」「USBが」「vender id」「vender product」「走らせるプログラム」
ということ。vender id とvender productはlsusbで探せる。

走らせるプログラムは
```canusb_setup.sh
#!/bin/bash 
sudo ip link set can0 type can bitrate 500000
sudo ifconfig can0 up
```
最後に、このプログラムの実行権限を
```
sudo chmod 777 canusb_setup.sh
```
にして完了。抜き差しした後に
```
candump can0
```
してデータが流れ出したら成功。
CHECKという名のスキーマは作成できない（方法はある）

## 結論

　予約語をそのまま`CREATE SCHEMA`文に記述すると、弾かれることがある。
　例えば CHECK というキーワードは、PostgreSQL 14のドキュメント「[付録C SQLキーワード](https://www.postgresql.jp/document/14/html/sql-keywords-appendix.html)」に依ると**予約語**として扱われているため、`CREATE SCHEMA CHECK;`では通らない。

　どうしてもCHECKでスキーマ作成したい場合には、
 ```sql
 create schema "check";
 ```
 などと二重引用符で括ると通る。

　なお、こうやって作成すると、`"check".t_foo_bar_baz`みたいなアクセス方法になることに注意。常に二重引用符で括ってあげなくてはいけなくなる。
Python 復習

# はじめに
先日、職業訓練校を修了した、bdrccです。
最近はPHPに注力していたこともあり、Pythonの基本構文がだんだん抜けていることに気がつきました。
そこで、改めて基本的な文法を、ここでアウトプットしておこうと思います。

# 文字列を１文字ずつ配列に
`split`ではなく、`list`で

```py:
name = 'bdrcc'
name_split = list(name)
print(name_split)
# ['b', 'd', 'r', 'c', 'c'] が出力される
```

# １文字ずつの配列を結合
`join(~)`で
これは記憶がありました

```py:
name_split = ['b', 'd', 'r', 'c', 'c']
name_join = ''.join(name_split)
print(name_join)
# bdrcc が出力される
```
AWS責任共有モデルについての学習記録

# AWSの責任共有モデルとは
#### AWSとユーザーの責任が明確に分かれていること

それぞれのセキュリティ担当範囲について下記の図をご覧ください。

![Qiita用.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806884/dcb7a210-a406-d9b6-645f-469e67603003.jpeg)
---

### クラウド本体のセキュリティ
##### AWS側はクラウド本体のセキュリティ部分を担当します。
ハードウェアやマネージドサービスのソフトウェアおよびそれに含まれる各種サービスの管理（アップデート、セキュリティパッチのインストール）は**AWSの担当**になります。

### クラウド内のセキュリティ
##### ユーザーはクラウド内のセキュリティを担当します。
ゲストオペレーティングシステムの管理、関連アプリケーションソフトウェアの管理、セキュリティグループファイアウォールの設定やデータなどが**ユーザーの担当**になります。使用するAWSサービスによっても変わりますが、AWSによってセキュリティに関する便利なサービスやツールも提供されています。

---

### マネージドでないサービスのセキュリティ
Amazon EC2(サービス)はユーザーが管理者権限を持ち、OSを管理します。
EC2インスタンスの場合ゲストOSの管理やインスタンスにインストールする全てのアプリケーションソフトウェアの設定、ファイアウォール(セキュリティグループ)の設定に責任を負います。
###### ・マネージドではないサービスにおいてユーザーが操作できる部分はユーザーの責任

### マネージドなサービスのセキュリティ
マネージドなサービスの例としてAmazon RDSやAmazon DynamoDBなどがあります。
ユーザーから直接見たり触れたりできない部分のセキュリティをAWS側が行います。(OSやDBのパッチ適用など)
###### ・マネージドなサービスを利用することでユーザーのセキュリティに関する負担を軽減

---

## まとめ
責任共有モデルとはユーザーとAWSが責任を擦り付けあうものではなく、それぞれが責任範囲を理解し注力することでエンドユーザーが安心・安全に使用できるITシステムを構築することが目的です。

---

#### 参考
https://aws.amazon.com/jp/compliance/shared-responsibility-model/
LinkStation LS720D 所感＆SSHアクセス

（うわ、5年ぶり？の投稿か…）

LS520Dからの置き換えでLS720D（1202）を購入。これで4代目。
初めてNASを導入したのはかれこれもう20年前くらいか…初代からBuffalo NASを使い続けている。

ここ数ヶ月、先代LS520Dが数日毎にフリーズするようになり騙し騙し使っていたのだが、起動しなくなった2代目からLS520Dへのデータ移行に非常に苦労したので、今回はまだ生きているうちにリプレース。
※あの時は2代目からドライブを抜き、PC内にLinuxの仮想マシンを構築して接続、rsyncでデータをPC内に吸い上げ、今度は別途用意した外付けHDDへ転送。LS520Dのダイレクトコピーが使い物にならず（後述）、まだSSHアクセスの情報も無く、仕方なく有線1Gbpsファイル共有のカメ足速コピーで凌いだ。

# 所感
正直だいぶガッカリしている。
先代LS520Dで苦労していたところが全く改善されていない。

## ダイレクトコピーが使い物にならない
先代LS520Dでも同じ現象が起きていたのだが、ダイレクトコピーを開始すると早いときは数分、遅くとも数時間で本体がフリーズする。
Buffaloさん、ちゃんとテストしてる？？
おそらく少量、小容量なら問題無いのだろうが、数十GBを超えると何度やっても全然ダメ。
コピー元はBuffaloの4TB外付けHDDと、トランセンドのUSB3.2 256GBメモリー。どちらも同じ結果。

## お粗末なWEBアクセス
データ移行、整理のためWEBアクセスでフォルダやファイルの移動を行っているのだが…
（異なる共有フォルダ間の移動は、PCの共有経由で行うとコピーになるので時間がかかる）
本体内での「移動」なのにメチャメチャ時間がかかる！いったいどういうこと？？
WEBアプリケーションの使用言語に用意されているファイル・フォルダ移動処理を使えば、一瞬…とまでは言わずとも、どんなに大量でも数分あれば終わるはずだ。数十分、数時間もかかることはあり得ない。
移動処理中の画面を見ていると、どうやらフォルダ階層を再帰的にたどってファイル・フォルダをひとつひとつ処理しているように見える。
なんでそんなことしているのだろう？？あまりにお粗末だ。

というわけで、またしてもSSHアクセスが必要になった。
（こんなことしなくて済めばいいのに…）

# SSHアクセス
[LsLoverさんのレビュー（LS720D0402）](https://review.kakaku.com/review/K0001312404/)がたいへん参考になりました。感謝。
以下、具体的なコマンドを整理したので、共有します。
※Java、acp_commander については省きます

#### sshd_config
HostKeyの設定が邪魔になるので、コメントアウトしてデフォルト値に戻す
```shell:sh
java -jar acp_commander.jar -t <LS720DのIPアドレス> -ip <LS720DのIPアドレス> -pw <adminのパスワード> -c "sed -i 's/^HostKey/#HostKey/g' /etc/ssh/sshd_config"
```

#### 起動スクリプト
ドハマリした箇所。ここをコメントアウトしないと起動スクリプトが走らない。※sftpを使いたい方はこれではダメかも
```shell:sh
java -jar acp_commander.jar -t <LS720DのIPアドレス> -ip <LS720DのIPアドレス> -pw <adminのパスワード> -c "sed -i '/SUPPORT_SFTP/,/fi/ s/^/#/' /etc/init.d/sshd.sh"
```

#### sudoの設定
LS720DはどうもSSH rootログインができないっぽいので、adminからsudoできるようにする。NOPASSWDはお好みで。
```shell:sh
java -jar acp_commander.jar -t <LS720DのIPアドレス> -ip <LS720DのIPアドレス> -pw <adminのパスワード> -c "sed -i 's/#%admin ALL=(ALL) ALL/%admin ALL=(ALL) NOPASSWD: ALL/g' /etc/sudoers"
```

#### sshdの起動
```shell:sh
java -jar acp_commander.jar -t <LS720DのIPアドレス> -ip <LS720DのIPアドレス> -pw <adminのパスワード> -c "/etc/init.d/sshd.sh start"
```

これでSSHアクセスができるようになります。
ユーザーはadminでアクセスしてください。

```shell:sh
ssh admin@<LS720DのIPアドレス>
```

なお、これらの変更は**再起動とともに消え失せて元に戻ります**。
なので以下のようなシェルスクリプトを作っておくとよいでしょう。

```shell:start-sshd.sh
#!/bin/bash
sed -i 's/^HostKey/#HostKey/g' /etc/ssh/sshd_config
sed -i '/SUPPORT_SFTP/,/fi/ s/^/#/' /etc/init.d/sshd.sh
sed -i 's/#%admin ALL=(ALL) ALL/%admin ALL=(ALL) NOPASSWD: ALL/g' /etc/sudoers
/etc/init.d/sshd.sh start
```

start-sshd.sh などとして共有フォルダに置いておけば、再起動後は以下のようにすればSSHアクセスができるようになります。

```shell:sh
java -jar acp_commander.jar -t <LS720DのIPアドレス> -ip <LS720DのIPアドレス> -pw <adminのパスワード> -c "/mnt/array1/<共有フォルダ名>/start-sshd.sh"
```
Unable to access configuration file (delegates.mgk) 発生

# はじめに
謎が残ったままですが解決したのでメモです。

エラーが発生したソースは以下です。
```php
use Gmagick;
:
        $file = $request->file('data');
        if (0 == strcmp($mime_type, 'application/pdf')) {
            // pdf -> jpg変換
            $gmagick = new Gmagick();
            $gmagick->setResolution(150, 150);
            $gmagick->readimage($file->getRealPath()); <= ここ！
```

# 動作環境
+ Laravel Framework 5.8.22
+ AWS EC2 (Amazon Linux)
+ PHP 7.2.17

# 前提
AWS EC2のコピーを作成し、作成された新しいEC2上で上記の処理を実行
**EC2のコピーを作成する手順の違いでエラーが発生するパターンと発生しないパターンに分かれた**

# エラーが発生するパターン
1. コピー元のEC2からスクリーンショットを取得
1. 上記1.のスクリーンショットからボリューム作成
1. ボリュームからEC2を作成

# エラーが発生しないパターン
1. コピー元のEC2からスクリーンショットを取得
1. 上記1.のスクリーンショットからボリューム作成（ここまでは上記と同じ）
1. 新しいEC2を作成
1. 上記3.で作成したEC2を停止し、自動で作成されたボリュームをデタッチ
1. 上記2.で作成したボリュームをアタッチ
【大学生必見】　Session Buddy　～研究に役立つ！おすすめChrome拡張機能～【初投稿】

# はじめに
はじめまして．
初投稿なんで今回は自分がよく使っているChromeの拡張機能について紹介します.

研究のために毎日いろんな文献を調べている人はもちろん，普段の生活でよく調べ物をする人にもおすすめです．
___
# Chromeの拡張機能って何？
もしかしたらChromeの拡張機能を知らない人もいるかもしれないので，一応ご説明します．
Chrome拡張機能とは， __Chromeブラウザに機能を追加することができるアドオンツール__ のことです．Chromeウェブストアからインストールができます．

調べ物を便利にするものから旅行計画に使うもの，リラックスしたいときに使うもの，暇なときにするゲームまで種類はたくさんありますので，「どれをいれたらいいのわからない」というようなことも起こりえると思います．

ネットでおすすめの拡張機能をまとめているサイトも多くありますので，それらを参考にしてみてもいいかもしれません．

ただし，拡張機能の中には悪意のある「マルウェア」なるものも含まれる可能性があり，十分に調べてからインストールするようにしましょう．
# Session Buddy
ここからは私のおすすめする拡張機能， __「Session Buddy」__ をご紹介します．

「Session Buddy」とは， __現在開いているタブをすべて一括で保存・復元する__ ことができる拡張機能です．
いまいちピンと来ていない方もいると思いますので，実際に導入から使用するまでを説明していきます．
___
まずChromeウェブストアにアクセスし，「Session Buddy」と検索しましょう．

![sessionbuddy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/eaa5b413-4310-cea1-c530-b90f0751d977.png)
この画面にたどり着いたら，「Chromeに追加」を押しましょう．

すると，右上のほうにパズルのピースのようなものが追加されたと思います．

これを押すだけで，追加した拡張機能を好きなだけ使うことができます．とても簡単でしょ？
___
実際の使い方もとても簡単です．

画像のようにたくさんのタブを出して調べ物をしていたとしましょう．

![スクリーンショット 2024-06-04 145942.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/ecbc170b-e16d-05a4-283f-0448b67104ce.png)

今日の作業をここまでにして次回また続きをやろうと思いますが，ここで「うわぁ，ここまで頑張って調べたけど，次また調べ物するときにはまた全部検索して見つけないといけないのか」とか「めっちゃいいサイトたくさん見つけた！まとめて保存したい！」と思ったときに，Session Buddyを選択しましょう．

![スクリーンショット 2024-06-04 150006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/a1bad916-0ad5-3557-c2ef-7d14c7ce10a2.png)

すると次のような画面が出ると思います．

![スクリーンショット 2024-06-04 150121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/59c8b6f2-8df6-5d24-9c30-6a0fe9114211.png)

ここで右上の「Save」を押すと開いているタブすべてを保存します．いくつかのタブのみを保存したい場合は，そのタブだけを選択してSaveしましょう．

保存したタブの塊は「COLLECTIONS」に保管されます．

ここではその塊たちを「テスト」と名前を付けておきましょう．

![スクリーンショット 2024-06-04 150211.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/08c0fe2d-d6c8-15e2-bc7b-a91f7d839b74.png)

この状態で一度ブラウザを落とし，再度ブラウザを立ち上げました．

そしてSession Buddyを押して先ほどの画面に移ります．

![スクリーンショット 2024-06-04 150959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/9d94476d-a76e-8e3f-02b4-0e454fed1be0.png)

画面を見てもらえるとわかりますが，タブは今開いているSession Buddy１つだけですね．ここでCOLLECTIONSから「テスト」を選んで「Open」を押すと…

![スクリーンショット 2024-06-04 150305.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801451/549f4775-e615-51b1-fab1-3f7cdc08167f.png)

このように「テスト」として保存しておいたタブすべてが一括で復元できました．これで前回の続きから調査を進められます．

１つ問題として，これはWeb上のサイトを保存・復元できるものなので，例えば自身のローカルに保存しているファイルなどは復元しようとしてもエラーが出てしまいます．その点は注意しましょう．
yfinanceを使って株価データを取得する方法

## yfinanceとは？

yfinanceは、Yahoo Financeから株価データを取得するためのPythonライブラリです。
このライブラリを使うことで、株価データの取得が非常に簡単になります。

## 環境設定

まず、yfinanceをインストールする必要があります。
以下のコマンドを実行してインストールしましょう。

```bash
pip install yfinance
```

## 株価データの取得

それでは、実際にyfinanceを使って株価データを取得してみましょう。
今回は、Appleの株価データを例にします。

```python
# yfinanceをインポート
import yfinance as yf

# 銘柄シンボルを指定してデータを取得
apple = yf.Ticker("AAPL")

# 歴史的な株価データを取得
hist = apple.history(period="1mo")

# 取得したデータを表示
print(hist)
```

### 各処理の説明

1. **ライブラリのインポート**
    ```python
    import yfinance as yf
    ```
    まず、yfinanceライブラリをインポートします。

2. **株式データの取得**
    ```python
    apple = yf.Ticker("AAPL")
    ```
    `Ticker`クラスを使って、Appleの株価データを取得します。
    ここでは、Appleのティッカーシンボル（AAPL）を指定します。

3. **歴史的な株価データを取得**
    ```python
    hist = apple.history(period="1mo")
    ```
    `history`メソッドを使って、過去1ヶ月間の株価データを取得します。
    `period`パラメータには、取得したい期間を指定します。
    （例: "1d"、"5d"、"1mo"、"3mo"、"6mo"、"1y"、"2y"、"5y"、"10y"、"ytd"、"max")

4. **データの表示**
    ```python
    print(hist)
    ```
    取得した株価データを表示します。

## グラフの作成

取得した株価データをグラフに表示してみましょう。
Pythonのmatplotlibライブラリを使用します。

まず、matplotlibをインストールします。

```bash
pip install matplotlib
```

以下のコードを実行して、株価データのグラフを表示します。

```python
# 必要なライブラリのインポート
import matplotlib.pyplot as plt

# 株価データの取得
apple = yf.Ticker("AAPL")
hist = apple.history(period="1mo")

# グラフのサイズを設定
plt.figure(figsize=(10, 5))

# 日付をX軸、終値をY軸にしてグラフを作成
plt.plot(hist.index, hist['Close'], label='Apple (AAPL)')

# グラフのタイトルを設定
plt.title('Apple Stock Price - Last 1 Month')

# X軸のラベルを設定
plt.xlabel('Date')

# Y軸のラベルを設定
plt.ylabel('Closing Price (USD)')

# 凡例を表示
plt.legend()

# グリッドを表示
plt.grid()

# グラフを表示
plt.show()
```

### 各処理の説明

1. **ライブラリのインポート**
    ```python
    import matplotlib.pyplot as plt
    ```
    matplotlibライブラリをインポートします。

2. **株価データの取得**
    ここは先ほどの株価データ取得と同じです。

3. **グラフの作成**
    ```python
    # グラフのサイズを設定
    plt.figure(figsize=(10, 5))
    # 日付をX軸、終値をY軸にしてグラフを作成
    plt.plot(hist.index, hist['Close'], label='Apple (AAPL)')
    # グラフのタイトルを設定
    plt.title('Apple Stock Price - Last 1 Month')
    # X軸のラベルを設定
    plt.xlabel('Date')
    # Y軸のラベルを設定
    plt.ylabel('Closing Price (USD)')
    # 凡例を表示
    plt.legend()
    # グリッドを表示
    plt.grid()
    # グラフを表示
    plt.show()
    ```

以上
ChatGPTを活用したセキュリティヘッダーの確認と改良方法

## はじめに
セキュリティヘッダーを適切に設定するの、難しくないですか？
個人でウェブサービスを開発していると、設定の方法がすぐにわからないのでついつい後回しにしがちですよね。
しかしウェブサイトのセキュリティを向上させるためには、セキュリティヘッダーの適切な設定が不可欠です。
本記事では、セキュリティヘッダーの確認ツールを使い、ChatGPTの力を借りて不足しているヘッダーを追加・改良する方法を解説します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807812/f2d16d9f-8086-784a-a8b7-fe8ce1b73775.png)

## セキュリティヘッダーの確認
まず、[securityheaders.com](https://securityheaders.com/)を使用して、サイトに不足しているセキュリティヘッダーを確認します。
画像は私の開発したウェブサービスの結果です。修正後なので評価がA+になっていますが、修正前はFでした。
不足しているヘッダー項目がある場合は「Missing Headers」セクションに表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807812/a3b02832-3332-3a4d-c55e-dca1da2c4ab4.png)
不足がある場合は以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807812/732c00d0-1c2c-3b83-d24c-3160c9ad65ab.png)

### 手順
1. ブラウザで[securityheaders.com](https://securityheaders.com/)にアクセスします。
2. 確認したいサイトのURLを入力し、`Scan`ボタンをクリックします。
3. 結果ページに表示される「Missing Headers」セクションで不足しているヘッダーを確認します。

## ChatGPTを使ってセキュリティヘッダーを改良する
次に、ChatGPTに不足しているヘッダーを追加する方法を尋ね、具体的な設定ファイルの内容を生成してもらいます。ここでは、Apacheを例に解説します。

### プロンプトの作成
ChatGPTに質問するためのプロンプトを作成します。以下はサンプルプロンプトです。

#### サンプルプロンプト
```
私はApacheを使用しているウェブサイトのセキュリティヘッダーを改善したいです。以下のヘッダーが不足しています。これらのヘッダーを追加するためのApacheの設定ファイルの内容を教えてください。

- Content-Security-Policy
- X-Content-Type-Options
- X-Frame-Options
- Strict-Transport-Security
- Referrer-Policy
- Feature-Policy
```

### ChatGPTの生成内容
ChatGPTが生成したApacheの設定ファイルの内容は以下のようになります。

#### Apacheの設定ファイル例
```
# /etc/apache2/conf-available/security-headers.conf

# Content-Security-Policy
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none';"

# X-Content-Type-Options
Header set X-Content-Type-Options "nosniff"

# X-Frame-Options
Header set X-Frame-Options "DENY"

# Strict-Transport-Security
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

# Referrer-Policy
Header set Referrer-Policy "no-referrer-when-downgrade"

# Feature-Policy
Header set Feature-Policy "geolocation 'self'; microphone 'none'; camera 'none'"
```

## Apacheに設定を反映させる
生成された設定ファイルの内容をApacheに反映させる方法を解説します。

### 手順
1. 設定ファイルを作成します。
   ```bash
   sudo nano /etc/apache2/conf-available/security-headers.conf
   ```
2. 上記の生成内容をコピーし、ファイルに貼り付けます。
3. ファイルを保存して閉じます。
4. 設定を有効にします。
   ```bash
   sudo a2enconf security-headers
   ```
5. Apacheを再起動して設定を反映させます。
   ```bash
   sudo systemctl restart apache2
   ```

## まとめ
セキュリティヘッダーの不足を確認し、ChatGPTを活用して適切な設定を生成することで、ウェブサイトのセキュリティを強化できました。
今回はApacheでしたが、NGINX等ほかの環境でもプロンプトで説明すれば問題なく設定ファイルの内容を生成できるかと思います。
本記事の手順に従い、自身のサイトのセキュリティヘッダーを見直してみてください。

---

以上で、ChatGPTを活用したセキュリティヘッダーの確認と改良方法を解説しました。この方法を活用して、皆さんもウェブサイトのセキュリティを簡単に向上させてみてください。
59日目 AWSを使った字幕付けをしてみた社畜L

## 🔎はじめに
さて今回は、新人研修も兼ねた社内開発でAWSのサービスを使って、
動画ファイルに半自動で字幕を付けられるようにしたのでそれについて話していくよ。

## 🔍今回のアーキテクチャ
![スクリーンショット 2024-06-04 155518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766505/9fd24f56-e673-4b0a-7877-5bb16cadf60e.png)




## 🔎動作概要
1⃣⇒2⃣⇒3⃣
指定フォルダに動画がアップロードをトリガとして2⃣の[[lambda](https://aws.amazon.com/jp/lambda/)]を実行

3⃣⇒4⃣
[[Amazon Transcribe](https://aws.amazon.com/jp/transcribe/)]を利用してsrtファイルを作成、
指定フォルダにアップロード

4⃣⇒5⃣⇒6⃣
srtファイルのアップロードをトリガとして5⃣の[lambda]実行

6⃣⇒7⃣
[[AWS Elemental MediaConvert](https://aws.amazon.com/jp/mediaconvert/)]を利用して字幕付きの動画ファイルを作成、
指定フォルダにアップロード

## 🔍今後の課題
- 可読性を高めるための方法として[Amazon Ttanscribe]のフィルタ機能を利用し、
予測可能なフィラー(「えー、」「あの、」等の意味のないつなぎ言葉)
を除外したsrtファイルを作成していますが、
除外するだけなのでさらなる可読性向上の工夫が必要ですね…。
</ul>

- アーキテクチャの5⃣で実行されるlambdaがアップロード用フォルダを参照時、
リストを作成し一つのオブジェクトキーを利用するようにしているため、
現状はバケットのライフサイクルポリシーでフォルダを空にしているが、
アップロード用に1つの動画しか存在できないようにする工夫する必要が必要かな。

## 👓真実はいつも１つ！（結論）
まだまだ課題はあるけど、ある程度実用可能なものが作成できたので記事にしてみたよ。
今後も随時アップデート予定なので、なにかいい案があればぜひ欲しいかな。
AWS IAM Policy のステートメントに条件キーを利用する場合は対応するアクションとリソースタイプのみを定義する

IAM Policy の JSON 定義で少しハマったのでメモ。

# 要約
- 各アクションとリソースタイプの組み合わせでどの条件キーが対応しているかは全てドキュメントに記載されている
  - https://docs.aws.amazon.com/service-authorization/latest/reference/reference.html
- ステートメントを分割して各アクションとリソースタイプに対応する条件キーを定義しよう

# 各アクションとリソースタイプの組み合わせでどの条件キーを利用できるかは決まっている
IAM Policy のステートメントには `Condition` 要素を含めることができ、これにより policy を実行するタイミングの条件を指定することができます。その指定する条件として条件キーを利用できます。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_condition.html

この条件キーですが、各アクションとリソースタイプの組み合わせでどの条件キーを利用できるかは決まっています。こちらの一覧は公式ドキュメントにまとまっているので `Condition` 要素を利用する場合は一読することをおすすめします。

https://docs.aws.amazon.com/service-authorization/latest/reference/reference.html

# 条件キーを利用する場合は対応するアクションとリソースタイプのみを定義したステートメントを用意する
`Condition`要素に条件キーを利用する場合は対応するアクションとリソースタイプのみを定義したステートメントを用意しましょう。対応していない条件キーが含まれていると Policy が正常に評価されません。

## 具体例
AWS IAM Identity Center の `sso:CreateAccountAssignment`アクションを例に説明します。

https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsiamidentitycentersuccessortoawssinglesign-on.html

このアクションはリソースタイプとして `Account`, `Instance`, `PermissionSet`の3つを必ず指定する必要があります。そして `Instance`と `PermissionSet`のみ条件キーとして `aws:ResourceTag/${TagKey}`が対応しています。

https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsiamidentitycentersuccessortoawssinglesign-on.html#awsiamidentitycentersuccessortoawssinglesign-on-resources-for-iam-policies

上記を前提に `Project=A`というタグが付いた `PermissionSet`に対してのみ `sso:CreateAccountAssignment`アクションを実行できる Policy を定義しようとすると以下になります。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example1",
            "Effect": "Allow",
            "Action": "sso:CreateAccountAssignment",
            "Resource": [
                "arn:aws:sso:::permissionSet/*/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Project": "A"
                }
            }
        },
        {
            "Sid": "Example2",
            "Effect": "Allow",
            "Action": "sso:CreateAccountAssignment",
            "Resource": [
                "arn:aws:sso:::instance/*",
                "arn:aws:sso:::account/*"
            ]
        }
    ]
}
```

ポイントとしては **`PermissionSet`リソースタイプのみに `Condition` 要素を定義したステートメントと、 `Account` と `Instance`リソースタイプに `Condition` 要素を定義していないステートメントの2つを定義**している所です。同じアクションを定義したステートメントが複数あるのは個人的に若干違和感を感じたのですが、こういうものだと割り切って Policy を構築していきましょう。
PHPのエラーPHP Notice: Undefined index: REQUEST_METHODについて

PHPで以下の構文エラーが出た場合の解決方法を記載します

PHP Notice: Undefined index: REQUEST_METHOD in /var/www/html/create.php on line 35

    if(!empty($_SERVER['REQUEST_METHOD'] === 'POST')){
    $company = [
    'title' => $_POST['title'],
    ];

※インデックスの異常であるが、
ローカル環境(アパッチ)でデバック上ではデーターのやり取りは正常。

# 解決方法
このエラーは、$_SERVER['REQUEST_METHOD']が存在しないために発生しています。これは通常、スクリプトがWebサーバー環境外で実行されるか、正しいHTTPリクエストがされていない場合に起こります。

このコードにはいくつかの問題があります。

比較の括弧位置:
1. $_SERVER['REQUEST_METHOD'] === 'POST' の結果が true か false となりますが、それを empty で判定しているため、常にtrueとなります。
2. $_SERVER['REQUEST_METHOD']の存在確認
3. $_SERVER['REQUEST_METHOD'] が設定されていない場合に備えて存在を確認する必要があります。

## 修正例

まず、比較の括弧位置を修正し、さらに$_SERVER['REQUEST_METHOD']の存在を確認する方法を以下に示します。

    if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $company = [
        'title' => $_POST['title'],
    ];
}


このように修正することで、$_SERVER['REQUEST_METHOD']が設定されているか確認し、さらにその値がPOSTであるかどうかを適切にチェックできます。

## ポイント

1. Webサーバーで実行されているか確認
スクリプトが正しいWebサーバー環境（例：Apache）で実行されていることを確認してください。

2. 正しいHTTPリクエスト
正しいHTTPメソッド（POST）が使われているかを確認します。例えば、フォームが正しく設定されているか、またはCurlなどを使って正しくリクエストを送信しているか確認します。

この修正を行うことで、エラーが解消され、意図した動作が得られるはずです。

## エンジニアの成長には環境が大切って話
やっぱエンジニアが成長するには環境が大切ってのをつくづく感じる。
優秀なエンジニアの近くで開発してると学びも多いし、その人の考え方自体を取得できる。

今はエンジニア転職アプリ作っているからよかったらどうぞ。
エンジニア向けスカウトアプリ「LUIDA」
https://luida-japan.com/lp/2410?utm_source=qiita&utm_medium=referral&utm_campaign=article1
![スクリーンショット 2024-10-11 184523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807837/460892b0-fcc4-5704-d780-20580f07a45d.png)
MacBook M3で発生する`Failed to allocate manager object, freezing.`の解決方法

# `Failed to allocate manager object, freezing.`のエラー発生

MacBook M3でDockerコンテナを実行する際に、以下のようなエラーメッセージが表示されて、コンテナが起動できない事象が発生しました。

```
Failed to allocate manager object, freezing.
```

どうやら、このエラーは`systemd`が必要なリソースにアクセスできないために発生しているようでした。
※特に、`cgroups`に関連する問題が原因。

本記事では、このエラーの原因と解決方法について説明していきます。

# エラーの原因

`Failed to allocate manager object, freezing.` のエラーは、以下の理由で発生します。

1. **`cgroups`へのアクセス不足**:
    - `systemd`は`cgroups`を使用してリソース管理を行っています。なので、`cgroups`へのアクセスが不足していると、`systemd`は正常に初期化することができません。
2. **必要なシステム権限の不足**:
    - `systemd`はシステム管理権限が必要です。なので、`SYS_ADMIN`権限が不足していると、`systemd`は正常に動作することができません。

# 解決方法

このエラーを解決するために、`docker-compose.yml`ファイルを以下のように変更します。

## 1. `docker-compose.yml`の修正

`docker-compose.yml`ファイルに以下の変更を加えます。

```yaml
version: ********

services:
  reditor:
    container_name: ********
    build: ********
    environment:
      ~略~
      container: docker    # 追加
    volumes:
      ~略~
      - /sys/fs/cgroup:/sys/fs/cgroup:ro    # 追加
    privileged: true
    platform: linux/amd64
    cap_add:
      - SYS_ADMIN    # 追加
    command: ~略~
    restart: always
    ports: ~略~
    stdin_open: true
    tty: true
```

### 変更点の説明

#### 1. `container: docker`の追加
`environment`セクションに`container: docker`を追加します。これにより、コンテナがDocker環境で実行されていることを明示的に設定して、コンテナ内での環境設定を行うようにします。

#### 2. `volumes`に`/sys/fs/cgroup:/sys/fs/cgroup:ro`の追加
この設定は、ホストシステムの`cgroup`ファイルシステムをコンテナ内にマウントします。これにより、コンテナが`cgroups`を正しく認識できるようになり、`systemd`が`cgroups`にアクセスできるようになります。

#### 3. `cap_add`に`SYS_ADMIN`の追加
`SYS_ADMIN`権限を追加することで、コンテナがシステム管理操作を実行できるようになります。`systemd`やその他のシステムサービスが正常に動作するためには、この権限が必要です。

## 2. Docker Engineの設定変更

Docker Desktopの設定で`exec-opts`を以下の手順で追加します。

1. **Docker Desktopを開く**:
    - MacのアプリケーションフォルダからDocker Desktopを開く。

2. **設定を開く**:
    - 画面右上の歯車アイコンをクリックして設定を開く。

3. **Docker Engine設定の編集**:
    - 左側のメニューから「Docker Engine」を選択する。
    - 現在の設定を以下のように編集する。

#### Docker Engineの設定例：

```json
{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "exec-opts": ["native.cgroupdriver=cgroupfs"]    # 追加
}
```


4. **設定を保存して再起動**:
    - 設定を保存して、Docker Desktopを再起動する。

## まとめ

これらの手順を実行することで、MacBook M3上で`docker-compose up`が正常に動作するはずです。

MacBook M3で`docker-compose up`を実行する際に発生する`Failed to allocate manager object, freezing.` エラーは、`cgroups`と必要なシステム権限の不足が原因です。`docker-compose.yml`ファイルの設定を適切に変更し、Docker Engineの設定を更新することで、この問題を解決できます。

インターネット上の記事を探しても、chatGPTに尋ねても、この問題を
docker-composeコマンドを使って解決する情報が見当たらなかったので、
記事として残します。
Visual Basic 6.0アプリケーションはいつまで使えるのか？

## Visual Basic 6.0ベースのアプリケーションはまだまだ現役
（2024年6月4日現在）最近、VBScriptの廃止スケジュールが公開になったことで、直接的には関係のない、Visual Basic 6.0(以下、VB6)ベースのアプリケーションのEnd of Life(Support)も気にされるケースがあるようです。
## OSにVB6ランタイムが含まれている限り、VB6アプリケーションのサポートは続く

シンプルに表現してしまえば、[Support Statement for Visual Basic 6.0 on Windows](https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/visual-basic-6-support-policy) を読みましょう、です。
現在の最新Windowsである、Windows 11、および、Windows Server 2022には、VB6ランタイムが含まれた状態でリリースされおり、VB6アプリケーションの実行環境として、Supportedです。
Windows 11のサポートライフサイクルは、「モダン」に移行していて明確な日付は指定されていませんが、Windows Server 2022には、2031年10月14日まで延長サポートが提供されます。

つまり、VB6アプリケーションは、最短でも、2031年10月14日まではなんらかの手段でサポートできるということです。

## "It Just Works" compatibility 
とはいえ、このサポート体制、100%動作はうたっていません。あくまで、"It Just Works" compatibility です。とはいえ、しっかり、サポート体制が整っているというのはものすごいです。
なんてったって、Visual Basic 6.0は、1998年リリース。少なくとも30年以上サポートされる言語ランタイムになるということです。

## VB6アプリが使えるうちに、次のシステムなんとかしましょう
少なくともあと、6年塩漬けできるから、VB6アプリケーションを使い続けてよいわけではありません。「動く」のと「使い物になる」はことなります。たとえば、VB6アプリケーションでは、フォントサイズ固定なアプリケーションもあります。当時は、1024x768や1366x768な解像度Windowsをりようしており、そのままのフォントサイズだと、高解像度になったWindowsでは、フォントサイズが小さすぎたりするケースもあります。
また、VB6アプリケーションは、当時のママ利用できるだけであり、OSやハードウェア進化を恩恵をまったく受けられません。
開発後20年経ってしまい、ソースコードも存在しないVB6アプリケーションを使い続けているケース、つまり、メンテナンスできないケースもあるでしょう。
まだ、しばらく、VB6アプリケーションが利用できるからという状況にあまえず、早めの移行計画をオススメします。
ALBの設定一覧を出力するスクリプト

# はじめに
ALBの設定一覧を取得して保存したいケースがありました。

基本情報、属性情報、リスナールール設定の情報が必要ですが
取得できるコマンドが異なります。

取得漏れなどを防ぐためにALBの設定一覧を取得するスクリプトを用意してみました。



# スクリプト

```shell
#!/bin/bash

# 環境変数にALBのARNを設定
ALB_ARN="your-alb-arn"

# ALBの基本情報を保存
aws elbv2 describe-load-balancers --load-balancer-arns $ALB_ARN > alb-info.json

# ALBの属性を保存
aws elbv2 describe-load-balancer-attributes --load-balancer-arn $ALB_ARN > alb-attributes.json

# リスナーの情報を保存
aws elbv2 describe-listeners --load-balancer-arn $ALB_ARN > listeners.json

# listeners.jsonからリスナーのARNを抽出し、各リスナーに対してリスナールールを保存
listeners=$(jq -r '.Listeners[].ListenerArn' listeners.json)

for listener in $listeners; do
    # ファイル名にスラッシュが含まれないようにリスナーARNを修正
    safe_listener=$(echo $listener | tr '/' '_')
    aws elbv2 describe-rules --listener-arn $listener > "rules-${safe_listener}.json"
done

echo "ALB設定とリスナールールが保存されました。"

```

# おわりに

たまに行うとコマンドを忘れてしまうので忘備録として残してみました。
どなたかの助けになれば幸いです。
初心者でもわかるGPTsの使い方

# はじめに

エンジニア歴1年目の僕がGPTsを使ってみたので、初心者ならではの視点から初心者でもわかりやすい言葉を用いて、GPTsとは何か、具体的な使い方まで記事にしたのでぜひ最後まで見ていただけると嬉しいです。それではいきましょう！

### 対象読者

- プログラミング初心者の方
- AIの知識を身に付けたい方
- GPTsの具体的に使い方を知りたい方

# もくじ
①GPTsって何？

②GPTsの使い方
 1. GPTs作成サイトから始める
 1. 作りたいChatGPTを決める
 1. 動作確認
 1. 完成品

③まとめと今後の展望


# ①GPTsって何？

簡単いうと、コーディング不要で誰でも簡単に独自のGPTを作成することができるAIツールのことです。

GPTsは、OpenAIによって2023年11月6日に発表されており、誰でも簡単に日常生活や特定の作業、仕事、家庭でより役立つようにカスタマイズしたバージョンのChatGPTを作成し、その作成を他の人と共有できるというAIツールのことです。

OpenAIの発表記事:https://openai.com/blog/introducing-gpts

# ②GPTsの使い方
※GPT4に課金をしていないと使用できませんのでご注意ください。

## 1. GPTs作成サイトから始める

URL:[chat.openai.com/create](http://chat.openai.com/create).

## 2. 作りたいChatGPTを決める

今回は「初学者向けのエンジニアに向けてわかりやすい言葉で回答してくれるメンター」を想定して作成してみました。
#### 1.Createメニューで「どんなChatGPTを作りたいですか？」と質問される

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/276cfd71-e42e-54f9-b61c-6053920c1e92.png)

#### 2.回答する
![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/18ad9620-7af7-c488-e60d-25e87253fc80.png)

#### 3.Get startedを押してGPTsを作成することを許可する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/5f5061b8-e798-87ef-7b64-55bf1c66f58d.png)

#### 4.いくつかの質問に答えていく
- どんな画像のメンターにするのか
- どんな経験を持っているのか
- 避けるべき言葉遣いなどはあるのか
- メンターはどのような性格であるのか
- 他に要望や追加したい内容はあるか

#### 5.すべての質問に答えたら自分のChatGPTを自動生成してくれる！

## 3. 動作確認

#### 1.Previewで実際の動きを確認

質問をしてみる
![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/aa6ffbfd-e3a7-c967-d72e-77aded602430.png)

メンターの回答
![Untitled (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/842e5d98-477b-695a-b823-3ee80b1fe811.png)
ChatGPTよりもわかりやすい言葉に変換しながらしっかり答えてくれる！

#### 2.微妙な部分があれば修正可能

Configureから名前変更、詳細設定などの変更できる。

![スクリーンショット 2023-11-30 12.44.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/466835fa-1b6d-c993-c3ba-489c5f2abe53.png)


#### 3.満足のいくものができたらセーブをする

画面右上のSaveからConfirmを押して作成完了する。

| Only me： | 自分しか使えない |
| --- | --- |
| Only people with a link： | リンクを知っている人だけ利用可能 |
| Public： | 公開 |

![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/2e1d2655-8364-38fa-7759-d1f8bedf6331.png)

## 4. 完成品

ChatGPTを開いて左上のメニューを押すと、、、

![Untitled (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/311e3b8f-9268-b70a-003f-3120fe3423b2.png)

作成したメンター発見！！

![Untitled (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116912/60c2d5b4-ae0b-3b65-5ddb-34c6027300c0.png)

これでメンターにいつでもすぐに相談できるようになった！

# ③まとめと今後の展望

### GPTsの将来性

GPTsは、人工知能と自然言語処理の領域で大きな進歩を示しています。この技術の発展により、より精度の高い言語理解と生成が可能になり、それによって多様な応用が期待されます。教育、医療、エンターテイメントなどの分野でも、GPTsの応用により新たなサービスや製品が生まれる可能性があります。

### 最後に

今まではChatGPTにどんな人が回答してくれるのかプロンプトを記述していましたが、理想の人物となるメンターをGPTsであらかじめ作成しておけばどのような人物に答えてもらいたいのかというプロンプトをわざわざ書く必要がないので作業効率化になると感じました。

このドキュメントを読み終えた方は、GPTsの基本的な知識を身につけましたかと思います。実際にGPTsを使って小さなプロジェクトを始めることで、理論的な知識を実践的なスキルに変えることができるので、あなたも実際に使ってみていただければ僕も嬉しいです！
Github Acitons 「より大きなRunner」でCIの実行速度を速くする 

# はじめに

CI実行は速ければ速いほど良い、特にテスト。

自分の場合、GithubActionsのデフォルトのRunnerだと、自分の端末のほうがずっとスペックが良くて、localで実行する方が速いという。



# 公式ページ

>より大きなランナー は、GitHub Team または GitHub Enterprise Cloud プランを使っている組織とエンタープライズのみが使用できます。

https://docs.github.com/ja/actions/using-github-hosted-runners/about-larger-runners/managing-larger-runners#allowing-repositories-to-access-larger-runners

# Github Teams 

今回の手順では Github Teamsを利用開始して、同時にOrganization を作る

https://github.co.jp/pricing.html

# Runer Group の作成

## グループを作成する

 `https://github.com/organizations/<組織>/settings/actions/runners` から設定できる

![CleanShot 2024-06-04 at 13 28 54@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/feb9b3b8-314d-4583-8de0-0938f7c34159)

## グループの詳細設定

利用レポジトリの制限などができる

![CleanShot 2024-06-04 at 13 29 18@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/6ff4cc64-8641-47e4-b70c-0b9ffd839b3b)

# 最強のRunnerの設定 ( カスタム設定 )

## Create new runner

 `https://github.com/organizations/<組織>/settings/actions/runners` から設定できる

![CleanShot 2024-06-04 at 13 31 52@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/0d9ae7df-3f9b-47fe-857a-a6aafee8e7db)

## スペック設定

Ubuntuの最強スペックにすると以下の通り
(BETAの `Linux ARM64` は除く)

先ほど作ったRunner Group に Runner を設定する

![CleanShot 2024-06-04 at 13 32 25@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/6be1d080-b3f6-448b-a6e3-f393e7364931)


# Workflowの書き方

Githubの画面に Runner のラベルが書かれているので、これを指定すれば良い

![CleanShot 2024-06-04 at 13 33 57@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/17f2618e-91cf-4d9f-8cca-3b5b02945937)

これを runs-on に指定する

```yml
jobs:
  setup:
    name: 'XXX'
    runs-on: ubuntu-latest-l
```


# 注意 : ubuntu-latest-m では速くならない

Github のおすすめ初期設定では `ubuntu-latest-m` が設定されるのだが、
2024/06/04 現在 スペックは `ubuntu-latest` とほとんど変わらないようなので、ほとんど速くならないはず

![CleanShot 2024-06-04 at 12 34 49@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/05ed6ccd-e2cf-4164-a3db-3d9400940162)

## ubuntu-latest

<img width="787" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/77b0188b-4baf-47fe-a6d8-6495a1da16d1">

https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners

## ubuntu-latest-m

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/956c16e2-2bd0-45c4-aac6-3584de4eea45)



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
IBM i 個別PTFをシュッと充てる

# 前置き:raised_hand:
- 個別FIXを充てることがあり、サイズも小さいので直接システムダウンロードを行いました
- 手順をすぐ忘れちゃう人なので、備忘録として記事に残します

# 作業環境前提
- PC
    - Windows11
    - Java8導入済

# FixcentralからPTFをダウンロードする
- 以下の通り最後のダウンロード・オプションページで、`個々のフィックスを直接システムにダウンロード`にチェックを入れる
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/5eef69c9-f774-d3d6-7bed-b196e51678d5.png)
- .jnlpファイルをダウンロードする
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/28385486-8886-5e2d-d975-062011f7bc9b.png)
- ダブルクリックしてダウンロードを開始する
- 実行を押下する
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/cf68e387-e30c-0a68-0e11-ee6e12b1e517.png)

- ダウンロード先のIBM i 区画情報を入力し、次へ進むを押下
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/65c7e812-7b10-169d-5142-4488f3c20a36.png)
- ファイルダウンロードが開始するので終わるまで待つ
    -　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/aa5df7bf-64ab-9f02-0b68-a3f5e9f96580.png)

# PTFダウンロード先IBM i でPTFを適用する
- PTFがちゃんとダウンロードできたか確認する
    - 以下にSAVFがあるか確認
        - QGPL/QXXXXXX（※XXXXXXは個別PTF-IDに読み替えてください)
- PTF適用コマンドは以下の通り
    - すでに個別PTFがシステムに適用されていない場合はRMVPTFコマンド不要
    ```
    RMVPTF LICPGM(ライセンスプロダクトID) SELECT(個別PTF-ID) RMV(*PERM)
    LODPTF LICPGM(ライセンスプロダクトID) DEV(*SAVF) SELECT(個別PTF-ID) SAVF(QGPL/Q個別PTF-ID)
    APYPTF LICPGM(ライセンスプロダクトID) SELECT(個別PTF-ID)
    ```

# おわりに:muscle:
- GRPPTFでなく、個別PTFを適用するときにはサイズが小さいため、直接システムダウンロードが楽ですね！
- FFRPGのデバッグ実行編はもうしばしお待ちください💦
【nginx】504 Gateway Time-out

サーバーにアップロードしたwebアプリが504を返すようになっちゃったときのメモ

## 環境

- nginx(1.26.0)

## エラーログ

```/var/log/nginx/error.log
upstream timed out (110: Connection timed out) while reading response header from upstream, "fastcgi://unix:/run/***",
```

cgiがタイムアウトしてる

## タイムアウトまでの時間を延ばしてみる
```/etc/nginx/nginx.conf
send_timeout 300;
keepalive_timeout 300;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
```

### 各パラメータの説明

#### send_timeout
- クライアントへのレスポンス送信にかかる最大時間
- デフォルト60秒

#### keepalive_timeout
- Keep-Alive接続のタイムアウトするまでの時間
- デフォルト75秒
- Keep-Aliveは、1回のTCP接続で複数のHTTPリクエストを処理する機能で、接続を再利用することでCPU負荷や時間を節約できる

#### fastcgi_connect_timeout
- FastCGIサーバーとの接続を確立するための最大時間
- デフォルト60秒

#### fastcgi_send_timeout
- FastCGIサーバーへのリクエストを送信する際の最大時間
- デフォルト60秒

#### fastcgi_read_timeout
- FastCGIサーバーからの応答を待つ最大時間
- デフォルト60秒

## 再起動
```
sudo systemctl restart nginx
```

表示できた

## 参考

https://nginx.org/en/docs/http/ngx_http_core_module.html

https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
【flutter】住所の都道府県のみ表示したい

こんにちは！
今回は文字列の一部を表示させる方法について紹介します。

## 実装例

![Screenshot_1717472605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524127/2c539a51-511d-ca3f-99f5-38eb024d46fd.png)


## コード

### リストの内容をそのまま表示
```php

//リスト
List<String> sampleList = [
  "東京都品川区",
  "埼玉県川越市",
  "神奈川県横浜市",
  "千葉県木更津市",
  "栃木県佐野市",
  "群馬県高崎市",
  "茨城県水戸市",
  "山梨県富士吉田市"
];
```
```php
//リストを使って各住所を表示
children: sampleList.map((sampleText) {
  return Center(
    child: Text(
      sampleText,
      style: const TextStyle(
        fontSize: 15,
        fontWeight: FontWeight.w600,
      ),
    ),
  );
}).toList(),

```

### リストの内容から都道府県を切り取って表示
```php
//正規表現の定義:
 RegExp regExp = RegExp(r'(東京都|北海道|(?:京都|大阪)府|.{2,3}県)');
```

```php
children: sampleList.map((sampleText) {
  // 各住所から都道府県部分を抽出
  Match? match = regExp.firstMatch(sampleText);
  String addressText =
      match != null ? match.group(0)! : '都道府県を選択してください';
  return Center(
    child: Text(
      addressText,
      style: const TextStyle(
        fontSize: 15,
        fontWeight: FontWeight.w600,
      ),
    ),
  );
}).toList(),

```

## RegExpとは？
正規表現（RegExp）は、文字列のパターンを表現するための記法です。これは、特定の文字列パターンを検索、抽出、置換、一致させるために使用されます。また、検索対象の文字列内でパターンに一致する部分文字列を見つけるための柔軟な方法を提供します。これにより、テキストデータを効率的に操作し、必要な情報を取得することができます。


## 終わりに
今回の記事は以上になります。
今回も最後まで読んでいただきありがとうございました。
では、また次の記事で〜！
アジャイル 日本発の概念と大きなムーブメント

※本稿はオピニオン誌『カレント』において2023年10月号に寄稿されたコラムです。アジャイルの歴史的経緯など、まとまって紹介することに意義があるかと思い投稿いたします。

## 政府の取り組み
　昨年の行政改革推進会議から「アジャイル型」政策手法導入が議論されている様に、政策改善を断続的に改善するという意味で「アジャイル」という言葉が使用されています。アジャイルとはソフトウェア開発で用いられる手法などを指す言葉であり、「アジャイル開発手法」であることが政府の調達の要件である国も存在します。政策形成の場でも注目されている他、製造業などでもアジャイルが提唱されるシーンも増えています。このようにアジャイルはソフトウェア業界を飛び出して一般化しつつあるのです。

## 一般化しつつあるアジャイルとその意義
　アジャイルという言葉や概念は、近年、多くの人々に知られるようになってきました。もともとはソフトウェアの開発手法として生まれたこのアプローチが、今やその領域を超えてさまざまな業界や分野で注目されています。なぜアジャイルは広がりを見せているのでしょうか。それは、迅速な変化に対応するための柔軟性が求められる現代社会において、アジャイルの持つ原則や価値が非常に適合しているからです。アジャイルは単なる手法ではなく、思考のフレームワークや哲学とも言える存在です。この考え方は、顧客のニーズや市場の変動に素早く対応するための手法として、多くの組織に採用されています。
　政府が直面する課題もまた、複雑かつ急速に変化しています。そのため、政策の策定や実施に際しても、アジャイルの原則に基づき、柔軟かつ迅速に対応する必要が出てきました。特に、デジタル技術の進展や社会的な変動を背景に、政策の見直しや改善が頻繁に求められる現代において、アジャイルのアプローチは有効であると言えるでしょう。

## スクラム　野中郁次郎の研究
　アジャイル開発で活用される手法にはさまざまなものがありますが、日本発のものも多く、アジャイル開発で採用される「スクラム」という手法の元は、『失敗の本質』の著者の一人でもある野中郁次郎氏の研究です。野中氏は、日米の軍や戦後の日本企業の動向を研究し、その中で日本独自の経営哲学や手法を発見しました。野中氏が世に示したことを簡単にまとめると次の通りとなります。
 
①組織が経験から学習するモデルを示した。
* モデル１　ダブルループ学習：既存の目的や前提そのものを疑い、それらも含めて軌道修正を行うこと
* モデル２　ＳＥＣＩモデル：組織において「形式知：言語化された知識」「暗黙知：されてない知識」がどのように醸成されるか
  
②ラグビーのスクラムを組んだように複数の専門性をもつ人材が各工程だけを受けもつのではなく製品の企画から製造販売まで一貫して取り組む体制が有効と示した。

　これを米ジェフ・サザーランドらが、自身のソフトウェア開発プロジェクトに対して応用し、それがのちに「スクラム開発」と呼ばれる方式へと発展しました。彼の考え方がアジャイル開発で多く活用される「スクラム」という手法の基盤を築いています。スクラムの原則は17ページにわたる「スクラムガイド」にまとめられ、インターネットで公開されています。

## リーン生産方式　無駄の排除と価値の最大化
　リーン生産方式は、無駄を極力排除し、顧客価値を最大化することを目的としています。「リーン」という言葉は「痩せた、筋肉質の」という意味で、米フォード社に代表された大量生産方式と比較された表現です。大量生産による在庫維持のコスト増、作ることが目的化することによる品質課題を乗り越えたのがリーン生産方式であり、１９５５年に１％程度だった世界の自動車産業の日本のシェアは１９９０年には30％に迫るほど躍進を遂げました。以降リーン生産方式は世界の自動車産業のスタンダードとなり、総務省の情報通信白書では人類の社会変革をもたらした汎用技術として「印刷」「蒸気機関」「工場」「鉄道」「インターネット」などと並んで紹介されています。　リーン生産方式の考え方は、後にソフトウェア開発の領域に取り入れられ、アジャイル開発の基盤となりました。
　リーン生産方式が認知されるようになったことで、その原則はソフトウェア開発の領域にも拡散しました。アジャイル開発は、リーンの考え方をベースにしつつ、迅速なフィードバックと柔軟な対応を重視する手法として成立しました。これにより、リスクを最小限に抑えつつ、最大の価値を生み出すことが可能となったのです。

## マネジメントの大きなムーブメント
　「スクラム」と「リーン」は、表面的には　異なる分野や背景を持ちますが、両者とも、戦略を見直し、振り返り、無駄を排除し、市場や顧客の真のニーズに応えることを最優先とし、相互に影響し合いアジャイル開発を形成しています。アジャイルは特定の手法を表す言葉ではなく、厳密な定義も意見が分かれるのですが、その背景には大きなムーブメントが現在進行で起こっていることがあります。　アジャイルは、政策改善・製造業のほか非ソフトウェア開発でもこれからのマネジメントにおける大きなムーブメントとなる可能性が高いです。組織やチームが直面する課題は、より複雑で予測不可能になってきており、それは今後より増長するでしょう。未来のビジネス環境や組織の運営において、アジャイルは中心的な役割を果たすことが予想されます。
Gitの基本操作

### 1. リポジトリの初期化

ローカルディレクトリをGitリポジトリとして初期化するには、以下のコマンドを使用します。

```sh
git init
```

### 2. リモートリポジトリのクローン作成

既存のリモートリポジトリをローカルにクローン（コピー）するには、以下のコマンドを使用します。

```sh
git clone <repository_url>
```

例：

```sh
git clone https://github.com/user/repository.git
```

### 3. ファイルのステージング

ファイルをステージングエリアに追加するには、以下のコマンドを使用します。

```sh
git add <file>
```

すべての変更をステージングするには、以下のコマンドを使用します。

```sh
git add .
```

### 4. コミット

ステージングエリアにある変更をリポジトリにコミットするには、以下のコマンドを使用します。

```sh
git commit -m "コミットメッセージ"
```

### 5. リモートリポジトリへのプッシュ

ローカルリポジトリの変更をリモートリポジトリにプッシュするには、以下のコマンドを使用します。

```sh
git push origin <branch>
```

例：

```sh
git push origin main
```

### 6. リモートリポジトリからのプル

リモートリポジトリから最新の変更を取得し、ローカルリポジトリを更新するには、以下のコマンドを使用します。

```sh
git pull origin <branch>
```

例：

```sh
git pull origin main
```

### 7. ブランチの作成

新しいブランチを作成するには、以下のコマンドを使用します。

```sh
git branch <branch_name>
```

例：

```sh
git branch feature-branch
```

### 8. ブランチの切り替え

別のブランチに切り替えるには、以下のコマンドを使用します。

```sh
git checkout <branch_name>
```

例：

```sh
git checkout feature-branch
```

### 9. ブランチの作成と切り替えを同時に行う

ブランチを作成し、同時にそのブランチに切り替えるには、以下のコマンドを使用します。

```sh
git checkout -b <branch_name>
```

例：

```sh
git checkout -b feature-branch
```

### 10. マージ

他のブランチの変更を現在のブランチにマージするには、以下のコマンドを使用します。

```sh
git merge <branch_name>
```

例：

```sh
git merge feature-branch
```

### 11. ステータスの確認

現在のリポジトリの状態を確認するには、以下のコマンドを使用します。

```sh
git status
```

### 12. ログの確認

コミット履歴を確認するには、以下のコマンドを使用します。

```sh
git log
```

### 13. 変更の取り消し

直前の変更を取り消すには、以下のコマンドを使用します。

```sh
git reset --hard
```

ステージングエリアの変更を取り消すには、以下のコマンドを使用します。

```sh
git reset HEAD <file>
```

ワーキングディレクトリの変更を取り消すには、以下のコマンドを使用します。

```sh
git checkout -- <file>
```
画像をBase64でエンコードしGPT APIで評価する手順

# はじめに
この記事では、写真に基づいて特定の評価を行う方法について紹介します。これは、写真の内容に基づいて評価を行い、0から5の評価を返すシステムです。ここでは、OpenAIのAPIを利用して評価を自動化する方法を説明します。

# 課題と対応
現在、OpenAI APIに画像ファイルそのものを送信することができません。そこで、画像のエンコード（変換）した上で、評価を行うAPIに送信します。

# 参考にした記事
https://qiita.com/danishi/items/7f1569151a766b678b02

https://qiita.com/rio_0402/items/65cb7261f85099ec942a

# 前提
OpenAIのAPIキーをすでに取得し、設定済みの状態とします
APIキーの取得の仕方がわからない方は、こちらをご覧ください：
https://platform.openai.com/api-keys

# 1.画像のエンコード(変換）
まず、評価対象の画像をBase64形式にエンコードします。以下のPythonコードは、指定した画像ファイルをBase64形式に変換する方法を示しています。

## Base64とは
Base64とは、64進数を意味する言葉で、すべてのデータをアルファベット（az, AZ）と数字（0~9）、一部の記号（+, /）の64文字で表すエンコード方式です。

## バイナリ型とテキスト型
Base64エンコードの情報自体は沢山ありますが、base64.b64encodeするだけだとバイナリ型（0と1のビットの組み合わせ）になります。このままでは画像として認識されません。decode('utf-8')することで、バイナリデータを文字列に変換することができます。

``` python
import base64

def encode_image_to_base64(file_path):
    with open(file_path, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
    return f"data:image/jpeg;base64,{encoded_string}"

# 画像のパスを指定
file_path = "sample-image.jpeg"
encoded_image = encode_image_to_base64(file_path)

```

# 2 OpenAI APIの設定と結果の取得
次に、OpenAIのAPIを利用して画像の評価を行います。エンコードされた画像とプロンプトを含むメッセージを作成し、OpenAIのChatCompletion APIに送信します。

```evaluate_image.py
import openai
import base64

def encode_image_to_base64(file_path):
    with open(file_path, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
    return f"data:image/jpeg;base64,{encoded_string}"

# 画像のパスを指定
file_path = "sample-image.jpeg"
encoded_image = encode_image_to_base64(file_path)


prompt = "This is an app to rate the quality of an image based on \
          specific criteria on a five-point scale. Please provide \
          a strict evaluation based on visible factors such as \
          clarity, composition, and overall appeal."

response = openai.ChatCompletion.create(
    model="gpt-4o",
    messages=[
        {"role": "system",
         "content": "You are an AI trained to evaluate the quality \
          of images based on specific criteria. Evaluate the \
          quality of an image very strictly on a scale of 0 to 5 \ 
          from the provided image. If it is not relevant, answer \
          with 0. No explanation is needed. Answer with a single \
          digit from 0 to 5. Example: 0, 1, 2, 3, 4, 5."
         },
        {"role": "user",
         "content": [
             {"type": "text",
              "text": prompt},
             {"type": "image_url",
              "image_url": {
                  "url": encoded_image,
                  "detail": "low"  # 解像度を指定（low、high、autoのいずれか）
              }
              }
         ]
         }
    ],
    temperature=0, #回答を固定
    max_tokens=100, 
    n=1 #一つの応答を生成
)

# 応答の表示
print(response["choices"][0]["message"]["content"]) #0〜5の数字が表示


```

# まとめ
この記事では、画像を基に評価を行うアプリケーションの実装方法を紹介しました。画像の評価基準は用途に応じてカスタマイズ可能です。ぜひ、皆さんのプロジェクトやアプリケーションにもこの方法を取り入れてみてください。
AWS CodeDeploy EC2にデプロイするときにhooksで実行するshellの出力先

## 概要

CodeDeployでEC2にデプロイするときのhooksで呼ばれているshellの出力先をメモ的にまとめる。

## 前提

当該のEC2へは当該のCodeDeployを使ってデプロイが行えており、当該EC2にssh接続ができること。

## 内容

デプロイ先EC2の`/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log`の中に出力されている。

例えば下記のようなshellを記載してデプロイ時に呼び出していたとする。

```bash
#!/bin/bash
echo "This is an output from the AfterInstall hook."
```

EC2の`/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log`に下記のように出力される。

```
[stdout]This is an output from the AfterInstall hook.
```

※[stdout]は標準出力という意味らしい。