OmniAICreator/Qiita-1.07M huggingface dataset:
GoのStringerインターフェースについて

**Stringer**は、Go言語の標準ライブラリに含まれるインターフェースの一つで、オブジェクトを文字列に変換する際に使われます。Goのパッケージfmtでは、このStringerインターフェースを利用して、構造体やカスタム型の出力を人間にとってわかりやすい形式で提供します。この記事では、Stringerインターフェースについて基本から実務での活用法までを解説します。

**Stringerインターフェースの概要**

**Goのfmtパッケージで、ある型のインスタンスをfmt.Printlnやfmt.Sprintfなどで表示する際に、その型に応じたデフォルトの文字列表現が出力されます。しかし、開発者がよりわかりやすい、カスタムな形式で出力させたい場合には、Stringerインターフェースを実装することで、任意の文字列表現を定義できます。**

**Stringerの定義**

Stringerは以下のように定義されています。

```Go
package fmt

type Stringer interface {
    String() string
}
```

つまり、Stringメソッドを持つ任意の型はStringerインターフェースを実装したと見なされます。Stringメソッドは、その型のインスタンスを表す文字列を返すべきです。

**Stringerの基本的な使用例**

Stringerインターフェースの実装方法を見てみましょう。以下の例では、Personという構造体にStringメソッドを追加して、独自の文字列表現を提供しています。

```Go
package main

import (
    "fmt"
)

type Person struct {
    FirstName string
    LastName  string
}

// Stringerインターフェースを実装
func (p Person) String() string {
    return fmt.Sprintf("%s %s", p.FirstName, p.LastName)
}

func main() {
    person := Person{FirstName: "John", LastName: "Doe"}
    fmt.Println(person) // 出力: John Doe
}
```

この例では、Person構造体にStringメソッドを実装することで、fmt.Println(person)とした際に、FirstNameとLastNameを組み合わせた形で出力されるようになっています。

**Stringerを実装する利点**

1. デバッグを容易にする

Stringerを実装することで、fmt.Printlnを使ったデバッグが非常に容易になります。デフォルトの出力では構造体のフィールドがわかりにくい形で表示されることが多いですが、Stringメソッドをカスタマイズすることで、必要な情報を簡潔に表示することができます。

2. ロギングやエラーメッセージのカスタマイズ

アプリケーションのロギングやエラーメッセージを出力する際に、読みやすく意味のある情報を提供することが重要です。Stringerを使えば、オブジェクトの内容をわかりやすい形式でログやエラーメッセージに含めることができ、メンテナンス性が向上します。

**実務での活用例**

**1. カスタムエラーメッセージ**

Goではエラーをerror型として扱いますが、エラーの内容をわかりやすくするためにカスタムエラー型にStringerを実装することがあります。これにより、エラー発生時により詳しい情報を提供できます。

```Go
type CustomError struct {
    Code    int
    Message string
}

func (e CustomError) Error() string {
    return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}

func main() {
    err := CustomError{Code: 404, Message: "Resource not found"}
    fmt.Println(err) // 出力: Error 404: Resource not found
}
```

この例では、CustomError型にErrorメソッドを実装し、エラーメッセージをカスタマイズしています。これにより、エラーメッセージが直感的で理解しやすくなります。

**2. データのフォーマットと整形**

例えば、ログ出力やレポート生成において、特定のデータ型のフォーマットを統一する必要がある場合にStringerを実装することで、統一されたフォーマットで出力することができます。

```Go
type Order struct {
    ID    int
    Amount float64
}

func (o Order) String() string {
    return fmt.Sprintf("Order #%d: $%.2f", o.ID, o.Amount)
}

func main() {
    order := Order{ID: 1234, Amount: 250.75}
    fmt.Println(order) // 出力: Order #1234: $250.75
}
```

このように、特定のフォーマットでデータを出力することで、利用者にとって理解しやすい情報提供が可能です。

**Stringerを実装する際のベストプラクティス**

**簡潔で分かりやすい表現にする**:
Stringメソッドはデバッグやユーザー向けの出力として使われるため、簡潔で理解しやすい情報を提供するべきです。

**フォーマットの一貫性**:
出力フォーマットが変わると、テストやログ解析が難しくなることがあります。そのため、フォーマットの一貫性を保つことが重要です。

**まとめ**

**Stringerインターフェースは、Goにおけるオブジェクトの文字列表現をカスタマイズするための非常に便利なツールです。これを使うことで、デバッグやロギングの際により理解しやすい出力が得られ、アプリケーションの保守性が向上します。また、実務での使用例として、エラーメッセージのカスタマイズやデータのフォーマットの統一が挙げられます。**

Stringerを活用して、Goの開発をより効率的に進めていきましょう。

**最後までよんでいただきありがとうございます。
@y-t0910をフォロー,いいねしていただけると嬉しいです！**
チームを強くするには体験が最強って話

NECソリューションイノベータ株式会社の齊藤です。
相変わらずスクラムで価値を提供し続けられるチームを作ることを頑張っている毎日です。

※自己紹介は [こちら](https://qiita.com/m-saito_nes/items/318940ccf42f3a9b3f32#%E8%87%AA%E5%B7%B1%E7%B4%B9%E4%BB%8B) をご覧くださいませ。

## どんな課題があったか

私が見ているとあるチーム、不確実な要求でも顧客が欲しいものに近づいていけるように、またチームが自律的に成長していけるようにとスクラムのフレームワークを導入していました。

スクラムイベントは粛々と実施されているし、レトロスペクティブで改善アクションも決まる。対話だって少なくなく、心理的安全性の面でも合格点の状態ですが、スクラムコーチ（私）から見ると今ひとつブレイクスルーしないような感覚のモヤモヤがありました。悪くはないのですが、最高でもない、もっと良くしたいですよね。

例えば下記のような状況でした。

**顧客への価値提供**

- 予定されたスプリントバックログは完了する。ただ、スプリントバックログを完了させることに気持ちが向きがちで、スプリントレビューでも「終わったということ」の報告が目立つ
- スプリントレビューではステークホルダーやPOからの質疑応答が主。インクリメントに対する議論をもっと行いたい

**チームの改善**

- 現状のプロセスの改善・効率化のアクションは多く上がるが、プロセスそのものを変えてしまうようなアクションはなかなか出てこず、現状からの脱却に苦労している

## これまでやってきたこと

普段からスクラムイベントの際にはその目的や効果を都度説明しながら実施していました。また、内発的動機づけに繋がるよう、チームが課題に直面するまで改善機会の提案を待ったりと、色々とやってきました。リモートのスクラムチームなので、物理的に空間を共有できないながらもコーチング技法のあれやこれやを駆使してきました。

その結果、チームは良好な状態にまでなったのですが、改革を実現できるようなもう一段上のチームに変身するのはなかなか難しいですね。

## やってみたこと

ここまで紹介したように何か突破口がほしいと考えていたタイミングでちょうどチームがオフラインで集まる機会ができました。賞味2日間くらいの時間を確保できたので、ワークショップと実践を組み合わせてチーム変革にトライしました。

こんな構成です。

**1日目：半日間のスクラムシミュレーション**

チームメンバーにスクラムチームの役割（開発者、プロダクトオーナー、スクラムマスター）を割り当て、半日の2スプリント程度をまわすスクラムのシミュレーションをやりました。自分たちの仕事とは違い、経緯やしがらみがまったくないプロダクトなので、スクラムイベントの目的によりフォーカスできます。

シミュレーションでは私が顧客の役になって、スプリントレビューでフィードバックを得ることでプロダクトが良くなっていく感覚を体験してもらうように頑張りました。（難しかった・・・笑）

シミュレーションの最後にはラップアップとして、自分たちのチームに活かせる学びは何かをチームから共有してもらって終了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879270/0ef3f132-d121-bedd-0e11-86a109df0972.png)

（これまであまりなかった「POとコミュニケーションを多くとる」「ステークホルダーの期待に適応する」というトピックが！）

**2日目：本物のスクラムイベント**

2日目には実際のスクラムイベントを集中させ、シミュレーションの学びをすぐに実践するようにしました。例えば以下のような効果を期待しています。

- スプリントレビューで顧客から良いフィードバックを得るための行動ができる
- レトロスペクティブで効率化以外のアクションが提案される

## やってみてどうなったか

<font color="red">**大成功でした！！**</font>

まず2日目のスプリントレビューでは、狙い通り良いフィードバックを得るための行動が増えました！ワーイ
例えば・・・

- スプリントバックログが終わったかどうかの話題は皆無！
- このスプリントで何を目的にし、何を作成したかという説明からスタート
- アジェンダを事前にPOと合意してからスプリントレビューに臨んだ
- 開発者からステークホルダーに対しての質問や議論が発生した（レビューじゃない、ワーキングセッションに近づいた！）
- ステークホルダーからは次に試してみたいことの提案がなされ、それが次スプリントのゴールを決めるインプットになった

スプリントレビューの後のレトロスペクティブとスプリントプランニングでは、改善だけでなく慣習的にやってきたことを「やめる」決定ができました。（これまでは促してもなかなか・・・）

- チーム内とステークホルダーに対する説明のためにパワポ資料を作ることを止める
- スプリントプランニングで稼働時間やベロシティを予測するアジェンダを止める

今後はこれまでよりも顧客により質の高いインクリメントをより多く提示できる気しかしません！

## なぜそうなった？

ではなぜこのやり方が上手くいったのでしょうか？

### 体験することで腹落ちできた

教科書やマニュアルでは知識は得られても自分事として捉えることは難しいです。自分の身にその出来事が起こっていないからだと私は思います。
スクラムガイドや研修で得た知識に対して「あぁ！こういうことか！」という感情が得られたんじゃないでしょうか。

### 制限時間内で成功体験を得られたことで自信になった

