OmniAICreator/Qiita-1.07M huggingface dataset:
情報伝達手段は変わらないことが良いのでは？


**これからの情報伝達手段の在り方について考えてみよう！**

せっかくなのでこのテーマを考えてみました。

なんかただの感想文みたいになってしまいましたが、よろしければお読みください。

## 伝達手段の進化
昔の遠方にいる人への伝達手段で思い描くのは・・・・


・
・
・
・
・
・
・


狼煙

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287130/b074b220-6723-2e80-185a-0c1f5aa21f5c.png)




ちょっと昔すぎますかね？


（笑）



今では「狼煙」ではなく「スマホ」で伝達するのではないでしょうか。

様々な便利ツールが生まれることで、ただ便利になるだけでなく伝達手段は多様化してきています。

電話に

メールに

手紙に

LINEに


私が大学生のときにはLINEなんてなかった気がします。しかし今では当たり前のように使っている人が多くいらっしゃるのではないでしょうか？

おそらく今後さらに便利な世の中になっていくのではないかと考えます。

しかしあえて時代と逆行するようなことを言います。


**「情報伝達手段は、現状から大きく変わらないことが望まれる。」**

さて、その真意は。。


## とある個人経営企業のDX

### 問題点

以前とある個人経営の企業様にDXの相談員として関わらせていただいたことがあります。

そのとき挙がった問題の１つに

**「お客さんから入る注文方法は多岐にわたることが問題」**

でわ、

なぜ問題となるのでしょうか。


お客様からの注文方法としては下記のようなケースがあります。

- 電話連絡
- HPでの問い合わせ
- メール
- FAX
- たまたま会って

なんか他にもあった気がします。

これだけでも注文という入り口が５つもあります。

入り口がたくさんあることで

「この注文なんだっけ？」

「あれ、この注文伝わってないの？」

「どこに注文詳細書いてあったけ？」

など情報をうまくキャッチして扱うことができず、空中で情報が浮遊してしまう状態になってしまうそうです。
その結果、余計なコミュニケーションコストが発生したり、注文の対応を忘れてしまったりしてしまうことが問題となりました。

### 解決策

この問題を解決するためには二点考えられると思います。

１つは **「窓口を絞ること」** です。

注文を受ける窓口を絞ることで、情報の流れの複雑性が解消されます。オペレーションが取りやすくなります。

しかしこの対策は現実的でありませんでした。

なぜならば、お客様によっては

「電話しかできません」

というように、限られた情報伝達手段しか用いることができない方も少なくありませんでした。

また窓口を絞ることで、注文のきっかけが減ってしまう可能性も危惧されます。

そうなると売上に影響してきます。

さて、困った・

・
・
・

そこで考えたのは２つ目の解決策

**「情報を一箇所にまとまる仕組みづくり」**

窓口がなんであれ、必ず情報が一箇所にまとまるようするのです。

そうすることで、「わからないことがあってもここを確認すれば良い」という状態になります。


## 変わらないことが良いのでは？

今回のケースは「情報伝達手段を変えることによって、今まで情報を伝えることができていたユーザーが情報を伝える手段がなくなってしまうことがある。」という一例になります。

そのため、

**「変わらないことが良いのでは？」**


と考えるに至りました。

##進化が悪いわけではない

便利な技術はどんどん普及すれば良いと考えます。

技術はどんどん進化していくべきだと考えます。

**「変わらないことが良いのでは？」**

というと

**ずっと同じものを使い続けるべき** 

そんな風に捉えられるかもしれません。

しかしそうではなく

**「既存のものと新しいものが共存できる世界を作ることを目指す」**

これが大切ではないでしょうか。

今回の解決策になった

**「情報を一箇所にまとまる仕組みづくり」**

これも大きな鍵になると考えます。

インターフェースは変えずに、より機能的に、便利に。


取り残される人が出ないような、皆にとって優しい世界が良いですよね。

そんな風に思いました。

以上！
JSのEventEmitterについて調べる

# はじめに
MSAを基盤としてサービスを構成するために必要なのはイベント駆動アーキテクチャです。これはイベントを登録し、そのイベントに対する応答を返すことでサービスの結合度を下げることができます。現在制作中のトイプロジェクトでは、エラーハンドリングやロギング処理などをイベントベースで作成していく予定です。

シングルスレッドはプロセス内で1つのスレッドが1つのリクエストのみを処理し、このとき他のリクエストを同時に実行できないため、**シングルスレッドブロッキングモデル**と呼ばれます。Node.jsはシングルスレッドですが、ノンブロッキングモデルであり、クラスタリングを通じてプロセスをフォークしマルチプロセシングを利用することができます。

# イベント駆動とは？
イベントが発生したときに予め指定した作業を実行することを意味します。JavaScriptでは`addEventListener`でアクションを登録し、イベントが発生したときに予め登録したコールバック関数を実行する方式で動作します。

~~~javascript
dom.addEventListener('click', () => {
    console.log("コールバック実行");
});

router.get('/getdata', (req, res, next) => {
    // getdataでリクエストが入ってきたときにcallbackを処理
});
~~~

https://www.geeksforgeeks.org/libuv-in-node-js/

Node.jsの内部構造はJavaScriptとC++言語で構成されています。このうちLibuvは100% C++で構成されたライブラリです。V8エンジンはJavaScriptをC++に変換します。Node.jsで動作するイベントループはLibuv内で実装されていますが、**Node.jsはシングルスレッドであるため、1つのイベントループを持ち、1つのスレッドがすべてを処理します。**

## イベントループの内部構造
イベントループは複数のフェーズを持ち、それぞれが独自のQueueを持ちます。また、ラウンドロビン方式でノードプロセスが終了するまで一定の規則に従って複数のフェーズを巡回します。**FIFO(FIRST IN FIRST OUT)**順序でコールバック関数を処理します。

## ノンブロッキングIO
Node.jsではブロッキング作業をバックグラウンドで実行しますが、実際にバックグラウンドで実行される一部の機能はマルチスレッドでも実行されます。**Libuvのスレッドプールはカーネルがサポートしていない作業を実行します。**つまり、Libuvのスレッドプールはマルチスレッドです。

## イベントループ内の6つのフェーズ
- timers
イベントループがフェーズを巡回し、timer段階に達すると処理可能なtimer関数を確認し、コールバック関数を実行します。
- pending callback
I/O作業が完了すると、I/O作業ブロック内のコールバック関数をpoll段階のキューに渡します。また、TCPエラーなどのシステム作業のコールバックを実行します。
- idle, prepare
- poll
I/Oに関連するコールバックを除くすべてのコールバックを実行します。timer段階での実行時間制御を担当します。
- check
setImmediate()のコールバック関数が実行されます。もし、poll段階がアイドル状態であれば、pollイベントを待たずにcheck段階に移行します。
- close callback
closeイベントに対応するコールバック関数を実行します。

以下の例では、もしイベントループが回っている時点がtimerであればsetTimeoutが先に、timerを過ぎていればsetImmediateのコールバック関数が先に実行されます。

~~~javascript
setTimeout(() => {
  console.log('timeout');
}, 0);

setImmediate(() => {
  console.log('immediate');
});
~~~

# イベント駆動プログラミングとは？
イベント駆動プログラミングは複数のイベントの発生を同期させ、プログラムをできるだけ簡単にするために使用されます。

イベントトリガーを受信する関数をobserverと呼びます。これはイベントが発生したときにトリガーされます。これらのイベントは'events'モジュールおよび**EventEmitter**クラスを通じてアクセスできます。

# イベント駆動プログラミングの原則

- イベントを処理するための機能の集合であり、実装によってブロッキングまたはノンブロッキングになることがあります。
- 登録された関数をイベントにバインドします。
- 登録されたイベントが受信されるとイベントループは新しいイベントをポーリングし、一致するイベントハンドラーを呼び出します。

~~~javascript
// 'events'モジュールをインポートします。
const events = require('events');

// EventEmitterオブジェクトをインスタンス化します。
const eventEmitter = new events.EventEmitter();

// イベントに関連するハンドラー
const connectHandler = function connected() {
    console.log('Connection established.');

    // 該当するイベントをトリガーします。
    eventEmitter.emit('data_received');
}

// イベントをハンドラーにバインドします。
eventEmitter.on('connection', connectHandler);

// データ受信イベントをバインドします。
eventEmitter.on('data_received', function () {
    console.log('Data Transfer Successful.');
});

// connectionイベントをトリガーします。
eventEmitter.emit('connection');

console.log("Finish");
~~~

上記のコードでは、connectionというイベントを発生させ、順次マッピングされたコールバックを実行します。
ABC361をPythonで（A～D）

デンソークリエイトプログラミングコンテスト2024（AtCoder Beginner Contest 361）の回答まとめ

