OmniAICreator/Qiita-1.07M huggingface dataset:
クリーンウィークの活動と感想について

## はじめに
この記事は、[ミロゴス Advent Calendar 2023](https://qiita.com/advent-calendar/2023/milogos) 16日目の投稿です。
当社では、月次でシステムリソースの断捨離を行うクリーンウィークという施策を実施しています。
本記事では、クリーンウィークの活動内容について話していければと思います。

## クリーンウィーク施策とは
クリーンウィークは、自社運用しているサービスのAWSリソースやドキュメントなどを幅広い範囲で見直し、不要なものがないかを定期的に整理・削除する活動です。

この活動を通してAWSリソースが整理され、コストが削減されることを期待しています。
このコストには、単純なAWS利用料という側面だけでなく、メンバーの認知不可の軽減や、各種作業における待ち時間の短縮などの観点も含まれています。
また、組織メンバーがプロダクトやプロジェクトについて理解を深める機会ともなります。

## 施策導入の経緯
当社では、歴史的経緯で過去のプロジェクトを見直す機会が少なかったため、既存プロジェクトの古いドキュメントに加え、それに付け加えられる形で新しいプロジェクトの資材等が積み重なり、管理が複雑化していました。
これにより余分な作業負荷や利用料のコストが発生しており、一定の時間を機械的に設定して問題に対処するためにクリーンウィークが導入されました。

## 最近の実施内容
最近のクリーンウィークでは、主にリソースの整理・削除に焦点を当てています。
月の最終週には、MTG（ミーティング）を通じて全員で当社のリソースを整理・削除する取り組みを実施しています。

### リソースの整理

#### 1. 現状のコストの確認
まず初めに、クリーンウィークの開始前にコストと使用量の内訳を確認して、現在のコストを明確にします。
そして、現在のコスト構造を把握し、どの領域でコストを削減できるかを特定します。
Cost Explorerと請求書を活用することで、コストがどのリソースやサービスにかかっているのかを視覚的に把握しやすくなります。

#### 2. 一覧表の作成
当社では、過去手動で作れたリソースとCDK等を用いて生成されたCloud Formation管理のリソースが混在しています。後者に関しても実験的に作られたもの、各種環境向けに作られ運用状態にあるものがあります。
クリーンウィークでは、これらをまとめ、スプレッドシートなどに詳細に記載します。
これにより、各プロジェクトやサービスで利用されている全体像を把握し、無駄なリソースを見つけやすくします。

##### 記載する内容について
サービスごとに異なりますが、削除対象のリソースの名称、コンソールへのリンクなどを主にまとめます。
以下は、具体的な項目です。

- リソースの名称: 削除対象となるリソースの具体的な名称を明記します。
- リソースのタイプ: リソースが何に分類されるかを示します（例: EC2 インスタンス、S3 バケットなど）。
- コンソールへのリンク: 削除対象のリソースに素早くアクセスできるよう、コンソールへのリンクを提供します。
- 作成日時: リソースが作成された日時を記録し、特定の期間内に作成されたものを把握します。

これらの項目を含む一覧表を作成することで、クリーンウィークの進行が円滑になり、不要なリソースの特定と削除を迅速かつ効果的に実行することができます。

#### 3. 不要なリソースの特定と削除
作成した一覧を事前に共有し、MTGの場でメンバーが不要なリソースを特定し、削除の可否を検討します。
経緯が不明なものがあれば、過去の資料を検索したり、関係者にヒアリングしたり、リソースの使用状況をモニタリングしたりといった調査を行い、利用状況を明らかにします。
これにより、余剰なリソースを効果的に除去すると共に、整備が不十分で理解が不足していたリソースに対しての知見を増やします。

#### 4. ベストプラクティスの共有
クリーンウィークでは、リソースの整理だけでなく、ベストプラクティスの共有も行います。
プロジェクトの内容からリソースの使用用途、効果的な管理方法を共有し、多くのメンバーの理解を深めます。

#### 5. クリーンウィークの成果の共有
削除終了後、実施したリソースの削除に関する成果やそれに伴うコスト削減額などについて、情報を共有します。
クリーンウィークの成果を積極的に共有することは、組織全体の進化と効果的なリソース管理の促進に寄与します。

## 活動を通じての所感
不要なリソースが一通り削除されたことにより、環境が整理され、良い変化があったと感じています。
この活動を通じて、組織全体がこのプロセスに参加することで、チーム全体がより一体となり、リソース管理に対する共通の理解が深まったと感じています。

## さいごに
この記事では、クリーンウィークに焦点を当て、効果的なリソース管理とコスト削減の重要性を紹介しました。
クリーンウィークを通じて、組織全体が無駄なリソースを発見し、これに対処することでコストの削減に成功しました。
今後も継続的にクリーンウィークを行い、組織全体がリソースを効果的に管理できるよう努めていきます。
読者の皆様も是非、組織で検討してみてください。
Mojo🔥をインストールして触ってみる

# はじめに
機械学習に向いている新しい言語がローカル環境で使えるようになったので、少し触ってみた

# 前提条件
実行端末：Mac(intel)

# インストール手順
## 1. 事前準備
公式サイトからアカウントを登録して「Download Now」を押下

https://docs.modular.com/mojo/manual/get-started/

登録すると自動でインストール手順が載っている画面に遷移するのでその手順に従ってインストールを進めていく(一部異なる手順で進めるのでこの後説明)

![スクリーンショット 2023-12-13 16.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580771/15ec0a04-9116-a615-2d89-8c452c077d23.png)

## 2. Mojoの実行環境作成
現状のMojoはintel版のMacでは使えないのでDockerを使って実行環境を作成していく
※手順にはVSCodeの拡張機能である「Dev Containers extension」を使うとなっているが最終的に環境構築を自動にしたかったのでDockerコンテナを自作

1. 環境構築のための設定ファイル(docker-compose.ymlとDockerfile)を作成する
    ```docker-compose.yml
    version: '3'
    services:
      mojo:
        build:
          context: .
          dockerfile: Dockerfile
        container_name: 'mojo-container'
        volumes:
          - '..:/app'
        tty: true
    ```
    ```Dockerfile.
    FROM mcr.microsoft.com/devcontainers/base:jammy

    RUN apt update
    RUN apt install curl -y

    WORKDIR /app
    ```
    
    最低限Mojoを動かすことができる環境を作成
    
1. Dockerコンテナを作成
    ```docker-compose up -d```コマンドを実行し、Dockerコンテナを作成する

## 3. Mojoのインストール
作成したDockerコンテナにはまだ何もインストールされていないので、Mojoをインストールする

1. 先ほど作成したコンテナにログインする
    ```docker compose exec mojo bash```
1. 最初に表示されたインストール手順の04に記載されているコマンドを実行
1. しばらく待って次のような画面が表示されればModukar CLIのインストールが完了
    ![スクリーンショット 2023-12-13 17.07.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580771/8b8707c3-a7fe-dc05-cd86-48f4070587e6.png)

1. 手順に従って05のコマンドを実行する前に以下のコマンドを実行しpythonをインストールする
    ```apt install python3.10-venv -y```
1. 05のコマンドを実行する
    ```modular install mojo```
1. 以下の画面が表示されればMojo SDKのインストールが完了
    ![スクリーンショット 2023-12-13 17.13.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580771/67e3bdb7-7390-b476-a5c5-b4121c527f2b.png)

### ※ pythonのインストールを実行せずにmojoをインストールした場合
```apt install python3.10-venv -y```を実行せずに```modular install mojo```を実行した場合、pythonをインストール後mojoをインストールしようとしても上手くいかない
そのため、```modular clean```を実行してから```modular install mojo```を実行する必要がある

# Mojoを触ってみる
## 1. REPLでコードを実行
コンソールにmojoと入力すると以下の画面が表示される
![スクリーンショット 2023-12-13 17.24.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580771/dcd256c5-2f78-63b9-3b56-58f0e8049011.png)
ここに好きなようにコードを入力ができる

書いたコードは
1. カーソルが末尾にない状態でEnterを1回押す
1. カーソルが末尾にある状態でEnterを2回押す

ことで評価して実行ができる

※カーソルが末尾にある状態でEnterを1回押すと改行して、コードを続けて書くことができる（テストで簡単に実行したいけど数行書きたい時に便利）

## 2. Mojoファイルを作成し実行する
チュートリアルに書いてある簡単なコードでhello.mojoというファイルを作成
```hello.mojo
fn main():
    print("Hello, world!")
```

以下コマンドを実行する
```mojo hello.mojo```

以下のように出力される
```
Hello, world!
```

## 3. ビルドして実行する
1. 2で作成したhello.mojoを使って以下のコマンドを実行する
```mojo build hello.mojo```

1. 実行後、helloというファイルが作成されるので、作成された実行ファイルを実行する
```./hello```

1. 2で出力された結果と同じメッセージが出力される(処理が簡単なので実感しにくいが2で実行した時より早く実行ができている)


# まとめ
Mojoがローカル環境で利用できるようになったので簡単に触ってみた。
Pythonと似たような記述でかけるので学習コストが抑えられて実行が早くなるので、今後も色々触っていきたいと思った。
Pythonの35000倍早いというのが売りらしいので、今後はPythonや他の言語との速度比較などをやってみたいと思う。
FourKeysと計測

この記事はZOZOアドベントカレンダー Series４　１４日目の記事です。

[「LeanとDevOpsの科学」](https://www.amazon.co.jp/dp/4295004901)で紹介されているFourKeysを計測しているチームは多いと思います。

私のチームでもFindyTeamsを活用しながら計測を続けています。

FourKeysで計測する内容は以下のとおりですね。

- デプロイの頻度
- 変更のリードタイム
- 変更障害率
- サービス復元時間

これらはGithubのPullRequest（PR）などを活用し計測されますが、デプロイの頻度・変更のリードタイムについては、すべてのPRを計測するかどうかについては疑問に感じていました。

たとえば、

- リファクタリングのみのPR
- ライブラリのバージョンアップのみのPR
- テスト追加のみのPR
- 負荷テストに必要な変更のみのPR
- バグ修正のためのPR

これらは既存の機能に変更を及ぼすものではなく、顧客になにかインパクトを与えるためのものではないですよね。

そして、Scrumなどイテレーションを積み上げていくようなアジャイルのプラクティスを採用している場合、これらはスプリントバックログの完了の定義に含まれているべきものであって、単独でPRを立てているのは「未完了」の消化というものになります。

それらがデプロイの頻度・変更のリードタイムに含んでしまうと、チームのパフォーマンスを計測するだけであれば有効かもしれませんが、「未完了」の消化ばかりデプロイしていてもパフォーマンスが高くても何も顧客に提供していない、アウトカムがないということにもなりかねません。

よって、このような「未完了」の消化用のPRとアウトカムのためのPRをタグで分けてアウトカムのためのデプロイの頻度・変更のリードタイムのみを計測する。

そうすると、「未完了」の消化はできるだけスプリントで収めようとする動きも取れるでしょうし、アウトカムに値するPRが増えていけばビジネス上、競合に立ち向かえるだけのパフォーマンスを発揮することもできるでしょう。

ひとつだけ補足しておくと、チームによってはどうしても「未完了」の消化用のPRというのは必要になることもあると思います。ライブラリのバージョンアップは[Renovate](https://docs.renovatebot.com/)みたいな仕組みでやっていたり、大型のバージョンアップなどはやはりスプリントとは切り離してやっていかないといけないでしょう。なので全てのPRがアウトカムのためのPRというわけにはいかないのはその通りかと思います。そしてこれらのPRは「変更障害率」「サービス復元時間」の削減に寄与することも考慮しておくべき点でしょう。

これらの点に注意しながらアウトカムのための計測をしていけたらと考えています。
VPC CNI IPAMDとSecurity Groups For Podを徹底分析

この記事は、CyberAgent Group SRE Advent Calendar 2023の16日目の記事です。

## はじめに
技術本部 サービスリライアビリティグループ（SRG）の石川 雲（@kumo_rn5s）です。

SRG（Service Reliability Group）は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
SRGでは以前から技術記事を執筆していますが、Google検索での最適化を施していないため、あまり知られていないようです。より多くの方に当社の記事を読んでいただくために、本記事の主要部分をSRGのサイトで是非ご覧ください。

この記事では、VPCCNIアドオンの動作と原理を解説し、Security Groups for Pod(SGP)を使用した際の注意点について説明します。また、2020年から発生し始めた「add cmd: failed to assign an IP address to container」というエラーに関して、ソースコードレベルの説明と分析を行う内容となっています。


## AWS VPCアドオン

AWS VPC CNIは、EKSのネットワーキング構成において中心的な役割を果たしており、AWS VPCとネイティブな連携することで、EKS上でのネットワーク管理を効率化しています。

AWS VPC CNIは以下のコンポーネントによって構成されています。

- CNI Plugin
    
    CNIの仕様に沿って、gRPCでIPAMDと通信してIPを取得し、ネットワーク設定を行う
    
- IPAMD Plugin
    
    各NodeにおいてAWS ENIを管理し、迅速なPod起動のためにIPアドレスの事前付与を行う
    

それぞれの関係は[Proposal](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#inter-process-communication--between-cni-plugin-and-l-ipam)に示された図に基づいています(実際に呼ばれる名前と若干違います)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618703/08b96d35-bc1c-3466-ad49-7203ac35b909.png)


### 仕組み

VPC CNIは、PodのIP割り当てとネットワークルーティングの機能を主に提供しています。

- PodのIP割り当て
    
    PodへのIPアドレス割り当ては、EC2 ENIとIPAMDを使用して行われます。一般的なフローは以下のようになります。
    
    ```mermaid
    graph LR
        B --> |制御|A[ENI IP Pool]
        B[IPAMD] -->|維持| C[Warm Pool]
        A --> |一部| C
        C -->|IP付与| D[Pod]
        D -->|終了時解放| C
    ```
    
- ネットワークルーティング
    
    Pod間やPodから外部へのネットワークルーティングは、複数のルーティングテーブルとIPTABLEを使用して構成されています。その使い分けは以下の通りです。
    
    - Pod ↔ 外部ネットワーク: IPTABLE
        
        通常のSNATのように、パケットが仮想ネットワークインターフェース(veth)とEC2 ENI(ethなど)を通過する際に実行されます。
        
    - Pod ↔ Pod: ルーティングテーブル
        
        Pod間の通信やPodから外部への通信は、主にvethとethなどを介して行われ、さまざまなルーティングテーブルが暗黙的に適用されます。

### ライフサイクル

VPCCNIのバイナリは、主に7種類があります

| Binary | 説明 |
| --- | --- |
| aws-k8s-agent | IPAMDのgRPCサーバ |
| aws-cni | CNI Pluginの実装、主にVPC内ENI/IPとLinux Networkなどの設定を管理する |
| grpc-health-probe | IPAMD向けヘルスプローブの確認ツール |
| cni-metrics-helper | メトリクスを収集し、CloudWatchへPutMetricsするサポートツール |
| aws-vpc-cni-init | (initContainer)システムパラメータ、IPV6、各バイナリファイルの複製など、前提条件が整っていることを保証するための初期化コンポーネント |
| aws-vpc-cni | 過去ではentrypoint.shとして存在し、現在はIPAMDの起動とライフサイクル管理を行うツール |
| egress-cni | CNI Pluginの実装、主にSNATを使用して、アウトバウンドトラフィックのための特定のルーティングルールやポリシーを管理する |

`aws-vpc-cni`: 過去では、`entrypoint.sh`によって起動の順番などを制御していましたが、[1.11以降](https://github.com/aws/amazon-vpc-cni-k8s/pull/2146)にバイナリファイルの制御は主にGoファイルによって行われます。


......

## IPADMと`add cmd`エラーについて

残りの内容については、ぜひSRGのサイトでご確認ください。

https://ca-srg.dev/922372aee0364004830578a09799d858
【Azure】Windows Server VMに仮想マシンエージェントを手動インストール

## 背景

近年、クラウドコンピューティングの進化と共に、多くの企業がオンプレミスの社内システムをAzureなどのクラウドプラットフォームに移行しています。
この移行プロセスでは、Azure Migrateの使用がベストプラクティスとされています。
しかし、ユーザー事情によりAzure Migrateの利用が難しい場合や制約があるケースも考えられます。

例えば、Azure Migrateでは対象の仮想マシンにエージェントをインストールしますが、ユーザーによって仮想マシンの構成変更が禁止されている場合があります。

これが原因でAzure Migrateの利用が難しく、代わりにオンプレミスで稼働していたサーバーのイメージをエクスポートし、Azureにおいてそのイメージから仮想マシン（VM）を復元する手段を取ることがあります。
私が参加している移行PJにおいても、この手段でオンプレ→Azure VMへの移行を行っています。

前置きが長くなりましたが、ここからが本題です。
エクスポートしたイメージからVMを復元したところ、仮想マシンエージェントがインストールされていない状態であることが判明しました。

Microsoftは、VMが正しく機能する上で仮想マシンエージェントのインストールを推奨しています。
> Microsoft Azure Windows VM エージェントは、仮想マシン (VM) と Azure ファブリック コントローラーのやり取りを管理する、セキュリティで保護された簡易プロセスです。 Azure Windows VM エージェントは、Azure 仮想マシン拡張機能の有効化と実行において主要な役割を果たします。 VM 拡張機能は、VM のデプロイ後の構成 (ソフトウェアのインストールと構成など) を有効にします。 VM 拡張機能は、VM の管理者パスワードのリセットなどの回復機能も有効にします。 Azure Windows VM エージェントがないと、VM 拡張機能を実行できません。

https://learn.microsoft.com/ja-jp/azure/virtual-machines/extensions/agent-windows

残念なことにエージェントの手動インストール方法を記載した記事があまりなく、インストールに四苦八苦しました。

今後、私のような状況に遭遇した方々にとって少しでも助けになればと思い、本記事では手動でWindows VMに仮想マシンエージェントをインストールする手順について解説していきます。

## VMの情報
・OS
　　Windows Server 2016
  
・VMサイズ
　　Standard B2ms
  
・ネットワーク構成
　　VM→インターネットへ接続できる状態
　　後述の手順でエージェントのインストーラーを取得するのにインターネットへ接続するため
  
・Azure Bastion
　　構成済み
　　Azure Portal上でVMにRDP接続するために必要
　　構成方法は以下を参照
 　　　https://learn.microsoft.com/ja-jp/azure/bastion/quickstart-host-portal#createvmset
　　プロビジョニング時間に応じて料金がかかるので、使い終わったら消しましょう
 　　　https://azure.microsoft.com/ja-jp/pricing/details/azure-bastion/

## 手順
Azure Bastionを使用して、Azure Portal上でWIndow VMにRDP接続します。
接続手順は以下を参照。
　https://learn.microsoft.com/ja-jp/azure/bastion/quickstart-host-portal#connect


ブラウザを開き、以下のGithubリポジトリから赤枠のインストーラーをダウンロードします。
https://github.com/Azure/WindowsVMAgent/releases/tag/2.7.41491.1024
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/92084025-b01c-faee-74c8-5b1da2aad394.png)

このmsiファイルを管理者権限で実行します。

・ダウンロードしたmsiファイルを所定のディレクトリに配置します。

・コマンドプロンプトを管理者権限で開き、カレントディレクトリをmsiファイルがあるディレクトリに変更します。

・以下のコマンドを実行し、msiファイルを実行します。
```
msiexec /i WindowsAzureVmAgent.2.7.41491.1024_2107271024.fre.msi
```

・ウィザードが立ち上がるので、指示に従ってエージェントのインストールを行います。

インストール完了後、少し時間が経つとVMコンソール画面上で、
「エージェントの状態」がReadyになります。
この状態になればインストール完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/7718e04c-a485-e96a-e655-97f96c803448.png)


## 参考


https://learn.microsoft.com/ja-jp/azure/virtual-machines/extensions/agent-windows

https://azure.microsoft.com/ja-jp/pricing/details/azure-bastion/

https://learn.microsoft.com/ja-jp/azure/bastion/quickstart-host-portal#createvmset
新規プロダクトQAを担当した際の振り返り

## はじめに
皆様本年もおつかれさまです。
今年もモバイルゲームにおける新規プロダクトのリリース前QAの業務に携わらせていただきましたので、その経験の中から皆様にも参考になりそうな情報を本記事で共有できればと思います。

## 取り組んだこと

### 概要
今回は新規プロダクトのリリース前QAの振り返りとして、苦労したことや工夫したこと、改善していきたいことなどのお話ができればと思います。

### 苦労したこと
* １）予定されていたリリース前QAの期間が極端に短かった
▼取った対応
検証スケジュールを全てQA主動で決めなくてはいけなかったこともあり、QA都合に合わせたスケジュールを作成し、それを基にプロダクトとすり合わせを実施して進行していきました。
QA進捗の認識合わせをプランナーやエンジニア交えてデイリーで実施することで、齟齬が出ないように進行もしました。懸念点や追加依頼などもその場で密に調整できたので、課題解決までのタイムラグがあまり発生しませんでした。
　
* ２）初めて一緒に仕事をするテスト会社様だった
▼取った対応
常駐/スタジオ管理者/スタジオリーダーのメンバーと朝会/夕会を実施することで、スケジュールの進捗や工数管理、問題点などのすり合わせを実施しました。
直接のコミュニケーションをする時間を増やすことで、メンバー間の得意不得意や性格なども深く知ることができたのが良かったと感じています。
連携齟齬などが出やすい状況でのスタートはありましたが、スタジオの拠点ごとでの認識漏れや齟齬を最小限に抑えることもでき、遅延や過剰な工数がかかることはなく、フリーテストや探索的テストのコントロールもしやすく進めることができ非常に円滑なやり取りをすることができました。
　
* ３）リリース時に実装されるデータ数が膨大だった
▼取った対応
本案件では違和感のなさやユーザー視点でのバランスなどはデータ検証では見ていくことができないものだったため、動作を常駐/社員で分散して検証をおこない、懸念点や不具合傾向、不具合数を常に情報共有しながら進めることで、最小限の工数で対応できました。（おおよそ4~5人日程度で完遂）
合わせてヘビーユーザーのテスターにも参画してもらうことで、バランスの違和感なども検知できるような体制も整えて進めることができ、品質に大きく貢献することもできました。

### 工夫したこと
* 非機能観点やユーザービリティ観点について
前回の新規プロダクトQA時に課題として挙がったゲームが正しく動くかという観点より、そのゲームが楽しいか、プレイしやすいか、分かりやすいか、ストレスがたまらないか、などのユーザー目線での観点が足りなかったというポイントの改善し、ユーザービリティ観点を重視したフリーテストの導入しました。
前回に比べユーザー目線での改善提案など実施することができ、ゲームへの魅力的品質向上に繋げることができたと考えています。

### 結果
* 苦労したことの対策や、工夫したことの積み重ねにより、高品質でのリリースに繋げることができ、合わせてQA予算やQA期間も全て遅延なく予定通りに完遂することができました。

## ふりかえり

### 良かった点
* QA期間などが極端に短かったりと数々の厳しい課題が立ちはだかりましたが、1つ1つしっかり考え、相談しながら進めていくことの大切さを学ぶことができました。今後も最後まで諦めずに何事にも取り組んでいければと思います。


### 改善点
* リリース前QAから運用QAに入るつなぎ目について
運用QAに入る際の事前準備が、リリース前QAの想定以上のバタつきにより思うように進めることができなかったことが反省でした。
次回はそのような状況に陥らないよう、先を見据えて事前に調整を進めていければと思います。

## まとめ
前回担当した案件の時に、今後改善していきたい部分などを今回取り入れることができ、より良い形でリリースまでの対応をすることができました。
今後もそういったPDCAを更に回しながらテスト業務に向き合っていければと思います。
QA知識のナレッジも非常に大事ですが、コミュニケーションをしっかりとることが仕事を進める上でもっとも重要だなということも今回再認識したので、皆様も意識してみると良いかなと思います。
[Elixir] phx.gen.releaseで生成されたDockerfileで外向きのHTTPリクエストができなくて手こずった話

この記事は [Elixir Advent Calendar 2023](https://qiita.com/advent-calendar/2023/elixir) カレンダー5の18日目です。昨日は @gx3n-inue さんでした！



https://qiita.com/gx3n-inue/items/b3caea9a931e5a4a661d

---

:::note info
最新のPhoenixならこの問題は起きません :v:
:::

Phoenixでは、`mix phx.gen.release` コマンドでリリース[^release]に必要なファイルを生成してくれますが、`--docker` フラグを指定するとDockerfileも合わせて生成してくれます。うーん、便利！

https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Release.html

[^release]:https://hexdocs.pm/mix/1.15/Mix.Tasks.Release.html

このDockerfileをそのまま使ってDockerイメージを作れば、あとはCloud Runなど適当なサービスにデプロイするだけでPhoenixアプリケーションを稼働できます :sparkles: 

ところが、外向きにHTTPリクエストすると :point_down: のようなエラーが出てしまいました...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28249/264405ee-f0d3-007a-cc4b-f94a634cf7ef.png)

phx.gen.releaseで生成されたDockerfileは、Dockerイメージのサイズが小さくなるような構成になっているので、あまり気を使わずにDockerfileを書いた場合に勝手に入るようなパッケージが入っていません。ログをちゃんと見ると予想がつきますが、原因は **CA証明書が入っていない** ことなので、[ca-certificates](https://packages.debian.org/bullseye/ca-certificates) パッケージをインストールするだけで解決します :tada: 

で、なぜ最新のPhoenixだとこの問題が起きないのか...ですが、phx.gen.releaseで使われるDockerfileのテンプレートが修正されたためです。感謝感謝 :pray: 

https://github.com/phoenixframework/phoenix/pull/5536

ここまでの話で、何に手こずったんだろう？と思ったことでしょう。以下、言い訳という名のポエムです :innocent: 

実はこの問題には自分で遭遇したのではなく、インフラ構築を対応した案件で「OAuthのコールバックで500エラーが出る」という旨の連絡を受けて知りました（リリース前です）。OAuthは一応それなりに仕組みを分かっているので、あ〜外向きのHTTPリクエストがうまくいってないんだろうな〜と当たりを付けて、ログを確認しないままインフラが原因かな〜と考えちゃったんですよね。Cloud Runで稼働させていたので、第2世代で何か変わったのかな〜と難しい方向に考えてインフラ構成を試行錯誤してしまって時間を使っちゃいました。で、いろいろ考えてるうちにどんなログ出てるんだろうと思って見てみたら、これインフラの問題じゃないなって気づいたという次第でした。ｵﾊｽﾞｶｼｲ

結論、ちゃんとログを見ろよってことです...w

---

明日の [Elixir Advent Calendar 2023](https://qiita.com/advent-calendar/2023/elixir) カレンダー5の19日目は @GeekMasahiro さんです！
お楽しみに :rocket:
Hacknetのすゝめ

本記事は、[めんどい太郎の Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mendoitarou_first_calendar) 15日目の記事です。

# はじめに

この記事は初心者が書いています。

皆さんはHacknetというゲームをご存知でしょうか。

今回はこのHacknetを紹介したいと思います。

# Hacknetとは

[Steamのページ](https://store.steampowered.com/app/365450/Hacknet/)から引用します

>Hacknetは実体験型、端末ベースのハッキング・シミュレーターです。
>マスコミ報道によると事故死ではないかもしれないという、最近死亡したハッカーの指示に従いながら、不思議な世界に飛び込んでみましょう。

ということで、ハッキングシュミレーターとのことです。

楽しそうですね。

# おすすめポイント

おすすめポイントとしては

- コマンドラインに慣れることができる
- 実際のコマンドに似ているため、学習にもなる。
- そんなに高くない

が挙げられます。

## コマンドラインに慣れる

HacknetではGUIによる操作も可能ではありますが、CUIを主に使っていくことになります。

わかりやすいチュートリアルも用意されており、コマンドラインに慣れることができると思います。

## 学習にもなる

ハッキングに使用するコマンドの中には、実際に存在するコマンドや似ているコマンドがあるのでコマンドの学習にもなります。

## そんなに高くない

2023/12/13現在では、1,200円とかなり安いです。

結構ボリュームもあるので、かなり安いと思います。

また、Steamなのでセールがあります。

セールでめちゃくちゃ安くなるのでそこが狙い目ですね。

# わかりやすい紹介サイト

[ドスパラのサイト](https://www.dospara.co.jp/express/tn1583557.html)が非常にわかりやすいです。

# 遊んでみての感想

楽しいです。

ハッキングは実際にやってしまうと犯罪なのでできないことができるというのは非常にいいですね。

ハッキングという行為は非常に楽しいです。

ゲームオーバーになってもリセットしたりセーブデータから戻ればミスっても大丈夫ですし。

それに時間制限などが設けられているので緊張感もあります。

ゲーム自体が軽量でLinuxでも動くので、ハードルが低いのもいいですね。

とにかく楽しいです。

現在はストレージ容量が全然ない状況なので削除してしまっていますが、Steamの機能でセーブデータがクラウド同期されているので別の端末でもできるのがいいですね。

# 終わりに

**Hacknetはいいぞ！！** という記事でした。

ぜひ遊んでみてください。
jQueryでツールチップ（リンクにマウスオーバーで文字と透過ボックス）を作る方法

リンク文字にマウスオーバーしたときに、透過ボックスと文字をツールチップで表示する方法

$(function() {
    $("span.tooltip").css({
        opacity:"0.9",
        position:"absolute",
        display:"none"
});
$("a").mouseover(function() {
    $("span.tooltip").fadeIn();
}) .mouseout(function() {
    $("span.tooltip").fadeOut();
}).mousemove(function(e){
    $("span.tooltip").css({
        "top":e.pageY+10+"px",
        "left":e.pageX+10+"px"
    });
});
});
サービスのセッションを切らさずにDockerコンテナを立ち上げ直す方法

EC2上にdockerでサービスを動かしていて、docker　imageの中にソースコードを埋め込んでデプロイしていました。
その際に、デプロイ時にセッションが切れてしい毎回ログアウトされる問題があったので改善するようにしました。
言語はPHPを使っています。 

## 解決方法
解決方法としては、EC2のローカル上にセッションを保存してdockerのbuild時にマウントさせることで解決しました。
セッションを保存したいローカルのディレクトリを `/var/sessions` 、マウント先のdockerコンテナのディレクトリはデフォルトでセッションが保存される　`var/lib/php/sessions` とします。

予めローカルに`/var/sessions`ディレクトリを作ります。
```
$mkdir　/var/sessions
```
次にdocker-compose.ymlファイルにマウントを書きます。
```:docker-compose.yml
volumes:
    - /var/sessions:/var/lib/php/sessions
```
こうすることで、ローカルの `/var/sessions`　がdockerコンテナの`var/lib/php/sessions` にマウント(コピーされるようなイメージ)されます。
そして、dockerコンテナの`var/lib/php/sessions`にセッションが保存されるとローカルの `/var/sessions`にも同期され`var/lib/php/sessions`の中身と同じものができています。

## セッションの確認
同じセッションが保存されているか確認してみましょう。
まずはdockerコンテナの`var/lib/php/sessions`にセッションが保存されているかを確認します。
```
$docker ps 
$docker exec -it [CONTAINER ID] /bin/bash
$ls var/lib/php/sessions
```
保存されていたら、次にdockerコンテナからexitしてローカルでセッションが保存されているか確認します。
```
$ls /var/sessions
```
同じセッションが保存されていたら成功です。

サービスに戻ってログイン機能があればログイン後、一度docker-compose　downしてからdocker-compose upするとログインされたままになってると思います。
AWS Amazon Polly機能と実装

# Amazon Pollyの概要と機能

## 概要
Amazon Pollyは、AWSが提供するテキストから音声合成（Text-to-Speech）サービスです。テキストデータを入力すると、高品質で自然な音声を生成することができます。Amazon Pollyは、アプリケーションやデバイスに音声合成機能を追加するために利用されます。

## 機能
以下に、Amazon Pollyが提供する主な機能を示します。

### 1. 多言語対応
Amazon Pollyは、多数の言語に対応しています。異なる言語やアクセントの音声を生成することができます。

### 2. 音声のカスタマイズ
Amazon Pollyでは、音声のトーンや速度、音量などを調整することが可能です。さまざまな声質や演説スタイルに合わせて、音声合成をカスタマイズすることができます。

### 3. SSML（Speech Synthesis Markup Language）のサポート
Amazon Pollyは、SSMLをサポートしています。SSMLを使用することで、音声の強調や音楽の挿入など、詳細な音声制御を行うことができます。

### 4. バッチ変換とストリーム変換
Amazon Pollyは、テキストをバッチ処理して一度に大量の音声ファイルを生成することも、ストリーム処理してリアルタイムに音声を生成することもできます。

## サンプルコード

### Java
```java
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.*;

public class PollyExample {
    public static void main(String[] args) {
        AmazonPolly client = AmazonPollyClientBuilder.defaultClient();

        String text = "こんにちは、Amazon Pollyのサンプルです。";
        String voiceId = "Mizuki";
        OutputFormat format = OutputFormat.Mp3;

        SynthesizeSpeechRequest request = new SynthesizeSpeechRequest()
                .withText(text)
                .withVoiceId(voiceId)
                .withOutputFormat(format);

        SynthesizeSpeechResult result = client.synthesizeSpeech(request);

        // 音声ファイルを保存する処理などを実装する
    }
}
```

### Go
```go
package main

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/polly"
	"os"
)

func main() {
	session, err := session.NewSession(&aws.Config{
		Region: aws.String("us-west-2")},
	)

	if err != nil {
		fmt.Println("Failed to create session", err)
		return
	}

	svc := polly.New(session)

	text := "こんにちは、Amazon Pollyのサンプルです。"
	voiceID := "Mizuki"
	outputFormat := "mp3"

	input := &polly.SynthesizeSpeechInput{
		Text:         aws.String(text),
		OutputFormat: aws.String(outputFormat),
		VoiceId:      aws.String(voiceID),
	}

	output, err := svc.SynthesizeSpeech(input)

	if err != nil {
		fmt.Println("Failed to generate speech", err)
		return
	}

	// 音声ファイルを保存する処理などを実装する
}

```

### C#
```csharp
using System;
using Amazon;
using Amazon.Polly;
using Amazon.Polly.Model;

class Program
{
    static void Main(string[] args)
    {
        var client = new AmazonPollyClient();

        string text = "こんにちは、Amazon Pollyのサンプルです。";
        string voiceId = "Mizuki";
        OutputFormat format = OutputFormat.Mp3;

        var request = new SynthesizeSpeechRequest
        {
            Text = text,
            VoiceId = voiceId,
            OutputFormat = format
        };

        var response = client.SynthesizeSpeech(request);

        // 音声ファイルを保存する処理などを実装する
    }
}
```

以上が、AWSのAmazon Pollyの概要と機能についての詳細な説明と、Java、Go、C#でのサンプルコードです。Amazon Pollyを活用して、テキストから高品質な音声合成を実現してください。
【Flutter】ボタン

# ボタンの種類
## [ElevatedButton](https://api.flutter.dev/flutter/material/ElevatedButton-class.html)
マテリアルデザインのボタン
``` dart
ElevatedButton(
  onPressed: () {
    // ボタンが押された時の処理
  },
  child: Text('Elevated Button'),
);
```
## [TextButton（テキストボタン）](https://api.flutter.dev/flutter/material/TextButton-class.html)
輪郭や塗りつぶしなし
``` dart
TextButton(
  onPressed: () {
    // ボタンが押された時の処理
  },
  child: Text('Text Button'),
);
```
## [IconButton（アイコンボタン）](https://api.flutter.dev/flutter/material/IconButton-class.html)
``` dart
IconButton(
  icon: Icon(Icons.add),
  onPressed: () {
    // ボタンが押された時の処理
  },
);
```
#　ボタンのスタイルについて
ElevatedButtonでサンプル作成
## 文字色や背景色、ボタンの形状の変更
``` dart
ElevatedButton(
  onPressed: () {
    // ボタンが押された時の処理
  },
  style: ElevatedButton.styleFrom(
    primary: Colors.green, // ボタンの背景色
    onPrimary: Colors.white, // 押下時の文字色
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(10.0), // 角丸
    ),
  ),
  child: Text('Styled Button'),
);
```
RDSのカスタムエンドポイントを設定したらインスタンスのフェイルオーバ優先度も設定する

# はじめに
Amazon RDSのカスタムエンドポイントを設定した場合、フェイルオーバーの優先度も確認する。

# 問題

RDSのカスタムエンドポイントを利用してリーダーインスタンスの用途を分割したい場合がある。例えば、検索が重い管理画面の参照を専用インスタンスに分けたい場合などが該当する。

複数のカスタムエンドポイントを作成した場合、インスタンスのフェイルオーバー優先度も設定しないと、フェイルオーバをさせたくないインスタンスがライターインスタンスに昇格してしまう可能性がある。仮にスペックの低いインスタンスがライターに昇格することで、アプリケーション全体のSQL性能劣化が起こってしまう。

# 解決方法

カスタムエンドポイントを利用する場合は、インスタンスのフェイルオーバー優先度も設定する。設定は0から15まで可能で、デフォルトは0(最優先)となっている。フェイルオーバーをさせたくないインスタンスは1以上の値を設定する。

# Terraformの設定例
フェイルオーバー優先度15(`promotion_tier = 15`)を設定する例は以下の通り。 

```
resource "aws_rds_cluster_instance" "admin" {
  cluster_identifier = aws_rds_cluster.this.id
  identifier = "${aws_rds_cluster.this.cluster_identifier}-admin-0"
  instance_class = local.env.rds.instance_class_admin
  engine = aws_rds_cluster.this.engine
  engine_version = aws_rds_cluster.this.engine_version
  db_subnet_group_name = aws_rds_cluster.this.db_subnet_group_name
  apply_immediately = aws_rds_cluster.this.apply_immediately
  copy_tags_to_snapshot = aws_rds_cluster.this.copy_tags_to_snapshot
  auto_minor_version_upgrade = false
  performance_insights_enabled = true
  db_parameter_group_name = aws_db_parameter_group.this.name
  promotion_tier = 15

  preferred_maintenance_window = aws_rds_cluster.this.preferred_maintenance_window
}
```

# 影響

なし。

無停止で設定できる。
Vue 基礎勉強 v-model

(Vue.js 3.1.5を使用)


**v-model**
双方向データバインディングを利用する時に使う。

双方向データバインディングとは、
dataオブジェクトの値変更をすると、テンプレートの値も変更される。
と同時に、
テンプレートの値を変更すると、dataオブジェクトの値も変更される。
ということ。
`
dataオブジェクトの値変更　＝＞　テンプレートの値変更
`
`
dataオブジェクトの値変更　＜＝　テンプレートの値変更
`

```javascript:javascript
const app = Vue.createApp({
    data: () => ({
        message: 'おはよう。Japan.'
    })
})
app.mount('#app')
```

```html:html
    <div id="app">
        <p><input type="text" v-model="message"></p>
        <p><input type="text" v-model="message"></p>
        <p>{{$data}}</p>
    </div>
```

初期状態だと、
dataオブジェクトの値が、テキストボックスに表示されている。

![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/117c44f7-0d38-b774-1939-821263682193.png)

上のテキストボックスに文字を追加すると、
dataオブジェクト(message)の値が変更されて、
下のテキストボックスの表示も変更される。

![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/3f23b665-e93d-d4ec-2a95-ba85ab529c3d.png)

下のテキストボックスを変更しても同様の動きになる。
（dataオブジェクト(message)の値が変更されて、上のテキストボックスの表示も変更される。）
![8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/d99a05aa-ed88-5011-4cd8-059af3bbc608.png)
Azure App Service × WordPress ブログ作成時のエラー解決記

# Azure App Service × WordPress ブログ作成時のエラー解決記

## はじめに

Azure App Serviceを利用してWordPressのブログを構築している際に、突然エラーが発生しました。このブログでは、そのエラーが発生した背景から、解決までの一連の流れを詳細に紹介します。同様の問題に直面している方にとって、この記事が役立つことを願っています。

## エラーの発生

WordPressの設定を行っている最中、WordPress上で「現在メンテナンス中のため、しばらくの間ご利用いただけません。」というエラーメッセージがｄた。それ以外のエラーメッセージには十分な情報がなく、問題の特定が難しい状況でした。しかし、問題解決のために着実に進めていくことが重要です。

## 調査

まず初めに、Web上で「WordPress 現在メンテナンス中のため、しばらくの間ご利用いただけません。」と検索。
その中で役立った記事を紹介いたします。

[SFTPを使用したWordPressサイトへの接続方法](https://kinsta.com/jp/knowledgebase/how-to-use-sftp/)

[WordPressのサイトに「現在メンテナンス中のため、しばらくの間ご利用いただけません」が表示され続けている時の対処法](https://ssaits.jp/promapedia/trouble/20230413.html)

しかし、私はFTPサーバーと格闘した結果ログインが出来ませんでした。
その先の解決方法を見るとどうやら、.maintenanceを削除するだけで、良いとのこと。
それならGithubとちょっと似ているなぁと思いながらも、Azureのポータルに戻り、AzureのSSHコンソール上から削除を試みました。

## 具体的な解決策
結論から言うと、Azure App Service SShからの削除で解決ができました！

**.maintenance**のありかを探すのに苦労しましたが、下記のコマンドで行けました！

まず、cdでWebアプリケーションのルートディレクトリに移動します。
```shell
0a2e59298948:/# cd home/site/wwwroot
```

**.maintenance**は**「.」**から始まる隠しファイルです。そのため、lsでは表示されないことに気を付けましょう！
```shell
0a2e59298948:/home/site/wwwroot# ls
index.php    nginx.conf   wp-activate.php  wp-blog-header.php    wp-config-sample.php  wp-content   wp-includes        wp-load.php   wp-mail.php      wp-signup.php     xmlrpc.php
license.txt  readme.html  wp-admin         wp-comments-post.php  wp-config.php         wp-cron.php  wp-links-opml.php  wp-login.php  wp-settings.php  wp-trackback.php
```

次にrmコマンドを使用して削除を行っていきます！
```
0a2e59298948:/home/site/wwwroot# rm .maintenance
```

再度rmコマンドを実行して、ディレクトリ内に**.maintenance**が存在しないことを確認します
```shell
0a2e59298948:/home/site/wwwroot# rm .maintenance
rm: cannot remove '.maintenance': No such file or directory
```
## エラーの原因
初めてのWordpressだったので、更新がとてもたまっていました！
WordPress自体の更新と、テーマの更新を一度に行ったことで引き起こされたエラーであったとわかりました。
今後はひとつづつ、更新が終わるのを待とうと思います。

## 結果
問題の解決後、WordPressブログは正常に動作しました。エラーの原因が特定できたことで、同様の問題に遭遇した際には、この記事が参考になると幸いです。

## 今後

現在は、[takayasora.com](takayasora.com)としてフレームワークで作ったWebサイトを運用しておりますが、静的なWebサイトになっており物足りなくなったので、一新してブログを開設します！今後も楽しんでブログを作っていきたいと思います！
ご一読ありがとうございました～！
コンサル一年目が学ぶことを読んでみた


こんにちは。新卒1年目エンジニア研修中のosadamです。
今回は研修の一貫として「コンサル一年目が学ぶこと」を読んだので、簡単にまとめてみました。

https://www.kinokuniya.co.jp/f/dsg-01-9784799315323

## 目的
 社会人として必要な普遍的なスキルを学ぶため。
 タイトルには、コンサル一年目と記載されていますが、コンサル一年目だけではなく、全ての社会人におすすめできる本です。
全ての業界・業種で活かせるスキルが詰め込まれています。

## 概要
この本の内容は、各界で活躍されている元コンサルタントの方に取材をし、新卒時代に学んだことで記憶に残っていること、今でも役になっているスキルや経験を解説している本です。
本書は以下の4章に分けて構成されています。

### 第1章 コンサル流話す技術
相手に伝わるように話す方法が書かれていました。
よく耳にするPREP法から始まり、ロジックで話す、論理と数字で話す等々の話す上で大事になるポイントが解説されていました。
全てのポイントにおいて大事なのが、「相手に伝わるか」という点です。自分が感覚で表現している部分を数字に置き換えることで相手が納得できる様になります。

### 第2章 コンサル流思考術
引用：コンサルティング会社に入って学ぶことは、一連のロジカルシンキングや問題解決の手順です。ただ、これはコンサルティング会社に入らないと学べないことではありません。

コンサルティング会社に入っていなくても思考術が学べる方法が書いてありました。コンサル思考の中でも特に大切な「仮説思考」等役に立つ思考法が記されています。

### 第3章 コンサル流デスクワーク術
コンサルとしてマスターするべき、議事録書き・パワーポイントの作り方が記されていました。
また、仕事の速さを2倍速3倍速にするための思考も紹介されています。

### 第4章 プロフェッショナル・ビジネスマインド
章タイトルの通り、コンサルとしてのビジネスマインドが書かれています。「時間はお金」と認識する、ヴァリューを出す等、働く上で心に留めておきたいマインドが記載されていました。

## 感想
この本を読んで、普段の自分の社会人としての態度を振り返り、そして新たな考えを学ぶいい機会になりました。
実際に活躍している方々の新卒時代に学んだことということもあり、説得力もありました。

## 終わりに

この本を読んで、たくさんの学びがたくさんありました。
特に「仮説思考」の話は、すぐに業務に活かせそうだと思いました。まだ知識が足らず分からないことが多いですが、分からないで片付けるのではなく、こうなのではないかと考える思考の癖をつけて行きたいと思います。
私と同じ新卒の方は、新たな学びが、社会人年数が長い方は社会人として必要な基礎を振り返る良い機会になると思います。
気になった方は、ぜひこの本を手に取ってみてください。
Nuxt 3 – build で生成される assets (Javascript/CSSファイルなど) のランダムはハッシュは何なのか

# ハッシュ生成の確認

`nuxt build` でハッシュ付きのアセットファイルが標準出力される

あとは `.output` `.nuxt` 以下の生成されたファイルを直接見ると良いようだ

実際にどのファイルが使われているかは実際にサイトにアクセスして、ブラウザの開発者ツールでNetworksタブを見るなどすれば分かる

# nuxt.config

nuxt.configでハッシュを消して固定化することも出来そうだが、ユーザのブラウザがJS/CSSなどをキャッシュしてしまい、状態が更新されない問題が起こりそう

```
vite: {
    build: {
      rollupOptions: {
        output: {
          chunkFileNames: '_nuxt/[name].js',
          assetFileNames: '_nuxt/[name][extname]',
          entryFileNames: '_nuxt/[name].js'
        }
      }
    }
  }
```

https://github.com/nuxt/nuxt/discussions/24623

# ハッシュが変わるタイミング

localで試すとbuildのたびにハッシュが変わったり、Dockerで試すと「コードの状態が同じ限り同じハッシュ値が生成」されたり、
設定によっても挙動が変わったりとマチマチっぽく思える

設定がSSRかCSR(SPA)かによっても挙動が変わるのかもしれない

# ビルドのたびにハッシュが変わるファイルもあれば、変わらないファイルもある

詳細は不明


# チャットメンバー募集


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

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


# Twitter

https://twitter.com/YumaInaura
SpotifyとiTunes(AppleMusic)の違いで躓いた話

本記事は、[めんどい太郎の Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mendoitarou_first_calendar) 14日目の記事です。

# はじめに

この記事は初心者が書いています。

先日の記事でiTunes Search APIとSpotify Web APIを紹介しました。[^1]

これらを組み合わせて使おうとしたときに細かい違いがあり、躓いたのでご紹介します。

# 返ってくるデータ

## 表記違い
先日の記事[^2]で紹介したJSONデータを見ていただければわかるかもしれませんが、表記の仕方などが微妙に異なります。

例を示しておきます。

```JSON:Spotify.json
{
    ~省略~
    "name": "鏡よ鏡",
    ~省略~
}
```

```JSON:iTunesSearchAPI.json
{
    "resultCount": 1,
    "results": [
        {
            ~省略~
            "collectionName": "鏡よ鏡 - Single",
            ~省略~
        }
    ]
}
```

記事にも書きましたが、シングルアルバムの表記が異なります。

Spotifyは``鏡よ鏡``と曲名そのままですが、iTunes Search APIは``鏡よ鏡 - Single``と`` - Single``が付きます。

これが原因でSpotifyで検索しても出てこないなんて現象が発生します。

困ります。

## 言語

さらにiTunes Search APIは帰ってくるデータが日本語を指定してもなぜか英語で返ってきます。(私の環境だけかもしれません。)

例を示しておきます。

```JSON:Spotify.json
{
    ~省略~
    "name": "花譜",
    ~省略~
}
```

```JSON:iTunesSearchAPI.json
{
    "resultCount": 1,
    "results": [
        {
            ~省略~
            "artistName": "KAF",
            ~省略~
        }
    ]
}
```

Spotifyはアーティスト名が``花譜``と日本語で返ってきていますが、iTunes Search APIは``KAF``と英語名で返ってきています。

そのため、返ってきた``KAF``をSpotifyで検索しても一番上に同じアーティストが必ず表示されるわけではないという結果となってしまいます。

非常に困ります。

# 解決方法

結論から言います。

わかってません。

リサーチ不足もあるとは思いますが...

シングルアルバムに関しては、`` - Single``の文字を消してやればOKだと思います。

しかし、これには問題があって普通のアルバムに入ってる方が検索結果に出てくる可能性があるということです。

同じ曲ではありますが、シングルを出したいのにシングルじゃないものが出てくるなんて言う結果になります。

これだとだめです。

[^1]:[iTunes Search APIを使って音楽検索をしてみる](https://qiita.com/mendoitarou_/items/d1838c8dede0571dccb4)<br>[SpotifyのAPIを使ってみる](https://qiita.com/mendoitarou_/items/ccba9ccb83697fae0829)

[^2]:[iTunes Search APIを使って音楽検索をしてみる](https://qiita.com/mendoitarou_/items/d1838c8dede0571dccb4)<br>[SpotifyのAPIを使ってみる](https://qiita.com/mendoitarou_/items/ccba9ccb83697fae0829)
スクレイピングで遊んでみた

:::note alert
スクレイピングが禁止されているサイトでのクロールは犯罪です。
記載されていなくても節度を守り、日々感謝を忘れず情報取得をしましょう
:::

## スクレイピングとは
まぁ多分ほとんどの方は知っていると思いますが、Web上の情報を集めることです。
クローリングはWebサイトを自動で巡回することですね。
クローリングしながらスクレイピングをしていきます。

## 今回の記事の経緯
突然ですが株式分析にハマっていまして、バフェットコードなんかを使って色々見たりしているのですが、
いちいち会社のところまで行って業績を調べるのは面倒、、
スプレッドシートなんかにぱっとグラフでまとめてくれたら便利なのになぁと思っていました。

バフェットコードにもAPIはあるのですが、高すぎて新人のぺーぺーが買えるような代物ではありません。
よって、自前で何とかしなければならないのでした。

## スクレイピング開始！
対象サイトは、よくあるやつです。正直怖いので「投資　スクレイピング　可能」とかで調べてみてください。多分何件かスクレイピングしても良い良心的な？サイトが出てくると思います(節度は守りましょうね！)

使うのはpython, excelです。
まずは下の設定を行います。(どうでもいい)

1. python, VScode, Chromedriverのインストール
2. venvの環境設定, pathの指定
3. VScodeでpythonとpowershellのダウンロード


pythonではselenium, bs4を主に使っていきます。
グラフ化するなら多分matplotlibとはPILとかを使えばいいと思います。
excelとの関連付けはopenpyxlを使っています。


```python:scraping.py

#URLの宣言
url = 'https://xxx.com'

#ドライバーを使ってurlを開いてもらう
driver = webdriver.Chrome('chromedriver.exe')
driver.get(url)
sleep(5)

#seleniumにより、NAME属性のuser_idの部分を取得し、自分のidを入力
userid = driver.find_element(By.NAME, 'user_id')
text_userid = 'xxxx'
sleep(3)
userid.send_keys(text_userid)

password = driver.find_element(By.NAME, 'user_pass')
text_password = 'xxxxx'
sleep(3)
password.send_keys(text_password)

#スクロールしてログインボタンをクリック
driver.execute_script("window.scrollBy(0, 500);")
sleep(2)
login_btn = driver.find_element(By.NAME, 'login')
login_btn.click()
sleep(2)

#目的のページまで行く
pointer = driver.find_element(By.CSS_SELECTOR, '#INNER-L > div.login > div..search_login > div.searchbox > ul > li.login > a')
pointer.click()
```


こんな感じで進んでいきます。
基本的に目的のページまで行くにはselenium, 
ページのソースを持ってきて使いやすくするのはbs4って感じです。

続き
```python:scraping.py
#ページソースをhtmlで格納
html = driver.page_source.encode('utf-8')

#bs4を使いパースする
soup0 = BeautifulSoup(html, "html.parser")

#ページの中のテーブルをtablesに格納
tables = soup.find_all('table', class_='leftTable')


#その後色々と処理をしていく

```

適当ですが大体こんな感じです。
とりあえずbs4でhtmlの使える部分を抽出していきます。
複数サイトやりたい場合は、またdriverを動かすなり、htmlをどっかにためておいて
後でbs4で一気に整形します。


excelへの保存はopenpyxlでやるのですが、簡単なので他のサイトで調べてください。
シート開いてセルを指定しながら、データフレームの行を書き写していくだけです。

# 躓いた点
Webサイトについて無知なもので、どうやらiframeという仕組みがあるみたいです。
他のページを現在のページに埋め込む技術らしいんですけど、これがあると上手くスクレイピングができません。(htmlを取り込むとiframe部分が消える)
なので、以下のようにスイッチしてあげる必要があります。

```python:scraping.py
iframe = driver.find_element(By.TAG_NAME,'iframe') 
driver.switch_to.frame(iframe)
```

私はこれに半日以上かけ悲しい思いをしました。

# 成果物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671407/ed9e13ec-2081-7de3-6ee8-b2a0f6651c14.png)

こんな感じです。
試作品なのでクオリティは許してください、、、

ちなみにバフェットコードのURLは会社のコードで分かれているため、自前でガッチャンこしているだけで、スクレイピング/クローリングはしてません。何とかしてバフェットコードを見たかったんです、、、


これで毎日実行にしてDB保存してグラフ作ってもいいですし、
もっと情報集めて、見たい指標だけ集めてもいいですね。


凄く適当な記事で申し訳ないですが、是非皆さんも安全に気を付けてやってみてください。
OpsRamp Logs - AWSログ転送のサンプル設定

本記事では、OpsRamp LogsのAWSログ転送(CloudWatch logs)のサンプル設定について説明します。

# 概要
OpsRamp Logsでは、Amazon Kinesis Data Firehoseを使用し、CloudWatch logsに集約されたAWSのログを取り込むことができます。

# 設定方法
Infrastructure > Logs 画面左上のハンバーガーマークのLog Configuration > AWSをご参照ください。
Amazon Kinesis Data FirehoseおよびClouldWatch logsでSubscription Filterの設定が必要になります。

- Amazon Kinesis Data Firehoseの設定
Amazon Kinesis Data Firehoseを作成し、「Choose source and destination」で「Source」および「Destination」を選択します。

| 項目 | 設定 |
|:-|:-|
| Source | Direct PUT |
| Destination | HTTP Endpoint |

![aws-fh-config1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/87468130-5305-f099-0b16-10e7e5028316.png)

「Destination settings」で「HTTP endpoint URL」および「Content ending」を設定します。

| 項目 | 設定 |
|:-|:-|
| HTTP endpoint URL | OpsRampの設定画面に表示されたURL |
| Content encoding | Not enbaled |

![aws-fh-config2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/4959a3ac-a7d8-f1af-1078-ef050371b6c3.png)


- CloudWatch logsの設定
AWSコンソールでCloudWatch > Logs > Log groupsから対象のロググループに対し、Subscription Filterを設定します。
対象のロググループを選択し、Actions > Subscription filters > Create Kinesis Firehose subscription filterから設定します。
![log-groups_SubscriptionFilter.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/19cfa68e-a4b8-8471-ba24-1a6b3a8debf5.png)

Choose destinationのKinesis Firehose delivery streamに作成したAmazon Kinesis Data Firehoseを選択します。
![subscriptionfilter1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/9c18ff00-692e-b453-8b7a-e793e2fa66f7.png)

Grant permissionで、Subscription FilterがAmazon Kinesis Data Firehoseに対して書き込むためのロールを設定します。
![subscriptionfilter2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/f721d0c4-f900-e82b-4a97-79c387360ad7.png)
``` AWS: Role - Trust relationships
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.us-east-1.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

``` AWS: Policy - Permissions
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": [
                "<作成したAmazon Kinesis Data FirehoseのARN>"
            ]
        }
    ]
}
```

Configure log format and filtersで、Log formatおよびSubscription filter nameに任意のフォーマットおよび名前を設定します。
![subscriptionfilter3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/ecd63761-1c99-c46f-30c6-42ac7e903202.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
急にクリーンインストールしたくなるときありますよね？え、ない？

この記事はHRBrain Advent Calendar 2023 17日目の記事です。

https://qiita.com/advent-calendar/2023/hrbrain

# はじめに

こんにちは、株式会社HRBrainでフロントエンジニアをやっているしっぽくんです。
12月も後半になり、年末の大掃除がてら部屋の模様替えや荷物の整理などを始める季節ですね（？）
今年も色々な技術が出てきましたが、皆様の中には試してそのまま。。。みたいなこともあると思います。
そこで今年1年のあれやこれやをクリーンインストールで解決することができます！

そんな時にあると便利なものがあります。そう、dotfilesさえあれば煩わしい環境設定に苦しむこともない(個人差があります)！さぁみんな明日と言わず今から自分だけのdotfilesを作ろう！！

会社のPCでクリーンインストールをNGです。また私用PCにおけるクリーンインストールは個人の責任となりますので、当方は一切の責任を負いません。

# ターゲット

- dotfilesってなに？って言う人
- 新しい会社にジョインしたときの環境構築をする人
- PC乗り換える人
- ターミナルをデフォルトで使っている人
- 自分の開発環境を管理したい人
- クリーンインストールをしたくなってる人

# そもそもdotfilesとは？

隠しファイル(.*)をdotfile と言いますがこれらをまとめたもの。基本的には設定ファイルが主になっています。
これらの設定ファイルを管理しているのがdotfilesと呼ばれます。

### 例えばどんなものがあるのか

bash, zsh などのshell の設定ファイルやvimなどのエディタが基本的には挙げられます。
ちなみにbrewで入れるものも管理できます。(後述します）

# 構築方法

構築自体は非常に簡単です。

- リポジトリを用意する
- 自身のdotfilesを用意したリポジトリに入れる(コピー)
- dotfilesからシンボルをはり、追従できるようにする
- pushする
- シンボルを貼るスクリプトを書く

これらで始めることが出来ます。
あとはREADMEにセットアップ方法を書いておき、スクリプトを用意しておけば一発で環境をセットアップすることが出来ます。
私は実際に入社初日にこれらの手順でセットアップを完了させました。(スタートダッシュがきれる)

一例ですが、自分が利用しているインストールスクリプトは下記のような内容です。
```sh
#!/bin/bash

for f in .??*
do
  # ここで不要なファイル/フォルダを除去している
  [[ "$f" == ".git" ]] && continue
  [[ "$f" == ".gitignore" ]] && continue
  [[ "$f" == ".DS_Store" ]] && continue
  [[ "$f" == ".zplugin" ]] && continue
  [[ "$f" == ".config" ]] && continue
  [[ "$f" == ".trash" ]] && continue

  echo "$f"
  # エイリアスを用意
  ln -s $PWD/"$f" $HOME/"$f"
done
```

参考までに自分のdotfilesはこちらです（ちなみにzshとvimまわりはちゃんと整備できていないので、いくつか壊れてます。。

https://github.com/shippokun/dotfiles

# 特に推しポイント

皆さんは自分のPCに入れているツールを把握していますか？
自分はある程度把握しています。把握のために使っているのはこちらのBrewfile。
このBrewfileもdotfilesで管理しています。

https://homebrew-file.readthedocs.io/en/latest/usage.html

:::note warn
自分の利用しているbrewのバージョンとは異なるので、以降に説明する内容と差異がある可能性があります。
:::


こちらも始め方はシンプルで `Brewfile` というファイルを作成し、そこに利用しているツールを突っ込んでいくだけです。

```
# Brewfile

# アプリケーションのインストール先を指定
cask_args appdir: "/Applications"

brew "git"
brew "gh"
brew "ghq"

cask "google-chrome"
cask "visual-studio-code"
cask "slack"
```
:::note success
事前にAppleStoreにログインしておき、 `mas "アプリ名", id: xxx` と書いておくと合わせてダウンロードすることが可能です。
:::

あとは `brew bundle` を `Brewfile` と同じディレクトリで実行するとインストールが開始されます。

# まとめ

dotfiles自体は始めるのはとても簡単です。
`~/.zshrc` などをコピーしてインストールスクリプトを書いたらそれだけで十分です。
必要なのは管理する気力と仕組み、あとはクリーンインストールをする勇気です。

この記事を読んだあなたもこれでいつでもクリーンインストールができるようになりましたね！

# PR

株式会社HRBrainでは一緒に働くひとを募集しています。
爆速で環境構築をして最速の立ち上がりによってValueをどんどん発揮していきましょう！！

https://www.hrbrain.co.jp/recruit
ECS タスク IAM ロールを利用する際は認証情報の取得タイミングに気を付ける (前編)

本記事は、[AWS Containers Advent Calendar 2023](https://qiita.com/advent-calendar/2023/aws-containers) の 13 日目 (12/13) のエントリーです。

本エントリーでは、Amazon Elastic Container Service (Amazon ECS) でタスクに IAM ロールを割り当てる機能である「タスク IAM ロール」を利用する際の Tips をご紹介します。

## タスク IAM ロールとは
タスク IAM ロールとは、文字通り「ECS タスクごとに IAM ロールを割り当てる」機能です。全体的な動作イメージは次の図のようになります。
（下記は ECS on EC2 を想定していますが、ECS on Fargate の場合も (2) 以降は同じような流れになります）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79239/de97aef6-d927-6379-2eb6-b7f1909769a3.png)

1. ecs-agent がコンテナインスタンスにアタッチされた IAM ロール (インスタンスプロファイル) の一時認証情報を取得
1. 1 で取得した一時認証情報を利用して、ECS タスクに紐付け予定の「IAM ロールの一時認証情報」を取得
1. 2 で取得した「IAM ロールの一時認証情報」を取得するための secret を付与して ECS タスクを実行
1. ECS タスクで動くアプリケーションが、3 の secret を利用して「IAM ロールの一時認証情報」を取得

参考: [Using IAM roles with Amazon ECS tasks \- Amazon Elastic Container Service](https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/security-iam-roles.html)

ここでポイントとなるのは、ECS タスクで動くアプリケーションが「IAM ロールの一時認証情報」を取得する場合、ecs-agent に対してリクエストが発生するという点です。

## タスクメタデータエンドポイントには rate limit がある
ecs-agent は、タスクメタデータエンドポイントで「IAM ロールの一時認証情報」を提供しています。タスクメタデータエンドポイントには rate limit が設けられており、一定期間中に大量のリクエストを送るとスロットリングが発生します。

つまり、アプリケーションが「IAM ロールの一時認証情報」を頻繁に行うようなケースでは、タスクメタデータエンドポイントへのリクエストでスロットリングが発生し、一時認証情報を取得できない場合がでてきます。本事象については、ecs-agent のタスクメタデータエンドポイントの rate limit の設定値を変更することで緩和できる場合があります。

[タスク用の IAM ロールのトラブルシューティング \- Amazon Elastic Container Service](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/troubleshoot-task-iam-roles.html)
> 「Unable to locate credentials」エラーが表示された場合、次の原因が考えられます。
> 
> (中略)
>
> ・ 認証情報の URL が調整されています。ECS_TASK_METADATA_RPS_LIMIT コンテナエージェントパラメータを使用して、スロットル制限を設定できます。詳細については、「Amazon ECS コンテナエージェントの設定」を参照してください。

ただし、`ECS_TASK_METADATA_RPS_LIMIT` の調整でも緩和できない場合や、`ECS_TASK_METADATA_RPS_LIMIT` パラメーターを変更できない ECS on Fargate 環境の場合は、どのように対処すればよいでしょうか。

　この場合、アプリケーション側のコードを見直すことで改善できる場合があります。アプリケーションコードをどのように見直すのかについては、本エントリーの後編をお待ちください！
AWS ECRへのDocker imageのpush時に発生する問題

## 記事の目的
自分用の備忘録。
AWSのECR(Elastic Conatiner Registry)へDocker imageをpushする際に詰まった。


```sh
$ docker push <id>.dkr.ecr.region.amazonaws.com/<repository:tag>
The push refers to repository [aws_account_id.dkr.ecr.region.amazonaws.com/<repository:tag>]
************: Retrying in 1 second
************: Retrying in 1 second
...
...
************: Waiting
EOF
```

## 確認項目
エラーが起きた時に確認すべきは以下
* ユーザのECR関連の権限が十分である
* configで権限を持つユーザが正しく指定されている
* 指定したregionにpush先のrepositoryが存在する

自分の場合は、権限が不足していた。やや過剰気味ではあるが、`AmazonEC2ContainerRegistryFullAccess`を付与することで解決。
[4年]プログラミングが楽しい時、つまらない時を振り返ってみた

# はじめに
友達がエンジニアを続けるか悩んでいて話を聞いたのですが、その理由が「向いていないと感じる」からでした。
もちろん彼自身と自分で見えているものが違うので、真実とかはわからないのですが
自分としてはエンジニアの向き不向きを判断するには時間がかかる、もしくは一生わからないものなんじゃないかと思っています。
そこでそのことをうまく伝えるために、プログラミングを初体験してから３年半ほどの自分の経験を振り返ってみました。

# プログラミング初体験期：楽しい
大学3年の終わりから
この頃はなんでも楽しかったです。
初めてのプログラミングは刺激がいっぱいでした。
ブラウザ上にHelloWorldが表示されるだけで感動しましたし、エンジニアというかっこいい存在になりたいという目標もあったので
割と一日中パソコンを触っても苦痛じゃなかったです。
この頃は「自分は今は実力はないけれど楽しめている、だから自分はエンジニアに向いているんだ。しかも成長率もすごいぞ」などと考えていました。

# 入社1年目：つまらない
このころの自分にとってプログラミングは修行でした。
楽しいと感じることも時々ありましたが、自分の才能のなさに気づいた瞬間でもあります。
なかなかできることがふえず、新しいことに挑戦しては失敗するということの繰り返しでした。
業務とハッカソン、社内の勉強会、など意欲的に活動していましたが、どれも自分の実力から成果を得たわけではなかったです。
勉強しても作りたいものがなかなか作れないし、チーム開発では足を引っ張っているという感覚がかなり辛かったです。

# 入社2年目~3年目の半年：つまらない？楽しい？
この頃は楽しさ半分、辛さ半分でした。
開発は楽しいが、仕事が辛いというような感じです。
ハッカソンに出た時は、チームの中で自分の価値を見出せるようになっていましたし、できることも増えて個人開発でも変なアプリを作って遊んでいました。
しかし仕事になると、
一年目の時にはなかった余裕が出てきて、逆に色々考えるようになっていました。
その結果、仕事の意味や目的が自分の中で見つけられなくなっていました。
もっと価値のあることをやりたい、自分の実力を試したいという気持ちが強くなっていました。
それを押し込めてひたすらプログラミングをしていたのですが、全然身が入っていなかったので、成長もほとんどしていません。。。
この頃は、周りからの評価もだんだん下がってきて、自分の中でも伸び悩みを感じていたので、プログラミングは向いていないんだなと感じていました。

# 退社後3ヶ月目まで：楽しい！！
今です。
今は神戸情報大学院大学という大学院に入って、やりたかった「認知症対策のITシステム」の研究を行っています。
他の方のお手伝いをしたり、qiita advent calendarに参加したり、ハッカソンや個人開発を行ったりと異常に忙しいのですが今までで一番楽しいです。
ただ、エンジニアには向いているわけではないと思っています。
他の方と比べるとなかなか成長スピードも遅く、モバイルアプリ界隈でも全然名が知られていません。
ただ、今までに比べると「エンジニアに向いているか」ということを考えることが少なくなりました。
そして何よりも今が一番楽しいです。
今後もなんとかして個人開発を続けていこうと感じています。

# 結論
「エンジニア」という漠然としたものに向き不向きはなく
環境やその時の仕事、評価する人など様々な要因で大きく変わるのではないかと思っています。

だから
どんな環境や仕事にも向いていない人はいないし、向いていないと感じるなら環境を変えてみると良いと思います。
まぁ逆につまらないならエンジニア辞めるのも一つの正解だと思います。

どんな選択もその後、正解になる可能性もあるし、間違いになる可能性もあるので
その後の行動次第です。

まだ4年もやっていないので、見えている世界は狭いのですが、今の所の自分の結論でした。
Copilot (Bing Chat)とのやりとりで奮闘した話

こんにちは。
ここではCopilot(Bing Chat)とやり取りした中で、もっといい回答をもらえるように奮闘した話をメモレベルで書いたものです。

ChatGPTで聞いてもわからんーという回答が返ってくる質問については、GoogleのBardか、BingのCopilot(Bing Chat)に聞いたりしている。インターネット検索して教えてくれるが、たまには自分で検索して探した方がいい答えが得られることも少なくはないのだ。

ここまでくると、やっぱり自分で検索して答えを探すのはめんどくさいときは結構ある。AIに聞いても変な話ばっかりすることも多いから信用できないので、頑張って探すかーとしても、どうしてもAIを活用したいという気持ちが強くなる。いいプロンプトを投げたら、もっといい答えを得ることができるんじゃないかという希望を持ってBingのチャット画面を開いた。

### とりあえず、聞いてみよう
テストとして、先月に発表されてすごく話題になっている「GPTs」について聞いてみようと思った。

:::note info
日本語のプロンプト
OpenAIが開発者向けコンファレンス「DevDay」で発表された「GPTs」の利用料金について教えてください。
:::

これを投げたところ、以下の回答が出てきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/f95555e9-e61b-5e84-72e3-28d740eb7aa6.png)

GPTsではなく、GPTモデルの利用料金を書いてくれた。

### 多言語の情報もほしい
英語のプロンプトで投げたら、参照先が変わると思ったので、やってみた。

:::note info
英語のプロンプト
What are the fees for using GPTs, which OpenAI announced at the DevDay conference for developers?
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/a8238729-f475-cd49-4424-d937252038fe.png)
回答は変わらずだった。

### 回答の数を増やそう！
Google Bardみたいに、回答案を３つにしてもらえたら、その中で自分が探す情報が入っているかもと思ったので、プロンプトを作ってみた。

:::note info
日本語のプロンプト（修正）
OpenAIが開発者向けコンファレンス「DevDay」で発表された「GPTs」に関して、１つの表でまとめて作成してください。
表を作る際、以下のルールに従って作ってください。
・列の項目：参照先URLのタイトル、利用料金
・行の項目：、日本語、英語
・「日本語」は日本語で、「英語」は英語で書いてあるニュース記事を参照する
・各言語ごと３つの情報を提示する
:::

表だと見やすいので👍！
列に「参照先URLのタイトル」を書かせることで、どこから持ってきたのかが一目でわかるので、よし！
日本語ベースの記事だけではなく、英語ベースの記事からも探してちょうだいー！
あと、各言語ごと３つぐらいは欲しいなー
これでもっといい回答がもらえるかと！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/d2d8c54e-acf6-8fea-3a00-cc24ecfdc54c.png)

想定の通り、いい感じになったー！
ただ、この中でもちゃんとした料金情報は取れなかったのは残念、、
もっといいプロンプトを作る必要があると思った。

### 最後に

キーワードをAmazonの生成AIサービス「Amazon Q」に変えてみた。
だが、今回は英語の記事は参照していないし、データを２件しか取っていない。
もう少し検証が必要そうだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/41108bd0-eaa5-7171-8fbb-c21f680695fd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/4686c2e7-49fb-0688-98e0-e6a92345696f.png)
[ThoughtSpot]キーワードを使って3年度分の同月比較グラフを作成する

## はじめに
ThoughtSpot利用歴約2年。
日々ThoughtSpotのキーワードわかんねぇと泣いております。

## やりたいこと
こんな感じで、とある数値を3年度分同月比較をしたい。
これをThoughtSpotで実現させる方法になります。
![画像7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/5d935647-def3-a8bb-09ec-d8393e4777ea.png)


## 方法
まず検索バーに、比較したい数値項目と軸にした日付項目を置きます。
今回はまんま「金額」と「日付」です。

ここからこれを3年度の比較にしていくわけですが、2種類のキーワードを使います。

* 比較のためのキーワード：**vs**
* 日付指定のキーワード：**this year**,　**last year**,　**2 years ago**

今回は3年度比較なのでこのように検索バーに入力していきます。
```
this year vs last year vs 2 years ago
```
![画像8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/45ca36c4-89b8-e52e-1c64-9a656dfe2f4e.png)

そうするとあら不思議、数値項目が各年度分作成されるじゃないですか。これを凡例に表示したい順番でY軸に設定します。
![画像9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/3d4603f6-0768-66a6-2e0a-9e4357c91446.png)
（this yearとlast year逆やんけ）

あとはX軸の日付バケットを「年の月」にし、
Y軸が分かれてしまっていればすべてグループすれば冒頭のグラフの完成です。

え？
「this yearを指定しても4月はじまりにならない」？
「自分の会社は9月はじまりだ」？
そういう方はまずは[こちらの記事](https://qiita.com/shiisaa/items/371d043f9fa3c0f1dba7 "[ThoughtSpot]カスタムカレンダーを使って自由に年度や四半期表記を変更する")からカスタムカレンダーを設定してください。

## おまけ
この**vs**の書き方ですが、普通に「2021年度 vs 2022年度 vs ......」という書き方でも全然機能します。
でも年度跨いだときに自動でグラフも年度切り替わってほしい、ということがほとんどかと思うので、日付キーワードである**this year**他で表現した方が無難かと思います。
今回は**2 years ago**までしか使わなかったですが、もっと前の年度も同じ要領で表現可能です。
（このキーワード、日本語でも指定できるみたいなのですが、この記事を書いている時点で日本語キーワードを認識してくれたりしてくれなかったりなので、英語表記が無難です）

今回は純粋に同月比較しましたが、弊社ではcumulative_sum関数を使って単年での累計比較として表現することが多いです。
![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/358e0b8b-66c5-33f6-6516-99a5cdeadffa.png)

今回使っているキーワード以外にもThoughtSpotには利用できるキーワードがたくさんあります。詳しくはリファレンスを見てみてください。
https://docs.thoughtspot.com/cloud/latest/keywords

## おわりに
みなさんはどのキーワードをよく使う？
this yearもキーワードなら私は断トツで日付関係のキーワードですね。
jQueryで写真をマウスオーバーで切り替える

jQueryで写真にカーソルが当たっている間、別の写真に切り替わる（マウスを画像のそとに当てると元の画像に戻る）をする方法

・jQueryのmauseoverとmouseoutを使用する




$(function() {
    $("img").mouseover(function() {
        $(this).attr("src","./images/suisen.jpg").attr("alt","水仙");
    }).mouseout(function() {
        $(this).attr("src","./images/bouquet.jpg").attr("alt","ブーケ");
    });
});