OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue3】npm run dev した際のportを固定にする方法

## 解決したいこと

- `npm run dev`を実行するとportが固定されずに変動してしまう
    - http://localhost:5173/ → http://localhost:5174/ → http://localhost:5175/ ・・・
    - ↑開こうとしているポート番号がすでに使用されている場合、vueはその次のポート番号でポートを開こうとするため

## 原因
- `vite.config.ts`で解放するポートを固定値で指定していなかったため
    - 固定値で指定すればそのポート番号が使用されている場合は、新たなポート番号を使用するのではなく、エラーを返すようにできる

## 具体的なやり方
```:vite.config.ts
export default defineConfig({
  plugins: [vue()],
  server: {  
    port: 5173,  // ここを追加
    strictPort: true // ここを追加
  }
})

```

## 固定値を指定した後で npm run dev がエラーになる場合
- 固定値で指定したポート番号(今回の場合は5173)に関連するプロセスを終了させることでポートを解放させることで解決できます

1. ターミナルで以下のコマンドを実行して、ポート5173を使用しているプロセスを見つけます。
```:zsh
lsof -i :5173
```
2\. コマンドの出力から、該当するプロセスのPID（プロセスID）を探します。通常は出力の2行目にあります。例えば以下のような出力があった場合
```:zsh
COMMAND  PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
node    12345   user   23u  IPv4  12345678      0t0  TCP *:5173 (LISTEN)
```
3\. 次に、以下のコマンドを実行して、該当するプロセスを強制終了します。<PID>の部分に先ほど見つけたPIDを入れてください。
```:zsh
kill -9 <PID>
```
例えば、上記の例では以下のコマンドを実行します。
```:zsh
kill -9 12345
```

4\. プロセスが終了したことを確認したら、もう一度npm run devを実行してください。これでポート5173で開発サーバーが立ち上がるはずです。
プリザンターの一覧画面にボタンを追加し、ボタンをクリックしてレコードを削除する

# はじめに
一覧画面からレコードを削除する時、デフォルトの一括削除ボタンをクリックすると確認ダイアログが表示されて面倒なので、レコードごとに削除ボタンをつけるという処理をサーバスクリプトで実装しました。また、追加したボタンをクリックすると削除処理が実行されるクライアントスクリプトも実装しましたので、この記事に記載します。

# ソースコード
## サーバスクリプト
```JavaScript
try {
    // 「data-id="${model.ResultId}"」でボタンを表示する行を指定
    let html = `<button data-id="${model.ResultId}"class="button-icon my-row-button"data-icon="ui-icon-circle-triangle-e">削除</button>`;
    // 該当業のClassA列に「削除」ボタンを表示
    columns.ClassA.RawText = html;
} catch (ex) {
    context.Log(ex.stack);
}
```
## クライアントスクリプト
```JavaScript
try {
    // my-row-buttonがクリックされたときのイベント
    $(document).on('click', '.my-row-button', function (event) {
        // レコードのIDをコンソールに出力
        $p.apiDelete({
        id: $(this).data('id'),
        done: function (data) {
            location.reload();
        }
    });
        // 編集画面が開かないようにイベントの伝搬を停止
        event.stopImmediatePropagation();
    });
} catch (ex) {
    console.log(ex.stack)
}
```

# さいごに
一覧画面で削除ボタンを表示し、削除ボタンがクリックされたらレコード単位で削除するという処理を実装できました。次は編集画面で削除ボタンがクリックされたらそのレコードを削除するという処理を実装しようと思っています。今回の実装では「確認ダイアログ」が表示されずに一発で削除されるという点が肝になります。
【JavaScript】数字をアルファベットに変換する

数字をアルファベットに変換（1→A，2→B，……，26→Z）する関数です。

```
// 数字→アルファベット変換
function ChangeNumberToAlphabets(number){
    const alphabet = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
    const alphabets = alphabet.split(",");

    return alphabets[number - 1];
}
```
rbenvによるRubyのインストール手順まとめ

# はじめに

rbenvによるRubyのインストール手順をまとめました。
なおrbenvやHomebrewそのものについての説明は省いてあります。

**実行環境**
- Apple M2 Max
- macOS Ventura 13.2.1

# インストール手順
## 準備：Homebrewをインストール
Homebrewがインストールされているかを確認。
```bash
brew -v
```