今回のシミュレーションはCertified Scrum Master®の研修で体験したものを参考にして設計しました。その中でも話されていたのですが、時間が限られていても目的にフォーカスすれば結構なことができるし顧客に喜んでもらえる。プロダクトがもっと良くなるフィードバックを得られる。そんな成功体験で自信を持てたことで行動につながったのではと思っています。

### すぐに試して効果を実感できた

成功体験の熱が冷めないうちに実践の機会を設けました。シミュレーションだけだと「用意された環境」で上手くいっただけという思考に陥るかもしれません。自分たちの仕事で試して効果を実感することでより大きな成功体験になり、自信が深まったと思います。

## おわりに

体験最強！！！！！！

スクラムに限らず、なかなか行動が変わらないなーという悩みを抱えている方はぜひ短い時間で効果を体験するようなプログラムを試してみてください！
【言語初心者】Javascriptってどんな言語？

# はじめに
どうも、Cheesecakeです:cheese:
今回は、Javascriptという言語は一体何者なのか、解説していきます。
意外とわかっていないことが見つかるかもしれませんね！

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

# Javascriptとは
Javascriptは、Webページで複雑な処理を実現する言語。
Javaと名前が似てるけど、中身は全然違います
2022年には、**世界でもっとも使われているプログラミング言語**であるとされています。

# どんなことに使われるのか？
- Webページ上の処理
- フロントエンドの開発

# 特徴
- 理解のしやすい文法
- 派生した言語が多い
- 汎用性が高い

# フロントだけじゃない Javascript
フロントエンド開発に使われると書きましたが、
Node.jsというものを使えば、バックエンドでも動作させることができます！
Node.jsについては別の記事で紹介したいと思います。

# 結論
JavascriptはWebサイトやバックエンドまで、色々な所で使える便利な言語！
モバイルアプリについて学ぼう（まとめ）

数回に分けて学んできたモバイルアプリ
- <strong>Webアプリ</strong>

https://qiita.com/masumi-s/items/6f56b9810c04f87fd947

- <strong>ネイティブアプリ</strong>

https://qiita.com/masumi-s/items/72c962076a83c560031d

- <strong>ハイブリッドアプリ</strong>

https://qiita.com/masumi-s/items/047a73e6fd6b2e73eb1d

- <strong>PWA（プログレッシブウェブアプリ）</strong>

https://qiita.com/masumi-s/items/1cb344dba8a55b9bec0a

今回はこれらの違いをまとめて見ていきたいと思います。

# 表
Webアプリ、ネイティブアプリ、ハイブリッドアプリ、PWAの違いを表にしました

| 操作 | Webアプリ | ネイティブアプリ | ハイブリッドアプリ | PWA |
|:-----------|:------------|:------------|:------------|:------------|
| 開発技術 | Web技術（HTML, CSS, JavaScript） | プラットフォーム固有の言語（Swift, Kotlin など） |Web技術（HTML, CSS, JavaScript）+ フレームワーク| Web技術（HTML, CSS, JavaScript）+ Service Worker |
|クロスプラットフォーム[^1]| 完全にクロスプラットフォーム（ブラウザさえあれば動作）| プラットフォームごとに別々に開発が必要（iOS, Androidなど） |クロスプラットフォーム（同じコードでiOS、Android両方に対応| 完全にクロスプラットフォーム（Webブラウザ上で動作） |
| アプリアイコン | ホーム画面に追加不可 | ホーム画面に追加可能 |ホーム画面に追加可能| ホーム画面に追加可能 |
| 配布方法 | ブラウザ経由でアクセス | アプリストア（Apple App Store, Google Play） |アプリストアまたはWeb経由でアクセス| ブラウザ経由でアクセス（インストール不要、またはApp Storeでも提供可能） |
| インストール | 不要（ブラウザ経由でアクセス） | 必要（アプリストアからダウンロード） | 必要（アプリストアからダウンロード） | 任意（ブラウザ経由で直接使用可能、オプションでインストール可能） |
| 更新| 自動的に更新（サーバー側の変更で即時反映） | アプリストア経由でアップデート（設定によりユーザーの手動操作が必要） |アプリストア経由でアップデート（設定によりユーザーの手動操作が必要）|自動的に更新（サーバー側の変更で即時反映）|
| オフライン使用 | 不可（インターネット接続が必要） |可能（デバイスにインストールされているため） |一部可能（Webビュー内でオフライン機能を実装）| 可能（Service Workerによりキャッシュ保存） |
| 起動・通信の速度 | 動作が遅く、反応が鈍い | Webサイトと比較して起動や通信が速い|デバイスに合わせてパフォーマンスを最適化| 通信環境が良くない場所に行った場合でも、問題なく使用 |
| デバイス機能へのアクセス | 限られた機能（ブラウザ制限に依存、デバイスの機能にはアクセスできない） | 完全なアクセス（カメラ、GPS、センサーなど） |一部機能にアクセス可能（Webビュー内でのアクセス） | 一部機能（カメラ、GPSなど）へのアクセスは可能だが、制限がある場合がある |
| コストと開発効率 | 低（シンプルな開発が可能）|高（各プラットフォームに個別対応が必要）|中（1つのコードベースで複数プラットフォームに対応） | 低（1つのコードベースで全プラットフォームに対応） |

[^1]: <strong>クロスプラットフォーム</strong>とは、複数のOSやデバイスで同じアプリケーションを動作させることができる開発環境やフレームワークのことです


# 情報通信機器の保有状況について
総務省の「令和5年通信利用動向調査」によるとスマートフォンの割合が90.6%となり、増加傾向にあるとの事でした。
また、インターネット利用者に占めるSNSの利用者の割合は、80.8％

https://www.soumu.go.jp/johotsusintokei/statistics/data/240607_1.pdf

この結果を見てもわかるように年々、スマートフォンのモバイルアプリを触る人が増えていることがわかります。

# モバイルアプリの種類が増える理由
テクノロジーの進化、ユーザーのニーズの変化、開発者のニーズの多様化、そしてビジネスの要件の変化に関連し、モバイルアプリの選択肢が増えてきました。

- <strong>技術の進化</strong>
テクノロジーの進化により、新しいフレームワークやプラットフォームが登場し、従来のネイティブアプリ開発の枠にとらわれず、さまざまな選択肢が増え、アプリ開発の手法やツールが多様化しています。

- <strong>ユーザーの多様化するニーズ</strong>
ユーザーが求める体験や利便性が多様化しており、それに応じたアプリの形式が求められています。
例：即時性と手軽さ、オフライン対応

- <strong>コストと開発効率のバランス</strong>
開発者や企業は、限られたリソースで効率的にアプリを開発したいと考えており、これに対応するために多様なアプローチが求められています。
例：コスト削減と開発の迅速化

- <strong>ターゲット市場とビジネスニーズ</strong>
異なるターゲット市場やビジネス要件に対応するために、アプリの種類が増加しています。
例：エンタープライズ向けニーズ、一般消費者向けニーズ

- <strong>多様なデバイスとプラットフォーム</strong>
モバイル端末に限らず、スマートウォッチやテレビ、さらには車載システムなど、さまざまなデバイス向けにアプリが必要とされています。これにより、アプリの種類やプラットフォームも増えました。

- <strong>プラットフォームや市場の競争</strong>
App StoreやGoogle Playなどのアプリストアは競争が激しく、開発者や企業はユーザーの注意を引きつけるためにさまざまなアプローチを試みています。

# まとめ
多様化や時代の変化などに合わせて、これからもモバイルアプリが増え続ける可能性はありますが、それぞれのアプリのタイプには利点と欠点があり、開発目的に応じて選択することが大切なのは変わらないでしょう。
Macで「.DS_Store」ファイルを一括削除する方法 - 指定ディレクトリ内とその下層も対応！

# Macで「.DS_Store」ファイルを一括削除する方法 - 指定ディレクトリ内とその下層も対応！

## 概要  
今回は、Macを使用して指定したディレクトリ内およびその下層に含まれる「.DS_Store」ファイルを一括削除する方法を説明します。  

「.DS_Store」ファイルはMacでフォルダを開いた際に自動生成されるもので、特に共同作業やバージョン管理ツールを使用する際に不要となるケースが多いです。この方法を活用することで、効率的に不要なファイルを整理できます。

---

## 作業環境  
- **作業端末**：iMac 5K（2019）  
- **OS**：macOS  

---

## 手順  

Macの標準ターミナルを使用して以下の手順を実施します。

### 1. ターミナルを開く  
Finderで「アプリケーション > ユーティリティ > ターミナル」を選択して起動します。  

---

### 2. 対象ディレクトリに移動する  
以下のコマンドを入力し、削除対象となるディレクトリに移動します。  
```bash
cd <ディレクトリ名>
```
※ <ディレクトリ名> は各自の環境に合わせて変更してください。また、< > は削除して入力してください。

---

### 3. 「.DS_Store」ファイルを一括削除する
以下のコマンドを入力して、対象ディレクトリ内およびその下層に存在する「.DS_Store」ファイルを削除します。
```bash
find . -name ".DS_Store" -delete
```
---

### 4. 削除されたか確認する
念のため、以下のコマンドで「.DS_Store」ファイルが存在しないことを確認します。

```bash
find . -name ".DS_Store"
```
コマンド実行後に何も表示されなければ、削除が正常に完了しています。

---
# 注意事項
コマンドの実行により誤って必要なファイルを削除しないよう、対象ディレクトリを慎重に確認してください。
信頼が生むチームの力：最高の成果を引き出すチームマネジメントの秘訣

# はじめに
「良いチーム」とは何でしょうか？  
それは、メンバー全員が信頼し合い、自律的に動き、目標に向かって最大限の成果を出すチームです。しかし、それを実現するためには、リーダーが意図的に環境を整え、文化を育む必要があります。この記事では、実践的なアプローチを具体例を交えながら解説します。

---

## 1. **仲間を信頼し、権限を委任する**
信頼はリーダーから始まります。例えば、新しいタスクをメンバーに任せる際、「すべて自分で確認しないと不安」と感じるかもしれません。しかし、信頼を示すことで、メンバーの成長を促すことができます。

