OmniAICreator/Qiita-1.07M huggingface dataset:
VeeValidate useFormについてAIにドラゴンボールに例えてもらった

## そもそもVeeValidateとは？
VeeValidateは、Vue.js用のフォームバリデーションライブラリである。

## なぜこの記事を書こうと思ったのか。
VeeValidateの公式ドキュメントが非常に読みづらいからである。

## Q.https://vee-validate.logaretm.com/v4/api/use-form/ に書いてあるものをそれぞれドラゴンボールに例えてわかりやすく説明して
A.vee-validateのuseFormのAPIをドラゴンボールに例えて、一つ一つ説明していきます！
### 基本的なフック（悟空の基本技）
#### values
戦闘力測定器のようなもの
フォーム内の全ての値（戦闘力）をリアルタイムで測定できる

#### errors
界王様からの警告メッセージ
技の使い方や戦い方が間違っている時に教えてくれる

#### meta
悟空の戦闘状態を示すスカウター的な存在
フォームの状態（戦闘中か、エラーがあるかなど）を示す

#### isSubmitting

かめはめ波を放っている最中かどうか
フォームが送信処理中かどうかを示す
### メソッド（使える技）
#### handleSubmit
「かめはめ波」を放つときの掛け声のような存在
フォームを送信する時の合図
#### handleReset
仙豆を食べるようなもの
フォームを初期状態に戻す
#### setFieldValue
瞬間移動のように、特定の場所（フィールド）に直接移動する
フィールドの値を直接設定できる
#### setFieldError
戦闘力が足りないことを自覚するような
エラーメッセージを手動で設定
#### setErrors
全体的な戦闘の問題点を認識する
複数のエラーを一度に設定
#### setValues
超サイヤ人への変身のように、一気に状態を変える
複数のフィールド値を一度に設定
### バリデーション関連（戦闘技術）
#### validate
修行のように、技が正しく使えているか確認する
フォーム全体のバリデーションを実行
#### validateField
個別の技の練習のように、特定のフィールドだけバリデーション
#### setTouched
気を感じ取るように、フィールドに触れたことを記録
フィールドが編集されたことをマーク
###その他の状態管理（戦闘状態）
#### resetForm
全ての技をリセットして初期状態に戻る
フォーム全体を初期状態にリセット
#### resetField
特定の技だけやり直す
特定のフィールドだけリセット

このように、vee-validateのフォーム管理は、まるで戦闘技術を磨きながら戦っていくようなものです。各機能が協力し合って、最終的に完璧なフォーム（戦い）を実現します！

## Q.resetFormには値を入れることができますか？
はい、resetFormには新しい初期値を渡すことができます！
```ts
const { resetForm } = useForm({
  initialValues: {
    powerLevel: 9000,
    technique: 'かめはめ波'
  }
});

// 新しい値でリセットする
resetForm({
  values: {
    powerLevel: 15000,
    technique: '界王拳'
  }
});
```
ドラゴンボールで例えると、これは「いったん戦闘力をリセットしつつ、新しい技や強さの状態からやり直す」というイメージです。
resetFormには以下のようなオプションを渡せます：

1.values - 新しい初期値
2.touched - タッチ状態（フィールドに触れたかどうか）
3.errors - エラー状態
4.submitCount - 送信回数

全てのオプションは任意で、指定しなかった項目は完全にリセットされます。例えば：

```ts
// エラーだけを残して他をリセット
resetForm({
  errors: {
    powerLevel: '戦闘力が足りません'
  }
});

// 値と触れた状態を新しく設定
resetForm({
  values: {
    powerLevel: 20000
  },
  touched: {
    powerLevel: true
  }
});
```

## 結果
公式ドキュメントを読むよりわかりやすくVeeValidateについて把握できた。
🦙 Unslothで作成したLLaMA 3.2ベースのファインチューニングモデルを使った高速推論ガイド（GoogleColab📒ノートブック付）

## 📦 必要なライブラリのインストール

```python
%%capture
!pip install unsloth
# 最新のUnslothナイトリービルドを取得
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
```

**解説**:
Unslothライブラリをインストールします。このライブラリを使用することで、LLaMAモデルのファインチューニングと推論を大幅に高速化できます。ナイトリービルドを使用することで、最新の機能と改善が利用可能です。

## 🔧 ライブラリのインポートと基本設定

```python
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from unsloth import FastLanguageModel
from unsloth.chat_templates import get_chat_template
import torch

# モデルの基本設定
max_seq_length = 512
dtype = None
load_in_4bit = True
model_id = "path/to/your/finetuned-llama-3.2"  # ファインチューニング済みのモデルパス
```

**解説**:
- 必要なライブラリをインポート
- モデルは4ビット量子化を使用して、メモリ効率を改善
- `model_id`には、Unslothでファインチューニングしたモデルのパスを指定

## 🚀 モデルとトークナイザーの初期化

```python
# モデルとトークナイザーのロード
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name=model_id,
    dtype=dtype,
    load_in_4bit=load_in_4bit,
    trust_remote_code=True,
)

# LLaMA 3.1のチャットテンプレートを使用
tokenizer = get_chat_template(
    tokenizer,
    chat_template="llama-3.1",  # LLaMA 3.1のテンプレートで問題なし
)

# 高速推論モードを有効化
FastLanguageModel.for_inference(model)  # 通常の2倍の速度
```

**解説**:
1. ファインチューニング済みのモデルをロード
2. LLaMA 3.1のチャットテンプレートを適用（3.2でも互換性あり）
3. Unslothの高速推論モードを有効化

## 💬 データセットを使用した推論の実装

```python
def generate_response(dataset_entry):
    """
    データセットのエントリーに対して応答を生成する関数
    """
    # メッセージの作成
    messages = [
        {"role": "user", "content": dataset_entry["conversations"][0]['content']},
    ]
    
    # チャットテンプレートの適用
    inputs = tokenizer.apply_chat_template(
        messages,
        tokenize=True,
        add_generation_prompt=True,  # 生成プロンプトの追加
        return_tensors="pt",
    ).to(model.device)
    
    # 応答の生成
    outputs = model.generate(
        input_ids=inputs,
        max_new_tokens=64,  # 生成するトークン数
        use_cache=True,     # キャッシュを使用して高速化
        temperature=1.5,    # より創造的な応答を生成
        min_p=0.1          # 出力の多様性を確保
    )
    
    return tokenizer.batch_decode(outputs)
```

**解説**:
この関数は：
1. データセットのエントリーからユーザーの入力を抽出
2. LLaMA 3.1形式のチャットテンプレートを適用
3. 以下のパラメータで応答を生成：
   - `max_new_tokens`: 64（短めの応答を生成）
   - `temperature`: 1.5（創造性を高める）
   - `min_p`: 0.1（多様な応答を確保）

## ✅ 実行例

```python
if __name__ == "__main__":
    # テストデータセット
    dataset = [
        {"conversations": [{"content": "量子コンピュータについて簡単に説明してください。"}]},
        {"conversations": [{"content": "機械学習の基本的な概念を教えてください。"}]},
        {"conversations": [{"content": "プログラミング初心者へのアドバイスをお願いします。"}]}
    ]
    
    # 2番目のデータセットエントリーで試してみる
    response = generate_response(dataset[2])
    
    print("入力:", dataset[2]["conversations"][0]['content'])
    print("応答:", response)
```

**解説**:
サンプルの実行方法を示しています：
- テスト用のデータセットを定義
- 選択したエントリーで応答を生成
- 入力と生成された応答を表示

このコードを使用することで、UnslothでファインチューニングしたカスタムのデータセットでトレーニングしたLLaMA 3.2モデルを、高速に推論できます。LLaMA 3.1のトークナイザーを使用することで、新しいモデルでも安定した出力が得られます。必要に応じて生成パラメータを調整することで、モデルの応答特性をカスタマイズできます。

## Google Colab📒ノートブック

https://colab.research.google.com/drive/1FkAYiX2fbGPTRUopYw39Qt5UE2tWJRpa?usp=sharing
パーソナルワンをもとにサプリを摂ってたら生産性が向上した話（おそらく）

エンジニアにとっても健康維持は大切ですよね。
特に熱が入って我を忘れると、作業以外に目がいかなくなりがちです。:fire:

健康と持続的な開発のため、栄養バランスについて考えていました。
しかし、自分に何の栄養素が足りないのかわからず、どうしたものかとインターネットを彷徨っていました。
そこで出会ったのがファンケルさんの「パーソナルワン」です。（回し者ではありません）

