OmniAICreator/Qiita-1.07M huggingface dataset:
ファシリテーションとは：参加者の力を引き出す会議運営のコツ

 
# はじめに
ファシリテーションは、会議や議論の進行をスムーズにし、参加者全員が意見を出しやすい場を作る技術です。しかし、ただ進行をこなすだけではなく、議論の本質に迫り成果を引き出すためには、いくつかのポイントを押さえる必要があります。本記事では、ファシリテーター初心者から経験者まで活用できるコツをまとめました。

---

## **ファシリテーションの基本：目的を軸に進める**
ファシリテーションを成功させるための基本は、「目的を明確にし、それを共有すること」です。会議が始まる前に「なぜこの会議をするのか」「どのような成果を目指すのか」を参加者全員に共有することで、議論の軸がぶれにくくなります。

さらに、会議の時間配分も事前に決めておくと効果的です。各議題に使える時間を明示し、「次の議題に進むタイミング」を意識させることで、時間内に議論を収束させやすくなります。

---

## **場の雰囲気づくり：発言しやすい環境を整える**
参加者が積極的に意見を出せる雰囲気を作ることは、ファシリテーターの重要な役割です。そのためには以下の工夫が役立ちます：

- **アイスブレイク**：会議冒頭に軽い自己紹介や雑談を取り入れ、参加者の緊張をほぐします。
- **気負わない姿勢**：ファシリテーター自身がリラックスしていると、参加者も自然体で発言しやすくなります。
- **否定しない対応**：「いい意見ですね。他にはどうでしょう？」とポジティブな反応を心がけ、意見を歓迎する雰囲気を醸成しましょう。

---

## **役割分担と議論の進行**
効果的な議論の進行には、役割分担と脱線の管理が重要です。

### **役割分担の明確化**
ファシリテーターは進行役に徹し、議事録は別の人が担当しましょう。一人で複数の役割を担うと、議論の流れを見失いやすくなります。

### **脱線の管理**
議論が脱線した場合の対応は、次のように状況に応じて切り分けます：
- **目的と関係ない話**：その場では扱わず、他の場に持ち越します。
- **必要だが長引きそうな話**：具体的なアクションを決めて後日取り組みます。
- **その場で必要な話**：時間に余裕がある場合は議論を延長する柔軟性を持ちましょう。

これにより、議論を効率的に進めつつ、重要なトピックを漏らさない運営が可能になります。

---

## **多様な意見を引き出す工夫**
参加者全員が同じ理解度ではないことを前提に進行することが重要です。一見して理解度が低そうな人にも積極的に話を振ることで、多様な視点を引き出すことができます。

例えば、「◯◯さんはどう思いますか？」と問いかけたり、意見を言いやすいトピックから始めたりすることで、参加者全員が自然に議論に加わる環境を整えられます。

---

## **ファシリテーターは決定者ではない**
進行役はあくまで議論を円滑に進める役割であり、意思決定を行うのはチーム全体です。自分が決定権を持つ立場にいる場合でも、議論の場ではその役割を切り離し、中立的な立場を維持することが求められます。

---

## **まとめ：会議を成果につなげるために**
ファシリテーションはスキルというより「意識と工夫」の積み重ねです。本記事で紹介したポイントを実践することで、スムーズな進行とより良い成果を両立させる会議運営が可能になります。

- 目的と時間配分を共有する
- 発言しやすい雰囲気を作る
- 役割を分担して効率よく進行する
- 脱線を管理しつつ議論を深める
- 多様な意見を引き出し、決定は全員で行う

会議後の成果を左右するのはファシリテーターの腕にかかっています。気負わず、自分らしいファシリテーションを楽しんでみてください！

---

この記事が役立ったと思ったら、ぜひ「いいね」や「ストック」をお願いします！さらに詳しい内容が気になる方はコメントで教えてください！
多額の奨学金を借りてでも情報系の大学へ行くべきか？


こんにちは。題名の通りですが、多額の奨学金を借りてまで情報系の大学へ進学する意味はあるのかについて、情報系の大学を中退した私の考えを話していきたいと思います。あくまで参考程度に見ていただけると嬉しいです。この記事が進路に悩む方の助けになることを願っています。

## 1\. 前提

題名では多額、としていますが、具体的にいうと私は月に８万円ほど奨学金を借りていました。第一種奨学金（利子なし）が５万円、第二種奨学金（利子あり）が３万円ほどです。４年間借り続けると合計約400万円ほどになります。地方の国立大学情報学部に通っていました。

世帯年収は６００万円ほどです。これぐらい世帯年収があると給付奨学金も学費免除も受けることができません。では何故奨学金を借りなければいけなかったのかというと、親の金遣いが荒く、全くお金の準備が無かったからです。現在の世論として「望む人は皆大学に行けるようにするべき」というものがあり、そのために政府は学費免除などの整備を進めていますが、これは「お金があるのに親が学費を出さない」というケースには対応していないのが現状です。

成績が優秀であれば給付の奨学金を用意している大学もあるとは思いますが、あまりメジャーでは無いと思います。

加えて私の場合、実家が田舎にあったので実家から通える距離に大学は無く、下宿をせざるを得ませんでしたので必要となる生活費も実家暮らしに比べて多くなりました。

## 2\. 結論

結局、私は３年生の時に大学を中退し、正社員としてSESの会社に就職することとなりました。３年前に戻れるならきっと今の進路は選ばないでしょう。大学生活を思い返しても精神的に苦しかった記憶が多いです。その理由について詳しく次の項で説明します。

## 3\. 辛かったこと
#### - 借金をするという事実が辛い

奨学金は借金であるとは、よく聞く言葉です。しかし実際は利子が極めて少なく、収入が減れば返還期限猶予に申し込めるなど、借金としてこれほど条件の良いものはありません。奨学金を借りても大卒と高卒の生涯年収を比べたとき、大学へ行く方がお得だと言われています。入学前の私はこのように考え奨学金を借りました。しかし人間の心というのは合理的なものではありません。若いうち、特に将来の進路が確定していない時は未来に対して漠然とした不安を抱えるものです。ただでさえ将来に不安があるのに加え、400万円という金額が常に頭の片隅にあります。常にお金の心配があるというストレスは在学中ずっと蓄積していきます。そして働いていない時間、つまり、大学へ通う時間や課題へ取り組む時間が苦痛になるのです。大学の授業を受けながらも、この時間で働きたい、働いてお金の不安を無くしたいと考えてしまい、大学へのモチベーションが下がってしまいます。自分が多額の奨学金を借りてメンタル面が元気でいられるのか、自分の性格を加味して考慮する必要があります。

#### - 他の大学生を見るのが辛い

他の大学生で奨学金を借りている人は少数派でした。そして大学では、地元で見なかったような恵まれた家庭環境にある人が多数おり、学費はもちろん生活費すら何の心配もしていない人たちの言動が嫌でも目につきます。別に彼らは何も悪いことをしているわけでは無いのですが、やはりそこにストレスを感じてしまう自分がいました。

#### - 情報系の大学は情報について学べない

大学には3年半在籍していましたが、そこで学んだ内容は基本情報技術者試験の3分の1程度の内容であり、周りも全くプログラミングができない人ばかりでした。昨今は特に、パソコンが好きで情報学部に入る人よりも、ITは安定していそうという理由で入ってくる、コンピューターに興味のない人が多いような気がします。実際在学中に何かアプリを作ったのは学部で数人程度でした。タッチタイピングすらできない、大学入学するまで授業以外でパソコンを使ったことがない人すらいました。

私は入学前からあまり授業には期待していませんでしたので授業のレベルの低さは予想通りでした。しかし、周りの学生のモチベーションが低いため、課外活動でチームでプログラミングをするとか、エンジニア就職の情報を得るといった、私が最低限大学に期待したものすら得ることはできず、通う意味がないのではと考えるようになってしまいました。

#### - 結局技術力があればいい疑惑

それでも、2年生までは卒業するつもりでいました。しかし、2年生の時にインターンを始め、実際にエンジニアとして働いている人を目の当たりにします。そして高卒が決して珍しくないということに気がつきました。実際、求人票を見ても学歴よりも実務経験が必要とされていると感じます。

## - ではどういう進路を取ればよかったか？

今、3年前に戻れるなら大学受験はしなかったでしょう。私は受験のために1年浪人しているので、お金だけでなく若い頃の1年を無駄にしたという感覚があります。学費を用意することが難しい人にとっては、働きながら通信制や夜間に通うのが最適解だったのではないかと今思い返しています。

## 4\. 最後に

どんな形であろうと借金は精神的にとてもしんどい。
【書きかけ】全エンジニアが使うべき神サイト

# この記事について
この記事を読めば、便利なツールがたくさん載っていて、
エンジニアの皆さんにきっと役に立つと思います！

## [remove.bg](https://www.remove.bg/ja)
![remove.bg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/cbbc3f8e-57db-7936-3c09-61bf82c9e4e1.png)

- 画像の背景を一瞬で抜くことができる背景透過ツール
- 足りない部分を簡単に増やしたり、いらない部分を消したりもできる
- とても高品質
:::note
### 利点
- 通常利用なら無料
- 有料会員でさらに高画質
- 日本語対応
:::

## [Squoosh](https://squoosh.app/)
![Squoosh](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/b20e5da0-2c2e-c14b-50e1-2d6d82df45ad.png)
- 画像圧縮、変換ツール
- Google製
:::note
### 利点
- 高速
- 多種多様なオプション
- 見やすいGUI
:::
JSR のガバナンスについて

JSR は Deno の開発者によって開発されたオープンソースのレジストリです。

Deno の開発者によって開発されはしたものの、JSR はリリース当初より「Deno のためのレジストリ」ではなく「JavaScript エコシステム全体のためのレジストリ」を目指しています。その目標をより忠実に実現するため、現在 JSR プロジェクトでは、ガバナンス体制の見直しが行われています。

https://jsr.io/docs/governance

具体的には隔週で、JSR Working Group Meeting が開催されていて、Deno 以外のメンバーを含めて新体制についての議論が行われています。

https://deno.co/jsr-meeting

過去のミーティングの様子は以下で見ることが出来ます。

