OmniAICreator/Qiita-1.07M huggingface dataset:
watsonx.ai Runtimeのプラン変更

watsonx.ai Runtime（旧Watson Machine Learning）のプラン変更を試しました。

# プランの変更
リソースリストから対象インスタンスを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f64a3c92-d9de-7dea-3340-e5d5db19240b.png)


[プラン](https://cloud.ibm.com/catalog/services/watsonxai-runtime?catalog_query=aHR0cHM6Ly9jbG91ZC5pYm0uY29tL2NhdGFsb2c%2Fc2VhcmNoPXdhdHNvbiUyNTIwbWFjaGluZSUyNTIwbGVhcm5pbmcjc2VhcmNoX3Jlc3VsdHM%3D)を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2a6ee786-e3dd-2b72-adda-483d3cd29c56.png)

変更したいプランを選択します。
ここではEssentialからStandardに変更しています。
「保存」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/09e5396e-80a7-6dd8-b732-225e1418632b.png)


確認画面がでるので「OK」で進みます。
![{EA5E8888-7A68-4F1E-AF75-1D94889EBACD}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f6ebb7e7-c9a3-985f-ef38-15a5f87bcc15.png)

# デプロイメントの動作確認
既存デプロイメントの動作確認をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a98d9b76-8df4-7b24-96c1-b057c32eb850.png)

23日前に作成したデプロイメントです。オンラインのままになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/62eadd01-fa27-b6a9-50d4-998617623cc7.png)

実行も可能でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0e724762-4041-3de0-5295-7bc977d0103a.png)


#### 参考：価格プランの更新
https://cloud.ibm.com/docs/account?topic=account-changing&interface=ui
KotlinとJavaの相互運用例で見る Null Object パターン 

:::note info
この記事の一部は生成AIによって書かれています。
:::

普段、実装していて「なんかNullチェックせずにいい感じにしたいなあ」と言う時ありませんか？
そんな時に覚えておくと役に立つかもしれないNull Object パターンをご紹介します。

# Null Objectパターンとは？
Null Objectパターンは、nullの代わりに特定のインターフェースや抽象クラスを実装するオブジェクトを提供するデザインパターンです。このオブジェクトは「何もしない」か、もしくは安全なデフォルト動作を実装します。このパターンを使うことで、nullチェックの煩雑さを減らし、コードの可読性を向上させることができます。

# 実装例

実装例を示して説明していきます。（本筋じゃないところは説明省いてます :bow: )

## Null Objectパターンを使用しない例

例として以下のような実装があったとします。

### 何かのイベント処理を実行するクラス

```kotlin
interface EventExecutor {
    fun execute()
}

class SomethingExecutor: EventExecutor {
    override fun execute() {
        println("Execute something!")
    }
}

```

### Eventに対応するEventExecutorを返すクラス

Event定義など細かいところは割愛しています


```kotlin
class EventExecutorFactory {
    companion object {
        @JvmStatic
        fun create(event: Event?): EventExecutor? {
            return when(event) {
                is Something -> SomethingExecutor()
                else -> null
            }
        }
    }
}
```

### 呼び出す

#### Kotlin

KotlinだとNull安全があるので、`?.`でNullじゃない場合に`execute()`を呼び出します。

```kotlin
fun doSomething(event: Event?) {
    EventExecutorFactory.create(event)?.execute()
}
```

#### Java

Kotlinだと簡素にかけますが、Javaとの相互運用が必要でJavaからこのコードを呼び出すとこんな風になります。

```java
void doSomething(Event event) {
    EventExecutor executor = EventExecutorFactory.create(event);
    if(executor != null) {
        executor.execute();
    }
}
```

nullチェックを忘れるとぬるぽ(`NullPointerException`)が発生する恐れがあります。（まあ、ただIDEが警告で教えてくれたりします。）

## Null Objectパターンを使用する例

### Null Objectを実装

`NoopExecutor`という何もしないクラスを実装します。

```kotlin
class NoopExecutor: EventExecutor {
    override fun execute() {
        // noop
    }
}
```

### EventExecutorFactoryを修正

`EventExecutorFactory.create`のnullを返していたところをNoopExecutorを返すように修正します。

```kotlin
class EventExecutorFactory {
    companion object {
        @JvmStatic
        fun create(event: Event?): EventExecutor {
            return when(event) {
                is Something -> SomethingExecutor()
                else -> NoopExecutor()
            }
        }
    }
}
```

### 呼び出し側を修正

`EventExecutorFactory.create`がnonNullになったのでNullチェックが不要になります。

#### Kotlin
```kotlin
fun doSomething(event: Event?) {
    EventExecutorFactory.create(event).execute()
}
```

#### Java

```java
void doSomething(Event event) {
    EventExecutorFactory.create(event).execute();
}
```

Nullチェックが不要になりスッキリしました。
呼び出し元が複数ある場合には、複数箇所でNullチェックがあると辛いですが、Null Objectパターンを使うと呼び出し元がNullかどうか意識しなくて済みます。

# まとめ

Null Object パターンのご紹介でした。

KotlinがNull安全かつ簡素にかけるのでそこまで利用シーンないかもしれませんが、Javaとの相互運用が必要だったり、Nullチェックしたくないなと言う時など、覚えておくと役に立つかもしれません。
クリエーションラインの長期インターンに参加しました

こんにちは、てつすけです！8月中旬から12月末の間、株式会社クリエーションラインにて長期インターンシップに参加させていただいています。

本記事では、長期インターンシップを通じて学んだことや感じたことを書いていきます。

# クリエーションラインについて

株式会社クリエーションラインは、「IT技術によるイノベーションにより顧客と共に社会の進化を実現する」をビジョンに掲げている会社です。より詳しく説明されている記事があるので気になった方は見てください。

https://qiita.com/k-yoshinobu/items/414fb1330d5a4d91ee3a

# インターンに参加した理由

学生コミュニティでのチーム開発や、システム開発のアルバイトを通じて、フィードバックをもらえる環境で実務経験を積みたいと強く思うようになりました。