# パーソナルワンとは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641121/9cc41e91-7ffc-5a0f-fa46-9b6b5e113840.png)
（引用元：[Personal ONE](https://www.fancl.co.jp/healthy/personalone/index.html "Personal ONE")）

パーソナルワンは、尿検査とアンケートをもとに健康状態を分析してくれるサービスです。
測定後には最適なサプリメントも案内してくれます。

# やったこと
**1. パーソナルワンで自分の栄養バランスを測定する
2. 結果をもとに足りない栄養素のサプリメントを飲む（記事投稿時で半年くらい）**

# 結果
1と2は明確でした。
特に2は半年で1回もできず、正直ここまで改善すると思わなかったので、驚きました。
焦って頬を噛んだときも治りがはやくなりました。

**1. 顔色が良くなった（と周囲の方から言われた）
2. 口内炎ができなくなった
3. 身体がシャキッとする（かも）
4. お肌がきれいになりつつある**

また、なんとなくだるいというのも減った気がします。
（気のもちようと言われればそれまでですが）

# 費用
結果が出たあとにサプリメントを購入する場合は測定が実質無料です。
測定料分のクーポンをもらえて、サプリメントの購入に使えます。

サプリメントを購入しない場合は5,500円のキット代がかかります。（投稿時の価格）

# 詳細
### 1. パーソナルワンで自分の健康状態（栄養バランス）を測定する
ファンケルさんのサイトから検査キットを申し込みます。
その際、食事やその他生活全般についてのアンケートに答えます。
これは10-20分くらいだったと思います。

1-2日後に検査キットが届いたら、尿を採取して返送します。

### 2. 結果をもとに足りない栄養素のサプリメントを飲む
約1週間後から結果を専用サイトで確認できます。

参考までに、私の結果は以下な感じです。
ビタミンA, C, Dが普通に不足していて、DHAが絶望です:innocent:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641121/65e2d9f7-6ef7-057a-a893-e72737d16239.png)

さらに下にいくと、必要なサプリメントを提案してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641121/0cf45600-e6a4-79d9-a63b-5712ce827dc7.png)

ここで出たサプリメントを定期購入して、毎日飲むという流れになります。
サプリメントはオーダーメイド生産しているため、少しお高めです。
とりあえず測定して、サプリメントはドラッグストアとかで買うのもありです。

また、購入するサプリは選択できますので、「微量不足している栄養素は食事で頑張って、絶望的なものだけ飲むようにする」というのもありです。

私はビタミンA, C, DとDHAをAmazonで購入して飲んでいて、残りのちょっと不足気味なものは食事で頑張っています。

# 感想
個人差があるのは言うまでもないです。
しかし、明確な結果が出たのは嬉しかったので共有しました。

結果自体は細かなことが多いですが、そういうことの改善が生産性向上につながるかなと思います。

サプリメントに関しては、あるお医者さんが「実際に食事で摂ることで、口で咀嚼して唾液が出て、その刺激が脳に行き、消化器でも消化酵素が出て…」という風に仰っていました。

そういった過程の中に未知のプラスな要素がたくさんありうるのです。
サプリメントはそういう過程をすべて省くので、本当は食事で摂りきるのが最も良いのは確かかと思います。

しかし、現代社会でそれはとても難しいものです。
私自身もバランスを考えて、食事やサプリメントとうまく付き合っていきます。

最後まで読んでいただき、ありがとうございます。
[Babylon.js] 読み込んだGLBの移動、拡大縮小、回転について

## はじめに
`ImportMeshAsync`で読み込んだGLBの、特にマイナス方向の拡大縮小について少しつまずいたので共有します。
ちなみに`ImportMesh`ではなく`ImportMeshAsync`を使いましょう。

https://doc.babylonjs.com/typedoc/classes/BABYLON.SceneLoader#ImportMeshAsync

## つまずき
GLBの3Dオブジェクトを左右反転したく、全ての3Dオブジェクトに対して`scaling.x = -1`としたが変化がなかった。（前提として3Dオブジェクトの原点は(0,0,0)）

ここで注意すべきは、GLBの読み込み時に**親オブジェクトである__root__が作成され、その中に3Dオブジェクトが内包されるという仕様**だ。

そしてGLBの全てのオブジェクトに対して変形を行うと、`__root__`、`__root__直下の3Dオブジェクト`それぞれに対し適用されてしまい、結果として**2回スケールマイナス1されて打ち消され**効果が成さなかった。

今回は全ての3Dオブジェクトを反転させたいため、**__root__のみマイナス1すれば良い。**

言われたら簡単なことだが、簡単すぎて気付くのに結構時間かかったし、何なら諦めて反転させてからGLB出力してた。。。
ぼーっとInspector眺めてたらふと気付いた感じ。
プラスのスケールや移動、回転では二重に適用されているものの一応思っている結果が得られている点も気付きにくいポイントである。


## 改善した書き方
```javascript:JavaScript 
BABYLON.SceneLoader.ImportMeshAsync("", "", "model.glb", scene).then(({ result }) => {
    // このGLBの__root__を取得
    const rootNode = result.find(({ name }) => name === "__root__");
    if (!rootNode) {
        console.warn("'__root__'を取得できませんでした。");
        return;
    }
    
    // __root__のみを変形
    rootNode.position.set(0, 0, 0);
    rootNode.rotation.set(0, 0, 0);
    rootNode.scaling.set(1, 1, 1);
});
```


