OmniAICreator/Qiita-1.07M huggingface dataset:
【ChatGPT・初心者】体験レポ Vol.1

こんにちは。東です。
ChatGPTに触れる機会があったのでそちらのレポを複数回に
渡って投稿したいと思います。
基本、遊ぶように使うので「真面目な記事が欲しいよ！」
という方には何か違うかもしれません。ご了承ください！

# 画面こんな感じ
Windows版、ios版、Android版など様々あるみたいで、今回はios版とWindows版を触っていました。
Windows版
![スクリーンショット 2024-12-23 184706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/741bb55d-79d5-8e84-4a1b-e48e815ee75d.png)
 ios版
![IMG_4733.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/1263fee5-fc0c-318b-2342-94e0b97a3aeb.png)

テーマなどもカスタマイズできるみたいですので、
割と楽しそう。

# そもそもChatGPTとは？
まず最初にChatGPTに __自己紹介して！__ と聞いてみると
以下のような返答が帰ってきました。

>こんにちは！私はChatGPT、OpenAIが開発したAIアシスタントです。あなたの質問に答えたり、問題解決のお手伝いをしたり、アイデアを一緒に考えたりできます。絵を描くことやIT業界についての話題、さらに記事作成のサポートなど、いろいろなテーマでお手伝いするのが得意です！
これまで、あなたが絵を描くことやQiitaで記事を書いていること、またSpring BootやAWSを使った開発をしていることを教えていただきました。ほかに好きなことや興味のあることがあれば、ぜひ教えてください！ 😊

とこんな感じでフレンドリーな返答が帰ってきました。
この中に「絵」「IT業界」「Spring Boot」など個人的なものが残ってしまっているので、
平たく説明はしてくれません。

聞き方にも工夫が必要みたいです...
そこで聞き方を変えてみました。

**以下の条件を満たすように説明してください。**
**・ 今までの履歴を返答の情報に使わないこと。**
**・ChatGPTの仕組みを簡潔に説明すること。**
**・ChatGPTができることを説明すること。**

すると、以下のような返答が返ってきました

>ChatGPTは、OpenAIが開発した**AIモデル**で、**膨大なテキストデータを基にトレーニング**されています。**テキストのパターンを学習し、入力に応じた適切な応答を生成する**仕組みです。トピックに関連する知識や文脈を理解し、自然な文章でやり取りができます。
ChatGPTができること：
・**情報提供**: 幅広いトピックに関する説明やアドバイスを提供します。
・**文章作成**: レポート、メール、記事、物語など、さまざまな形式の文章を作成します。
・**コードのサポート**: プログラミングの質問に答えたり、コードの修正や生成を手伝ったりします。
・**学習サポート**: 勉強の疑問解消や、トピックの要点を整理するお手伝いをします。
・**創作活動**: 詩やイラストのアイデア、物語のプロットなどの創作を支援します。
わからないことや困りごとがあれば、ぜひ気軽に質問してください！

このように少しお堅い指定をするとその通りに生成してくれるようになります。
これによると
### ChatGPTとは
__・大量のテキストデータをもとに学習させたAIモデル。__
__・テキストのパターンを学習させ、知識や文脈を理解しているのでやり取りが自然。__
__・情報提供はもちろんのこと文章やコード、アイデアなどが生成出来る。__

らしいです。
すごい。

# じゃあ何する？
さて、何をしようかと考えた時に困りました。
そこでやったのが __アキネイター__ ごっこです。
人間側が思い浮かべたキャラクターを魔人が当ててくれるというあれです。
ChatGPTに聞いてみたところ
__アキネイターをChatGPTでも同じようなことができますか？__
>はい、ChatGPTでもアキネイターのような「質問を通じてユーザーの考えているものを推測する」ことは可能です！ただし、いくつかの違いがあります：
__制約__
・連続性
・データベースの差

など制約があるみたいですが出来そうなので
先ずは「サザ○さん」を当ててもらいました。
以下、やり取りです。

第1問 そのキャラクターは 現実の人物 ですか？→ いいえ
第2問 そのキャラクターは アニメまたは漫画 に登場しますか？→ はい
第3問 そのキャラクターは 主人公 ですか？→ はい
第4問 そのキャラクターは 男性 ですか？→ いいえ
第5問 そのキャラクターは 特別な力や能力 を持っていますか？→ いいえ
第6問 そのキャラクターは 日常的な生活 が中心に描かれているキャラクターですか？→ はい
第7問 そのキャラクターは 学園もの の作品に登場しますか？→ いいえ
第8問 そのキャラクターは ファンタジー の世界に登場しますか？→ いいえ
第9問 そのキャラクターは 動物 ですか？→ いいえ
第10問 そのキャラクターは 人間 ですか？→ はい
第11問 そのキャラクターは コメディ要素 の強い作品に登場しますか？→ はい
第12問 そのキャラクターは 「お○松さん」 に登場しますか？→ いいえ
__以下怒涛の作品名ラッシュ...__

ここまで
第20問 で限界みたいで、
>ここまで質問に答えていただきありがとうございます！少し絞り込みが難しくなっていますね。
もし可能であれば、もう少しヒントをいただけると、推測が進みそうです。たとえば、そのキャラクターの外見や特徴、どんなシーンで登場するのかなど、教えていただけると助かります！

と無理そうでした。

結局
__毎週日曜日の週末にアニメーションがテレビで放送されています。__ と言ったら
>ありがとうございます！そのヒントから推測すると、キャラクターは 「サザエさん」 の登場人物、波平さん や サザエさん かもしれません。
「サザエさん」は、毎週日曜日に放送されているアニメーションで、主人公の名前が作品名に含まれています。もし違う場合は教えてください！

と当ててくれました！(同じようなやり取り3回ほどした)
誰か問のなかで当てられた方おりませんか...w

# Vol.1まとめ
ここまで万能だと最初何をしていいかわからなかったので、遊ぶような導入で
今回は触りました。
次回からもう少し機能に踏み込んだ体験をしようと思います。
1年を振り返ってあってよかったと思った機能

# 概要
1年を振り返って、「あってよかった！」と思った機能をまとめます。

# ①サクラエディタ 置換、正規表現
ctrl+R で置換ダイアログを開いた後、正規表現を使って変更することが多かったです。
先頭(^)、末尾($)の変更するときに便利でした。

#### 参考
https://sakura-editor.github.io/help/HLP000089.html

# ②サクラエディタ Grep
ctrl+G で調べたい単語を検索すると、どこのファイルのどの行にあるのかが分かり、検索結果をクリックするとそのファイルに遷移できます。
「特定のID」で調べたいときに便利でした。

#### 参考
https://digital-literacy88.com/sakura-3/

# おわり
面倒だと感じるから機能を探すので、「面倒」という気持ちは大事だなと思いました。
##### 手で1つずつ作業するのが面倒くさい→調べて使えそうな方法を見つける→実際にやってみる
を繰り返すことでどんどんノウハウもたまっていくので、知識を増やしつつ頑張りたいと思います！
二分探索法（バイナリサーチ）で問題解決力を高める：実生活への応用例

# 注意事項

本記事は最初に言いたいこと（まとめ）を書きました。
個人的に最後まで見ないと内容わからない記事は好きでないので、このような構成にしてます。

最初のまとめを読んで、役に立ちそうだなと思ったときは本記事を読んでもらえたら嬉しいです。

## まとめ

アルゴリズムやデータ構造など勉強すると必ずといっていいほど登場する二分探索法（バイナリサーチ）を問題の発生箇所特定に使ってない人がいることに知ったので本記事を作成しました。

===

## 二分探索法とは何か？

硬い言葉でいうと、、、
```
二分探索法（バイナリサーチ：以下、バイナリサーチ）は、ソートされたデータから特定の値を効率的に探し出すアルゴリズム
```
です。
で後半に説明しますが、要は何かを探し出すときに使えるよ！ってことをこのあと説明していきます。

なお、バイナリサーチは以下のような手順にて目的の値を探し出す方法となります。

1. **中央の要素を選択**: データの中央に位置する要素を選びます
2. **比較**: 目的の値と中央の要素を比較します
   - 目的の値が中央の要素より小さい場合、探索範囲を左半分に絞ります
   - 目的の値が中央の要素より大きい場合、探索範囲を右半分に絞ります
3. **再帰的操作**: 上記の手順を、目的の値が見つかるか、探索範囲がなくなるまで繰り返します

## 数字を使った具体例

例えば、以下のように昇順にソートされた数列があるとします：[3, 8, 14, 31, 55, 72, 98]

この数列から、値 `72` を探すとなった場合、

1. **初期設定**:
   - 左端（L）: インデックス `0`（値 `3`）
   - 右端（R）: インデックス `6`（値 `98`）

2. **1回目の比較**:
   - 中央（M）: インデックス `3`（値 `31`）
   - `72` は `31` より大きいため、探索範囲を右半分に絞ります
   - 新しい左端（L）: インデックス `4`（値 `55`）

3. **2回目の比較**:
   - 中央（M）: インデックス `5`（値 `72`）
   - `72` は `72` と等しいため、目的の値が見つかりました

と2回で探し出すことができます。
一般的に、バイナリサーチは最大でも(log2N＋1)回、平均でもlog2N回という回数でできるため大規模になればなるほど効果的な探し方となります。

## システム障害時の二分探索法による原因特定

さて、ここからが本題です。
実生活での応用例として、システム障害が発生した時のことを考えてみます。

例えば「画面が表示されない」や「急に動作が重くなった」といった問題が発生した場合、バイナリサーチの考え方を応用すると以下のような手順になります。

