OmniAICreator/Qiita-1.07M huggingface dataset:
ThoughtSpotとTiDB Serverlessの接続方法

# はじめに
本記事は、@bohnenさんの[[TiDB] 各種BIツールからTiDB Serverlessへの接続方法](https://qiita.com/bohnen/items/7aebacca03e062ba2b16 "タイトル")を参考に、ThoughtSpotとTiDB Serverlessの接続方法について解説しております。
TiDB Serverlessと「LookerStudio」、「Tableau」、「PowerBI」の接続方法について知りたい方は、以下の@bohnenさんの記事をご覧ください。

https://qiita.com/bohnen/items/7aebacca03e062ba2b16

# TiDB Serverlessの準備
### クラスタの作成
以下の「Create Cluster」で、クラスタを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/04ffff57-2ca4-355a-689c-515e5cf44b71.png)
### データのインポート
作成したクラスタにデータをインポートします。
今回は、snowflakeのマーケットプレイスで公開されている日本の市区町村データをインポートしてみます。Local fileのインポートは、50MiBのデータ容量制限があるので、データは大阪府の市町村だけに絞っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/c470804d-52d9-90a4-c855-90616219ad15.png)
### 接続情報の取得
クラスタのOverviewに戻り、`connect`ボタンを押して接続情報を表示します。
`Generate Password`ボタンでパスワードを作成し、以下の接続情報を控えます。
* HOST
* PORT
* USERNAME
* PASSWORD
* DATABASE
![connect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/759a0210-261d-efcc-6912-7d1ec624d300.png)
# ThoughtSpotとTiDB Serverlessの接続
### 接続の作成
ThoughtSpotのデータタブから接続の作成まで遷移し、その他を選択する。
![新しい接続を作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/0ec626cf-b984-8f0c-491a-5ad4643e7102.png)
MySQLを選択し、続行をクリックする。
![Mysql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/0cd47d99-7d0d-ce8e-b417-f2f72182b636.png)
先ほど控えていた接続情報を入力する。
* HOST　→　ホスト
* PORT　→　ポート
* USERNAME　→　ユーザー
* PASSWORD　→　パスワード
* DATABASE　→　データベース
![Mysqlの接続情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/868cfad0-df18-c6bc-941c-9b2a937976af.png)
TiDB Serverlessで作成していたクラスタに、インポートしていたデータ（osaka）を選択し、接続を作成する。
![接続の作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/c0ddfbf9-7cba-ddeb-2cb5-f33636186b19.png)
接続の作成に成功すると、以下のように作成した接続が表示されます。
![成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/5e100925-93fd-36be-446e-888113498a5c.png)
# ThoughtSpot上での挙動
先ほど作成した接続（テーブル）に対して、以下を設定します。
* Sageを有効にする ※ThoughtSpotのAIによる自然言語分析機能をSageと言います
* 「City_name」などの列名に、「市町村名」といった日本語の同義語を設定する
![ThoughtSpot上での設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/f7084834-4176-53f8-c9d4-4eb831038bf4.png)
Sageで「大阪府の市町村名別の人口を可視化してください。」と、日本語でプロンプトを入力すると、AIがTiDB Serverless上のデータ（osaka）を元に、大阪府の市町村別の人口を可視化してくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126836/65c0a20f-ebed-7bd8-43eb-9c527e8d041b.png)
Tips #017 特定の条件を満たしたリストのアイテムについてだけ承認フローを飛ばしたいゾ（後編）

https://qiita.com/Novskiiiiiiiiii/items/772732191e9ce4f57875

前回の続きだ。放置していてすまない。
　
まず作成したフローを保存して実行してみよう。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/5288c72e-6ca0-e600-97ba-b286d2e8deee.png)
　
  前回のTipで以下のようなリストを作成している。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/3957d50b-dd7e-49e8-d329-4882ddbef362.png)
　
 入力パラメータには以下のように設定しているはずだ。
　

    {
      "dataset": "https://*****.sharepoint.com/sites/*****",
      "table": "*************************************",
      "$filter": " shonin_status eq '未承認' and shinsei_status eq '未申請' and shonin_user ne null"
    }
　
つまりテストデータ２だけが出力されていればよいという事になる。
　
では実行結果を見てみよう。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/a322a7de-616a-fb83-b5a2-a9e467193395.png)
　
パッと見で心が折れそうになるかもしれないが、「body」の部分を見ればOKだ。
　

    "value":

　
から始まる部分に取得されたアイテムの各項目の値が表示されている。
ユーザーが定義した項目をはじめ、内部で保持している項目も含まれている。
　 
今回の場合はTitleの部分に「テストデータ２」と表示されているので、無事に取得出来ていることがわかる。
検証するデータをあらかじめわかりやすくしておくことも大事だ。
　

    "Title": "テストデータ２（条件を満たしている）",
　
ここで取得した項目を後続処理で活用していくことがPower Automateではほぼ必須になってくる。
　
取得した値を制するものはPower Automateを制す、だ。
　
「大丈夫だろう」と過信して突き進まずに、狙ったアイテムが取れているか、
余計なアイテムが取得されていないかなど、確実に１つ１つのアクションの結果を確認してから着実に進む事をおすすめする。
　
決してあとからまとめて検証しようなどと思ってはならない。
　
さてでは続いて取得したアイテムについての承認フローを設定していこう。
　
アクションの追加で「承認」と検索して、「開始して承認を待機」を選択しよう。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/16d55dcd-4614-1d6f-7a34-6b8ebefe24eb.png)
　
「承認を作成」や「承認を待機」と何が違うのか、と気になった人が自分で検索しよう。
わからない事があったらまずは自分で調べる事は社会人の基本中の基本だ。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/e2f43fa2-f33a-548f-45da-0c2995200b6c.png)
　
承認の種類が色々と出てくるが、ここではシンプルに「承認/拒否 - 最初に応答」を選択しよう。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/692dab6b-6857-6bfb-1e8f-88dfa060eb98.png)
　
タイトルは承認者への依頼通知の件名となる。
失礼のないようにしよう。
　
担当者欄に、承認者として設定したい相手のメールアドレスを設定しよう。
ベタ打ちでも入力可能だが、ここでは前の処理で取得したアイテムにある「承認者」
のユーザー情報にあるメールアドレスを設定したい。
　
右の「詳細モードに切り替える」を選択し、「承認者 Email」を選択しよう。
　
このようにすればアイテムの情報をそのまま流用する事ができ、非常に便利だ。
　
詳細やアイテムリンクも同様に設定してくれればよい。
よしなにやってくれ。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/1f153d26-36a5-3a3d-fdf8-111e50d06f49.png)
　
ここまで設定すると何やら「For each」なるものが勝手に設定されているが臆する事はない。
　
複数の項目を取得したからには、それぞれのアイテムごとに承認フローを走らせる必要があるはずで、それを親切に設定してくれているのだ。お言葉に甘えよう。
　
ただ、場合によっては「ありがた迷惑」なケースもある。
　
が、それはFor eachの事をきちんと理解してから考えれば大丈夫だ。
　
さて、では作成したフローを実行してみよう。
　
実行したら以下のような通知が届くはずだ。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/067879f7-f091-bb03-ca7d-3ea187abcd89.png)
　
ここでは詳細やリストへのリンクを省いているが、通知するメールの本文にアイテムの詳細な情報を入れておくことで、わざわざアイテムのリンクを確認するまでもなく「承認」をクリックするだけで済む。
　
承認者にいかにストレスなく承認してもらうかをどれだけ考慮できるかが業務設計の腕の見せ所だ。
　
今回はここまでで終了とするが、実際の業務においては何かしらのエビデンスを添付しないといけない場面も多いと思う。
　
次回はアイテムに添付された添付ファイルを、承認フローに添付するというやり方にチャレンジしたい。
アイテムごとに複数の添付ファイルがある場合もあるので、一筋縄ではいかなそうだ。
　
筆者もまさにいまここの課題に直面している。
　
ともに乗り越えていこうではないか。
　
ではまた！

https://qiita.com/Novskiiiiiiiiii/items/77580100ea15ed2f40a7
【備忘録】Gmail でダークモードに対応させる方法


## はじめに

Gmail のダークモードに対応したメールを作成する際のポイントをまとめました

## 対応方法

1. メールの HTML で `color-scheme` を指定します

```html
<html>
  <head>
    <meta name="color-scheme" content="light dark" />
    <meta name="supported-color-schemes" content="light dark" />
  </head>
  <body class="contents">
    <!-- メール本文 -->
  </body>
</html>
```

2. CSS でダークモード時のスタイルを定義

```css
@media (prefers-color-scheme: dark) {
  .contents {
    background-color: #1f1f1f;
    color: #ffffff;
  }
}
```

`@media` クエリを使って、ダークモード時のスタイルを指定します

3. ウェブ環境にも対応する

```css
[data-ogsc] .contents {
  background-color: #1f1f1f;
  color: #ffffff;
}
```

`[data-ogsc]` は、ウェブ環境において
`color-scheme` が効かない問題を解決するための CSS セレクタです

## 主な注意点

- `color-scheme` は、`<meta>` タグに指定する必要がある
- `color-scheme` は、`light` と `dark` の 2 つの値を指定する

## テスト方法

おすすめのツール

https://putsmail.com/

Putsmail は、HTML メールを簡単にテストできるツールです

## まとめ