https://drive.google.com/drive/folders/1nkV3s4SQP2-lQdy---0oHwHSVCjzhJlR
Claude MCPでSpotifyを操作する

## はじめに
Claude MCPアツいですね！  
Claude MCPのおかげでClaude DesktopのようなLLMアプリケーションからSpotifyのようなサービスをチャットのやり取りだけで操作することが可能になります。  
今回はClaude MCPを使ってClaude Desktop上からSpotify上で曲を探したり、再生したりする方法を紹介します。

## Claude MCPについてざっくり
Model Context Protocolについて公式ドキュメントから引用すると  
```
LLMアプリケーションと外部データソースやツールとのシームレスな統合を可能にするオープンプロトコルです。
AI搭載のIDEを構築する場合でも、チャットインターフェースを強化する場合でも、カスタムAIワークフローを作成する場合でも、
MCPはLLMが必要とするコンテキストに標準化された方法で接続する手段を提供します。
```
引用: https://modelcontextprotocol.io/introduction

つまりMCPはLLMアプリケーションと今回でいうとSpotifyのデスクトップアプリのような  
ツールの統合を可能にするプロトコルです。


## Claude MCPアーキテクチャ説明

```mermaid
flowchart LR
    subgraph Your Computer
        direction LR
        A[Claude Desktop] -->|MCP Protocol| B[Spotify MCP Server]
    end
    subgraph Internet
        direction LR
        B -->|Web APIs| C[Spotify Resources]
    end
```

Claude DesktopとSpotify MCP ServerはMCP Protocolを介して接続が維持され、  
Spotifyのリソースに対してSpotify MCP ServerがSpotifyのWeb APIを介して操作を行います。
具体的にはSpotifyのWeb APIを使って曲の検索や再生、キューへの追加などを行います。  
（更に言うとSpotifyのWeb APIでできる操作ならどんなことでもできるので、プレイリストの作成や削除、アーティスト情報の取得なども実装すれば可能です。）  
（また他の外部データソース、例えばWikipediaなどと繋いで今再生しているアーティストに関する情報を仕入れるといったことも可能だと思います。夢が広がりますね）



## spotify-mcpのセットアップ
Claude DesktopとSPotifyをMCPで接続するためにはSpotify MCP Serverをセットアップする必要があります。
私の手元の環境としてはMacbook Air（M1）を使用して検証しています。  
公式ドキュメントによるとmacOSとWindowsでは動作するようです。