**手順**:

1. **システムの全体像を把握**: システムが複数のモジュールやコンポーネントから構成されている場合、それらをリストアップし、依存関係やデータフローを確認します

2. **問題の範囲を半分に分割**: システム全体を大きく二つの部分に分け、どちらに問題が存在するかを確認します。例えば、フロントエンドとバックエンド、またはユーザーインターフェースとデータベースなどに分けます

3. **各部分の検証**:
   - 片方の部分に問題がないことを確認できれば、もう片方に焦点を当てます
   - 問題のある部分をさらに二つに分割し、同様の手順で問題箇所を絞り込んでいきます

4. **詳細な調査**:
   - 問題のあるモジュールや機能が特定できたら、その内部をさらに細かく分割し、コードや設定、リソースの使用状況などを確認します
   - ログやエラーメッセージを参照し、異常な動作やエラーの発生箇所を特定します

実際にはある程度の経験から問題の発生箇所をある程度推測してやることもありますが、正直良くわからんなーって時は変な先入観なく作業的に問題発生箇所特定できるので知っておくと便利なやり方かなと思います。

##参考文献##

- [【バグ発見のコツ】二分探索でバグ発生個所を特定する - Qiita](https://qiita.com/mtanabe/items/91f93b236b89cf11057a)
- [システム障害の切り分け手法：一次切り分けと二次切り分けの違いを徹底解説 - xhours](https://x-hours.com/articles/25122)
- [システム障害の「切り分け」とは！一次、二次の違いは - Geekly](https://www.geekly.co.jp/column/cat-technology/1903_035/)
- [障害の一次切り分けと二次切り分け - itsupplee](https://itsupplee.jp/keyw34/)
- [プログラミング一般で使えるデバッグ方法 #debug - Qiita](https://qiita.com/nogitsune413/items/a2e1dc373210932407c8)
SQLで集計作業をする際、CASE文の使用のすすめ

# 概要
SQLで何か集計作業をする場合、CASE文の使用すると効率よく集計できるかもというお話です。

ここでは例として、選手の過去の成績で1位から3位になった回数をそれぞれ集計する例をあげます。

# テストデータ

| 試合テーブル(game) |
|-------------------|
| id |
| game_name |

| 試合結果テーブル(result) |
|------------------------|
| id |
| game_id |
| player_id |
| rank |

| 選手テーブル(player) |
|--------------------|
| id |
| player_name |


# 非効率な方法

パッと思いつく方法としては、where句でrankを条件分岐して、1つ1つ集計する方法が考えられるかと思います。

```
SELECT
    player_id,
    COUNT(*) AS first_place_count
FROM
   result
WHERE
   - 2着、3着の場合は下記の条件分岐を変更
   rank = 1
GROUP BY
   player_id
;
```

しかし、上記の方法の場合、SQLを3回実行しなくてはいけなくなり、I/O面で効率的ではありません。
上記のようなことを解決するために、登場するのがCASE文です。

# CASE文を利用した集計SQL

CASE文を使用すると、1回でそれぞれの回数を算出することができます！

```
SELECT
   player_id,
   - 1着回数
   SUM(
        CASE
            WHEN rank = 1 THEN 1
            ELSE 0
        END
    ) AS first_place_count,
    - 2着回数
    SUM(
        CASE
            WHEN rank = 2 THEN 1
            ELSE 0
        END
    ) AS second_place_count,
    - 3着回数
    SUM(
        CASE
            WHEN rank = 3 THEN 1
            ELSE 0
        END
    ) AS third_place_count
FROM
    result
GROUP BY
    player_id
;
```

上記の方法であれば、一度のSQLで1着から3着までの回数を算出することができるため、効率的な集計をすることができ、処理も複雑になることがありません。

# まとめ

もし、何かデータを集計する処理が出てきた場合には、where句で条件分岐することを考える前に、CASE文でうまく集計できないか考えてみるのも良いかと思います。

私自身、where句ばかりで条件分岐をさせることばかり考えていたので、CASE文という方法を知り、かなり効率的に集計処理をすることができるようになりました。

ぜひ、よかったらみなさんもCASE文の使用を考えてみてください！
Github Actionsを使ったGoテストの自動化

## 最初に
みなさん、こんにちは！
この記事では、GitHub Actionsを使ってGoの自動化テストを案件で挑戦した事例を紹介します。エンジニアとして自動化テストはとても重要なスキルだと思うのでより良い完全等があればコメントいただければ幸いです。

## 必要な準備(チュートリアル)
まず最初に、あなたのプロジェクトに`go.mod`ファイルがあることを確認してください。それでは、早速始めましょう！
### ステップ1: GitHubリポジトリの作成
​リポジトリを作成する​: GitHubで新しいリポジトリを作成しましょう。名前は何でもOKです。ここでは例として`go-automation`リポジトリを使います。

### ステップ2: go.ymlファイルの作成
プロジェクトのルートディレクトリに`.github/workflows`ディレクトリを作成し、その中に`go.yml`ファイルを作成します。この`go.yml`ファイルがGitHub Actionsのワークフローを定義します。
```
name: Go CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:

    runs-on: ubuntu-latest

    steps:
    - name: Check out code
      uses: actions/checkout@v2

    - name: Set up Go environment
      uses: actions/setup-go@v2
      with:
        go-version: 1.18

    - name: Install dependencies
      run: go mod tidy

    - name: Run tests
      run: go test ./... -v
```

### ステップ3: プッシュしてみる
​変更をコミットする​: go.ymlファイルを作成したら、それをコミットしてプッシュしましょう。    
```
$ git add .
$ git commit -m "Add GitHub Actions for Go CI"
$ git push origin main
```
    
​GitHub Actionsの確認​: GitHubリポジトリのページに移動し、「Actions」タブをクリックします。新しく作成されたワークフローがトリガーされ、テストが実行されるのを確認しましょう。
結果の確認
ワークフローが正常に実行されると、テストの結果がGitHubの「Actions」タブに表示されます。すべてのテストがパスしていることを確認すればチュートリアルは完了です。

## 実例
your-go-project/workflows配下にtest.ymlを追加しました。

案件では
```
your-go-project/
├── .github/
│   └── workflows/
│       └── list.yml
├── cmd/
│   └── yourapp/
│       └── main.go
├── pkg/
│   ├── yourpackage/
│   │   ├── yourfile.go
│   └── anotherpackage/
│       └── anotherfile.go
├── go.mod
├── go.sum
└── README.md
```

test.yml
```
name: test  # ワークフローの名前

on:
  pull_request:  # プルリクエストが作成されたときに実行
  workflow_dispatch:  # 手動でワークフローを実行

jobs:
  test:
  runs-on: ubuntu-latest  # ジョブを実行する環境として最新のUbuntuを使用

  steps:
  - uses: actions/checkout@v3  # リポジトリのコードをチェックアウトするステップ

  - name: Set up Go
  uses: actions/setup-go@v4  # Go環境を設定するステップ
  with:
  go-version: 'go1.23.3'  # 使用するGoのバージョンを指定

  - name: Run tests
  run: go test -v ./...  # 指定されたディレクトリ以下のすべてのテストを実行
```
まとめ
GitHub Actionsを使ってGoの自動化テストを設定する手法をまとめました。
自動化テストで反復で行う処理を自動化して楽できるだけでなく、バグの早期発見にも繋がります。
今回はAWSに連携したりと複雑な処理は行なっていないので次回はCDについても実装していきたいと思います。
インパクトマッピングをやってみた

このエントリは、[SmartHR Advent Calendar 2024](https://qiita.com/advent-calendar/2024/smarthr) シリーズ1の24日目の記事です。

シリーズ1の昨日の記事は8chariさんの [SmartHR UXライターの責任範囲を明文化した話](https://note.com/8chari/n/n5739546127de)、シリーズ2の昨日の記事はおくらさんの [できるさ！チーフー！](https://todomasa.hatenadiary.org/entry/2024/12/23/122922) でした。
どちらの記事も想いが込められた寒さ忘れるアツい記事でした！

# これはなに？
インパクトマッピングをやってみた体験記です。

# インパクトマッピングとは
インパクトマッピングは、プロダクトを作るときの迷いを防ぐ戦略的なプランニング手法です。解決したい顧客課題に対してゴールを起点として、アクターを定義し、アクターごとのインパクトを整理して、インパクトに紐づく成果物を考えていきます。
考えられた成果物は、ユーザーストーリーマッピングとして分類して整理することができます。

サイモン・シネックのゴールデン・サークルに則り、ゴール（Why）を考え、インパクト（What）、成果物（How）を順に考えていきます。
また、ゴールから達成されたときの基準を定めることで、フィーチャーの仮説検証を行うことができます。

書籍『[プロフェッショナルプロダクトオーナー](https://amzn.asia/d/f2fT6by)』で紹介されています。

## インパクトマッピングの例
あるケーキ屋さんの課題を例に考えてみます。
クリスマスシーズンに、予約が殺到して、予約管理と受取時間の調整がうまくできず、いつも店舗内が受取待ちの人で溢れ、店舗の外にも寒い中ケーキの受取行列ができているとします。

ゴールに「クリスマスケーキの受取時間を調整して、店舗内の収容人数を超えない」と定めます。
ゴールからアクター「顧客」「店舗」ごとのインパクトを書き出します。
インパクトの行動変容を起こすための作るものが成果物です。
最後にゴールが達成できたかを評価するための基準を定めます。

これらを図にしたものが以下のインパクトマッピングです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15643/fcebddd2-e10b-d49a-f950-8d45e3f734c8.png)

※師走の思いつきで書いたので、内容の妥当性は薄いかもしれません。

# やってみた
私のチームでのとある機能の開発時に、インパクトマッピングで機能を使う役割ごとのインパクトを整理しました。

2つの実現方法案で揺らいでいたのですが、インパクトマッピングでゴールを起点にして整理したことによって、ゴール達成のためにより早く到達する方法を見極めて選択することができました。
整理した成果物はそのままユーザーストーリーとして活用して、実装に入っていくことができました。
ゴールが何か、アクターは何ができるか、を整理しているので、詳細仕様を検討するときにも、目的を見失わずに議論できるといった効果もありました。

合わせて他のチームで実践していた[顧客理解を深めるロールプレイング](https://tech.smarthr.jp/entry/2024/07/18/140316)を通して、業務ドメインの理解を深め、詳細仕様を詰めていきました。

## 体験者の声
インパクトマッピングをやり、ストーリーを整理したチームの声です。

- これまで機能ベースで検討してしまっていたが、ユーザーが本当に求めているものを認識しながら仕様検討ができた
- アクター（登場人物）をそれぞれ考慮して、アクターの操作や業務の関わりを意識しながら仕様を考えることができた
- 睡眠の質が改善されました（注：これは誇大広告です）

# まとめ
なにか課題があって解決方法を考えるとき、方法論にどうしても目がいってしまいがちです。インパクトマッピングは誰にどのような行動変容があるかといった影響を踏まえた上で方法論を考えていくことができ、ゴールからの因果関係を辿って考えることができます。

達成したいゴールを外さないために、インパクトマッピングをぜひやってみてはいかがでしょうか？
各ユーザーの履歴データを件数を限定して、一括取得する方法の案

# 概要
実装していく中で、複数ユーザーの履歴をそれぞれ最新3件だけ表示するという必要があり、その方法を私なりに考えた結果をまとめておきたいと思います。

ここで使用するのは、SQLのウィンドウ関数とサブクエリです。

# 説明するためのテストデータ紹介

例えば、以下のようなテーブルがあったとします。

**ユーザーテーブル(user)**
| カラム名 | 説明 |
|----------|--------|
| id | ユーザーID |
| user_name | ユーザー名 |


**操作履歴テーブル(history)**
| カラム名 | 説明 |
|----------|--------|
| id | 操作履歴id |
| user_id | ユーザーID |
| history_content | 操作内容 |

# 考え方

操作履歴をすべて取得する場合は簡単だと思いますが、
ここに件数という条件が付与されると少し工夫が必要になります。

さて、ユーザーごとの操作履歴を3件ずつ取得する方法を考えてみます。

まず、私がすぐに思いついたのはユーザーidごとに3件取得するという方法です。
しかし、この方法は取得したいユーザー数が増えるほどクエリ数が増えるため、おすすめできません。

そこで、以下の方法を考えました。

1. ユーザーごとに最新の履歴から順番を付与
2. 順番が3以下のデータを取得

上記の方法を実現するためにはウィンドウ関数とサブクエリを使用します。
(WITH句でも良いとは思いますが、ここではサブクエリを使用する方針とします。)


# 実際の方法

**1.ユーザーごとに最新の履歴から順番を付与**
下記のSQLでindexという名称で順番を付与することができます。

```
SELECT
    id,
    user_id,
    history_content,
    - 以下でウィンドウ関数を利用し、履歴の最新順に順番を付与
    ROW_NUMBER() OVER( PARTITION BY user_id ORDER BY id DESC ) AS index
FROM
    history
WHERE
    user_id IN (1,2,3)
;
```
**2.順番が3以下のデータを取得**
単純に、1で付与した順番に対して、3以下のものを取得するようにwhere句で条件を付与します。

```
SELECT
    *
FROM
    (1のサブクエリ)
WHERE
    index <= 3
;
```

**1と2を合わせた結果**

```
SELECT
    *
FROM
    (
        SELECT
            id,
            user_id,
            history_content,
            - 以下でウィンドウ関数を利用し、履歴の最新順に順番を付与
            ROW_NUMBER() OVER( PARTITION BY user_id ORDER BY id DESC ) AS index
        FROM
            history
        WHERE
            user_id IN (1,2,3)
    ) AS history_index
WHERE
    history_index.index <= 3
;
```

**注意点**
ユーザーを絞り込むwhere句については、サブクエリの段階で絞り込みをしないと、すべてのユーザー履歴を読み込んで順番を付与することになるので、DB負荷があがってしまいます。


# まとめ

上記のような形で、取得することでユーザー数に関係なく、クエリの発行回数は固定で効率よく取得できるので、おすすめです。

ユースケースとして、特定のユーザーでのグループがあり、そのグループページにて、それぞれの最新の投稿履歴やゲームであれば戦闘履歴などを表示する場合には有効かと思います。
ショート動画でクイックに知る！ ファイス・ボット・ソリューションとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/f11af5f8-c2d9-779a-5bd1-4c7f92106d50.png)

# はじめに

みなさん、IBM Videoというサイトをご存知でしょうか？
IBMが提供する製品をショート動画でわかりやすくご紹介している動画サイトです。
* スキルアップしたくてもなかなか時間が取れない
* 気になる製品があるけど、マニュアルを読んで理解するのはきつい
* 製品の特徴やメリットをクイックに知りたい

という方には、うってつけの動画を提供するサイトです。
興味のある方はぜひご覧いただければと思います。

# 今回ご紹介する動画へのリンク

[フェイス・ボット・ソリューションのご紹介](https://video.ibm.com/playlist/645386/video/132691658)

# フェイス・ボット・ソリューションとは？

## 現状と課題認識

* 多くの企業でチャットボットが導入され、AIを活用した顧客対応が一般化してきている。
* しかし、チャットボットとリアルなヒューマンコミュニケーションの間にはギャップがあり、期待を下回る体験も少なくない。
* 最近では、ボイスボット（自動音声応答システム）への移行が進んでいるものの、さらに進化した対話型インターフェースが求められている。

## フェイス・ボット・ソリューションの提案

* フェイス・ボット・ソリューションは、ソウルマシーンズ社が提供するアバター技術とIBM watsonx AssistantのAIエンジンを組み合わせたソリューション。
* 高度にリアルなアバターによるコミュニケーションを実現し、より人間らしい対話を可能にする。
* 顧客満足度を向上させると同時に、企業のブランド価値や信頼性を高める効果も期待できる。

## 対象顧客と利用用途

* eコマース分野において、よりパーソナライズされた接客や対話体験を提供したい企業向け。
* 新しいビジネスモデルを検討している顧客に対し、次世代の顧客体験を提案できるサービスとして推奨。


## デモンストレーションの内容

* ピザの注文受付シナリオを通じてFaceBotの自然な対話機能を実演。
* サイズや配達時刻の指定、持ち帰り割引への柔軟な対応など、実際の接客に即した高度な対話例を紹介。

## FaceBotの強みと導入メリット

* リアルタイム対応力: 人間らしい自然な会話を通じてスムーズな取引を実現。
* 顧客満足度向上: ユーザーエクスペリエンスを向上させ、リピーターの獲得やブランド価値向上に寄与。
* 導入の簡便さ: Watsonアシスタントと連携することで、既存のAI基盤を活用したスムーズな導入が可能。

# まとめ

* FaceBotを活用し、自社の商品やサービスに応用することで新しいeコマース体験を創出できることを提案。
* 具体的なトライアルの実施を提案。

# 参考

フェイス・ボットのご紹介

https://video.ibm.com/playlist/645386/video/132691658
Ubuntu ServerにOpenSSHをインストール

Ubuntu ServerにOpenSSHをインストール

1. OpenSSHのインストール: Ubuntuには通常、OpenSSHがプリインストールされていますが、インストールされていない場合は次のコマンドでインストールできます。
sudo apt update
sudo apt install openssh-server
SSHサービスの状態確認: インストール後、SSHサービスが正常に動作しているかを確認します。
sudo systemctl status ssh
サービスが「active (running)」と表示されていれば、SSHサービスは稼働中です。

2. SSHの設定ファイル編集: /etc/ssh/sshd_config ファイルを編集して、必要に応じて設定をカスタマイズします。例えば、パスワード認証を無効にするには、以下の設定を編集します。
sudo vi /etc/ssh/sshd_config
設定例：
パスワード認証を無効にする: PasswordAuthentication no
ルートログインを禁止する: PermitRootLogin no
SSHサービスの再起動: 設定を変更した後、SSHサービスを再起動して変更を適用します。
sudo systemctl restart ssh

3. ファイアウォール設定 (必要に応じて): Ubuntuのファイアウォールが有効になっている場合は、SSHトラフィックを許可する必要があります。
sudo ufw allow ssh
sudo ufw enable
sudo ufw status
これらのステップでUbuntu ServerにOpenSSHを設定できます。設定によってはセキュリティリスクが伴う場合があるため、必要な変更を慎重に行ってください。

4. 秘密鍵と公開鍵のペアを生成する: ターミナルを開き、以下のコマンドを実行します。ここで -b オプションで鍵のビット数を指定でき（例えば2048ビットまたは4096ビット）、-t オプションで鍵のタイプを指定できます（一般的には rsa が推奨されますが、ecdsa や ed25519 も選択できます）。
ssh-keygen -t rsa -b 4096
このコマンドを実行すると、鍵の保存場所とパスフレーズの入力を求められます。特に指定がなければ、デフォルトの場所（通常は ~/.ssh/id_rsa）に鍵が保存されます。パスフレーズはオプショナルですが、セキュリティを強化するために設定することをお勧めします。
公開鍵をサーバーにコピーする: 公開鍵（.pub ファイル）をサーバーの ~/.ssh/authorized_keys ファイルに追加する必要があります。これにはいくつかの方法がありますが、一番簡単なのは ssh-copy-id コマンドを使用することです。次のコマンドを使用して公開鍵をサーバーにコピーします（username と server_ip を適切なものに置き換えてください）。
ssh-copy-id -i ~/.ssh/id_rsa.pub username@server_ip
このコマンドは、指定されたユーザー名とIPアドレスでサーバーにログインし、公開鍵をサーバーの適切な場所に追加します。
鍵の使用
生成された秘密鍵を使用してサーバーにSSH接続するには、通常のSSHコマンドを使用します。

ssh username@server_ip
鍵の生成と配置が正しく行われていれば、パスフレーズを設定した場合を除き、パスワードを入力することなくサーバーにログインできます。パスフレーズを設定した場合は、接続時にそのパスフレーズの入力を求められます。

5. ~/.ssh/config ファイルを設定することで、SSH接続の設定をカスタマイズし、接続情報を簡単に管理できます。このファイルを使用すると、サーバーのアドレス、ユーザー名、使用する鍵、その他のオプションを予め定義しておくことができ、コマンドラインから毎回詳細な情報を入力する手間を省くことができます。

基本的な設定方法
SSH設定ファイルの作成: もし ~/.ssh/config ファイルがまだ存在しない場合は、新しく作成します。
touch ~/.ssh/config
ファイルの編集: お使いのテキストエディターで ~/.ssh/config ファイルを開きます。例えば、nano を使用する場合は以下のコマンドです。
vi ~/.ssh/config
設定の追加: 以下は一般的な設定の例です。これは Host キーワードを使用して特定のSSH接続の設定を定義します。
Host server_alias
    HostName server_ip_or_domain
    User your_username
    Port 22
    IdentityFile ~/.ssh/id_rsa
この設定により、server_alias というエイリアスで接続設定を行い、次のように簡単にSSH接続を行うことができます。

ssh server_alias

Enjoy ssh!!!
Azure運用の完全自動化ガイド：AIとDevOpsを統合した実践手順

この記事では、Azure Cognitive Servicesを使ったAI運用の自動化とAzure DevOpsを活用した高度な自動化パイプラインの構築方法を、詳細に解説します。

# 1. Azure Cognitive Servicesを使ったテキスト解析の自動化
Azure Cognitive Servicesを活用して、運用アラートやログのテキスト解析を自動化し、対応の効率化を図ります。以下は具体的な構築手順です。

## 手順: テキスト解析APIを用いた自動化
前提条件
Azureサブスクリプションが必要。
Azure Automation アカウントを作成済み。
PowerShellの基礎知識があると良い。
### ① Cognitive Services リソースの作成
Azure ポータルにログイン。
左側メニューの「+リソースの作成」をクリック。
「Cognitive Services」を検索し、選択。
次の情報を入力してリソースを作成：
名前: TextAnalyticsService
サブスクリプション: 適切なものを選択。
リージョン: 使用するリージョンを選択。
価格レベル: 無料または必要なプラン。
### ②API キーの取得
作成したリソースを開く。
「キーとエンドポイント」をクリック。
提供されたキー1とエンドポイントURLをメモ。
### ③Automation Runbookを作成
Azure ポータルでAutomation アカウントを開く。
「Runbook」セクションで「+ 新しいRunbook」を選択。
次の情報を入力してRunbookを作成：
名前: TextAnalysisRunbook
種類: PowerShell
ランタイムバージョン: 5.1
以下のスクリプトを貼り付ける：
powershell
Cognitive Services Text Analyticsを使ったテキスト解析
apiKey = "YOUR_API_KEY" # 取得したAPIキーを入力
endpoint = "YOUR_ENDPOINT" # エンドポイントURLを入力
text = "Critical issue detected in the system logs"

 REST APIリクエストの設定
headers = @{
    "Ocp-Apim-Subscription-Key" = apiKey
    "Content-Type" = "application/json"
}
body = @{
    documents = @(@{
        id = "1"
        language = "en"
        text = $text
    })
} | ConvertTo-Json -Depth 10

API呼び出し
response = Invoke-RestMethod -Uri "endpoint/text/analytics/v3.0/keyPhrases" -Method Post -Headers headers -Body body
response.documents.keyPhrases
### ④ スケジュールの設定
作成したRunbookを公開。
「ジョブ」セクションでスケジュールを作成し、定期的にテキスト解析を実行。

# 2. DevOpsとAutomationの統合でCI/CDを高度化
Azure DevOpsを活用し、Automation Runbookと連携した高度なCI/CDパイプラインを構築します。

## 手順: DevOpsによるインフラ展開とRunbookの実行
前提条件
Azure DevOpsアカウントが必要。
Azure Automation アカウントを作成済み。
### ① Azure DevOps プロジェクトの作成
Azure DevOpsポータルにログイン。
「新しいプロジェクト」をクリックし、次の情報を入力：
プロジェクト名: AutomationWithDevOps
可視性: パブリックまたはプライベートを選択。
### ②リポジトリとパイプラインの設定
プロジェクトの「リポジトリ」セクションに移動し、コードをプッシュ。
「パイプライン」セクションで「新しいパイプライン」を作成し、次のYAMLファイルを記述：
yaml
trigger:
 main

pool:
  vmImage: 'windows-latest'

steps:
 task: AzureCLI@2
  inputs:
    azureSubscription: 'YOUR_AZURE_SERVICE_CONNECTION'
    scriptType: 'ps'
    scriptLocation: 'inlineScript'
    inlineScript: |
      # Runbookの実行
      Connect-AzAccount
      Start-AzAutomationRunbook -AutomationAccountName "YOUR_AUTOMATION_ACCOUNT" -ResourceGroupName "YOUR_RESOURCE_GROUP" -Name "TextAnalysisRunbook"
### ③ CI/CDトリガーの追加
パイプライン設定で、リポジトリの更新をトリガーとして登録。
テスト環境や本番環境にデプロイする条件を明確に記述。

# 3. AI+DevOps統合の運用事例
ユースケース: 自動障害対応フロー
障害検知: Azure Monitorがシステム異常を検出。
Runbook実行: Automation Runbookがテキスト解析を実行し、問題を分類。
通知: TeamsやSlackに結果を自動送信。
再試行またはエスカレーション: Runbookの結果に応じて対処。
実装ポイント
通知の設定: Azure Logic Appsを使い、結果を通知。
再試行ポリシー: DevOpsパイプラインにリトライロジックを追加。
# まとめ
この記事では、Azure Cognitive ServicesとDevOpsを統合した自動化フローの具体的な手順を解説しました。

AIの活用: Cognitive Servicesでのテキスト解析を自動化。
CI/CDの統合: DevOpsとAutomation Runbookの連携。
運用効率化: インテリジェントな障害対応フローの構築。
次回は、さらに高度なトピックとしてAzure OpenAI Serviceの活用や、複雑なマルチクラウド運用を深掘りしていきます。ぜひお楽しみに！
[Rust]TypeScriptと比較してRustの文法をおさらいする①

## 変数の宣言

### TypeScriptの場合
TypeScriptでは`let`や`const`を使って変数を宣言します。

```typescript
let mutableVariable = 42; // 再代入可能
const immutableVariable = "Hello, TypeScript!"; // 再代入不可
```

### Rustの場合
Rustでは`let`を使って変数を宣言します。デフォルトでは不変（immutable）ですが、再代入可能にしたい場合は`mut`キーワードを使用します。

```rust
let immutable_variable = "Hello, Rust!"; // デフォルトで不変
let mut mutable_variable = 42; // 再代入可能
mutable_variable = 100; // OK
```

## 関数の宣言

### TypeScriptの場合
TypeScriptでは`function`キーワードを使うか、アロー関数の形で関数を宣言します。戻り値の型はオプションですが、型を明示することが推奨されます。

```typescript
// functionを使う
function add(a: number, b: number): number {
  return a + b;
}

// アロー関数で書く
const greet = (name: string): string => {
  return `Hello, ${name}!`;
};
```

### Rustの場合
Rustでは`fn`キーワードを使って関数を宣言します。パラメータと戻り値の型を必ず指定する必要があります。

```rust
fn add(a: i32, b: i32) -> i32 {
    a + b // セミコロンを省略すると値が戻り値になる
}

fn greet(name: &str) -> String {
    format!("Hello, {}!", name) // Stringを生成
}
```

## 型アノテーション

### TypeScriptの場合
TypeScriptでは、変数や関数のパラメータ、戻り値に型を付けることができます。型推論させることも可能です。

```typescript
let count: number = 10;
let message: string = "TypeScript is fun!";
```

### Rustの場合
Rustでも型アノテーションを使います。型推論させることも可能です。


```rust
let count: i32 = 10; // 型を明示
let message = "Rust is fun!"; // 型推論で&strと判定
```

## オブジェクト型の宣言と生成

### TypeScriptの場合
TypeScriptでは、`interface`や`type`を使ってオブジェクトの型を定義します。その型に基づいてオブジェクトを生成します。

```typescript
type User = {
  id: number;
  name: string;
};

const user: User = {
  id: 1,
  name: "Alice",
};
```

### Rustの場合
Rustでは、`struct`を使って構造体を定義します。インスタンスを生成する際はフィールド名を指定して値を渡します。

```rust
struct User {
    id: u32,
    name: String,
}

let user = User {
    id: 1,
    name: String::from("Alice"),
};
```

## `undefined`の可能性と`Option`型

### TypeScriptの場合
TypeScriptでは、型に`undefined`を含めて明示することで対応します。

```typescript
function findUser(id: number): User | undefined {
  if (id === 1) {
    return { id: 1, name: "Alice" };
  }
  return undefined;
}

const user = findUser(2);
if (user) {
  console.log(user.name);
}
```

### Rustの場合
Rustでは、値が存在するかどうかを安全に扱うために`Option`型を使用します。`Some`で値をラップし、`None`で値がないことを表現します。

```rust
fn find_user(id: u32) -> Option<User> {
    if id == 1 {
        Some(User {
            id: 1,
            name: String::from("Alice"),
        })
    } else {
        None
    }
}

let user = find_user(2);
if let Some(user) = user {
    println!("{}", user.name);
}
```
paiza.ioでc その12

# 概要
paiza.ioでc#、やってみた。
AtCoderシリーズ

# 整数 a,b,cと、文字列 s が与えられます。 a+b+c の計算結果と、文字列 s を並べて表示しなさい。

https://qiita.com/ohisama@github/items/0ef038fa6caa9aeb55c9

# 文字列内の、'1' の個数をカウントする

https://qiita.com/ohisama@github/items/45a8441c76f8d4047e4a

# 二つの整数a,bの積の偶奇を判定する。

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

# 文字列Sが、'dream','dreamer','erase','eraser'の組み合わせで作れるかどうかを判定する。

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

# N個の整数値を受け取り、一度の操作ですべての数を2で割る。割り切れなくなるまで割っていった時、何回割ることが出来るか？

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

# 1以上N以下の整数のうち、10進法での各桁の和がA以上B以下であるものの総和を求めてください。

https://qiita.com/ohisama@github/items/4548b53220fff4507338

# N個の整数の重複しない値の数を求める。

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

# 10000円札、5000円札、1000円札がある前提で、合計がN枚、Y円になる組み合わせを求める。

https://qiita.com/ohisama@github/items/22f3994240925b12e2bf

# 座標(0,0)を出発地点とした場合、時刻ti時点で(xi,yi)にいることができるかどうかを判定する。

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

# N枚のカードを交互に自身の得点が最大になるように取っていった場合の、二人の得点の差分を求める。

https://qiita.com/ohisama@github/items/74a62e823d199bec7bbf

# 500円玉、100円玉、50円玉を使ってXX円を支払う方法が何通りあるかを求める。

https://qiita.com/ohisama@github/items/23e9f04b2c0adabda964


以上。
自動で類似ワード群を作成し共起関係をWeb図で確認する(SPSS Modeler データ加工逆引き13-2)

# 自動で類似ワード群（カテゴリー）を作成し共起関係をWeb図で確認する

![スクリーンショット 2024-12-18 9.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/6f7be32d-5fbf-b957-812b-d71490853397.png)

この記事はSPSS Modeler Premium Ver18.6から追加された日本語テキスト機能を利用して書いています。SPSS Modeler Professionalをお使いの方はアップグレードするかPython連携を用いて実現します。

Python連携を紹介する記事はこちら

https://qiita.com/harrowharrow16/items/248ff8fe3879b63e7ae3

## 1.想定される利用目的

・コンタクトセンターの応答ログから解約に影響する単語の探索
・営業日報のコメントから成約予測モデルの説明変数を作成
・アンケート自由回答データからブランドと評価のポジショニングマップを作成
   
## 2.ストリームとデータのダウンロード

ストリーム

https://github.com/yoichiro0903n/blue/raw/a453dd98d6281769a12be2b82fa0c753c0fd5e2d/category2network.str

データ

https://github.com/yoichiro0903n/blue/blob/b02b11130c8c35ff26b8f2336d1aa8001374316a/comments2024_mac.csv

## 3.サンプルストリームの説明

![スクリーンショット 2024-12-18 10.03.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ed64d101-4a02-e580-605b-398325589337.png)

a.入力データは以下の通りです。[comment]列の文章から頻出ワード群を自動作成してWebグラフにします。

![スクリーンショット 2024-12-13 10.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5e740adc-dfde-7dfd-f7b6-6a51676d053c.png)

b.[テキストマイニング]ノードを編集します。[IDフィールド]と[テキストフィールド]を以下の通り選択します。

![スクリーンショット 2024-12-18 10.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/609a7ddc-efbd-b432-79e7-25a97ce54674.png)

[モデル]タブを以下の通り設定して[実行]します。

![スクリーンショット 2024-12-18 10.14.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a7d4b7f3-5a9d-a6b7-7372-50e280083346.png)

以下のインタラクティブウインドウが表示されます。左下の領域に多頻度ワード（コンセプト）が列挙されます。類似ワード群（カテゴリ）を作るため[作成]ボタンを押します。

![スクリーンショット 2024-12-18 10.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3058463d-689d-0078-b23a-16b8431a18af.png)

カテゴリが右上に自動的に作成されました。[スコア]ボタンを押します。

![スクリーンショット 2024-12-18 10.18.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/626cbf5a-d5e2-907b-d066-c6b224944c23.png)

[表示]ボタンを押します。[カテゴリーweb]タブでWebグラフが表示されます。

![スクリーンショット 2024-12-18 10.20.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/35000d27-ea7f-3056-645c-4c5536e45e32.png)

特定のカテゴリーを右上のリストで選択します。例ではバッテリーをフォーカスします。

![スクリーンショット 2024-12-18 10.22.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2df415d2-3bb0-05b4-fb96-7efb99ac69d0.png)



#### 注意事項

どのカテゴリーが共起するか（同じコメントから発言されるか）を可視化することができますが事後の設備故障・インシデント・解約とどのワードの関係性が強いかはModeler本来の機能で確認します。
（データ検査、平均値ノード、クロス集計、統計モデル）

コンセプトの関係性は[マップ]ボタンで表示することができます。

![スクリーンショット 2024-12-24 8.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d0000f6e-aa34-fd6c-397c-1919c5ac33d0.png)


## 4.参考情報

#### Python連携によるテキストマイニング

https://qiita.com/harrowharrow16/items/248ff8fe3879b63e7ae3

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/items/4bf813e6cba84b2a1008
p5.js でおえかきしよう！

[ユニークビジョン株式会社 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/uniquevision) 16日目の記事です！

# 年に一度のお祭り、なにか楽しいことしたい！
というわけで、コンピュータでお絵描きをします！
[p5.js](https://p5js.org/) という JavaScript ライブラリを使います。
# できました！
https://openprocessing.org/sketch/2495717

クリスマスっぽい！！かも、、

## ソースコード
```typescript:sketch.ts
import p5 from "p5";

const sketch = (p: p5) => {
	let size: number;
	let cellSize: number;
	let distMax: number;
	let diamMax: number;
	const GRID_SIZE = 50;
	const FRAME_RATE = 24;
	const RED = p.color(236, 31, 40, 80);
	const GREEN = p.color(58, 141, 49, 80);

	p.setup = () => {
		size = Math.min(p.windowWidth, p.windowHeight);
		cellSize = size / GRID_SIZE;
		distMax = p.dist(0, 0, size / 2, size / 2);
		diamMax = cellSize * 3;

		p.createCanvas(size, size);
		p.frameRate(FRAME_RATE);
		p.noStroke();
	};

	p.draw = () => {
		p.blendMode(p.BLEND);
		p.background(0, 80);
		p.blendMode(p.SCREEN);

		for (let row = 0; row < GRID_SIZE; ++row) {
			const centerY = (row + 0.5) * cellSize;
			for (let col = 0; col < GRID_SIZE; ++col) {
				const centerX = (col + 0.5) * cellSize;
				const dist = p.dist(centerX, centerY, size / 2, size / 2);
				const diameter = p.map(dist, 0, distMax, 0, diamMax);
				p.fill(chooseColor(centerX, centerY));
				p.circle(centerX, centerY, diameter);
			}
		}
	};

	function chooseColor(x: number, y: number) {
		const d = p.dist(x, y, size / 2, size / 2);
		const t = p.frameCount * 0.1;
		const n = p.noise(d * 0.01 + p.noise(x * 0.01, y * 0.01) - t);
		if (n < 0.35) {
			return RED;
		}
		if (n > 0.65) {
			return GREEN;
		}
		return p.color(0);
	}
};

new p5(sketch);
```

（使い捨てのコード感が若干出ちゃってますが、ちょっとしたお絵描き用のコーディングスタイルってのがあっていいはずです！）

円の色を決めるところ（`chooseColor()`）で、noise 関数というのを使っています。

## Perlin ノイズ
p5.js の noise 関数は、Perlin ノイズを生成する関数です。通常の乱数生成と異なり、入力に対して「連続で滑らかな」関数です。noise 関数を使うことで、より自然なランダムを作品に取り入れることができます。
応用範囲は広く、Minecraft のような地形生成に使えることでも有名ですね。

```typescript
function chooseColor(x: number, y: number) {
	const d = p.dist(x, y, size / 2, size / 2);
	const t = p.frameCount * 0.1;
	const n = p.noise(d * 0.01 + p.noise(x * 0.01, y * 0.01) - t);
	if (n < 0.35) {
		return RED;
	}
	if (n > 0.65) {
		return GREEN;
	}
	return p.color(0);
}
```
今回は、canvas の中心からの距離`d`と、経過フレーム数`t`に適当な係数をかけて足したものを noise 関数の入力としてます。noise 関数は 0～1 の値を取り、値の範囲で赤色と緑色を出し分けているわけです。
ただ、それだけだと対称性を持ちすぎてやや退屈だったので、x 座標と y 座標を入力とした noise である `p.noise(x * 0.01, y * 0.01)` を、noise 関数の入力に噛ませてみました。

こんなふうに、noise 関数を取り入れたり、使い方にひと工夫を入れるだけで印象がガラッと変わったものになって面白いです。OpenProcessing でソースコードを編集できるので、係数の値をいじったり、sin 関数を噛ませてみたり... などぜひいろいろ遊んでみてください！

# p5.js でおえかきしてみたい人へ
- [p5.js Web Editor](https://editor.p5js.org/)というのがあり、気軽に始められます！
- ローカルにモダンで快適な環境を構築したい場合は、[Bun で p5.js の開発環境を構築する](https://qiita.com/shinjikuriy/items/45b1dbcb8448df291faf)という記事が参考になります

# 感想
素朴なアイデアを思いついて、実装して、動かして、そのフィードバックをもとにまたアイデアを考えて... のサイクルが楽しかったです！

いま見返したら途中経過のこっちのほうが好きかもしれない...
https://openprocessing.org/sketch/2495735
ショート動画でクイックに知る！ Smart Agent Advisorとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/29922c36-6bd3-18ad-cb42-bb9d8a1ceb85.png)

# はじめに

みなさん、IBM Videoというサイトをご存知でしょうか？
IBMが提供する製品をショート動画でわかりやすくご紹介している動画サイトです。
* スキルアップしたくてもなかなか時間が取れない
* 気になる製品があるけど、マニュアルを読んで理解するのはきつい
* 製品の特徴やメリットをクイックに知りたい

という方には、うってつけの動画を提供するサイトです。
興味のある方はぜひご覧いただければと思います。

# 今回ご紹介する動画へのリンク

[Smart Agent Advisorデモ〜コンタクトセンターにおけるオペレーター支援〜](https://video.ibm.com/playlist/645386/video/131375265)

# Smart Agent Advisorとは

## 概要
このソリューションは、Watson Discoveryを活用したスマートエージェントアドバイザーのデモを通じて、アウトバウンドコール業務の効率化と顧客対応力の向上を支援します。

特に、通信サービスプロバイダーのケーブルテレビキャンペーンを例に、エージェントが顧客の関心を引き出し、最適な情報提供を行う方法を示しています。

## デモの流れと特徴

### 課題認識

* 通話後すぐに断られるケースが多い。
* エージェントは押し売りのように感じられ、顧客の反応に応じた柔軟な対応が困難。

### 応答例と改善策

* 忙しい顧客へのクッション言葉（例：「お忙しいところ、大変申し訳ありません」）や返答ガイドを提示。
* 興味を示す発言（例：「ゴルフもあるの?」）に対して即座に詳細情報を提供。

### 対話の展開

* お客様の発言に基づく関心ポイントの分析と追加情報の提示（例：ゴルフレッスンや限定コンテンツの紹介）。
* 不安や疑問（例：「キャンセルは可能?」）に対して、適切なガイドをリアルタイムで提示。

### 成果

* 最初は無関心だった顧客が、具体的な興味を示すようになり、最終的には無料体験の申し込みを決定。

# まとめ

このソリューションは、リアルタイム分析とガイド提供によりエージェントの応対力を向上させ、顧客との会話をスムーズに進める支援をします。

興味や疑問に即座に対応することで、顧客の関心を引き出し、購買意欲を高める効果が期待されます。

# 参考

Smart Agent Advisorデモ〜コンタクトセンターにおけるオペレーター支援〜

https://video.ibm.com/playlist/645386/video/131375265
上流工程と下流工程って結局どっちが立場が上？

こんにちは、Naotoです。Ψ

最近、多種多様な方が出席する飲み会で、表題の件について議論が盛り上がったので、投稿したいと思います。  
皆さんは上流と下流、どちらで業務をされていますか？  
フルスタックな人は「どちらもやっています」と答えるかもしれませんね。  

まずは前提知識として「上流工程と下流工程」について簡単に整理してみましょう。

---

### 上流工程と下流工程のイメージ

- **上流工程**: 要件整理やプロジェクト計画など、いわば「コンサルタント的」なイメージ。
- **下流工程**: 実装やテストなど、エンジニアリング寄りのイメージ。

#### 簡単にまとめると
- **上流工程**: 計画・設計段階。ビジネス理解とコミュニケーションが重要。
- **下流工程**: 実装・テスト段階。技術的スキルと実行力が重要。

---

## 🟢 上流工程

### **目的**
プロジェクトの方向性や全体設計を決定し、基盤を築く段階。

### **主な作業**
- **要件定義**:
  - 顧客やステークホルダーの要求を整理し、仕様を明確化。
- **基本設計**:
  - 要件に基づいてシステム全体の構造を設計。
- **プロジェクト計画**
  - スケジュールやコスト、人員配置を計画。

### **必要なスキル**
- **ビジネス理解力**: 業務知識や市場動向の把握。
- **コミュニケーション能力**: ステークホルダーとの調整。
- **分析・設計スキル**: 抽象的な要求を具体化する能力。

### **特徴**
- 抽象的な作業が中心で、不確定要素が多い。
- 成果物はドキュメント形式が主流。

---

## 🔴 下流工程

### **目的**
上流工程で決定した設計を具体化し、システムを構築する段階。

### **主な作業**
- **詳細設計**
  - 基本設計を基に、プログラム単位の詳細設計を行う。
- **実装（プログラミング）**
  - 詳細設計に基づきコードを作成。
- **テスト**
  - 単体テスト、結合テスト、システムテストなどを実施。
- **運用・保守**
  - システムの運用やトラブル対応。

### **必要なスキル**
- **プログラミング能力**: 実装技術。
- **テスト・デバッグスキル**: 正確性と問題発見能力。
- **問題解決能力**: 障害対応や改善提案の能力。

### **特徴**
- 実務作業が中心で、成果が目に見えやすい。
- 技術的なスキルが求められる。

---

## 🔄 上流工程と下流工程の関係性

- **連携の重要性**
  上流の曖昧な仕様は、下流のトラブルや手戻りにつながる。
- **役割の分離と共有**
  大規模プロジェクトでは分業が一般的だが、情報共有と密なコミュニケーションが成功の鍵。
- **スキルセットの違い**
  上流は抽象化や分析力、下流は具体化や実行力が必要。

---

## 「上流工程 vs 下流工程」の本題

結論から言うと、どちらが立場が上ということはありません。  
なぜなら、1つのシステムを作るために上流工程と下流工程の両方が不可欠だからです。

### **それぞれの重要性**
- 上流は要件を決め、クライアントとの調整を行う。
- 下流はその要件に基づいてシステムを構築し、場合によっては改善提案も行う。

どちらも重要で、欠けてしまえばシステムを完成させることはできません。

---

## 両方を経験する意義

上流だけ、下流だけをやりたいという考えではなく、**両方を経験すること**が重要だと思います。  
なぜなら、互いの大変さを理解することで、立場に関する議論が生じる余地がなくなり、協力して良いシステムを作ることに集中できるからです。

キャリア形成にも影響が出る部分かと思いますが、
どちらも経験した上で、自分が力を発揮できる部分でキャリアを築くのが良いと私は思います。

---

## 飲み会での議論を振り返って

- **エンジニア目線**: 「上流の人は現場を知らない」と不満を持つ人も。
- **コンサル目線**: 「下流は手を動かすだけだから簡単だろう」と軽視する人も。

お互いに誤解があるのは事実ですが、それ以上に共通していたのは、  
「良いシステムを作りたい」「プロジェクトを成功させたい」という想いでした。

## まとめ

上流工程も下流工程も、それぞれの役割を全うし、共存していくことが大切だとお話を聞いていて感じました。  
これからも良いシステムを作るために、お互いを理解し協力していく未来が続くと信じています。AIも本領を見せてきてますし尚更ですね！

皆さんは上流工程と下流工程についてどう考えますか？  
ぜひコメントや意見をお聞かせください！  
もしこの記事が面白いと思ったら、グッドボタンをお願いいたします！ 😊
PHPカンファレンス実行委員を経験して

[GMOペパボエンジニア Advent Calendar 2024](https://adventar.org/calendars/10317)の24日目の記事です。
23日目の記事は[どすこい](https://x.com/doskoi64)さんの[Difyワークフローを繋ぐSlackBotをgoで作った話](https://zenn.dev/ctk64/articles/f7e6cf44bf4be7)でした！

# はじめに
[PHPカンファレンス 2024](https://phpcon.php.gr.jp/2024/)に実行委員として参加してきました。
思えば、初めてスタッフをした時にネットで体験記が見つからず、不安でした。
この記事で皆さんのスタッフ応募の一助になればと思います。

# PHPカンファレンスについて
テックカンファレンス全般に言えることだとは思いますが、運営側の想いとしては「コミュニティに貢献したい」、「もっと皆に知って便利に使ってもらいたい」という愛が紡がれていっています。
このあたりはFindyさんの記事がものすごく良いです。
[四半世紀もの間、受け継がれてきたバトン。PHPカンファレンスの歴代委員長が歩みを振り返る](https://findy-code.io/engineer-lab/phpcon)

# 事前準備
当日スタッフとして参加した時には、事前MTG、前日準備、当日運営の3日間だけしか携われませんでした。
しかし、実行委員となると半年前から2週間に1回MTGを行います。
MTGで話すことは、全体のスケジュールや各担当決め、スポンサープランやスピーカーの採択など多岐に渡ります。
私はスピーカー担当だったため、スピーカー担当のマニュアルやシフト表、受付表の作成(前年度を最大限活かした)を行いました。

# 事前MTG
開催数週間前に都内某所で当日スタッフ、実行委員を集めて事前MTGをします。
事前MTGでは、各担当ごとの顔合わせや当日の段取りを打ち合わせます。

# 前日準備
前日準備では、各展示ホールへ机や椅子、演台を設置します。
スポンサーブースの設置や、来場者へ配る配布物の封入も行います。
封入作業はトートバックに配布物をひたすら詰めます。その数、1300。

この何も設置されていない空間が数時間後に
![PXL_20241221_045109703.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871802/33a21ea3-c32c-f1ac-2317-8f4e274848de.jpeg)
![PXL_20241221_045105355.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871802/173a3311-077c-0985-d4ee-d7580030c542.jpeg)

ここまで設営されます。
![PXL_20241221_091509896.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871802/e63f0aa3-3e89-0d32-07a6-69e49daa4583.jpeg)
![PXL_20241221_091505004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871802/6cf1d9ff-916d-7012-921f-356108aa5e2f.jpeg)

# 当日運営
当日の朝は07:45集合と早いです。
スポンサー入場までの間にスポンサー受付の設置、前日準備できない展示室の設営と慌ただしく準備をします。
一般来場者の入場が始まるまではひたすら準備、始まったあとは各種対応をします

私の担当のスピーカー受付では、スピーカーの方々に受付をしてもらいます。
その際にTシャツ、水、ネームプレートを渡し、登壇の際の呼び方を伺い、情報を管理しているスプシに記載します。
午前中に大半のスピーカーの方が受付をしてくださるため、午前中が忙しいですが、その後も行方不明スピーカー(登壇会場に来ていない)の捜索もします。

各スタッフは常に裏方で作業をしているかというと、そうではなく、観たいセッションの際はシフトの調整をしていますし、参加者としても楽しめます。
「スタッフも楽しむカンファレンス」がコンセプトでもありました。

# 懇親会
タイムテーブル最後のLT大会~クロージングの間に、スタッフは片付けや懇親会の設営に勤しみます。
懇親会では、スピーカー、スポンサー、スタッフ、懇親会申込者が入り乱れてお酒や料理を楽しみながら会話をします。
スピーカーの方と登壇内容のディスカッションをしたり、たまたま隣になった方と使用している技術について語り合ったりと楽しい場です。

# スタッフ打ち上げ
懇親会の後はスタッフのみの打ち上げがあります。
話す機会のなかった方と様々な話をします。
私の卓では、ソフトウェア設計とLintについて二時間くらい会話していました。

## 実行委員を終えて
ほどよい疲労感と満足感が心地よいです。そして二日酔い気味の翌日を迎えられました。
翌日には「もうしばらくお酒はいいや」となるのに、その次の日には「お酒飲みたい」となるのもお酒の魅力ですね。

テックカンファレンスの開催には、多くの人が協力して企画していることを感じられ、感謝しかありません。
また、懇親会やスタッフ打ち上げで色々な方と交流できたことは、よい刺激になると改めて感じました。

# 最後に
参加者の中には、スピーカー兼スタッフの方もいました。
その方々に刺激を受け・・・PHPerKaigiのプロポーザル出しました！
~~この記事を読んでくださっている関係者の方は忖度をしてください。~~
今後はスタッフだけでなく、登壇も通して貢献できればと思います！
SFDX Data Move Utility 



+ [SFDX データ移動ユーティリティ](https://help.sfdmu.com/)

SFDX データ移動ユーティリティ (SFDMU) は、最先端の最新のSalesforce データ移行ソリューションです。
わずか数分で、Scratch または Sandbox に高品質のレコードが追加されます。

+ [SFDX Data Move Utility(SFDMU)によるファイルの移行](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KAUhf)

:::note
このツールはsandboxやスクラッチOrgに対するデータ転送を目的としているので、大規模な組織の移行には向いてないようなことが書かれています。

どうもクライアントPCのメモリなどに影響を受けるみたいです。

However, it's important to be aware that SFDMU is designed to transfer only small to medium data volumes to seed sandboxes or scratch orgs with limited demo data needed for developers. It is highly NOT recommended to use SFDMU for transferring entire large orgs.

https://help.sfdmu.com/faq/bulk-api-query-management/what-are-the-limitations-on-data-volume-processing

資料を見ると色んな機能がありそうです。

ファイルは中間生成物なしに、直接移行するみたいですね

It supports direct Org-to-Org data migration without having to deal with annoying intermediate CSV files.
:::

# 関連資料

+ [Salesforce → Salesforceのデータ転送を楽にする？脱データローダー？？ SFDMUを試してみる](https://qiita.com/takaHAL/items/0d6978269af28eaaf4bd)
+ [Salesforce組織間データ移行ツール SFDX Data Move Utility (SFDMU)の使い方](https://note.co-meeting.co.jp/n/n126171ad4e9f)


# エラー

+ [SFDMU Installation issue](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Tiy7X)

Nodeの設定の問題かとは思うけど、ずばり説明できない

:::note alert
CannotFindNodeExecutable: Cannot locate node executable.
    Code: CannotFindNodeExecutable
:::
tRPCを使ってみる

# tRPCとは？
TypeScript Remote Procedure Callの略
tRPCを利用することで、TypeScriptで定義した型をフロントエンドとバックエンドの双方で共有し、API通信を一貫した型安全性のもとに行える。結果として、IDEの自動補完や型推論のサポートをフルに活用しつつ、クライアントとサーバー間のデータ構造の不一致やバグを未然に防ぎ、効率的な開発を実現できる。

# 実際に使ってみる
今回はNext.js, trpc, zodを利用してモノレポ構成で利用する。

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

`npm install @trpc/server@next @trpc/client@next @trpc/react-query@next zod`

## サーバーサイドの実装
### trpcのルーターを定義する
```trpc/router.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

const t = initTRPC.create();

export const appRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => {
      return { message: `Hello, ${input.name}!` };
    }),
});

// クライアント用の型
export type AppRouter = typeof appRouter;

```

### trpcエンドポイントの定義
```ts:app/api/trpc/[trpc]/route.ts
import { NextRequest } from 'next/server';
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
import { appRouter } from '@/trpc/router';

export const runtime = 'edge'; // Edge Runtime で動かす場合 (任意)

const handler = (req: NextRequest) => {
  return fetchRequestHandler({
    router: appRouter,
    req,
    endpoint: '/api/trpc',
    createContext: () => ({}),
  });
};

export { handler as GET, handler as POST };

```
## クライアントサイドの実装

### trpcクライアントの作成
```utils/trpcClient.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '@/trpc/router';

export const trpcClient = createTRPCProxyClient<AppRouter>({
  links: [
    httpBatchLink({
      url: '/api/trpc', // tRPC のエンドポイント
    }),
  ],
});

```

### 画面の作成
```tsx:app/page.tsx
'use client';

import React, { useState } from 'react';
import { trpcClient } from '@/utils/trpcClient';

export default function Home() {
  const [name, setName] = useState('Alice');
  const [result, setResult] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  const handleClick = async () => {
    setLoading(true);
    try {
      // tRPC の greeting メソッドを呼び出し
      const response = await trpcClient.greeting.query({ name });
      setResult(response.message);
    } catch (error) {
      console.error(error);
      setResult('エラーが発生しました');
    } finally {
      setLoading(false);
    }
  };

  return (
    <main style={{ padding: '1rem' }}>
      <h1>tRPC + Next.js + Zod Example</h1>
      <div style={{ marginBottom: '0.5rem' }}>
        <input
          type="text"
          value={name}
          placeholder="Enter your name"
          onChange={(e) => setName(e.target.value)}
        />
      </div>
      <button onClick={handleClick} disabled={loading}>
        {loading ? 'Loading...' : 'Get Greeting'}
      </button>
      <div style={{ marginTop: '1rem' }}>
        {result && <p>{result}</p>}
      </div>
    </main>
  );
}
```

ブラウザからページを開き適当な文字を入力してGet Greetingを押すとapiが呼び出され入力した文字列が表示される。
これでフロントエンドとバックエンドの双方で型を共有しIDEの自動補完やAPI通信を型安全に行える。
FON2601Eを手に入れた

12/21に秋葉原のHardOffでFON2601Eを330円で購入しました。箱入りでアダプタ付のほぼ新品でした。

![20241228074815639 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/0375d811-9998-c490-b704-8fda637bd081.jpeg)

10年くらい前から欲しかったのですが、なかなか出てきませんでした。サンタさんからのクリスマスプレゼントかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/b7e4f14b-d30c-ebd5-a08d-84ec271478fc.png)

下がFON2305E,FON2405Eで上がFON2412J,FON2601Eです。FON2405Eが一番生産数が多かったのではないかと思われます。

SOCはRT3052,RT3052,RT5350,MT7620Aです。すべてアーキテクチャはMIPS 24Kです。Ralinkの頃には、74KなSOCも作っていましたが、Mediatekになってからは24Kと1004Kの製品を作っています。

FON2305E,FON2405E,FON2412JはFlashが小さいので、8M Flashに貼り代えています。

RT3052は5Vのアダプタの製品が多かったのですがMT7620は12Vのものが多いです。FON2601も12Vでごついアダプタです。

GPS,JJY NTP ST1はFON2405Eで動かしています。[おうちモニター](https://qiita.com/yamori813/items/776ce00bedb558450490)はFON2412Jで動かしています。

FON2601EはFlash 16M,メモリ128MでUSBのコネクタも付いています。

USBコネクタに印がありFON2601EはFoxcon製のようです。FoxconはUSBコネクタからモジュールの製造まで非常に広範囲に事業を行ってるのですね。

シリアルの穴はあり、めずらしいVCC,RX,TX,GNDになっています。

MT7620Aは100MのEthernet Switchが内蔵ですがGMACも入っていて、RTL8211Eで白いほうのRJ45はGigaになっています。

FreeBSD/mipsのMediatek/RalinkはZRouterのrayがいじっていたころのhintsベースからユーゴスラビアのStanislav GalabovさんによってFDTベースで再実装されたものです。非常に面白い実装になっていて、安定していて良い実装です。

MT7620なターゲットはZRouterにすでにいくつかあるのでboardsの下のファイルは適当なものをコピーします。dtsファイルはopenwrtからコピーしてFreeBSD用に修正しました。

u-bootは一般的なimageではなくヘッダーが32バイト大きくなっていたので、ツールを改修してboard.mkファイルでUBOOT_FOXCONPADを指定するようにしました。

FreeBSDのコードは12-STABLEにいくつか修正を加えた以下のレポジトリを使っています。

https://github.com/ZRouter/freebsd-src/tree/zrouter_yamori813

FreeBSD/mipsは13までコードは入っていて14で消されましたが、13はclangになって、kernelが起動できなくなったので12が最終リースです。

SPIのドライバーは[私がチューニング](https://qiita.com/yamori813/items/9920d84783fdea8ee98e)しました。

https://dmesgd.nycbug.org/index.cgi?do=view&id=8105

ZRouterを始めたころは、USBのサポートがあればいろいろ出来ると思っていましたが、flashだけで動くのがZRouterの良いところなので、結局あまり使っていません。

NetBSDにはZRouterで利用しているような機能がないので、USB HDにrootfsをインストールして使っています。

RT3052はRalinkの初めての24K SOCで結構発熱して故障率も高かったのですが、MT7620は発熱は少な目です。

リモートからのflashのアップデート(reupgrade)が失敗するので調べたら、[以前にも直して](https://qiita.com/yamori813/items/0366609cb5ef78b1873d)いました。

FreeBSDは12で終ってしまいましたが、古いシステムでもシンプルで限定的な使い方であれば、致命的な脆弱性は発生しないと思うので、使い続けたいと思っています。
DJプレイをProcessingでビジュアライズしてVJごっこ

# 概要
DJをしている最中に、映像や光なども自分で操りたくなるタイミングが人間誰しもあると思います。
ちょうど最近Processingで遊んでいたので、せっかくならとDJコントローラのMIDI信号をProcessingで処理してVJごっこをしてみたいと思います。

https://qiita.com/watanabe_kippei/items/00f0f002030f80e089aa

2年前に、Pioneer社製のDDJ-400というDJコントローラーから操作情報を取り出すプログラムは書いていました。
今回はそれをさらにアップグレードしてビジュアライズしていきます。

## コード

今回使用した、ビジュアライズ用のメソッド（`divideRect()`）はこちらの記事から拝借しました。
https://note.com/outburst/n/na98a31f0b2cb

行っていることはシンプルで、サーバーを立てて入力を受け付けるごとにフラクタル図形を描画するだけです。
暫定的に、受け付けた入力の文字列が「`action`」であれば描画を実行する実装になっています。
ここを後述する入力用のpythonスクリプト側で上手いこと調整して、数字の羅列ではなくいい感じの操作名を受け付けられると良さそうですが、体力が尽きたのでまたの機会にします。

```visualize.pde
import processing.net.*;

int port = 50000; // 適当なポート番号を設定
Server server;

void setup() {
  server = new Server(this, port);
  println("server address: " + server.ip()); // IPアドレスを出力
  
  size(700, 700);
  stroke(2);
  noFill();
}

void draw() {
  Client client = server.available();
  if (client !=null) {
    String action = client.readString();
    if (action != null) {
      background(250);
      divideRect(10, 10, width-20, height-20, 8);
    } 
  }
}

//(x座標, y座標, 幅, 高さ, 再帰回数)
void divideRect(float x, float y, float w, float h, int n) { 
  rect(x, y, w, h);

  n--;
  
  if (n>=0) {   
    //幅が高さよりも大きい、または幅と高さが等しい場合
    if (w>=h) {
      //ランダムな値を得る
      float randomW = random(w*0.1, w*0.9);
      //ランダムな値から2つのdivideRectを呼び出す
      divideRect(x, y, randomW, h, n);    //左側の四角形
      divideRect(x+randomW, y, w-randomW, h, n);    //右側の四角形
    }

    //幅が高さよりも小さい場合
    if (w<h) {
      float randomH = random(h*0.1, h*0.9);
      divideRect(x, y, w, randomH, n);    //上側の四角形
      divideRect(x, y+randomH, w, h-randomH, n);    //下側の四角形
    }
  }
}
```

DJコントローラからMIDI信号を取得してソケットサーバー（Processing側で立てている）にデータを投げるpythonコード。
DJコントローラーの操作情報は下記のように、数字の羅列になっているので一旦「`action`」という文字列を固定で送るようにしている。
```
[[[151, 53, 127, 0], 1062196]]
[[[151, 54, 127, 0], 1062364]]
[[[151, 53, 0, 0], 1062396]]
[[[151, 54, 0, 0], 1062446]]
[[[151, 55, 127, 0], 1062667]]
[[[148, 71, 0, 0], 1062797]]
...
```

```observer.py
import socket
from pygame import midi as m

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 50000))
m.init()
i = m.Input(1)

try:
  while True:
    if i.poll():
      midi_input = i.read(1)
      print(midi_input)
      client.send("action".encode("utf-8"))
except KeyboardInterrupt:
    print("\nTerminating Observation...")
finally:
    client.close()
    i.close()

```

## 結果

DJコントローラーを操作してみた時の挙動はこんな感じです。

![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2969791/cfed9993-1896-f727-a9ec-854a301d0f73.gif)

操作ごとにフラクタルが描画されていることがわかります。

これによって雰囲気だけでもVJを感じることができましたが、とても素朴な見た目になっているので、
音の波形に合わせて描画内容を変えたりしてみたいです。

また、Processingよりも高速に動作するアプリがあるらしいのでそちらも使ってみたいですね。
最後までお付き合いいただいてありがとうございました。
声でつながるAIとの対談: 挿入曲 #10 - Jazz, Soul, Funk, Piano【Suno AIでつくった楽曲】 v4 & Custom Mode: On 【動画 3分21秒】【YouTubeチャンネルからの転記です】

この記事は、わたしの[YouTubeチャンネル](https://bit.ly/Yamanaka-YouTube "Living without things. 持たない生き方 手放す生き方")にある公開動画を転記しております。
( どこかのタイミングで、プログラミング-Google Apps Script or iPaaS-Zapier をつかって自動転記させる予定です )

転記のための時間コストを少なくしたいので、文字装飾( Markdown記法 )を極力つかわずに書いております。

こちらが動画内容です👇

***

![01 YouTubeサムネイル & 再生中の画像 Suno AI _ 声でつながるAIとの対談_ 挿入曲 #10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386308/0e9b2617-2b10-7d80-c73e-c6f143ef5ec4.png)




* # 動画URL
    * https://youtu.be/1N5QzsbUOxs

<br>

* # 動画タイトル
    * 声でつながるAIとの対談: 挿入曲 #10 - Jazz, Soul, Funk, Piano【Suno AIでつくった楽曲】 v4 & Custom Mode: On 【動画 3分21秒】

<br>

* # 動画の説明欄(一部を抜粋)

📅撮影日 = 2024-12-19(木)

Suno AIとは、文章から音楽を生成することができるAI( Text-to-Music-AI )です。
わたしは、2024-04-02(火)に初めてSuno AIで有償プランを契約してから、時々楽曲をつくって遊んでいます。

🎦【Suno AI】文章から音楽を生成するAI( Text-to-Music-AI )で、3分間で2曲、6分間で4曲作りました【試聴可能】1)伴侶の曲 2)税理士の曲【動画 16分11秒】
https://youtu.be/QKfhk4HgQ_g

🎦“Suno AIでつくった楽曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe

🎦“効果的にSuno AIを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


今回は、Suno AIでつくった曲を WAV で出力してから、動画編集いたしました。

“声でつながるAIとの対談”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghOpTHU0rmfXSgjqV1_j6Eao
👆の挿入曲としてつかう予定です。

ぜひ聴いてみてください。
そして、ぜひみなさんも、ご自身の対談、番組、コンテンツのために楽曲をつくってみてください！

作曲日:
2024-12-04(水)

Suno AI 契約の種類:
Pro Plan

Suno AI Version:
v4

楽曲の正式名称:
声でつながるAIとの対談: 挿入曲 #10 - AI Voice Talks: Minimal Melody

Suno AI Library URL:
https://bit.ly/AI-Voice-Talks-Minimal-Melody-10

Custom Mode: On

Audio Inputs: Not Used

Instrumental:


---


Suno AIへの指示文章( プロンプト/Prompt ): Custom Modeの場合は”Style of Music”を指定します。


🇬🇧English

[Jazz][Moog][Piano][220 Seconds][Break][Outro]


🇯🇵日本語訳

[ジャズ][モーグ(ムーグ)][ピアノ][220秒][ブレイク][アウトロ]


---


Suno AI 公式URL
https://accounts.suno.ai


---


🎥この動画と関連が強いわたしの動画
・“Suno AIでつくった楽曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe


・“効果的にSuno AIを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


・“声でつながるAIとの対談”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghOpTHU0rmfXSgjqV1_j6Eao


🎥Shortened URL for this video | この動画の短縮URL
https://bit.ly/3Pa9zeB