# A問題
```python:A
n, k, x = map(int, input().split())
a = list(map(int, input().split()))

b = a[:k] + [x] + a[k:]
print(*b)
```
# B問題
```python:B
a = list(map(int, input().split()))
b = list(map(int, input().split()))

def check(s, t):
  return s[0] < t[3] and s[1] < t[4] and s[2] < t[5]

if check(a, b) and check(b, a):
  print("Yes")
else:
  print("No")
```
# C問題
```python:C
n, k = map(int, input().split())
a = list(map(int, input().split()))

if k == n - 1:
    print(0)
    exit()

a.sort()
ans = float("inf")
for i in range(n):
    j = i + n - k - 1
    if n <= j:
        break
    ans = min(ans, a[j] - a[i])

print(ans)
```
# D問題
```python:D
from collections import deque

n = int(input())
s = list(input()) + [".", "."]
t = list(input()) + [".", "."]

if sorted(s) != sorted(t):
    print(-1)
    exit()

d = dict()
d[tuple(s)] = 0
q = deque()
q.append([0, s, n])

while q:
    c, a, space = q.popleft()
    if d[tuple(a)] < c:
        continue
    
    for i in range(n + 1):
        if i in {space, space + 1}:
            continue
        if i < space:
            nxt = a[:i] + a[space:space + 2] + a[i + 2:space] + a[i:i + 2] + a[space + 2:]
        else:
            nxt = a[:space] + a[i:i + 2] + a[space + 2:i] + a[space:space + 2] + a[i + 2:]
        if tuple(nxt) in d and d[tuple(nxt)] <= c + 1 or len(nxt) > n + 2:
            continue
        else:
            d[tuple(nxt)] = c + 1
            q.append([c + 1, nxt, i])
        
print(-1 if tuple(t) not in d else d[tuple(t)])
```
[備忘録]　キーボードについて分かったことをまとめてみた

# はじめに
こんにちは，Umamusume22です．最近．友人がキーボード制作に取り組んでいました．茶軸や青軸がどうのこうのと話していました．そこで，今回はキーボードについて調査して分かったことをまとめます．

# 備忘録[1]
#### メカニカルキーボード
- メカニカルキーボードとはタイピングしたら「カチャカチャ」と音がするタイプです．つまり，1つ1つのスイッチが独立した構造を持ったタイプです．以下の写真がメカニカルキーボード[2]ですね．電化製品屋さんに行ったら見かけますね．ちなみに私はメカニカルキーボードのタイピング音が好きです．(変態)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964975/3f302055-81af-d93e-2ae7-2803658ea211.png)



- 初期費用がかかる
- メンテナンスや故障対応が楽
- メカニカルキーボードの根幹にはスプリングと呼ばれる特殊なバネが採用されている
- スプリングの上に軸，さらに軸の上にキーキャップが被せられている
- メカニカルキーボードの主なスイッチは青軸，茶軸，赤軸
- 1つ1つ独立したボタンを持つ

#### メンブレンキーボード
次にメンブレンキーボードについて説明します．メンブレンキーボードは全体に1枚のスイッチを使用します．メカニカルキーボードと異なりそれぞれのボタンが独立していません
以下はメンブレンキーボードの写真[3]です．見た目はメカニカルキーボードと割と似ていますね．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964975/2d92bb76-36bc-a792-2f0e-6960291f996e.png)

- キーボード全体に1枚のスイッチを採用
- ラバーカップと呼ばれる柔軟性のある素材が使用されている
- キーを押すことでラバーカップが変形
- メンブレンスイッチの接点部分に触れることによって電気が流れて入力が行われる


# 最後に
今回も記事の内容が短くて申し訳ありません．
今回はキーボードのタイプを二つピックアップしてまとめました．私はmacユーザーですがタイピング中はそんなにカチャカチャ言わないです．windowsを扱うときはショートカットキーがmacと異なるので慣れるまで大変です笑
macユーザーにとってwindowsを使いこなすのが少し大変です．私だけかもしれませんが笑

ここまで記事を読んでいただきありがとございました!

※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!

# 参考文献
[1] “メカニカルキーボードの特徴と種類について　青軸に赤軸、茶軸とは？"
https://www.dospara.co.jp/5info/cts_str_peri_mecha-kb.html

[2] "【2024年】メカニカルキーボードのおすすめ26選 仕事で使いやすいモデルもラインナップ"
https://www.biccamera.com/bc/i/topics/osusume_mechanical_keyboard/index.jsp

[3] "メンブレンゲーミングキーボードTKLCRC-GMBKRGB02"
https://www.century.co.jp/racen/lineup/crc-gmbkrgb02.html
OSC信号を受信してTouchDesignerで映像を出す1

TouchDesigner（以下TD）でOSCを使用する、という記事はいくつかあったのですが、同じような使い方をしている記事を見かけなかったので書いてみます。画像が多いせいか長くなってしまったので、3回に分けて記事にします。

まず何がしたかったのかというと、照明の操作と映像の操作を同時に行いたい、というところから出発しています。

TD単体でDMXの操作もできてしまうのですが、できれば使い慣れているDoctorMXを使って映像も操作できないかと考えました。

やり方としては、DoctorMXからフェーダーを操作して流す映像を選択する。それをDoctorMXの機能でOSCにして TDに送る。 TDでOSC In CHOPを使用して、映像を選択して出力する。という流れです。
DoctorMXからOSCを送る方法については、標準機能なので割愛します。

TDの中身です。

TDを使用したことのある方はご存知だと思いますが、基本的に左側から右側に向かって流れていきます。

左側がOSC関係、真ん中が映像、右側が出力関係です。

![TD_all.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/2743324a-c12a-4fb9-a5e4-b527587dccbc.png)

左側から見ていきます。

OSC関係はこちらの動画を参考にしています。

https://www.youtube.com/watch?v=c5WxMbUVHGk


## OSC In CHOP

![スクリーンショット 2024-07-07 15.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/aa72a5f4-18f9-f8ec-1040-42d39b948a4e.png)

Network PortをDoctorMX側のOSC Outで指定した値に合わせます。

この場合は51002です。

なくても動作するようだったのですが、OSC Address Scopeで/dmxと指定します。

## Select CHOP

OSCinで512ch分送られてくるので、使用するチャンネルをselectで選びます。

![スクリーンショット 2024-07-12 19.51.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/613836d6-e59a-0893-d069-667d43a339a7.png)

今回は映像選択を481ch(TDでは0chから始まるため画像では480ch)を使用し、フェードアウトに482ch (同様に481ch)を使用します。

## Rename CHOP

そのままだとdmx○○○としか出ないので、Rename CHOPで名前を変更します。

![スクリーンショット 2024-07-12 19.58.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/18db7f43-1287-b058-497e-d386635013cc.png)

今回はMo1（映像選択用）とCross（フェードアウト用）にしました。名前がややこしくてすみません。

## Math CHOP

Mo1（映像選択用）OSCの値が0~255で来るため、今回使用する映像（黒画面も合わせて10個）の数に合わせてTo Rangeを0~10にします。

![スクリーンショット 2024-07-07 15.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/ff323da1-5177-4119-a5e0-dd5bece8cf06.png)

Cross（フェードアウト用）では0~1の値だけあれば十分なので、To Rangeを0~1に指定します。

![スクリーンショット 2024-07-12 20.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/848771/68c1c644-acc1-efd0-4790-bfd9dd211337.png)


以上でOSC関連は終わりです。次回はほとんどNoise Topのみで作った生成映像について書きます。
複合主キー

# そもそも主キーとは
- プライマリキーとも言う。primary 意味：主要な
- データベースにおいて特定のテーブル内の各レコードを一意に識別するためのもの
- 主キーは、重複する値が持てない、かつNULL値を持つことができない

# 複合主キー
- データベースのテーブルにおいて、複数の列を組み合わせて一意性を確保するために使用されるキーのこと。
- 通常、主キーはテーブル内の各行を一意に識別するために使用されますが、単一の列だけでなく複数の列を組み合わせて主キーとすることもある
Linuxの起動に毎回30秒待たされた話

# きっかけ
古いPCを再利用して運用しているUbuntu Serverが、起動時に毎回GRUBの選択画面で30秒待たされるので、解決するために調査をした。

# 原因
GRUBにはrecordfailという機能がある。

起動時にGRUBがgrubenvにrecordfail=1を設定、
正常に起動するとgrub-common.serviceがgrubenvからrecordfailを削除する。

次回起動時にrecordfailが無ければGRUBの選択画面をスキップしすぐに起動、
recordfail=1の場合はgrub-common.serviceが削除していない=起動に失敗と判断し、選択画面が表示され、リカバリモードなどに入りやすくなる。

しかし、recordfailはブート時にgrubenvへの書き込みが必要なため、環境によっては動作しない。
今回の問題は、recordfailが動作しない環境だったのが原因だった。

# 詳細
/boot/grubが
1. diskfilter | lvmに置かれている
2. btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfsに置かれている

上記いずれかに該当する場合、recordfailが動作しない。
これに加えて、efiでインストールされている場合、GRUB_RECORDFAIL_TIMEOUTが使用され、選択画面がこの時間表示される。
GRUB_RECORDFAIL_TIMEOUTのデフォルト値は30秒。

# 解決方法
### 1. recordfailが動作するようにインストールし直す
これが一番良い解決方法だが、OSインストールからやり直す必要があるため、新規インストールの際に気を付けるのが良い。
/bootを分割し、ext4でフォーマットすると良さそう。

### 2. GRUB_RECORDFAIL_TIMEOUTを短くする
OSの再インストールをせずに解決できるので、既存のシステムで発覚した場合、この方法が安全。
/etc/default/grubにGRUB_RECORDFAIL_TIMEOUTを設定し、grub.cfgを更新するだけで良い。

### 3. grubenvに嘘の値を設定する (非推奨)
ファイルシステム等が上記のリストに一致しても、efiでなければ30秒の待ち時間は発生しない。
そのため、grubenvにgrub_platform=xなど、efi以外の値を設定し騙すことで選択画面をスキップできる。
ただし、この方法は他の場所でefi用に書かれたものも動かなくなるので、不具合が生じる可能性がある。
そのためこの方法は非推奨とする。
フロントエンドでHEIC画像をjpegやpngに変換したい