#### Spotify Developerアカウントの用意
MCP Serverを使ってSpotifyを操作するためにはSpotify Developerアカウントが必要です。  
[Spotify for Developers](https://developer.spotify.com)からアカウントを作成し、 [Dashboard](https://developer.spotify.com/dashboard)からアプリケーションを作成します。  
その際以下のように設定しておきます。
- Redirect URIs: `http://localhost:8888`
- Which API/SDKs are you planning to use?: Web Playback SDKにチェックを入れておく


#### MCP周りの準備
- MCP Serverの起動に必要な `uv`, `git`をインストールしておきます。  
`$ brew install uv git sqlite3`
- [Claude Desktop](https://claude.ai/download)をインストールします。  
- ターミナルなどから`~/Library/Application\ Support/Claude/claude_desktop_config.json`を開き以下のように編集します。  

``` json 
{
  "mcpServers": {
    "spotify": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/spotify_mcp",
        "run",
        "spotify-mcp"
      ],
      "env": {
        "SPOTIFY_CLIENT_ID": YOUR_CLIENT_ID,
        "SPOTIFY_CLIENT_SECRET": YOUR_CLIENT_SECRET,
        "SPOTIFY_REDIRECT_URI": "http://localhost:8888"
      }
    }
  }
}
```
`/path/to/spotify_mcp`には Spotify MCP Serverのコードのパスを設定しておきましょう。  
https://github.com/varunneal/spotify-mcp.git でSpotify MCP Serverのコードを公開してくれている方がいるのでこのコードをcloneしてきて使うことができます。

これでSpotify MCP Serverの設定は完了です。  

## 利用例
設定が完了したらClaude Desktopを起動してSpotifyを操作してみましょう。

- 利用例その1
Claude DesktopでLLMと会話しながら曲をかけてもらってます。  
今回はナイスなファンクをリクエストしました。
![mcp_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536302/d1e15b35-9383-1c7f-9795-58ac55b8b50e.gif)

- 利用例その2
聴いているうちに気分が乗ってきたので別のアーティストの曲も教えてもらいます。  
気になるアーティストがあったのでキューに入れてもらうことにしました。
![mcp_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536302/879efc91-624e-f885-9a22-28f5b150b840.gif)




## まとめ
Claude MCPでSpotifyを操作する方法についてご紹介しました。
個人的には音楽の視聴体験に革命が起きた感じがしました。
今後はWikipediaやウェブ検索などの外部リソースと組み合わせてリッチな視聴体験を追求したいなと考えています！
logi cool のwave keysで間違ってwindows用を買ってしまった場合の対処雑記

以下で秒で解決
Karabinerを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116042/6de2af15-d535-c1a8-c612-5b328b7c7026.png)
右パネルのVirtual Keyboardから「JIS」を選択
Karabiner再起動
終わり。

念の為、Macも再起動して確認したほうがいい。

ちなみに理由とか詳しいことは不明w
だって別のプロジェクトが忙しいんだもの。
5日kwsk鳴🇹🇭
React 19 の新機能と改善点を要約してみた

## はじめに
React19がリリースされましたね！
ドキュメントの概要理解のために要約してもらったので参考にどうぞ！
（あくまで概要理解なので詳細を知りたい方はリリースノートを参考にしてください）
https://react.dev/blog/2024/12/05/react-19#actions

## 安定版のリリース
- React 19が正式にリリースされ、npmで利用可能になりました
- 4月のRC版からの追加機能として、suspended treesのプリウォーミングとReact DOM Static APIが含まれています

## Actions（新機能）
- データの変更と状態更新をより効率的に処理する新機能
- 非同期関数をトランジションで処理し、以下の状態を自動管理：
  - pending状態
  - エラー処理
  - フォーム
  - 楽観的更新
- useTransitionを使用した新しい実装方法により、コードがシンプルに

## フォームの改善
- `<form>`要素が`action`と`formAction`プロップをサポート
- フォーム送信後の自動リセット機能
- useFormStatusフックによるフォーム状態の簡単な取得

## 新しいフック
1. useActionState
   - Actionsの共通ケースを処理する新しいフック
   - 以前のuseFormStateから改名・改善
2. useFormStatus
   - フォームのコンテキスト情報へ簡単にアクセス
   - プロップのドリルダウンなしでフォーム状態を取得可能
3. useOptimistic
   - データ更新時の楽観的UIを実現
   - 非同期リクエスト中でもユーザーに即座にフィードバックを提供

## 新しいuse API
- レンダリング時にリソースを読み込むための新API
- Promiseを使用した非同期データの取り扱いが可能
- 注意点：レンダリング時に作成されたPromiseはサポート外

## React DOM Static APIs
- prerenderとprerenderToNodeStreamの2つの新APIを追加
- 静的サイト生成のためのHTML生成を改善
- Node.js StreamsやWeb Streamsとの連携をサポート

## React Server Components
- コンポーネントをビルド前にレンダリングする新オプション
- クライアントアプリケーションやSSRサーバーとは別環境で動作
- CIサーバーでのビルド時実行や、Webサーバーでのリクエスト時実行に対応
- 注意点：Server Componentsには専用のディレクティブは不要

## Server Actions
- クライアントコンポーネントからサーバー上の非同期関数を呼び出し可能
- "use server"ディレクティブを使用して定義
- フレームワークが自動的にサーバー関数への参照を作成

この更新により、React開発の効率性と柔軟性が大幅に向上し、特にフォーム処理、状態管理、サーバーサイド機能の統合が改善されています。
Playcanvasでボタンクリックイベントを作成する

Hierarchyビューの下にある➕️ボタンを選択
「UserInterface」→「Button」を選択。
Positionで位置を調整。Scaleで大きさ調整。

「➕️ADD COMPONENT」から「〈〉Script」を選択。
SCRIPTで「➕️Create Script」を選択。

仮で「ButtonClick.js」とする。
「〈〉Script」で「ButtonClick.js」を設定。

ButtonClick.jsを開く。

```
var ButtonClick = pc.createScript('buttonClick');

// initialize code called once per entity
ButtonClick.prototype.initialize = function() {

};

// update code called every frame
ButtonClick.prototype.update = function(dt) {

};

// uncomment the swap method to enable hot-reloading for this script
// update the method body to copy state from the old instance
// ButtonClick.prototype.swap = function(old) { };

// learn more about scripting here:
// https://developer.playcanvas.com/user-manual/scripting/
```

クリックしたときにコンソールにメッセージを表示。

```
var ButtonClick = pc.createScript('ButtonClick');

// initialize code called once per entity
ButtonClick.prototype.initialize = function() {
    if (this.app.touch) {
        // タッチデバイスを監視
        this.entity.element.on(pc.EVENT_TOUCHSTART, this.onClick, this);
    } else {
        // マウスクリックを監視
        this.entity.element.on(pc.EVENT_MOUSEDOWN, this.onClick, this);
    }
};

ButtonClick.prototype.onClick = function(event) {
    console.log('OK');
};

// update code called every frame
ButtonClick.prototype.update = function(dt) {

};

// uncomment the swap method to enable hot-reloading for this script
// update the method body to copy state from the old instance
// ButtonClick.prototype.swap = function(old) { };

// learn more about scripting here:
// https://developer.playcanvas.com/user-manual/scripting/
```

Launchで確認する。
Zoom Video SDK の文字起こし・翻訳を試してみよう

ご無沙汰しております。

前々回、サンプルとして Zoom Video SDK の録画機能を紹介いたしました。今回は、同様の手口で文字起こし、翻訳を試してみたいと思います。

![Screenshot 2024-11-26 at 17.41.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442226/f667067e-20c1-6b79-b2ef-3992a2ae6cb9.png)

文字起こし・翻訳機能（Live transcription and translation）のご利用には、Zoom Video SDK Live transcription and translation のアドオンのご購入、または Zoom SDK Universal Credit のご購入が必要です。Zoom SDK Universal Credit の場合、[Video SDK Universal Credit Plan](https://developers.zoom.us/docs/video-sdk/video-sdk-plans/) で紹介されている各種機能

- Video SDK Sessionの従量課金時間
- オーディオカンファレンスの利用時間
- 翻訳・文字起こしの利用時間
- Cloud Room Connectorの利用時間
- Cloud Recordingの利用時間・ストレージ利用量

のどれに使うこともできる、共通のプリペイドクレジットとして利用することができます。詳細はお問い合わせください。

https://developers.zoom.us/docs/video-sdk/video-sdk-plans/

## Live transcription and translation とは

https://developers.zoom.us/docs/video-sdk/web/transcription-translation/

Zoom Video SDK Live transcription and translation では、音声データをJSONオブジェクトとしてリアルタイムで受信することができます。

この機能では、ある言語の音声を別の言語のテキストにリアルタイムで翻訳することもできるため、自動クローズドキャプション、感情分析、eラーニングの言語翻訳などさまざまなユースケースが可能になります。

たとえば、あるユーザーが英語で「Hello world」と言うと、他のユーザーはこの音声を、イタリア語の「Ciao mondo」、スペイン語の「Hola Mundo」、フランス語の「Bonjour le monde」など、各自が選択した言語でテキストとして受け取ることができます。

### Video SDK for Web からの呼び出し
最初に`liveTranscriptionClient`を初期化し、`startLiveTranscription`を呼ぶことで処理が開始されます。

この際、`setSpeakingLanguage()` で発話言語の指定を、また`setTranslationLanguage()`で翻訳先の言語を指定できます。もちろん、単なる文字起こしの場合には`setTranslationLanguage()`の指定は不要です。

```javascript
//initialize
let liveTranscriptionTranslation = client.getLiveTranscriptionClient();

//start transcription and translation
function startTranscript() {
  let liveTranscriptionTranslation = client.getLiveTranscriptionClient();
    liveTranscriptionTranslation.startLiveTranscription().then(() => {
      liveTranscriptionTranslation.setTranslationLanguage('en')//to lang
      liveTranscriptionTranslation.setSpeakingLanguage('en')//from lang
    });
}

// stop live transcription and translation
function stopTranscript() {
  let liveTranscriptionTranslation = client.getLiveTranscriptionClient();
  liveTranscriptionTranslation.disableCaptions();
}
```

## テキストの取得
その後 `caption-message`のコールバックを受けて、textを処理します。
```javascript
client.on('caption-message', (payload) => {
    console.log("caption-message: " + JSON.stringify(payload));
}
```

## 実装例
こちらも、録画の記事とそう変わりませんが、githubにてご確認いただけます。

https://github.com/bitzed/vsdkBasic-transcript

入室後、`Start Transcript` ボタンをクリックすると、発話した内容がログに残っていきます。

以上、お試しください。
Github Copilotのカスタムインストラクションを触ってみる

:::note info
この記事はZOZO Advent Calendar 2024 シリーズ7の6日目の記事です。
:::

## はじめに
先日Github Copilotのカスタムインストラクションが正式に利用可能になったと言うことで今回は簡単に触ってみようと思います


## Github Copilotとは
GitHub CopilotとはAIコーディングアシスタントです
昨今の開発では使ってる人も少なくないと思います

GitHub Copilotについて詳しくは以下のサイトをご覧ください
https://docs.github.com/ja/copilot/about-github-copilot/what-is-github-copilot


## 実際に触ってみる
### カスタムインストラクション
カスタムインストラクションを設定することでコーディングガイドラインに沿ったコードを生成してくれるようになります
ちなみにカスタムインストラクションの対象はチャットで生成してくれるコードのみでエディタ上でサジェストしてくれるコードは対象外のようでした

`.github`ディレクトリ配下に`copilot-instructions.md`ファイルを作成し、そこにコーディングガイドラインをマークダウン形式で書いていきます

```md:.github/copilot-instructions.md
- 関数宣言はアロー関数を使ってください
```

これを元にチャットでコードを生成してもらいます
今回は自作のsleep関数を生成してもらいます
念のためカスタムインストラクション設定前とも比較してみます

#### カスタムインストラクション設定前
![スクリーンショット 2024-12-06 16.14.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1602210/1d959479-9e76-48e0-15f2-24b46f078924.png)


#### カスタムインストラクション設定後
![スクリーンショット 2024-12-06 16.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1602210/b851d50c-e603-e129-b24a-7758fb3b8506.png)

上記のように`copilot-instructions.md`ファイルが参照され、アロー関数を使って実装されているのが分かります


## おわり
今回は簡単にカスタムインストラクション機能を触ってみました！
サジェストのコードもカスタムインストラクションで設定できたらいいなと持ったのですが、現状はできないんですかね？
引き続き自分も色々触ってみて新しい発見があったら共有していこうと思います！

最後まで読んでいただきありがとうございました！
壁にぶつかりまくっていたとっとこちゅら太郎がちゃんと走ってくれた話（自動運転AIチャレンジの話です）

ちゅらデータアドベントカレンダー8日目の記事です

先日開催された「[自動運転AIチャレンジ2024](https://www.jsae.or.jp/jaaic/2024ver/)」に参加したのでその話を書きます

参考：[ちゅらデータチームが自動運転AIチャレンジ2024決勝に参加してきました。](https://churadata.okinawa/blog/automotive-ai-challenge2024final/)

ちゅらデータは「とっとこちゅら太郎」というチーム名で参加しました
「ちゅら太郎」はちゅらデータのロゴに描かれているシーサーの名前です

カートに貼られたちゅら太郎
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275821/5627305e-ba27-85c8-8c32-f0f8e4d20f16.png" width="400">



決勝大会では事前練習会が事前にあり、事前練習会ではなかなかうまく走れませんでした
事前練習会の後にいくつか改良を行った結果、決勝大会ではそれなりにうまく走ることができました
この記事では事前練習会の後に行った改良についてざっくり紹介します

## 事前練習会で壁にぶつかりまくっていたとっとこちゅら太郎
![事前練習3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275821/ae2c5978-c133-6e1c-b38e-1a9979119802.gif)
これ以外にもたくさんぶつかったりしてました

## 事前練習会の後に行った改良1：ルートの改良

今回の自動運転のプログラムではあらかじめMapで理想のルートを指定してあり、カートはそのルートに沿って走ろうとします
事前練習会では主催側が用意したデフォルトルートで走っていたのですが、デフォルトルートではコーナーの角度がきつかったためルートを改良しました

デフォルトルート
緑色の部分がコースでコースの中心に引かれている線がルートです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275821/cfdaee56-0d20-3609-17e9-ec744f4f1f36.png)

改良後のルート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275821/7984ed9a-90fe-1d7c-ee2e-58ee6a9ff8d2.png)

ルートの改良には[vector_map_builder](https://tools.tier4.jp/feature/vector_map_builder_ll2/)を使いました

ルートのPointを選択してキーボードの上下左右キーで位置を調整します
もしくはLinestring（Pointの集合）を選択して位置を調整します
Linestringは複数Pointをまとめて移動させることができます

## 事前練習会の後に行った改良2：目標速度の変更
デフォルトでは目標速度はreference.launch.xmlのexternal_target_velの値が使用されます
設定を変更することで目標速度をMapで指定することができます

Mapに設定された目標速度を使用するにはreference.launch.xmlのuse_external_target_velをfalseにします
するとMapのLaneletのSpeedLimitの値が目標速度として使われます

## Laneletの分割
デフォルトではLaneletは結構大雑把に分割されているので、Laneletを更に分割することでコース上の細かい位置に応じた目標速度を設定することができます

Mapファイル(.osmファイル)はxml形式なので適当なエディタで直接編集してLaneletを分割しました
タグが3種類あります
ndタグ：ノードを定義する
wayタグ：ndタグで定義されたノードを複数集めて線にする
relationタグ：wayタグで定義された線を3つ集めてLaneletにする

既存のwayタグを分割して新しいwayをつくり、それを新しいLaneletとして定義します

## 決勝大会でそれなりにうまく走ってくれたとっとこちゅら太郎
![本番2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275821/5868c078-9baf-fcef-d628-f63e0a8fda08.gif)

決勝大会の様子はYoutubeでも見ることができます！
https://www.youtube.com/live/_wxX7OjICFk?si=kvKGZHmAQb0sZ7H_&t=21874

## まとめ
Mapをいろいろ修正することでなかなかいい感じに走ることができました！
プロジェクト引き継ぎでの課題と解決策

# はじめに

Gakken LEAPのmizunoです。
現在、ベンダーから引き継いだRailsのプロジェクトの保守・機能開発を担当していますが、プロジェクトの構造が複雑で、特定の要件によっては実装の難易度が著しく変わる状況にあります。
以下に、その主な課題と、それに対する解決策を詳細に説明します。

## 課題

### 1. RESTful設計の欠如

本プロジェクトのAPI設計では、RESTful設計が十分に徹底されていません。
具体的には、`index`、`show`、`create`、`update`、`destroy`といった標準的なアクション以外にも多数のカスタムアクションが、1つのコントローラ内に集中して記述されています。このような構造の問題点は以下の通りです。

- **保守性の低下**: カスタムアクションが増えるほど、ロジックの依存関係が複雑化し、既存機能に手を加える際のリスクが高まる。
- **コードの見通しの悪化**: 開発者がコントローラを読解する際に全体像を掴むのに時間がかかる。
- **テストの煩雑化**: 膨らんだコントローラ内の各アクションに対する適切なテストケースを用意するのが困難。

**解決策への布石**

APIの構造を見直し、各リソースごとに専用のコントローラを作成するなどのリファクタリングを進めます。ただし、既存システムの互換性を保つ必要があるため、後述の解決策を併用します。

### 2. コールバックの過剰な利用

現在のシステムでは、`before_action`による権限チェックやフィルタリングが多用されています。
例えば、管理者、業者、ユーザーなどの権限ごとに異なる処理が必要な場合でも、それらを1つのコントローラで対応しているため、以下の問題が発生しています。

- **視認性の低下**: コールバックが多すぎて、どのアクションでどの処理が実行されるか追跡しづらい。
- **重複処理の発生**: 複数の`before_action`で同様の認証ロジックが繰り返され、システム全体のパフォーマンスが悪化。
- **デバッグの難しさ**: コールバックの流れが明確でないため、問題の特定に時間がかかる。

**解決策への布石**

コールバックの使用を最小限に抑え、共通化できるものはベースのコントローラに記述し継承することで、権限管理のロジックを各コントローラから切り離します。
これにより、各コントローラの責務が明確化され、処理の重複を避けることが可能です。

### 3. 複雑なJSONレスポンス生成

ユーザーの役割（例: 管理者、業者、エンドユーザー）によって異なる情報をAPIで返す必要があるため、現在は`ActiveModelSerializers`を利用しています。しかし、この手法にもいくつかの課題があります。

- **複雑な条件分岐**: JSON生成時に多くの条件分岐が必要となり、可読性が低下。
- **統一性の欠如**: 一部のAPIエンドポイントでは`ActiveModelSerializers`を使用せず、独自ロジックでJSONを生成しており、メンテナンスが煩雑。
- **設計書の不足**: APIのレスポンス形式が明確に文書化されておらず、新たな開発者が仕様を把握するのに時間がかかる。

**解決策への布石**

`ActiveModelSerializers`の利用箇所を段階的に見直し、統一されたフォーマットを策定することで、複雑な条件分岐を回避します。また、API仕様を明確にするために、OpenAPI（後述）を活用した設計書を作成します。さらに、新規API設計時にはベストプラクティスを取り入れ、APIが一貫性のあるレスポンスを返すように設計を行います。

## 解決策

### APIをV2として新たに作成する

既存APIを全面的にリファクタリングする方法も検討しましたが、このアプローチでは以下の課題が予想されました。

- **フロントエンドとの同期が必要**: 既存のフロントエンドアプリケーションがAPIに依存しているため、同時に修正・リリースを行う必要がある。
- **運用中の影響**: 一度に大規模な変更を加えると、予期せぬ不具合が発生する可能性が高い。

そこで、既存APIをそのまま運用しながら、上記の課題を解決した**V2のAPI**を新たに設計する方針を採用しました。

#### 実施プロセス

1. **事前合意**: 設計段階でフロントエンドチームと綿密に連携し、V2のAPI仕様に合意。
2. **先行リリース**: V2のAPIを単独でリリースし、後からフロントエンドの接続先を切り替え可能にする。
3. **柔軟な移行**: フロントエンド側は既存のV1 APIを使用し続けながら、新しいAPIに段階的に移行可能。

### OpenAPIでのAPI設計書作成

V2のAPI開発では、設計書を**OpenAPI**で管理する方針としました。この方法の利点は以下の通りです。

- **明確な仕様定義**: APIのエンドポイントやレスポンス形式が一目で分かる。
- **自動生成の活用**: テストコードやモックサーバーを自動生成できるため、効率的な開発が可能。
- **引き継ぎの容易化**: ドキュメントが標準化されるため、新たな開発者が迅速にプロジェクトを理解できる。

#### Apidogの採用

OpenAPI設計書の作成には[Apidog](https://apidog.com/jp/)を利用しました。このツールは以下の点で非常に効果的でした。

- **GUI操作**: エンジニアリングスキルに依存せず、直感的にAPI設計が可能。
- **スキーマ管理**: 複雑なスキーマの定義や複製が容易。
- **リアルタイム参照**: APIの変更が即座に反映され、チーム間での情報共有が迅速化。

## まとめと展望

プロジェクト引き継ぎにおける課題は、システムの複雑性が原因で保守性と拡張性に影響を及ぼしていました。しかし、以下の取り組みにより、これらの課題を解決できる見込みです。

- RESTful設計の徹底とコントローラの責務分離
- コールバックの簡素化とロジックの外部化
- 統一されたAPIレスポンス設計とドキュメントの整備

今後は、V2 APIのリリース後にパフォーマンスや保守性の向上を測定し、さらに継続的な改善を進めていきます。

## エンジニア募集

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています！！
ぜひお気軽にカジュアル面談へお越しください！！

https://gakken-leap.co.jp/recruit/
Linux mint 以外の Cinnamonで日本語入力を有効にする

Linux mint 以外の Cinnamonで日本語入力を有効にするには  
fcitx5-imをインストールした後  
.xprofile を手書きする
```
export GTK_IM_MODULE=fcitx5
export QT_IM_MODULE=fcitx5
export XMODIFIERS=@im=fcitx5
```
【言語初心者】Node.jsって何？

# はじめに
どうも、:cheese::cake:です
今回は、Node.jsは一体何者なのか、解説していきます。
<b>追記:2024/12/6 16:55 Node.jsは言語ではなくJavaScript実行環境です。
普通に間違えました...
</b>

:::note warn
注意
この記事は初心者が調べたことをまとめているだけです。
間違いがあるかもしれません
:::

# Node.jsは何者？
- JavaScriptで書かれたプログラムを実行するための環境、実行エンジン
- Webブラウザ内（クライアントサイド）ではなく、単体（サーバサイド）で実行できる！
- 大量のネット接続をすぐにさばける！
といった、つよつよJavaScript実行エンジンです！

# 用途
大体の場合は、JavaScriptで書かれたWebサーバ・Webサービスを動かす。

# 使用例
- Uber
- Netflix
- Spotify
- Scratch (多分)

# 結論
Javascriptを使い非同期でサーバーを立てることができるのがNode.js！
現在のディレクトにあるファイル、フォルダを一つ上の階層のディレクトリに移動させるコマンド


ターミナルを使って、現在のディレクトリにあるファイルやフォルダを一括で上の階層に移動する方法をご紹介します。

## 基本のコマンド

まずは、基本のコマンドから見ていきましょう。

```bash
mv * ..
```

このシンプルなコマンドで、現在のディレクトリ内のすべてのファイルとフォルダを、一つ上の階層に移動できます。

### コマンドの解説

- `mv`: 「move」の略で、ファイルやフォルダを移動するコマンドです。
- `*`: ワイルドカードで、現在のフォルダ内のすべてのファイルとフォルダを指します。
- `..`: 一つ上の階層のフォルダを表します。

## 注意点とTips

### 隠しファイルの移動

基本のコマンドでは、隠しファイル（ドットで始まるファイル）は移動されません。隠しファイルも含めて移動したい場合は、以下のいずれかのコマンドを使いましょう。

```bash
mv .??* * ..
```

:::note warn

`.a`のような2文字のファイル名は対象外となります。

:::

```bash
mv .[^.]* * ..
```

:::note warn

`..xxx`のような`..`で始まるファイル名は対象外となります。

:::

::: note alert

`mv .* * ..`は避けよう!

`.*`とすると`.`と`..`を含む形に展開されてしまうため、意図しないファイルの移動やディレクトリ構造の破壊など、期待していない操作になる可能性があります。

:::

### 安全に使うためのチェック

1. `pwd`コマンドで現在のディレクトリを確認
2. `ls`コマンドで移動するファイルとフォルダを確認 (隠しファイルも確認する場合は`-a`オプションを付ける)

これらのチェックを行うことで、意図しないファイルの移動を防げます。

### 上書きに注意

移動先のフォルダに同名のファイルやフォルダがある場合、上書きされる可能性があります。慎重に使いましょう！

## まとめ

`mv`コマンドでファイルやフォルダの一括移動が簡単にできます。ただし、使い方には注意が必要です。

質問や不明点があれば、コメントで教えてください。

それでは、Happy Coding!
【初投稿】自己紹介

# はじめに
学校のQiita Organizationへの参加申請の前に記事を一つ以上公開する事と条件があったので
自己紹介だけでも書いてみることにしました。
これから少しづつでも記事を書いていこうと思っているのでよろしくお願いします。

# 私について
S高等学校[^1]の3期生で、普段は提携している専門校のキャンパスで授業を受けています。
小学校の2年生ごろからプログラミング言語に触れ始め、
最近は個人開発でモーションキャプチャシステムを作ったりしています(いずれ記事にしたい)
## 技術スタック
 - Python
 小学校3年生-現在まで
 機械学習ライブラリは触れるけどあんまり得意ではないです
<br></br>
 - C#(Unity)
小学校5年生頃から2Dミニゲームを作ったりで触り始めました。
最近はVRChatにハマってるのでUDONフレームワークも勉強中
<br></br>
 - C, C++
中学校1年生-現在
Unreal Engine4で使うために勉強してます
<br></br>
- Rust
高校1年生-現在
サーバーサイドの開発で使うために勉強し始めました。
綺麗に書かないとコンパイル通らないのでガサツな性格の矯正に役立ってるかも(?)
<br></br>
- TypeScript
高校1年生-現在
元来JSに苦手意識があって避けてたんですけど思ったよりも書きやすくていいですね
<br></br>
- Java
小学校6年生-高校1年生
MinecraftのMOD開発をするために勉強していましたが
Spring Bootなどのフレームワークも一通りは扱えます。
<br></br>
# 保持資格
 ### 国家資格
 - ITパスポート
  <br></br>
 - 基本情報技術者試験
  <br></br>
 - 応用情報技術者試験
  <br></br>
 - 第二種電気工事士

  ### ベンダー資格
 - AWS Certified Developer Associate
 <br></br>
 - Cisco Certified Network Associate (200-301 CCNA)
 <br></br>
 - Oracle Certified Java Programmer, Bronze SE 11
 <br></br>
 - Oracle Certified Java Programmer, Silver SE 11

# 今後の記事内容
趣味で開発しているツールに関連した記事や
アウトプット重視で備忘録的な内容の記事も投稿できればいいなと考えています。
就活に備えてインターンに参加したり等しているので感想記事等も書いていきたいです

# 最後に
ここまで読んでいただきありがとうございました。
コメントやいいねなどで反応頂けると嬉しいです。よろしくお願いします。
[^1]:https://nnn.ed.jp/high_school_feature/s_high_school/
DSLの構文解析をかぎ針編みの英文パターンに注目して行うためにBNF記法で表してみた

## はじめに
 編み物の経験がある方はご存じかもしれませんが編み物には編み図と呼ばれる設計図があり、日本では編み図によって作り方の記録や共有がなされています。一方、海外では文章で作り方を記すことが一般的です。
例えば以下のような表現がされます。
これはかぎ針編みの手順を表したものですが、編み図を読むことに慣れた日本人にとって英語で書かれた文章パターンは直感的に理解しがたく、取り組みにくいものとなっています。その一方でプログラミングに似た規則性を持っています。おそらくプログラムを書くことが好きな人ならこの文章パターンもプログラムを読むかの如く楽しく読めることでしょう。
かぎ針編みのパターンをDSL(ドメイン固有言語)として捉え、構文解析を使って読み解き、編み図生成を行うことができれば、限られた人しか扱えなかったパターンをより多くの人に身近に感じてもらえるのではないかと考え、今回はその先駆けとしてまずはパターンのパースを容易にすることを目的としてBNF記法で表してみました。

## DSLと構文解析
### DSL(Domain specific language)
DSLとは日本語ではドメイン固有言語と訳され、ある特定の分野に特化した言語のことです。かぎ針編みのパターンも"編み物に特化した言語"ととらえることができます。
### 構文解析(Parsing)
ある入力に対し、思い通りの挙動をさせることを目的として、入力を意味のある構造に変換させることです。これにより機械的な処理や可視化が可能となります。

## BNF記法(Backus-Naur form)
BNF記法とは
構文を構成する規則を定義することに用いられる記法です。文章パターンをBNF記法として表現することで
- 英文パターンの規則を理解する
- コンピュータでの処理を容易にする
ことを目指します。

### 手順
まずは英文パターンで出現する文字の最小単位を定義します。
~~~
<digit>        ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" #数字
<number>       ::= <digit> | <digit> <number>#<digid>を繰り返してより大きな数字も定義
<stitch_kind>  ::= "ch" | "sc" | "dc" | "tr" | "hdc" | "inc" | "dec"
                | "CH" | "SC" | "DC" | "TR" | "HDC" | "INC" | "DEC" #編み方
~~~
また、英文パターンはスペースやコンマで区切られるため区切り文字を定義します。
~~~
<split>		   ::= " " | ","
<end>		   ::= "." 
~~~

編み方は'ch 1'のようにどの編み方で何回編むのかを決めています。それを表現します。
~~~
<stitch>       ::= <stitch_kind> | <stitch_kind> <split>? <number> | <number> <split>? <stitch_kind> 
~~~
繰り返しパターンも定義します。
~~~
<repeat>       ::= "(" <operations> ")" <split>*   "x" <number> 
~~~

英文パターンは'ROW1'のように何段目かを表すヘッダーが先頭にあるためこれを定義します。
~~~
<header>       ::= "R" | "Row" | "ROUND" | "ROW"
<header> <split>*  <number> <split>*
~~~
文章の最後にその段に何目になっているかを表すことがあるのでそれを定義します。
~~~
<all_col>      ::=  "[" <number> "]" | "(" <number> ")" | "<" <number> ">"  
~~~
先ほど定義したものを用いて一連の操作をひとまとまりとします。
~~~
<operations>   ::= <stitch> | <stitch> "," <operations> | <repeat> | "turn" | "turn around" | "crochet" | "Place"
~~~
文章パターンでは<operations>をいくつか繰り返すことで成り立っていることが分かります。
~~~
<pattern>      ::= <header> <split>*  <number> <split>* ":" <split>* <operation_group>* <end>* <all_col>?
~~~
### 完成
~~~
<header>       ::= "R" | "Row" | "ROUND" | "ROW"
<split>		   ::= " " | ","
<end>		   ::= "." 
<all_col>      ::=  "[" <number> "]" | "(" <number> ")" | "<" <number> ">"  
<number>       ::= <digit> | <digit> <number>
<digit>        ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<stitch_kind>  ::= "ch" | "sc" | "dc" | "tr" | "hdc" | "inc" | "dec"
                | "CH" | "SC" | "DC" | "TR" | "HDC" | "INC" | "DEC"
<special>      ::= "sl st" | "Fasten off" | "close ring" | " in MR"
<stitch>       ::= <stitch_kind> | <stitch_kind> <number> | <number> <stitch_kind> 
<repeat>       ::= "(" <operations> ")" <split>*   "x" <number> 
<operations>   ::= <stitch> | <stitch> "," <operations> | <repeat> | "turn" | "turn around" | "crochet" | "Place"
<operation_group> ::=  <operations> <split>* <special>*
<pattern>      ::= <header> <split>*  <number> <split>* ":" <split>* <operation_group>* <end>* <all_col>?
~~~
### まとめ
本記事ではかぎ針編みの英文パターンをBNF記法で表してみました。
次はこの結果を踏まえて英文パターンをパーシングしていこうと思います。
こうしてみると編み物はとてもシステマチックで、プログラミング言語に近いもののように思います。
年末年始、やることがなくなったらチャレンジしてみてはいかがでしょうか。
【JP1】バッチ実行ユーザーの設定はAgent側にあるよ

## 何の話？
JP1上のバッチからファイルサーバーにアクセスできない！フォルダにはアクセス権が付いているのに・・・

## ん？JP1って？
> 統合システム運用管理・JP1は、システムの自動化や稼働性能重視、資産の管理やセキュリティ管理などを統合的に行うソフトウェア製品です。

https://www.hitachi-solutions.co.jp/jp1/partnership/

## ハマりポイント
「バッチはJP1が実行するんだから、JP1 Manager側のJP1ユーザー（※）がバッチの実行ユーザーでしょ？」と**誤認**した
※正確には、JP1ユーザーにひもづくOSユーザー

## 本当は？
JP1 Managerから実行指示を受けたJP1 Agent側のJP1ユーザー（※）が動かしています
※正確には、JP1ユーザーにひもづくOSユーザー

## どうやって気付いたの？
**弊社の知識人に助けを求めた**ところ、こちらの図（URL）を紹介されました
もろに答えが書いてありますね・・・
![2210_JP1_01a%20(2)[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198710/e423e658-09e8-43f4-7b56-292599f1bb5c.png)

https://www.ashisuto.co.jp/jp1blog/article/202211-base.html

## 教訓
落ち着いて、人に聞く前、ググりましょう

すみません💦、記事をQiitaに投稿した後、アドベントカレンダーに投稿する（設定する）のをすっかり失念しておりました…
関係者の方々にはご心配をおかけしました…
Deno の --allow-env フラグにワイルドカード指定ができるようになった

Deno 2.1 から `--allow-env` のパラメーターの指定に、部分的にワイルドカードを使えるようになりました。

https://github.com/denoland/deno/pull/25255

特定のサービスに関係する環境変数は特定の接頭辞 (prefix) を持っていることが多いです。

例えば AWS の各種サービスを使う場合は `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION` といった環境変数を利用します (接頭辞
 `AWS_` が共通)

例えば Supabase を使う場合は `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `SUPABASE_DB_URL` のような環境変数を利用します (接頭辞 `SUPABASE_` が共通)。

従来だと、このような環境変数アクセスをパラメータで絞って許可したい場合:

```shell
deno --allow-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION script.ts
deno --allow-env=SUPABASE_URL,SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY,SUPABASE_DB_URL script2.ts
```

のように全ての変数名をカンマ区切りで指定する必要がありました。

Deno 2.1 からは、環境変数の末尾に `*` を使ってパターンでの指定が出来るようになりました。パターンを使って上の例を書き直すと:

```shell
deno --allow-env="AWS_*" script.ts
deno --allow-env="SUPABASE_*" script2.ts
```

以上のように、すっきりと記述することが出来ます。
AWS Certified AI Practitioner（AIF）対策：SageMaker Feature Store

# SageMaker Feature Store

***<font color="MediumVioletRed">『モデルで使用する特徴量を一元管理し、チーム間で共有できる』</font>***

異なるプロジェクトで同じ特徴量を再利用し、**<font color="Darkcyan">重複作業</font>** を避けることができます。

例えば、

- ユーザーの購買履歴
- 行動データ
    
を管理しておくことで、同じデータを何度も計算し直さずに、他のモデルで使い回すことができます。

## 特徴量グループ

***<font color="MediumVioletRed">『特徴量を特徴量グループとして保存し、再利用や共有を可能にする』</font>***

特徴量グループは、

- **<font color="MediumBlue">特徴量のスキーマ</font>**
- **<font color="MediumBlue">エンティティID</font>**

によって構成され、特徴量が正確に管理されます。

## ストア形式

### <font color="MediumBlue">オンラインストア</font>

- リアルタイム推論に使用する特徴量を保存します。
- 低レイテンシーでアクセスでき、高頻度な推論に最適です。

### <font color="MediumBlue">オフラインストア</font>

- バッチ処理や長期的に保存する特徴量を保存します。

## データの一貫性

データの一貫性を維持するために、

- **<font color="MediumBlue">トレーニングデータ</font>**
- **<font color="MediumBlue">推論データ</font>**

で同じ特徴量を使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1df26282-c04b-0a2b-9f4d-d28c0fd4ad39.jpeg" width="500">
【言語初心者】Pythonってどんな言語？

# はじめに
どうも、チーズケーキが好きだから、ユーザー名がCheesecakeな人です:cheese:
今回は、Pythonという言語は一体何者なのか、解説していきます。

:::note warn
注意
この記事は初心者が調べたことをまとめているだけです。
間違いがあるかもしれません
:::

# Pythonとは
ざっくり言うと、1991年に開発された機械学習、Webサーバー、アプリケーションなど
身近なところにたくさん使われている言語です。

# 実際にPythonが使用されているサービス
- Google
- Youtube
- Facebook

# 構文
```python
# コメントアウト

# モジュールのインポート
from hoge import hoge
import hoge

# 変数の定義
huga = True

# if文,while文,for文
if huga:
    # インデントを必ず開けること
    print("huga is true")
else
    print('huga is false') # "か'で挙動は変わらない

for i in range(10):
    # 十回のループ
    print(i) # iはループ回数

while huga:
    # hugaがtrueの間、繰り返す
    print("fuga!")
```

# 特徴
- 理解しやすい構文
- インデントが必須
- インタプリンタ型言語

# 結論
機械学習などのことによく使われ、今後活躍するであろう言語。
ポートマッパー

# 事前に指定されていないポートを知るためには
>固定のTSAPアドレスの利用は、少数で普遍の主要なサービス（Webサーバーなど）に関してはうまくいくかもしれない。しかしながら、`事前にわかるTSAPアドレスを持っていないプロセスや、一時的にしか存在しないプロセスに接続する場合も多い`。

# 代表的なポートにポートマッパーでlisten,その他のプロセスのコネクションを確立させる
>これに対応するために他の手法、すなわち、`ポートアッパー(portmapper)と呼ばれる特別なプロセル`を利用する手法がよく使われる。ユーザーは、ある与えられたサービス名、例えば「BitTorrent」に対応するTSAPアドレスを見つけ出すために、`周知のTSAP(well-know TSAP)でリッスン(listen)しているポートマッパーに接続`する。そして名前サーバーにサービス名の指定を含むメッセージを送ると、ポートマッパーは対応するTSAPアドレスを送り返してくれる。`ユーザーはポートマッパーとのコネクションを開放し、所望のサービスとのコネクションを新規に確立`する

* ポートマッパーを介してサービスとのコネクションを確立する
### ポートマッパー
>`ポートマッパーは、ポート番号を管理する機能`です。クライアントは、利用可能なポート番号を知らなくても、`ポートマッパーが動作する代表ポート番号へコネクション要求を発行することで、メッセージブローカとのコネクションを獲得できます`。
>
>ポートマッパーは、デフォルトで動的にポート番号を割り当てます。
メッセージブローカ起動時にポート番号を指定して割り当てることができます。
>
>注意
>
>静的にポート番号を割り当てた場合でも、各接続サービスを利用する場合は、ポートマッパーの代表ポート番号を使用してください。

https://software.fujitsu.com/jp/manual/manualfiles/M090101/B1WS0321/06Z200/B0321-00-03-15-05.html#:~:text=%E3%83%9D%E3%83%BC%E3%83%88%E3%83%9E%E3%83%83%E3%83%91%E3%83%BC%E3%81%AF%E3%80%81%E3%83%9D%E3%83%BC%E3%83%88,%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82

### portmap プロトコル
>portmap プログラムは、RPC プログラムとバージョン番号を、トランスポート固有のポート番号にマップします。portmap プログラムは、リモートプログラムの動的結合を可能にします。
>
>1.`サーバーが portmap に登録する`
>
>2.`クライアントは、サーバーのポートを portmap から得る`
>
>3.`クライアントが、サーバーを呼び出す`
>
>予約ポート番号は少ないのに対して、リモートプログラム数は非常に多くなる可能性があります。したがって、よく知られたポートでポートマッパーを実行しておけば、その他のリモートプログラムのポート番号はポートマッパーに問い合わせることによって得られます。図 E–1 では、 a、111、b、c はポート番号を表し、111 はポートマッパーに割り当てられたポート番号です。

https://docs.oracle.com/cd/E19253-01/816-3978/6ma7kltpa/index.html#:~:text=portmap%20%E3%81%AE%E6%93%8D%E4%BD%9C-,portmap%20%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB,111%20%E3%81%AF%E3%83%9D%E3%83%BC%E3%83%88%E3%83%9E%E3%83%83%E3%83%91%E3%83%BC%E3%81%AB%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%89%E3%82%8C%E3%81%9F%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%A7%E3%81%99%E3%80%82,-%E3%83%9D%E3%83%BC%E3%83%88%E3%83%9E%E3%83%83%E3%83%91%E3%83%BC%E3%81%AF%E3%83%96%E3%83%AD%E3%83%BC%E3%83%89%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88

# 初期コネクション・プロトコルのプロセスサーバーで待っているときは代替をする
>マシン上に存在している多くのサーバー・プロセスはまれにしか使用されない。それゆえ全てのサーバー・プロセスをあらかじめ起動しておいて、TASPアドレスを一日中リッスンし続けるのは無駄が多い。図6−9に、`初期コネクション・プロトコル(initial connection protocol)`として知られる代替手法を示す。
### 同時に複数のポートを持つプロセスサーバー
>全てのサーバー・プロセスが周知のTSAPで待ち受ける代わりに、遠隔のユーザーにサービスを提供する各マシンが、`頻繁には利用されないサーバー・プロセスのプロキシ（代理）として振る舞う特別なプロセス・サーバー(process server)`を持つ。このサーバーは`UNIXシステム上ではinetd`と呼ばれている。`プロセス・サーバーは同時にいくつかのポートを受け持ち、コネクション要求を待つ`。

### プロセスサーバーがサーバー・プロセスを生成して要求に応じる
>プロセス・サーバーは要求を受けとった後、`ユーザーの要求するサーバー・プロセスを生成`する。生成されたサーバー・プロセスは、`ユーザーとのコネクションを継承し、要求された仕事を実行`する。`プロセス・サーバーは新規の要求を待ち受けるために、再び待ち受ける状態に戻る`。この手法は、サーバー・プロセスが要求に応じて起動できる場合にのみ適用できる

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
アドレッシング

# コネクションの要求を受け付けるポートを設定する
>あるアプリケーションが遠隔のアプリケーション・プロセスに対してコネクションを確立するときは、遠隔のエンド・ポイントのどのプロセスに接続するかを指定する必要がある。通常利用される手法は、コネクション要求を待ち受ける`プロセスのトランスポート・アドレスを定義`することである。これらの`エンド・ポイントは、インターネットではポート(port)`と呼ばれる。

### トランスポート/ネットワーク層でポートの用語が違う
>ここでは`トランスポート層固有のエンド・ポイントのことを、一般的な用語であTSAP(Transport Service Access Point: トランスポート・サービス・アクセス・ポイント）`で表す。それと同じように、`ネットワーク層におけるエンド・ポイント（すなわちネットワーク層のアドレス）をNSAP(Network Service Access Point:ネットワーク・サービス・アクセス・ポイント)`と呼ぶ。IPアドレスはNSAPの一例である。

### NSAPは一つ、TSAPはプロセスごとにある。
>TSAPを持つ目的は、一部のネットワークにおいて`各コンピュータはNSAPを一つだけ持つため、NSAPを共有する複数のトランスポート・エンド・ポイントを識別する`ための手段が必要がだからである。

* 自身に対してLISTEN呼び出しによってTSAPを結びつける
* CONNECT要求で相手のTSAPに対してトランスポートコネクションが確立される。


# どのプロセスがどのポートと結びついているのかを知るのか？
>ホスト1のユーザー・プロセスはどうやってメール・サーバーがTSAP1522に結び付けられていることを知るのだろうか。`歴史的にメール・サーバーがTSAP1522に結び付けられ、ネットワーク・ユーザーがそれを学ぶ`ということが考えれる。この場合、サービスは固有のTSAPアドレスを持ち、例えばUNIXの`/etc/serviceファイルのようなよく知られた場所のファイルに登録`される。そのファイルはどのサーバーがどのポートに固定的に結び付けられているかをメール・サーバーがTCP25番ポートを使用しているといったような事実とともに管理している。

### /etc/servicesを調べる
>/etc/servicesファイルは、TCPやUDPのポート番号と、そのポートを利用するサービス（あるいはプロトコル名）の情報を対応させるファイルです。
>
>実際に/etc/servicesファイルの内容を見てみましょう。
```
ssh            22/tcp                          # The Secure Shell (SSH) Protocol
ssh            22/udp                          # The Secure Shell (SSH) Protocol
```
https://linuc.org/study/knowledge/511/#:~:text=/etc/services%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AF%E3%80%81TCP%E3%82%84,udp%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20The%20Secure%20Shell%20(SSH)%20Protocol

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
AWS PrivateLink cross-region connectivity 検証

# AWS PrivateLink now supports cross-region connectivity

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/aws-privatelink-across-region-connectivity/

PrivateLinkがクロスリージョン接続に対応、とあるので何ができるようになったのか検証しました。
期待値は、あるリージョンにVPCEndpointを作成すれば、他リージョンのS3バケットなどに接続できるようになることです。


## 結局何ができるようになったのか
先に結論です。

:::note info
自前サービスのエンドポイントサービスを構築する時にサービスリージョンが指定できるようになり、サービスリージョンで指定したリージョンでリージョンを跨いだエンドポイントが作成できるようになった。
:::

## 何が変わったのか

### Endpointサービスの作成
Iralandリージョンで検証します。
“Create endpoint service”で自前のサービス作成をする際に、オプションで「Service Regions」の設定項目が増えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/c82d31b9-0c13-af2b-aa6e-b7311c3ebdbe.png)

サービスリージョンは複数指定できます。
サービスを作成するのはeu-west-1(Ireland)で、サービスリージョンをus-east-1(N.Virginia)、us-west-2(Oregon)の二つ指定して作成します。
(選択肢には出てきますが、ここで発表にあるサポートリージョン以外を指定するとエラーになります。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/4d0278ef-5020-2bd6-d879-fed6d071eea4.png)

### Endpointの作成

OregonリージョンでEndpointの作成を実施します。

EndpointServiceを作るときに、ServiceRegionとして選択したリージョンで、Create Endpointするとき、(“AWS services”ではなく)
“Endpoint services that use NLBs and GWLBs”や“PrivateLink Ready partner services”を選択し、Enable Cross Region endpointをチェックすると「他のリージョンで自前作成したエンドポイントサービス」を直接指定できる動きとなります。
今回は“Endpoint services that use NLBs and GWLBs”を選択し、サービスリージョンとして先ほどサービスを作成したeu-west-1を指定します。
以下のようにService Name Verfiedとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/ed997eac-3904-2933-1ca7-9cc283ae448b.png)

### サービスリージョンとして指定しなかった場合
サービスリージョンとして指定しなかったリージョンで同様に指定するとエンドポイントの検証がエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/1a06523a-6dcd-5079-b9e6-86575d3b7b52.png)

### サポートされていないリージョン
サポートリージョン以外では、Enable Cross Region endpointのチェックボックスが表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/b0a60d67-bde8-5379-5778-f517329ecb72.png)

## AWSサービスではどうなっているか
AWSサービスを選択してエンドポイントを作成する場合は他のリージョンのサービスは指定できないようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/6f6a7def-11a2-803b-7f0c-0cc00a129fe0.png)

ただし、「Service Region」というカラムが増えているので、AWS側で各サービスを別リージョンで使用できるように今後展開していくのでは、と期待しています。

# まとめ
検証の結果、AWS PrivateLink cross-region connectivityは現状では自前で作成したエンドポイントのサービスだけが対象のようであることがわかりました。
今後の機能拡充に期待しています。
crypto-policiesによる暗号スイートの一括管理

# 概要
- RHEL8以降、RHEL系統のLinuxディストリビューションには、crypto-policiesパッケージが含まれるようになりました
- この記事はcyrpto-policiesについての備忘録です


# crypto-policiesとは

crypto-policiesは、TLS、SSH、DNSSec、およびKerberosの各プロトコルや、それらを利用するサーバー、あるいはJavaアプリケーション等について、従来の個別での暗号スイート管理・設定を省力化し、サーバー単位で一括管理しやすくするものです

:::note
従来Linuxでは、アプリやライブラリごとに個別に暗号スイートの管理をしていました。しかし一部のアプリやライブラリで十分な強度のある暗号スイート設定を維持していても、もし他の箇所で**暗号スイートに脆弱な暗号が含まれていたら**、攻撃者は強固な部位を迂回して**脆弱な部位を攻撃**するでしょう。crypto-policiesを使うメリットは**暗号スイートの一括管理によって安全性を確保**することにあります
:::

# 暗号スイート(Cipher suite)とは

暗号スイートは、使用する暗号技術の組み合わせのことです
暗号技術には様々な用途や性質を持つものがあり、必要に応じて複数の暗号技術を組み合わせて使用します

:::note
- 時代の変遷や状況の変化によって、新しい暗号技術が使えるようになったり、これまで安全とされていた暗号技術が専門機関によって脆弱と判断され非推奨になったりします
- このような推奨される暗号技術の変化に合わせて、管理するシステムで使用される暗号スイートを管理することは大事なことといえます
:::

# crypto-policiesによる暗号スイート管理

crypto-policiesは、ポリシーおよびサブポリシーの組み合わせによって暗号スイートを管理します

## ポリシー

暗号スイートは基本的にポリシーに定義されています
crypto-policiesは、それぞれの性質に応じて設定されたポリシーがあります
通常はこれらを選択することによって設定します

| ポリシー | 概要 | 留意点その他 |
|:-----------|:------------|:------------|
| DEFAULT | デフォルトのポリシー | 初期状態、通常これで問題ない |
| LEGACY  | 互換性を重視したポリシー | 安全ではない暗号技術も含まれる |
| FUTURE  | 近い将来を想定したポリシー | 強力だが互換性に欠ける |
| FIPS    | 米国政府基準のポリシー | 米国政府機関で使用するためのもの |


## サブポリシー

サブポリシーは、ポリシーの断片のようなものです
より柔軟な暗号スイート管理を可能とするために、サブポリシーをポリシーに組み合わせることで、ポリシーに定義された暗号スイートから特定の暗号技術を追加したり除外したりすることが可能です


# crypto-policiesの使い方

主に`update-crypto-policies`コマンドを使います

## 現在のポリシー確認

```shell-session:現在のポリシー確認
$ update-crypto-policies --show
DEFAULT
```

## ポリシーの切り替え

```shell-session:ポリシー切り替え
$ update-crypto-policies --show
DEFAULT
$ update-crypto-policies --set FUTURE
(再起動、または必要なプロセスを再起動)
$ update-crypto-policies --show
FUTURE
```

## サブポリシーを組み合わせる

DEFAULTポリシーにSHA1を追加して、古いOSや機器と互換性を確保する場合

```shell-session:サブポリシー組み合わせ
$ update-crypto-policies --show
DEFAULT
$ update-crypto-policies --set DEFAULT:SHA1
(再起動、または必要なプロセスを再起動)
$ update-crypto-policies --show
DEFAULT:SHA1
```


## カスタマイズによるより細かな管理

ポリシーやサブポリシーは予め用意されたものだけではなく、管理者が独自に作成して適用することができます

### カスタムサブポリシーの作成

カスタムサブポリシーを作成することで、任意の内容のサブポリシーを作成することが可能です

もしDEFAULTポリシーにSHA1を追加して、古いOSや機器と互換性を確保する場合でも、それがsshに限定できるのならば、サブポリシーSHA1を用いて全体にSHA1を許可するよりも、sshに限定して許可する方が望ましいでしょう

```shell-session:カスタムサブポリシー作成・適用例
$ cat /usr/share/crypto-policies/policies/modules/SHA1.pmod
# This subpolicy adds SHA1 hash and signature support

hash = SHA1+

sign = ECDSA-SHA1+ RSA-PSS-SHA1+ RSA-SHA1+

sha1_in_certs = 1

$ cd /etc/crypto-policies/policies/modules
$ cp -a /usr/share/crypto-policies/policies/modules/SHA1.pmod SHA1_SSH.pmod
$ vi SHA1_SSH.pmod
$ cat SHA1_SSH.pmod 
# This subpolicy adds SHA1 hash and signature support

hash@SSH = SHA1+

sign@SSH = ECDSA-SHA1+ RSA-PSS-SHA1+ RSA-SHA1+

#sha1_in_certs = 1

$ update-crypto-policies --set DEFAULT:SHA1_SSH
$ systemctl restart sshd
$ update-crypto-policies --show
DEFAULT:SHA1_SSH
```


| 記述例 | 意味 |
|:-|:-|
| SHA1+ | 末尾に追加 |
| +SHA1 | 先頭に追加 |
| -SHA1 | 削除 |


### カスタムポリシーの作成

ポリシーそのものを任意の内容で作成することが可能です

```shell-session:カスタムポリシー作成・適用例
$ cd /etc/crypto-policies/policies
$ cp -a /usr/share/crypto-policies/policies/DEFAULT.pol MYPOLICY.pol
$ vi MYPOLICY.pol
$ update-crypto-policies --set MYPOLICY
(再起動)
$ update-crypto-policies --show
MYPOLICY
```
追加開発不要！NewRelic導入したけども…からの非構造化ログを活用したビジネス貢献


## はじめに
ファミリーマートのアプリ「ファミペイ」では、オブザーバビリティを高めることで、顧客体験の改善に取り組んでいます。
今回は、構造化されていないテキストログをNewRelicに取り込むことで、ログを障害原因調査以上に活用することができました。

## システムの状況
- ネイティブアプリ→サーバ→DBのオーソドックスな構成
- 協力会社にシステム開発を委託
- サーバは構造化されていないテキストログを出力
- ログはAmazon CloudWatch Logsに取り込み

## これまでのログ調査
NewRelic導入前のログ調査は、「Amazon CloudWatch Logs上で発生時刻のログを流し見し、目grepする」や「高度な分析はCSVダウンロードしてエクセル上で解析」ということをしていました。

また、Amazon CloudWatch Logsのみにログを取り込んでるため、CloudWatch Logsの機能やどのログがどのように保存されているかを熟知している担当者のみログ調査可能で、ログ調査は特定の担当者に集中していました。

## NewRelicを導入するも…
このような状況の中で、NewRelicを導入してログを取り込んだところ、使いやすいUI(時刻指定、検索結果の時系列グラフ化等)のおかけでログ調査の負担は改善しました。
しかしながら、取り込むログ自体はどのようなログが出ているかを熟知している担当者のみログ調査しており、それ以上の活用はできていませんでした。

その後も「ログ調査は便利になったものの従来のログ調査ぐらいしか活用できていない」という悩みを抱え、NRUG(NewRelicユーザ会)に参加し、様々な活用事例を聞いていましたが
- 自社システムのログは構造化ログではないため、分析/集計しづらく、ビジュアライズも難しい
- 生ログはログの特徴を熟知していないと読みづらい
- ビジネス側には生ログはとっつきづらい
という理由かからこれ以上のログ活用は難しいと考えていました

## NewRelicの機能を活用！
しかし、NewRelicテクニカルサポート様と会話していく中で以下のような機能を使えるのではないかというアドバイスをいただきました
- ログの時系列グラフ化(TIMESERIES)
- ログを正規表現でパースし、複数の時系列グラフを表現する(FACET)
- ダッシュボードの変数機能

 ## 実際に作ったもの
### エラーコード別の時系列グラフ

 ![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952110/9b3591a1-3325-db05-e86d-50fd11ca28f4.png)

#### 使った機能
facet関数

#### 対象となるログ
```
[INFO ] 2024-11-20 19:01:11,434 foo=123 bar=123 action=get errorCode=123
```

#### エラーコードを正規表現でパースするNRQL
```sql
select count(*) from Log where 'action=get' facet capture(message,r'.*erroCode=(?P<erroCode>\d).*') timeseries
```

このグラフを使って、新機能リリース前後に増加しているエラーコードがないかを確認しています。
また、「Create a chart」でグラフの共有リンクを払い出し、ビジネス部門担当者にも共有しています。
これにより、チャットでのアクセス状況の報告が不要になりました。
※Pro以上のプランが必要

### ビジネス向けのBIツール
![unnamed (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952110/8c121761-32a1-1636-392d-3e681bee2d2b.png)

#### 使った機能
- 変数機能
- LookupTable(エラーコードをCSVで取り込み)

このダッシュボードでは会員番号を入力すると、当該会員のログを表示するだけでなく、生ログをわかりやすい言葉に置き換えて表示しています。
これを使うことでログに関する知識なしに、あるお客様がいつどのような操作をしたかを調べることができるようになりました。

## 運用していて感じた課題
### ログパターンごとに正規表現を書くのが大変
NewRelicは、ログ取り込み時点でログを正規表現でパースできるGrokパターンという機能があり、これを使うことで、非構造化ログとして取り込むことができます。
この機能を使えば、NewRelic内でログを構造化ログとして扱えるので、各段に扱いやすくなります。
※Grokパターンでパースした結果は、生ログに戻せないので本番運用時は要注意

### 一つのログを複数行で出力している
2024年から複数行のログにGrokパターンが対応した

### ダッシュボードの描画に時間がかかる
①ログを個別のパーティションとして分割して取り込むことができるパーティション機能を使い、パーティションを指定したNRQLを書くことで検索が早くなる
※パーティションを分割するとLogイベントに関する既存のNRQLすべてに影響を受けるので注意
②これまで正規表現でパースするNRQLとしてcapture関数を使っていましたが、機能は制限されますがaparse関数を使うと検索が早くなる

## これからやりたいこと
#### 構造化ログの出力
ログフォーマットの変更や新機能追加ごとにNewRelic上で対応するのではなく、システムから構造化ログを出力する
#### 新機能リリースごとのダッシュボード追加対応の自動化
機能追加ごとにダッシュボードにウィジェットを追加するのではなく、リリース時にNewRelicのAPIを使って自動的にウィジェットを追加する

## おわりに
ファミリーマートでは、金融・デジタル戦略を支える自社決済アプリ「ファミペイ」の運用メンバーを募集しています！
累計2,000万ダウンロードを超え、社会インフラとなりつつある「ファミペイ」の運用に少しでもご興味があればぜひ以下サイトからご応募ください！

https://www.familymart-recruit.jp/job/630d676d-0431-4c49-a210-d6ad3913d455/
【初心者向け】bash_profileの基本とおすすめ設定まとめ



## はじめに

LinuxやmacOSを使っていると、ターミナルを開いたときに自動で設定が適用されることがあります。それを制御しているファイルの一つが`bash_profile`です。

本記事では、`bash_profile`について以下の内容を解説します。

- `bash_profile`の概要
- `bash_profile`と`bashrc`の違い
- おすすめの設定
- コピペで使える実用例

初心者の方でも理解しやすいように丁寧に説明しています。ぜひ参考にしてください！


## bash_profileとは？

`bash_profile`は、**ログインシェルが起動した際に実行される設定ファイル**です。具体的には以下のような設定を記述します。

- 環境変数の設定
- PATHの追加
- エイリアスの定義
- カスタムスクリプトの読み込み

**ファイルの場所**は通常以下になります。

```bash
~/.bash_profile
```

ターミナルを開いたとき、このファイルが読み込まれて設定が適用されます。


## bash_profileとbashrcの違い

`bash_profile`と`bashrc`はよく混同されますが、役割が異なります。

| ファイル       | 読み込まれるタイミング                          | 主な用途                         |
|----------------|---------------------------------------------|--------------------------------|
| `bash_profile` | **ログインシェル**が起動したとき                  | 環境変数の設定やログイン時の初期化処理 |
| `bashrc`       | **非ログインシェル**（新しいターミナルやスクリプト実行時） | エイリアスや関数の設定など           |

### ログインシェルと非ログインシェル
- **ログインシェル**：ターミナルを初めて開くときやSSHでログインするとき
- **非ログインシェル**：既存のターミナルで新しいシェルを開くときや、スクリプト実行時

### 統一的な設定方法
`bash_profile`内で`bashrc`を呼び出すことで、両方のシェルで同じ設定を利用できます。

```bash
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi
```

これにより、設定管理が一元化され、メンテナンスが容易になります。


## おすすめの設定例

### 1. 環境変数の設定
以下のように環境変数を設定します。

```bash
# 環境変数
export EDITOR=vim
export PATH=$PATH:$HOME/bin
```

### 2. エイリアスの定義
よく使うコマンドを短縮形で登録すると便利です。

```bash
# エイリアス
alias ll='ls -alF'
alias gs='git status'
alias gp='git pull'
```

### 3. シェルプロンプトのカスタマイズ
作業効率を上げるために、プロンプトを見やすく設定します。

```bash
# シェルプロンプト
export PS1="\u@\h \w \$ "
```

### 4. カスタムスクリプトの実行
独自のスクリプトがあれば、`bash_profile`で読み込みます。

```bash
# カスタムスクリプト
if [ -f ~/custom_script.sh ]; then
    source ~/custom_script.sh
fi
```


## コピペで使えるbash_profileのテンプレート

以下は、すぐに使える`bash_profile`のサンプルです。

```bash
# ~/.bash_profile

# bashrcの読み込み
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi

# 環境変数の設定
export PATH=$PATH:$HOME/bin
export EDITOR=vim

# エイリアスの定義
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias gs='git status'
alias gp='git pull'
alias gc='git commit -m'

# シェルプロンプトのカスタマイズ
export PS1="\u@\h \w \$ "

# カスタムスクリプトの実行
if [ -f ~/custom_script.sh ]; then
    source ~/custom_script.sh
fi

# ログイン時のメッセージ
echo "Welcome, $(whoami)! Today is $(date)."
```

**使い方**：
1. 上記のコードを`~/.bash_profile`として保存します。
2. 以下のコマンドで変更を反映します。

```bash
source ~/.bash_profile
```


## まとめ

`bash_profile`を活用することで、ターミナル操作がより効率的になります。この記事では、`bash_profile`の基本からおすすめの設定までを紹介しました。特に`bash_profile`と`bashrc`の違いを理解し、設定を整理することが重要です。

この記事が皆さんの作業環境の改善に役立てば幸いです！質問やコメントがあればぜひお寄せください。
【TIPS】Elixir で配列から要素を取り出す全ての順列を取得する

## はじめに

例えば `[1, 2, 3, 4]` という配列から 3 個の要素を取り出して並べる場合、以下のような並び（順列）が有り得ます

```elixir
[
  [1, 2, 3],
  [1, 2, 4],
  [1, 3, 2],
  [1, 3, 4],
  [1, 4, 2],
  [1, 4, 3],
  [2, 1, 3],
  [2, 1, 4],
  [2, 3, 1],
  [2, 3, 4],
  [2, 4, 1],
  [2, 4, 3],
  [3, 1, 2],
  [3, 1, 4],
  [3, 2, 1],
  [3, 2, 4],
  [3, 4, 1],
  [3, 4, 2],
  [4, 1, 2],
  [4, 1, 3],
  [4, 2, 1],
  [4, 2, 3],
  [4, 3, 1],
  [4, 3, 2]
]
```

順列の数は以下の公式で簡単に計算できます

$$
{}_nP_r = \frac{n!}{(n-r)!}
$$

しかし、実際の順列を取得するには少し工夫が必要なので、 TIPS としてまとめておきます

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/tips/all_permutations.livemd

## 順列取得モジュール

以下のコードが順列取得モジュールです

```elixir
defmodule Permutations do
  def all(list) do
    1..length(list)
    |> Enum.reduce([], fn n, acc ->
      acc ++ all(list, n)
    end)
  end

  def all(_, 0), do: [[]]
  def all([], _), do: []

  def all(list, n) do
    for x <- list,
        rest = list -- [x],
        perm <- all(rest, n - 1),
        do: [x | perm]
  end
end
```

やっていることは以下の処理です

- 配列の要素数が 1 の場合、順列も一つしか存在しない
  `[1]` の順列は `[1]` のみ
- 配列の要素数が 2 の場合、要素のうちどちらが先頭になるかで二つの順列が存在する
  `[1, 2]` の順列は `[1, 2]` と `[2, 1]`
- 配列の要素数が 3 の場合、先頭以外の要素でできる順列に先頭要素をつけた順列が存在する
  `[1, 2, 3]` の順列を考えると、以下の手順で全ての順列が作成できる
  - `[2, 3]` の順列 `[2, 3]` と `[3, 2]` それぞれに `1` を追加し、 `[1, 2, 3]` と `[1, 3, 2]` ができる
  - `[1, 3]` の順列 `[1, 3]` と `[3, 1]` それぞれに `2` を追加し、 `[2, 1, 3]` と `[2, 3, 1]` ができる
  - `[1, 2]` の順列 `[1, 2]` と `[2, 1]` それぞれに `3` を追加し、 `[3, 1, 2]` と `[3, 2, 1]` ができる

このことを再帰的に利用すると、短い長さの順列からどんどん要素を追加していくことで長い配列の場合でも全ての順列が取得できます

## 使用例

入力の配列が以下のようなものだったとします

```elixir
list = [1, 2, 3, 4]
```

取り出す数に 2 を指定して実行します

```elixir
Permutations.all(list, 2)
```

実行結果

```elixir
[[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 4], [3, 1], [3, 2], [3, 4], [4, 1], [4, 2], [4, 3]]
```

取り出す数に 3 を指定します

```elixir
Permutations.all(list, 3)
```

実行結果

```elixir
[
  [1, 2, 3],
  [1, 2, 4],
  [1, 3, 2],
  [1, 3, 4],
  [1, 4, 2],
  [1, 4, 3],
  [2, 1, 3],
  [2, 1, 4],
  [2, 3, 1],
  [2, 3, 4],
  [2, 4, 1],
  [2, 4, 3],
  [3, 1, 2],
  [3, 1, 4],
  [3, 2, 1],
  [3, 2, 4],
  [3, 4, 1],
  [3, 4, 2],
  [4, 1, 2],
  [4, 1, 3],
  [4, 2, 1],
  [4, 2, 3],
  [4, 3, 1],
  [4, 3, 2]
]
```

長さを指定しない場合、取り出す数についても全てのパターンを網羅します

```elixir
Permutations.all(list)
```

実行結果

```elixir
[
  [1],
  [2],
  [3],
  [4],
  [1, 2],
  [1, 3],
  [1, 4],
  [2, 1],
  [2, 3],
  [2, 4],
  [3, 1],
  [3, 2],
  [3, 4],
  [4, 1],
  [4, 2],
  [4, 3],
  [1, 2, 3],
  [1, 2, 4],
  [1, 3, 2],
  [1, 3, 4],
  ...
]
```

## まとめ

再帰処理を使うことで、全ての順列を取得できました

Advent of Code や AtCoder などでも活用できるので、参考にしてみてください