## 余談
[ラティス変形](https://help.autodesk.com/view/MAYAUL/2024/JPN/?guid=GUID-334813CE-30E5-43CB-B032-CF8FE1ED96F7 "Mayaのラティス変形のドキュメント")ができるらしい。試してみようと思う。
WebGLでこんな事もできるの！と毎回驚かされる。

https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/lattice/
新卒が質問する際に意識していること

# 質問するための準備
新卒にとって仕事はわからないことだらけです。特に最初は新卒にとって、質問すること自体ハードルが高いです。
先輩社員から「わからないならどんどん質問してほしい」と言われることは非常にありがたいです。ただ、何もまとまっていない状態で質問に行ったところで先輩社員の方からしたら、
　・何が聞きたいのかわからない
　・解決するために何をしたのかわからない
　・話が長すぎて覚えられない
などと感じるでしょう。もはや、質問自体を一緒に考える始末です。
互いにとって有益な時間にするため、私が質問するための準備として最低限していることを紹介します。

## フォーマットに沿って考えをとにかく書き出す
わからない、困っている状況にある際には、まずは現状を考えていることを以下に沿って、思いつく限り書き出します。

【質問内容】相手に質問したいこと、疑問
【質問の背景】なぜその疑問に至ったのか、その内容を質問したいと思ったのか
【理想の状態】何がわかったらその疑問クリアになるのか、クリアになってどう次の作業につなげたいのか
【自分が調べたこと・試したこと】現状の自分でどこまで何を調べたのか、どんな試しを行ってみたのか
【自分の考え・仮説】調べた/試した上で自分が思いつく解決策、どこがわかれば今の疑問も解消されそうなのか

これらの内容を書き出すことで、
　・本当に質問したい内容が見えてくる
　・自分で何ができる、何を調べてみればいいのかがわかる
　・質問する際に話がまとまっているため、話しながら考える無駄が省かれる

 書き出すことで「本当に聞きたいことは何か」が少しでも明確になったうえ、質問する際も順序立てて伝えることができるでしょう。
 
## 「YES / NO」で答えられるような質問をする
新卒からしたら先輩社員は何でも知っているように感じます。
しかし、自分が取り組んでいる業務は自分の業務であって、相手の業務ではありません。なので、相手が答えを知っているわけでもなければ、全部教えてもらったらそれはもはや自分の仕事ではなくなります。

なので質問する際には、
　・自分の仮説の中で考慮できていない部分はあるか
　・この方針で進めようとしているがいいと思うか
　・この方法で調べた/試したが他に方法はあるか

いきなりオープンクエスチョンが飛んでくるより、YesかNoで答えるほうが相手としても回答しやすいと思います。
自分の考えが相手に伝われば、相手も伝えるべき事柄がわかりやすくなるでしょう。

## 15～25分調べて/試して/考えて、それでもわからなければ質問する
質問するためにも正直時間はかかります。
最初は「質問するためにこんなに時間をかけて意味があるのか」とも思います。
ですが、自分の頭で考えることによって、自身の力もついていきます。時間はかかってもまずは自分で考える習慣を持つ必要があります。

そうはいっても、1時間もかけていてはさすがに相手も「それならもっと早くに相談してよ」と思うでしょう。
（最初は質問の準備をしていて、気づいたら1時間くらいかかっていました…）

よく聞く話では「15分かけてわからなければ質問する」というものがあるでしょうが、今の自分では考えを書き出して、調べる手段を洗い出して調べていたら15分なんて一瞬です。
なので、どれくらいやるかは多少人にもよるとは思いますが、私は早くても15分、遅くても25分ほど自分でできることをやってから質問しているようにしています。

## さいごに
質問することは簡単なことではありませんが、仕事をするうえでは必要です。
自分と質問をする相手、互いにとって有益な時間にするためにも、まずは今のうちから準備を心がけています。

質問の仕方もまだまだ改善すべきところはあるので、よりよい質問ができるよう試行錯誤していきます。
Rspecでresponse.bodyがない

# はじめに

地味にハマってしまい、情報がなかったのでまとめます

# 問題

Rspecを書いたのですが、なぜかresponse.bodyでエラーが出ました

```rb
        
        get :index, format: :json
        res      = JSON.parse(response.body)
```

```
     Failure/Error: response      = JSON.parse(response.body)
     
     NoMethodError:
       undefined method `body' for nil:NilClass
```

# 解決方法

responseにJSON.parse(response.body) のような未定義の変数に再代入するような形になっていたのが原因だった

```rb
        
        get :index, format: :json
        res      = JSON.parse(response.body)
```

responseをresに変えたらかいけつした

# おわりに

これもやりがちな感じがするけどあまりネットにはありませんでした
ZED2iとRealSense D435との仕様上の比較


## 解像度
#### [ZED2i](https://www.stereolabs.com/en-jp/store/products/zed-2i)

2K at 15 FPS with Output resolution side-by-side of 2x(2208x1242)
1080p at 30 or 15 FPS with Output resolution side-by-side of 2x(1920x1080)
720p at 60, 30 or 15 FPS with Output resolution side-by-side of 2x(1280x720)
376p at 100, 60, 30 or 15 FPS with Output resolution side-by-side of 2x(672x376)

#### RealSense [D435](https://www.intel.co.jp/content/www/jp/ja/products/sku/128255/intel-realsense-depth-camera-d435/specifications.html)
Depth 解像度と FPS　1280 X 720


### ReasSense [D455](https://www.intel.co.jp/content/www/jp/ja/products/sku/205847/intel-realsense-depth-camera-d455/specifications.html)

Depth 解像度と FPS: 1280x720 upto 90FPS

## 視野角
#### ZED2i
Field of View
110°(H) x 70°(V) x 120°(D) max. (for 2.1mm)
72°(H) x 44°(V) x 81°(D) max. (for 4mm)
#### D435
Depth 視野85.2 x 58
#### D455
Depth 視野86x57

## 基線長
#### ZED2i
Baseline 120 mm (4.72’’)
#### RealSense D435 （注：コメントを参照）
50mm

#### RealSense D455
95mm

## Depthの範囲
#### ZED2i
Depth Range Max
0.3m to 20m (1ft to 65ft) with 2.1 mm lens
1.5m to 35m (4.9ft to 114.8ft) with 4 mm lens
Ideal Range
0.3m to 12m (1ft to 39ft) with 2.1 mm lens
1.5m to 20m (5ft to 65ft) with 4 mm lens


#### D435
動作範囲 (最小 - 最大): ~.3m - 3m

#### D455
動作範囲 (最小 - 最大): .6m-6m

## マシンビジョン用のカメラとしてみたときの私見(ZED2i と D435の場合の比較）
この文章でのマシンビジョンとは、工場など所定の場所に取り付けられていて、制御された環境での画像計測や画像認識をとを想定しています。ヒューマノイドロボットは想定に含まれていません。
#### 作業距離が3 m 以遠:
この作業距離では、ZED2iだけ。　D435はサポートしていない。
#### 作業距離が0.3 m ~ 3 mの範囲:
この作業距離ならば両方とも候補になる。
- 算出した点の安定性を重視するならば、active stereoであるRealSense D435が優れる（はず）。
- 作業距離が0.3 m ~ 3 mの範囲での、計測点の密度についていうと、ZED2iの方が上回る。
- depth画像での画素とRGB画像での画素の対応付けを優先するならば、ZED2i がよい。どちらもステレオカメラで算出しているため。

#### 作業距離が1.5 m ~ 3 mの範囲:
この作業距離ならば両方とも候補になる。
ZED2iでは以下の焦点距離のものがおすすめになる。
1.5m to 35m (4.9ft to 114.8ft) with 4 mm lens
72°(H) x 44°(V) x 81°(D) max. (for 4mm)
視野角が狭くなるぶん、作業距離上での点の密度が向上する。
- 算出した点の安定性を重視するならば、active stereoであるRealSense D435が優れる（はず）だが、撮影条件の改善などで、ZED2iの動作を安定させるのがいいだろう。
- ZED2iでは、ステレオ平行化済みの左右の画像を取得できるので、ZED-SDKに用意されていないステレオマッチングアルゴリズムを利用するようにプログラムを書くことも可能だ。

## より本格的な計測をめざしている場合には
#### 寸法の精度を上げたい場合
- 工場での利用を目的とした産業用の3Dカメラを利用することです。
基線長がZED2iよりも長いカメラで、カメラの画素数が大きく、視野角も狭いものだと、
　寸法を計測する精度を上げることが可能になりやすいです。
#### 計測のフレームレートを上げたい場合
- 産業用のカメラだと高いフレームレートを実現するものもあります。

#### より本格的な計測をめざす場合でも
- 10万円以下の金額で購入できる3Dカメラは、試してみる価値があります。
- RealSenseやZED2iで試してみて、目的を達成できるならばそれでいい。
- 試してみて、どこに課題があるのかが見えてくれば、どういう仕様のカメラを購入するのがよいのかが見えてきます。
- 本格的な計測のためのカメラを、目的が達成できるものを、オーバースペックにならないように購入するのは簡単ではありません。

----
## 実験に基づく比較レポート
[Depth Accuracy Comparison: Luxonis OAK vs StereoLab™ ZED vs Intel® RealSense™](https://discuss.luxonis.com/blog/3734-depth-accuracy-comparison-luxonis-oak-vs-stereolab-zed-vs-intel-realsense)

![by_luxonis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/566fc55f-4e75-bd01-eb81-c9c305b8ebcd.png)

この表でのZED2i は広角になる設定の焦点距離のカメラの場合です。

<7m, <10m は、仕様に示しているOperating Range (Min-Max)~.3m - 3m　よりも遠方であることに考えると、RealSenseも頑張っているといえるだろう。
ASTERIA Warpで何ができる？機能概要のご紹介

こんにちは、[SCSK株式会社](https://www.scsk.jp/product/common/asteria/)です！

前回はEAIとASTERIA Warpの特長についてお話しましたが、今回はその続きをお届けします！
ASTERIA Warpを利用すると、専門スキルがなくてもデータ連携や業務自動化が簡単に実現できます。今回は、「<font color="red">ASTERIA Warpでできること</font>」をいくつかご紹介します。

https://www.scsk.jp/product/common/asteria/

# ASTERIAでできること

### システム間連携
ASTERIAは、<font color="Blue">様々なシステムとシームレスにデータを連携</font>できます。例えば、一定の時間間隔でデータベースの顧客情報を取得・加工し、それをSalesforceなどのSaaSにRestAPIで連携する処理をリアルタイムで実現可能です。
データの流れの一元管理により新しいシステム導入や変更にも柔軟に対応することができるため、お客様のビジネスにおける製品・サービス品質の向上や業務効率化を実現できます。

![ASTERIA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919043/17e383e7-3f79-460d-556a-7ce518577b6a.png)


### ファイル入出力
Excel、CSV、TEXTなど<font color="Blue">様々な形式のファイル</font>に対してデータ入出力が可能です。例えば、データベースから取得した受発注データをExcelに出力して帳票を作成することや、CSVで受け取ったデータを会計システムに取り込むことができます。
様々なファイル形式を扱えることにより連携元/連携先システムのフォーマット差異を吸収することができるため、システムに改修を加えずにデータ連携を実現することが可能となります。

![ファイル入出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919043/6253fe8f-87c5-d57f-f17d-d5443f7f0687.png)


### データ加工
連携先の仕様に合わせた<font color="Blue">データ加工</font>も簡単なGUI操作で可能です。例えば、文字列フォーマットの変更や演算結果の出力、レコードの結合など、視覚的に分かりやすいアイコンを使って実装できます。

![データ加工.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919043/7c62d47b-b979-8b68-98b5-0ec5a7a55b0e.png)


### メール送受信
ASTERIAでは<font color="Blue">メールの送受信や添付ファイル処理</font>も行えます。例えば、作成したファイルを添付してメール送信したり、メールの添付ファイルを取得・データ加工して共有フォルダにアップロードするような定型業務を自動化できます。また、処理の正常終了時やエラー時にメールで通知するような、処理監視機能を実装することも可能です。
メールを自動送付することで業務効率化を図るとともに、ヒューマンエラーの防止、軽減に寄与できます。


### トリガー（実行設定）
ASTERIAのフローは開発画面などから直接実行することもできますが、予め設定しておいたトリガーで実行することも可能です。<font color="Blue">トリガー実行</font>とは、特定の条件やイベントが発生した際に、自動的に処理やスクリプトを実行する仕組みのことです。
指定日時での<font color="Blue">スケージュール実行</font>のほかに、<font color="Blue">繰り返し実行</font>、<font color="Blue">メール受信でフローを起動するメールトリガー実行</font>、<font color="Blue">HTTPリクエストでフローを起動するURLトリガー実行</font>など多種多様なトリガーが用意されています。もちろん、バッチファイル等での実行も可能ですので、JP1などのシステム運用管理ツールなどと組み合わせて使用することもできます。
URLトリガーやメールトリガーを利用することでリアルタイム連携が可能となるため、連携されるデータの鮮度が上がり、ビジネススピードや意思決定が高速化されます。

![トリガー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919043/7a5ef7c7-fd8f-a765-8570-b53521dd75a0.png)

# おわりに
今回はASTERIA Warpでできることを紹介しました。これらの機能を活用することで定型業務を自動化し業務効率化につなげることが可能となります。
次回以降はASTERIAの便利機能をさらに深掘りしてご紹介させていただきます。

※ASTERIAのエディションによっては機能制限がございますので、詳細はお問い合わせください。


最後までご覧いただきありがとうございました！

<font color="Blue">※SCSK株式会社はASTERIA Warpのマスターパートナーです。15年以上の販売実績および、様々な業種・業務での構築ノウハウによりお客様をサポート致します。
※SCSK株式会社では、EAIの導入支援や最適なソリューションの提供を通じて、企業のIT環境をサポートいたします。EAIに関するご相談や詳細については、ぜひお気軽にお問い合わせください。</font>

https://www.scsk.jp/product/common/asteria/
【競技プログラミング】AtCoder Beginner Contest 295_D問題

# 問題
https://atcoder.jp/contests/abc295/tasks/abc295_d

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)



# アプローチ
各数字を2のべき乗に対応させ、累積XORを計算することで、部分文字列が嬉しい列かどうかを判定できる。
・任意の数Aに対して、A XOR A = 0となる性質
・0 XOR A = Aとなる性質
を活用する。


# 解法手順

1. 入力文字列Sを数字のリストに変換する。

2. 長さNを取得する。

3. defaultdictを使用して、XOR和の出現回数を記録する辞書Dを初期化する。

4. フラグ変数flagを0で初期化し、D[0]を1に設定する。

5. 文字列Sを先頭から順に走査し、以下の操作を行う：
   - 現在の数字nを整数に変換する。
   - flagをn番目のビットでXOR演算する（flag ^= 2**n）。
   - 新しいflagの値をDに記録する（出現回数を1増やす）。

6. 辞書Dの各値vに対して、v * (v-1) // 2 を計算し、その合計を答えとする。

7. 最終的な答えを出力する。


# ACコード
```python:ac.py
from collections import defaultdict

def solve(S):
    # 2. 長さNを取得する
    N = len(S)

    # 3. defaultdictを使用して、XOR和の出現回数を記録する辞書Dを初期化する
    D = defaultdict(int)

    # 4. フラグ変数flagを0で初期化し、D[0]を1に設定する
    flag = 0
    D[0] = 1

    # 5. 文字列Sを先頭から順に走査し、XOR和を計算する
    for n in S:
        # 現在の数字nを整数に変換する
        n = int(n)
        # flagをn番目のビットでXOR演算する
        flag ^= 2**n
        # 新しいflagの値をDに記録する（出現回数を1増やす）
        D[flag] += 1

    # 6. 辞書Dの各値vに対して、v * (v-1) // 2 を計算し、その合計を答えとする
    answer = 0
    for v in D.values():
        answer += v * (v - 1) // 2

    # 7. 最終的な答えを出力する
    print(answer)

if __name__=="__main__":
    # 1. 入力文字列Sを受け取る
    S = input().strip()
    solve(S)



```

# おまけ(パターン箇所の表示)

問題では、組数しか問われていないけど、パターン発生箇所とパターン文字列も摘出しておきたい。
動的計画法とか、仕事で使うことはたまにある(というより、競プロで身につけたスキルだから使う場面を狙ってる)けど、結果より復元の方が大事なことが多いんですよね。

```python:ac.py
from collections import defaultdict

def solve(S):
    # 2. 長さNを取得する
    N = len(S)

    # 3. defaultdictを使用して、XOR和の出現回数を記録する辞書Dを初期化する
    D = defaultdict(int)

    # 4. フラグ変数flagを0で初期化し、D[0]を1に設定する
    flag = 0
    D[0] = 1

    # ※ XOR和の値とその位置を記録する辞書
    positions = defaultdict(list)  
    positions[0].append(-1)  # 初期位置を-1とする
    patterns = []  # パターンの開始位置と終了位置を記録するリスト

    # 5. 文字列Sを先頭から順に走査し、XOR和を計算する
    # ※ 復元のためにindexを追加
    for i, n in enumerate(S):
        # 現在の数字nを整数に変換する
        n = int(n)
        # flagをn番目のビットでXOR演算する
        flag ^= 2**n
        
        # パターンの開始位置と終了位置を記録
        if flag in positions:
            for start in positions[flag]:
                patterns.append((start + 1, i))  
        positions[flag].append(i)
        
        # 新しいflagの値をDに記録する（出現回数を1増やす）
        D[flag] += 1

    answer = sum(v * (v - 1) // 2 for v in D.values())
    print(f"繰り返しパターンの総数: {answer}")

    print("繰り返しパターンの位置:")
    for start, end in patterns:
        print(f"開始位置: {start}, 終了位置: {end}, パターン: {S[start:end+1]}")

if __name__=="__main__":
    S = input().strip()
    solve(S)


```
LeetCodeを1日1題解いてみる (day28)

28日目に取り組んだ問題はこちら！

# 125. Valid Palindrome

https://leetcode.com/problems/valid-palindrome/description/

## 問題文
A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

## 僕の回答
```py
class Solution:
    def isPalindrome(self, s: str) -> bool:
        clean_s = ''.join(char for char in s if char.isalnum())
        clean_s = clean_s.lower()
        reversed_s = ''.join(list(reversed(clean_s)))
        return reversed_s == clean_s
```

## より効率の良い回答例

```py
class Solution:
    def isPalindrome(self, s: str) -> bool:
        s = "".join(filter(str.isalnum, s.lower()))
        return s == s[::-1]
```

## コメント
- `char.isalnum()`で`char`がアルファベット又は数字のみで構成されているかを確認する。
(`isalpha`はアルファベットかどうか。`isdigit`は数字かどうか。)
- `lower()`で大文字を小文字に変える。(`upper`で大文字に変える)
- `''.join(list)`で配列を一つの文字列にする。
- `str1 == str2`で２つの文字列を比較する。
- `filter(func, iterable)` `filter` 関数は、指定された func を適用して True を返す要素だけを iterable から取り出す。
今回の問題で文字列操作について多くを学べました。

## 次の問題はこちら!
https://qiita.com/h_y_s_d/items/6ffd533fcb6eeef98e29
会社員としての働き方

# 前提
今もらっている給料分は、仕事で価値を出し続けるし、それを信じてもらう(信じてもらえるような振る舞いをする(報連相をしっかり行う。timesにやっていることを書いたり、週次のMTGで共有したりする。))。

仕事をすることが、自分の目標達成のための手段となっている。

評価者(マネージャー)には私を信じて任せてもらう。時間の使い方も完全に任せてもらう。

# Goal
理想の金額まで昇給する。

# How
理想の収入を得るために、目前のタスクに対してどれくらいの期待値を満たせばいいのかを、各タスクに対してマネージャーに定義してもらう(Q, C, D)。

それを満たすために自由かつ自律的に仕事をする。

タスク完了後に評価してもらう。

魅力的に感じない仕事は可能な限り他の人に任せてもらう。

# 具体的な仕組みづくり
タスクごとに期待値の条件を聞いて、タスクボード等にメモしておく。

後で評価できるように、Timesに何をどれだけやったかを毎日残しておく。

タスク完了時に、QCDを評価してもらう。
RailsでCurlをするとパラメーターが最初しか取れない

# はじめに

RailsでAPIを叩いたときにパラメータの挙動がおかしかったのでまとめます

# 問題

以下のエンドポイントを作成しました
ここではリミットとキーワードをパラメータから受け取ります

```rb
  def index
    limit    = params.fetch(:limit, 50)
    keyword = param.fetch(:keyword)
    # 中身を表示する
    p params
    return render json: { message: "hello" }, status: :ok
  end
```

しかしCurlを叩くと`params`には`keyword`しかありませんでした。

```
$ curl localhost:3000?keyword=hoge&limit=1
```

```
{"keyword"=>"test", "controller"=>"/", "action"=>"index"}
```

curlのクエリの順序を変えたところ最初のクエリのみを受け取っていました

```
$ curl localhost:3000?limit=1&keyword=hoge
```

```
{"limit"=>1, "controller"=>"/", "action"=>"index"}
```

# 解決方法

curlを以下にしたら治りました

```
$ curl "localhost:3000?keyword=hoge&limit=1"
```

# おわりに

あまりcurlでクエリつけたものを叩いたことなかったので時間がかかりました
ネットに同じ症状の人がいなかった
macOS Sequoia 15.1 からパスが通らなくて Permission denied になったときの解消手順

# これなに

macOS Sequoia 15.1 にバージョンアップした時に ssh が通らなくなったのでその解消を行った時の手順を記録しました


# 遭遇した事象

いつも通り踏み台に ssh しようと思ったら以下のようなメッセージが出た

```zsh
% ssh test-bastion
Warning: Permanently added '[nlb0.bastion.test.bastion.com]:1030' (ED25519) to the list of known hosts.
Load key "/Users/su3-hokkaido/.ssh/keypair": Permission denied
su3-hokkaido@nlb0.bastion.test.bastion.com: Permission denied (publickey).
% 
```


# 直接原因

対象のファイルにアクセスするための権限がなかった


# 解消方法

Read & write 権限を付与することで解消

```zsh
chmod 600 ~/.ssh/keypair
```

所有者が現在のユーザーではないケースもあるので、これもじっこうしておくとべたー

```
sudo chown $(whoami) ~/.ssh/known_hosts
```


# 補足

- `chmod 600`:
    - 所有者に read & write の権限を付与
    - グループや他のユーザーには一切の権限を付与しない
- `chmod 644`:
    - 所有者に read & write の権限を付与
    - グループや他のユーザーには read 権限を付与する


# あとがき

- OS アップデートしたら発生した事象ですが、根本原因は調べていないのでよくわかりません（ごめんなさい）
- たぶん同様の事象に出会っている人がいるっぽいので、[StackOverflow](https://stackoverflow.com/questions/79213830/how-do-i-get-the-issue-permission-denied-fixed-on-macos-sequoia-15-1
) とか [Reddit](https://www.reddit.com/r/LibreWolf/comments/1gei8ys/cannot_open_librewolf_after_the_latest_macos_151/?rdt=36097) にも質問が挙がっていた模様

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/d4ad3454-4364-9a16-36f8-e9d50401d518.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/6ec57675-681e-6106-5ee5-6fd50cf51067.png)
【AWS】EFSマルウェアスキャンの定期実行（ECS Fargate＋ClamAV）

# はじめに
AWSマネージドサービスのNFSサーバーである **`EFS`** に対してECS Fargate＋ClamAVでマルウェアスキャンを定期実行する方法を共有します。

要件として「マルウェア対策を導入すること」というのがよくあります。EFSを使っているケースで、安価にマルウェア対策したい場合の参考になれば幸いです。


# 概要
現時点でAWSによるEFSのマルウェア対策の機能は提供されていません。
- サードパーティー製品の導入などのコストをかけたくない
→ OSSのClamAVとサーバーレスのコンテナで定期スキャンしよう！

## 想定ケース
Webシステムでアップロードされたファイルの保存先としてEFSを使用

## 要件
- EFS上のファイルを定期スキャンしたい（週1回、フルスキャンなど）
- 安価に対応したい。過剰な対策コストはかけられない

## 対応検討
- 万一、EFSにマルウェアが保存されても、それだけでは悪用されないと割り切る
- エンドポイント側とサーバー側で責任共有／分担する
- **サーバー側では定期的なフルスキャンのみ対応する**
    - エンドポイント側でリアルタイムスキャンできなかった未知のマルウェアは、サーバー保存時のスキャンでも対応できない可能性が高い
    - サーバー側では定期的にフルスキャンすることでカバーする。（時間が経ち、未知→既知になれば対応できる）


# 具体策
- 安価に対応したいため、OSSの **`ClamAV`** を使用する
- docker版があるため、サーバーレスのコンテナで動かす
    - 制限の少ない ECS Fargate を選択
    - ECSタスク定義で、EFSマウントを設定
- コンテナでウイルスデータベース更新(`freshclam`)とスキャン(`clamscan`)を実行する
- 定期実行するため、ECSタスクスケジューリングを使用

## ClamAVについて
オープンソース(GPLv2)のウイルス対策ツールキット。Cisco Systems, Incによって提供されている。
- [**`ClamAV`**](https://www.clamav.net/)
https://www.clamav.net/

- [**`Docker Hub - clamav/clamav`**](https://hub.docker.com/r/clamav/clamav) (公式イメージ)
https://hub.docker.com/r/clamav/clamav

## 構成要素
- EFS
- ECS Fargate＋タスクスケジューリング
- ClamAV（Docker Hub / clamav/clamav:1.2)

## 構成図
![aws-ecs-efs-scan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/5c63b7b6-280a-ec7f-29a5-9465a17056e6.png)

## ClamAVコンテナの用意

- Dockerfile
    ```
    FROM clamav/clamav:1.2
    COPY scan.sh /
    RUN chmod +x /scan.sh
    RUN mkdir -p /data
    CMD /scan.sh
    ```
- scan.sh
    ```
    #!/bin/sh
    freshclam
    clamscan -v -r /data
    ```
- 参考：docker-compose.yml (ローカル検証用）
    ```
    services:
      clamav:
        build: .
    ```
## AWS設定
手順（詳細は省略）
- 前提：EFS 作成、アクセスポイント設定済み
- CodeCommit リポジトリ作成 (Git)
- ECR リポジトリ作成 (コンテナイメージ管理)
- ECS タスク定義作成
- ECS タスクスケジューリング設定


## 留意事項
- メモリは2GB以上必須
    - 1GBメモリでは clamscanの実行中に `Killed` で停止した
    - AWS Cloud9の場合、t3.small (1GBメモリ) ではハングアップ状態になった。t3.mediumで動くことを確認
エージェントモードが追加された Cursor v0.43アップデートまとめ

## 概要
Cursorの大型アップデートとなるv0.43がリリースされました。新しいComposer UI、AIエージェント機能、コンテキスト推奨システムなど、大幅な機能追加と改善が行われています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019/46419d6b-e03f-76bc-91e5-1929826385d1.png)

## 主な変更点

### 1. 新しいComposer UI
- サイドバーに差分表示機能を搭載
- ChatとComposerの履歴参照UIが統一
- ファイル編集履歴の保存・復元機能を追加

### 2. AIエージェントモード
- normalとagentを選択可能に
- コンテキストの自動選択
- ターミナル操作機能

### 3. インテリジェント推奨機能
- `@Recommended`による関連ファイルの自動提案
- チャット/Composer内でのファイル推奨

### 4. その他の改善
- 画像ドロップ操作の改善
- 複数のパフォーマンス最適化
- バグ検出機能のベータ版プレビュー

## スクリーンショット

### 新しいエージェントモードUI

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019/a6fc139a-611f-b003-d871-bdc210a2219f.png)

### `@Recommended`機能
`@Recommended`を選択すると、自動で関連しそうなコンテキストを提案してくてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019/42d0bf2f-f9f0-4904-a14a-4951334d23bb.png)

### 統一された履歴UI
- ChatとComposerの履歴を探すUIが同じになりました。ChatとComposerの機能差異が減って、使い分けを意識しないでよくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019/c19fd50a-f7b4-3903-1e32-1677c42fa742.png)


### ファイル編集履歴
バージョン管理してないドキュメントでも、自動で簡易なバージョン管理してドキュメントを編集できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019/13538f45-90c1-4d6b-e1c5-473aaab70689.png)

## まとめ
このアップデートでは、AIとの対話をより効率的にする機能が多く追加されました。特にエージェントモードとファイル推奨機能は、開発者の生産性向上に大きく貢献することが期待されます。
Swiftで、日誌アプリを作り始めた

昨日から、ユーザークラスと日誌用のクラスを用意して、日誌アプリを作り始めた。
Realmの導入は、何度も試みてはリレーショナルで躓いてきたが、今回はやっとうまくいった。


```// Userクラス
class User: Object {
    @Persisted(primaryKey: true) var id: String = UUID().uuidString
    @Persisted var name: String = ""
    @Persisted var email: String = ""
    @Persisted var joinDate: Date = Date()
    @Persisted var preferences: String = "{}" // JSON文字列として保存
    @Persisted var dailyRecords: List<DailyRecord>

    override static func primaryKey() -> String? {
        return "id" // 一意のIDを指定
    }
}
}
```


```// DailyRecordクラス
class DailyRecord: Object {
    @Persisted(primaryKey: true) var id: ObjectId // 一意のID
    @Persisted var date: Date                    // 日付
    @Persisted var score: Int                    // スコア
    @Persisted var memo: String                  // メモ
    @Persisted var emotionalType: String         // 感情タイプ
    @Persisted var allowance: Double // お小遣い
    @Persisted var expense: Double // 出費
    let users = LinkingObjects(fromType: User.self, property: "dailyRecords") // Userへのリンクを保持
    // EmotionalType を String 型で保存するための計算プロパティ
     var emotionalTypeEnum: EmotionalType {
         get {
             EmotionalType(rawValue: emotionalType) ?? .happy
         }
         set {
             emotionalType = newValue.rawValue
         }
     }

    override static func primaryKey() -> String? {
        return "id" // 一意のIDを指定
    }
}
```
notionでチームに参加し、権限をもらったが反映されなかったことの解決法

チームのnotionに参加し、編集権限をもらったのになにも表示されないことがありました。
そこで「ctrl + R 」で読み込みをすると解決しました。
今回は、責任者がチームリーダーにフルアクセス権を付与し、そのチームリーダーがチームメンバーに編集権を付与する形でした。
別のチームメンバーも同じ状況になっていたので、よくあることかもしれません。
Oracle Analytics Cloud Classic:隠しダッシュボードプロンプト

隠しダッシュボードプロンプト
---
OAC Enteprise Editionではダッシュボード機能が利用できます。ダッシュボードには分析やワークブックを配置できます。同じダッシュボードページに配置されている複数の分析やワークブックに対して、同じ条件をセットしてレポートを実行する際にダッシュボード・プロンプトを利用します。ダッシュボード・プロンプトは画面に表示して利用しますが、レポートを参照するユーザーにダッシュボード・プロンプトは見せたくない。といった要件がある場合、隠しダッシュボード・プロンプトの機能が有効です

ダッシュボード編集画面の"フィルタと変数"で非表示で埋め込むダッシュボードプロンプトを追加します
![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/70f7e3db-5ba3-b9f6-d1d9-b28e0c24001f.jpeg)

デフォルト値をセットしておいたダッシュボードプロンプトを追加します
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/7b6ee9f1-74d1-fb83-6114-ebb04d01396c.jpeg)

以上で、ダッシュボードページに非表示でダッシュボードプロンプトが埋め込まれ、デフォルト値がセットされた状態で検索が実行されます。

記事記載バージョン：2024 Nov版
ACDLを提唱します。その22

# 概要
ACDLとは、アプリは、クラウド、大切なデータは、ローカルです。
アプリ作ったので、plunkerに上げてみた。

# 機能
マップから、２点間の距離を求める。


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d0edd0ca-7fa3-ed6a-e625-f67f75b3529c.png)

# サンプルコード

```

var map = L.map('map').setView([38.3748331, 139.9574997], 8);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var info = L.control();
info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info');
    return this._div;
};
info.addTo(map);
info.update = function (stats) {
    const totalDistance = (stats.totalDistance ? (stats.totalDistance > 10000) ?(stats.totalDistance / 1000).toFixed(0) + ' km' : (stats.totalDistance).toFixed(0) + ' m' : 'invalid')
    this._div.innerHTML = '<h4>Statistics</h4><b>totalDistance</b><br/>' + totalDistance + '<br/><br/><b>Points</b><br/>' + stats.points +        '<br/><br/><b>Vertices</b><br/>' + stats.vertices;
};
var Berlin = new L.LatLng(38, 140);
var LosAngeles = new L.LatLng(38, 141);
var A = L.marker(LosAngeles, { 
    draggable: true 
}).addTo(map);
var B = L.marker(Berlin, { 
    draggable: true 
}).addTo(map).bindPopup("Drag me.").openPopup();
const geodesic = L.geodesic([A.getLatLng(), B.getLatLng()], {
    weight: 20,
    opacity: 0.5,
    color: 'red',
    steps: 4
}).addTo(map);
info.update(geodesic.statistics);
A.on('drag', (e) => {
    geodesic.setLatLngs([e.latlng, B.getLatLng()])
    info.update(geodesic.statistics);
});
B.on('drag', (e) => {
    geodesic.setLatLngs([A.getLatLng(), e.latlng])
    info.update(geodesic.statistics);
});