そんな中、在学中の高専の先生に相談したところ、「教え子にアジャイル開発の会社でCTOを務めている [荒井康宏さん](http://twitter.com/kimotuki) という方がいる」と教えていただき、そのご縁でクリエーションラインを知ることになりました。

はじめは、Web開発に携わるつもりで応募しましたが、カジュアル面談の中で生成AIの研究開発に参加できると伺い、このチャンスを逃すわけにはいかないと感じ、インターンシップに参加することを決めました。

# 生成AIについて理解を深める

ChatGPTやGitHub Copilotを使ったことはありましたが、生成AIについてあまりは知りませんでした。

## SITUATIONAL AWARENESS

これまでとこれからのAIについて理解を深めるために、OpenAIの元研究者Leopold Aschenbrenner氏が書いたエッセイを読み、その要約から始めました。

このエッセイを通じて、スケール則によってLLMが賢くなったこと、エージェントとして活用するために必要な要素、そしてLLMのこれからの発展について大まかに学ぶことができました。

ただ、読み進める中で書いてある内容をそのまま鵜呑みせず、自分なりの視点を持つことの重要性を改めて感じました。

https://situational-awareness.ai/

## Dify.AIでLLMの基本に触れる

ノーコードでチャットボットやコンテンツ生成ができるDifyを使用して、検索ワークフローやTwitter投稿の要約ワークフローを作成するこで、LLMの基本に触れました。

ノーコードで実装できることから学習コストが低く、LLM入門としては良いサービスだと感じました。しかし、複雑な処理を実装するのが難しいため、慣れてくるとコードで実装したいと思うようになりました。

![スクリーンショット 2024-12-18 23.55.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629113/9539fc3f-ba04-a5d7-7cb4-0be04a89204c.png)


# 最前線で実践

インターンシップというと、自社プロダクトや社内システムの開発をイメージしがちですが、今回は顧客先の新規プロジェクトに参加させていただき、とても印象に残りました。お客様に近い場所で実務を経験できたことは、貴重な学びになりました。

## 新たに学んだ技術

### LangGraph (+ LangChain)

ワークフロー形式とエージェント形式どちらとも実装する必要があったので、LangGraphを利用しました。ステートマシンを用いて構築できるため、構造を理解しやすいと感じました。

https://www.langchain.com/langgraph

### LangFuse

プロンプトのバージョン管理や、トレースを管理できるOSSのLLM Engineering Platformです。LangFuseを使うことで、LLMアプリケーションには欠かせない機能の実装工数を減らすことができました。

https://langfuse.com/

## AI駆動開発 (AI-Driven Development)

VS CodeにAIを組み込んだCursorや、プロトタイピングツールのBolt.newを、積極的に利用して開発工数を減らしました。

https://www.ai-driven.dev/

### Cursor Composer

Cursor Proプランを契約して、APIにAnthropic Claude 3.5 Sonnetを利用しました。
実際にCursor ComposerとGitHub Copilot Editsを試したところ、現時点ではCursor Composerの方が開発者体験において優れていると感じました。その理由は、Cursor Composerは、既存のReactコンポーネントを明示的にコンテキストに入れなくても、コードベース全体を把握して再利用していたからです。

https://www.cursor.com/

### Bolt.new

StackBlitz社が提供するサービスで、 AIエージェントと共に、ブラウザから直接フルスタックアプリケーションを構築・デプロイができます。自然言語でイメージしたUI/UXをすぐに構築できる点が、Bolt.newの強みだと感じます。
Bolt.newでUI/UXを作成した後は、Cursorを活用してバックエンドの実装やリファクタリングを行い、仕上げていきました。

早い段階でお客様に動くものを見せることで、認識ズレを解消できるため、Bolt.newは非常に役立ちました。

https://bolt.new/

この画面は、Bolt.newのトライアルとして20分ほどで作成した勤怠管理アプリです。

(本プロジェクトとは関係ありません。)

![スクリーンショット 2024-12-19 0.42.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629113/0aa23056-f27e-2e0f-e8bd-50d4c544c4c7.png)

## インターンシップのサポート体制

定例ミーティングやCTO、人事の方との1on1など、充実したサポート体制が整っていました。
初めての経験も多く、当初はプレッシャーを感じることもありましたが、1on1で相談しながら現状を整理することで、気持ちがかなり楽になりました。

## 意識したこと

限られた時間を有効に活用するために、WeeklyとDailyの目標設定を意識して取り組みました。
それぞれの目標を設定することで、タスクの優先順位を明確にし、モチベーションを高く維持することができました。

# おわりに

クリエーションラインの長期インターンシップに参加して、非常に貴重な体験を得ることができました！
コンフォートゾーンを抜け出すのは大変ですが、その分、大きく成長できたと感じています！
開発環境データベース（ MariaDB ）の複製手順【忘備録】

# 概要
開発環境のデータベースを別環境に複製する作業手順をまとめました。この手順は、開発環境の検証や並行開発のために新しい環境を作成する際に役立ちます。
# 環境
MariaDB 10.x
OS: Linux/Windows
対象データベース：開発環境DB（dvlp0001）→ 検証環境DB（dvlp_new__0001）
# 1. データベースの確認
まず、既存のデータベース一覧を確認します：
```bash:Bash
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| dvlp               |
| dvlp0001           | # 複製元の開発環境DB
| dvlp_new           |
| dvlp_new__0001     | # 複製先の検証環境DB
| information_schema |
+--------------------+
```
# 2. 開発環境DBのダンプ作成
```bash:Bash
mysqldump -u [username] -p dvlp0001 > dvlp0001_dump.sql

```
# 3. 検証環境DBのバックアップ（安全のため）
```bash:Bash
mysqldump -u [username] -p dvlp_new__0001 >  dvlp_new__0001_backup.sql

```
# 4. 開発環境DBのデータを検証環境DBへインポート
```bash:Bash
mysql -u [username] -p dvlp_new__0001 < dvlp0001_dump.sql

```
# 注意事項
- 実行前に必ずバックアップを取得してください
- 複製先の既存データは上書きされます
- テーブル構造の違いがある場合、エラーが発生します
- 大規模なデータベースの場合、処理に時間がかかります
- 実行権限の確認を行ってください

# 所感
矢印の向きが図的で分かり易い。
- A　<　B　A に B を入れる
- A　>　B　A を B に出す
共に成長する場をつくる輪読会

# はじめに
この記事は [アイスタイル Advent Calendar 2024](https://qiita.com/advent-calendar/2024/istyle) 21日目の記事です。  
こんにちは。アイスタイルでアットコスメストアの開発をしている大村(omuram)です。
本記事では、チーム内で開催している輪読会について紹介します。

# 輪読会開催の背景 
下記が開催に至った背景です
- 会社全体としてシステムのクラウド化や刷新などの新しい挑戦を進めているため、常に新しい知見を取り入れ続ける必要がある。
- チームとしてインプットとアウトプットの習慣を形成し、専門知識の蓄積と共有を促したい  
- 技術的関心領域や学習対象のすり合わせを行うことで、チーム全体の足並みを揃えやすくする

運営方法や輪読会フォーマットは下記を参考にさせてもらってます。
- [輪読会でチームを強くする](https://qiita.com/ShingoYadomoto/items/446570c2648f35f2a73a)  
- [有意義な輪読会を開催し続けるコツ](https://techblog.lycorp.co.jp/ja/20231209a)

# 進め方
**「事前に読んでくる + ディスカッション方式」** で開催しています

具体的な流れ
- **事前準備**: 当日までに指定された範囲を各自が読み込む  
- **疑問点の整理**: 読書中に浮かんだ疑問点や不明点、興味深い点をあらかじめ用意された輪読会フォーマットに記入  
- **当日の進行**: 輪読会では参加者が疑問点を持ち寄り、意見交換や共有を行う。モデレーターは進行をサポートする  
- **記録**: 議論で得られた知見や回答は随時フォーマットへ加筆し、後から参照可能なナレッジとして残す
 
輪読会のフォーマット記入例
![スクリーンショット 2024-12-15 22.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736630/9c43dab5-1705-013b-3b3a-19e35af5407c.png)


その他運用面  
- **頻度**: 原則として週1回に1回程度開催  
- **時間**: 1回あたり1時間
- **参加自由度**: 任意参加（興味のある本のみの参加でもOK）

# 気をつけているポイント
- **リアル開催**: チームの出社日があるのでその日に開催。可能な範囲でオフィスに集まることで、雑談的な質問や自然な対話を促進
- **1回で扱うページ数**: ページ数は比較的多めを意識しています
理由としてはLINEヤフーさんの「なるべく1冊を早めに読み切る」とほぼ同じ理由です。
> 輪読会は、積んでしまった技術書を読み切るのには最適の場です。モチベーションを保ちながら続けるためには、なるべく1冊を早めに読み切るのがいいでしょう。 
引用：https://techblog.lycorp.co.jp/ja/20231209a

読み切ることが目的ではないですが、読み切ることで得られる達成感は大事だと思っています。
（私自身プライベートで輪読会を行なった際にも時間をかけすぎてしまって、モチベーションが低下しました...）
- **積極的な意見交換ができる雰囲気作り**: 感想や疑問点、異なる視点を歓迎し、情報をオープンに共有できる空間を意識する。

# 最後に
輪読会は、単なる読書ではなく、チーム内での知見共有や問題解決の場として機能します。  
今後も継続的に実施し、改善を重ねることで、チーム全体の学習速度や知識の深さを高めていくことを目指しています。  
それでは良いお年を。
【Bootstrap v5】ポップオーバーとツールチップの機能に複雑なHTML構成が対応できず問題

:::note warn
ポップオーバーとツールチップの機能は、Bootstrap v5.3.2に組み込まれていますが、複雑なHTML構成（入力項目を含むフォームなど）に関しては、うまく対応できていない問題があります。
⇒inputタブを入れてもPopが表示された最後、無くされている問題など

そのため、カスタマイズ開発した共通部品を利用するほうが良いかと思います。
:::
Blender 動画　備忘録

役に立ったBlenderの動画教材を残しておく
Youtubeの後で見るから削除したいのでこちらに記載する
適宜必要な動画は追加を行う


### Create Magical Particle Animation in Blender EEVEE

https://www.youtube.com/watch?v=2ZuwsOTA7-I&list=WL&index=101

### Tutorial: How to Create Robotic Arms in Blender (Part 1)

https://www.youtube.com/watch?v=-2HCxy4Kh4E&list=WL&index=100

### 【blender初心者】無料アドオンArchimeshで部屋作る

https://www.youtube.com/watch?v=yzyE7VU6zdc&list=WL&index=84

### Blender Crown Modeling Tutorial

https://www.youtube.com/watch?v=46L4t6PqDco&list=WL&index=85

### Gold material in Blender

https://www.youtube.com/watch?v=MFVuo9HsSG0&list=WL&index=86

### Create Ornaments in Blender in 1 Minute!

模様の作り方がわかる
壺や造形に繊細な模様を付けることができる

https://www.youtube.com/watch?v=dRucEKGmVHo&list=WL&index=87

### From Concept to Reality: Modeling a Gold Ring in Blender

指輪の作り方がわかる
特に細かな細工の作り方については勉強になる

https://www.youtube.com/watch?v=z8w8wMbpXVE&list=WL&index=88

### Simple DRAGON Animation in BLENDER

ドラゴンの作り方とアニメーションまでが学べる

https://www.youtube.com/watch?v=DDuJLH75KwU&list=WL&index=89

### Create a Combat Knife in Blender in 1 Minute!

非情に手早くナイフの作成ができる

https://www.youtube.com/watch?v=moGDjnZXUA4&list=WL&index=90

### Create a Castle in Blender in 1 Minute!

城作りに便利なツールについて学べる

https://www.youtube.com/watch?v=-aLOOitN6kY&list=WL&index=91

### #01 Blender Pythonで作る「俺たちのAddon」企画＆準備編

アドオンの作り方について学べる

https://www.youtube.com/watch?v=E9Oihsgexio&list=WL&index=92

### 【Blenderチュートリアル】車輪とキャタピラの連動アニメーション

Driverを利用したアニメーションが学べる
キャタピラの作り方も知れるのでその用途でも便利

https://www.youtube.com/watch?v=_04rCh1tsYo&list=WL&index=93

### Abstract 3D Design - Blender 3D Tutorial

不思議な造形の作り方が学べる

https://www.youtube.com/watch?v=J3w1T9fxtP4&list=WL&index=96

### Create A Living Parasite Effect With Geometry Nodes (Blender Tutorial)

Geometry Nodesを利用した不思議なアニメーションが作れる
　
https://www.youtube.com/watch?v=t61gMdBXjQw&list=WL&index=97

### Sci-fi style Geometry Nodes Modeling in Blender 3.0 & Eevee

Geometry Nodesを利用した石のような造詣のアニメーションが作れる

https://www.youtube.com/watch?v=LgQSBcKwUCM&list=WL&index=98

### Make Abstract Models with Geometry Nodes

Geometry Nodesを利用したバリアのような球体のアニメーションが作れる

https://www.youtube.com/watch?v=K5eNdCpoRD4&list=WL&index=99

drive機能を利用したアニメーションの作り方

https://youtu.be/uNnLfrgp-u0?feature=shared
usonについて

μson (uson)はシェルのために特別に設計された、人間が読めるコンパクトなデータシリアライゼーションフォーマットです。

https://github.com/burningtree/uson

以下の特徴を持ちます。

- JSONの上位互換
- ホワイトスペースはパース結果に影響を与えません
- 文字列を `"` でクォートすることはオプションです
- 配列の区切りの `,` はホワイトスペースで代替できます
- コロン `:` を繰り返すことでネストしたオブジェクトを表現できます
- カスタムデータ型をしようでき、`!` でキャストできます

# 例
以下のUSONオブジェクトは、

```
endpoint:id:wikipedia pages:[Malta Prague "New York"]
```

JSONではこの用に表現されます。

```
[
  {
    "endpoint": {
      "id": "wikipedia"
    }
  },
  {
    "pages": [
      "Malta",
      "Prague",
      "New York"
    ]
  }
]
```

# サポートされている型
USONは以下の型を持ちます

- false
- null
- true
- array
- object
- number
- string

## 基本的な型
基本的な型の例を示します。

```
number:12.05 text:Banana quotedText:"John Devilseed" empty:null good:true
```

このUSONは以下のJSONと同等です。

```
{
  "number": 12.05,
  "text": "Banana",
  "quotedText": "John Devilseed",
  "empty": null,
  "good": true
}
```

## 配列型
`[]` で囲むことで配列を表現できます。

```
simple:[1 2 3] texts:[Malta Budapest "New York"] objects:[{id:1}]
```

```
{
  "simple": [
    1,
    2,
    3
  ],
  "texts": [
    "Malta",
    "Budapest",
    "New York"
  ],
  "objects": [
    {
      "id": 1
    }
  ]
}
```

## オブジェクト型

```
obj:{name:John} {nested:[{id:42} value:"Nagano"]}
```

オブジェクト型の表現には `{}` を使います。

```
{
  "obj": {
    "name": "John"
  },
  "nested": [
    {
      "id": 42
    },
    {
      "value": "Nagano"
    }
  ]
}
```

## ネストしたオブジェクト
コロン `:` を繰り返すことでネストしたオブジェクトを表現できます。

```
cities:eu:hu:budapest:Budapest
```

```
[
  {
    "cities": {
      "eu": {
        "hu": {
          "budapest": "Budapest"
        }
      }
    }
  }
]
```

## キャスト
!を使ってキャスト表現できます。例えば、以下は文字列型の42を表しています。

```
str!42
```

## コメント
`#` から行末まではコメントとして扱われます。

```
array:[1 2 3] # this is comment
```
ブラウザによるポップアップブロック機能について

ブラウザによって、JavaScriptが動作したりしなかったりすることがあります。
今回は、`window.open()`メソッドを使用した際にうまく動作しなかったため、調べたことをまとめます。

## 原因
ポップアップブロッカーが有効になると、ポップアップが制限されます。
ブラウザは、ユーザーの意図しないポップアップと判断し、ブロックします。
ユーザーが許可しない限り、ユーザーのアクションなしでポップアップを開くことはできません。

Chrome:Chromeでポップアップをブロックまたは許可する

https://support.google.com/chrome/answer/95472?hl=ja&co=GENIE.Platform%3DDesktop

Safari:Safariでポップアップ広告やポップアップウインドウをブロックする

https://support.apple.com/ja-jp/102524

Firefox:ポップアップブロックの設定とトラブルシューティング

https://support.mozilla.org/ja/kb/pop-blocker-settings-exceptions-troubleshooting

## Window.open()メソッドとは
`window.open()`メソッドは、JavaScriptで新しいブラウザウィンドウまたはタブを開くためのメソッドです。このメソッドを使うことで、指定した URL を新しいウィンドウやタブで表示したり、ポップアップウィンドウを開いたりできます。

使い方
```js
window.open('https://example.com', '_blank');
```

https://developer.mozilla.org/ja/docs/Web/API/Window/open


## うまく動作する時
### ボタンの要素を取得して、取得したボタンがクリックされた時に、別タブに遷移する
※HTMLファイルにコピーして動作確認できます。
```html
<script>
    document.addEventListener('DOMContentLoaded', (event) => {
		const button = document.getElementById('openWindow');
        button.addEventListener('click', function () {
            window.open('https://example.com', '_blank');
        });
    });
</script>
<button id="openWindow">Open example</button>
```

`document.addEventListener('DOMContentLoaded', (event) => {}`を記述する理由は、以下の記事にまとめています。

https://qiita.com/engsekine/items/dab6adb7f7ce8da7c1b0


## うまく動作しない時
### ページが読み込まれた後に、そのまま別ページに遷移させようとする
ブラウザが、ユーザーが意図しないポップアップと判断してブロックします。
※HTMLファイルにコピーして動作確認できます。
```html
<script>
    window.open('https://example.com', '_blank');
</script>
```

### 非同期で取得した値をURLに付け加えて遷移させようとする時
ブラウザの仕様によって、遷移が失敗する
※google chromeでは成功するが、safariでは失敗する
※HTMLファイルにコピーして動作確認できます。
```html
<script>
    document.addEventListener('DOMContentLoaded', (event) => {
        const openWindowUrl = 'https://example.com';
		async function getToken() {
            return new Promise((resolve) => {
                setTimeout(() => {
                    // 適当な文字列を生成する
					const random = Math.random().toString(32).substring(2);
					const openWindowUrlWithToken = openWindowUrl + `?token=${random}`;
					// トークンを含めたURLを返す
					resolve(openWindowUrlWithToken);
				}, 999);
			});
	}

	document.getElementById('openWindowGeneratedUrl').addEventListener('click', async function () {
        const generatedUrl = await getToken();
        window.open(generatedUrl, '_blank');
		});
	});
</script>
<button id="openWindowGeneratedUrl">Open example generated url</button>
```

Reactでこのような実装は注意が必要です。
※こちらはHTMLファイルにコピーしても動作しません。
```js
const openWindowGeneratedUrl = async () => {
const openWindowUrl = 'https://example.com';
    try {
        const { auth_token } = await getToken();
        const generatedUrl = `${openWindowUrl}?token=${auth_token}`
        window.open(generatedUrl, '_blank');
	} catch (err) {
        console.error(err);
	}
};
openWindowGeneratedUrl();
```

## まとめ
`window.open()`メソッドを使って、別タブで外部サイトを開く時に使いたい時があります。
しかし、ユーザーがポップアップを許可していない場合や、ブラウザによって動作しないことがあるため、注意が必要です。
別タブではなく同じタブで開く、またはボタンを押したタイミングで別タブに遷移するなどの実装方法を検討する必要があります。
【Forge1.19.4】マイクラMod開発 進捗追加方法

どうもAtsu1209です。
今回はマイクラのModを作ります。
今回つくるModは進捗を追加するModにしようと思います。
なお環境構築はいろいろな方が構築方法を解説しているので、そちらをご覧ください

# 環境
intelliJ idea
Forge 1.19.4

# 作りたいMod
今回は、「錆止めされた酸化した切り込み入りの銅のハーフブロックを取得する」という
進捗(挑戦)を追加したいと思います。
名前はWoccsMod(WaxedOxidizedCutCopperSlabModの略)

# 進捗の追加方法
1.19.4での進捗追加方法はとても簡単で、jsonだけで追加できます。
まずは`root.json`を追加して、進捗タブに「WoccsMod」を追加します。

```json:root.json
{
  "display": {
    "icon": {
      "item": "minecraft:copper_block"
    },
    "title": "WoccsMod",
    "description": "錆止めされた酸化した切り込み入りの銅のハーフブロックModの始まりだ",
    "background": "minecraft:textures/block/copper_block.png",
    "show_toast": false,
    "announce_to_chat": false
  },
  "criteria": {
    "root": {
      "trigger": "minecraft:tick"
    }
  }
}
```
・`icon`の`item`で、進捗のWoccsModタブのアイコンを銅ブロックに指定
・`title`でタブの表示名を`WoccsMod`に
・`description`で、説明を追加
・`background`で進捗タブ`WoccsModの背景画像を指定`
・`trigger`でトリガーをティックが読み込まれたときに設定

次に本題のJsonを追加します。
```json:woccs.json
{
  "parent": "woccsmod:cut_copper_slab",
  "display": {
    "icon": {
      "item": "minecraft:waxed_oxidized_cut_copper_slab"
    },
    "title": "ん? なんて? もう一回いって?",
    "description": "錆止めされた酸化した切り込み入りの銅のハーフブロックを手に入れる",
    "frame": "challenge",
    "show_toast": true,
    "announce_to_chat": true,
    "hidden": false
  },
  "criteria": {
    "long_long": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "items": [
              "minecraft:waxed_oxidized_cut_copper_slab"
            ],
            "count": {
              "min": 1
            }
          }
        ]
      }
    }
  }
}
```

参考サイト↓↓↓

https://minecraft.fandom.com/ja/wiki/%E9%80%B2%E6%8D%97/JSON%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88

# 最後に
これを少しパワーアップさせたModを配布しているのでぜひ使って見てください。

https://github.com/Atsu1209/WaxedOxidizedCutCopperSlabMod/releases
AWS　クラスルームトレーニングを受講してみた感想

先日、会社の制度を用いてAWS研修を受けてみました。
受講前に色々調べたもののユーザ視点の情報がなかったため、
AWS クラスルームの雰囲気や研修内容についてお話しできればと思います。
## 受けた時の状況
SAA取得
業務で一年弱AWSは触っている
調べながら使えはするもののちゃんと理解があるかと言われると微妙。
勢いでAdvancedのクラスを受けてしまったが大丈夫か...と思っていました。
→講師の方が丁寧に解説して頂いて、思ったより理解できる内容で非常にタメになりました。
## AWSクラスルームとは
AWSが公式に提供するトレーニングプログラムの一環です。
•クラスルームトレーニング:プロの講師が教える集合型またはバーチャル型トレーニング。
•自己学習: オンラインコースで、自分のペースで学べる教材を提供。
•ハンズオンラボ: AWS環境で実際にスキルを練習
## 受講手順
1. 受講したいクラスルームを探す([参考](https://www.aws.training/LearningLibrary?query=&filters=Language%3A2%20DeliveryFormat%3A0&from=0&size=15&sort=_score))
2. 複数日程あるので日時を選ぶ
3. 支払い
4. 事前準備の資料がメールで送られるのでそれに従って準備
　自分はWebexのインストール/bookshelfのアカウント作成などを行いました
## 研修について
自分が受講したコースはAdvanced Architecting on AWSでした
受講期間については下記です。
3日間　9:30 ~ 17:30

また研修中の決まりとして下記が定められていました
- チャット
 質問や不明点ができたタイミングで投稿してOK
 基本は「全員」宛で送信
- カメラとマイク
 基本オフでした
 口頭で質問したい場合はオンでも問題ないらしいです
- その他
 軽食なども特に気にせずリラックスして受けてくださいと指示がありました
 体調や業務による長時間の離席は、講師にご連絡する必要があります
 短時間の離席の場合には特にご連絡いただく必要はありません
 コースの修了には 2/3 以上の出席が必要
## 研修内容
今後、復習も兼ねて取り扱った内容についての記事を投稿して行きたいと思います

<details><summary>復習も兼ねた備忘録</summary>

</details>

主に大規模で複雑な構築を、最適なソリューションで行うための知識を身につける
といったことが目的とされているようです
- モジュール
講義形式で講師の方が構築の方法などを丁寧に解説してくれました。
- ラボ
ハンズオンを用いて実際に課題に取り組んでそのあと講師の方からの解説を聞いて復習を行いました
- ワーク
参加者個人がAWSでアーキテクティングしてきた中で陥った課題の共有とそれに対するソリューションを考えてチャットで共有しました。


 


## 感想
受講前は正直Advancedという名前に怯えていましたが、受けてみると割と理解できる内容かつ実践できそうな内容が非常に多くとてもタメになりました。AWS認定試験を受験するという目的だと少し内容が少ないような気もしますが、実際の業務にはかなり役立つ知識が多かったです。

特にラボで実際にECRやECSを使ったりなど、普段の業務では使わないリソースも触れたので、知識として知っていたものの解像度を上げることができました。
JavaScriptの読み込みがうまく行かない時に試すこと

取得したDOMに対して、ハンバーガーメニューやアコーディオンなど、クリック時に何らかの動作を実行したい場合があります。
JavaScriptに不慣れな方は、コードをそのままコピペしても動作しない理由がわからないことがあるかもしれません。
今回は、HTMLに`<script>`タグでJavaScriptを読み込む時に、`document.addEventListener('DOMContentLoaded', (event) => {}`を追加する理由をまとめます。

## DOMContentLoadedとは？
`DOMContentLoaded`は、HTMLドキュメントの初期の読み込みが完了したことを示すイベントです。
HTMLが生成された後に、DOMを取得する時に使います。
`<script>`タグをDOMの前に置いた時に、`DOMContentLoaded`を追加しない場合、buttonタグが生成される前に JavaScriptが読み込まれるため、エラーが発生します。

比較するために以下のコードをHTMLにコピペして確認してみてください。

```
<!-- 動作するコード -->
<script>
    document.addEventListener('DOMContentLoaded', (event) => {
        const successButton = document.getElementById('success_button');
        successButton.addEventListener('click', function () {
            // 動く
		    console.log('Success button');
		});
    });
</script>
<button id="success_button">Success button</button>
<!-- 動作するコード -->

<!-- 動作しないコード -->
<script>
    const failButton = document.getElementById('fail_button');
    failButton.addEventListener('click', function () {
        // 動かない
        console.log('Fail button');
	});
</script>
<button id="fail_button">Fail button</button>
<!-- 動作しないコード -->
```

動作するコードでは、ボタンに機能を追加するコードが`document.addEventListener('DOMContentLoaded', (event) => {}`の中に書かれているため、DOMが生成された後に実行されます。
動作しないコードでは、基本的にプログラムは上から下に実行されるため、ボタンに機能を追加するコードが先に実行され、ボタンが見つからないとエラーが発生します。

### DOMContentLoadedを使わない方法
基本的にプログラムは上から下に実行されるため、DOMの要素を先に書けば、正常に動作します。

比較するために以下のコードをHTMLにコピペして確認してみてください。
```
<!-- 動くコード -->
<button id="success_button">Success button</button>
<script>
    const successButton = document.getElementById('success_button');
    successButton.addEventListener('click', function () {
        // 動く
		console.log('Success button');
	});
</script>
<!-- 動くコード -->

<!-- 動かないコード -->
<script>
    const failButton = document.getElementById('fail_button');
    failButton.addEventListener('click', function () {
        // 動かない
        console.log('Fail button');
	});
</script>
<button id="fail_button">Fail button</button>
<!-- 動かないコード -->
```

`document.addEventListener('DOMContentLoaded', (event) => {}`がなくても動作します。
ただし、`<script>`タグは、DOMの読み込みよりも上に書かれることが多いため、`DOMContentLoaded`を追加した方が良いでしょう。

## まとめ
コピペしたコードがうまく動作しない場合は、試してみてください！
Hotwire初心者におすすめの記事やコンテンツを集めてみた

## はじめに

2024年12月18日に開催された「[Hotwire.love meetup Vol.39](https://hotwire-love.connpass.com/event/339194/)」で、「Hotwire初心者におすすめの記事やコンテンツを教えてください」という質問が挙がりました。

この記事ではその質問に対して経験者のみなさんから紹介されたオススメの情報源を紹介します。

## 猫でもわかるHotwire入門 Turbo編

https://zenn.dev/shita1112/books/cat-hotwire-turbo

- 一番わかりやすい
- これを見ながら最初から順番に手を動かすのがよい
- Railsを前提としているので、Railsプログラマには特におすすめ
- 最終更新日が2022年なので若干情報が古いが、基本的な考え方は大きく変わっていないはず

## Hotwireの公式ドキュメント

https://hotwired.dev/

- 公式ドキュメントも当然チェックすべし
- ただし、**公式ドキュメントの説明はRailsを想定していない点に注意**（Hotwire自体はJSのフレームワークであり、バックエンドはRailsでもPHPでもなんでもよいため）
- 例：サンプルコード上は`<turbo-frame id="message_1">`のようなプレーンなHTMLが書かれているが、Railsなら`turbo_frame_tag`ヘルパーを使うはず

## turbo-railsのREADMEやソースコード

https://github.com/hotwired/turbo-rails

- Railsプログラマは公式ドキュメントとturbo-railsの両方をチェックしよう
- turbo-rails自体はREADME以外の公式ドキュメントはないが、シンプルなライブラリなのでコードを見るだけでもだいたい把握できるはず（viewやcontroller用のヘルパーメソッドがメイン）
- チェックすべきコードの例: [DriveHelper](https://github.com/hotwired/turbo-rails/blob/v2.0.11/app/helpers/turbo/drive_helper.rb)
- `dom_id`メソッドで`message_1`のようなidを自動的に作ってくれたりするので便利

## Railsの公式YouTubeチャンネル

https://www.youtube.com/@railsofficial

- ちょくちょくHotwire関連の動画がアップされたりする
- 基本的には英語だが、Rails Worldの講演動画は日本語訳が付いている

## Hotwire Weekly (メルマガ）

https://hotwire.io/newsletter

- 最新の動向を知りたいならメルマガを購読すると良い（無料）

## 万葉さんの「Hotwireことはじめ」
https://note.com/everyleaf

- 「Hotwireことはじめ」という入門記事がいくつか投稿されている

## Hotwire.love （オンライン勉強会）

https://hotwire-love.connpass.com/

- 記事ではありませんが、Hotwire.love は初心者さんの参加や質問を大歓迎しています。何か困ったことがあればいつでも相談しに来てください！
- 毎月第3 or 第4水曜日にオンライン開催しています

## まとめ
というわけで、この記事ではHotwire初心者におすすめの記事やコンテンツを紹介してみました。

これからHotwire (Turbo/Stimulus)を始めようとしている人はここで紹介した情報源をぜひチェックしてみてください！（Hotwire.loveにも遊びに来てね❤️）
nvmでNodeのバージョン管理をしよう[mac] 

nodeのバージョンを切り替える必要があり、nvmを使ってみようと思ったので、その際に調べたnvmの使い方をまとめておこうと思います。

# nvm
nvm(node version manager)はNode.jsのバージョン管理ツールです。

使用パッケージやライブラリによってはある一定のNodeのバージョンでないと動作しない時があり、そのような時に簡単にNodeのversionを変更できるツールです。

# インストール
```zsh:zsh
brew install nvm
```

```zsh:zsh
Please note that upstream has asked us to make explicit managing
nvm via Homebrew is unsupported by them and you should check any
problems against the standard nvm install method prior to reporting.

You should create NVM's working directory if it doesn't exist:
  mkdir ~/.nvm

Add the following to your shell profile e.g. ~/.profile or ~/.zshrc:
  export NVM_DIR="$HOME/.nvm"
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion
```

フォルダを作ります。

```zsh:zsh
mkdir ~/.nvm
```

nano等でzshrcにパスを記載します。
```zshrc
export NVM_DIR="$HOME/.nvm"
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion
```

設定を反映させます。
```zsh:zsh
source ~/.zshrc
```

# インストールできるversionを確認する

`ls-remote`を使うと、nvmでインストール可能なバージョンを確認できます。

```zsh:zsh
nvm ls-remote
```

下のようにインストール可能な一覧を確認できます。
```zsh:zsh
       v20.17.0   (Latest LTS: Iron)
        v21.0.0
        v21.1.0
        v21.2.0
        v21.3.0
        v21.4.0
        v21.5.0
        v21.6.0
        v21.6.1
        v21.6.2
        v21.7.0
        v21.7.1
        v21.7.2
        v21.7.3
        v22.0.0
        v22.1.0
        v22.2.0
        v22.3.0
        v22.4.0
        v22.4.1
        v22.5.0
        v22.5.1
        v22.6.0
        v22.7.0
        v22.8.0
        v22.9.0
```

# 特定のversionをインストールする

特定のversionをインストールするときは`install`コマンドを使用します。
例えば`v18.20.4`をインストールする時は、下のように行います。

```zsh:zsh
nvm install v18.20.4
```

nvmで設定したnode.jsのversionは、馴染みのあるnodeの`--version`で確認します。
```zsh:zsh
node --version
```

nvmインストールされたversionが自動的に適応されます。
```zsh:zsh
node --version
v18.20.4
```


# バージョン切り替え

`npm install`で下のような表示が出た場合は、nodeのverを切り替える必要があると思います。
```zsh:zsh
Expected version: v20.2.x
Got: v18.20.4
```

その場合は、`use`コマンドを使ってversionを変更します。

```zsh:zsh
nvm use v20.2
```

nodeのversion変わってると思います。

```zsh:zsh
node --version
v20.2.0
```

# nvmにあるバージョンを確認する

下のコマンドでnvmに入っているバージョンを確認します。

```zsh:zsh
nvm ls
```

下のような感じで出力されます。
```zsh:zsh
       v18.20.4
->      v20.2.0
       v20.17.0
```

# バージョンを削除する。

`v18.20.4`を削除したい時は、`uninstall`コマンドで削除します。
```zsh:zsh
nvm uninstall v18.20.4
```

下のような出力が出たら消えています。
```zsh:zsh
Uninstalled node v18.20.4
```

`ls`でも確認してみるとしっかり消えていました。
```zsh:zsh
 nvm ls
->      v20.2.0
       v20.17.0
```

Nodeでバージョンを変更したいときはぜひ使ってみてください
pandas.DataFrameの要素にindexやcolumnをプレフィックス（接頭辞）、サフィックス（接尾辞）に追加する

:::note info
これは [ZOZO Advent Calendar 2024](https://qiita.com/advent-calendar/2024/zozo) カレンダー Vol.8 の19日目の記事です。
:::

# 目的
pandas.DataFrameの要素にindexやcolumnをプレフィックス（接頭辞）、サフィックス（接尾辞）に追加する
# コード
```py
import pandas as pd

df = pd.DataFrame({'A': ["A", "AA"], 'B': ["B", "BB"], 'C': ["C", "CC"]},
                  index=['ONE', 'TWO'])
```
dfは以下のテーブルになる
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| ONE | A | B | C |
| TWO | AA | BB | CC |
## columnを接頭辞、接尾辞に追加する
接頭辞に付ける場合以下のテーブルが出力される
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| ONE | A_A | B_B | C_C |
| TWO | A_AA | B_BB | C_CC |

接尾辞に付ける場合以下のテーブルが出力される
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| ONE | A_A | B_B | C_C |
| TWO | AA_A | BB_B | CC_C |

コード
```py
# 接頭辞に付ける場合
df.columns.to_list() + ("_"+ df)

# 接尾辞に付ける場合
(df + "_") + df.columns
```
## indexを接頭辞、接尾辞に追加する
接頭辞に付ける場合以下のテーブルが出力される
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| ONE | ONE_A | ONE_B | ONE_C |
| TWO | TWO_AA | TWO_BB | TWO_CC |

接尾辞に付ける場合以下のテーブルが出力される
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| ONE | A_ONE | B_ONE | C_ONE |
| TWO | AA_TWO | BB_TWO | CC_TWO |
```py
# 接頭辞に付ける場合
(df.index + ("_" + df.T)).T

# 接尾辞に付ける場合
((df.T + "_") + df.index).T
```
社内勉強会（OAuth入門）

## はじめに

:::note info
この記事は、[リンクアンドモチベーションアドベントカレンダー2024](https://qiita.com/advent-calendar/2024/lmi)の記事です。
:::

先日、初めて社内勉強会を開催しましたので作成した資料の共有と簡単な感想を残します。
自分は普段プラットフォームチームで開発を行なっており、[モチベーションクラウドシリーズ](https://www.motivation-cloud.com/)の認証に関わる業務にも関わることが多く、「認証認可の知見を広められるのでは？」という思いからOAuthについての内容に触れています。

- 参加人数：20名程度
- 時間：30分
- 開催形式：オンライン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527942/6081aae5-9659-420a-6d09-70b0c47b974a.png)

## 資料

<iframe src="https://docs.google.com/presentation/d/1eerVwWggJiVnQaJpOWrnWlveY0iOylqfEFcS2Pi5CtA/embed?start=false&loop=false&delayms=3000" 
        frameborder="0" 
        width="640" 
        height="480" 
        allowfullscreen="true"></iframe>

## 開催してみた感想

とても反省が多かったです！

### ターゲットにしていた層への壁打ちが足りなかった。

今回の勉強会は普段の開発業務で認証認可周りの開発に関わったことのないメンバーへの入門編として資料を作成したつもりでした。
ですが、当日はどちらかというと「認証認可周りの開発経験あり」の人たちの掴みは良かったものの、ターゲットにしていた層は情報量が多過ぎて置いてけぼりにしてしまっていたと思います🙇
一発目で20人という規模で開催してしまっていましたが、最初ターゲットとしていた2~3人に対して発信。その後、わかりづらい箇所を直して大勢に発信とすればだいぶ改善できたと思います。

### 自分→参加者の一方的なコミュニケーションが多過ぎた。

資料を見て貰えばわかるのですが、ほぼ説明です。
実際に手を動かす時間を確保しておけばもっと知識が定着しやすかったと思います。
例えば自分で簡単に実装してみるとか、世の中のIDaaS製品を使ってみるとか。


### システムチックな話が多過ぎた。

勉強会後、OAuthの説明をする際にシステム的に何が嬉しいのかという話が多過ぎてイメージが掴みにくかったのではないかと感じました。
もう少し認証認可周りの話を現実のもので例えていれば導入がしやすかっただろうと。
参加者が知らない前提での資料作りは今後改善ポイントだと思います。

## おわりに

ぐだぐだ反省を書きましたが、結果的にはやって良かったと思います👍

自分の発信と学び直しの機会になりましたし、自分の説明スキルのなさを実感できました笑

勉強会は社内外に向けたアウトプット文化作りのきっかけにもなると思うので、今後も続けていこうと思います✌️
SOC報告書についてまとめておく

監査対応をしているので個人的には馴染みのあるSOC報告書について
社内向けに記事を書いたことはあるのですが、Qiitaにもまとめておこうと思います！

# SOC報告書とは
SOC（Service Organization Contro）
SOC報告書とかSOCレポートと呼ばれているもの。

SOC報告書とは、受託会社（サービスを提供している企業）における管理・セキュリティの状況を監査法人や公認会計士が客観的に評価した報告書のこと。
引用：https://biz.moneyforward.com/erp/basic/1985/

SOCレポートには1,2,3と種類がある。
**SOC1**：委託会社（サービスを利用する企業）の財務報告に関連する受託会社の内部統制を評価した内容。

受託会社が委託会社へSOC1レポートを提出し、
委託会社も監査人にSOC1レポートを提出する。
これによって個社ごとに監査対応をする必要がないので負担が減ります。

また、第三者からの評価を得ていることで、自身でちゃんとできてますよ。
と言うより信頼性も増しますね！

**SOC2**：セキュリティに重点を当てた内容。

**SOC3**：SOC2と同様の評価基準だが、簡易的で一般的に公開できる内容。

# SOCレポートにはTypeがある
Type1：内部統制のフロー（運用手順やルール）のみを見られ、評価を受けます。

Type2：内部統制のフロー＋運用を継続して出来ているかについて評価を受けます。
       運用を継続してできているかの確認のため6か月以上の評価期間となっています。



# ブリッジレターとは
SOC報告書の評価期間とお客様の会計期間のズレが生じた期間を補完する報告書。
残余保証報告やギャップレターといった記載がされていることもあるようです。

SOC報告書の評価対象期間が1~12月(2024/1~12)
委託会社の会計期間が4~3月の場合、(2024/4~2025/3)
4~12月分については2024年のSOC報告書で満たしていますが、1~3月分の評価が確認できません。
2025/1~3のブリッジレターを監査法人に提出します。
ブリッジレターには評価対象期間以降に内部統制に重要な変更の有無についての内容が記載されています。  


# おわりに
以上、ぐぐればもっと詳細書いてあるページもあるので、まとめ終わり。
もう3年前位に書いた社内向けの記事はまだSOCについて知識が浅い状態で学びながら書いていたので
「監査」って名前だけで何か堅苦しそうで内容が難しく感じたし
受託会社、委託会社、とか監査法人が、とか最初はすぐに理解できなかったな～
と記事を書いた時の気持ちを思い出して少し懐かしくなりました。
リモートワークチームにアイスブレイク「Good & New」を取り入れてみた

# はじめに
こんにちは山本です。
今回は、私の所属するチームにGood & Newというアイスブレイクをデイリー前に取り入れてみたのでその結果を共有させていただきます。

# なぜ?
はじめに、なぜアイスブレイクを導入しようとなったのかをお話します。
私たちは４人のチームで、リモート勤務です。前提として、これまで意見が言いにくい、あまり仲が良くないなどは一切なくチーム関係は良好であることをお伝えします。
一方で、業務中に一切の雑談はないため各メンバーの気持ちの部分など、業務とは少し離れた内容を話す機会がありませんでした。
以前から、雑談も取り入れていきたいと話題には出たものの、いざどうしたらいいのか困っていました。そんな時に、Good & Newを見つけちょうといいのではないかと思い導入してみることにしました。

# Good & New とは
Good & New とは簡単に説明すると、24時間以内に起きた「よかったこと（Good）」や「新しい発見（New）」チームの1人ずつ発表する取り組みです。
次のような効果があります。
- メンバー同士の相互理解が深まる
- コミュニケーションが活性化する
- 物事の見方がポジティブになる
- 脳が活性化する
- 従業員自身がポジティブな気持ちになる

以下のサイトにより詳しい内容が書かれているので見てみてください。

https://thanks-gift.net/column/communication/good-new/

# やり方（ルール）
やり方はとてもシンプルです。
- 24時間以内の、GoodまたはNewを1分以内程度で発表する

特に必要なものはありません。
私たちのチームでは、リモート用に次のルールを追加しました。
- アイスブレイク中はカメラをONにする
- 発表が終わったら、拍手のリアクションをする

# 私たちのチームで出たトピック
私たちのチームで出たトピックの例を紹介します。
- 昨日の晩御飯
- 面白かったYouTube動画
- 趣味
- 新しい言語に挑戦した

# 大切なこと
ここでGood & Newを導入するにあたって個人的に大切だと思ったことを２点共有します。
1. アイスブレイクを行う目的をチームメンバーで共有すること
これは、私が実際にチームに提案した時。一番大切にしたことです。この目的が、曖昧であったりなかったりするとなんでこのアイスブレイクを行なっているのかメンバーはわからず効果が発揮されなくなってしまいます。
2. カメラをONにして、リアクションは大きめにすること
私たちチームでは、zoomを使用しています。zoomでは、２人以上が同時に話すと他の人が聞き取りにくくなってしまいます。そのため、声を出すリアクションは極力避けられがちなのですがそれでは発表者が一方的に話しているだけで寂しい気持ちになります。そこで、カメラでリアクションをすることでより楽しいアイスブレイクにしようというものです。リアクションも小さいと伝わらないこともあるので少しオーバーリアクションでもいいかもしれません。

# 結果
チームメンバーでまとめたよかった点と課題点です。

よかった
- リモートワークなので気持ちの切り替える良いタイミングとなった
- ポジティブな気持ちで1日をスタートできた
- 新しい発見ができた
- 日本語の勉強になった（ニアショアの社員より）
- 心理的安全性も確保されより柔らかい雰囲気になった

課題と対策
- 出社の際など周りが映らないように配慮する必要がある→カメラのONは柔軟に対応する
- カメラを消すタイミングが難しい→アイスブレイク後はカメラをOFF
- 盛り上がりすぎてデイリー準備に支障がでかけた→発表時間とは別に各自の持ち時間を設定する

# おわりに
Good & Newはチーム結成直後や新たなメンバーが参加した際にもおすすめですし、すでにチームとして稼働してしばらくたっていてもマンネリ化を解消する良い機会になると感じました。
私たちチームでは、率先して雑談を始めるメンバーがいなかったので、そういったチームでは雑談をする良いきっかけになりと思います！
バウンディングボックスでOpenStreetMapデータ部分的に抽出する

# はじめに
OpenStreetMap (OSM) データは、地理データ分析や地図作成において強力なデータソースです。しかし、利用するデータが大規模な領域をカバーしている場合、自身の環境で利用するには、取り込みや処理が重くなることがあります。
本記事では、以下の2つの例に関して、特定の領域に絞ったデータの利用方法を解説します。

1. **osm2pgsql を使用してPostgreSQL に部分的に取り込む**
2. **osmium-tool を使用してデータを抽出する**

尚、今回は手元にPBF形式のデータを持っているケースを例にして事例を紹介しています。
OSMのデータ形式（主にPBF、OSM）についてはこちらの記事もあわせてご参考ください。
[.pbfと.osm](https://qiita.com/AshMap/items/ab235f09fd211a8b714f)
[PBFフォーマットの概要と他のデータ形式との比較](https://qiita.com/AshMap/items/455d2a19e09db9e46ec5)

## 1. osm2pgsql を使った PostgreSQL へのデータ取り込み（例：神田周辺）

`osm2pgsql` を使用して、大規模な PBF データから PostgreSQL の PostGIS 拡張に取り込む方法を解説します。
Postgresへの取り込みについては下記の記事もあわせてご参考ください。
[QGISでPostGISでのPBFデータの読み込み方法](https://qiita.com/AshMap/items/b6f7177ea75584619f0f)
[OSMデータをPostgreSQLに取り込む：hstore拡張の有無による違い](https://qiita.com/AshMap/items/602e90d429905a5689d6)
[osm2pgsqlで特定のタグキーを指定してデータを効率的に取り込む(PBF)](https://qiita.com/AshMap/items/ca37decc8bf16f981827)

### 必要なツール
- osm2pgsql
- PostgreSQL + PostGIS 拡張

### コマンド例
手元のPBF データから神田周辺（バウンディングボックス指定）のデータのみを取り込んでみます。

```bash
osm2pgsql -c -d my_database -U $(whoami) --bbox 139.766,35.692,139.773,35.701 --slim -r pbf kanto-latest.osm.pbf
```

>今回のサンプルはGeofabrikでダウンロード可能なkanto_region(約394M)のデータを活用します。kanto-latest.osm.pbf


### オプションの説明
- --bbox 139.766,35.692,139.773,35.701: 神田周辺のバウンディングボックス（経度・緯度）を指定。
 >バウンディングボックスの作成については[klokantech](https://boundingbox.klokantech.com/)のサイトが便利です。
地図上でバウンディングボックスを指定して、下部のCopy & PasteからCSVを選ぶと下記のコマンドに入力する値を得られます。

- -d my_database: PostgreSQL のデータベース名。
- --slim: 中間テーブルを作成して効率的にデータを処理。

### 実行後の確認(QGISで表示)
![Screenshot 2024-12-18 at 15.06.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789281/58833f84-113c-8702-d729-b103baa24488.png)

## 2. osmium-tool を使った特定領域の抽出（例：上野周辺）

osmium-toolではPBFデータから特定領域のデータを抽出（pbfからpbf）することが可能です。ここでは上野周辺のデータを抜き出してみます。

### 必要なツール
- osmium-tool

### コマンド例

以下のコマンドで、上野周辺（経度・緯度指定）のデータを新しい PBF ファイルに抽出します。

```bash
osmium extract --bbox 139.771,35.709,139.780,35.718 -o ueno.osm.pbf kanto-latest.osm.pbf
```

### オプションの説明
- --bbox 139.771,35.709,139.780,35.718: 上野周辺のバウンディングボックスを指定。
- -o ueno.osm.pbf: 抽出結果を新しい PBF ファイルとして保存。

### 抽出後の確認(QGISで表示)
![Screenshot 2024-12-18 at 15.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789281/0715e97e-bb99-f249-cff6-2ac07599cc83.png)

>本記事に表示されている地図には、OpenStreetMapのデータを利用しています。
https://www.openstreetmap.org/copyright

# まとめ

今回2種類の方法、osm2pgsql と osmium-tool を使った領域限定データの取り扱い方法を紹介しました。地域を抽出することができるツールなどは他にもあるようですので、OSM データを効率的に扱うため、それらを利用して、必要な領域を抽出して利用するのが効果的かと思います。これにより実際の処理時間も短縮できるので、作業も効率的に実施できるようになるかと思います。

メリット
	1.	処理の軽量化: 必要な領域のみを取り込むことで、データベースやツールの負荷を軽減。
	2.	取り込み時間の短縮: データサイズが小さくなるため、処理速度が向上。
	3.	柔軟性: PostGIS や PBF ファイル形式のまま活用可能。

本記事がOSMデータを自分のプロジェクトで効率的に活用する助けになると幸いです。
EC2を閉域で使用するちょっとしたTips

# 内容
要件によって使える場面が限定されるものもありますが、閉域でEC2を運用するTipsを下記観点で記載しました。

* マルウェア対策
* パッチ適用
* アラート通知

![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/7ccc6a67-a9e6-b8da-0ce7-f06410c7a37a.png)

# マルウェア対策

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/711e056e-d47d-8bb4-39af-49fbe9b2b7cb.png)

オンプレミス環境ではウィルス対策サーバを用意して、各サーバのパターンファイルを更新するといった運用を行うことがあると思いますが、AWSのマネージドサービスを使用してマルウェア対策を行う方法に「GuardDuty Runtime Monitoring」といった機能があります。EC2サーバにエージェントをインストールして、GuardDutyにイベント送付、分析するといった仕組みです。エージェントはSystem Manager経由で自動インストールが可能です。またGuardDutyとの通信はRuntime MonitoringのVPCエンドポイント経由で行います。現在対応OSはAmazon LinuxやUbuntuなど一部のOSに限定されます。

https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/prereq-runtime-monitoring-ec2-support.html

# パッチ適用

![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/c12891b6-7204-5f50-2c12-6cbd1d722efc.png)

こちらもOSが限定された方法となりますが、Amazon Linuxであればインターネット接続環境が無くてもyumコマンドでパッケージのアップデートが可能です。Amazon LinuxのパッケージリポジトリはS3でホストされているためです。そのためS3のVPCエンドポイントは必要です。VPC内からのアクセスのため無料のゲートウェイエンドポイントを作成しています。

# アラート通知

![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/4b546c79-f7cd-55e7-164e-6f1c8402e7cb.png)

EC2を監視して、アラートメールを通知する方法です。こちらは一般的に使用する方法ですが、たまに外部向けのメールサーバが必要か？と質問をされることがあるため記載しました。CloudWatchでEC2を監視、CloudWatchやAmazon EventBrigeのターゲットとしてSNSを指定、SNSで通知先のメールアドレスを設定すれば外部のメールアドレスに通知可能です。
マルチステージビルドを使ってimageサイズを縮小する

## マルチステージビルドとは
複数のビルドステージを用いて、最終的なイメージを効率的かつ軽量に構築するimageのビルド方法です。
ビルドの途中で生成される不要なファイルやツールを最終イメージに含めることなく、必要なアーティファクトだけを次のステージに引き継ぐことで、軽量化されたimageを作成することができます。

## マルチステージビルドの嬉しさ
マルチステージビルドの嬉しさといえば、imageサイズを小さく保てるところです。
imageサイズを小さくしておくことで、転送速度の改善やストレージコストの縮小などをすることができます。
それに加えて、不要なツール・パッケージを排除できるのでセキュリティリスクの低減にもつながります。

## imageサイズの縮小例
マルチステージビルドによるimageサイズの縮小例として、以下の簡単なCプログラムとDockerfileを想定します。
```main.c
#include <stdio.h>

int main() {
  printf("Hello world!\n");
  return 0;
}
```
```Dockerfile
FROM ubuntu:24.04

RUN apt-get update && apt-get install -y gcc

COPY ./main.c .
RUN gcc -o /usr/local/bin/hello_world main.c

CMD [ "/usr/local/bin/hello_world" ]
```
このDockerfileをビルドすると、imageサイズは`340MB`になります。
```sh
$ docker build . -t hello_world
$ docker images | grep hello_world
hello_world  latest  1c8709e2e153  30 seconds ago  340MB
```

ベースになるimageとして`ubuntu:24.04`を使っていますが、`ubuntu:24.04`のimageサイズは`101MB`です。
```sh
$ docker images | grep ubuntu | grep 24.04
ubuntu  24.04  20377134ad88  4 weeks ago  101MB
```

コンテナに入りビルドされた実行ファイルのサイズを確認すると、`69KB`でした。

```sh
$ docker run -it hello_world bash
$ root@3572e1c41714:/# ls -lh ./usr/local/bin/hello_world
-rwxr-xr-x 1 root root 69K Dec 18 22:22 ./usr/local/bin/hello_world
```

- カスタムimage: `340MB`
- ベースimage: `101MB`
- 実行ファイル: `69KB`

明らかにプログラムの実行に不要な部分がimageに含まれてしまっているということがわかります。
今回のCプログラムをコンテナを使って実行するにあたり、本当に必要なのものOS環境とビルドされた実行ファイルです。

これをマルチステージビルドを用いて改善します。

以下のようにビルド用のステージと実行用のステージを作成し、ビルド用のステージのアーティファクト(今回で言うとコンパイルされた実行ファイル)を実行用のステージに持ち越すようにします。
```Dockerfile
FROM ubuntu:24.04 AS builder

RUN apt-get update && apt-get install -y gcc

COPY ./main.c .
RUN gcc -o /usr/local/bin/hello_world main.c

FROM ubuntu:24.04 AS final
COPY --from=builder /usr/local/bin/hello_world /usr/local/bin/hello_world
CMD [ "/usr/local/bin/hello_world" ]
```
```sh
$ docker build . -t hello_world_with_multistagebuild
```
ビルドされたimageを確認すると、先ほどのものより明らかにimageサイズが縮小されていることが確認できます。(`340MB` -> `101MB`)
(※ ベースimageの`ubuntu:24.04`のサイズと同じになっていますが、アーティファクトのサイズが極めて小さいためです。)
```sh
tsuzuki-takaaki@TakaakinoMac-mini hakababa % docker images | grep hello_world_with_multistagebuild
hello_world_with_multistagebuild  latest  f4dcb4d37627  27 seconds ago  101MB
```

## 参考
https://docs.docker.jp/develop/develop-images/multistage-build.html

https://docs.docker.com/build/building/multi-stage/

https://www.youtube.com/watch?v=OVYNUg0aODw
TryHackMe cookies

HTTP in detailの学習メモ

Answer the questions below
Which header is used to save cookies to your computer?

PC上でcookiesの保存に使われるヘッダーを答える問題

画像で
> The server responds with a Set-Cookie header telling the client to save the data name=adam.

となっている箇所が存在する。
つまり**Set-Cookie**が正しい答えとなる。
elixir 複雑なマッチ

パターンマッチ
```elixir
iex> list = [1, 2, 3]
[1, 2, 3]

[a, b, c] = list
[1, 2, 3]
```

> Elixirは、左辺の値と右辺の値を同じにする方法を探す。左辺は三つの変数を含むリスト、右辺は三つの値からなるリストだ。そのため、変数それぞれに対応する値をセットすれば、両辺を同じにできる。
この処理をパターンマッチという。

※プログラミングElixir 第2販 P.17より抜粋

つまりあるリストに対して対応する値をそれぞれ入れることと説明できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330568/062dc102-9027-d01b-0c52-f911a177b0a9.png)

https://access-company.github.io/server_training/elixir/pattern_match.html

さらにリストを見ていく
以下は失敗パターン
```elixir
iex(11)> list = [1, 2, 3]
[1, 2, 3]
iex(12)> [a, 1, b] = list
** (MatchError) no match of right hand side value: [1, 2, 3]
    (stdlib 6.1.2) erl_eval.erl:652: :erl_eval.expr/6
    iex:12: (file)
```
これはiex(11)でlistに1, 2, 3を入れたにもかかわらず次のiex(12)で[a, 1, b]と照らし合わせたためである
a = 1
1 = 2
b = 3
となってしまい２つ目の1 = 2が不正なためマッチエラーが出力された。

参考文献
プログラミングElixir 第2版
変数のtrue,falseの切り替えについて

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737462/8f1730db-da1f-f385-ec0b-a6ada18696f7.png)
PowerAppsにて`Label.Text`に`locVariable`という変数を設定しそれを切り替える方法ですが
今までは
```
If(locVariable=false,
    UpdateContext({locVariable:true}),
    UpdateContext({locVariable:false})
    )
```
だったり
```
Switch(locVariable,
    false,UpdateContext(UpdateContext({locVariable:true}),
    UpdateContext({locVariable:false})
)
```
の様に記載していたが`Not`を利用して
```
UpdateContext({locVariable:!locVariable})
```
で表せる事に今頃気づいた。
[AWS #33] AWS Organizations

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
皆さまお疲れ様です。
今回は<font color="c00000"> **「AWS Organizations」**</font>について見ていきたいと思います。
:upside_down: 「Organizations」は直訳すると<font color="c00000">**「組織」**</font>です。簡単にまとめると **「複数のAWSアカウントを一元管理できるAWSのサービス」** です。

## AWS Organizations
「AWS Organizations」を使用すると、**複数のアカウントを「組織」としてまとめて管理**することができます。（色々なAWSの機能と連携できます）グループ化し、そのグループごとに共通のポリシーを設定することができます（許可するものや、許可しないものも）

何かのグループごとにAWSアカウントをまとめて、「このサービスはAグループは使用許可。Bグループは使用不可」というような設定もできます。

:::note info
「AWS Organizations」のポイントは、アカウントに個別にではなく、<font color="c00000">**グループごとにポリシー設定をし、統制できることです**</font>
:::

これを正しく利用することで、**AWSの複数あるアカウントを効率よくまとめることができます**。まとめることができると下図のように...

![AWS3301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/d99eac61-ae33-aa5e-7e44-df03aeab0cca.png)
:upside_down: 企業側も**バラバラに請求が発生するより**も、<font color="c00000">**１つにまとまっている方が支払い管理は楽になる**</font>と思います。

### 一元管理
冒頭に出てきたOrganizationsの機能 **「一元管理」** について簡単にまとめます。
![AWS3302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/f389529e-fa9c-fd71-46c2-29d6a36d19f1.png)

:::note info
**OU（Organizational Unit）** ➡ **組織単位**を意味します　グループやチームと呼ぶことも
:::
また一元管理には **「請求」も可能**です。
上図に記載のルートアカウント（親）でメンバーアカウント（子）の請求書をまとめて管理することができます。

さらに一元管理には**リソースの共有も可能**です。
「組織内のAWSアカウント間」または「OU間」でリソースを共有することができます。

## おわりに
今回のちょっとしたまとめになります。

:::note info
AWS Organizationsの **「一括請求」で複数アカウントの請求をまとめられます**
:::

:::note info
AWS Organizationsは複数の**AWSアカウントを管理することができます**
:::

:::note info
一元管理や請求も組織内のAWsリソースの共有などの機能があります
:::
:rolling_eyes: 因みにOU（Organizational Unit）の「Unit」のUniは **「１つ」「１つになる」** という意味があるだとか。だからチームや組織、１つにまとめる..という感じなんですかね

最後までお読みいただきありがとうございました！
>>**日頃より活用している参考書です。**
>> **「参考書」**
[**AWS認定クラウドプラクティショナー改定第3版（AWS Organizationsは382ページ）**](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[**AWS Organizations**](https://aws.amazon.com/jp/organizations/)

> **「Youtube」**
[**【AWS Organizations】ソリューションアーキテクト アソシエイト(SAA) 第39回講座**](https://x.gd/OrtX6)
>
Emacs Lisp 超初心者がコマンドを作ってみる 〜一時バッファーを使ってみる〜

前回までで比較対象となる previous msgid (コメント欄の #|) と msgid をそれぞれバッファーに入れる事ができました。

しかし、 msgid は unquote してあるのに比べて previous msgid は 抜き出したままで、 これでは msgid との比較には使いにくいです。

そこで、 previous msgid も msgid と同様に unquote 等してみます。

# 処理の流れ

1. 一時バッファーを作って previous msgid からコピー
1. そこで処理した結果を文字列として返します

# プログラム
````elisp
(defun po-extract-previous-msgid (buffer start end)
  "Delete '#|' marker and unquote text from BUFFER START END.
delete '^#| ' each line.  then unquote.
return is String with property."
  (with-temp-buffer
    (insert-buffer-substring buffer start end)
    (goto-char (point-min))
    (while (re-search-forward "^#\\(~\\)?|[ \t]*" nil t)
      (replace-match "" t t))
    (po-extract-unquoted (current-buffer) (point-min) (point-max))
    )
  )

````

with-temp-buffer は with-current-buffer に似ていて、 with-current-buffer が指定のバッファーに対して、 with-temp-buffer は with-current-buffer 自身が勝手に一時的なバッファーを作り、そちらに切り替えます。 with-current-buffer を抜けると元に戻して一時的なバッファーは破棄(kill)します。

with-temp-buffer カレント・バッファーが切り替わり、 with-temp-buffer が勝手に作った謎のバッファーになっています。元のバッファーにアクセスするには、save-current-buffer や with-current-buffer と同様にそれらの外で oldbuf などとシンボルに代入(バインド)してから参照する必要があります。

実際の処理部分は正規表現マッチングで、マッチした部分を "" に置換しています
````elisp
 (while (re-search-forward "^#\\(~\\)?|[ \t]*" nil t)
      (replace-match "" t t))
````

po-extract-unquoted は msgid の unquote をする関数で、上記正規表現置換でテキストは msgid と同じ形になっているのでコレを使います。

# ためしに動かしてみる

前回で作成された *pepm-previous-msgid* バッファで試してみます。

M-: Eval:(po-extract-previous-msgid (current-buffer) (point-min) (point-max)) 

![po-extract-previous-msgid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435164/877e384e-2314-c9f2-e54e-f1b4cabac63c.png)

実行結果(参考)
![result-po-extract-previous-msgid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435164/d687d0b4-d435-fb78-f6fd-1483a5240f9a.png)

とりあえず動いているようなのでヨシッ

今回はここまで。
pager-modeを作ってEmacsのバッファ内でログを読んだりできるようにした

# はじめに

これは[Emacs Advent Calendar 2024](https://qiita.com/advent-calendar/2024/emacs)の18日目の記事です。そしてこれは[以前書いた日記](http://gonypage.jp/diary/article-265.html)の改稿です。

最近は業務でもプライベートでも端末内で生活している時間が長く、特に業務ではsshなのでセッション数を増やすのも面倒で可能な限りなんでも[Emacs](https://www.gnu.org/software/emacs/)上で済ませたいと思っています。なので、[eshell](https://www.gnu.org/software/emacs/manual/html_mono/eshell.html)を導入してEmacs内でコンパイルもバージョン管理も済ませるようにしたのですが、これが端末としての互換性はかなりきびしくてlessがまともに動かなく、しょうがないので環境変数PAGERにcatを設定して逃げていました。

それにしてもあまり快適ではないのでもっとよい方法がないのかと思っていたのですが、[Emacs上でテキストファイル内のエスケープシーケンスを色付け表示する方法](https://stackoverflow.com/questions/23378271/how-do-i-display-ansi-color-codes-in-emacs-for-any-mode)があるということで、それを使ってページャーとして動作するモードを作成すればよいのではないかと思って実験しました。

その後ずっと実用していますがすでに手放せなくなっていますので、この機会にご紹介したいと思います。

# pager-modeの作成

まずは.emacsに以下のように追加してpager-modeを作ります。

```elisp:.emacs
(define-derived-mode pager-mode fundamental-mode
  "Pager"
  "Pager mode to view texts with ANSI colors."
  (ansi-color-apply-on-region (point-min) (point-max))
  (set-buffer-modified-p nil)
  (setq buffer-read-only t)
  (define-key pager-mode-map (kbd "SPC") 'scroll-up-command)
  (define-key pager-mode-map "b" 'scroll-down-command)
  (define-key pager-mode-map "q" 'kill-this-buffer))
(add-to-list 'auto-mode-alist '("\\.pager\\'" . pager-mode))
```

拡張子.pagerで起動するように、ANSIカラーを適用するように、バッファ削除時に確認されないように、そしてリードオンリーに設定します。キーバインドはスペース、B、Qくらいあればよいでしょう。

# emacspagerの作成

続いてページャーコマンドを作ります。ここではPythonで書いてemacspagerという名前でパスが通っている場所に置きました。

```python:emacspager
#! /usr/bin/python3

import os
import sys
import tempfile

if __name__ == "__main__":
    text = ""
    if len(sys.argv) == 1:
        done = False
        while not done:
            try:
                text += input() + "\n"
            except EOFError:
                done = True
    else:
        with open(sys.argv[1]) as file:
            text = file.read()

    fd, file_name = tempfile.mkstemp(".pager", "")
    with os.fdopen(fd, "w") as file:
        file.write(text)
        file.close()

    os.system("emacsclient -n " + file_name)
```

やっていることは引数がなければ標準入力を、引数があればそのファイルの内容を一時ファイルに出力し、emacsclientを起動するだけです。

# 環境変数PAGERとEmacsサーバーの設定

最後に.emacsに環境変数PAGERを設定し、emacspagerがページャーとして使用されるようにします。emacsclientを使用するのでEmacsサーバーも起動する必要があります。

```elisp:.emacs
(server-start)
(setenv "PAGER" "emacspager")
```

その後eshell内でページャーを使用するコマンドを実行すると、その内容がEmacsのバッファ内に開かれるようになります。非常に便利ですがまあエラーハンドリングや大きい文書表示時のパフォーマンスなどいろいろ課題はあります... そのへんは追ってなんとかしたいところです。
インデックスの役割と活用

## はじめに
データベースの求められる性能を支える重要な技術、インデックスについて解説します。「なぜ使うのか」「どう使うのか」に焦点を当て、インデックスの基本概念から実践的な利用方法までを解説します。

## インデックスとは？
いわゆる「索引」です。本や辞書に「あいうえお順」や「アルファベット順」にまとめた索引があるかと思いますが、DBにも同様の機能があります。
RDBも特定のルールで並べられている場合、インデックスを使えば検索時間を短縮することができます。

インデックスは以下のような特徴を持つ表で効果が現れやすいです。

・行数が多い
・検索対象の項目に値の重複、偏りが少ない
・表の更新・追加・削除が少ない

一方以下のような表では効果が現れにくくなります。

・行数が少ない
・表のほとんどの行を取得する

## インデックスの使い方
前提としてインデックスは**特定のカラムに貼るものです。**
インデックスの作成方法
```sql:sql
/* CREATE INDEX [インデックス名] ON [テーブル名](カラム名); */
CREATE INDEX IDX_MYNUMBER ON users(my_number);
```
複数のカラムを一つとしてインデックスを貼ることができます。これを複合インデックスと呼びます
```sql:sql
/* CREATE INDEX [インデックス名] ON [テーブル名](カラム名1,カラム名2); */
CREATE INDEX IDX_MYNUMBER ON users(my_number, name);
```

インデックスの削除方法
```sql:sql
/* DROP INDEX [インデックス名] ON [テーブル名]; */
CREATE INDEX IDX_MYNUMBER ON users;
```

## どのカラムにインデックスを貼るべきか
WHERE・JOIN・ORDER BYでよく指定されるカラムに貼るのが望ましいです。
※主キー、外部キーには自動的にインデックスが貼られます

## インデックス利用の注意点
インデックスを増やしすぎると、データ書き込み(update、insertなど）の際にインデックスの更新も行うため、パフォーマンスが下がることがあります。
使用するクエリに対して、本当にインデックスが必要かを評価することが大切です。

## 終わりに
インデックスは、データ検索性能の向上や一意性保証に起立活举する重要な技術です。しかし、その利用にはコストやメリットを完全に考える必要があります。本記事が、インデックスの基本概念を理解する上での参考になれば幸いです。

## 参考記事
https://qiita.com/masayasviel/items/b4f2fe76235f30270b07

https://products.sint.co.jp/siob/blog/index

https://qiita.com/towtow/items/4089dad004b7c25985e3