iPhoneで撮影した画像はHEIC形式になっていますが、HEICだとブラウザで表示することができません。そのため、アップロードされたHEIC画像をブラウザで表示する場合は、jpegやpngに変換する必要があります。
もしフロントエンドで変換をするのであれば、`heic2any`というライブラリをおすすめします。

https://github.com/alexcorvi/heic2any

`heic2any`は、HEIC形式の画像ファイルをJPEG、PNG、GIFなどの画像形式に変換するためのJavaScriptライブラリです。

# 実装例

HEIC画像をjpeg画像に変換するコード例はこちらです。

```javascript
import fs from 'fs/promises';
import heic2any from 'heic2any';

// HEICファイルを読み込み、JPEGに変換し、結果をファイルに保存する関数
async function convertHeicToJpeg(inputPath, outputPath) {
    try {
        // HEICファイルを読み込む
        const heicBuffer = await fs.readFile(inputPath);

        // HEICからJPEGに変換
        const jpegBuffer = await heic2any({
            buffer: heicBuffer,
            toType: 'image/jpeg',
        });

        // JPEGバッファをファイルに書き込む
        await fs.writeFile(outputPath, Buffer.from(jpegBuffer));
        console.log(`Converted ${inputPath} to ${outputPath}`);
    } catch (error) {
        console.error('Error converting HEIC to JPEG:', error);
    }
}

// 実行例
const inputPath = heicImage; // ブラウザにアップロードしたファイルデータを指定
const outputPath = 'output.jpg';

convertHeicToJpeg(inputPath, outputPath);
```

png形式へ変換する場合は、`toType`に`image/png`を指定してください。
heic2any関数に`quality`や`multipe`などのオプションを指定することも可能なため、詳しくは公式ドキュメントを参照ください。

**公式ドキュメント**
https://alexcorvi.github.io/heic2any/
Vue.jsのPropsについて調べてみた

# はじめに
エンジニア2年目の雑魚です
今のPJに配属となり始めて、Vue.jsを始めて触ってる、初心者エンジニアです。勉強として記録していきます
今のpjのコードベースで書いていきます

# ざっくりPropsとは
親コンポーネントから子コンポーネントに値を渡す

# 親コンポーネント
`index.vue`
```Vue
<template>
	<hoge-edit
	  :is-create="true" ←子コンポーネントにisCreateのtrueを送っている
	/>
</template>

<script>
  @Component({
    name: "create_hoge",
    components: {
      "hoge-edit": HogeEdit
    }
  })


  import HogeEdit from "~hoge/edit.vue" ←子コンポーネントをimportしている（isCreate="true"）
</script>	
```
※PJでvue-class-component のライブラリ使ってます

# 子コンポーネント
```Vue
<template>
  <v-row v-if="isCreate"> ←ここでPropしてきたものを使っている
    // 〜〜〜
  </v-row>
</templata>

<script>
  @Prop({
    type: Boolean,
    default: () => false
  })
  readonly isCreate!: boolean;
  
</script>
```
自分の知らない自分の強みが「壁打ち相手」だと偶然見つかった

## この記事は何？

私の強みが偶然見つかった経験について紹介する記事です。

## きっかけ

友人が「単独公演を開催したい」と言っていました。

私が支援できることはないか尋ねたところ、壁打ち相手になってほしいと頼まれました。
コンセプトを固めたいとのこと。

壁打ちを引き受けたと同時に、自分の強みが「**壁打ち相手**」だと気づきました。

友人や同僚から過去に受けたフィードバックを思い出しました。「話すと解決につながる」「解決しそう」「言語化が上手い」などです。
点と点が線でつながり、膝を打つような感覚でした。

さらに、友人たちからチャットで「これどう思う？」とよく聞かれることに気づきました。
すでに私は壁打ち相手になっていました。

自分では気づけなかった自分の強みです。

## 良い「壁打ち相手」になるために

「壁打ち」とは、アイディアをカタチにしていくことです。

さらに良い「壁打ち相手」になるために、改めてコツをリサーチしました。3つ紹介します。

**(1)「話し手が一歩前進できる」を目標にする**

壁打ちの目標は、「話し手が一歩前進できる」です。
ミニマムサクセスは「一歩前進」と考えます。

場合によっては、大きく前進することもありますが、全ての壁打ちでうまくいくとは限りません。
まずは「一歩前進」を目標に取り組みます。

参考

https://baigie.me/nippo/2023/11/30/kabeuchi_nogami/


**(2)前提条件を序盤に確認する**

> 「譲れないことは何ですか」と尋ねる

https://note.com/hax/n/nf26a010b681c

前提条件を合わせるための問いです。
壁打ちする際の序盤に聞くと有効です。


**(3)本人の着想を生かす**

話を聞くと全然ダメなこともあります。最初からやり直した方が早いこともありますが、それだと本人の当事者意識が薄くなります。

本人の着想を生かしながら、話を整理していきます。

https://note.com/kikakudou/n/nf8e7c0b92238


## おわりに

この記事では、自分の強みが壁打ち相手だと気づいた経験と、壁打ち相手になるコツを紹介しました。

私が自分の強みを見つけたように、自分のことをよく知っている人に「何か支援できることはない？」とオープンに聞いてみると、自分の知らない自分の強みが見つかるかもしれません。

よかったら試してみてください。

それでは。
ホテルマンがSEになるまで

## :writing_hand_tone1:ネタが、、、
冒頭からぶっちゃけるけど、Qiita投稿のネタがない、、
こういう時は自身の過去を切り売りしていくしかない！
と謎理論で本記事を投稿しております。

## :mouse_three_button:他業種からエンジニアへ転職を検討してる方へ
私は他業種からエンジニアに転職してきて9年目になります。
9年前までビジネスホテルでフロントに立って接客してました。
ずっと転職を考えていたしIT業界に興味はあったけど
**「経験はないし転職できないかな。やっていけないだろうな。」**
と一歩を踏み出す勇気がなかなか出ませんでした。

だけどひょんなことがキッカケ（血みどろの話になるので割愛:high_heel:）で前職を退職。

その後の転職活動で運よくエンジニアに転職することが出来ました。
転職時にIT知識もほぼなく最初は本当に大変でした:sweat_smile:

だけど、毎日が新しいことで日々自分の力になっていく感覚はそう味わえるものではないし、楽しかったです！


## :ramen:〆
何が言いたいのか自分でもわかりませんが、もし私と同じ理由で二の足を踏んでる方がいるならすぐにでも一歩を踏み出してみてください！
正直未経験からでも努力次第でやっていけます。

:::note warn
警告
今は色んな媒体があるので最低限の知識は身に着けておきましょう
:::

ただ、日進月歩のこの業界で1流のエンジニアになるためには、毎日自己学習を続けて成長し続ける必要があります　~~（3流エンジニアが言ってる）~~

勇気を出して一歩を踏み出してください。
お待ちしております:relaxed:
この解消法→「error: path '/nix/store/...-source/flake.nix' does not exist」

## はじめに

Nixを使用している開発者の皆さん、こんにちは。今回は、`nix develop`コマンドを実行した際に遭遇する可能性のある、ちょっと厄介なエラーについて解説します。

## 問題

`nix develop`コマンドを実行すると、次のようなエラーメッセージが表示されることがあります：

```
error: path '/nix/store/0ccnxa25whszw7mgbgyzdm4nqc0zwnm8-source/flake.nix' does not exist
```

## 原因

このエラーが発生する主な理由は、**`flake.nix`ファイルがGitで管理されていない**ことです。

Nixは、Flakeを使用する際、Gitリポジトリの状態を参照するようで、`flake.nix`ファイルがGitの管理下にない場合、Nixはそのファイルを見つけることができず、上記のエラーが発生するみたいです。

ただし、正直なところ、この問題の根本的な原因や、Nixがなぜこのような挙動をするのかについての詳細は、私も完全には理解していません。Nixの内部動作やFlakeの仕組みについて、より深い知識を持つ方がいらっしゃれば、ぜひこの記事にコメントやフィードバックをいただけると幸いです。

## 解決方法

解決方法は非常にシンプルです。`flake.nix`ファイルをGitリポジトリに追加するだけです。

以下のコマンドを実行してください：

```bash
git add flake.nix
```

このコマンドにより、`flake.nix`ファイルがGitの管理下に置かれます。

## 確認

`flake.nix`ファイルをGitに追加した後、再度`nix develop`コマンドを実行してみてください。エラーが解消され、正常に動作するはずです。

## まとめ

Nixのflakeを使用する際は、`flake.nix`ファイルが必ずGitで管理されている状態にあることを確認しましょう。この小さな注意点を覚えておくだけで、不要なトラブルを避けることができます。

Happy Nixing!
[備忘録]　ハッカソンなどで活用する開発素材やIotの用語について分かったこと ~ver.2

# はじめに
こんにちは，Umamusume22です．今回も引き続きIotのハッカソンなどでよく使われる開発素材(M5Stackなど)について調べて分かったことをまとめました．また，Iotの開発を行う上で頻繁に使う用語も調査しました．

# 備忘録
#### TouchGFX[1]
- STM32マイクロコントローラをベースにしたシステム
- C++およびSTM32上の組込みGUI開発に関する基本的な技能を持つソフトウェア開発者を対象
- 組み込みグラフィックスの開発で使用される
- Windows10で使用するように開発されている
    - linuxでも使える

#### UART[2]
- シリアル通信用の信号とパラレル通信用の信号の変換を行う部品(集積回路)のこと
- 非同期式のシリアル通信に対応
- 同期式のシリアル通信に対応していない