```

# 成果物

https://embed.plnkr.co/plunk/9eYb7BRuvNQ6pWk9


以上。
ACDLを提唱します。その21

# 概要
ACDLとは、アプリは、クラウド、大切なデータは、ローカルです。
アプリ作ったので、plunkerに上げてみた。

# 機能
マップに、EEZを表示する。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d725ce51-6d3d-db6d-50f3-7679c2cfbceb.png)


# サンプルコード

```

var map = L.map('map').setView([39.5, 139.5], 5);
var mapLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>';
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; ' + mapLink + ' Contributors',
  maxZoom: 18,
}).addTo(map);

$.getJSON('eez.geojson', function(data) {
  L.geoJson(data).addTo(map);
});




```

# 成果物

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


以上。
(QA) Navigator for i で収集サービスのライブラリーが表示されない

主題のご質問をいただきました。

## エラーの状況

・収集サービスのデータ（*MGGCOLオブジェクトからCRTPFRTDTAコマンドで作成した各種テーブル・ビュー）はIBM i 上に存在している
・5250、OSコマンド等で上記ライブラリーは確認できる
例）GOMACOLというライブラリーに収集サービスデータを作成・復元済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6bd45412-2610-fcd2-ce4d-3a9129e8455c.png)

・にもかかわらず、Navigator for i のパフォーマンス分析パースペクティブ上に上記のライブラリー（例ではGOMACOL）が表示されない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/fa570611-f2fd-9ddb-d0fd-3c398ad65097.png)

## 原因

**IBM i OSは収集サービスのデータが格納されているライブラリー情報を保持したテーブル（マニュアルでは収集表、と表記）があります。この収集表が何らかの操作時にシステム上に実在する収集サービス・データと乖離する事があるようです。**

私の遭遇したケースでは、新しく復元した収集データライブラリーがNavigator for i のパフォーマンス分析の画面に表示されない、のほかに、既に削除済みのパフォーマンスデータライブラリーが表示される（分析もできる(^^;）というエラーもありました。


参考：[収集表の再作成](https://www.ibm.com/docs/ja/i/7.5?topic=collections-rebuilding-collection-table)

## リカバリー手順

上記マニュアルページにもあるとおり、**収集表の再作成を実行することで、実在するパフォーマンスデータのライブラリーやファイルが表示可能になります。**

手順は以下の通りです。

**Navigator for i で　すべての収集サービス　を開く**
**アクション　から　収集テーブルの再作成　を選択する**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/2cf5fabe-e6d6-21d7-6731-990f7083e386.png)

**収集サービスの再ビルド というパネルが表示されるので、再ビルド ボタンを押します。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/9d69d711-a73e-20bb-57f5-525ec9b5f284.png)

収集表の再ビルドが実行されます。
結果、下記のように表示されなかった収集データのライブラリーが表示されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/e3f96957-c03c-bc31-1509-f708d1664445.png)


## 補足：OSコマンドによる再ビルド手順

GURI GURIさんからIBM i OSコマンドを使用したコレクションテーブルのリビルド手順を教えて頂きました♪ありがとうございます。

[Rebuild Collection Table](https://www.ibm.com/support/pages/rebuild-collection-table)

（以下引用）
```
Rebuilding the collection table from the green screen
To rebuild the collection table from a command line, you must call program QPMCCRBD.