Gmail のダークモードに対応したメールを作成する際は、`color-scheme` を指定して、ダークモード時のスタイルを `@media` と `[data-ogsc]` で定義することがポイントです
Xcode16のコード予測変換機能とSwift Assist機能について試してみたこと

# この記事でわかること
- Xcode 16で導入されたコード予測変換機能(GitHub Copilot的なやつ)の有効化方法
- コード予測変換機能をざっくり動かしてみた感じ
- **Swift Assistは現時点（2024年11月10日）ではまだリリースされていない**

## 有効化方法
1. Xcode 16を開く
2. 「Editor」タブを選択
3. タブの一番下に「Show Swift Assist」という項目があるので、それをONにする
![0.有効化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213832/70aa2f04-d16f-caf0-55b7-69bcd17576ab.png)

## できたこと
- コメントを付与しておくとコードの続きを予測して表示してくれる
![1.コメントだけではまだ無理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213832/fc98ef03-1d45-5f10-16b6-d553dc3cec1c.png)
↑コメントだけではまだ予測してくれない
![2.Tと打つと予測してくれた.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213832/0a36c830-2d15-ad0d-6320-0e328cc961b5.png)
↑「Te」まで打つと予測してくれた
![4.コメント無しでもコードからある程度推測してくれる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213832/f39bd8ec-c9a9-c447-44e2-e65378c6f2a5.png)
↑コメント無しでもある程度は推測してくれそう

## できないこと
- Swift以外のコードは未対応っぽい（有効化するための機能名が「Swift Assist」なので当然か）
![3.Swiftだけしかまだ無理？.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213832/f7f2013d-9a45-5d33-dd84-9a64d494889f.png)