# 最後に
今回も記事の内容が短くて申し訳ありません．
今回はIotのハッカソンなどでよく見かけるモジュールや用語について調べてみました．
UARTやARMなどアルファベットの用語が多いですよね笑．用語が分からなければ技術記事を読んでもチンプンカンプンです．基礎をバカにしてはいけない．

読んでいただきありがとございました!

※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!

# 参考文献
[1] “TouchGFXドキュメント"
https://support.touchgfx.com/ja/docs/introduction/welcome

[2] “「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典"
https://wa3.i-3-i.info/word12982.html
[MySQL][Docker] DockerでMySQLを動かす 

# 目的
DockerがインストールされたMacOS環境で、`MySQL`を`Docker`(`Terminal`)経由で動かす方法を記載

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

# 目次

# Docker実行用のコマンド（Terminal）
~~~sh:Terminl
docker run -d --name local-mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_USER=myuser -e MYSQL_PASSWORD=password -p 13306:3306 mysql:latest
~~~

## 解説
### 使用しているDockerコマンド
- `run`：コンテナの実行（生成/起動/停止）
- `mysql:latest`：使用するDockerイメージとして mysql の最新バージョンを指定※1

### 使用しているDockerオプション
- `-d`：コンテナをバックグラウンド実行
- `--name`：コンテナ前
    - 名前を付けない場合、ランダムでコンテナの名前が付けられる
- `-e`：環境変数※2 
- `-p`：ポート番号
    - 記法：`-p {ホストのポート番号}:{コンテナ内のポート番号}`
    - ホストのポート`13306`（**Dockerコンテナ（任意）のポート番号**）をコンテナのポート`3306`（**MySQLのポート番号**）にマッピングしている。

### ※1：Dockerイメージの指定について
Docker Hub（Dockerイメージの格納先）には様々なDockerイメージが公開されており、`run`コマンドの末尾につけることで、イメージを指定できる。
例えば、↓はNginxのDockerイメージを使ってWebサーバーを立ち上げるコマンド。
~~~sh
docker run --name some-nginx -d -p 8080:80 nginx
~~~

# MySQL接続用のコマンド（Terminal(Docker上)）※3
~~~sh:Terminal(Docker上)
mysql -h localhost -P 13306 -u myuser -p password 
~~~

### 使用しているMySQLオプション
- `-h`：ホスト名の指定
- `-P`：コンテナの名前
- `-u`：ユーザ名の指定
- `-p`：パスワードの指定

### ※3：下記赤線のTerminalアイコンから開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/f40463f6-2cbe-ac53-2aa5-f90b561b4964.png)