The program has three parameters.

    Collection format (10 character blank-padded string)
       Allowed values: '*ALL      ', '*CSFILE   ', '*CSMGTCOL ', '*PEXFILE  ',
                  '*PEXMGTCOL', '*JWFILE   ', '*DWFILE   ', '*BCHFILE  '
    Pointer to error feedback structure
       Pass in a null pointer by using value x'00000000'
    Library name (10 character blank-padded string) *only available in release 7.2 and later*
       Allowed values: '*ALL      ' or 10 character blank-padded library name string

Examples:

    Rebuild all collection formats in all libraries:
       CALL QSYS/QPMCCRBD ('*ALL      ' x'00000000' '*ALL      ')
    Rebuild only *CSFILE collections in all libraries:
       CALL QSYS/QPMCCRBD ('*CSFILE   ' x'00000000' '*ALL      ')
    Rebuild all collection formats in library QPFRDATA
       CALL QSYS/QPMCCRBD ('*ALL      ' x'00000000' 'QPFRDATA  ')
    Rebuild only *CSFILE collections in library QPFRDATA
       CALL QSYS/QPMCCRBD ('*CSFILE   ' x'00000000' 'QPFRDATA  ')


```
【Kotlin】mutableMapのListを管理する方法

# ひとりごと
kotlinを使ってなんとなくプログラミングを学んできましたが、
基礎から立ち返って理解を深めたいと思います。

# はじめに
kotlinのmutableMap（key,value）(※)をList形式にしたいなと思うことがありましたが、
想定した出力になっておらず、使い方がよくわかっていないなと感じたため、記事にしました。

※データを管理する方法
(name,Taro,name,Hanako)みたいな感じでkey:名前,value:値というpairでデータを管理するデータ型のこと。


# 何をしたかったのか？何が想定外だったのか？

```
fun main() {
    var testmap = mutableMapOf("name" to "taro")
    var list = mutableListOf<MutableMap<String, String>>()
    for (i in 0..5) {
        testmap["name"] = "taro_$i"
        list.add(testmap)
    }
    println(list)
}
```

上記のようなfor文を用いて、mutableMapにtaro_1~taro5までを生成して、
定義したListに追加することで、以下mapのリストを作りたかった
> [{name=taro_0}, {name=taro_1}, {name=taro_2}, {name=taro_3},,,]

一方で実際に出力された結果は以下であった
>[{name=taro_5}, {name=taro_5}, {name=taro_5}, {name=taro_5}, {name=taro_5}, {name=taro_5}]


# 原因

結論、同じtestmapオブジェクト（mutableMap型）をlist.add(testmap)で参照していることが原因だと思われる。

````
var testmap = mutableMapOf("name" to "taro")
var list = mutableListOf<MutableMap<String, String>>()
for (i in 0..5) {
        testmap["name"] = "taro_$i" //testmapオブジェクトにtaro_iを追加
        list.add(testmap) //上記結果を元にtestmapオブジェクトをリストに追加
    }
````

具体例を挙げると、
- 1回目のループ]
    for(i in 0..5)の初回ループの時、testmapのMapは以下のようになる
    > {name=taro_0}
    
    また、list.add(testmap)で以下のようになる
    > [{name=taro_0}]  

<bk>

- 2回目のループ
    for(i in 0..5)の2回目ループの時、testmapのMapは以下のようになる
    > {name=taro_1}
    
    また、list.add(testmap)で以下のようになる
     > [{name=taro_1},{name=taro_1}]

    つまり、[{name=taro_1},{name=taro_1}]の各要素は、以下である
     > {mapオブジェクト},{mapオブジェクト}
     
    そのため、mapオブジェクトがループで更新される最後のtaro_5が
    mapオブジェクトの最終的な値となり、各Listのmapが以下になるのである
    >[{name=taro_5}, {name=taro_5}, {name=taro_5},{name=taro_5{name=taro_5}, {name=taro_5}]
    

# 対処法
では、連続した要素をlistに格納するためにはどうしたら良いだろうか？
> [{name=taro_0}, {name=taro_1}, {name=taro_2}, {name=taro_3},,,]

結論以下のようにforループの中でmapオブジェクトを都度生成すればいのである。

````
fun main() {
//   var map = mutableMapOf("name" to "Taro") //ここではなく
  var List = mutableListOf<MutableMap<String,String>>()
  
  for (i in 0..5 ) {
  var map = mutableMapOf("name" to "Taro") //ここに配置
    map["name"] = "Taro_$i"
    List.add(map)
  }
  println(List)
}

````

こうすることで、各ループごとにmapオブジェクトが作成され、

- {name=taro_0}のmapオブジェクトA
- {name=taro_1}のmapオブジェクトB

という各生成されたmapオブジェクトをListに追加するので、
はじめに生成したmapオブジェクトAがforループの中で更新されることはなく、{name=taro_0}としてListに保持されるのである。


# ひとりごと
以上です。ご指摘等あれば、いただければと
GASによるWebアプリの作り方：初心者向けの解説


Google Apps Script（GAS）は、GoogleスプレッドシートやGmailといったGoogle Workspaceのサービスを連携させて、様々なWebアプリケーションを開発できるスクリプト言語です。プログラミング経験がなくても、比較的簡単にWebアプリを作成することができます。

### GASでWebアプリを作るメリット

* **Googleサービスとの連携が容易:** Googleスプレッドシート、Gmail、Googleカレンダーなど、Google Workspaceのサービスと簡単に連携できます。
* **学習コストが低い:** JavaScriptに似た構文で、プログラミング初心者でも学びやすいです。
* **無料:** Googleアカウントさえあれば、無料で利用できます。
* **手軽に公開:** 作成したWebアプリをすぐに公開することができます。

### Webアプリ作成の基礎

GASでWebアプリを作成する基本的な流れは以下の通りです。

1. **GASプロジェクトの作成:** Google Apps Scriptのエディタで新しいプロジェクトを作成します。
2. **HTMLファイルの作成:** ユーザーインターフェースとなるHTMLファイルを記述します。
3. **JavaScriptコードの記述:** HTMLと連携し、Webアプリの機能を実現するJavaScriptコードを記述します。
4. **デプロイ:** 作成したWebアプリをデプロイし、公開します。

### 各ステップの詳細

#### 1. GASプロジェクトの作成
* Googleドライブにアクセスし、「新規」→「その他」→「Google Apps Script」を選択します。
* プロジェクト名を入力し、作成します。

#### 2. HTMLファイルの作成
* プロジェクト内に新しいファイルを作成し、拡張子を「.html」にします。
* HTMLファイルに、ボタン、テキストボックスなどのUI要素や、JavaScriptコードを呼び出すためのスクリプトタグなどを記述します。

#### 3. JavaScriptコードの記述
* プロジェクト内に新しいファイルを作成し、拡張子を「.gs」にします。
* JavaScriptコードで、HTMLのUI要素を操作したり、Googleスプレッドシートのデータを取得・更新したりといった処理を記述します。
* HTMLファイルからJavaScript関数を呼び出すには、`google.script.run`を使用します。

#### 4. デプロイ
* プロジェクトのメニューから「デプロイ」を選択し、「新しいデプロイ」をクリックします。
* デプロイの設定を行い、Webアプリを公開します。

### 例：簡単なWebアプリの作成
例えば、Googleスプレッドシートのデータを表示する簡単なWebアプリを作成する場合、以下のようなコードになります。

**HTMLファイル (index.html)**
```html
<!DOCTYPE html>
<html>
<head>
  <base target="_top">