### 実践例：
- **定期的な1on1ミーティング**を行い、メンバーが自信を持てるようサポート。
- 「あなたに任せる」と明言し、適切なフィードバックを行う。

権限委任はリスクを伴いますが、最終的な責任をリーダー自身が取ることを明確にすれば、メンバーは安心して取り組むことができます。

---

## 2. **心理的安全性を高める雑談の力**
「心理的安全性が高いチームは成果を上げやすい」という研究結果があります。メンバーが自由に意見を言える環境を作るには、日常の雑談が効果的です。

### 実践例：
- 朝の定例ミーティングで**「最近ハマっていること」**を共有する時間を作る。
- チャットツールで、仕事に関係ない軽いトピックを投稿する。

これにより、仕事以外の部分でもメンバー同士がつながりを感じ、信頼が深まります。

---

## 3. **モチベーションを維持する仕組みを作る**
モチベーションは「外発的」と「内発的」に分けられます。外発的モチベーション（賞与、昇進など）に加えて、内発的モチベーション（達成感、成長の実感）を引き出すことが重要です。

### 実践例：
- **目標設定をSMARTにする**（Specific, Measurable, Achievable, Relevant, Time-bound）。
- 達成したタスクについて、**感謝の言葉を明確に伝える**。
  - 「素晴らしいコードレビューでした。バグを未然に防げたのはあなたのおかげです。」

これらの小さな取り組みが積み重なることで、メンバーの意欲を継続的に高められます。

---

## 4. **チームメンバーを尊敬し、適材適所を意識する**
「誰にでも得意不得意がある」という前提を理解することが大切です。例えば、論理的思考が得意なメンバーには分析タスクを、クリエイティブな発想が得意なメンバーにはアイデア出しを任せましょう。

### 実践例：
- チーム内で**スキルマトリックス**を作成し、各メンバーの強みを見える化。
- プロジェクト開始時に「このタスクは○○さんにぴったりだと思います」と役割を説明。

尊敬が伝わることで、メンバーはチームに貢献する意欲を高めます。

---

## 5. **成果物を共有し、迅速にリアクションを返す**
メンバーが作成した成果物をただ受け取るだけでは、次の成果にはつながりません。速やかにリアクションを返すことで、改善のヒントを与えたり、達成感を感じてもらえます。

### 実践例：
- 成果物をレビューする際、**ポジティブな点と改善点を具体的に伝える**。
  - ポジティブ：「コードの構造が非常に分かりやすいです。」
  - 改善点：「エラーハンドリングのカバレッジをもう少し増やせるとさらに良くなります。」

迅速なリアクションは、メンバーの成長と信頼の土台となります。

---

## 6. **サーバントリーダーとしての姿勢を持つ**
「リーダーはチームのサポーターであるべき」という考え方が、サーバントリーダーシップの基本です。リーダーがチームのために障害を取り除き、働きやすい環境を提供することで、メンバーは自律的に動きやすくなります。

### 実践例：
- タスクの進行を妨げる問題が発生した場合、リーダー自ら**解決の先頭に立つ**。
- メンバーの負担が偏っていないか、**リソース分配を定期的に見直す**。

---

## 7. **目的と目標を共有し、一体感を生む**
チーム全体が同じ方向を向くためには、目的と目標を具体的に設定し、共有することが欠かせません。

### 実践例：
- プロジェクトのキックオフ時に、**目標を「Why（なぜ）」から説明**。
  - 例：「この機能は、ユーザーが健康管理を簡単に行えるようにするために重要です。」
- 定期的な振り返りで進捗を確認し、必要なら**目標を調整**。

---

## 8. **素晴らしいチーム文化を育む**
チーム文化は、一朝一夕では生まれません。リーダー自身が模範を示し、メンバーと一緒に育てていくものです。

### 実践例：
- チームの価値観を言語化し、**定期的にその実践状況を確認**。
- 成功体験を共有し、**「このチームで働けてよかった」と感じられる瞬間**を増やす。

---

## おわりに
チームマネジメントは、単なる「管理」ではなく、「環境作り」と「文化作り」です。この記事で紹介したアプローチを一つひとつ実践することで、信頼と成果を両立する理想的なチームを作ることができます。

ぜひ、この記事を参考にして、あなたのチームをより強く、より魅力的に成長させてください！
VPSを借りてドメイン設定を行う

# はじめに
非エンジニアが勉強用にVPSを導入したので、初期設定などノウハウ蓄積のために少しずつ書き溜めていきます。  
初回はドメインを取得後の設定について  