## Swift Assist機能は現時点（2024年11月10日）ではまだリリースされていない
[プレスリリース](https://www.apple.com/jp/newsroom/2024/06/apple-empowers-developers-and-fuels-innovation-with-new-tools-and-resources/)に記載されていたSwift Assist機能（自然言語でコード生成）を使いたくて、
Xcodeの設定や公式のリリースノートを探していたのですが、
[開発フォーラムのトピック](https://forums.developer.apple.com/forums/thread/756605)によると現時点（2024年11月10日）ではまだリリースされていないようです。

コード予測変換機能を有効化するための項目名が「 **Show Swift Assist** 」なので
「絶対どこかにあるはず！」と思って探したのに、、、やられました。
フォーラムのコメントによれば「今年後半」らしいので、それを待ちます。

# 最後に
一番最後の「**Swift Assist機能は現時点（2024年11月10日）ではまだリリースされていない**」が無念だったので、
私と同じように「Swift Assist機能の使い方」を調べる方が出ないことを願い、
この記事を作成しました。

どなたかのお役にたったら幸いです。
最後まで御覧いただきありがとうございました。
RubyでOpenAIのSpeech APIを読んで、mp3を出力する簡単なコマンドラインツールのスクリプト

## はじめに

標準入力やファイルを引数にとって、mp3を出力したい。
ChatGPT API課金勢なら、OpenAIのAPI叩くのが一番簡単。

```
echo "この文章をスピーチして" | speech.rb -o out.mp3
```

gistでもいいのだが、検索しにくいのでQiita。

## 使うもの

- [OptionParser](https://docs.ruby-lang.org/ja/latest/class/OptionParser.html) - オプション引数の解析
- [ruby-openai](https://github.com/alexrudall/ruby-openai) - OpenAIのAPIを叩くライブラリ
- [whirly](https://github.com/janlelis/whirly) - 待ち時間にスピナーを表示

## スクリプト本体

```rb:speech.rb
#! /usr/bin/env ruby

require 'optparse'
require 'openai'
require 'whirly'

options = {
  output: 'speech',
  model: 'tts-1',
  voice: 'alloy',
  response_format: 'mp3',
  speed: '1.0',
  input: nil
}

OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename($0)} [options]"

  opts.on('-o', '--output FILE', '出力ファイル名（拡張子なし） [speech]') do |v|
    options[:output] = v
  end

  opts.on('-m', '--model MODEL', '使用するモデル [tts-1] tts-1-hd') do |v|
    options[:model] = v
  end

  opts.on('-i', '--input FILE', '入力テキスト') do |v|
    options[:input] = v
  end

  opts.on('-v', '--voice VOICE', '使用するボイス [alloy] echo fable onyx nova shimmer') do |v|
    options[:voice] = v
  end

  opts.on('-f', '--response-format FORMAT', '出力形式 [mp3] opus aac flac wav pcm') do |v|
    options[:response_format] = v
  end

  opts.on('-s', '--speed SPEED', '読み上げ速度 [1.0] 0.25 - 4.0') do |v|
    options[:speed] = v
  end

  opts.on('-h', '--help', 'このヘルプメッセージを表示') do
    puts opts
    exit
  end
end.parse!

options[:input] ||= ARGF.read

client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])

Whirly.start spinner: 'dots', remove_after_stop: true
response = client.audio.speech(
  parameters: {
    model: options[:model],
    input: options[:input],
    voice: options[:voice],
    response_format: options[:response_format],
    speed: options[:speed]
  }
)

File.binwrite("#{options[:output]}.#{options[:response_format]}", response)
Whirly.stop
```

## 感想など

Rubyはこういうスクリプトがさくっとかけて助かる。

Crystalが好きなので、Crystalで実装したかったけど、ライブラリに自分でSpeech APIを追加するのが面倒くさかったのでRubyにした。ruby-openai の実装がどうなっているか確認したけれども、パラメータやレスポンスはクラスで固めておらず、将来OpenAI側のAPIが変更されても動くようになっている。Crystalのような静的言語は、かちっと構造体にする実装を選ばざるをえないことが多く、脆い。その点、動的言語はロバストなところがいい。

こういうの見ていても、静的言語がどんなときも動的言語の上位互換という話はないよなあと思う。（僕はCrystal大好きですが）
OCamlで日本語を一文字ずつ扱う

UTF-8文字列として日本語の文を一文字ずつ処理したい。

## 問題

OCamlには標準ライブラリに Unicode「文字」を扱う [Uchar](https://ocaml.org/manual/5.2/api/Uchar.html) モジュールはあるが `string` から UTF-8 「文字列」への変換とかはやってくれない。

[Uutf]() というライブラリがあって UTF-8文字列を処理してくれそうだけど、[APIリファレンス](https://erratique.ch/software/uutf/doc/Uutf/index.html)を見る限り `string` との相互変換や一文字ずつfoldするみたいな関数は用意してなさそう。

## UTF-8文字を一文字ずつ処理する関数を書きました

`string` からの変換や `fold` や `map` などできるようにしました。

型です:
```utf8.mli
type t

val fold : ('a -> Uchar.t -> 'a) -> 'a -> t -> 'a
val map : (Uchar.t -> Uchar.t) -> t -> t

val uchar_of_string : string -> Uchar.t
val string_of_uchar : Uchar.t -> string

val of_string : string -> t
val to_string : t -> string
```

実装はこうです:
```utf8.ml
type t = string

let fold f init ustr =
  Uutf.String.fold_utf_8 (fun acc _i -> function
      | `Uchar uchar -> f acc uchar
      | `Malformed _s -> acc) init ustr

let map f ustr =
  let buf = Buffer.create (String.length ustr) in
  fold (fun buf uchar -> Uutf.Buffer.add_utf_8 buf (f uchar); buf) buf ustr
  |> Buffer.contents

let uchar_of_string s =
  let decoder = Uutf.decoder ~encoding:`UTF_8 (`String s) in
  match Uutf.decode decoder with
  | `Uchar u -> u
  | _ -> failwith "Invalid UTF-8 character"

let string_of_uchar uchar =
  let buf = Buffer.create 4 in
  Uutf.Buffer.add_utf_8 buf uchar;
  Buffer.contents buf

let of_string s = s
let to_string s = s
```

## ライセンス

public domain です。ご自由にご利用ください。

## 応用

かなを一文字ずつ変換する[ファイナルファンタジー](https://www.jp.square-enix.com/ffx_x-2HD/)の[アルベド語](https://wikiwiki.jp/ffdic/%E8%A8%AD%E5%AE%9A/%E3%80%90%E3%82%A2%E3%83%AB%E3%83%99%E3%83%89%E8%AA%9E%E3%80%91)変換サイトを `js_of_ocaml` で作りました。

[![albhed](https://proof-ninja.github.io/albhed/statics/img/tw_card.png)](https://proof-ninja.github.io/albhed/?lang=al2ja&al=%E3%83%88%E3%83%BC%E3%83%81%E3%82%83%E3%83%AC%E3%82%A6%E3%80%80%E3%83%99%E3%80%80%E3%82%AF%E3%81%81%E3%83%9F%E3%83%8F%E3%82%A6%E3%82%AF%E3%81%81%E3%83%B3%E3%82%B5%E3%82%AE%E3%83%BC%E3%80%80%E3%82%AA%E3%80%80%E3%83%AF%E3%82%A6%E3%82%BC%E3%82%B4%E3%82%BE%E3%80%80%E3%83%AD%E3%83%B3%E3%82%BF%E3%83%AB%E3%83%81%E3%80%80%E3%83%A0%E3%82%AE%E3%83%83%E3%83%9B%E3%83%95%E3%82%AD%E3%83%A4%E3%82%AD%E3%82%B5)
カプレカ数

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。

## はじめに
最近 :frog: のエントリでは「娯楽数学」というジャンルを取り上げており、名前のついた合成数[^ref]を数回に渡り紹介してきました。今回の本稿でも特徴的な数字遊びでもある『カプレカ数』について紹介します。また、カプレカ数を求めるHaskellプログラム（決して効率的ではないです）も紹介します。

## カプレカ数
カプレカ数を定義する前に『カプレカ操作』という数字の計算を定義します。

:::note info
<dl><dt>カプレカ操作</dt>
<dd>正の整数 $n$ に対して、次の減算で得られる整数 $K(n)$ を求める操作を『カプレカ操作』といいます。

「$n$ の各桁を大きい順に並べた数」-「$n$ の各桁を小さい順に並べた数」

</dd></dl>
:::

例えば、
$n=175$ のときは、$K(175) = 751 - 157 = 594$
$n=3003$ のときは、$K(3003) = 3300 - 33 = 3267$
となります。

この操作を使ってカプレカ数は次のように定義されます。

:::note info
<dl><dt>カプレカ数</dt>
<dd>
カプレカ操作で不変な数、つまり $K(n) = n$ を満たす正の整数 $n$ 
</dd></dl>
:::

注：「カプレカ数」という言葉を別の意味で使うこともあります。[^kap2]

この数の名称は、インドの数学者カプレカル（Kaprekar）に由来します。彼は大学院教育を受けていませんでしたが、学校の教師として働いて、広範囲にわたったレクリエーション数学の執筆を行い、カプレカ数のほかに「[自己数（コロンビア数）](https://ja.wikipedia.org/wiki/%E8%87%AA%E5%B7%B1%E6%95%B0)」「[ハーシャッド数](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%83%E3%83%89%E6%95%B0)」「[デムロ数](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%94%E3%83%A5%E3%83%8B%E3%83%83%E3%83%88)」なども定義しています。

カプレカ数は、3桁では $495$ のみ、4桁では $6174$ のみで、5桁のカプレカ数は存在しません。最初のリストは、オンライン整数列大辞典の数列 [A099009](https://oeis.org/A099009) を参照してください。


### カプレカ数を求めるプログラム
さて、カプレカ数を求めるプログラムをHaskellで実装してみましょう。

```haskell: カプレカ数の数列を出力する 
kaprekars = [x | x <- [0..], mod x 9 == 0, k x == x] where k n = big n - small n where big = read . reverse . sort . show :: Integer -> Integer; small n = read $ sort $ show n :: Integer
```

決して効率的ではありませんが、このプログラムをGHCiで実行してみると次のように出力されます。（オンライン整数列大辞典のリストと同じように出力されます）ちなみに、９の倍数であること（`mod x 9 == 0`）は簡単に示せるためプログラムではチェックする数を減らすために条件として入れてあります。

```haskell: カプレカ数の出力
ghci> kaprekars
[0,495,6174,549945,631764,63317664,97508421,554999445,864197532^CInterrupted.
```

無限リストを出力するプログラムですので適当なタイミングで `Ctrl-C` で処理を中止しました。なお、:frog: の環境ではかなりの時間を要しました。


## おわりに
もう少し効率的にできないかとも思いますが、本稿では定義に比較的忠実にプログラムを書きました。もし良いアイディアがあれば試してみてください。

最後に、本稿を記載するために検証したHaskell環境を記しておきます。お手元の環境で検証する際に、動作が異なるときには参考になるかもしれません。

<details><summary>本稿の環境</summary>

本稿のために使用した環境は以下となります。

* macOS: Sonoma 14.6.1 (chip: Apple M1)
* GHCup: 0.1.30.0
* GHC: 9.6.6

</details>

ご一読いただきまして有り難うございます。
（●）（●） Happy Hacking!
/""　＿＿""＼


[^ref]:[ラッキー数とハッピー数](https://qiita.com/kyamaz/items/9fdfefa45aba14702f88), [ヴァンパイア数](https://qiita.com/kyamaz/items/3e13559ed016423b23ee), [スミス数](https://qiita.com/kyamaz/items/330c80063a2692e5f299), [キース数](https://qiita.com/kyamaz/items/570456620bd4415a2594)

[^kap2]:ある自然数 $n$ を2乗した数の上位の半分と下位の半分とに分けて和を取ったとき、その和が元の値 $n$ に等しくなる自然数 $n$ のことを「カプレカ数」という定義もあります。
[CodeSandbox] consoleの表示方法

# 環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0（23A344）
Homebrew 4.3.8
gh 2.52.0

# 方法
1. 矢印の`Chrome DevTools for preview`をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/43e64a8a-f64e-5976-aa4c-8efc6b379531.png)
1. 表示される
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/bcfc5728-4cf3-3d1a-9fd7-ac193b49c6bf.png)

# 参考リンク
 [Where is the console output on the new CodeSandbox Cloud Web Editor?](https://stackoverflow.com/questions/76239326/where-is-the-console-output-on-the-new-codesandbox-cloud-web-editor)
[読書メモ]プロフェッショナルプロダクトオーナー

# [読書メモ]プロフェッショナルプロダクトオーナー

## はじめに
最近、プロダクトオーナーとしての役割に興味を持ち始め、より深く理解したいと感じていました。そこで、「プロフェッショナルプロダクトオーナー」という書籍を手に取りました。この本を通じて、プロダクトオーナーの戦略的・戦術的なアプローチについて学ぶことができるのではないかと思い、読んでみることにしました。以下、その読書メモをまとめます。
![](https://storage.googleapis.com/zenn-user-upload/225bda266c03-20241110.png)

## 各章読書メモ

### 第1章：戦略

#### プロダクトマネジメントのすきま

![プロダクトマネジメントのすきま](https://storage.googleapis.com/zenn-user-upload/14af7d44ade8-20241110.png)

経営層が考える「戦略（WhyとWhen）」と、開発者が関心を持つ「戦術（WhatとHow）」の間には「すきま」が存在することを知りました。このギャップを埋めるのがプロダクトオーナーの役割であり、ビジョン、価値、検証がその鍵を握っていると感じました。

#### プロダクトのビジョン

ビジネスモデルキャンバスやリーンキャンバスといったツールを活用して、プロダクトのビジョンを具体化する方法が紹介されていました。これらの手法を使うことで、ビジネスの全体像を把握しやすくなると感じました。

#### 価値

「プロダクトはリリースされるまでは価値がない」という指摘は印象的でした。価値は最終的に収益と費用で表され、指標にインセンティブを設けてもパフォーマンスや士気は改善しないとのこと。グッドハートの法則を踏まえ、指標を目標そのものにしないことの重要性を理解しました。

#### 検証

市場でテストするまではすべてが仮説に過ぎないという考え方に共感しました。ステークホルダーからのフィードバックを積極的に取り入れることで、プロダクトの方向性に対する責任感を持ってもらえると感じました。

### 第2章：スクラム

スクラムのフレームワークについて、プロダクトオーナーの視点から詳しく解説されていました。特に以下の点が印象に残りました。

- **スクラムはフレームワーク**：その形を変えてしまうと本来の効果が得られない。
- **変更と追加**：スクラムチームがフレームワークを変更するのは望ましくないが、追加するのは良い。

これを踏まえ、スクラムの基本を尊重しつつ、チームに適した方法を模索する必要があると感じました。

### 第3章：戦術

#### プロダクトバックログ

プロダクトバックログは、機能要求や非機能要求、実験、バグ修正など、あらゆる種類の作業を受け付けることを再確認しました。スプリント内で完了できない大きすぎるアイテムは、適切なサイズになるまでリファインメントが必要であると理解しました。

#### スパイク

チームの知識が不十分な場合、スパイクを活用して調査を行う手法が紹介されていました。しかし、スパイク自体は直接的なビジネス価値を生まないため、乱用は避けるべきだと感じました。

#### プロダクトバックログの並び順

優先順位を決定する際の指標として、以下の公式が紹介されていました。

優先順位 = （ビジネス価値 + リスク） ÷ サイズ


ビジネス価値、リスク、コスト/サイズ、依存関係を総合的に考慮することで、より効果的な優先順位付けが可能になると感じました。

#### 完成

「完成」を定義する重要性を学びました。バリー・オーフレイムの例では、設計の適切さ、ドキュメントの更新、テストの実施、プロダクトオーナーの受け入れ、デモ手順の明確化などが挙げられており、チーム全体で共有すべき基準だと感じました。

#### プロダクトのスケーリング

プロダクトの規模に応じて、以下のようなチーム体制の検討が必要であると理解しました。

- **一つのプロダクトに1つの開発チーム**：スクラムの基本形態。
- **複数のプロダクトに一つの開発チーム**：効率が低下するため避けるべき。
- **複数のプロダクトに複数の開発チーム**：各プロダクトに専任チームを配置。
- **一つのプロダクトに複数の開発チーム**：大規模プロダクトへの対応策。

## 気づき

- **ビジョンの共有**：ビジョンを明確にし、チーム全体で共有することの重要性を改めて感じました。これにより、全員が同じ方向を向いて開発を進められると考えます。
- **価値の測定と指標の扱い**：指標を目標にするのではなく、価値の検証手段として活用する姿勢が大切だと気づきました。
- **ステークホルダーの巻き込み**：フィードバックを通じてステークホルダーの責任感を高めることで、プロダクトの成功につながると感じました。
- **スクラムの原則の遵守**：基本を崩さずに、必要な追加を行うことで、スクラムの効果を最大化できると理解しました。

## まとめ

「プロフェッショナルプロダクトオーナー」を読んで、プロダクトオーナーとしての役割や責務について深く学ぶことができました。特に、ビジョンの重要性や価値の最大化、ステークホルダーとの関係構築において、新たな視点を得られたと感じています。この学びを活かし、今後のプロダクト開発に貢献していきたいと思います。
【所感】G検定を受験してみて

G検定を受験してきましたので、所感をメモ程度に残しておきます。~~（まだ合否出てません）~~
24.11.25追記　合格してました。
![202411251318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539300/81cc616f-d303-a4cd-24a6-6165e80fb844.png)



## 想定読者
これからG検定の受験を考えている方へ。  
文系出身のIT営業や非エンジニア職でも、AIに関連する仕事をしているのであれば教養として取得しておくといいと思います。「**AI版ITパスポート**」みたいなものだと思ってください。

## G検定とは？
ジェネラリスト検定。日本の団体が実施している試験で、AIやディープラーニングについてビジネス・技術など色々な面から総合的に基本的な知識を学ぼうという試験です。より詳しいことは[公式サイト](https://www.jdla.org/certificate/general/#general_No01)に書いてあるのでそちらを参照してください。

（公式には推奨していませんが）オンライン試験で監視員などはおらず、自宅でも受験できるため、**実質的にカンペの閲覧が可能**です。カンペなしだと難しい問題が多いですが、カンペが使えるならそこまで難しくないと感じました。
<br>
ただし問題数がかなり多いため1問30秒～1分程度で消化しないといけません。グーグルやChatGPTで一つ一つを調べていると当然時間切れになります。
ある程度の概念を理解し、基礎問題を秒で即答できるようにした上で要点をまとめたカンペの準備が求められる試験だと思えば良いかと思います。

## 受験動機
「**AIエンジニアとして、客観的に技能を証明できるものが何一つなく、転職時などに困るのではないか？**」と思い、受験しました。
ちなみに私はサーバエンジニアDevOps→生成AIエンジニアというエンジニア系のキャリアで、AI業務に携わり始めたのはつい最近（1年以内）です。

## 受験してよかったこと
「AIエンジニア」であることを証明できる代表的な資格で、資格取得にかかる学習コストも比較的低めです。 
また、エンジニアとしてはなかなか触れることのない「AIのガバナンス」「AIに関する法律」「AI・機械学習の技術発展の歴史」なども学べるため、それなりに有意義だと思います。


最近ではAWSやMS Azureなどクラウド事業者もAI資格を新設するようになりましたが、クラウド資格はどうしても自社サービスの利用法の技術的な話に寄ってしまい、開発PJの回し方や法律、歴史、ガバナンスといった分野が手薄になってしまうあたりがネックであるように思われます。

## 受験してイマイチだったこと
この試験は基本的に用語の暗記ゲーです。基礎中の基礎がわかることを証明できるだけで、**この資格を持っていても機械学習や生成AIを設計・実装できる即戦力エンジニアの証明にはなりません**。あくまで箔がつく程度だと思ってください。

また、非エンジニアの文系職にもお勧めできる「AI版ITパスポート」ですが、テキストの説明文や問題は高校～大学程度の数学知識（微積、線形・非線形関数、行列演算）を前提として書かれているように思います。次元削減アルゴリズムや最適化問題などもその前提ベースで説明されているため、馴染みのない方には少し難しいかもしれません。

## 勉強法
1. 試験申し込み、シラバスで出題範囲を確認
2. 出題範囲を参考書でインプット
3. 模擬問題をひたすら解く
4. 覚えきれないところをカンペにまとめる
5. 受験

前提知識の量に依るので何とも言えないですが、集中してやれば2週間～2か月程度で合格可能かと思います。  
試験は奇数月開催で受験後合格発表までも2週間程度空くので、会社で成果目標に設定している、など合格のデッドラインがある場合は早めに申し込みしておきましょう。

AI業界は技術の進化が速く、**出題範囲や問題数もコロコロ変わるため最新の情報やテキストを使用することが重要です**。私が使用したテキストは版数が古く、生成AI関連の内容が薄かったです。会社の業務で勉強していたため対応できましたが。

カンペは自分でまとめても良いですが、先駆者がWEB上で公開しているものも既にあったりするのでそれを利用してもよいでしょう。ただしカンペの情報鮮度や、最新の出題範囲とマッチしているかには注意すること。

## 参考書、WEB問題集
G検定の公式ページにもおすすめ参考書一覧は載ってるのでそこから選んでもいいと思います。
（以下は2024/11時点の最新版です。書籍のリンク先はAmazon、アフィはなし）

- [深層学習教科書 ディープラーニング G検定（ジェネラリスト）公式テキスト 第3版](https://amzn.asia/d/f9R5MX9)
  ざっと一読しましょう。出題範囲の基本的な内容がまとまっており最初の一冊としてはベストですが、これだけでは網羅できてないです。機械学習のアルゴリズムなどを本気で理解しようとすると手を動かして実装という話になってくるので、最短合格を目指すのであればそこまでの深堀はお勧めしません。
  
- [Study-AI G検定模擬テスト](https://study-ai.com/generalist/) 
  WEB模擬問題集。非常に役に立ちました。生成AI関連など最新のシラバスに対応した問題も入ってます。このサイト以外にも無料でG検定の模試が受けられるサイトがあるのでどれを使っても良いですが、繰り返し解いて出題形式に慣れましょう。

- [徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 (徹底攻略シリーズ)](https://amzn.asia/d/9xwWXpt)  
  書籍形式の問題集（いわゆる「黒本」）です。解答解説はそれなりに充実していますが、版数が古く、生成AIや最新動向のトピックが少ないため、これ一冊で挑むのは危険だと思います。WEBの模試をやるならこれはナシでもいいですが念の為。
AWS CDK vs Terraform: 主要コマンドの比較ガイド

# はじめに

クラウドインフラストラクチャの管理において、Infrastructure as Code (IaC) は不可欠なアプローチとなっています。今回は、AWSのCloud Development Kit (CDK) とHashiCorpのTerraformという2つの主要なIaCツールを比較します。特に、両者の主要コマンドに焦点を当て、その違いを簡単に解説します。

# 主要コマンドの比較

## 1. プロジェクトの初期化

- CDK: `cdk init app --language=typescript`
- Terraform: `terraform init`

CDKでは言語を指定してプロジェクトを作成します。
一方、Terraformは既存のディレクトリを初期化します。

## 2. インフラストラクチャの定義

- CDK: `TypeScript、Python、Javaなどのプログラミング言語で記述`
- Terraform: `HCL (HashiCorp Configuration Language)で記述`

CDKの大きな特徴は、一般的なプログラミング言語を使用できる点です。

## 3. 構文チェックと変更プレビュー

- CDK: `cdk synth`
- Terraform: `terraform validate`

CDKの`cdk synth`はCloudFormationテンプレートを生成しながら構文チェックを行います。
Terraformの`terraform validate`は設定ファイルの構文チェックを行います。
両方とも、デプロイ前にコードの正確性を確認するために使用されます。


## 4. デプロイ

- CDK: `cdk deploy`
- Terraform: `terraform apply`

## 5. リソースの削除

- CDK: `cdk destroy`
- Terraform: `terraform destroy`

## 6. 差分の確認

- CDK: `cdk diff`
- Terraform: `terraform plan`

## 7. リソースの一覧表示

- CDK: `cdk list`
- Terraform: `terraform show`

## 8. ブートストラップ（初期セットアップ）

- CDK: `cdk bootstrap`
- Terraform: 特に必要なし

CDKは初回使用時にAWS環境のセットアップが必要です。
Terraformはバックエンドの設定が必要です。

# CDKとTerraformの主な違い

1. **言語**: CDKは一般的なプログラミング言語を使用し、Terraformは独自のHCL言語を使用します
2. **柔軟性**: CDKはプログラミング言語の機能を活用できるため、より柔軟な設計が可能です
3. **クラウド対応**: Terraformはマルチクラウドをサポートしていますが、CDKは主にAWSに特化しています

# まとめ

| ステップ | Terraform | AWS CDK |
|---------|-----------|---------|
| 1. 初期化 | `terraform init` | `cdk init app --language=typescript` |
| 2. 構文チェック | `terraform validate` | `cdk synth` |
| 3. プラン確認 | `terraform plan` | `cdk diff` |
| 4. デプロイ | `terraform apply` | `cdk deploy` |
| 5. 破棄 | `terraform destroy` | `cdk destroy` |


AWS CDKとTerraformは両方とも強力なIaCツールですが、使用方法や特徴に違いがあります。プロジェクトの要件や開発チームのスキルセットに応じて、適切なツールを選択することが重要です。CDKを学習する際は、特に`cdk synth`と`cdk diff`コマンドの使い方をよく理解しておくと、開発効率が大きく向上するでしょう。

どちらのツールを選択しても、IaCアプローチを採用することで、インフラストラクチャの管理が格段に効率化されることは間違いありません。
OpenCVを用いたコーナー検出のやり方

コーナー検出は、画像内の物体の形状やエッジの特徴を捉えるのに役立ちます。今回は、代表的なコーナー検出アルゴリズムであるHarrisコーナー検出とShi-Tomasiコーナー検出を使用します。

## 必要なライブラリのインポート
OpenCVとNumPyをインポートします。OpenCVは画像処理のため、NumPyは配列操作に使用します。
```python
import cv2
import numpy as np
```

## 1. 画像の読み込みとグレースケール変換
まず、解析対象の画像を読み込み、コーナー検出を行いやすくするためにグレースケールに変換します。
```python
# 入力画像の読み込み
image = cv2.imread("input.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
```
ここでinput.jpgは解析対象の画像ファイルです。

## 2. Harrisコーナー検出
Harrisコーナー検出は、エッジや角のような急激な変化のある領域を検出するアルゴリズムです。次のコードで、OpenCVのcv2.cornerHarris関数を使用してHarrisコーナーを検出します。
```python
# Harrisコーナー検出
dst = cv2.cornerHarris(gray, 2, 3, 0.04)

# 結果を目に見える形にするため、コーナーの強度が閾値を超えた部分を強調
image[dst > 0.01 * dst.max()] = [0, 0, 255]
```
・2 はブロックサイズで、コーナー検出のウィンドウサイズを指定します。
・3 はSobel微分のカーネルサイズです。
・0.04 はHarris検出器のパラメータで、コーナーの敏感度を調整します。
dst > 0.01 * dst.max()という条件を用いることで、コーナーと判断されたピクセルを赤色（[0, 0, 255]）で強調表示しています。

## 3. Shi-Tomasiコーナー検出
Shi-Tomasiコーナー検出は、Harrisコーナー検出の改良版で、より正確な角点を検出できます。cv2.goodFeaturesToTrack関数を使って、指定した数の最も強いコーナーを取得します。
```python
# Shi-Tomasiコーナー検出
corners = cv2.goodFeaturesToTrack(gray, maxCorners=100, qualityLevel=0.01, minDistance=10)
corners = np.int0(corners)

# コーナーを描画
for corner in corners:
    x, y = corner.ravel()
    cv2.circle(image, (x, y), 3, (0, 255, 0), -1)
```
・maxCorners=100は、検出するコーナーの最大数を指定しています。
・qualityLevel=0.01は、最小限のコーナー品質を指定します。値が小さいほど多くのコーナーが検出されます。
・minDistance=10は、検出されるコーナー間の最小距離を指定します。

検出された各コーナーの座標を取得し、緑色の小さな円（半径3）を描画します。

## 4. 結果の表示
処理結果をウィンドウに表示し、コーナー検出の結果を確認します。
```python
# 結果を表示
cv2.imshow("Corners", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
cv2.imshowで結果画像を表示し、cv2.waitKey(0)でキーが押されるまでウィンドウを開いたままにします。最後にcv2.destroyAllWindows()ですべてのウィンドウを閉じます。
killallやpkillを使いこなそう

# killallやpkill 使っていますか！
Linucの勉強をしていてkillallやpgrepの便利さに感動したのでシェアしたいと思い記事を書きました。
一つのプロセスをキルする目的であればkillコマンドで事足りますが、複数のプロセスをキルしないといけない場合はkillallやpkillを使ったほうが良いです。

# killとkillallの違い
- killはプロセスIDを指定するが、killallはプロセス名を指定する
- killは1つのプロセスをキルするが、killallは複数のプロセスをキルする

# 実際に使ってみよう
実際にkillallを使うシチュエーションを再現して、killallを使ってみましょう。

↓のシェルスクリプトを作ってください。
今回はファイル名`killall_test.sh`としました。
```bash
#!/bin/bash

while true; do
  echo "無限ループなう"
  sleep 1
done
```

実行権限を付与します。
`chmod u+x killall_test.sh`

バックグラウンドでkillall_test.shを実行するコマンドを複数回実行します。(実行した回数だけプロセスが増えます)
`nohup ./killall_test.sh &`

psコマンドでkillall_test.shのプロセスが立ち上がっているか確認しましょう
`ps x | grep killall`

6つ立ち上がっているようです。

```bash
 404506 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404565 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404620 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404677 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404735 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404792 pts/0    S      0:00 /bin/bash ./killall_test.sh
 404958 pts/0    S+     0:00 grep --color=auto killall
```

`killall killall_test.sh`を実行してみましょう

すると
6つ立ち上がっていたkillall_test.shにSIGTERMが送られてプロセスが終了されました。
```
[1]   Terminated              nohup ./killall_test.sh
[2]   Terminated              nohup ./killall_test.sh
[3]   Terminated              nohup ./killall_test.sh
[4]   Terminated              nohup ./killall_test.sh
[5]-  Terminated              nohup ./killall_test.sh
[6]+  Terminated              nohup ./killall_test.sh
```

## killallでもプロセスがキルされないときは
killallやkillはSIGTERMをプロセスに送るのがデフォルトの挙動になります。
SIGTERMはプロセスに「終了してください」という命令を送って終了させるものなので、暴走してるプロセスはSIGTERMでは終了しない場合があります。
そのような場合は`killall -s SIGKILL killall_test.sh`のようにSIGKILLを指定することで強制的にプロセスをキルすることができます。(強制終了なのでSIGTERMで終了出来ない時にのみ使用するのが望ましいかと思います。)

SIGKILLでkillallすると↓のようになります。
先程のTerminatedがKilledに変わっているのが確認できると思います。
```
[1]   Killed                  nohup ./killall_test.sh
[2]   Killed                  nohup ./killall_test.sh
[3]   Killed                  nohup ./killall_test.sh
[4]   Killed                  nohup ./killall_test.sh
[5]-  Killed                  nohup ./killall_test.sh
[6]+  Killed                  nohup ./killall_test.sh
```
アウトプット学習を4ヶ月続けた結果

# はじめに

アウトプット学習を初めて4ヶ月が経ったので振り返っていきたいと思います。

ちなみにこれまでの振り返りはこちらになりますので、ご興味があれば覗いてみてください。

https://qiita.com/acu8/items/19b7fd61722435eeb282

https://qiita.com/acu8/items/30ab56eb9d77c2a67594

https://qiita.com/acu8/items/d228f1bb2dde3b28c960



# この1ヶ月の振り返り
### やったこと
- Next.jsで個人開発を進める
- Qiita記事投稿(計3記事）

# 学習を続けて気づいたこと
今までは簡単なアプリで個人開発を進めていたのですが、JISOUカリキュラムの最終段階に来たので、サービスとしてリリースできるようなプロダクト開発を進めています。

9月に企画をして着手をしていたのですが、9月終盤から10月の1ヶ月はただ闇雲に苦しんでいたように思います。
というのもまず技術力が足りないことをほぼ毎日つきつけられている感じがしました。
一つ一つの実装のハードルが高く、調べても同じようなことをしている人が少なかったり、AIに聞いてもいまいち答えがなかったりといったことが多かったからです。

そんな時に、一旦手を止め、少し時間をとって冷静に考えることがありました。

**「ユーザーに提供できる最低限の価値は何か？」**
**「まずはその価値だけに集中するようにしたらどうだろう？」**

その視点から考えると、今まで苦しんで作ろうとしていたほとんどの機能が必要ないことに気づきました。
またその視点から自分の作成しているものを見るとユーザーに使いやすいものは何か、どのようなデザイン、ページ構成だと使いやすいのか、など考える視点も変わりました。

それまではとにかく自分の作りたい多機能なアプリの構想があり、それを一気に作ろうとして思うようなスピードで進められず苦しんでいました。
上記の最低限の提供できる価値でリリースをしてみるという考え方に切り替えてからは、何が必要かがもう少しクリアになり、進めやすくなりました。

もしかしたらこの視点はアジャイル開発や自社開発をしている人には当然の考え方なのかもしれないのですが、これまでの現場ではそういう考え方をする機会がなかったので言葉で聞いたり説明されても腑に落ちませんでした。

# 今回の経験から学べたこと

- 実際に開発をしてみること、
- 苦しくても考え続けてみること、
- やめないこと
っていう流れを繰り返すことが成長には大切なのかもしれないと今月は学習を続ける中で学ぶことができました。


# おわりに
ユーザーに実際に使ってもらえるようなものを作る過程は想像していたよりも知らないことが多く、ハードルが急に高くなった感じがしました。
それでも継続することでこの記事で紹介したような気づきを得ることができるとわかったのでこれからも頑張って開発を続けていこうと思います。


# JISOUのメンバー募集中！

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
実践的なカリキュラムで、あなたのエンジニアとしてのキャリアを最短で飛躍させましょう！
興味のある方は、ぜひホームページからお気軽にカウンセリングをお申し込みください！
▼▼▼

https://projisou.jp/
FBXをVRMに変換すーる

# はじめに

metapersonを用いて、1枚の顔写真からアバター（FBX）を作成しました
https://metaperson.avatarsdk.com/

今回は、FBXをVRMに変換していきまーす

# 開発環境
- Windows 11 PC
- Unity 2021.3.4f1
- VRM-0.127.2_e16c.unitypackage

# 導入
1．UniVRMをダウンロード（VRM-0.127.2_e16c.unitypackage）
https://github.com/vrm-c/UniVRM/releases

2．Unity 2021.3.4f1を開く

3．FBXをインポートする

4．Extract Texturesからテクスチャを抽出する

5．Extract Materialsからマテリアルを抽出する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/f56c1db2-025f-1cc1-d96f-54badbdbdcc9.png)

6．RigをHumanoidに変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/3feddc7a-8023-5ee6-9cb1-a1e24fc586d2.png)

7．MaterialのShaderをUnlit/Textureに変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/0da4432d-e91b-0bf4-4eb2-27a820dee74d.png)

8．modelを選択し、VRM1 > Export VRM 1.0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/82d7e398-7d37-56b0-eb4e-4550d4bcf147.png)

9．Name、Version、Authorsを入力し、Exportする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/04e0ed9e-ad2b-8bbf-bf1b-ee6f795e40a0.png)

10．vrmが作成されていたらClusterなどにアップロードしましょう！

お疲れ様でした。
OpenCVを用いた線分のフィッティング

画像処理において、物体の輪郭を検出し、その輪郭に基づいて形状をフィッティングするのはよく行われる手法です。本記事では、PythonとOpenCVを使用して線分フィッティングを行う方法について詳しく説明します。

## 1. 必要なライブラリのインポート
まず、必要なライブラリをインポートします。OpenCVとNumPyを使います。OpenCVは画像処理、NumPyは配列操作に役立ちます。
```python
import cv2
import numpy as np
```
## 2. 画像の読み込みとグレースケール変換
次に、解析対象となる画像を読み込み、グレースケールに変換します。グレースケール化することで、画像の情報量を減らし、エッジ検出を行いやすくします。
```python
# 入力画像の読み込み
image = cv2.imread("input.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
```
ここでinput.jpgは解析対象の画像ファイルのパスです。
## 3. エッジ検出
エッジ検出にはCanny法を使います。Cannyエッジ検出は、画像内のエッジ（急激な輝度の変化部分）を抽出する手法です。OpenCVのcv2.Canny関数を使ってエッジを抽出します。
```python
# エッジ検出 (Canny)
edges = cv2.Canny(gray, 100, 200)
```
ここで、100と200はCannyエッジ検出の閾値です。
## 4. 輪郭検出
次に、エッジから輪郭を検出します。輪郭検出は、画像中の連続したエッジを集めて輪郭として扱う処理です。cv2.findContours関数を使用し、抽出したエッジから輪郭を検出します。
```python
# 輪郭の検出
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
```
cv2.RETR_TREEは、階層的な輪郭情報を取得するためのモードです。cv2.CHAIN_APPROX_SIMPLEは、輪郭の近似法を指定しており、輪郭を単純化してメモリ効率を向上させます。

## 5. 線分フィッティング
各輪郭に対して線分フィッティングを行います。cv2.fitLine関数は、最小二乗法を使って指定した輪郭に線をフィッティングします。
```python
# 線分フィッティングの処理
for contour in contours:
    # 輪郭が2点以上の場合のみ線分フィッティングが可能
    if len(contour) >= 2:
        # cv2.fitLineを使って線をフィッティング
        [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01)
        
        # フィッティングした線の始点と終点を計算して描画
        lefty = int((-x * vy / vx) + y)
        righty = int(((image.shape[1] - x) * vy / vx) + y)
        cv2.line(image, (image.shape[1] - 1, righty), (0, lefty), (0, 255, 0), 2)
```
ここでは、次のようにして線分フィッティングを行います
・cv2.fitLine関数により、最小二乗法で線の方向（vx, vy）と線上の1点（x, y）を取得します。
・フィッティングされた線を描画するために、画像の左端と右端のy座標を計算し、cv2.lineで線を引きます。

## 6. 結果の表示
最後に、フィッティングの結果を表示し、線分フィッティングの結果を確認します。
```python
# 結果を表示
cv2.imshow("Ellipses", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
cv2.imshowで画像を表示し、cv2.waitKey(0)でキーが押されるまでウィンドウを開いたままにします。cv2.destroyAllWindows()はすべてのOpenCVウィンドウを閉じます。
[Unity][RoboCup] CrossView開発日記 #0

# CrossViewとは
こちらの記事をご覧ください。

https://qiita.com/suzuki_nene/items/cbdb701622a738f1b2ee

# 開発をはじめるにあたり
Unityを使って作りたい内容は決まっていたけど、プログラミングに少しブランクがあったので、復習を兼ねて書籍でお勉強しようと思いました。

# 書籍
購入した書籍は、次の通りです。
- 『Unity 3Dゲーム開発ではじめるC#プログラミング 』

https://www.amazon.co.jp/Unity-3D%E3%82%B2%E3%83%BC%E3%83%A0%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8BC-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-impress-gear/dp/4295012459/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=

# スクリーンショット
![Hero-Born.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/843818/428d98cb-7af9-f335-0668-5f0dcedd674e.png)

# 操作方法
- WASDキーまたは上下左右の矢印キーで、前後の移動と左右の方向転換を行います。
- マウス左ボタン押下で、弾を発射します。
- 敵(Enemy)は、3発弾を受けると消えます。
- Spaceキーでジャンプします。
- フィールドの四隅にある回転するアイテムをすべて取得すると、勝ち。
- 敵(Enemy)に見つかると追いかけてくる。追いつかれるとHPが減り、０になれば負け。

# 復習と変更点
本に書いてある通り、実際にUnityでコードを書いて試してみつつ、以下のような変更を行ってみました。

- Enemyをプレハブ化して、試合開始時に塔の上に出現するようにした。
また、弾を受けてEnemyが消えた時に、新たなEnemyが再度出現を繰り返すようにした。
- Enemyは、Playerを見つけた時にPlayerが居た「座標」に対して向かってくるだけだったが、OnTriggerStay()を実装して、逃げるPlayerを追うように変更した。
- Enemyは、発見したPlayerを追っている間は、ボディーの色を変更するようにした。
- Enemyは、追っていたPlayerが検知範囲から逃げ出した時、直前に目指していたパトロールルートに戻るようにした。
- Playerは、ジャンプ処理はFixedUpdate()ではなくUpdate()の時点で実行するようにした。
- Playerの撃つ弾が、物体をすり抜けてしまう場合があったので、BulletのRigidbody->Collision Detection=Continuousに変更した。

# 書籍の感想
- これからC#を学習しようとする人向けの入門書としては良いと思います。
- Unityによるアプリ開発の内容では、ところどころ、心もとない部分がありました。

# サンプルコード
変更したコードは、次の場所にアップロードしました。

https://github.com/SuzukiNene/Hero-Born

以上です。
Reactにおける画像の配置と相対パスの扱いについて



1. **publicフォルダ内に配置した場合**:
   - `public`フォルダには、アプリケーションの静的ファイルを配置します。ここに置いた画像は、ビルド時にそのままルートにコピーされます。相対パスを使う場合は、`/画像名`の形式でアクセスします。
   - 例: `public`内に`logo.png`がある場合、URLは`/logo.png`になります。

2. **srcフォルダ内に配置した場合**:
   - `src`フォルダ内に画像を配置した場合、Webpackなどのモジュールバンドラーが画像を処理します。この場合、画像はインポートする必要があります。相対パスではなく、JavaScriptの`import`文を使います。
   - 例: `src/images/logo.png`に画像がある場合、次のようにインポートします。
     ```javascript
     import logo from './images/logo.png';
     ```
   - その後、`<img src={logo} alt="Logo" />`のように使用します。

### まとめ
- **public**: 直接URLでアクセス可能。相対パスはルートから。
- **src**: インポートして使用。相対パスはモジュールの階層に基づく。
C++でRaspberry PiのLチカ


```led.cpp
#include <wiringPi.h>
#define LED 17  // 17ピンからLEDのプラス端子に印加

int main(void) {
        wiringPiSetupSys();

        pinMode(LED, OUTPUT);

        for (int i=0 ; i < 5 ; i++) {
                digitalWrite(LED, HIGH);  //オン
                delay(500);
                digitalWrite(LED, LOW);   //オフ
                delay(500);
        }
        return 0;
}
```


GNDとpin17に接続。
回路内のLED以外に、「抵抗」を付ける必要がある。
![DSC_1733.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83724/c59c2608-6345-a82a-d5dc-2e48e7b61541.jpeg)


コンパイル
```bash
g++ -o led led.cpp -lwiringPi
```
実行
```bash
./led
```
ACDLを提唱します。その18

# 概要
ACDLとは、アプリは、クラウド、大切なデータは、ローカルです。
素晴らしいアプリ見つけたので、plunkerに上げてみた。

# 参考にしたページ

https://qiita.com/tetsutakamurata76/items/5d7d2e0ed2fe542b5169

# 写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b1a8e9b9-b747-7dfd-70a1-f041b6ecff8b.png)


# 成果物

https://embed.plnkr.co/plunk/vBo0yP97iKZxsk6a


以上
Instanaで挑む！トラブルシュート事件簿　第3回　新人は速い、部長は遅い？CRMの応答遅延をInstanaで解析

# はじめに

こんにちは、Airitech株式会社の代表取締役をしている、山﨑政憲と申します。
普段は会社の経営の傍ら、遅いシステム、止まってしまうシステムのトラブルシュートを行っています。
これからInstanaが現場で活躍した事例をいくつか紹介していこうと思います。
システムトラブルに対して、Instanaを用いてObservabilityを獲得し、速やかに解決した事例を紹介していく本連載、第3回は、社内で使用するCRMシステムの応答時間を、Instanaを使って改善した事例になります。
今回も、あっという間に解決できた分、記事も短いです。
ぜひ、ご覧ください。

# Instanaとは

InstanaはIBMが提供しているObserbavilityツールです。
私は起業した2017年からInstanaを性能改善やトラブルシューティングに活用しており、「早い」「美味い」「安い」と三拍子揃ったInstanaの便利さを日々、実感していますし、Instana好きが高じてIBM Championの認定も受けていましす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76238/8dd06a80-9c0e-bead-57bf-fff3bc5357c1.png)


Airitechでは、X上でマンガも掲載しています。
こちらもご覧ください。
https://x.com/AiritechSupport/status/1765633493084893569
<link href="https://x.com/AiritechSupport/status/1765633493084893569">
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76238/f3d27c44-a4b1-ede6-1fbf-5765d1bbec2b.png">
</link>

# 第一幕　事件発生
あるお客様から以下の相談が寄せられました。

「10年程度、運用を続けたCRMの応答が、ベテラン社員のみ悪化して困っています。
　画面遷移に5分くらいかかるようになってしまいました。」
「新人の応答速度は悪くなく、3秒程度で画面遷移します。」
「CRMの導入を行ったSIerに解析をお願いして2カ月ほと経過しましたが、
　SQLが原因では無い、という経過報告だけで、まだ解決していません。」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76238/a25b4aba-4394-341e-c344-78eca27e0a0d.png)

 という訳で、画面遷移に5分かかるので、大変、困ったという事でした。
 確かにそれは大変だということで、Instanaを適用させてもらって、解析を始めました。

# 第二幕　Instanaを使って解析
Instanaでトレースを見ましたが、確かに、遅いSQLは見当たりませんでした。
トレース結果からすると、プログラムで時間がかかっている模様。
Instanaのトレース画面には以下のように表示されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76238/a48afe3b-d6d6-38e0-a890-6c5eb13f569d.png)

オレンジのSQLの部分が長ければ、インデクスを追加するとかデータを削減するとかして、そのSQLの処理時間を改善すれば良いのですが、CRM製品のプログラムとなると、ベンダに依頼するほかなく、すぐの改善は難しいですね。
ちょっと困ったなと思いつつ、さらに調査を薦めました。

# 第三幕　原因判明
プログラムの遅延ということで、どう解析しようかなと思いましたが、Instanaにはスレッドダンプを採取する機能があるのをここで思い出しました。
という訳で、遅い処理を実行してもらいながら、スレッドダンプを採取して、プログラムのどこで時間がかかっているのかを確認しました。

スレッドダンプで頻出する関数の名前からすると、参照履歴を処理しているように見えます。
参照履歴、、、よくWordやExcelでも目にする「最近使ったアイテム」っていうやつですね。
以前に参照した顧客情報等の履歴を保持している機能ということです。

なぜそれにこんな時間がかかるのか、、、ちょっと不思議でしたが参照履歴テーブルを覗いたところ、疑問が氷解しました。

「履歴データが大きいユーザと小さいユーザがいる！」

そうです。
画面には直近の10件くらいしか表示されていませんが、データベースにはそれこそ10年分の参照履歴が記録されていたのです。
そりゃあ、新人は速い訳だ。

ということで、参照履歴が消えても業務に支障が無いかをユーザに確認後、参照履歴の削除作業が行われました。
結果、全てのユーザの画面遷移時間が4秒程度まで短縮されました。

これにて解決です。

# さいごに

いかがでしたでしょうか？
けっこう、名の通ったCRMなのですが、それでもこんな問題があるのか、と驚いた事例でした。
スレッドダンプを見るというは手法としては古いですし、スマートでもないですが、こういうテクニックも便利ですよという事ですね。
Obserbavilityツールが適用されていないシステムでの性能改善では、今でも、度々、使っている手法です。

Instanaの使い方、効果に興味を持たれた方はIBMのSoftware Salonでも使い方や事例について解説しているので、ぜひ、ご覧になってみてください。

IBM Software Salon 第10回 (2024/9/19)
トラブル解決でヒーローになろう！障害事例にみるObservabilityツール活用の勘所
https://video.ibm.com/recorded/133995814
<link href="https://video.ibm.com/recorded/133995814">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76238/165aeb44-f50b-e035-7e36-fa84e56f1290.png">
</link>

また、Instanaユーザコミュニティも、定期的にイベントを行っています。
こちらもぜひ、ご覧ください。
https://instanautsjp.connpass.com/

それでは、今後もInstanaの便利な使い方や事例の紹介を行いますので、よろしくお願いいたします。
Direct Connect Gateway (DXGW)とVGWとVIFのまとめ

# そもそもDXGWとは
Direct Connect Gateway (DXGW)
オンプレのルーターとAWSのネットワークに接続する際に必要とするVIFとプライベートゲートウェイの間に追加するコンポーネントであり複数のVIFおよびVGWが接続できるようになる。
オンプレから複数のVPC間の通信ができる。

〇DXGWでできること
・オンプレのインターフェース→DXGW→VPC-A
・オンプレのインターフェース→DXGW→VPC-B

※VPC間の通信を行いたい場合は、VPCピアリングやAWS Transit Gatewayなど他のサービスを検討する。

×DXGWでできないこと
・VPC-A→DXGW→VPC-B
・オンプレA→DXGW→オンプレB

※DXGWを経由して別のネットワークと通信することはできない

# VIF（仮想インターフェース）とVGW（仮想プライベートゲートウェイ）について
VIFとVGWについて説明する。

## VIF（仮想インターフェース）とは？
AWSクラウド内の特定のリソースやサービスと接続するための「専用の通り道」
public、private、transitタイプの仮想インターフェースがある。
実際にDXGWで使用するのはprivate、transitタイプの仮想インターフェースがある。

イメージしやすい記事がこちら
占有型？共有型？AWS Direct Connect の接続（Connection）と仮想インターフェース（VIF）関連の用語を整理してみた


https://dev.classmethod.jp/articles/aws-direct-connect-connection-vif-organize-terms/

## transitタイプのVIF
DXGWを介して複数のVPCやTransit Gatewayに接続する。
これにより複数のVPC間の通信やオンプレミスと複数のVPC間の通信を効率的に管理できる。
使用例として大規模なネットワーク構成で複数のVPCを一元的に管理し、相互接続する場合に使用される。これらの仮想インターフェースを適切に使用することでAWS環境とオンプレミスのネットワーク間の接続を最適化できる。

## privateタイプのVIF
プライベートIPアドレスを使用してオンプレミスのネットワークとVPC内のリソースを接続する。
使用例として企業の内部ネットワークとAWSのクラウドリソースを安全に接続する場合に使用される。

## publicタイプのVIF
AWSのパブリックサービス（S3やDynamoDB、SQS）にアクセスするときに使用される。パブリックIPアドレスを使用してオンプレミスのネットワークからAWSのパブリックエンドポイントに接続して使用する。
こちらはDXGWのコンソール画面には表示されない。AWSのパブリックサービスにアクセスするために使用しているため。

## VGW（仮想プライベートゲートウェイ）とは？
VPCとオンプレミスのネットワークを接続するためのゲートウェイ。（クラウドとオンプレミスのネットワークを安全に結ぶ「出入り口」的なもの）
privateタイプのVIFを利用しDirect Connect接続を介してVPCに接続する。
VGWはVPCにアタッチされてプライベートIPアドレスを使用して通信を行う。
これによりオンプレのネットワークとVPC内のリソースとの間で安全な通信が可能となる

## 参考にしたドキュメント
参考にしたドキュメント
【Direct ConnectでオンプレとAWS環境を繋ぐ！第3弾】　仮想インターフェイス（VIF）の承認作業手順

https://blog.serverworks.co.jp/2022/02/14/180000

AWS Direct Connectを整理してみた

https://qiita.com/zumax/items/5aca0e1b841082a3c6c5

[新機能] AWS Direct Connect Gatewayで世界中のAWSリージョンとプライベート接続する

https://dev.classmethod.jp/articles/direct-connect-gateway/

占有型？共有型？AWS Direct Connect の接続（Connection）と仮想インターフェース（VIF）関連の用語を整理してみた

https://dev.classmethod.jp/articles/aws-direct-connect-connection-vif-organize-terms/

Private VIFとVGWの直接接続構成からDirect Connect Gatewayを経由する構成への切替作業をまとめてみた

https://dev.classmethod.jp/articles/migrate-traffic-direct-connect-gateway/
GhostBSDでEiffelを動かしたい（その前にCのプログラムをコンパイルしたい）

# はじめに
[FreeBSD（にしようかと(以下略)](https://qiita.com/koizumistr/items/969972b0a612c98ff70a)を読んで、GhostBSDをインストールした人が次にやりたいと思うことはもちろんプログラムのコンパイルでしょう。でも、最近のGhostBSDでは、えっ！？、となりますので、それを解決するまでの記録です。
ここでは対象としてLiberty Eiffelのコンパイラー一式のコンパイルを目標にします。が、「Liberty Eiffelのコンパイラー」って基盤部分はCで書かれていますので、Cのプログラムをコンパイルしたいなと思った場合一般に役立つはずです。
あと、以下のコマンドの中には普通はsudo[^sudo]が必要になるものがあるかと思いますが、敢えて付けていません。（マネするのはいいけど、考えてマネしてね、ということで。）

[^sudo]: 別にsudoでなくてもいいです。doasでも、お好きなものを。要するにルート権限が必要ってことです。

# 最初の試み
~~~
$ git clone git://git.sv.gnu.org/liberty-eiffel.git
$ cd liberty-eiffel/
$ pkg install boehm-gc
$ ./install.sh 
~~~
ほとんどの行は自明かと思います（Gitで本家から持ってきて、展開されたディレクトリに移動して、インストール、と）。3行目はやらなくてもいいのですけど、インストール時に警告が出ますので先にやっておきます。（これはガベージコレクタでして、なければないでコンパイルはできます。ただ、FreeBSD/GhostBSDにはパッケージで用意されていて、導入は簡単ですから、ここでやっています。）

# stdio.hがない！？
これでインストールできて欲しいところですよね。が、いきなりエラーになりました。エラメッセージを読むと **stdio.hがない** ということのようです。 **えっ？stdio.hがない！？** 一体どういうことでしょうか。
「Liberty Eiffelのコンパイラーなんてニッチなものをコンパイルしようとしているのが悪いんだ」と思った方、そうではないのです。C で "hello world" とでも出力するプログラムを作ってコンパイルしてみましょう。（超有名なプログラムだと思うので、プログラム自体はここには載せませんよ:smile:）
~~~
$ cc hello.c
~~~
同じく **stdio.hがない** というエラーでコンパイルできません。

# 解決策
最近のGhostBSDは初期状態では開発環境が入らなくなったようです。でも、Cコンパイラー[^cc]だけは入っているため、インクルードファイルが見つからずに **stdio.hがない** というエラーになるようです。ということで、以下のコマンドで解決です。
~~~
$ pkg install -g 'GhostBSD*-dev'
~~~
以下のページに開発者さんが書いてました。（"Why can’t I compile code or ports on GhostBSD?" のところです。）

https://ghostbsd-documentation-portal.readthedocs.io/en/latest/user/FAQ.html#why-can-t-i-compile-code-or-ports-on-ghostbsd

[^cc]: 「Cコンパイラーも開発環境ではないか」と言われるとそういう気もします。なので、初期状態ではCコンパイラーすら入っていない、という環境も見たことがあります。確か過去のGhostBSDがそうだったような、、、

# 再挑戦
~~~
$ ./install.sh 
$ cd tutorial/
$ ../target/bin/se c hello_world.e 
$ ./a.out 
Hello World.
~~~
今度は install.sh でコンパイラー一式ができました。2行目以降はできあがったコンパイラーの動作確認です。tutorial ディレクトリに "Hello World." と表示するサンプルプログラムがありますので、それをコンパイルして、その結果できたプログラムを実行しています。確かに "Hello World." と表示されました。めでたし、めでたし。

# おことわり
この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。
型 "new"を型 'boolean | "shell" | undefined' に割り当てることはできません

# はじめに

puppeteerを使用している中で設定した型にエラーが出ました。

```
const browser = await puppeteer.launch({
            headless: 'new'
 });
```
エラー内容：
<font color="Red">型 '"new"' を型 'boolean | "shell" | undefined' に割り当てることはできません</font>

# エラー原因
puppeteerの型定義でheadlessオプションが以下の型を受け付けると定義されていて、今回の"new"はどれにも該当しなかったため発生したエラーのようです。

```
- boolean: true/false
- "shell": 文字列の"shell"
- undefined: 未定義
```

以下の公式ドキュメントでは設定変更のオプションが記載されています。
https://developer.chrome.com/docs/chromium/headless?hl=ja

```
const browser = await puppeteer.launch({
  headless: 'true', // (default) enables Headless
  // `headless: 'old'` enables old Headless
  // `headless: false` enables "headful" mode
});
```
ここに設定する値でHeadlessの有効化・無効化をすることが可能なようです。

# 解決策


最終的に今回のコードは以下のようにHeadlessを有効化させて解決ができました。

```df:
const browser = await puppeteer.launch({
      headless: true // 'new'から`true`に変更
});
```

# おわりに
はじめて使うライブラリなので公式ドキュメントを確認しつつ進めるのが一番いいのかもしれないと気づくきっかけになりました。
GitHubPagesで404ページを作る方法

どうもAtsu1209です。
今回はGitHubPagesで 404エラーページを作る方法を書いて行きます。

# 404エラーとは
404エラーは「クライアント側はサーバーに接続できたけど、クライアントが要求しているものがサーバーに見つからなかった」
簡単に言うと「サーバーへいらっしゃい。いきなりで悪いけどあなたの見たいページうちにはないよ」ということです。
GitHubPagesに限らずいろいろなところで404エラーのときに表示させるページを作ることができます。

# 作り方
GitHubPagesで404ページを作るのはとても簡単で、
`404.html`というHTMLファイルを作って入れておくだけです。
例として私のホームページ(GitHubPagesで管理)を見てみましょう
![canvas (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3374328/96c85e13-70ed-c122-d717-c5c35bf2874d.png)

##### (かなり整理しました。 整理の話は下のリンクから)

https://qiita.com/Atsu1209jp/items/fa137ce2c3f337ad41db

# 404ページをカスタマイズするメリット
メリットとしてはこんなことがあります。
・本来404はエラーのためなにもいいことはないが、ページを管理する側が見てほしいものなどを404ページに書くことで、そちらに誘導することができる。
・隠し要素的なのを入れてクライアントをちょっとだけ楽しませることができる。
などが挙げられます。
neovimのファイラーneo-treeの設定と、よく使うキーバインドまとめ


# neovim用ファイラー「neo-tree」のインストールと設定方法

neovimで便利なファイラー「neo-tree」をインストールし、設定する手順を紹介します。  
初めてneovimを導入する方にもわかりやすいよう、必要なパッケージやディレクトリ構成から丁寧に解説します。

## 1. neovimのインストール

まず、neovimがインストールされていない場合は以下のコマンドでインストールします。

```bash
sudo apt install neovim
```

## 2. ディレクトリ構成

設定ファイルは`~/.config/nvim`に以下の構成で配置します。

```
~/.config/nvim
├── lua
│   ├── config
│   │   └── lazy.lua
│   └── plugins
|       ├── nui.lua
|       ├── plenary.lua
│       └── neo-tree.lua
└── init.lua
```

## 3. 設定ファイルの作成

### init.luaの設定

`init.lua`で、`lazy.lua`を読み込みます。

```lua
-- init.lua
require("config.lazy")
```

### lazy.luaの設定

`lazy.lua`では、プラグイン管理用に`lazy.nvim`を設定します。

```lua
-- lazy.lua

-- lazy.nvimのクローンと設定
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  local lazyrepo = "https://github.com/folke/lazy.nvim.git"
  local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
  if vim.v.shell_error ~= 0 then
    vim.api.nvim_echo({
      { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
      { out, "WarningMsg" },
      { "\nPress any key to exit..." },
    }, true, {})
    vim.fn.getchar()
    os.exit(1)
  end
end
vim.opt.rtp:prepend(lazypath)

-- リーダーキーの設定
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

-- lazy.nvimのセットアップ
require("lazy").setup({
  spec = {
    { import = "plugins" },
  },
  install = { colorscheme = { "habamax" } },
  checker = { enabled = true },
})
```

### neo-tree.luaの設定

`neo-tree`プラグインを設定するために`neo-tree.lua`を作成します。`neo-tree`は以下の依存関係がありますので、これらもインストールします。

```lua
-- neo-tree.lua
return {
  'nvim-neo-tree/neo-tree.nvim',
  requires = {
    'nvim-lua/plenary.nvim',
    'kyazdani42/nvim-web-devicons', -- ファイルアイコン用（オプション）
    'MunifTanjim/nui.nvim',
  }
}
```

### その他の依存プラグインの設定

依存するプラグインは`nui.lua`と`plenary.lua`として、それぞれ以下の内容で設定します。

```lua
-- nui.lua
return {
  "MunifTanjim/nui.nvim"
}
```

```lua
-- plenary.lua
return {
  'nvim-lua/plenary.nvim',
}
```

## 4. neo-treeの便利なデフォルトのキーバインド

`neo-tree`でよく使用するデフォルトのキーバインドの一覧をまとめました。

| キー | 動作 |
| --- | --- |
| `<cr>` [^1] | ディレクトリ・ファイルを開く |
| `a` | 新しいファイルを追加 [^2]|
| `A` | 新しいディレクトリを追加 |
| `c` | ディレクトリ・ファイルをコピー |
| `d` | ディレクトリ・ファイルを削除 |
| `H` | 隠しファイルを表示 |
| `i` | ディレクトリ・ファイルの情報を表示 | 
| `r` | ディレクトリ・ファイルの名前を変更 | 
| `P` | ファイルの内容をプレビュー |
| `q` | neo-treeを閉じる |
| `R` | 更新 |

[^1]: `<cr>`キーはWindowsでは`Enter`、Macでは`Return`キーに相当します。  
[^2]: ファイル名の最後に`/`をつけて入力すると、新しいディレクトリが作成されます。

他の詳細なコマンドやオプションについては、neo-treeの[公式README](https://github.com/nvim-neo-tree/neo-tree.nvim?tab=readme-ov-file#the-neotree-command)をご参照ください。

---

### 参考文献

https://lazy.folke.io/installation

https://zenn.dev/ryo1217intern/articles/04588c196b3181

https://github.com/nvim-neo-tree/neo-tree.nvim

https://github.com/MunifTanjim/nui.nvim

https://github.com/nvim-lua/plenary.nvim
ウォークフォワード

うーん、ここからどうしたもんか。

![ret_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303759/7195bb5b-2a53-c75d-1c9e-5114ac0cfdad.png)
![ret_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303759/197f666e-b3e3-11d5-9580-5294ddc63865.png)
![ret_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303759/a0e7aa57-5cb7-7d71-b6fc-d03758514ed1.png)
![ret_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303759/b782f090-5b3d-ba80-be51-0136cd5b7eda.png)
![ret_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303759/60b2f148-0b02-088e-f67e-3f87fa567039.png)