</head>
<body>
  <button onclick="getData()">データを取得</button>
  <div id="result"></div>
  <script>
    function getData() {
      google.script.run
        .withSuccessHandler(showData)
        .getDataFromSheet();
    }

    function showData(data) {
      document.getElementById('result').innerText = data;
    }
  </script>
</body>
</html>
```

**JavaScriptファイル (code.gs)**
```javascript
function getDataFromSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange("A1:A10");
  var values = range.getValues();
  return values.join('\n');
}
```

### より詳しく学びたい方へ
* **Qiita:** GASに関するチュートリアルやサンプルコードが豊富です。
* **Google Apps Scriptドキュメント:** 公式のドキュメントで詳細な情報を確認できます。
* **オンラインコミュニティ:** GASに関する質問や情報交換を行うことができます。

### まとめ
GASは、手軽にWebアプリを作成できる強力なツールです。Google Workspaceのサービスとの連携を活かして、業務効率化やアイデアの実現に役立ててみましょう。

**さらに詳しく知りたいことや、具体的なアプリを作成したい場合は、お気軽にご質問ください。**

**以下、より具体的な質問の例です。**
* 「Googleフォームの回答をGoogleスプレッドシートに自動で転記するWebアプリを作りたいのですが、どうすればいいですか？」
* 「GASで作ったWebアプリを外部のドメインで公開することはできますか？」
* 「GASで複雑な計算処理を行うことは可能ですか？」

これらの質問に対して、具体的なコード例や手順を交えて解説いたします。
 
**ぜひ、GASでWebアプリ開発に挑戦してみてください！**

**[関連キーワード]**
Google Apps Script, GAS, Webアプリ, プログラミング, JavaScript, Googleスプレッドシート, Googleフォーム, オートメーション

**[補足]**
* 上記はあくまで基本的な説明です。GASには、より高度な機能や設定も可能です。
* GASの学習には、JavaScriptの基礎知識があるとより理解が深まります。
* GASで作成したWebアプリは、セキュリティ対策をしっかりと行う必要があります。

**[その他]**
もし、特定の機能を実装したい場合や、エラーが発生した場合などは、具体的なコードやエラーメッセージを提示いただけると、より的確なアドバイスができます。
BrainF*ckを叫ばせる話 JS編

どうもAtsu1209です。
前回記事`BrainF*ckを叫ばせる話 C++編`は見ていただけましたでしょうか?
前回記事の最後に`今度JSでも変換ツール作ります。`と書いてあります。
なのでしっかりとJSでも`AaaLang`に変換できるようにします。

<br>
<br>
AaaLangとは

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

C++編

https://qiita.com/Atsu1209jp/items/9680445daf5f5bb1a42b

# AaaLangとは
AaaLangとはBrainF*ckをもとにC++で作ったやつです。

BrainF*ckの対応表を貼っておく
|Brainfuck|AAA|
|:---:|:---:|
|`>`|`AAA`|
|`<`|`AAa`|
|`+`|`AaA`|
|`-`|`Aaa`|
|`.`|`aAA`|
|`,`|`aAa`|
|`[`|`aaA`|
|`]`|`aaa`|
# JSコード
```js
 function convertCode() {
            const input = document.getElementById('input').value;
            const output = document.getElementById('output');
            let converted = '';

            const conversionMap = {
                '>': 'AAA',
                '<': 'AAa',
                '+': 'AaA',
                '-': 'Aaa',
                '.': 'aAA',
                ',': 'aAa',
                '[': 'aaA',
                ']': 'aaa'
            };

            for (let char of input) {
                if (conversionMap[char]) {
                    converted += conversionMap[char];
                } else {
                    converted += char;
                }
            }

            output.textContent = converted;
        }

        function copyToClipboard() {
            const output = document.getElementById('output').textContent;
            navigator.clipboard.writeText(output).then(() => {
                alert('クリップボードにコピーしました！');
            }).catch(err => {
                alert('コピーに失敗しました: ' + err);
            });
        }