バージョンが表示されない場合はHomebrewをインストール。
([Homebrewのホームページ](https://brew.sh/index_ja)にあるインストール用のスクリプトを実行)

## rbenvをインストール

以下のコマンドでrbenvをインストール。

```bash
brew install rbenv
```

パスに関する記述を`~/.zshrc`に追加する。

```bash
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

`~/.zshrc`を読み込む。

```bash
source ~/.zshrc
```

## Rubyをインストール

インストール可能なRubyバージョンを確認。
(安定版のみを表示)

```bash
rbenv install -l
```

※すべてのバージョンを確認したい場合は次のコマンドを実行

```bash
rbenv install -L
```

バージョンを指定してRubyをインストール。

```bash
rbenv install 3.2.2
```

指定したバージョンがインストールされたかを確認。
(指定したバージョンが表示されたらOK)

```bash
rbenv versions
```

### Rubyのインストールに失敗した場合

次のようなエラーでRubyのインストールに失敗する場合がある。

```bash
BUILD FAILED (macOS 13.2.1 using ruby-build 20230330)

Inspect or clean up the working tree at /var/folders/y5/2wqq81m50p75p8hr49b0vpph0000gp/T/ruby-build.20230411184408.35522.zX8tbp
Results logged to /var/folders/y5/2wqq81m50p75p8hr49b0vpph0000gp/T/ruby-build.20230411184408.35522.log

Last 10 log lines:
	Check ext/psych/mkmf.log for more details.
*** Fix the problems, then remove these directories and try again if you want.
Generating RDoc documentation
/private/var/folders/y5/2wqq81m50p75p8hr49b0vpph0000gp/T/ruby-build.20230411184408.35522.zX8tbp/ruby-3.2.2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
make: *** [rdoc] Error 1
```

`please install libyaml and reinstall your ruby`というログをふまえて、
libyamlをインストールすることで対処する。

**対処方法**
libyamlをインストール。

```bash
brew install libyaml
```

Rubyを再インストールし、指定したバージョンがインストールされたかを確認。

```bash
rbenv install 3.2.2
```

```bash
rbenv versions
```

## 使用するRubyバージョンを設定

グローバルに使用するRubyバージョンを変更する。

```bash
rbenv global 3.2.2
```

※現在のディレクトリで使用するRubyバージョンを変更する場合は次のコマンドを実行

```bash
rbenv local 3.2.2
```

シェルを再起動。

```bash
exec $SHELL -l
```

使用されているRubyのバージョンを確認。
(指定したバージョンが表示されたらOK)

```bash
ruby -v
```
Webpackerのコンパイルファイルを溜めない方法

## 概要
MacM2で開発を進めています。
古いコンパイルファイルが溜まるので、定期的にコマンドで削除することにしました。

このようなファイルです。
![スクリーンショット 2023-04-28 18.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468139/ff0c2ff8-7782-51a3-7987-784e502660ee.png)

下記が削除のコマンドです。
~~~
bin/rails webpacker:clean
~~~

なお、webpacker.ymlファイルのcleanup_assetsオプションをtrueに設定することで自動削除もできるようですが、
ユーザーがブラウザーキャッシュから古いバージョンのアセットを読み込もうとした場合に404エラーが発生する可能性があるとの情報なので、
私は今回、この方法を選びませんでした。

最適解ではないかもしれませんが、ご参考までに。

## 追記
コンパイルファイルはその他、アセットファイルとCSSファイルがあるとのこと。
こちらは作成される頻度が少ないので削除しないことにしました。

コンパイルファイル群をまとめて削除するコマンドもあるとのことですが、
自分に必要なさそうなので割愛します。

おわり。
【Rails】ログを自動で削除する

## はじめに
Railsを使っていて、なんとなしにlogディレクトリのファイルを見たらなんと一万行くらいのログが溜まっていて心配になりました。
このまま溜めっぱなしだと動作にも影響が出そうなので自動で削除したいと思いました。

## 環境
zsh
rails 6.1.3.7

## logファイルのデータ削除
ファイルの内容を削除したい場合にはrakeタスクを実行します。
```
$ rake log:clear 
```
## ログ削除の自動化
`gem 'whenever'`をインストールします。
これは、cronの設定を簡単に行えるライブラリです。
```ruby:Gemfile
gem 'whenever'
```
chedule.rbファイルを作成
```
$ bundle exec wheneverize .

[add] writing `./config/schedule.rb'
[done] wheneverized!
```
ファイルを編集。
```ruby:config/schedule.rb
#実行時のログファイルの置き場所指定
set :output, "#{path}/log/cron.log"

#zshで実行
set :job_template, "/bin/zsh -l -c ':job'"
#rakeコマンド実行時の設定
job_type :rake, "export PATH=\"$HOME/.rbenv/bin:$PATH\"; eval \"$(rbenv init -)\"; cd :path && RAILS_ENV=:environment bundle exec rake :task :output"

# 毎日の午後6時に実行
every 1.day, at: '6:00 pm' do
  rake 'log:clear'
end

# 毎週土曜日の午前3時に実行
every :saturday, at: '3:00 am' do
  # ジョブの中身
end

# 毎月1日の午前2時に実行
every '0 2 1 * *' do
  # ジョブの中身
end

# 平日の午後4時30分に実行
every :weekday, at: '4:30 pm' do
  # ジョブの中身
end
```
cronやwheneverがbundleなどを実行する際には、rbenvの設定が効いていないため
`export PATH=\"$HOME/.rbenv/bin:$PATH\"; eval \"$(rbenv init -)\"`
という記述をしないと、デフォルトでインストールされていたrubyのバージョンで実行されることになり、もしアプリ内で違うバージョンのrubyを使っていたとしたらエラーが発生する。

## 参考
https://teratail.com/questions/248501

https://qiita.com/mmaumtjgj/items/19e866f31541abb6c614
【NeosVR】DeskTopモードでフェイシャル＆アイトラッキングする方法

皆さん！デスクトップモードでも簡単に顔の表情:grinning:や視線:eyes:、首の動き:man_with_turban:が動かせるとしたら試してみたいですよね！
今回はいくつかあるDeskTopモードでのフェイシャルトラッキングのうち比較的簡単な「WCFaceTrack」について紹介します！


# 用意するもの
+ 設定するアバター
> DeskTopフェイシャルトラッキングを使用するには、アバター側にそのための設定を行う必要があります。
自分はひゅうがなつみかんさんの[Lunalitt](https://hyuuganatu.booth.pm/items/4063740)を使っていきます！
+ Webカメラ
> Zoomなどで使用するような基本的なWebカメラで問題ないです。ノートパソコンなどで備え付けがあればそれを使ってください。自分は[このカメラ](https://www.biccamera.com/bc/item/8496687/?source=googleps&utm_content=001100112005)を使用しています。
+ WCFaceTrackのフォルダー
![20230328202746_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/f41a88da-b562-fd33-7036-b98b631cd77f.jpeg)

> 以下のurlをコピーしてNeos内でペーストしてください。(デスクトップモードならctrl+v、VRモードならダッシュメニュー、ホームのクリップボードからペースト)
> neosrec:///U-Ruz/R-14757885-7241-4011-abc9-f6724f806c72
> 
> スポーンしたフォルダーをインベントリに保存しておいてください。

# WCFaceTrack インストーラーを使う
先ほどインベントリに保存したフォルダーを開いて、中にあるインストーラーを出してください。
![スクリーンショット (311).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/84c9cabe-5c2d-1049-083a-43d175066651.jpeg)
また設定するアバターも出しましょう。
![スクリーンショット (312).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/6e313a69-c853-eee6-260f-76d528deb0a5.png)

1. DevToolTipを使ってアバターのインスペクターを開き、表情のシェイプキーが入っているスロットを開きましょう。
※大体のアバターはCenteredRoot -> RootNode -> Bodyに表情のシェイプキーが入っています。
 DevToolの使い方がわからない方は[こちら](https://neosvrjp.memo.wiki/d/DevToolTip#content_2_2)。
![ezgif.com-optimize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/2b9951f7-48d3-651c-d997-b32fa91cad9c.gif)

    2. UIX キャンバスに対応する表情のシェイプキー名をDrop hereと書いてあるところにドラッグ&ドロップします。
それぞれの表情設定(Mouth Smallなど)と同じ、もしくは似ている表情のシェイプキーを参照付けていきます。
挿入されるとUIが緑色に変わりGot it!と表示されます。間違えた場合は、いつでも配置を元に戻すことができます。
MariaDBでデータベースを作ってテーブルにデータを入れて取得してみた

# 概要
今日もデータベースの勉強ということで、MariaDBで遊んでみました。
インストールして、データベースを作って、テーブルを作って、データを入れて、取得するところまでやってみました。
以下のページを参考にしました。
https://www.javadrive.jp/mariadb/

# 環境構築
以下のコマンドを実行しました。
```
$ sudo apt install mariadb-server
```
（インストール途中で確認あり。OKで通過。）

# rootでログイン
以下のコマンドを実行しました。
```
$ sudo mariadb -u root -h localhost
```
ユーザーを作りました。create userを実行しました。
```
MariaDB [(none)]> create user 'user1'@'localhost' identified by '********';
Query OK, 0 rows affected (0.015 sec)
```
データベースを作りました。create databaseを実行しました。
```
MariaDB [(none)]> create database mydb;
Query OK, 1 row affected (0.000 sec)
```
user1に権限を与えました。grantを実行しました。
```
MariaDB [(none)]> grant all on mydb.* to 'user1'@'localhost';
Query OK, 0 rows affected (0.015 sec)
```

# user1でログイン
以下のコマンドを実行しました。
```
$ mariadb -u user1 -p
```
データベースを切り替えました。useを実行しました。
```
MariaDB [(none)]> use mydb
Database changed
```
テーブルを作りました。create tableを実行しました。
```
MariaDB [mydb]> create table animal (id int, name varchar(10));
Query OK, 0 rows affected (0.145 sec)
```
データを入れました。insertを実行しました。
```
MariaDB [mydb]> insert into animal (id, name) values (11, 'monkey');
Query OK, 1 row affected (0.033 sec)
```
データを取得しました。selectを実行しました。
```
MariaDB [mydb]> select * from animal;
+------+--------+
| id   | name   |
+------+--------+
|   11 | monkey |
+------+--------+
1 row in set (0.000 sec)
```
今のところMySQLとほぼ同じですね。何かの役に立てばと。
JavaScriptの変数（const,let,var）。再宣言、再代入の可否について。

・変数とは
　複数回使う文字列や数値などのデータに名前をつけることで、
　繰り返し利用できるようにする機能。
　変更する際にも変数だけ変えればよいので、ミスが起こりづらい。


・JavaScriptの変数
　const,let,varの３つある。


・再宣言、再代入
　再宣言　-　１度宣言した変数を、新たに宣言しなおすこと。
　　例　const Title = "The Matrix";
　　　　const Title = "The Matrix Reloaded";

　再代入　-　１度宣言した変数に、新たな値を代入すること。
　　例　const Title = "The Matrix";
　　　　Title = "The Matrix Reloaded";


・変数ごとの再宣言、再代入の可否
　const 再宣言：x 再代入：x
　let 再宣言：x 再代入：○
　var 再宣言：○ 再代入：○


参考にしたサイト
https://jsprimer.net/basic/variables/　（JavaScript Primer 変数と宣言）
Python　tkinterを使ってボタン描画

目的：
日経ソフトウェア１月号
「Pythonで将棋アプリを作ろう　ー前編ー」に載っている
canvasウィジェットのテストプログラムを写経し動かしてみました。

環境：
Mac OS　13.2.1　　　
Intel Core i7
Python 3.11

プログラム：

#Canvasのテストプログラム　その１
import tkinter

#Botton-1 イベント時のイベントハンドラ
def canvas_click(event):
    xa = event.x
    ya = event.y
    canvas.create_rectangle(xa, ya, xa + 10, ya + 10, fill="Red")

root = tkinter.Tk() #window
root.geometry("640x480") #window size

#キャンバス作成
canvas = tkinter.Canvas(root, width=640, height=480)
canvas.pack() #キャンバスの配置

#Botton-1 イベント時のイベントハンドラを指定
canvas.bind("<Button-1>", canvas_click)
root.mainloop()

実行結果：

canvas上に赤ボタンを描画することができました。

![スクリーンショット 2023-04-28 18.13.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297682/4ca1d794-ae1c-8871-d7d6-1f0b19433352.png)



参考文献：
日経ソフトウエア 2023年1月号
https://info.nikkeibp.co.jp/media/NSW/atcl/mag/111700045/
if文のネストを減らすための書き方

# はじめに
ソースコードの可読性と保守性を向上させるための、if文のネストを減らす方法について簡単にまとめてみました。初学者の方にとって参考になるかもしれません。
サンプルプログラムはPythonで記述していますが、汎用的なものなので、他の言語でも適用できる場合がほとんどです。

※全てのケースにおいて適用できるわけではありません。また、完全にelif（else if）やelseを使わないという制約は、コードの論理的な構造を表現するための有用なツールを制限してしまう可能性がありますので、適切なバランスを見つけることも重要かと思います。

# サンプルプログラム
## 内容
- 年齢（age）をもとに飲酒できるかどうかを判定する
    - 年齢が0未満の場合は「You are not born yet.」と出力
    - 年齢が0以上20未満の場合は「You cannot drink.」と出力
    - 年齢が20以上の場合は「You can drink.」と出力
    - 年齢が数字以外の場合は「Invalid age.」と出力

実際どう実装すれば良いのでしょうか。まず`悪い例`を見てみましょう。

```python
age = 20

if isinstance(age, int):
    if age < 0:
        print("You are not born yet.") 
    elif age >= 0 and age < 20:
        print("You cannot drink.")
    else:
        print("You can drink.")
else:
    print("Invalid age.")
```

一見問題なさそうなプログラム（実際問題なく動く）ですが、いくつかの問題点があります。

# 問題点&改善点
## 条件のネストをなるべく避ける
上記の例では、ネストしたif文が使われていて、条件が`入れ子構造`になっています。
```python
if isinstance(age, int):
    if age < 0:
        pass
```
二重入れ子構造になっているので、まだそこまでわかりにくいわけではないかもしれませんが、条件が多くなり、`ネストが深くなる`と、プログラムの`可読性と保守性が低くなってしまいます`。

## 関数として切り出す
上述のように、if文やelse文のネストが複雑になりがちです。この場合、判定処理を関数として切り出すと良いでしょう。
```python
def can_drink(age):
    pass

age = 20
result = can_drink(age)
print(result)
```
関数として切り出したら、次に判定条件を修正する必要があります。

## 一致する条件から結果をreturnする
サンプルプログラムでは、まず年齢（age）が数字かどうかを判定し、数字の場合は次の条件の判定に入っているので、入れ子構造になっています。条件のネストを避けるために、判定条件を変更し、先に一致する条件から結果をreturnしていくと良いでしょう。
```python
def can_drink(age):
    if not isinstance(age, int):
        return "Invalid age."
```
`isinstance(age, int)`が`True`の場合に次の判定に入るのではなく、`isinstance(age, int)`が`False`の場合に「Invalid age.」を返せば、年齢（age）が数字でない時点で処理が終了します。
※戻り値がない場合はreturnのみを記述します。

同じように他の条件の記述方法も修正すれば、`else`や`elif`の使用を避けることができます。
```python
def can_drink(age):
    if not isinstance(age, int):
        return "Invalid age."
    if age < 0:
        return "You are not born yet."
    if age < 20:
        return "You cannot drink."
    return "You can drink."
```
このように判定条件を修正し、いずれも一致しない場合のデフォルトの戻り値を最後に記述します。



# リファクタリング
以下、上記の問題点と改善点をもとにリファクタリングを行った後のプログラムの一例です。
```python
def can_drink(age):
    if not isinstance(age, int):
        return "Invalid age."
    if age < 0:
        return "You are not born yet."
    if age < 20:
        return "You cannot drink."
    return "You can drink."

age = 20
result = can_drink(age)
print(result)
```

# まとめ
- 条件のネストをなるべく避ける
- 判定処理を関数として切り出す
- 一致する条件から結果をreturnする
PID制御の基礎と応用　山本・加藤先生　朝倉書店

```r

#p.39 安定性を調べる

a1=1
a2=0


if(a1^2<(4*(a2+1))){
print("複素共役根を持つ") 
  
root=polyroot(c(a2+1,a1,1))[1]  
sigma=Re(root)
alpha=Im(root)
pthi=atan(-alpha/sigma)

y=function(t){
return((1-sqrt(sigma^2+alpha^2)*exp(sigma*t)*sin(alpha*t+pthi))/(sigma^2+alpha^2))}

}

if(a1^2==4*(a2+1)){
print("重根を持つ") 
root=polyroot(c(a2+1,a1,1))[1]   
sn=Re(root)  
y=function(t){
return((1-exp(sn*t)*(1-sn*t))/(sn^2))  
}  
}

if(a1^2>(4*(a2+1))){
print("2つの実根を持つ")  
root=polyroot(c(a2+1,a1,1))   
s1=Re(root[1])
s2=Re(root[2])
y=function(t){
return(((1-exp(s2*t))/s2-(1-exp(s1*t))/s1)/(s1-s2))  
}
  
}


ts=seq(0,100,0.01)
plot(ts,y(ts))


```

```r

#p.71 PID制御による調整

data("AirPassengers")
b=5
a=0
dt=(b-a)/length(c(AirPassengers))
t=seq(a+dt,b,dt)

r=4;dim=1
values=c(AirPassengers)
tvec=c()

X=array(0,dim=c((length(values)-r),dim*r))
Y=c()
for(j in 1:(length(values)-r)){
vec=c()
for(i in 1:dim){
vec=c(vec,values[j:(j+r-1)]^i)  
}
X[j,]=vec
Y=c(Y,(values[r+j]))
tvec=c(tvec,t[r+j])
}

beta=solve(t(X)%*%X)%*%t(X)%*%Y
cor(X%*%beta,Y)

#測定値、目標値、偏差
PVt=X%*%beta
SVt=Y
et=SVt-PVt


PB=150
TI=100
TD=0.01


mn=c()
tmn=c()
mt_et=c()
for(j in 2:length(tvec)){
val=100*(et[j]+sum((et[1:j]^2)*dt)/TI+TD*(et[j]-et[j-1])/dt)/PB
mn=c(mn,val)
mt_et=c(mt_et,val+SVt[j])
tmn=c(tmn,tvec[j])  
}

dmn=c()
for(j in 2:length(mn)){
dmn=c(dmn,mn[j]-mn[j-1])  
}


#制御量を追加した出力
plot(tmn,mt_et,xlim=c(min(tmn),max(tmn)),ylim=c(min(c(mt_et,Y)),max(c(mt_et,Y))),col=2,xlab="t",ylab="制御値と出力")

par(new=T)

plot(tmn,Y[2:length(Y)],xlim=c(min(tmn),max(tmn)),ylim=c(min(c(mt_et,Y)),max(c(mt_et,Y))),col=3,xlab="t",ylab="制御値と出力")

#plot(tmn,mn,xlim=c(min(tmn),max(tmn)),ylim=c(min(c(mn)),max(c(mn))),col=1,xlab="t",ylab="制御量")


```

```r

#p.71 PID制御による調整(Gauss-newtonアルゴリズムによるパラメータ調整)

data("AirPassengers")
b=5
a=0
dt=(b-a)/length(c(AirPassengers))
t=seq(a+dt,b,dt)

r=4;dim=1
values=c(AirPassengers)
tvec=c()

X=array(0,dim=c((length(values)-r),dim*r))
Y=c()
for(j in 1:(length(values)-r)){
vec=c()
for(i in 1:dim){
vec=c(vec,values[j:(j+r-1)]^i)  
}
X[j,]=vec
Y=c(Y,(values[r+j]))
tvec=c(tvec,t[r+j])
}

beta=solve(t(X)%*%X)%*%t(X)%*%Y
cor(X%*%beta,Y)

#測定値、目標値、偏差
PVt=X%*%beta
SVt=Y
et=SVt-PVt



#Gauss-newton methodによるPID制御パラメータの推定

f=function(x){
PB=x[1]
TI=x[2]
TD=x[3]
mt_et=c()
for(j in 2:length(tvec)){
val=100*(et[j]+sum((et[1:j]^2)*dt)/TI+TD*(et[j]-et[j-1])/dt)/PB
mt_et=c(mt_et,val+SVt[j])
}
return(mt_et)
}

Y=SVt[2:length(SVt)]
h=0.001
lam=1
ite=10^4
sita=rep(1,3)
eta=5*10^(-1)

for(l in 1:ite){
sita_pre=sita
Z=array(0,dim=c(length(Y),length(sita)))
vec=sita
for(j in 1:ncol(Z)){
vec_sub=vec;vec_sub[j]=vec_sub[j]+h
Z_sub=(f(vec_sub)-f(vec))/h
Z[,j]=Z_sub
}
beta=solve(t(Z)%*%Z+diag(lam,ncol(Z)))%*%t(Z)%*%(Y-f(sita))
sita=c(sita+eta*beta)
print(sum((Y-f(sita))^2))
}

tmn=tvec[2:length(tvec)]

#制御量を追加した出力
plot(tmn,f(sita),xlim=c(min(tmn),max(tmn)),ylim=c(min(c(Y)),max(c(Y))),col=2,xlab="t",ylab="制御値と出力")

par(new=T)

plot(tmn,Y,xlim=c(min(tmn),max(tmn)),ylim=c(min(c(Y)),max(c(Y))),col=3,xlab="t",ylab="制御値と出力")

plot(tmn,mn,xlim=c(min(tmn),max(tmn)),ylim=c(min(c(mn)),max(c(mn))),col=1,xlab="t",ylab="制御量")


```
シリアル通信で１行の文字列を入力

# シリアル通信によりテキストを１行読み込み
arduinoやesp32でシリアル通信により１行分だけ受信します。
受信したテキストをコマンドとして処理することで、マイコン側の動作を変えていくことができます。




```c
#define MAX_LINE_LENGTH 100


static int recptr = 0;  //受信した文字数を保存する
static char recv[MAX_LINE_LENGTH];   //受信した文字列を保存する


int receiveCommand(void)
{
  int cmd = -1;           // -1 受信中 or 受信エラー


  //すべての受信データを受け取る
  //whileループを抜ける条件はシリアル受信データが無い
  while (1) {
    int receive_byte = Serial.read();

    //受信データが無ければループを抜ける
    if (receive_byte == -1) {
      cmd = 0;
      break;
    }

    recv[recptr] = receive_byte;


    //受信データの終わりをCRまたはLFとする(他の文字にすることも可能）
    //CRまたはLFの受信でループを抜ける
    if ((recv[recptr] == '\n') || (recv[recptr] == '\r')) {

      //'\0'は文字列の終端として認識される
      recv[recptr] = '\0';
      recptr = 0;
      cmd = 0;
      break;

    } else {

      //受信データがある場合は文字列の書込位置を一文字分だけ移動
      recptr++;
      //MAX_LINE_LENGTHで定義された文字数以上の場合は先頭に戻って上書きする
      if (recptr >= MAX_LINE_LENGTH) recptr = 0;

    }
  }
  return cmd;
}



void setup() {
  Serial.begin(115200);
}


void loop() {

  int cmd;

  // コマンドを受信
  if (Serial.available() > 0) {
    int rdata = receiveCommand();
    if (rdata != -1) cmd = rdata;
  }


  Serial.printf("%s\n", recv);
  delay(500);
}

```

# 動作確認
arduinoIDEの場合は[CRおよびLF]に設定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683949/aeaf95e0-d9cf-e1f0-ee52-c1547cc748f3.png)


# こちらを参考にして書き換えています

https://blog.goo.ne.jp/lm324/e/1f4df4437fa3b372c8668298eacd1572#comment-list
Cost ExplorerとCompute Optimizerの守備範囲はどこ？

## はじめに
### 概要
[コスト最適化ガイドブック](https://www.amazon.co.jp/AWS%E3%82%B3%E3%82%B9%E3%83%88%E6%9C%80%E9%81%A9%E5%8C%96%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E9%96%80%E7%95%91-%E9%A1%95%E5%8D%9A/dp/4046053550/ref=sr_1_1?adgrpid=149069678831&gclid=CjwKCAjwuqiiBhBtEiwATgvixM-EsncJvsk2vDuwjvkjMWRQcEMcgxsRvbGeC281_TSuAYOfLAr37RoC1h0QAvD_BwE&hvadid=648437705946&hvdev=c&hvlocphy=1009685&hvnetw=g&hvqmt=e&hvrand=17496674490370312426&hvtargid=kwd-2006515392173&hydadcr=25437_13559188&jp-ad-ap=0&keywords=%E3%82%B3%E3%82%B9%E3%83%88%E6%9C%80%E9%81%A9%E5%8C%96%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF&qid=1682609053&sr=8-1)を読む中でAWS Cost ExplorerとAWS Compute Optimizerの特徴とTrusted Advisorとの使い分けがよく分からなかったので調べてみました。

### この記事で得られること
- AWS Cost ExplorerとAWS Compute Optimizerの特徴とユースケース
- AWS Trusted Advisorとの使い分け

## AWS Cost Explorerとは
### 特徴
AWS Cost Explorerは、AWSのコストと使用状況データを視覚化し、分析できるツールです。
さまざまなフィルターやグループ化オプションを利用して、データを詳細に分析できます。また、コストの推移や予測も可能です。

### ユースケース
1. **コスト分析**: AWSのサービス別やアカウント別のコストを分析し、コスト削減のポイントを特定します。
2. **予算管理**: コストの推移や予測をもとに予算を設定し、予算オーバーを回避します。
3. **最適化**: リソースの使用状況を分析し、適切なサイズやタイプのリソースを選択します。


## AWS Compute Optimizerとは
### 特徴
AWS Compute Optimizerは、ワークロードに適したEC2インスタンスやオートスケーリンググループを推奨するサービスです。
機械学習を利用し、パフォーマンスとコストの最適化を図ります。

### ユースケース
1. **インスタンス最適化**: インスタンスのリソース使用状況をもとに、適切なインスタンスタイプやサイズを推奨します。
 EC2にCloudWatch エージェントをインストールすることでEC2のメモリ使用率も確認することが可能です。
2. **オートスケーリング最適化**: オートスケーリンググループのリソース使用状況をもとに、適切な最小・最大・必要なインスタンス数を推奨します。 

## AWS Trusted Advisorとの使い分け
Cost ExplorerとCompute Optimizerはそれぞれ異なる目的で利用されるサービスです。
ここでは似た機能を持つAWS Trusted Advisorとの使い分けを以下の表でまとめました。

| サービス | 特徴 | ユースケース |
|:-------:|:----:|:---------:|
| Cost Explorer | コストと使用状況データを視覚化・分析 | コスト分析、予算管理、リソース最適化 |
| Compute Optimizer | ワークロードに適したEC2インスタンスやオートスケーリンググループを推奨 | インスタンス最適化、オートスケーリング最適化 |
| Trusted Advisor | AWSのベストプラクティスに基づいた最適化提案 | セキュリティ、パフォーマンス、コスト最適化 |

## まとめ
Cost Explorer、Compute Optimizerでは過去のデータを元にコストの最適化を行います。
また、AWS Trusted AdvisorではAWSのベストプラクティスに基づいたリソースの最適化を行います。
似た機能を持っていますが、それぞれのサポート範囲を理解してサービス組み合わせて使うことでより効率的なコストの削減が得られます。

### 所感
何を元に最適化を行うのか？何に対して最適化を行うのか？という部分に着目することで各サービスの違いを理解することができました。
実際に手を動かして理解したいところですが、個人では最適化できるほどの使用量がないのでまたすぐに忘れそうです。。。

### 参照
[コスト最適化ガイドブック](https://www.amazon.co.jp/AWS%E3%82%B3%E3%82%B9%E3%83%88%E6%9C%80%E9%81%A9%E5%8C%96%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E9%96%80%E7%95%91-%E9%A1%95%E5%8D%9A/dp/4046053550/ref=sr_1_1?adgrpid=149069678831&gclid=CjwKCAjwuqiiBhBtEiwATgvixM-EsncJvsk2vDuwjvkjMWRQcEMcgxsRvbGeC281_TSuAYOfLAr37RoC1h0QAvD_BwE&hvadid=648437705946&hvdev=c&hvlocphy=1009685&hvnetw=g&hvqmt=e&hvrand=17496674490370312426&hvtargid=kwd-2006515392173&hydadcr=25437_13559188&jp-ad-ap=0&keywords=%E3%82%B3%E3%82%B9%E3%83%88%E6%9C%80%E9%81%A9%E5%8C%96%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF&qid=1682609053&sr=8-1)
Ruby3.2+RailsでYJITを有効化

Ruby3.2+Rails7.0でYJITを有効化してみました。

## TL;DR

* Rustをインストールしてから、Rubyをビルド
* Rails起動時に環境変数 `RUBY_YJIT_ENABLE=1` や `RUBYOPT=--yjit` を設定

## 手順

### Rustインストール

Ruby3.2ではビルド時にRustコンパイラ(rustc)が検出されると、自動的にYJITを含めてくれます。そのため最初にRustをインストールします。

Rustのインストール手順は省略しますが、一通り済んだら正常にインストールできたか確認します。

```sh
$ rustc --version
rustc 1.69.0 (84c898d65 2023-04-16)
```

### Rubyインストール

詳細は省略しますが、いつもと同じ様にRuby3.2をインストールします。ここではrbenv(+ruby-build)を使用しています。
前述の通り、自動的にRust版YJITを含めてくれるので、 `RUBY_CONFIGURE_OPTS` 等の指定は不要です。

```sh
$ rbenv install -v 3.2.2
```

インストールできたらYJITを有効化できるか確認します。
以下のように `+YJIT` と出力されていればOKです。

```sh
$ ruby --jit -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [arm64-darwin22]
```

### Rails設定

RailsアプリケーションでもYJITが有効となるように環境変数を設定します。
RUBY_YJIT_ENABLEを使用する場合、その値は ~~Rubyでtruthyなものであれば何でも良さそうです。~~ `1` / `true` / `yes` のいずれかを指定します。( @jnchito さんにご指摘いただきました。ありがとうございます :pray: 詳細は　[コメント欄](https://qiita.com/takeyuichi/items/d1aaa441873ee3508343#comment-a1dfda22e4747b3696d6) を参照ください。 )
RUBYOPTを使用する場合は、rbenvでも同環境変数が使われるため上書きしてしまわないように注意が必要です。

```sh
$ export RUBY_YJIT_ENABLE=1
# OR
$ export RUBYOPT=--yjit
```

ちなみに、 `dotenv-rails` gemを使用して環境変数を `.env`ファイルにまとめて管理しているケースも多いかと思いますが、この方法ではYJITは有効になりません。
(まずrubyが起動されてから `.env` ファイルが読み込まれるため)


設定が終わったらYJITが有効化されるか確認します。
以下のように `true` と出力されていればOKです。

```sh
$ bin/rails r 'p RubyVM::YJIT.enabled?'
true
```

springを使用している場合は環境変数が反映されないと思います。
その場合は `bin/spring stop` や `bundle exec spring stop` してから、再度 `bin/rails r 'p RubyVM::YJIT.enabled?'` を実行します。
Flutter関連の雑まとめページ

## はじめに
最近調べ始めたFlutterについてまとめていくページ
実案件に使えるかどうかの目線でパッケージを見ていっています

気が向いたら追加していく予定です

## 公式
### flutter
    - https://flutter.dev/
    - flutter公式サイト

### pub.dev
    - https://pub.dev/
    - Flutter用のPackagesまとめサイト、iOSのCocoapods.orgみたいなもの

## お勉強サイト
### flutter-study.dev
    - https://www.flutter-study.dev/
    - AppBar,ListViewなど基礎UIの使い方を学べる

### すらぼうの開発ノート
    - https://note-tmk.hatenablog.com/
    - Flutterのいろんな機能の解説をしてくれているサイト、シングルトンとかHiveの解説も有って便利

### Flutter基礎入門 by Flutter大学
    - https://zenn.dev/kboy/books/ca6a9c93fd23f3
    - 画面遷移（Navigator）などの使い方、基礎UIなどを動画も交えて説明してくれている

## 便利そうなパッケージ
### Navigation
#### persistent_bottom_nav_bar_v2
    - https://pub.dev/packages/persistent_bottom_nav_bar_v2
    - BSD-3-Clause
    - Flutterで用意されている標準のBottomNavigationBar使うより便利かつ高性能

### 内部データ保存
#### Hive
    - https://pub.dev/packages/hive
    - Apache License
    - 各種サイトを見る限りsqlite使うより高速、独自データクラスも可

#### sqflite
    - https://pub.dev/packages/sqflite
    - BSD-2-Clause
    - どうしてもsqliteを使いたい場合などに使用、基本的には速度の関係上Hiveの方が有利に感じる

#### shared_preferences
    - https://pub.dev/packages/shared_preferences
    - BSD-3-Clause
    - 簡易的なデータ保存用。AndroidのSharedPreferences、iOSのUserDefaultsのようなもの

### 多言語対応
#### flutter_localizations
    - https://docs.flutter.dev/accessibility-and-localization/internationalization
    - 
    - flutterの標準機能の多言語対応パッケージ

#### slang
    - https://pub.dev/packages/slang
    - MIT License
    - json,csv,YAMLでリソースの管理ができる

### 内部通知機能
#### flutter_local_notifications
    - https://pub.dev/packages/flutter_local_notifications
    - BSD-3-Clause 
    - AndroidとiOSの内部通知機能が比較的楽に実装ができる
pyopenjtalkがwindows10に入らない時の、自分の解決策

# 0.pyopenjtalkが入んない
win10でpyopenjtalkが入ってないとか言われて
入れようとしてもwheelsでエラー出る…。
え、なんかapi入れてビルドしてpyopenjtalkもビルドしないといけないの？

# 1.解決策
windowsビルドツールのcmakeにpath通しましょう…
本当にそれだけだった…
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin
そしたらすんなりpyopenjtalk入ってくれた…
Macの設定メモ

新しい端末を使い始めるときにやる設定の自分用メモ。

## 技術的なの
- Docker Desktop
	- 端末のスペックに応じてResourcesをいじる
- Visual Studio Code
	- 拡張機能
		- GitHub Copilot
			- 相棒。こいつがいないと生きていけない
		- GitHub Themes
			- テーマ集
			- GitHub Darkがお気に入り
        - GitHub Pull Requests and Issues
            - プルリクの差分をVSCode上で確認できる
        - その他VSCodeが勧めてくるやつ
		- あんまり入れてない。調査不足
- iTerm
	- ターミナル
	- 会社の推奨だから使ってるけど、特にこだわりはない
- Homebrew
    - git
    - 言語のランタイムとかあれば
- .zshrc
	- Powerlevel10k
    	- あんまりこだわりはない
    - GitHubのトークンとか
- 必要に応じてPostmanとか


## キーボード
- システム環境設定
	- 修飾キー
		- CapsLock→Control
	- ユーザー辞書
		- 会社メールアドレスとか登録しておく
	- IME
		- 特に不満ないのでMac標準
		- ライブ変換、Windows風のキー操作
		- 変換候補のフォントをゴシック体に
	- 音声入力
		- 使ってないけど、便利かもしれない
- Karabiner Elements
	- 左Cmd単打ちで英数、右Cmd単打ちでかな
	- Windows用キーボードのWin（Cmd）とAlt（Opt）切り替え
	- Space + IJKLで↑←↓→
	- Space + UOでHome, End
	- トラックボール用の設定（Kensington純正ソフトがうまく動かない場合）
- Clipy
	- クリップボード拡張
	- スニペット
    	- 業務報告文（`おはようございます。本日の予定：`）

## ポインティング
- KensingtonWorks
	- トラックボール（Slimblade Pro）の設定
	- 単ボタン：左右クリック、中央クリック、esc
	- 組み合わせ：Mission Control、仮想デスクトップ左右切り替え、あと一つ検討中
	- スクロール反転
- Mos
	- Macの慣性スクロールが気に食わないのでWindowsみたいにする
	- マウスだけスクロール反転もできる

## ウインドウ
- AltTab
	- Cmd+TabでWindowsみたいなウインドウ切り替えができる
- Rectangle
	- Windowsみたいに、ドラッグとかショートカットとかでウインドウを左右に寄せたり最大化したりできる
	- テンキーサイズのマクロパッドにショートカットを割り当ててる

## ブラウジング
- Vivaldi
	- 暫定最強ブラウザ
	- マウスジェスチャー
		- L 前のタブ
		- R 次のタブ
		- D タブを閉じる
		- U 更新
		- RD 選択した文字列で検索
	- ロッカージェスチャー
		- 右クリック→左クリック 戻る
		- 左クリック→右クリック 進む
	- ~~右クリック+スクロールでタブ切り替え~~
		- WindowsならできるのにMacだとできない。ユーティリティソフトをかましてるせいな気がする
	- 検索
		- デフォルトをDuckDuckGoに
		- 必要に応じてGoogle Driveとかbacklogとか追加しておく
	- 拡張機能
		- 1Password
		- DeepL
	- ブックマーク
    	- よく使うページにはニックネームを付けておく
        	- 例えばQiitaのトップページに「qi」と付けておけば、`cmd+E→qi`と打つだけでQiitaを新しいタブで開ける
		- [表示しているページのタイトルをコピーするブックマークレット](https://zenn.dev/lollipop_onl/articles/eoz-copy-url-bookmarklet)
- 1Password
	- パスワード管理
		- Chromeに紐つけたりAppleアカウントに紐つけたりすると、別ブラウザとかWindowsとかで使いにくいので独立させた方がいい
	- TouchID対応

## コミュニケーション・ドキュメント
- Slack
- Notion

## その他
- システム環境設定
    - Dockを自動的に隠す
    - Hey Siriを無効に
    - ダークモード
- Obsidian
	- シンプルなMarkDownメモ
	- 個人メモに使ってるけど、あんまり使いこなせてない
- SpaceLauncher
	- Space + 任意のキーでアプリを起動できるランチャー
	- あんまり使ってない
- Screenie
    - スクリーンショットをメニューバーからドラッグ＆ドロップできる
Hugo + CloudFront + S3 + GitHub Actions でCI/CD付きブログサイトを構築してみる Part1 Hugo構築編

## 作成経緯
自分のHP的なのを作ろうとふと思う。
Amazon LightsailでWordPressを使って一度構築してみたけど、セキュリティとか色々やらなきゃならないことがあって常に更新が必要で、気まぐれで更新するスタイルを取りたい自分には合わないかも……。
よくよく考えると別にWordPress自体いらなくてもっと静的で簡単な構築でいいのでは……？と考えていたところ、https://dev.classmethod.jp/articles/cloudfront-and-s3-using-hugo-with-github-actions/ のサイトを見つけ、構成自体はシンプルで簡単そうなので、AWS/github Actionsの勉強がてらこちらでの構築を目指した。

記事の内容をまるまる真似ではなくて自分の環境に合わせて変更を加える。
例えばcloudformationはちょっと使いにくいのでterraformに変更する。
CloudFrontまで使うかな……？

まずはHUGOの環境構築から始める。

この記事はそのメモやまとめです。
すでに設定済みの項目がいくつかある。
試行錯誤しながらやったので、手順として不要かもしれない。**あくまでメモ用。**

## 環境
```bash
Windows10 WSL2 AlmaLinux 8.6 #基本的にVscode上でこのWSL2を操作します
Docker Desktop/Vscode/WSL2が連携済み
VscodeにDockerの拡張機能がインストール済み
```

## 最終形
最終的にはこのようなディレクトリ構成になった。
HUGO専用のgitリポジトリを作ってそこに格納している。
```bash
.
├── docker-compose.yml
├── hoge
│   ├── archetypes
│   ├── assets
│   ├── config.toml
│   ├── content
│   ├── data
│   ├── layouts
│   ├── public
│   ├── resources
│   ├── static
│   └── themes
└── README.md
```

## docker-compose でHUGOを立ち上げる
まずはHUGOの実行環境を整えていく。
dockerのイメージがあるようなのでそれを活用していく。
参考：https://qiita.com/ub0t0/items/4ac2f2d8c3e8fbdfcfad
```docker:docker-compose.yml
version: '3'
services:
    hugo:
        image: klakegg/hugo:0.107.0-ubuntu
        volumes:
            - ".:/src"
        entrypoint: bash
        ports:
            - "1313:1313"
        tty: true
        working_dir: /src
```
保存して以下を実行してdockerを動かす。
```bash
docker-compose up -d
```
その後、vscode上のdocker拡張機能に移動し、Attach Shell
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185852/4de3fd09-1617-36f4-4316-55c54cc7ac86.png)
でコンテナがvscode上のターミナルで開かれるので、
```
hugo version
```
を実行してversionが帰ってくれば成功。ブラウザで`http://localhost:1313/` にアクセスしてみる。
今段階ではなにもコンテンツがないので`ERR_EMPTY_RESPONSE`が帰ってきても想定内。

## 一時的なHPのコンテンツを作る
参考：https://zenn.dev/harachan/articles/a043e9a756cae4
themeについては https://themes.gohugo.io/ から自分にあったものを選ぶといい。
今回はお試しなので参考にした手順と同じthemeを利用した。
```
hugo new site hoge
cd hoge

# gitをインストール
apt-get update
apt-get install git

# themeを導入する
cd themes
git clone https://github.com/kakawait/hugo-tranquilpeak-theme.git
```

###  config.tomlを編集する
仮なので参考手順からコピペしてプロフィールなどだけ編集。
細かくいじる場合は https://github.com/kakawait/hugo-tranquilpeak-theme/blob/master/docs/user.md#tranquilpeak-configuration にマニュアルがあるのでこちらを参考にしながらいじるといい感じになりそう。

編集後、コンテナ上で
```
hugo server -D
```
を実行してブラウザから`http://localhost:1313/`にアクセスしてHPが表示されるか確認する。
確認できたらCtr + cでプロセスを止める。

### 記事を作る
```
hugo new posts/my-first-post.md
```
適当に記事を書く
```
---
title: "My First Post"
date: 2023-04-27T08:44:14Z
draft: true
---
## テスト投稿
こんにちは
```
保存後、
```
hugo server -D
```
を実行して新しい記事が作成されていれば成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185852/5cb7928b-777b-f541-dc07-98467eac8c90.png)

# ハマったところとか
dockerのコンテナをvscode上からvscodeにアタッチして、コマンドを実行すると、
実行によって生成されたファイルなどのユーザーなどがすべてrootになっている。
気持ち悪いので自分のユーザーとグループに変更したがなにか解決方法はないものか……。

# 参考記事
https://zenn.dev/harachan/articles/a043e9a756cae4
https://qiita.com/ub0t0/items/4ac2f2d8c3e8fbdfcfad
https://dev.classmethod.jp/articles/cloudfront-and-s3-using-hugo-with-github-actions/

# 次にやること
必要なAWSのリソースをterraformで作成
HUGOでHPをいい感じに編集する
GitHub Actionsの設定
vee-validateのメールアドレス用ルール(email)に気をつけろ

## vee-validateのemailルールは全角文字が許容されている

このようにemailルールを使用すると、xxxxxxx@yyy.zzzというアドレスを入力した際に'xxxxxxx'の部分に全角文字が入力できてしまう。
`<input v-validate="'email'" data-vv-as="email" name="email_field" type="text">`
## 解決
シンプルにカスタムルールを作る。

```js:vee-validate.js
extend('customEmail', {
  ...email,
  validate(value) {
    // 全角文字の正規表現
    const fullWidthCharRegex = /[^\u0020-\u007E]+/
    // 全角文字が含まれている場合は false を返す
    if (fullWidthCharRegex.test(value)) {
      return false
    }
    // email ルールの結果を返す
    return email.validate(value)
  },
  message: '出力するエラーメッセージ',
})
```
MVCモデル

# MVCモデルとは
MVCモデルは，ソフトウェアの設計モデルの一つで，Webアプリケーションの構成要素をModel(モデル)，View(ビュー)，Controller(コントローラー)という３つに分割し，それぞれの機能ごとに開発・管理を行うモデル．

# それぞれの役割
MVCモデルは機能によってプログラムを分けることを目的として利用されるため，それぞれに以下のような役割を持つ．
### Model(モデル)
ビジネスロジックを担当する．アプリケーションが扱うデータの取得・保存・更新・削除などを行う．

:::note info
ビジネスロジックとは
そのシステムにおける、システム固有の処理を行う部分で，Modelにおいて，DBの操作などを指す．
:::

### View(ビュー)
ユーザが直接見る画面の表示や入出力などのユーザインタフェースを担当する．HTMLやCSSなどを利用して実装される部分．

### Controller(コントローラー)
ViewとModelの橋渡し的な役割を担当する．ViewとModelの間に位置し，ユーザからの操作を受け取ってModelを操作し，結果をViewに反映する． 

# メリットとデメリット
MVCモデルを利用することで，以下のメリット・デメリットがある．
### メリット
**○効率が良い**
役割や機能別でコードを分けることで，作業区分が明確化され，開発や変更などがしやすくなり，作業効率が上がる．また，並列的に開発を行うことができるため，開発の効率は高くなる．

**○保守性の確保**
MVCモデルを利用した場合，比較的に独立性が高いため，他の要素に対する変更やバグなどの影響が小さく，保守性や品質が向上する.

**○再利用性**
MVCモデルの考え方で開発したコードは，他のMVCアプリでも再利用しやすい．あるアプリで機能することが検証されているため，再利用した際の，信頼性も確保することができる．

### デメリット

**×処理速度の低下**
DBのやり取りを行うModelや，仲介を行うControllerの負担が大きくなり，処理速度が遅くなる可能性が生じる.

**×開発に制約がかかる**
オブジェクトを機能ごとにを分割して作成した場合，オブジェクト間のやりとりに制約が生じ，コードを柔軟に記述できなくなることがある．

# 処理の流れ
![MVC image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/12d750f1-5f86-3715-1573-ef86b46f1478.png)
MVCモデルにおける基本的な処理の流れは以下である．
1. ユーザからのリクエストを<font color="red">Controller</font>が受け取る
2. <font color="red">Controller</font>は受け取ったリクエストをもとに，<font color="SkyBlue">Model</font>に指示を送る
3. <font color="SkyBlue">Model</font>はデータの処理を行い，処理結果を<font color="red">Controller</font>に送る
4. <font color="red">Controller</font>は受け取った処理結果を<font color="Green">View</font>に送る
5. <font color="Green">View</font>は受け取った処理結果(レスポンス)を画面に表示する

# その他のソフトウェア設計モデル
MVCモデル以外にもさまざまなソフトウェア設計モデルがある．（説明は割愛）
* MVP：Model, View, <font color="Gold">Presenter</font>
* MVVM：Model,View, <font color="Gold">ViewModel</font>
* Document-View：<font color="Gold">Document</font>, View
* PAC：<font color="Gold">Presentation, Control, Abstractio</font>
* BCE：<font color="Gold">Boundary, Control, Entity</font>
[Git] 動作を試す 実行例6：statusで現在の作業フォルダ内の変更状況を見る

Gitの動作を理解するために、Gitのコマンドを実際に試して、結果を見てみました。

1つの記事内で一連のGitコマンドが完結しているので、これら一連のコマンドを順に実行させて結果を見ることで、一連のGitの動作を実際に体感でき、一通り独習することが可能です。

※前回記事のリポジトリ状態からの続きになっています。
| [前回記事へ](https://qiita.com/dl_from_scratch/items/a4db247acdfd3c7381ba) | [目次へ：Git関連記事のまとめページ](https://qiita.com/dl_from_scratch/items/597bc28a4787a7901d21) | [次回記事へ](https://qiita.com/dl_from_scratch/items/c8ea6c200fbaa91adc14) |
|:-:|:-:|:-:|

# 実行例

```
echo Sample-Added-14 >> test1.txt
echo Sample-Added-41 > test4.txt
git status
↓
結果: 
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test4.txt

no changes added to commit (use "git add" and/or "git commit -a")

※状態表示を簡略化して表示
git status -s
↓
結果: 
 M test1.txt
?? test4.txt

git add *.txt
git status
↓
結果: 
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test1.txt
        new file:   test4.txt

git status -s
↓
結果: 
M  test1.txt
A  test4.txt

git commit -m "message4"
↓
結果: 
[master 94996a0] message4
 2 files changed, 2 insertions(+)
 create mode 100644 test4.txt

git status
↓
結果: 
On branch master
nothing to commit, working tree clean

git status -s
↓
結果: 
(なし)

-----

dir /b
↓
結果: 
test1.txt
test2.txt
test4.txt

del test4.txt
dir /b
↓
結果: 
test1.txt
test2.txt

git status
↓
結果: 
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    test4.txt

no changes added to commit (use "git add" and/or "git commit -a")

git status -s
↓
結果: 
 D test4.txt

git add .
git status
↓
結果: 
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    test4.txt

※「git add .」により、削除したファイルも削除としてコミットされる予定との表示となる。

git status -s
↓
結果: 
D  test4.txt

※「git add .」操作の前の状態に戻す
git restore --staged .
git status
↓
結果: 
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    test4.txt

no changes added to commit (use "git add" and/or "git commit -a")

git status -s
↓
結果: 
 D test4.txt

※削除したファイルと同じ内容を書き込んで、手動で復元すると、
echo Sample-Added-41 > test4.txt
git status
↓
結果: 
On branch master
nothing to commit, working tree clean
```

# 環境

Windows 10、PortableGit-2.40.0-64-bitを使用、全てローカルPC上で実施、GitHub等は不使用。
Vue3でpdfmakeの日本語化するときのvfs周りの問題対処

# 結論
[このgithub投稿](https://github.com/bpampuch/pdfmake/issues/1877#issuecomment-962446474)のorderでコンポーネントをimportする

# 環境
+ Win11
+ Laravel Jetstream with Inertia.js
+ Vue3

# 詰まるまでの過程
+ [公式](https://pdfmake.github.io/docs/0.1/getting-started/client-side/)を見てインストールしました。その際コンポーネントは公式にもある通り、
```vue:hogehoge.vue
<script setup>
import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
```
を用いました。
+ [公式](https://pdfmake.github.io/docs/0.1/fonts/custom-fonts-client-side/vfs/)を参考に、游ゴシックをttfファイルに変換し、node_module/pdfmake直下にexamples/fontsというフォルダを作りそこにコピーし、``node build-vfs.js "./examples/fonts"``しました。
+ 生成された``build/vfs_fonts.js``の中身を見て、用意したttfファイルの名前を確認し、正しくbuildされたことが確認できました。
+ この時点では以下のようなコードとなっています。
```vue:hogehoge.vue
<script setup>
import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
pdfMake.vfs = pdfFonts.pdfMake.vfs;

pdfMake.fonts = {
    YuGothic: {
        normal: 'YuGothic-Regular-01.ttf',
        bold: 'YuGothic-Regular-01.ttf',
        italics: 'YuGothic-Regular-01.ttf',
        bolditalics: 'YuGothic-Regular-01.ttf'
    }
}

const defaultStyle = "YuGothic"

function exportPdf() {
    let text = [["hogehoge","hugahuga"]]
    let document = {
        content: [
            {
                table: {
                    widths: [100, 100],
                    body: text
                }
            },
        ],
        defaultStyle: {
            font:defaultStyle
        }
    }   
    pdfMake.createPdf(document).open();
}
</script>
```

+ 適当なボタンで関数を発火させたところ、``Uncaught File 'YuGothic-Regular-01.ttf' not found in virtual file system``とコンソールに表示されました。
+ vfsにフォントが見つからないという趣旨ですが、VScodeのvite拡張機能を使っているため更新時にbuildされているし、このエラー文でググるとStackOverflowで見かける``pdfMake.vfs = pdfFonts.pdfMake.vfs``の記述は既に済ませていました。

# 解決
最初に貼った、pdfFontsにdefault export出来ないという趣旨のIssueを眺めていたところ、Svelte環境におけるimportとして
```vue
import * as pdfFonts from  'pdfmake/build/vfs_fonts';
import pdfMake from "pdfmake";
pdfMake.vfs = pdfFonts.pdfMake.vfs
```
があり、その下に
> Thank you! Doing this solved my build issue using vite bundler with a vue project
> ありがとう！viteを使ったvueプロジェクトのbuild時の問題もこれで解決したよ。

とあったので自分も流用したら解決しました。
ポイントとしては先頭の``import * as pdfFonts from  'pdfmake/build/vfs_fonts';``で、まずviteだと気付きにくいのですが手動で``npm run build``をしてみると、

``"default" is not exported by "node_modules/pdfmake/build/vfs_fonts.js", imported by "resources/js/hogehoge.vue".``

と表示され、defaultに関係するエラーが表示されています。`` import * as``とすることでこのエラーはなくすことが出来ます。
次の順序を逆にすることで動くことは原理が分からないので何とも言えませんが、公式Docsがたまに全くあてにならない（どころか、変な先入観を持たせて来るせいで足を引っ張る）ので気を付けるという勉強になりました。
「DevOpsチームとして」持つべき9つの能力

最近はDevOpsチームとしてプロダクト開発を進める会社も増えてきた印象があります。

一方で**DevOpsチームとして機能しているかどうか**悩んだり、DevOpsチームだけでは上手く開発が進められないこともあるように感じています。

## DevOpsチームが持つべき9つの能力

『チームトポロジー　価値あるソフトウェアをすばやく届ける適応型組織設計』では、ストリームアラインドチームが持つべき能力を次のように定義しています。

> - アプリケーションセキュリティ
> - 事業成長性分析と運用継続性分析
> - 設計とアーキテクチャー
> - 開発とコーディング
> - インフラストラクチャーと運用性
> - メトリクスとモニタリング
> - プロダクトマネジメントとオーナーシップ
> - テストとQA
> - ユーザーエクスペリエンス（UX）

「ストリームアラインドチーム」はこの著書で定義されているチームの種類ですが、この観点はDevOpsチームでも利用できるかと思います。

スーパーエンジニアであれば、上記の能力すべてを満たすことができるでしょうが、一般的には「〜はわかるけど、...は知らない」となるはずです。

そのため各エンジニアのスキルを合計した結果が重要になります。そのうえで、チームの特徴や弱点が見えてくるでしょう。

## どのようにギャップを埋めるか

チームの弱点が見えてきたとして、これをどう埋めていくかはとても難しい課題です。

『チームトポロジー』では、ギャップを埋めることをサポートするチーム(イネイブリングチーム)との協働を推奨していますが、実際にこういうチームを抱える会社は少ないことでしょう。

現実に照らし合わせるなら、近くにいるスペシャリストや有識者をつかまえて、アドバイスをもらったりしばらくの間サポートしてもらったりするのが良さそうです。
carrier waveの基本的な使い方

## Gemfileにcarrierwave追加
```
# gem
gem 'carrierwave', '~> 2.0'
```

## アップローダークラスの生成
```
bundle exec rails g uploader アップローダー名
# bundle exec rails g uploader Image
```

:::note 
デフォルトでstorage :fileが指定されているので、アップロードしたファイルはpublic/配下に保存されます。保存されるディレクトリは、store_dirで設定されます。
:::

余談ですが、保存先は以下のstore/dirです。

```app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
.
.
.

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_whitelist
    %w(png jpg)
  end

  def filename
    original_filename if original_filename
  end
end
```
もし、例えばS3に変更したい場合は、'fog'というgemをインストールした上で、以下のファイルの設定を変更する。
```config/initializers/carrierwave.rb
unless Rails.env.development? || Rails.env.test?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: 'XXXXXXXX',
      aws_secret_access_key: 'XXXXXXXXXXXXXXXXXXX',
      region: 'ap-northeast-1'
    }

    config.fog_directory  = 'rails-photo-123'
    config.cache_storage = :fog
  end
end
```

## アップロード画像のカラムを追加
続いて、アップロード画像を保存したいモデルにカラムを追加する。
```
bundle exec rails g migration add_カラム名_to_users カラム名:string
# bundle exec rails g migration add_picture_to_users picture:string
```
::: note 
このカラムには、「画像のデータ」ではなく「画像のファイル名」を保存します。カラムを追加する際もstringを指定するようにしましょう。
:::

## アップローダークラスとカラムの紐づけ
最後にアップローダークラスとカラム名を紐づければおわりです。簡単...
```
class モデル名 < ActiveRecord::Base
  mount_uploader [:カラム名], [アップローダークラス]
  # mount_uploader picture,Image
end
```
IBM Cloud: App IDのユーザーに動的に権限を設定する

# 1. はじめに

App IDユーザーがIBM CloudのCustomer Portalにログインしても、最初は何もできない。当然ながら何も権限が付与されていないからである。特に、App IDを使ってユーザーを管理している際に困るのは、**初回ログインが完了するまでユーザーが登録されない**ことである。もちろんユーザーに1度ログインしてもらい、連絡をもらってから管理者が権限を割り当てるということもできるだろうが、運用的に非常に面倒である。
IBM CloudのIAMでは、ユーザープロファイルの属性の内容に応じて、動的に権限を割り当てる機能があるので、その機能を利用してこの問題を解決したい。
今回は、VPN for VPCの[Client to Server VPN機能を利用するための権限](https://cloud.ibm.com/docs/vpc?topic=vpc-create-iam-access-group)を動的に付与する方法を例に紹介したいと思う。

P.S. [App IDのユーザーでIBM Cloudのポータルを利用する際に動的にアクセスグループを設定する](https://qiita.com/teruq/items/e72fececdab8d8736176)という記事も参考にさせていただきました。

# 2. アクセスグループの作成と動的ルールの設定

- アクセスグループ名は`Client-to-Site VPN`とする。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/87188b33-cb1f-0038-8194-cdb2ff610e6e.png)
- このアクセスグループに、Client to Server VPNを利用するための権限を付与する。
    - Accessに移動し、`Assign access`を押下。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/6aa08636-62b5-99c9-a9c8-3a9687feddeb.png)
    - `VPC Infrastructure Services`というServiceに対して、`Users of the VPN server need this role to connect to the VPN server`を割り当てる。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/85249623-973e-db4e-0a8c-fdde54d2376e.png)
    - 登録結果。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a8f7149b-088b-ee2a-dffc-78f64395a620.png)
- 動的ルールの追加
    - Dynamic rulesに移動し、`Add`を押下。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/dca58553-d1b4-90a8-5b35-7d0cc2ac3c74.png)
    - rule名や、連携するApp IDのIDP(`https://cloud.ibm.com/iam/identity-providers`で登録している情報）を選択。以前はIDPのrealm IDを指定する必要があったが、現在はUIから選択可能となっていて設定が容易になっている。今回は、ユーザー属性に`"isclientvpn"="true"`となっていた場合に、権限が付与されるようになっている。またこの権限のセッション時間はデフォルトでログインしてから1時間である。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/487b7bc1-0eed-2a94-3ca3-1ed6dcadfe0b.png)
    - 設定完了後の結果。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/0d5d5bff-bf92-02ec-7481-a117d4b44b50.png)

# 3. ユーザー設定に条件に適合する属性を追加
今回はApp IDのCloud Directoryで管理しているユーザーで、まだ一度もログインしたことがないユーザーを使って検証してみる。
- ユーザーの詳細情報を確認。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/fe2ecd8a-607b-b473-90da-2676035c709c.png)
- Custom Attributesとして以下を設定。

```
{"isclientvpn":"true"}
```

- 結果、以下のようになる。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/0229ac64-3af0-f2ae-50fa-feeff1b3bb4a.png)


# 4. App IDユーザーでのログインした際の結果

- IAMでユーザー情報を確認した結果。今回作成したアクセスグループが動的に割り当てられている（有効期限が1時間）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/2e77c6d7-eda5-79a4-db6f-449df659a5a3.png)
- IAMでアクセスグループを確認した結果。対象ユーザーが動的に追加されている（有効期限が1時間）![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/02a02aea-0bd3-226b-cc7b-533cb0ce565b.png)
pycocotoolsをgithubのソースコードからインストールするときに気を付けること

# githubからソースコードをcloneする前にしておくこと
以下のコマンドで必要なライブラリをインストールしておく
```
$ pip install numpy matplotlib cython 
```

# pycocotoolsをインストールする
1. githubからcloneする
```
素のcocoapiが欲しい人
$ git clone https://github.com/cocodataset/cocoapi.git

YoutubeVISが必要な人
$ git clone https://github.com/youtubevos/cocoapi.git
```
1. 以下のコマンドを実行する
```
$ cd cocoapi/PythonAPI
$ python setup.py build_ext --inplace
$ python setup.py build_ext install
```

# インストールできたか確認する
```
$ pip list
...
...
pycocotools
...
...
```
ChatGPTで最新情報を取得したい【WebChatGPT】


## WebChatGPTとは



WebChatGPTとは、ChatGPTに機能を追加するためのChrome拡張機能です。
ChatGPTは大量のテキストデータを学習しており、様々な質問に対して回答をすることができますが、最新の情報については答えることができないことがあります。

WebChatGPTを利用することで、ChatGPTの回答にリアルタイムの検索結果を含めることができます。

WebChatGPTはChromeウェブストアからダウンロードができ、ChatGPTのチャット入力欄下部にボタンとプルダウンメニューが追加されます。

![スクリーンショット 2023-04-28 16.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/294b5c1d-310e-be04-ed16-17883bf88ca9.png)

## 使ってみた


### プロンプト
```プロンプト
現在出ているiphoneの最新機種は？
```

### WebChatGPTなし 
```WebChatGPTなし
2023年4月現在、私が知る限り、iPhoneの最新機種はiPhone 15シリーズです。ただし、この情報は私がトレーニングされた2021年までに発表されたものであり、実際の最新情報についてはAppleの公式ウェブサイトやニュースソースをチェックすることをお勧めします。
```

### WebChatGPTあり
```WebChatGPTあり
現時点で最新のiPhoneはiPhone 14シリーズとなります。iPhone 14シリーズは2022年11月現在、Apple、4キャリア（楽天モバイル、ドコモ、au、ソフトバンク）、家電量販店で予約を受け付けており、一括購入価格は各社で異なります[[5](https://www.smamoba.jp/mobalife/iphone-price/)]。

iPhone 14シリーズには、iPhone 14、iPhone 14 mini、iPhone 14 Pro、iPhone 14 Pro Maxがあります。これらの機種については、各社の最安値や性能、評判などが比較されており、選ぶ際の参考になります[[1](https://rentry.jp/note/iphone/), [3](https://crusie-n-more.com/iphoneosusumekisyu/), [4](https://bitwave.showcase-tv.com/recommended-iphone-model-is-this/)]。

なお、iPhone 15の最新情報についても報じられており、最新のスペックやデザインに関する情報が出回っていますが、発売日などの詳細についてはまだ明らかにされていません[[2](https://www.maturikun.com/iphone-15)]。
```


2023年4月現在は、iPhone 14が最新になります。
やはり、WebChatGPTを入れている方は正解でいれていない方は不正解でした。
Linux初心者 .soファイルとヘッダーファイルを使ってC++のソフトを作る

Linux初心者が蹴躓くところですが、.soファイルとヘッダーファイルを使って、C++のソフトを作ってみた。（備忘録）

```
my_project/
├── CMakeLists.txt
├── include
│   └── test.h
├── src
│   └── main.cpp
└── lib
    └── libtest.so
```

libtest.soには、
```cpp
int add(int a, int b);
```
として、aとbの足し算の関数を用意。

main関数

```cpp
#include <stdio.h>
#include "test.h"

int main() {
  int a = 3, b = 4;
  int c = add(a, b);
  printf("%d + %d = %d\n", a, b, c);
  return 0;
}
```

CMakeLists.txtは下記。
```cmake
cmake_minimum_required(VERSION 3.10)
project(my_project)

# includeディレクトリをインクルードパスに追加する
include_directories(include)

# 共有ライブラリをリンクする
link_directories(lib)
link_libraries(test)

# 実行可能ファイルをビルドする
add_executable(main src/main.cpp)

# 実行可能ファイルにリンクするライブラリを指定する
target_link_libraries(main test)
```

LD_LIBRARY_PATHを設定する。
libフォルダに設定するには
```
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH
```
とする。

コマンドで
```
mkdir build
cmake ..
make
```
とすると、mainという実行ファイルができるので、
コマンドでmainを実行すると、
3 + 4 = 7
という出力を得られる。
ターミナル上でインクリメンタルサーチを行う fzf の便利な利用法を思いつく限り挙げてください。

思ったほどいいのはでてきませんでした。

---

以下は、fzfを使用してターミナル上でインクリメンタルサーチを行う便利な利用法の例です。

1.  ファイルの検索:

```makefile
# ファイルを検索して開く
vim $(fzf)

# ファイルを検索して削除
rm $(fzf)
```

2.  コマンドの履歴の検索:

```bash
# コマンドの履歴を検索して実行
$(history | fzf | awk '{print $2}')

# 直近のコマンドを再度実行
fc -s $(history 1 | fzf | awk '{print $1}')
```

3.  Gitリポジトリ内のファイルの検索:

```bash
# gitリポジトリ内のファイルを検索して開く
vim $(git ls-files | fzf)

# gitリポジトリ内のコミットを検索して表示
git log --oneline --decorate | fzf | awk '{print $1}' | xargs git show
```

4.  SSHホストの検索:

```bash
# SSHホストの検索して接続
ssh $(cat ~/.ssh/config | grep Host | cut -d ' ' -f2 | fzf)
```

5.  環境変数の検索:

```bash
# 環境変数を検索して表示
printenv | fzf
```

以上のように、fzfを使うと、様々な用途でインクリメンタルサーチを利用することができます。fzfの詳しい使い方は、公式のドキュメントを参照してください。


## ユニークだったりニッチな使用法でも構いません。もっと用例を挙げてください。
なお、コマンド例は不要です。


以下は、fzfを使用してターミナル上でインクリメンタルサーチを行う便利な利用法の例です。

1.  キーバインディングの検索:

fzfは、キーバインディングの検索にも使用できます。例えば、Vimの場合、`:help`コマンドでキーマップのドキュメントを表示し、`<C-d>`でfzfで検索して、該当するキーマップを見つけることができます。

2.  集計データの検索:

fzfは、データの集計や統計分析などのタスクでも役立ちます。例えば、CSVファイルの中から特定の列を抽出し、集計した結果をfzfで検索して、目的のデータを見つけることができます。

3.  リンクの検索:

ブラウザのブックマークやMarkdownファイルなどで、リンクを検索する場合にもfzfが役立ちます。例えば、Markdownファイル内で、リンクを検索する際にfzfを使用して、目的のリンクを見つけることができます。

4.  プログラム言語の関数の検索:

fzfは、プログラム言語の関数やメソッドの検索にも使用できます。例えば、Pythonの場合、`dir()`関数でオブジェクトの属性を表示し、fzfで検索して、目的の属性を見つけることができます。

5.  タスク管理:

fzfは、タスク管理にも役立ちます。例えば、ターミナル上でタスクを管理するために、fzfでTODOリストを作成し、未完了のタスクを検索して、目的のタスクを見つけることができます。

以上のように、fzfは、様々な場面で役立つインクリメンタルサーチのツールです。ただし、fzfの使い方には熟練が必要であることを忘れずにください。


## もっと別の用例をたくさん挙げてください。なお、説明は不要です。


以下は、fzfを使用してターミナル上でインクリメンタルサーチを行う便利な利用法の例です。

1.  システムログの検索
2.  コードの履歴の検索
3.  プロセスの検索
4.  キャッシュファイルの削除
5.  重複ファイルの削除
6.  シェル関数の検索
7.  Dockerコンテナの検索
8.  パッケージの検索
9.  ネットワークデバイスの検索
10. ドキュメントの検索
11. 翻訳辞書の検索
12. クリップボード履歴の検索
13. プロジェクト内のファイルの検索
14. ファイルのタイムスタンプの検索
15. サーバーのログの検索
16. バージョン管理システムのログの検索
17. パッチファイルの検索
18. パスワード管理の検索
19. 複数のバッファを切り替える
20. カーソル位置に関する操作

以上のように、fzfは、様々な場面で役立つインクリメンタルサーチのツールです。fzfの使い方には熟練が必要であることを忘れずにください。