# 利用サービス
[お名前.com](https://www.onamae.com/)
[シンVPS](https://www.shin-vps.jp/)

# ドメイン取得
お名前.comからドメイン検索し、取得可能なものから申し込んでください
>参考サイト：[ドメインを取得する｜ドメイン取るならお名前.com](https://www.onamae.com/service/domainregist/)  

# ネームサーバー変更
VPS側が準備しているネームサーバーに紐づけを行います。  
お名前.comの初期設定ネームサーバーと競合を起こすため、お名前.com側の設定を変更する必要があります  
>参考サイト：[【ドメイン】ネームサーバーの変更方法は？｜ヘルプ _ ドメイン取るならお名前.com](https://help.onamae.com/answer/20390)  

### ネームサーバー
今回はシンVPSを利用しているため、ネームサーバーは以下のものが準備されています  
| ネームサーバー | サーバー名 |
| ---- | :----:|
| ネームサーバー1 | ns1.shin-vps.ne.jp |
| ネームサーバー2 | ns2.shin-vps.ne.jp |
| ネームサーバー3 | ns3.shin-vps.ne.jp |

# レコード設定  
VPSにAレコードを設定し、ドメインとIPアドレスを紐づけます  
>参考サイト：[DNSレコードの編集 _ 他社を凌駕するシン世代VPS【シンVPS】サポートサイト](https://www.shin-vps.jp/support/manual/man_server_dns.php)

### 設定例  
webサーバーを設定する場合、サブドメイン```www```もAレコードに設定することを推奨します
| ホスト名 | 種別 | 内容 | 優先度 |
| ---- | :----: | :----:| :----: |
| mydomain.com | A | XXX.XXX.XXX.XXX | - |
| www.mydomain.com | A | XXX.XXX.XXX.XXX | - |

# ネームサーバー情報反映  
上記レコード設定まで完了後、DNSに情報反映されるまでに数時間から72時間程度かかると言われています。  
参考サイトで各地のDNSが返すIPアドレスの確認ができます
>参考サイト：[Global DNS Propagation Checker](https://www.gdnspc.com/)
Astroでimportエイリアスを設定する方法


この記事はHRBrain Advent Calendar 2024 14日目の記事です。

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

## はじめに

こんにちは。HRBrainでオウンドメディアやランディングページの開発を担当している渡邉です。

HRBrainでは、[サービスサイト](https://www.hrbrain.jp/)の開発にAstroを採用しています。

Astroは、高速なウェブサイト構築を可能にするフレームワークであり、サーバーサイドレンダリング（SSR）や静的サイト生成（SSG）を行うことができます。

この記事では、Astroプロジェクトでimportエイリアスを設定する方法と、設定する中で遭遇した問題への対処法について解説します。

https://docs.astro.build/ja/guides/imports/

## tsconfig.jsonでのエイリアス設定

TypeScriptでimportエイリアスを使用するには、`tsconfig.json`を編集します。

以下の設定例では、`@/*`形式のエイリアスを使用して、`src`配下のディレクトリを対象にしています。

```jsonc:tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "baseUrl": ".", // 追加
    "paths": {
      "@/*": ["src/*"] // 追加
    }
  }
}
```

`compilerOptions.baseUrl`が設定されていないと、エイリアスのパスが解決できないので注意して下さい。

パスを`"src/*"`のように設定することで、`src`配下に新しいディレクトリが増える場合でも、新たにエイリアス設定を追加する必要がありません。

```typescript:src/pages/index.astro
// 相対パスを使用したimport
import Button from '../../components/Button.astro';
import companyLogo from '../../assets/images/logo.png';
import someFunction from '../../utils/someFunction.ts';

// エイリアスを使用したimport
import Button from '@/components/Button.astro';
import companyLogo from '@/assets/images/logo.png';
import someFunction from '@/utils/someFunction.ts';
```

### エイリアスに関する注意点

`@types`のように、スラッシュを挟まない形式でエイリアス設定をすると、TypeScriptがそれをnpmパッケージの`@types`と誤認識し、以下のようなエラーが発生する場合があります。

```bash
Cannot find module '@types/...' or its corresponding type declarations.
```

この問題を回避するために、エイリアス名を`@/`から始めるように設定しています。

### CSSのurl()で発生するパス解決問題

2024年12月時点では、前述した設定方法だと、CSSの`url()`で画像パスを指定する際にエイリアスが正しく解決されないというバグが潜んでいました。

発生した環境は以下の通りです。

- Astro：v4.5.5
- Node：v20.17.0
- Package Manager：Yarn

https://github.com/withastro/astro/issues/9633

例えば、以下のようにCSSでエイリアスを使用すると、ビルド時にパスが解決されずエラーになりました。

```css
.image {
  background-image: url("@/images/example.png"); /* 解決されない */
}
```

この問題に対しては、`astro.config.mjs`でViteのエイリアスを設定することで、CSS内の`url()`でもエイリアスが解決されるようになりました。

```javascript:astro.config.mjs
import { fileURLToPath } from 'node:url' // 追加
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    resolve: {
      alias: {
        '@/images': fileURLToPath(new URL('./src/assets/images', import.meta.url)) // 追加
      },
    },
  },
});
```

```css
.image {
  background-image: url("@/images/example.png"); /* 解決される */
}
```

この問題はAstro本体に起因するものであり、今後のアップデートで公式による解消が期待されます。

現時点ではこの方法を利用しつつ、公式の修正を待つことにしました。

## まとめ

Astroでimportエイリアスを設定する際のポイントと、CSSの`url()`におけるパス解決問題への対処方法を紹介しました。

1. `tsconfig.json`の`compilerOptions`にimportエイリアスを設定。
2. CSSの`url()`問題を回避するには、`astro.config.mjs`でViteのエイリアス設定を追加する。

これらを参考に、エイリアスを活用して効率的なプロジェクト運用を目指してください！

## PR

HRBrainではフロントエンドエンジニア（コミュニケーションデザイン）の採用も行なっているので、ぜひ！

https://hrmos.co/pages/hrbrain/jobs/2110310

https://www.hrbrain.co.jp/recruit
SSD換装備忘録

1: この方の記事通りにクローンする

https://note.com/combat_travor/n/n931acb354e2d

2: この方の記事("ssdの容量を反映する"の部分)通りに回復パーティション削除＆ボリューム拡張する

https://qiita.com/mogumogu_nyannyan/items/3ed07a426e25efd2870f#ssd%E3%81%AE%E5%AE%B9%E9%87%8F%E3%82%92%E5%8F%8D%E6%98%A0%E3%81%99%E3%82%8B

3: 以上

補足: クローン時にエラーが出たらこの方の記事が参考になるかもしれない

https://uhiyama-lab.com/blog/dialy/ssd-clone-and-replacement-guide/
ThoughtSpot Japan コミュニティ Meet-up in Osakaに参加してきました【参加レポート】

## ThoughtSpot Japan コミュニティ Meet-up in Osakaとは
>関西地域のThoughtSpotユーザーや潜在的なユーザーの皆様が集まり、コミュニティの活性化とユーザー満足度の向上を目指します。
参加者の皆様が積極的に議論やQ&Aに参加できるインタラクティブな場です。
カジュアルな雰囲気の中で、学びや意見交換、そしてThoughtSpotコミュニティ内の有意義な交流ができます。

ThoughtSpot自体を知りたい方は[こちら](https://www.thoughtspot.com/jp)

最近、ThoughtSpot Japan コミュニティの名前が「SPOTLiGHT」に決まったこともあり、会場案内の看板には「SPOTLiGHT」が記載されていました。
![20241205_190530.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/47a00e2b-fb4d-e875-c537-9adbd0984af9.jpeg)

*本記事は12/05に大阪のMOTEXホール（MOTEX新大阪ビル）で開催された
ThoughtSpot Japan コミュニティ Meet-up in Osaka の感想記事です。

# 製品/会社の最新情報 ThoughtSpot Inc.CDO Sumeet Arora
[Gartner 2024 MQ for Analytics and BI Platforms](https://www.thoughtspot.com/data-trends/business-intelligence/gartner-magic-quadrant-bi-analytics)で、ThoughtSpotがLeaderの評価を獲得したことを紹介していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/cfd6cd09-2240-f794-e44c-7ba6ed5f6b1c.png)

Roadmapに関しても言及していて、AI機能の「Sage」が後述する「Spotter」に名称・機能変更することも発表されていました。
![20241206_135151.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/f662a7ea-a93b-4e01-c461-d5f7d97175be.jpeg)
「Spotter」と「Sage」は、両者とも自然言語で質問した内容からBI画面を出力するところは変わりませんが、後者は単一の質問に対する回答だけなのに対して、前者はループして繰り返し対話しながらBI画面などの洞察を出力してくれるみたいです！
![20241206_135224.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/c31c0835-12b9-52ef-aa17-ce2c401bf578.jpeg)

「Spotter」に関するBlog記事は[こちら](https://www.thoughtspot.com/blog/introducing-spotter-ai-analyst)

ThoughtSpotはAI活用BIツールだけではなく、包括的なデータ分析プラットフォームになっていくみたいなビジョンが伝わってきました！他社のAI活用BIツールとの差別化点についても言及されていて勉強になりました！
![20241206_135237.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/910d2066-5cdd-840d-68f7-2057dd2ddc9b.jpeg)

# 最新の製品デモンストレーション ThoughtSpot Japan Mashi Yam
以下の機能やアップデートについてのデモンストレーションがありました。

* keywordの多言語対応
以下の制約が解除されて、ロケールを日本に設定している場合でも英語のkeywordが使用できる
>一度に使用できるキーワードのセットは 1 つだけです。ロケールを日本語に設定した場合、使用できるのは日本語のキーワードのみです。英語のキーワードや他の言語も使用できません。ThoughtSpot では、Liveboard、SpotIQ などのブランド用語は翻訳されません。

https://docs.thoughtspot.com/cloud/latest/keywords-ja-JP

* 列名の多言語対応
google スプレッドシートなどを使った列名の多言語対応が可能になる

* Analyst Studio
SQL、Python、Rがかけるエディタでデータ加工ができる。
接続したDWHに合わせたSQLをAI Assistが生成してくれたり、
Python使ってAPI経由でデータ拾ってきてThoughtSpot上で使えるようにできる。これめっちゃ凄いと思う。

「Analyst Studio」に関するドキュメントは[こちら](https://docs.thoughtspot.com/cloud/latest/analyst-studio-getting-started)

# ユーザー事例 エムオーテックス株式会社 管理本部 BX推進部 芝田 沙織 様
### 「全社展開への挑戦：ThoughtSpot普及と社内教育のステップ」
サイバーセキュリティのプロダクト・サービス「LANSCOPE」を展開するエムオーテックス株式会社で、全社・全部署が使うBIツールとしてThoughtSpotを普及させたお話を聞けました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/9560230c-bca2-3bad-2d32-e5ca5f8a7381.png)
業務でデータ分析基盤構築をお手伝いする機会が多い弊社でも、せっかく作ったBI画面・ダッシュボードが使われていないというケースは聞くことがあります。MAUをKPIとして色々な施策を実施するPDCAのプロセスは、勉強になりました。

特に、ThoughtSpotの使用方法の手引きがまとまっているボードのお気に入り登録を、全社に向けてお願いするという取り組みは、450名以上の従業員規模でMAU360人を達成した結果も相まって、素晴らしいと感じました！

# まとめ

めっちゃわくわくするコミュニティイベントでした！
個人的に「Analyst Studio」の機能追加がアツいと思いました！
やれることの幅が凄く広がった分、技術的な難易度も上がるので、データ分析基盤構築支援の需要も増えそうなアップデートだと思っています！
次回以降の「SPOTLiGHT」のコミュニティイベントにも、積極的に参加&協力していきたいと思っています！
AIエージェントの自律アクションのためのNode-RED

## AIエージェント

AIエージェントとは、従来のAIがユーザーの入力したプロンプトに対して、単に情報を提供するにとどまっていたのに対し、自ら行動し、ユーザーの目標達成を支援する新たな形態に進化したAIのことを指します。

Andreessen Horowitzは、次世代B2B SaaSが、ユーザーのコンテキストを理解し、自ら課題を解決するような高度な自動化を実現すると述べています。

https://a16z.com/owning-the-workflow-in-b2b-ai-apps/

![b954edf7c9be-20240825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952120/bea3b3ae-59a2-35ba-6312-85384f9c4d58.png)

引用: https://a16z.com/owning-the-workflow-in-b2b-ai-apps/

## 環境の変化を起点としたAIエージェントの必要性

AIエージェントが私たちの生活や業務に溶け込む時代が到来しつつあります。AIエージェントがより高度なタスクを自律的に実行するためには、ユーザーの指示だけでなく、ユーザーの環境変化にも柔軟に対応できる必要があります。

環境の変化とは、ユーザーを取り巻く様々な状況の変化を指します。例えば、

- **周辺環境**: 部屋の温度、照明、音など
- **組織**: 売上、顧客数、在庫状況など
- **設備**: 機械の稼働状況、センサーデータなど
- **健康**: 自分自身のバイタルデータなど

このような多岐にわたる環境の変化をAIエージェントが的確に捉え、それに応じたアクションを実行することが、理想的な未来の姿と言えるでしょう。

## 状況把握のための取り組み

環境の変化を把握するために、[MCP（Model Context Protocol）](https://www.anthropic.com/news/model-context-protocol)などの新しいプロトコルが策定されています。しかし、既存のレガシーなソフトウェアやハードウェアから情報を収集することも不可欠です。これらのシステムは、異なるプロトコルやデータ形式を採用していることが多く、AIエージェントが直接利用できる状態ではありません。

## Node-REDに再び注目が集まる理由

このような状況下で、Node-REDが再び注目を集めています。Node-REDは、様々なデータソースから情報を収集し、それらを加工・処理するための視覚的なプログラミングツールです。Node-REDの主な特徴は以下の通りです。

- **柔軟性**: 豊富なノードライブラリにより、様々なデータ形式やプロトコルに対応可能
- **視覚化**: ノードを繋ぎ合わせることで、処理フローを直感的に理解できる
- **拡張性**: 新しい機能をカスタムノードとして追加できる
- **実績**: 10年間の実績があり、この間に数十年も歴史のある古いプロトコルにも対応済

Node-REDを活用することで、レガシーなシステムから最新のIoTデバイスまで、様々なデータソースから情報を収集し、AIエージェントに提供することができます。これにより、AIエージェントはより精度の高い判断を下し、自律的なアクションを実行できるようになります。

## まとめ

AIエージェントが真に自律的な存在となるためには、環境の変化に柔軟に対応できることが求められます。Node-REDは、そのための重要なツールの一つです。Node-REDを活用することで、レガシーなシステムとの連携を強化し、AIエージェントがより高度なタスクを実行できる環境を構築することができます。

## 更にその先の展望

更にその先の未来では、物理空間に対してAIエージェントのアクションがフィードバックされるようになると考えられます。具体的にはAIエージェントが自律的にロボット・機械・車両などに対して指示する未来です。この世界観においてもNode-REDは重要な役割を果たしていくことが期待されます。

AIエージェントに情報を与えるNode-RED、AIエージェントからの指示を橋渡しするNode-RED、いずれのユースケースも過去の豊富なNode-REDの活用事例がヒントになることでしょう。
Streamlitのst.video()で動画が再生できない時の解決方法

# 概要
streamlitによるWebアプリ開発時に，Webアプリ内でエンコードした動画が再生されない問題が発生．当該問題に対して考えられる原因の一つと，その解決策を提示する．

# 背景
## 実装したかったこと
- 画像処理を行った画像群から動画を作成
- 作成した動画をブラウザに表示

## 実装方法
### 動画エンコード
- 事前の処理で画像群のリストを作成
- opencv-pythonのVideoWriter()を使用
```
h, w, c = images[0].shape
fourcc = cv2.VideoWriter_foucc(*'mp4v')
video = cv2.VideoWriter(output_path, fourcc, fps, (w, h))

for image in images:
    video.write(image)

video.release()
```

### ブラウザ表示
- streamlitのst.video()を使用
```
st.video(output_path)
```

# 問題
- ブラウザで開くと動画が再生されない
- エラーは出力されない

# 原因
- 動画に音声が入っていないこと

# 対策
- 動画に音声を合成する
- moviepyとsoundfileを使用
## ライブラリのインストール
```
pip install moviepy soundfile
```

## 実装
```
# ライブラリのインポート
from moviepy.editor import ImageSequenceClip
from moviepy.audio.AudioClip import AudioArrayClip
import soundfile as sf

# 音が鳴らない音声データを作成
duration = n_frames / fps
silent_audio = np.zeros((int(duration * 22050), 2)
audio_clip = AudioArrayClip(silent_audio, fps=22050)

# 動画のエンコード
# opencvとmoviepyではRGBの順番が異なるので対応させる(BGR->RGB)
images = [cv2.cvtColor(image, cv2.COLOR_BGR2RGB) for image in images]
clip = ImageSequenceClip(images, fps=fps)
video_clip = clip.set_audio(audio_clip)
video_clip.write_videofile(output_path, codec='libx264', audio_codec='libvorbis', fps=fps)

st.video(output_path)
```

# 補足
- VSCodeで動画が開かない問題も音声を合成することによって解決
Reactを勉強し直す 〜 v16.0~16.4 〜

# はじめに
React19がベータ版ではあるものの2024年4月にリリースされました。

にも関わらず自分の知識は16くらいから止まっているので、再度16から勉強し直していきます。

# React 16.0~16.4
以下にReact 16.0~16.4で追加された機能について一部抜粋しながらまとめていく。

## render()の返り値
配列や文字列が返せるようになった。ただし配列の場合はkeyをつける必要あり。
```React
// 配列
render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

// 文字列
render() {
  return 'Look ma, no spans!';
}
```

## Fragment
v16.0から配列を返せるようになったが、子要素をカンマで区切らなければいけなかったり、keyをつけなければいけなかった。

v16.2でFragmentが登場したことによりkeyをつけずに書けるようになった。

```React
render() {
  return (
    <Fragment>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </Fragment>
  );
}
```

## Context API
コンポーネントツリー全体にわたってデータを共有できる。問題となる親から子へのpropsのバケツリレーをすることなくデータにアクセスできる。

Providerでラップしたコンポーネントが対象範囲。

```React
const ThemeContext = React.createContext('light');

class ThemeProvider extends React.Component {
  state = {theme: 'light'};

  render() {
    return (
      <ThemeContext.Provider value={this.state.theme}>
        {this.props.children}
      </ThemeContext.Provider>
    );
  }
}

class ThemedButton extends React.Component {
  render() {
    return (
      <ThemeContext.Consumer>
        {theme => <Button theme={theme} />}
      </ThemeContext.Consumer>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <ThemeProvider>
        <ThemedButton />
      </ThemeProvider>
    );
  }
}
```

## createRef API
DOM要素やクラスコンポーネントのインスタンスに直接アクセスするためのもの。

ただし、Reactはstateやpropsを通じて状態が管理されるべきであり、refは直接的なDOM操作を行うためできる限り使用はしない方が良い。

```React
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }
}
```

## forwardRef API
親コンポーネントから子コンポーネントにrefを渡す（フォワードする）ためのもの。これによって親コンポーネントから子コンポーネントのDOMノードやクラスインスタンスに直接アクセスできる。

```React
// 子コンポーネント
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// 親コンポーネント
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
```

## Strict Mode
アプリケーションの潜在的な問題をチェックするためのツール。Fragmentのように実際には表示されない。ラップした子孫コンポーネントに対してチェックと警告を行う。

StrictModeチェックは開発モードでのみ実行されるため本番ビルドには影響しない。

v16.3では以下をサポートしてくれる。
- 安全でないライフサイクルのコンポーネントを特定する
- レガシー文字列参照APIの使用に関する警告
- 予期せぬ副作用の検出

```React
import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}
```

## PointerEvent
以下のポインタ系のイベントが使えるようになった。ただし、サポートされていないブラウザでは使えない。

- onPointerDown
- onPointerMove
- onPointerUp
- onPointerCancel
- onGotPointerCapture
- onLostPointerCapture
- onPointerEnter
- onPointerLeave
- onPointerOver
- onPointerOut

# 参考

https://ja.legacy.reactjs.org/blog/2017/09/26/react-v16.0.html
No ST-Link device detectedの解決方法

ST-LINKを使おうと思ったらエラーになって使えないよ...という方への情報共有です。
わたしは以下を間違えていました。

### 現象
１．STM32F7ボードをつないでデバッグしようとしたら以下のエラーになり、ダウンロードできない

ST-Linkデバイスの初期化エラー。
理由: (2) ST-Link DLLエラー

２．ST-LINK Utilityでファームウエアを更新しようとしたら「No ST-Link device detected」エラーになり、接続できない。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/6bbe3283-4896-e2d3-8d18-0bf42a9ed5d8.png">

ドライバ(STSW-LINK009)、ツール(STM32 ST-LINK utility)、共に最新版であることは確認済み。

### 原因
J-LINKを使用するようにボードを書き換えていた。(すっかり忘れていた)

### ポイント
・J-LINKとST-LINKは共存しない
・デバッガの設定(デバッグプローブ)はST-LINKにしていた
・ボードはSTLinkReflash utilityでJ-LINKにしていた

### 解決方法
今回はST-LINKを使用したいので、STLinkReflashでST-LINKを使用するように書き換える。その後、改めてST-LINK Utilityでファームウエアを更新する。

① ボードをPCにつなぐ
② STLinkReflash.exeを起動(コマンドプロンプトが起動します)
③ ライセンス関連の質問に答える
④ 希望する処理を選択する(今回はST-LINKに戻すので[3]を選択）
  ```
  [0] Quit
  [1] Upgrade to J-Link
  [2] Update J-Link firmware
  [3] Restore ST-Link
  Selection>
  ```
※ この時点までにボードをつなげていないと「ERROR: ERROR: No J-Link connected to PC.」エラーになります(経験談)

⑤ ST-LINKが使えるようになっているはず

### 結果
ST-LINK Utilityから接続できました。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/0dccd033-7426-f285-9723-c4136f71cc36.png">

もちろんデバッガも使えるようになりました。
めでたし、めでたし。

### 反省
今後もJ-LINK<--->ST-LINKの切り替えはあり得るので、ボードの状態を忘れないようにしないと。ふー。

(参考)
https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/
Vim操作

## Vim 簡単操作方法

### Vimの基本モード
#### ノーマルモード
- デフォルトのモードで、カーソル移動やコマンド実行を行います。
- **入力モードやビジュアルモードから戻るには `ESC` を押します。**

#### 入力モード
- テキストを編集するモード。


#### コマンドラインモード
- ファイルの保存や終了などを実行するモード。
- ノーマルモードで **`:`** を押してコマンドラインモードに入ります。

---

## ファイルの操作
| 操作              | コマンド                    |
|-------------------|-----------------------------|
| ファイルを開く     | `vim ファイル名`             |
| 保存              | `:w`                        |
| 保存して終了      | `:wq` または `:x`           |
| 終了（保存なし）  | `:q!`                       |
| 別名で保存する    | `:w 新しいファイル名`        |

---

## テキストの編集
### 入力モードへの切り替え
| コマンド | 内容                             |
|----------|----------------------------------|
| `i`      | 現在位置に文字を挿入              |
| `a`      | カーソルの後ろに文字を挿入         |
| `o`      | 新しい行を作成して挿入            |

### 削除
| コマンド | 内容                                       |
|----------|--------------------------------------------|
| `x`      | カーソル位置の1文字を削除                   |
| `dd`     | 現在行を削除                                |
| `dG`     | カーソル位置からファイル末尾まで削除         |
| `d$`     | カーソル位置から行末まで削除                |

### コピー & ペースト
| コマンド | 内容               |
|----------|--------------------|
| `yy`     | 現在の行をコピー    |
| `p`      | 貼り付け           |
| `y`      | 選択範囲をコピー    |

---

## カーソル移動
### 基本の移動
| 操作         | コマンド       |
|--------------|---------------|
| 左に移動     | `h`           |
| 下に移動     | `j`           |
| 上に移動     | `k`           |
| 右に移動     | `l`           |
| 行頭に移動   | `0`           |
| 行末に移動   | `$`           |

### 単語単位の移動
| 移動                  | コマンド |
|-----------------------|----------|
| 次の単語へ            | `w`      |
| 前の単語へ            | `b`      |

### ページ移動
| 移動                  | コマンド    |
|-----------------------|-------------|
| 半ページ下            | `Ctrl + d`  |
| 半ページ上            | `Ctrl + u`  |

---

## 検索と置換
### 検索
| コマンド          | 内容                           |
|-------------------|--------------------------------|
| `/文字列`         | 「文字列」を下方向に検索        |
| `?文字列`         | 「文字列」を上方向に検索        |
| `n`               | 次の検索結果に移動             |
| `N`               | 前の検索結果に移動             |

### 置換
| コマンド                             | 内容                                          |
|--------------------------------------|---------------------------------------------|
| `:%s/検索文字列/置換文字列/g`         | ファイル全体で検索文字列を置換                |
| `:n,m s/検索文字列/置換文字列/g`      | 行番号`n`〜`m`の範囲で検索文字列を置換        |

#### 最後に


---
以上
rp2040のpio

# 概要

ラズパイpicoのpioは、小さいcpuです。
verilogが手に入ったのでやってみた。

# 参考にしたページ

https://github.com/lawrie/fpga_pio


# rp2040のpio
PIOにはステートマシンという小さなRISC CPUが４つ内蔵されており、ステートマシンのためのプログラムを書くことにより、プロトコルを実装します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/9bae66a9-4e16-08e3-32f9-762081162917.png)

# cpuの仕様
- 命令
命令は、９個
命令長は、16bit
メモリーは、32語
- レジスタ
受信シフトレジスタ
送信シフトレジスタ
受信バッファ
送信バッファ
プログラムカウンタ
アキュムレータ



|命令|	命令コード|内容|
|:-|:-|:-|
|JMP|	0	0	0	Delay/side-set					Condition			Address	|条件分岐。			
|WAIT|	0	0	1	Delay/side-set					Pol	Source		Index|	一定の条件が成立するまで停止。			
|IN	|0	1	0	Delay/side-set					Source			Bit count|受信シフトレジスタへビット列を読み込む。				
|OUT|	0	1	1	Delay/side-set					Destination			Bit count|送信シフトレジスタからビット列を書き出す。			
|PUSH|	1	0	0	Delay/side-set					0	IfF	Blk	0	0	0	0	0|受信シフトレジスタから受信バッファへデータを読み出す。
|PULL|	1	0	0	Delay/side-set					1	IfE	Blk	0	0	0	0	0|送信バッファから送信シフトレジスタへデータを書き出す。
|MOV|	1	0	1	Delay/side-set				Destination			Op		Source|	レジスタ等の間でデータをコピーする。	
|IRQ|	1	1	0	Delay/side-set					0	Clr	Wait	Index|割り込みフラグの読み書き。			
|SET|	1	1	1	Delay/side-set					Destination			Data	|GPIOピンやレジスタに即値を書き込む。

# ディスアセンブラを書いた。

https://qiita.com/ohisama@github/items/4e43ca9bd36c2214a9b5

# アセンブラを書いた。

https://qiita.com/ohisama@github/items/d810d41a85fa6ed93b4c

```
アセンブラ
      .wrap_target
      0: set    pins, 1                    
      1: set    pins, 0                    
      .wrap


バイナリー
e101
e100


逆アセンブル
.program test
    set pins 1 [1]
    set pins 0 [1]

```

以上。
バックアップしていた2021年頃のandroid projectを再インストールしようとして苦労した話

とりあえず、当時のandroidStudio(android-studio-ide-202.7486908)をインストールして、デフォルトのテンプレートを何もせずにビルドしてみたが、エラーが出てそもそも動かなかったし、バックアッププロジェクトの再ビルドもできなかった。
次に最新のandroidStudio(android-studio-2024.2.1.11)を試してみて、デフォルトのテンプレートは動いたが、バックアッププロジェクトの再ビルドは色々なエラーが出てできなかった。

新旧のandroidStudioのログを見直してみて、おかしな事に気づいた。androidStudioの初回起動時にコンポーネントのダウンロードが行われるが、どちらもAPI35(android version 15)のplatformとtoolをダウンロードしていた。
app/build.gradleを見ると2021年当時のプロジェクトではAPI30(android version 11)がターゲットになっていた。

android-studio-ide-202.7486908をインストールし直して、SDKマネージャーでAPI30のplatformとtoolをインストールして、API35のplatformとtoolを削除した所、デフォルトのテンプレートも動作するし、バックアッププロジェクトの再ビルド／インストールも出来るようになった。

**古いバージョンのandroidStudioを久々にインストールして使おうとすると、コンポーネントは最新のものをダウンロードして、内部で不整合を起こしてそもそもビルドできなくなる模様。**

SDKマネージャーのplatformの画面
![pic01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979214/d1affe91-6506-b9e4-6b8c-6bf011d8e2cd.png)

toolの方では、Show Package Details のチェックが必要
![pic02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979214/1b3acd77-05aa-bf4f-3e60-b567e77473b4.png)


### 検索用関連エラーメッセージ

FAILURE: Build failed with an exception.

Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.

Installed Build Tools revision 35.0.0 is corrupted.
Remove and install again using the SDK Manager.

Incompatible Gradle JVM

Cannot sync the project.

KotlinJvmAndroidCompilation with name 'debugAndroidTest' not found

Deprecated Gradle features were used in this build, making it icompatible with Gradle 9.0.

Unsupported Java.

Unable to load class 'org.gradle.initialization.BuildCompletionListener'

Gradle's dependency cache may be corrupt
ゲームサウンドの鳴らし方

音出してますか！？

グレンジのサウンドクリエーター/サウンドデザイナーのかわのです。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323938353436352f63346631346231662d326235302d383963612d333035662d6332643363393737316232392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985465/16cb19b7-38d5-da92-5bb3-415caa2900ee.png)

本日は箸休め的なコラムっぽいお話を。
「**ゲームサウンドの鳴らし方**」とありますが、ゲームサウンドはどんな曲か、どんな音かといった中身より、**どうやって鳴らされるのか**に最大の特徴があると思っています。
そして、その一番の要因は「**インタラクティブ性**」、簡単にいうと**プレイヤーによって状況がさまざま**ということです。

# ゲームサウンドの鳴らし方1　「ループ曲」


プレイヤーによって状況がさまざまと言っても、マルチエンディングとかシナリオ分岐とかそういう話では無く、ひとつのステージをクリアする時間、もっと言えばどのタイミングでどのボタンを押すかまで**プレイヤーによって違う**わけです。

例えば戦闘が30秒で終わる人もいれば、5分かかる人もいる。
制作側が3分あれば終わるだろうと思って、3分で終わる曲を作った場合、5分かかる人は**途中で曲が終わってしまう**わけです。なので、始まりと終わりがつながった、ループするように楽曲を制作します。

これが、映画やドラマの場合、尺が決まってるので、場面に合わせて盛り上がりを作り、その場面が終わると同時に曲も終わらせることができます。

状況によってBGMが変化するインタラクティブミュージックと呼ばれる手法もありますが、それも基本、ループする曲とそれを繋ぐパートで構成されています。

ループ曲というのはゲームならではの文化なのかなと思います。

![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985465/64b1b07f-3b4f-c025-1f1e-0e5ef632c0db.png)

# ゲームサウンドの鳴らし方2　「同時発音数」
言葉を補えばわかりやすいですが、
「**同時**」に「**発音**」できる「**数**」
です。

同じ敵が100匹いて一度に同じ攻撃をした場合、それに対応した効果音が100個同時になることになります。
「そんな状況ないでしょ」と思うかもしれませんが、**ゲームの状況はプレイヤー次第**。
増殖や召喚する敵を面白がって画面を埋め尽くすまで増やすプレイヤーがいてもおかしくありません。

100個同時になるとどうなるか。
**シンプルに音が100倍の大きさ**になります。だいたいの場合**歪みます**。
ものによっては処理能力がオーバーして、他の音、例えば**BGMが鳴らなくなります**。
なんにせよ没入感を損なう、良いとは言えない状況ですね。

そのため、同時に発音できる数を制限するわけです。
足音、銃などの発射音や着弾音、被ダメや与ダメの音など、たくさん鳴る可能性のあるものは制限をつけておくと安心です。

また、人間は大抵の場合一度に一つしか言葉を発することができません。
なので、ボイスはキャラクターに対して、同時発音数「1」で常に制限しておくとこれまた安心です。

# まとめ
今回は二つだけですが、ゲームサウンドならではの鳴らし方は他にも色々あります。
ゲーム遊んでる方からすれば言われてみれば当たり前の内容だと思いますが、実際にサウンドを実装する際、これらは**当たり前すぎて忘れられることも多い**です。
かと言って、一つ一つ見て聞いて、もなかなかに大変ですし、コツのいる作業が多いです。

この記事では、
「**ゲームていうのはプレイヤーによってさまざまな状況になるよー。だから、音の鳴らし方には少し工夫が要るよー**」
↑だけ覚えてもらって、あとはサウンド担当にお願いしてみましょう。
VSCode でEnterが効かなくて人生詰んだ

# 始まりは自己紹介から
はじめまして
VSCodeがまともに使えないあおげばにゃんこです。
今回はVSCcodeでEnterが　効かなくなった　or　効きづらくなった　話をしようと思います。
基本的にはしょうもな記事なので気楽に書きます。

# 最近の悩み
ここ最近VSCodeで開発する際、Enterを押しても改行しない現象が発生しました。
しかもこの症状、最長で5分近く発生していたので非常に困っていました。

# 洞察力の発揮
動作するまで待っている間、画面を見てふとあることに気づきました。

VSCodeの「ソース管理」のアイコンがずっと読み込み中であるということに!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804334/23ca5b9e-0a9c-8039-60f6-694cbc400f8f.png)

そして私は
"gitの影響でこの事態が発生しているのではなかろうか！"
という結論に至りました。

# 自演乙！
気づきを得た私はおもむろに以下のコマンドを実行しました

```
git stash list
```

すると

```
.
.
.
stash@{27}: WIP ~~~~~~~~~~~~~~~~~
stash@{28}: WIP ~~~~~~~~~~~~~~~~~
```

バケモンみたいな数字が現れました

もうお分かりですね？
私はアホみたいにgit stashコマンドを使っていたせいで、リソースをこの保持に使用していたのです。

# おかえり　快適なVSCodeライフ！

こうしてstashを削除した私は安寧を手に入れました

# 余談
stashをdropする際に28もあったので楽に消したいと考えるのがエンジニアとしての習性です。
私はshellに詳しくないので、調べてみました。
すると以下の様に実行すれば良いと判明しました

```
for i in {28..5}; do
  git stash drop stash@{$i}
done
```

※後から処理するのは削除されて番号がズレるためです
SSL、TLS、HTTP、HTTPSメモ

以下に **SSL**、**TLS**、**HTTP**、**HTTPS** の意味とそれぞれの関係について簡単に説明します。

---

### **1. SSL（Secure Sockets Layer）**
- **概要**: インターネット通信を暗号化するためのプロトコル。
- **特徴**: 
  - データの盗聴や改ざんを防ぐために、送受信されるデータを暗号化する。
  - 現在は廃止されており、後継のTLSに置き換わっています。
- **使用例**: 過去にHTTPS通信の暗号化として使用されていた。

---

### **2. TLS（Transport Layer Security）**
- **概要**: SSLの後継で、よりセキュアな暗号化プロトコル。
- **特徴**: 
  - 現在のHTTPS通信の標準暗号化プロトコル。
  - SSL 3.0を改良したもので、バージョンとしてはTLS 1.0、1.2、1.3がある。
- **使用例**: Webサイト、メール、VPNなど幅広い通信で利用。

---

### **3. HTTP（HyperText Transfer Protocol）**
- **概要**: インターネット上で情報を送受信するためのプロトコル。
- **特徴**: 
  - ウェブページのテキスト、画像、動画などをやり取りする。
  - データは暗号化されず、平文で送られるため、セキュリティが低い。
- **使用例**: 暗号化を必要としないウェブ通信。

---

### **4. HTTPS（HyperText Transfer Protocol Secure）**
- **概要**: HTTPにTLS（以前はSSL）を組み合わせたセキュアな通信プロトコル。
- **特徴**: 
  - 通信内容が暗号化され、盗聴や改ざんを防止。
  - URLが「https://」で始まり、ブラウザには鍵マークが表示される。
- **使用例**: 銀行やショッピングサイトなど、セキュリティが重要な通信。

---

### **関係性まとめ**
- **HTTP**: 暗号化なしで通信。
- **HTTPS**: HTTP + TLS（または旧SSL）で暗号化。
- **SSL/TLS**: HTTPS通信のセキュリティを担う暗号化プロトコル。

### 図解イメージ
```plaintext
HTTP:  [ブラウザ] ---- 平文 ---- [サーバー]
HTTPS: [ブラウザ] -- 暗号化(TLS) -- [サーバー]
```
【Goで学ぶコンピューターサイエンス】並列処理と並行処理の違い

## 並列処理

**並列処理**は、複数のタスクを**同時に実行**することを指します。この実行は主にマルチコアプロセッサなどの**複数のハードウェアスレッド**を活用して行われます。つまり、複数のコアがそれぞれ別々のタスクを処理することで、処理を高速化します。

### 特徴
- 複数のタスクが同じタイミングで処理される
- 並列処理には複数のCPUコアまたはスレッドが必要
- パフォーマンスの向上（処理速度の向上）

### イメージ図
```
Task 1: [----処理----]
Task 2: [----処理----]
```

### Goサンプルコード
```go
package main

import (
	"fmt"
	"math"
	"runtime"
	"sync"
)

// 配列内の要素を平方根に変換する
func parallelProcessing(arr []float64) []float64 {
	numCores := runtime.NumCPU() // 使用可能なCPUコア数
	runtime.GOMAXPROCS(numCores)

	chunkSize := len(arr) / numCores
	var wg sync.WaitGroup
	result := make([]float64, len(arr))

	// 並列で処理
	for i := 0; i < numCores; i++ {
		start := i * chunkSize
		end := start + chunkSize
		if i == numCores-1 {
			end = len(arr)
		}

		wg.Add(1)
		go func(start, end int) {
			defer wg.Done()
			for j := start; j < end; j++ {
				result[j] = math.Sqrt(arr[j])
			}
		}(start, end)
	}

	wg.Wait()
	return result
}

func main() {
	data := make([]float64, 1_000_000)
	for i := range data {
		data[i] = float64(i + 1)
	}

	result := parallelProcessing(data)
	fmt.Println("First 10 results:", result[:10])
}
```

```
Number of CPU cores: 4
First 10 results: [1 1.4142135623730951 1.7320508075688772 2 2.23606797749979 2.449489742783178 2.6457513110645907 2.8284271247461903 3 3.1622776601683795]
```

## 並行処理

**並行処理**は、複数のタスクを**同時に進めているように見せる**ことを指します。タスク間で処理を切り替えながら進行するため、実際には1つのCPUコアで複数のタスクを処理する場合もあります。

### 特徴
- タスク間の切り替えを繰り返して実行される
- 単一のコアでも実現可能
- スループットの向上（複数のタスクを効率よく管理）

### イメージ図
```
Task 1: [--処理--]         [--処理--]
Task 2:          [--処理--]         [--処理--]
```

### Goサンプルコード
```go
package main

import (
	"fmt"
	"time"
)

// 時間のかかる処理
func task(name string) {
	for i := 1; i <= 3; i++ {
		fmt.Printf("%s: step %d\n", name, i)
		time.Sleep(1 * time.Second)
	}
}

func main() {
    // 並行処理
	go task("Task A") 
	go task("Task B")
	go task("Task C")

    // プログラムが終了しないように待機
	time.Sleep(5 * time.Second)
	fmt.Println("All tasks completed")
}
```

```
Task C: step 1
Task A: step 1
Task B: step 1
Task B: step 2
Task A: step 2
Task C: step 2
Task C: step 3
Task A: step 3
Task B: step 3
All tasks completed
```
Docker、はじめてみました (Part 3)

「Docker、はじめてみました」シリーズの続編です。
※ 本記事ではWindows WSL2上の説明をしていますが、基本的にMacでも使えます

## 本記事で目指すところ
実際にdockerfileを作成し、イメージ作成とコンテナ作成を行います。
今回はPython環境の設定を目指します。
基本的にPart2と同じです。
JupyterLabを使っています。

## dockerfileの作成
Pythonのdockerイメージは色々とあるけどbullseye選んでおく
今後Dockerfileを更新していくことを考えてbase版を記載しておく
```plaintext:plaintext
# Python 3.12 ベースイメージ
FROM python:3.12-bullseye

# 作業ディレクトリを設定
WORKDIR /home/jupyter

# 必須パッケージをインストール
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Jupyter Lab のインストール
RUN pip install --no-cache-dir \
    jupyterlab

# ポート設定
EXPOSE 8888

# デフォルトのコマンド
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
```

## Dockerイメージの作成
作成したDockerfileがあるディレクトリに移動しておく
```bash:bash
docker build \
> -f py3.12-bullseye:base \
> -t py3.12:base \
> .
```
※今回はあえて具体的な名称を入れておきます！

## Dockerコンテナ作成
```bash:bash
docker run \
> --name <Dockerコンテナ名> \
> -p 8888:8888 \ # この部分でポートを割り当てている
> -v /home/<ユーザー名>/<マウントしたいディレクトリ>:/home/jupyter/<マウントしたいディレクトリ> \
> -d <Dockerイメージ名>
```
※Dockerコンテナ名は[a-zA-Z0-9][a-zA-Z0-9_.-]しか入れられないらしい

## Dockerコンテナ起動
```bash:bash
docker start <コンテナ名>
```

```bash:bash
docker logs py3.12-base
```
上記で表示されるURLにアクセスするとJupyter Labが立ち上がっている
→ ブラウザのお気に入りにでも入れておきましょう！

# 最後に
これでRとPythonがひとまず使えるようにはなった。

:::note info
**この時点で知っておくべきTipsや基本的内容があればぜひコメントください！**
:::
キャリアブレイク中にやっている勉強③ コンパイラ自作

今日もキャリアブレイク中に具体的にやっている勉強について書きます。その③は「コンパイラ自作」です。

# コンパイラ作成
コンパイラを自作したいと思ったきっかけは、[セルフホストできるCコンパイラの作り方を夏休みの特別授業で教えた話](https://turingcomplete.fm/30)を聞いたからです。ただ少なくとも普段から聞いているポッドキャストでもないし、なのに1話目でもなく30話目を聞いている理由も謎だし、自発的に選ぶタイトルでもない（少なくとも過去作りたい！と思ったことはない）ので、このポッドキャストを聞いたきっかけが全く思い出せません。。。まあ何か心のアンテナに引っかかったのでしょうか。

# 教材
兎にも角にも、コンパイラを作ったらより低レイヤーの知らないことが分かるかもしれないと思って、[低レイヤを知りたい人のためのCコンパイラ作成入門](https://www.sigbus.info/compilerbook)を読んでいます。余談ですが、このサイトを見るまで、自分はハードに近いプログラミングを低レベルと言っていましたが、このサイトを見てから低レイヤーと呼ぶようにしましたｗ。

# スタイル
勉強スタイルは昨日書いた[CS](https://qiita.com/binnmti/items/de57b4b500ae21eadcbe)と同じで、淡々と読み、気になった所は[Discord](https://discord.com/invite/7MhrBqvF)にメモしつつ、コードは写経しています。このスタイルは自分の中では確立してきているようで、今後他の勉強をする時も多分同じスタイルでやると思います。

# 画面分割
僕は32インチのディスプレイ1枚で作業しているので、CSも、コンパイラ作成も、ウィンドウを2分割して左側(Windowsキー+←)を教材、右側(Windowsキー+→)をメモに使っています。左側が教材で、右側上下でメモとコードにしたこともありますが、体験がイマイチだったので、コードの時は切り替えています。

# 進行
今のところ、教材の[半分ぐらい](https://www.sigbus.info/compilerbook#%E5%88%86%E5%89%B2%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%A8%E3%81%AF)進んでいます。ただCSのように常に把握しながら進んでいる感じではなく、書いてあることは理解出来たし、コードは写経しているけれど、実際にこれで自分でコンパイラが作れるぐらい理解出来ているかは、自分もよく分かっていません。一旦全部読まないと評価が出来ないですね。。

# 得られているもの
普通に読んでいるだけでも抽象構文木とかスタックマシーンとか学べていることは結構あるし、何よりコンパイラ作成してなければ得られないだろうなと思う知識は結構あります。コラムも面白いし、特に自分はアセンブラは本当にちょっとしか組んだことがないので、C言語のprintf出力でアセンブラを作っていく感じは、なかなか刺激的です。

# リンク
CSの勉強をしていると、コンパイラの話が出てきます。CSとコンパイラ作成はリンクする部分もあるので、そういう意味では相乗効果があり、あ、これさっきやったことと似ているなと思う体験もちらほらあります。近しい2つのことを同時に学ぶのは学習効果としても意味があるのかなと思います。

# モチベーション
実は勉強課題で選びはしたのですが、Cコンパイラに対して作りたいモチベーションはあまり強くありません。でもC#コンパイラなら話は別です！作ってみたい気持ちがニョキニョキと出てきます。とはいえ、方向転換するにしても書かれている内容の理解は必須だと思うので、一旦はテキストを最後まで読もうと思っています。

# まとめ
コンパイラ作成も、毎日1時間取っていますが、1日の勉強時間がMAXで取れない日などはわりとコンパイラ作成を短くしたり、削ったりすることもあります。ただペース的には一番早く終わる可能性が高そうだし、その後は、[低レイヤー講演会](https://gdsc-osaka-univ.connpass.com/event/333363/)で見た[オレオレ抽象機械](https://katsujukou.github.io/dam4g/)の方向に進むのも面白そうだなーと思っています。
「資料の山」と「見てませんでした」地獄を回避するための5つの対策 - おじさん流スマートな資料管理術

こんにちは！いつの間にか40を過ぎた **IT 関係**を仕事にするおじさんです。  

プロジェクトが始まると必ずついて回るのが、**「資料の山」**と**「見てませんでした」地獄**。  

この地獄、資料を送ったのに見てない人がいたり、確認のための時間が無駄になったりで、プロジェクトがどんどん非効率になりますよね。  

でも、おじさんたるもの、ここで嘆いてばかりではいられません。  
今回は、この地獄をスマートに回避するための**5つの対策**を面白く、且つ真面目にお伝えしていきます。

## 対策1: Wiki ツールを活用して情報を一元管理  
資料の山を整理整頓するには、まず **Wiki ツール**を活用するのが最も効果的です。Wiki ツールは、全員がアクセスできるオンラインの**ナレッジベース**を構築するもので、資料が散乱するのを防ぎ、誰がどこで何を見ればいいのかが明確になります。  

### 具体的な使い方  
- **プロジェクトごとに Wiki のスペース**（文書（ページ）の置場所）を作成し、スペースに階層（設計書、リリース計画書等）を作成する。階層構造を作っておくと、案外みんなその配下に文書を作成してくれます。  
- **最新情報や重要な情報を「トップページ」にリンクづけ**して、「これだけは見てください！」という内容を強調。  
- Wiki 内には大抵、**バージョン管理機能**がついていますので、誰がどの資料を更新したかも確認可能。  

**Wiki ツールの良いところ**は、資料をメールで送りつけるのではなく「ここにあります」と誘導できる点です。おじさんも Wiki を導入した結果、「どれが最新でしたっけ？」の質問が減り、資料を見てない問題が大幅に解消されました。  

クラウド上の Wiki ツールなら Notion や Confluence がメジャーですが、実際にプロジェクトで利用するとなると、価格的にちょっと、、、と思いますし、不慣れな人は結構手間取ったりします。  

まあ、色んな Wiki ツールを使った結果、、、完全に個人的なバイアスのかかった推しにはなってしまいますが、**ONES.com の ONES Wiki** が私は好きですね〜。  
ONES Project とセットになっているのですが・・・  [**簡潔で必要十分なツールにして、価格も妥当、ONES Wiki！**](https://ones.com/ja/pricing)という感じです。  

自分で言うのもなんですが、語呂が良い気がします。

## 対策2: 「読んだフラグ」を運用ルールにする  
資料を見てもらったかどうかを確認できないことが多いですよね。そこで導入したいのが、「**読んだフラグ**」を活用することです。例えば、資料を確認したら「既読」のチェックボックスを入れるようお願いする仕組みを作り、誰が資料を読んでいるかを可視化します。  

### 具体的な方法  
- **Wiki ツール**ではリアクションボタンが大抵有るので、読んだらリアクションを基本動作とする。そうすると、作成側も、嬉しくなっちゃってドキュメント作成を楽しめたりします。  
- チーム全員が目を通すべき重要資料には、「読んだ人の名前をコメントしてください」などのコメントを求める。もしくは、チェックボックスと「＠メンション」を組み合わせてチェックを入れてもらう。  

これを導入してから、おじさんの「資料、読んだ？」という確認の手間が大幅に減りました。読んでいない場合も一目でわかるので、フォローアップが楽になります。案外みんな、自分の名前が記録されると思うと「ちゃんと読もう」という気持ちになるんですよね〜。
## 対策3: 資料の「適量主義」を徹底する  
資料を送る際に「多すぎる情報」も問題の一因です。そこで**資料の適量主義**を徹底しましょう。簡潔でポイントを絞った資料にすることで、読む気を削ぐことなく、相手に必要な情報だけを伝えます。  

### 具体的な方法  
- 資料作成時には、最初に「この資料の目的」を明確にし、それ以外の情報を極力省く。  
- 詳細な情報が必要な場合は、資料本体とは別に「**参考資料リンク**」を用意して、読む必要がある人だけが詳細を確認できるようにする。  

おじさんも昔は「念のため」と情報を詰め込みすぎて、結果的に誰も読まない状況を作りがちでした。でも、適量主義を実践してから、「必要な情報がコンパクトにまとまっていて分かりやすい」とチームメンバーからも好評です。

## 対策4: 定期的な「資料確認ミーティング」を設ける  
「見てませんでした」を防ぐには、定期的な「**資料確認ミーティング**」も効果的です。あらかじめ全員が資料を確認する時間を設け、その場で不明点や不足点を解消する場を作ります。  

### 具体的なやり方  
- 資料送付後に「資料確認のための短時間ミーティング」を設定し、全員で内容をざっと確認。  
- 確認ミーティング中に「この部分は見ておいてください」と指摘し、重要箇所を強調。  

おじさんも最初は「ミーティングなんて余計な時間では？」と思っていましたが、これを実施することで「見てなかった」という状況が激減しました。短時間で終わるので、むしろ効率的です。
## 対策5: 「簡易版資料」を先に作る  
資料を送る前に、内容をざっくりまとめた「**簡易版資料**」を作成して共有するのも有効です。これは、資料全体を読むのが難しい人向けに、概要だけを簡潔に伝えるもの。まず簡易版を確認してもらい、興味を持った人が詳細版を読む、という流れを作ることができます。  

### 具体的なやり方  
- PowerPoint や Google スライドなどを使って、資料の要点を簡単な箇条書きや図解でまとめる。  
- メールやチャットで簡易版を配布し、「詳細はこちらのリンクでご確認ください」と案内する。  

おじさん的には、「資料が長くて読む気が起きない」という声も理解できます。そこで簡易版を用意したところ、まず概要を確認してくれる人が増え、その後の会議でも内容の共有がスムーズになりました。
## おわりに  
いかがでしょうか？「**資料の山**」と「**見てませんでした**」地獄は、プロジェクト進行中に避けられない課題ですが、今回紹介した5つの対策を実践することで、かなり軽減できます。  

特に**Wiki ツール**の活用や、資料の**適量主義**は、おじさん自身も効果を実感しています。プロジェクトをスムーズに進めるために、資料管理を効率化し、みんなで「資料がちゃんと活用される世界」を目指しましょう！  

他にも、「こんな Tips があるよ！」とか「これは効果的だった！」などなど、みなさんの視点やアイデアがあればぜひシェアをお願いします！  

そうすればきっと、プロジェクトでハマってしまっている、世の中のおじさんを１人でも救うことができるかもしれません。
【LLM文章校正】"隣の脚はよく牡蠣食う格だ"



問：次の文章を校正せよ。"隣の脚はよく牡蠣食う格だ"

考察
PLaMoは慣用句と判定し、（頭文字が）近い慣用句を持ってきた？
gpt-4oは形態素毎に文脈の意味がとおるように修正していると思われる。


PLaMoを使った場合

```txt
隣の芝生は青い」ということわざと「脚」を「牡蠣」に置き換える間違いが起きていると考えられます。
正しくは「隣の芝生は青い」もしくは「隣の芝生はよく見える」となります。

よって、校正後の文章は「隣の芝生はよく牡蠣食う格だ」→「隣の芝生は青い」もしくは「隣の芝生はよく見える」となります。

「格」という単語は文脈によって意味が変わるため、校正対象としていません。
もし別の意味で使用されている場合はご教示ください。
```
<br>

gpt-4oを使った場合
```
隣の客はよく牡蠣を食う客だ。
```
<br>


PlaMo ver sample code
```python:main.py
from openai import OpenAI
import os

client = OpenAI(
    base_url="https://platform.preferredai.jp/api/completion/v1",
    api_key = os.getenv("PLAMO_API_KEY")
)

def proofreading(target: str):
    try:
        query = f"以下の文章を校正しろ。「{target}」"
        res = client.chat.completions.create(
            model="plamo-1.0-prime",
            messages=[
                {
                    "role": "system",
                    "content": "",
                },
                {"role": "user", "content": query}
            ],
            max_tokens=4000,
            temperature=0,
            top_p=0.8
        )
        return res.choices[0].message.content.strip()
    except Exception as e:
        return f"エラーが発生しました: {e}"

def run():
    query = "隣の脚はよく牡蠣食う格だ"
    response = proofreading(query)
    print(response)

if __name__ == "__main__":
    run()
```