```
クリップボード機能もつけておきました。

# 実際に変換する
変換するワードは前回と同じく`5000TYO!`です。5000兆円 欲しい!風です。

```brainfuck:BrainF*ckコード
++++++[>+++++++++<-]>-.
>++++++[>++++++++<-]>.
>++++++[>++++++++<-]>.
>++++++[>++++++++<-]>.
>+++++++++[>+++++++++<-]>+++.
>+++++++++[>+++++++++<-]>++++++++.
>++++++++[>+++++++++<-]>+++++++.
>+++[>+++++++++++<-]>.
```
##### 結果
```
AaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAAaaaAAAAAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAaAAAAAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAaAAAAAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAaAAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAAaAAaAAaAaAAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAAaAAaAAaAAaAAaAAaAAaAAaAaAAAAAAaAAaAAaAAaAAaAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAAaAAaAAaAAaAAaAAaAAaAaAAAAAAaAAaAAaAaaAAAAAaAAaAAaAAaAAaAAaAAaAAaAAaAAaAAaAAAaAaaaaaAAAaAA
```
C++プロジェクトに戻って`code.aaaa`にこのコードを入力してみる。
##### 出力結果
```
5000TYO!
```

しっかり変換できました。

# 最後に
GithubPagesで公開するかもです。
MS365のOutlook(Web)では、ドラッグするだけで添付ではなくOneDriveリンクでファイルを手軽に送信できる（ただし注意点1つあり）

# 概要

PPAPはもちろん、メールにファイルを添付するということ自体も、だいぶ古い作法扱いになってきたと思います。全てメールサーバーが上手いことやってくれるような大規模システムを使っているところはともかく、普通くらいの運用だと、会社で契約しているクラウドストレージのリンクを貼るというのが手軽で効果が高いと思います。送信後に元データをコントロールできるという点でも。

リンクを貼る方式については、Microsoft 365契約が有ってOutlookのWeb版を使っている場合、ドラッグ＆ドロップで割と手軽にできるようになっています。ただし落とし穴が一つ。その手順と落とし穴をまとめます。

PPAPセキュリティ相当なのかどうかは議論があると思いますが、少なくとも添付よりは安全になると思います。

これはあくまで便利情報の紹介なので、社内のルールが有る場合は当然そちらに従ってください。

# 説明

* 注意:MS365のプランやテナントの設定によって、動作が異なるかもしれません。これを参考にして自分の環境で実験してから使うことをお勧めします。

OutlookのWeb版でメール作成画面を開いたら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/da4d0639-97c3-5a8f-dc9e-4c67f20da545.png)

本文へファイルをドラッグ＆ドロップ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/e8958255-d7cb-2ad7-7510-828eac1f2fd3.png)

この時点で、自動で自分のOneDrive上へファイルがアップロードされ、そのリンクが書かれます。ちなみにファイルは「自分のOneDriveのフォルダ\添付ファイル」に入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/fbc53f0b-1eac-429c-646e-2c273cfde201.png)

注意！実はこの時点では、組織内の人だけが見られるリンクになっているので、そのまま社外に送っても使えません。ここが落とし穴です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/0424b3a1-1716-78a4-bdae-22614c8587c0.png)

「このリンクを知っている～」の部分をクリックし、「全てのユーザー」にするなど、用途に合わせて変更しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/4af6f50b-07dd-2a63-2812-8aa9425f55c1.png)

これで送信OKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/c0ef858b-3e5b-dc8d-f0ca-091808fd6b6d.png)

# まとめ

いつも通り（？）のドラッグ＆ドロップ手順だけで、添付ではなくクラウドストレージのリンクを送信する事ができて、とても便利です。しかし、いつも通りにやると落とし穴が1つありました。そこだけ注意すれば便利なので、どんどん使っていきましょう！
Oracle Analytics Cloud:OACサービスのスケール、OCPU数の変更範囲が拡張

はじめに
---
2024/9アップデートで、OCPU数のスケール範囲が、1から16の範囲で変更できるようになりました。2024/9アップデート以前では、1から8の範囲で変更できましたが、16までの範囲に拡張されました。

![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/19e472f2-9af8-9270-9d17-4efbea64c689.jpeg)


記載時のバージョン：2024 Nov版

前提
---
・OACサービスが作成されている

OCI管理コンソールにログイン
---
OCI管理コンソールにOACサービスを作成したユーザーでログインします。
※もしくはOACサービスを管理する権限を持つユーザーでログインします
メニューで、アナリティクスとAIからアナリティクス・クラウドにアクセスします
![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/36fb0959-6b9b-e436-45fd-c280f1249759.jpeg)

OACサービスを作成しているリージョン、ドメインを選択し、OACサービスの名前部分のリンクをクリックします。
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2cd06757-b4cd-744c-9bd5-c44fe4ddf067.jpeg)


OACサービスのスケール
---
OACサービスがアクティブであることを確認し、容量の変更をクリックします
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/26fec233-6e8e-1c1c-6144-37bf6241a4b5.jpeg)

容量の変更画面で、OCPU数のリストボックスをクリックすると、1から16まで選択できることが確認できます。変更後のOCPU数を選択します
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/19e472f2-9af8-9270-9d17-4efbea64c689.jpeg)

メッセージを確認し、"変更の保存"をクリックします
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/3ff8024a-4cde-77cd-2104-5cc6faaf5644.jpeg)

変更中は、ステータスが更新中になります
![g6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/8d25f98c-94ea-3aa2-ce42-ac28a8af3ad4.jpeg)


まとめ
---
2024/9アップデートで、OCPU数のスケール範囲が、1から16の範囲で変更できるようになりました。テナントではOACのOCPU数の上限がコンパートメント単位などでも設定されているため、最大値の制限エラーがでた場合は、サービスリクエストで、上限の引き上げをリクエストします

以上
VSCode + github copilotでコードレビューする

自分のコードをセルフレビューするのがめんどくさいのでcopilotにやってもらいたい。
そんなときの手順を残しておきます。

# 要約
1. VSCodeでレビューしてほしいコードを選択
2. Ctrl + i / Command + i
3. このプログラムをコードレビューしてください。と入力
4. レビューが生成されます

# 詳細

## 今回のレビュー対象

私の過去の公開記事にしてみました。

https://qiita.com/Syn256/items/bede4f3cd4692aab6b6e

### コードを選択
![スクリーンショット 2024-11-27 9.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/ef06d49b-684e-5152-3a6d-ebd11fedfb08.png)

### Ctrl + i / Command + i でcopilotのチャットウィンドウを表示

![スクリーンショット 2024-11-27 9.33.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/94f2971c-9fe7-0315-50ef-53b5eb362ca2.png)

/ をタイプし、explainを選択

![スクリーンショット 2024-11-27 9.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/61e2af7a-2804-bb26-09be-116a4366bcc1.png)
![スクリーンショット 2024-11-27 9.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/3ee17fb5-63d4-62e8-b938-8b49b1e02529.png)

### レビューの依頼を入力

![スクリーンショット 2024-11-27 9.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/11f28244-6ce7-580d-a344-9d39200570d7.png)

### レビューが開始されます

![スクリーンショット 2024-11-27 9.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/1ba282a7-7c36-8aeb-2524-72a8b922b815.png)

完了するとチャットウィンドウへの表示が選べます。

![スクリーンショット 2024-11-27 9.36.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/25fab53d-58d0-0358-e637-1c32de25c428.png)

### チャット表示例

![スクリーンショット 2024-11-27 9.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57579/3aa8edb3-295e-c20c-7ad5-227fae8e2163.png)

# 結果

いい点と改善点を示してくれました。
ここでは省略していますが、改善後のコード案も提示してくれるのでとても参考になります。
そして、過去の私のコードが事例とは言えお目汚しであったことが認識できました。
今後とも自分のコードの品質を高めていきたいと心に誓いました。

```
このJavaScriptコードは、地図上でドラッグ操作を行うためのスクリプトです。以下にコードレビューを行います。

良い点
初期化関数の使用: mapInit関数を使用して地図の初期化を行っており、コードの可読性が高いです。
イベントハンドラの設定: mousedown, mousemove, mouseupイベントを適切にバインドしており、ドラッグ操作を実現しています。
改善点
グローバル変数の使用: ymap, dragStartPos, dragEndPos, movingPos, isDraggingなどの変数がグローバルスコープに定義されています。これらは関数スコープに閉じ込めるか、モジュールパターンを使用してグローバル汚染を避けるべきです。
jQueryの依存: jQueryを使用していますが、現代のブラウザではネイティブのDOM操作が強化されているため、jQueryの使用を再検討しても良いでしょう。
ハードコーディングされた座標: 地図の初期位置がハードコーディングされています。これを設定ファイルやユーザー入力から取得するようにすると柔軟性が増します。
イベントハンドラのリファクタリング: イベントハンドラ内のコードが冗長です。例えば、dragStartPosやdragEndPosの初期化は一行で行うことができます。
改善例
以下に、いくつかの改善点を反映したコード例を示します
```