# 参考リンク
- [DockerコンテナでMySQLを動かす方法](https://blackbird-blog.com/docker-mysql01)
- [[Docker]覚えておきたいオプションまとめ](https://qiita.com/ryoishizawa/items/637d39574026bbd54dbf)
- [Dockerコマンド一覧](https://qiita.com/nimusukeroku/items/72bc48a8569a954c7aa2)
- [Docker Hub](https://hub.docker.com/)
- [MySQLのよく使うコマンドとオプションまとめ](https://it-kyujin.jp/article/detail/1082/)

↓近い目的で検討している（PostgreSQL）
- [PostgreSQL サーバーを docker-compose で起動する](https://dev.to/kaede_io/sql-ji-chu-part-01-postgresql-sabawo-docker-compose-deqi-dong-suru-1ml7)
ITパスポート ファイルのバックアップ

・バックアップ
システムやデータの複製を別の記憶媒体に保存すること

・バックアップ方法
・フルバックアップ
全てのデータをバックアップする方法

・差分バックアップ
フルバックアップ以降に変更されたデータをバックアップする方法

・増分バックアップ
フルバックアップまたは各増分バックアップ以降に変更されたデータをバックアップする方法

・復元方法
・フルバックアップ
最新のフルバックアップを使用して復元する方法

・差分バックアップ
フルバックアップと最新の差分バックアップを使用して復元する方法

・増分バックアップ
フルバックアップと各増分バックアップを使用して復元する方法

差分バックアップと増分バックアップは、フルバックアップのデータに変更データを反映させる必要があるので、復元時間が長くなる
Djangoのtrim_whitespaceは改行も削除する

DjangoのSerializerのフィールドには「trim_whitespace」というオプションがある。
削除してくれるのは「whitespace」=「空白」=「スペースだけ」だと思っていたが、「改行」も削除されたので調べてみた。
その結果、「空白」=「スペースだけ」というのは盛大に間違っていてた。

## 1. trim_whitespaceは、空白を削除する

> **CharField**
> ...省略...
> trim_whitespace - If set to True then leading and trailing whitespace is trimmed. Defaults to True.
> [Serializer fields - Django REST framework](https://www.django-rest-framework.org/api-guide/fields/#charfield)

## 2. trim_whitespaceは、strip()を使っている
引用元 : [django-rest-framework/rest_framework/fields.py at master · encode/django-rest-framework · GitHub](https://github.com/encode/django-rest-framework/blob/master/rest_framework/fields.py#L766)

```python
class CharField(Field):
    # ...省略...
    def to_internal_value(self, data):
        # ...省略...
        value = str(data)
        return value.strip() if self.trim_whitespace else value
```

## 3. Pythonのstrip()は、引数なしで空白文字を除去する
> **str.strip([chars])**
> 文字列の先頭および末尾部分を除去したコピーを返します。引数 chars は除去される文字集合を指定する文字列です。 chars が省略されるか None の場合、空白文字が除去されます。 chars 文字列は接頭語でも接尾語でもなく、そこに含まれる文字の組み合わせ全てがはぎ取られます:
> [組み込み型 &#8212; Python 3.12.4 ドキュメント](https://docs.python.org/ja/3/library/stdtypes.html#str.strip)

## 4. 空白には「タブ」「改行」なども含まれていた
空白とは？はisspace()で確認でき、その説明には「タブ」「改行」が含まれると書いてあった。

> bytes.**isspace()**
> bytearray.**isspace()**
> シーケンスが空でなく、かつ全てのバイト値が ASCII 空白文字である場合は True を、そうでなければ False を返します。ここでの ASCII 空白文字とはシーケンス `b' \t\n\r\x0b\f'` に含まれるバイト値です (半角スペース、タブ、ラインフィード、キャリッジリターン、垂直タブ、フォームフィード) 。
> [組み込み型 &#8212; Python 3.14.0a0 ドキュメント](https://docs.python.org/ja/3.14/library/stdtypes.html#bytes.isspace)

## 5. 正規表現でも`\s`は「改行」を含む

> **\s**
> Unicode (str) パターンでは:
> Unicode 空白文字 (これは [ \t\n\r\f\v] その他多くの文字、例えば多くの言語におけるタイポグラフィ規則で定義されたノーブレークスペースなどを含みます) にマッチします。
> [re --- 正規表現操作 &#8212; Python 3.12.4 ドキュメント](https://docs.python.org/ja/3/library/re.html#regular-expression-syntax)
【DocC】ContentAndMediaディレクティブのAPIドキュメントを読む

# この記事は何？

DocCドキュメントを作成するための[ContentAndMedia](https://www.swift.org/documentation/docc/contentandmedia)について、Apple開発者向けドキュメントを読む。

## ディレクティブの階層

### Tutorialページ

- Tutorial
    - XcodeRequirement
    - Intro
        - Image
        - Video
    - Section
        - ContentAndMedia（←これ）
        - Steps
            - Step
                - Code
                    - Image
                - Image
                - Video
        - Stack
            - ContentAndMedia（←これ）
                - Image
                - Video
    - Image
    - Assessments
        - MultipleChoice
            - Choice
                - Justification
                - Image

### Ariticle（解説記事）

- Article
    - Intro
        - Image
        - Video
    - ContentAndMedia（←これ）
        - Image
        - Video
    - Stack
        - ContentAndMedia（←これ）
            - Image
            - Video
        - Image
    - Assesments
        - MultipleChoice
            - Choice
                - Justification
                - Image

## ContentAndMedia

チュートリアルページのセクションに「テキスト、画像、ビデオを含むグループ」を表示する。

### Overview

`@Section`または`@Stack`ディレクティブ内で使用できる。
`layout`パラメータの値を`horizonal`に設定すると、複数のテキスト段落を設けて、その後に画像またはビデオの指示を提供する。

```swift:.tutorialファイルの例
@Tutorial(time: 30) { 
    ...
    
    @Section(title: "Add a customization view") {
        @ContentAndMedia {
            Add the ability for users to customize sloths and select their powers.
            
            @Image(source: 01-creating-section2.png, alt: "An outline of a sloth surrounded by four power type icons. The power type icons are arranged in the following order, clockwise from the top: fire, wind, lightning, and ice.")
        }
            
        ...
    }
}
```

### 含めるべき要素

`@ContentAndMedia`には以下のいずれかを、1つ以上含める必要がある。

- `@Image`（画像）
- `@Video`（動画）

### Containing Elements

`@ContentAndMedia`は、次の要素に含めることができる。

- `@Section`
- `@Stack`
LivePortrait: 最先端の効率的なポートレートアニメーション技術

## はじめに

LivePortraitは、ステッチングとリターゲティング制御を用いた革新的なポートレートアニメーション技術です。この記事では、LivePortraitの概要、その特徴、そして使用方法について詳しく解説します。

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">「LivePortrait」を動かしてみた！③～3D編～ <a href="https://t.co/DWS4Ft35YP">https://t.co/DWS4Ft35YP</a> <a href="https://t.co/EkSRLXINT4">pic.twitter.com/EkSRLXINT4</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1811328776925593654?ref_src=twsrc%5Etfw">July 11, 2024</a></blockquote> 

## LivePortraitとは？

LivePortraitは、静止画のポートレートを動画に変換する先進的な技術です。従来の方法と比べて、より効率的かつ高品質なアニメーションを生成することができます。

https://hamaruki.com/liveportrait-innovative-portrait-animation/

### 主な特徴

1. ステッチング技術: 複数の画像を滑らかにつなぎ合わせる
2. リターゲティング制御: 元の画像の特徴を維持しながら、動きを自然に適用する
3. 高速処理: 最適化されたアルゴリズムにより、素早くアニメーションを生成

## 技術的な仕組み

LivePortraitは、複数のニューラルネットワークを組み合わせて動作します。主要なコンポーネントは以下の通りです：

1. Appearance Feature Extractor: 入力画像から特徴を抽出
2. Motion Extractor: 動画から動きの情報を抽出
3. Spade Generator: 特徴と動きの情報を組み合わせて新しい画像を生成
4. Warping Module: 生成された画像を自然に変形
5. Stitching and Retargeting Modules: 最終的な出力を調整し、滑らかにつなぎ合わせる

これらのモジュールが連携することで、自然で高品質なアニメーションが可能になります。

## LivePortraitの使い方

### 環境設定

LivePortraitを使用するには、以下の手順で環境を準備します：

1. GitHubからリポジトリをクローン
2. Condaで専用の環境を作成
3. 必要なライブラリをインストール

```bash
git clone https://github.com/KwaiVGI/LivePortrait
cd LivePortrait
conda create -n LivePortrait python==3.9.18
conda activate LivePortrait
pip install -r requirements.txt
```

### 学習済みモデルのダウンロード

LivePortraitの性能を最大限に引き出すには、学習済みのモデルが必要です。これらは以下の手順でダウンロードできます：

1. Google DriveまたはBaidu Yunから学習済みモデルをダウンロード
2. ダウンロードしたファイルを解凍し、`./pretrained_weights`ディレクトリに配置

### 基本的な使用方法

LivePortraitを使用するための基本的なコマンドは以下の通りです：

```bash
python inference.py
```

このコマンドを実行すると、サンプルの入力画像と動画を使用してアニメーションが生成されます。

### カスタム入力の使用

自分の画像や動画を使用したい場合は、以下のようにコマンドを変更します：

```bash
python inference.py -s [ソース画像のパス] -d [駆動動画のパス]
```

例えば：

```bash
python inference.py -s assets/examples/source/s9.jpg -d assets/examples/driving/d0.mp4
```

### 高度な設定

LivePortraitには様々な設定オプションがあります。詳細は以下のコマンドで確認できます：

```bash
python inference.py -h
```

## パフォーマンスと速度

LivePortraitは高速な処理を特徴としています。RTX 4090 GPUを使用した場合の各モジュールの処理時間は以下の通りです：

- Appearance Feature Extractor: 0.82ms
- Motion Extractor: 0.84ms
- Spade Generator: 7.59ms
- Warping Module: 5.21ms
- Stitching and Retargeting Modules: 0.31ms

これらの数値は、LivePortraitが実時間に近い速度で動作可能であることを示しています。

## Dockerを使用した簡単な起動

LivePortraitはDockerを使用して簡単に起動することもできます。以下の手順で実行できます：

1. プロジェクトのルートディレクトリに移動
2. 以下のコマンドを実行

```bash
docker-compose up
```

これにより、LivePortraitアプリケーションがDockerコンテナ内で起動し、ポート8890でアクセス可能になります。

## まとめ

LivePortraitは、効率的で高品質なポートレートアニメーション技術です。ステッチングとリターゲティング制御を組み合わせることで、自然で魅力的なアニメーションを生成することができます。簡単な設定と使用方法により、研究者からクリエイターまで幅広いユーザーに活用されることが期待されます。

## 参考文献

本技術の詳細については、以下の論文を参照してください：


LivePortraitの詳細な情報や最新のアップデートについては、[公式GitHub](https://github.com/KwaiVGI/LivePortrait)を確認してください。

## オリジナルのリポジトリ

https://github.com/KwaiVGI/LivePortrait

## 日本語ドキュメントを追加したフォークリポジトリ

https://github.com/Sunwood-ai-labs/LivePortrait

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
[備忘録]　ハッカソンなどで活用する開発素材(M5Stackなど)について分かったこと ~ver.1

# はじめに
こんにちは，Umamusume22です．今回はIotのハッカソンなどでよく使われる開発素材(M5Stackなど)について調べて分かったことをまとめました

# 備忘録
#### M5Stack[1]
- 約5cm×5cmの正方形のケースの中にWi-FiとBluetoothによる無線通信機能が備わっている
- 小型のマイコンモジュール
- CPUやGPIOなどが搭載されている
    - センサによる監視
    - LEDやモータの制御，無線通信によって他のデバイスと連携することが可能
        - ロボットの遠隔制御
        - Iotシステムでセンサの監視
        - PC・タブレットなどのデバイスとデータを送受信
- 開発環境はArduino IDEやUIFlow

#### obniz[2]
- スマホのようにアプリを入れるだけでIot化が可能
- Web上でデータを管理
- Javascriptでプログラム．マイコンに接続しobjectとして扱う

# 最後に
今回も記事の内容が短くて申し訳ありません．
今回はIotのハッカソンなどでよく見かけるモジュールについて調べてみました．
M5Stackやobnizはまだ使ったことがありません．もし，使う機会があれば購入して使う予定です．
読んでいただきありがとございました!

※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!

# 参考文献
[1] “人気のマイコンモジュール「M5Stack」とは？特徴や使い方を紹介！"
https://deviceplus.jp/mc-general/what-is-m5stack/#:~:text=%E7%84%A1%E7%B7%9A%E9%80%9A%E4%BF%A1%E6%A9%9F%E8%83%BD%E3%82%92%E4%BD%BF%E3%81%86,%E3%81%A7%E3%82%88%E3%81%8F%E7%94%A8%E3%81%84%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

[2] “IoTのためのスマートデバイス OS搭載だからアプリを入れるだけ スマホの手軽さがIoTの世界に"
https://iot.obniz.com/
vue3 npm run dev で動かなくなった固まる

vue3でnpm run dev しても止まる時がある。


```
  VITE vx.x.1  ready in 839 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: http://xxxx:5173/
  ➜  press h to show help

  LARAVEL vxx  plugin vxx

  ➜  APP_URL: https:/xxxx.com

```

自分の場合はport 5173なので
port 5173 の プロセスを確認

```
sudo lsof -i :5173
```

node が 2781 のプロセスを使っています

```出力
node    2781 root   18u  IPv6 3xxx5x      0t0  TCP *:5173 (LISTEN)
```

ということで　kill

```
sudo kill 2781
```

はい、これで

```
npm run dev
```

をやると動作するようになる
LivePortrait: 革新的なポートレートアニメーション技術の詳細解説

## LivePortraitとは

LivePortraitは、静止画のポートレートを自然な動画に変換する最先端の技術です。この技術は、ステッチングとリターゲティング制御という2つの革新的なアプローチを組み合わせることで、高品質かつ効率的なアニメーション生成を実現しています。

## LivePortraitの主要な特徴

### ステッチング技術

ステッチング技術は、複数の画像フレームを滑らかにつなぎ合わせる手法です。LivePortraitでは、この技術を用いて以下の利点を実現しています：

- 連続性の向上: フレーム間の急激な変化を抑え、より自然な動きを生成
- アーティファクトの削減: 画像のつなぎ目で発生しがちな不自然さを最小限に抑制
- 高品質な出力: 滑らかで違和感のないアニメーションを生成

### リターゲティング制御

リターゲティング制御は、元の静止画の特徴を維持しながら、新しい動きを適用する技術です。LivePortraitにおける利点は以下の通りです：

- アイデンティティの保持: 元の人物の特徴や表情を維持しつつ、自然な動きを付加
- 柔軟な動きの適用: さまざまな動きのパターンを、元の画像に違和感なく適用可能
- 表現力の向上: 多様な感情や動作を、元の静止画に効果的に反映

### 高速処理

LivePortraitは、最適化されたアルゴリズムと効率的なネットワーク構造により、高速な処理を実現しています：

- リアルタイムに近い処理速度: 一般的なGPUでも高速な処理が可能
- 低レイテンシー: 入力から出力までの遅延を最小限に抑制
- スケーラビリティ: さまざまなハードウェア環境に対応可能

## LivePortraitの技術的詳細

### アーキテクチャの概要

LivePortraitは、複数のニューラルネットワークモジュールから構成されています。各モジュールの役割と特徴を詳しく見ていきましょう。

#### Appearance Feature Extractor (外見特徴抽出器)

- 役割: 入力された静止画像から重要な視覚的特徴を抽出
- 特徴:
  - 軽量設計: わずか0.84Mのパラメータ数で高速処理を実現
  - 効率的な特徴表現: 3.3MBのモデルサイズで豊富な情報を抽出

#### Motion Extractor (動き抽出器)

- 役割: 駆動動画から動きの情報を抽出し、静止画に適用可能な形式に変換
- 特徴:
  - 高度な動き解析: 28.12Mのパラメータを使用して複雑な動きを捉える
  - 迅速な処理: 108MBのモデルサイズながら0.84msの高速処理を実現

#### Spade Generator (SPADE生成器)

- 役割: 抽出された特徴と動きの情報を組み合わせて新しい画像フレームを生成
- 特徴:
  - 高品質な画像生成: 55.37Mのパラメータで詳細な画像を生成
  - 効率的な処理: 212MBのモデルサイズで7.59msの処理時間を実現

#### Warping Module (ワーピングモジュール)

- 役割: 生成された画像を自然に変形させ、よりリアルな動きを表現
- 特徴:
  - 精密な変形処理: 45.53Mのパラメータで微細な動きを表現
  - バランスの取れた性能: 174MBのモデルサイズで5.21msの処理時間を達成

#### Stitching and Retargeting Modules (ステッチングとリターゲティングモジュール)

- 役割: 生成されたフレームを滑らかにつなぎ合わせ、最終的な出力を調整
- 特徴:
  - 軽量設計: わずか0.23Mのパラメータ数で効率的な処理を実現
  - 高速処理: 2.3MBのモデルサイズで0.31msの驚異的な処理速度を達成

### 処理フロー

1. 静止画像の入力: ユーザーが指定した静止画ポートレートを入力
2. 動画の入力: アニメーションの動きを提供する駆動動画を入力
3. 特徴抽出: Appearance Feature Extractorが静止画から特徴を抽出
4. 動き抽出: Motion Extractorが駆動動画から動きの情報を抽出
5. 画像生成: Spade Generatorが特徴と動きの情報を組み合わせて新しいフレームを生成
6. 変形処理: Warping Moduleが生成された画像を自然に変形
7. 最終調整: Stitching and Retargeting Modulesが出力を滑らかにつなぎ合わせ、最終的な調整を行う
8. アニメーション出力: 完成したポートレートアニメーションを出力

## LivePortraitの応用分野

LivePortraitの革新的な技術は、以下のような幅広い分野で応用が期待されています：

1. エンターテインメント産業
   - 映画やアニメーションの制作効率化
   - バーチャルインフルエンサーの動画生成
   - ゲームキャラクターの表情豊かな動きの実現

2. 教育分野
   - 歴史上の人物の「復活」による没入型学習体験の提供
   - 言語学習における表情豊かな会話パートナーの生成

3. コミュニケーションツール
   - ビデオ会議での代替アバターの生成
   - SNSでのアニメーション付きプロフィール画像の作成

4. アート＆デザイン
   - デジタルアートにおける新しい表現方法の提供
   - ポートレート写真の動的な展示方法の革新

5. 医療・福祉分野
   - 患者とのコミュニケーション支援ツールの開発
   - 心理療法における感情表現の補助

## LivePortraitの今後の展望

LivePortraitは現在も活発に開発が続けられており、以下のような発展が期待されています：

1. リアルタイム処理の更なる高速化
2. より多様な表情や動きのサポート
3. 3D モデルとの統合による立体的なアニメーション生成
4. 音声同期機能の追加によるリップシンク機能の実現
5. AR/VR技術との融合による没入型体験の創出

## まとめ

LivePortraitは、ステッチングとリターゲティング制御を巧みに組み合わせた革新的なポートレートアニメーション技術です。高品質な出力と効率的な処理を両立し、様々な分野での応用が期待されています。技術の進化とともに、LivePortraitは私たちの視覚体験や表現方法に新たな可能性をもたらすでしょう。

今後のアップデートや詳細な情報については、[公式GitHub](https://github.com/KwaiVGI/LivePortrait)を定期的にチェックすることをおすすめします。LivePortraitの発展が、デジタルコンテンツの未来をどのように形作っていくのか、注目に値する技術と言えるでしょう。

## オリジナルのリポジトリ

https://github.com/KwaiVGI/LivePortrait

## 日本語ドキュメントを追加したフォークリポジトリ

https://github.com/Sunwood-ai-labs/LivePortrait
Git基本操作コマンド一覧

## リモートリポジトリの設定
#### リモートリポジトリを追加:

```
git remote add origin [gitlink]
```
#### リモートリポジトリのURLを変更:
```
git remote set-url origin [new_gitlink]
```
#### リモートリポジトリを確認:
```
git remote -v
```
## クローン
#### リポジトリをクローン:
```
git clone [gitlink]
```
#### 特定のブランチをクローン:
```
git clone -b [branch_name] [gitlink]
```
## ローカルリポジトリの初期化とコミット
#### リポジトリを初期化:
```
git init
```
#### 変更をステージング:
```
git add .
```
#### 変更をコミット:
```
git commit -m "コミットメッセージ"
```
#### 変更されたファイルの一覧を確認（ステージング前）:
```
git diff --name-only
```
## リモートリポジトリへのプッシュ
#### 初回プッシュ:
```
git push -u origin master
```
#### 特定のブランチをプッシュ:
```
git push origin [branch_name]
```
## ブランチの操作
#### 新しいブランチを作成して切り替え:
```
git checkout -b [branch_name]
```
#### 現在のブランチを確認:
```
git branch
```
#### 新しいブランチをリモートリポジトリにプッシュ:
```
git push -u origin [branch_name]
```
#### ブランチを削除（ローカル）:
```
git branch -d [branch_name]
```
#### ブランチを削除（リモート）:
```
git push origin --delete [branch_name]
```
## 変更の管理
#### ブランチのマージ:
```
git merge [branch_name]
```
#### マージのコンフリクト解消:
```
git mergetool
```
#### マージの中止:
```
git merge --abort
```
#### リモートから最新の変更を取得（fetch後にmergeせずに確認する）:
```
git fetch
```
#### リモートの変更を確認してマージする:
```
git pull
```
## リベース
#### リベースの開始:
```
git rebase [branch_name]
```
#### リベースのコンフリクト解消:
```
git rebase --continue
```
#### リベースの中止:
```
git rebase --abort
```
## ログと状態の確認
#### コミットログの表示:
```
git log
```
#### 変更の確認:
```
git status
```
#### 特定のファイルの変更内容を見る:
```
git diff [file_name]
```
## リセット・変更の取り消し
#### 変更を破棄（ステージングエリアから）:
```
git reset HEAD [file_name]
```
#### 変更を破棄（ワーキングディレクトリから）:
```
git checkout -- [file_name]
```
#### 直前のコミットを取り消す（コミットのみを取り消すが、変更内容は保持）:
```
git reset --soft HEAD~1
```
#### 直前のコミットを完全に取り消す（変更も取り消す）:
```
git reset --hard HEAD~1
```
## タグ
#### タグを作成:
```
git tag [tag_name]
```
#### タグをリモートにプッシュ:
```
git push origin [tag_name]
```
#### タグを削除:
```
git tag -d [tag_name]
```
## スタッシュ
#### 変更を一時保存:
```
git stash
```
#### スタッシュを適用:
```
git stash apply
```
#### スタッシュを削除:
```
git stash drop
```
## その他の操作
#### ファイルを削除:
```
git rm [file_name]
```
#### ファイル名を変更:
```
git mv [old_file_name] [new_file_name]
```
Optionalを使ってNPEを撲滅する

用語 NPE：NullPointerException

## 🏃‍♂️はじめに
たとえば以下のように、
String型の値を返すメソッド `getMailTemplateByClient`を作っていて、呼び出し元で返り値を使っているとします(`mailTemplate`にセット)。

```java
public Client getClientInfo(int clientId) {

    // メソッドコール
    String mailTemplate = getMailTemplateByClient(clientId);
    int mtCharCount = mailTemplate.length();

    //（以下略）
}

// 顧客に送るメール定型文を取得する
private String getMailTemplateByClient(int clientId) {

    // 顧客IDに紐づいたメール定型文をDBから取得する
    final String mailTemplate = selectMailTemplateFromClientTbl(clientId);
    return mailTemplate;
}
```

ところがところが、
単体テストをしていく中で上記コードの`.length()`でNPEが生じるケースがあり、実はgetMailTemplateByClientメソッドは**nullを返す可能性がある**ことが分かりました😨
ということで以下のようにnullを想定した条件分岐を追加することでNPEを回避しました！
めでたしめでたし👍

```java
public Client getClientInfo() {

    // メソッドコール
    String mailTemplate = getMailTemplateByClient(clientId);
    // int mtCharCount = mailTemplate.length();
    int mtCharCount = 0;
    if(mailTemplate != null) {
        mtCharCount = mailTemplate.length();
    }
}
```
...ではないです。（動きはするけど）
これでは将来、追加の要望対応とかでgetMailTemplateByClientを再利用するときに、また同じワナを踏む可能性があります。
とくに再利用を考えている第三者をも不幸にしてしまいます😥（バグの温床）



## ✅Optionalを使って解決！
Java(8~)には以下のような素敵なクラスがあることを知りました。
`java.util.Optional`
参考: https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html

これを踏まえてgetMailTemplateByClientメソッドを以下のように修正することで、
**その返り値はnullかもしれないことを表現しました。**
これで再利用を考えている第三者にもその可能性を伝えることができ、未来のNPE撲滅に貢献できます👌

```java
// 顧客に送るメール定型文を取得する
private Optional<String> getMailTemplateByClient(int clientId) {

    // 顧客IDに紐づいたメール定型文をDBから取得する
    final Optional<String> mailTemplate = selectMailTemplateFromClientTbl(clientId);
    return mailTemplate;
}
```

また呼び出し元は以下のように`map`メソッドを使ってOptinalの値を取り出すように修正しました。
（そして元のif文で書いていた頃よりもスッキリとなった😄）


```java
public Client getClientInfo() {

    // メソッドコール
    Optional<String> mailTemplate = getMailTemplateByClient(clientId);
    int mtCharCount = mailTemplate.map(mt -> mt.length()).orElse(0);
    
    //（以下略）
}
```

(補足)
今回は取り出した値を返して mtCharCount にセットするためmapメソッドを使いますが、
値を返さないケースでは`ifPresent`メソッドを使います。

⚠ 注意
`mailTemplate.get().length()` のように、値の取り出しに**get()は使わない**方が良いです。
get()は中身があることを前提としており、中身が空なら例外を吐いてしまうためです。

## 🍜〆
- nullの可能性があることはOptional型を使うことで表現する。
- Optionalの値の取り出しには map / ifPresent メソッドを使う。
History of the Trend: Rompers

<h1><a href="https://www.lydiadesignstudio.com/post/what-are-rompers">What is a rompers</a>
<h1>

A romper is a one-piece garment typically worn by children and infants. It consists of a connected top and bottom part, making it a convenient and practical outfit for young children learning to use the bathroom or dress themselves. Rompers can be worn with or without a diaper and often feature snap or zipper closures for easy diaper changes.

<h2>The History of Rompers<h2>

Rompers began as children’s clothing, which explains their similarity to overalls, jumpers, and (as some are quick to point out) onesies. I don’t know about you, but I’d much rather wear a romper!

<h2>Early Advertisements and Popularity<h2>

The earliest advertisement found for rompers was in a 1904 issue of the New York Times. The ad described rompers as “pinaforelike garments” with the skirt portion gathered into shorts for comfort. Easy to play in and often made of cotton or other washable material, rompers became the go-to play clothes of the 20th century.

<h2>Rompers in the 1920s<h2>

Rompers continued to be popular into the ’20s, appealing to stylish young women as much as to children. With their one-piece design, rompers offered a chic alternative to a blouse and full skirt and could be dressed up or down, depending on the fabric.

<h2>The Rise of the Jumpsuit in the 1970s<h2>

In the ’70s, the romper’s leggy cousin, the jumpsuit, became a wardrobe staple for anyone with disco on the brain. Since then, jumpsuits have gone in and out of fashion, recently being revived as part of spring 2011’s 1970s trend.

<h2>Modern-Day Romper Revival<h2>

These days, the romper is back in a big way, with designers featuring rompers on the runway and retailers experimenting with patterns, tailored and relaxed silhouettes, and eye-catching details. It’s likely you have one in your own closet right now.

<h2>Why We Still Love This Trend<h2>

<h3>Versatility<h3>

The romper is as easy to wear to the beach as it is to a dinner out. It’s like a great dress with a playful and comfy feel. You can find one that fits every event by using the same guidelines you already use to pick out your outfits. Stick with flowy fabrics for day, then amp it up with more structured looks for night.

<h3>Something for Everyone<h3>

Still not sure you can pull off a romper? Check out articles on finding a romper for your body type. It’s a great starting point to see what you should be looking for, and you can still put your own twist on it with great accessories!

<h3>Fun and Unique<h3>

While it may take a little courage to wear a romper, you can’t deny the individual twist it gives a look. Try it out and discover why this trend has been hot for so long!

<h3>Tell Us What You Think!<h3>

Have you given the romper trend a try? Should it stick around or head to the back of the closet? Any trends you’d like to know the history of? Leave a comment and let us know!
DifyとOllamaで完全ローカルLLM環境セットアップ手順

想定環境 Mac ( Apple silicon )

## Ollamaのインストール

1. [Ollamaのサイト](https://ollama.com/) から、インストーラをダウンロードして実行する。
2. 起動するとコマンドラインプログラムをインストーするウインドウが表示されるので、インストールする。
3. ターミナルを開き、gemma2 9Bをインストールする

```
ollama run gemma2:9b-instruct-fp16
```

※18GBのモデルなので時間がかかります。

インストールがおわり、プロンプトが表示されれば、正しくインストールされています。

## Difyのインストール

[公式ドキュメント](https://docs.dify.ai/getting-started/install-self-hosted/docker-compose)を参考にしてください

1. リポジトリをclone
1. .env をコピー
1. docker composeで起動
1. http://localhost/ にアクセス

```
git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
docker compose up -d
```

## Difyのユーザーを登録

http://localhost/ にアクセスすると、最初はユーザー登録画面になるので、ユーザー登録する

## モデルにOllamaを登録

- 右上のユーザー名をクリックしてメニューを開き「設定」を選ぶ
- 「モデルプロバイダー」を選択し、「ADD MORE MODEL PROVIDER」から「Ollama」を選択
- Model Type: LLM
- Model Name: gemma2:9b-instruct-fp16
- Base URL: http://host.docker.internal:11434/
- Completion Mode: Chat

で保存して、しばらくすると追加完了（時間がかかる）

これであとは、アプリを作るだけ
RustとWebAssemblyでパラパラ文字作ってみた



# はじめに

下記で電光掲示板ツール作った時とほぼ同じ構成でGifみたいに1文字ずつ画像をパラパラさせてみようとおもいます。

電光掲示板ツールについて

https://qiita.com/shisojuice/items/0bd4663aed0a3152d1f6


# プロジェクトの作成

Rustで文字から画像を生成するために、文字とFontデータ(今回はNotoSansJPを使用)を受け取る。

今回は1文字のみを表示してパラパラさせるので半角、全角をなるべく中央に来るように

scaleやLayout時の座標などを設定する。

(今回はざっくり計算のpaddingで中央に寄せたので、、、

文字によってはずれている、、、)

最後に、Base64の文字列を返す。

```rust:lib.rs

// 省略

#[wasm_bindgen]
pub fn str_to_png(str:&str,font_data:&[u8]) -> String{
    let ch = str.chars().nth(0);
    let font = rusttype::Font::try_from_vec(Vec::from(font_data)).unwrap();
    let scale = Scale::uniform(256.0);
    let v_metrics = font.v_metrics(scale);
    let glyphs: Vec<_> = font
        .layout(&*ch.unwrap().to_string(), scale, point(65.0, 15.0 + v_metrics.ascent ))
        .collect();
    let glyphs_height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
    let mut image = DynamicImage::new_rgba8(glyphs_height + 64, glyphs_height + 64).to_rgba8();
    for glyph in glyphs {
        if let Some(bounding_box) = glyph.pixel_bounding_box() {
            let pad = 220 - bounding_box.max.x;
            glyph.draw(|x, y, v| {
                image.put_pixel(
                    x + bounding_box.min.x as u32 + pad as u32,
                    y + bounding_box.min.y as u32,
                    Rgba([0, 0, 0, (v * 255.0) as u8]),
                )
            });
        }
    }
    let mut buffer = Cursor::new(Vec::new());
    image.write_to(&mut buffer, ImageFormat::Png).unwrap();
    let base64_string = general_purpose::STANDARD.encode(buffer.get_ref());
    // データURL形式で返す
    format!("data:image/png;base64,{}", base64_string)
}

// 省略

```

Javascriptで文字数分ループさせて、

0.5秒ごとに1文字ずつ上記関数からBase64のImageを受けとり、

パラパラさせる🕺

```Javascript:index.js

// 省略

  await fetchFontAsUint8Array("./NotoSansJP-Regular.ttf")
    .then(uint8Array => {
      for (let i=0;i<words.length;i++)
      {
        setTimeout(function() {
            document.getElementById("mainImg").src = str_to_png(words[i],uint8Array);
            if(i === words.length -1)
            {
                document.getElementById("GeneBtn").disabled =false;
            }
        }, i*500);
      }
    });

// 省略

```

これでメインの機能は実装完了！

残りのその他の実装して完成！！

# 今回の成果物

デモURL

https://shisojuice.github.io/Rust_WordsFlow2/


デモ画像

画面(下記は静止画ですが、実際にはパラパラ自動で流れる)

![RustとWebAssemblyでパラパラ文字作ってみた_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/e4748607-eddf-91aa-5e78-c8f68ba68ea6.jpeg)

ソース

https://github.com/shisojuice/Rust_WordsFlow2


# まとめ

今回はRustを使ってGifのようなパラパラ文字作ってみました。🧑‍🎨

正直Gif使えば済む話なので、、、

何の役にも立ちそうにないが、気になったので

記事にしました。💪


※間違い等ありましたら、ご指摘いただけると助かります。
Qiitaで見たReactロードマップを実践する ~簡単な個人開発編~

# はじめに
今回はQiitaで見たReactロードマップの最終ステップである簡単な個人開発をやってみました。以下参考記事とこれまでの記事です。

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

https://qiita.com/bisketoriba/items/dde798808498d0c26c42

https://qiita.com/bisketoriba/items/bf8dfa9cd4c4d0e17739
# ルール
簡単な個人開発をする上でロードマップでは以下のような条件が与えられていました。
```
- 1週間以内にできる規模のものを作る
- そのアプリをちょっと実用性のあるものにする (何か課題を解決してくれる)
- 極力いままで学んだことを生かして作る (新しい技術を使う試みは控える)
```

このルールに適した題材として今回はReactに関する簡単なクイズアプリを作成しました。正直このアプリ自体は1~2日で一通り完成したので、ロードマップが求める水準の個人開発ができているかは怪しいですが一応ルールは守っているのでこれでよしとします。
# 作ったもの
gif作り慣れておらず適当ですみません💦 コードは[こちら](https://github.com/hirohiro-sys/react-roadmap/tree/main/STEP4/quiz-app)になります。
![quiz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/152beeff-5495-c0ce-a791-dd1a47c4d544.gif)

Reactに関する4択のクイズアプリで、5問で15秒の時間制限を設けてあります。今回はChakra UIを使って見た目を作ったのですが、モーダルやアラート等が予めコンポーネントとして用意されてるので結構便利だと思いました(環境構築も楽)。figmaというツールでデザインしたものをChakra UIのコードにもできるみたいなので今後も使っていきたいです。


# ロードマップを終えての感想
結論から言うと自信を持ってReactを使えます！っていうレベルでは全然ないけどReact入門者から初心者にはなれたかなと言う感じです。よくある教材が羅列されてるロードマップとは違い結構アウトプットを重視しているのでアウトプットのいい練習になると思います。また実際の開発ではReactだけで開発する機会はほぼないと思うので別途バックエンド周りは学習が必要かと思います。

# おわりに
次はNext.jsをやってみたいです。

# 追記
最近同著者の方が新しいロードマップ記事をあげてくれているので、今からやるならそちらの方がいいかもです。

https://qiita.com/Sicut_study/items/7d8c6f309dddda1a3961
【DB設計】正規化をシンプルに考える

# はじめに

DB設計をする上で、「**正規化**」が大事だと思われますが、そもそも正規化って何かと思い書籍を漁るも、第一〜第三正規形まで全くわかりませんでした。

ですが、学習を進める中でシンプルに考えると正規化への理解が容易になったので、備忘録としてこの記事を残そうと思います。

下記の動画は正規化を学習する上でかなりわかりやすいのでおすすめです。

https://youtu.be/WEmY9s0Ky88?si=e5gcszbs9lpa5GFY

# シンプルなやり方

#### 横の繰り返しをなくす
#### 縦の繰り返しをなくす
#### 1:多のテーブルを必要な分用意

これらにつきます。次は順追ってやってみます。

## 横の繰り返しをなくす(第一正規形)

繰り返しの項目が排除されていないテーブルを用意(**非正規化**)して、横の繰り返しをなくします。

例えば、学生とその教科の点数を管理する場合、次のように「国語」「数学」「英語」を「教科」にまとめます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772961/2a234a8e-bccf-068b-7a93-620f05cd0303.png)

## 縦の繰り返しをなくす(第二正規系)

次に縦の繰り返しをなくします。繰り返されている部分を見極めて、1対多の関係を持つ別テーブルを作成します。

今回の場合、氏名が繰り返されているので、別のテーブルを用意してまとめます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772961/579a6554-3742-7e82-0c8b-fa96b26fa1ed.png)

## 縦の繰り返しをなくす(第三正規系)

同様に、縦の繰り返しがあれば、1対多の関係を持つ別テーブルを作成します。

まだ、教科の部分で繰り返しがあるので、新しいテーブルを作成してまとめ、外部キーで繋ぎます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772961/5d27115f-405d-a021-71c2-b012a885818b.png)


これで正規化（データの繰り返し項目、重複をなくし、整合的にデータを取り扱えるように設計されたテーブル）の完了です。

# おわりに
いかがだったでしょうか。
今回の例は簡単なものでしたが、基本的な考え方は一緒だと思われます。

今でも第一〜第三正規形までの完全な理解には到底及んでおりませんが、考え方がシンプルになり、もっと理解の深まる日が来るだろうと感じています。

この記事が、正規化の基本を理解する助けになれば幸いです。

もし、この記事の内容に不備や改善点などがありましたら、ご指摘いただけると嬉しいです。

# 参考

#### この記事の参考内容

https://youtu.be/WEmY9s0Ky88?si=e5gcszbs9lpa5GFY

https://proengineer.internous.co.jp/content/columnfeature/6480

#### 学習書籍おすすめ

https://www.amazon.co.jp/%E3%83%9E%E3%83%B3%E3%82%AC%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9-%E9%AB%98%E6%A9%8B-%E9%BA%BB%E5%A5%88/dp/4274066312/

https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702/
アジャイル専門部隊の一構成員が敢えてウォーターフォールを語るぞ

# アジャイル開発の浸透？なんだそれは。
アジャイル開発という概念が世に出て二十余年（2001年「アジャイルソフトウェア開発宣言」による）、最早、この技術も最新とは言えない、成熟したものとなりました。あなたの職場でも「**アジャイルに進めよう**」的な、**凝り固まらず柔軟なプロジェクト体制にして行こう**という流れ、**プロダクト開発の長大化を防ぎアウトプットを細かく出していこう**という意識変革が内外から求められているかと思います。

しかしプレイヤーとしての皆様は、とはいえ**作るものは変わっておらず納期が決まっている**ので大変になるだけ、だとか、**現場ボトムアップな提案は通らずトップダウンにやることが降ってくる**からやる意味なくね、だとか、果ては**作るもの・仕様が決まってないけど予算がついたからいい感じにアウトプット出して**ね、の意味だとか、都合よく「アジャイル」を使われて疲弊することもあるでしょう。多くは**会社の通例**や**予算検討の流れ**がいまだにアジャイルに沿ってないからであり、一社員がなんともできないところもあり歯痒いものですね。いいの作ることは保証するからお金つけてくれよーー（泣）

# うちの会社はアジャイル無理なんで…
とはいえお金は大事なんですよ。いかなる開発も「**先に**お金・人的コストを払って、**後の**利益・コストメリットを受け取る」ための手段なので、「**何が出来るかわからん**けど**お金はください**」は通らない。
だから、先に要件定義してくれないならアジャイルはうちの会社でやれないんだよねー、、、という~~甘え~~しがらみはいくつも聞いてきてて、まあその通りではありますが、そこは一旦頭まっさらに、どうしたら御社でもアジャイル開発に取り組めるか、想像してみましょ。

いくつかの事例を見てきて私が思うのは、アジャイル開発を開始する（≒お金を貰って開発する）にあたってお偉方とある程度の**コミットメント**（期間までにこれやるって話）を少なからずやらざるを得ないとは上記背景とかからも理解するんだけど、そこで確約する**もの**がよくない例、多いんですよね。つまり、何を作るか（**What**）、どういうアーキで作るか（**How**）、挙句、いつ（**When**）までに完成するかを決めにいく方法。ここってアジャイル開発していくと一番変わる可能性が高いとこなんですよね。

なので、理想的には、ペルソナは誰か（**Who**）、何故作らないといけないのか（**Why**）、そのうえで、作るものではなく（**not product**）どういったことを目標（**KPI**）として評価するかを握りに行けるといいんですよね。~~まあそれができたら苦労せんわい、という声も聞こえてこなくもないですが。~~

# ウォーターフォールはキメゴトを先にするスタイル
さて、~~絵空事は終わりにして~~それでも色々な都合上、ウォーターフォールで！ってケースもあると思うので、じゃあ折角ならいいウォーターフォール開発にしたいですよね。

まあもちろん案件別の向き不向きとかそういう話もあるんですけど、でもやることはアジャイルだろうと、ウォーターフォールだろうと実は本質あまり変わりません。そもそも、**プロジェクトとは「何が課題か」、「何が制約・障害か」を常に切り分けしつづけていくプロセスおよびそのための検証作業**なのですから。

ウォーターフォールは先に確認することを重視します。先にプロジェクトのモヤモヤしたところを明確化することにより、次の工程で**手戻りなく進められること**を期待して動きます。

アジャイルも基本的には先に確認しますが、明確化はそこまで強く求めません。代わりに**多少の手戻りを許容**し、**再度課題・制約・障害を確認するフェーズに戻る**ことを恐れません。

私の理解するかぎり、ウォーターフォールとアジャイルの違いはこれだけです。

# 高度なウォーターフォールはアジャイルに似る？
それなのにウォーターフォールは要件定義が一苦労、なんて言われます。いやしかしながら、アジャイル開発でも要件を全然決めずに、少なくともDevメンバーが思い思いに勝手に作るなんてことはまずありえません。アジャイルでも要件定義（にあたるもの・行為含む）はなんらかの形で実施されますが、大きな違いは、その行動が都度実施されることです。先ほどの通り、やり直しを許容するわけですね。

さて、一般的なウォーターフォールの作業には順番はあります。まずは大きな要求の確認、そして順を追って要件定義、詳細設計とつめていきます。
何故、このステップを踏むかと言えば、やっぱり細かいことは始めからは見えないからですね。だから、外堀から決めていって、これはスコープ外である、このケースは対象外としてよい、と検討を深めていき、ようやっと細かいユースケースへとフォーカスできるようになるわけです。

ここで、ちょっと考えてほしいのは、このやり方って**とてもアジャイル**なんですよ（う～ん哲学ワード）。
何が言いたいかって言うと、ウォーターフォールってやり直しは即プロジェクト遅延につながるから避けたい、そして、本当は最終的に策定したいのは開発そのものの仕様、だけどいきなりそこからは着手は出来ない、そのゴールに一番最短で近づきたいからこそ、外堀から決めていくしかないーーー結果、**わからないからこそ、できることから着実に取り組む**。ほら、これってアジャイルでしょ。

# 要はスタンスの違いってやつね
はい（完）。

ウォーターフォールは正しい中身（プロダクトの完成形）がわからないからこそ、外側から中へぎゅっと閉じ込めていく作業。アジャイルもまた正しい中身（プロダクトの完成形）がわからないからこそ、今できる中身を作りながら外枠を見つけに行く作業。方向性の違いとも言えそうですね。

私の業務は外部の会社様からアジャイル開発案件をいただいたあと、企画側のアシスタント役としてプロジェクトに入っていくかたちが多く、内容によってその都度求められる動き方が変わってくるんですよね。時にごりごりウォーターフォールな出力も求められるわけです。ただ、そのとき「アジャイルじゃないと嫌！」なんて言ってられませんので、そのときに考えるのは今まで書いてきた、ウォーターフォールはスタンスの違いでしかないってこと。本質を忘れなければきっとウォーターフォールだってアジャイルマインドで進められるんよ！