OmniAICreator/Qiita-1.07M huggingface dataset:
RetainCycle(循環参照)とweak/unowned【iOSメモリ管理の基本vol.2】

## はじめに
Swiftでは、オブジェクト同士が互いに参照し合うことでメモリリークが発生することがあります。この問題は「Retain Cycle（循環参照）」と呼ばれ、アプリのクラッシュやメモリ使用量の増加を引き起こす原因になります。
本記事では、Retain Cycleの仕組みとその対策として使われる `weak`, `unowned` について、コード例を交えながら解説します。

本記事に登場するARC(Automaric Reference Counting)についてはこちらの記事で解説しています。

https://qiita.com/kojirotsugaru/items/52fd1cf10117f02f30d9

## 強参照 (strong) とRetain Cycle

Swiftではメモリを参照する方法が２つあり、その１つが強参照 (strong)です。

強参照の特徴
1. 他のオブジェクトが強参照している限り、メモリは解放されない
2. Swiftのデフォルトの参照方法

この強参照とARCが組み合わさることで起こりうるのがRetain Cycle (循環参照) です。

Retain Cycleとは
- 2つのオブジェクトが お互いを強参照 していると、どちらの参照カウントも0にならず、メモリが解放されない＝メモリリークになる現象

以下の例をみてみましょう。

```swift
class Person {
    var name: String
    var pet: Cat?

    deinit {
        print("\(name)は解放されました！")
    }
}

class Cat {
    var name: String
    var owner: Person?

    deinit {
        print("猫の\(name)は解放されました！")
    }
}

var jiro = Person(name: "じろう")
var meow = Cat(name: "ミャオ")

jiro.pet = mewo
meow.owner = jiro

jiro = nil // ⚠️ 何も出力されない
```

上は`jiro: Person`が`meow: Cat`を`pet: Cat?`として持っているといった例です。
`deinit`はオブジェクトが参照されなくなったタイミングで呼び出されます。

最後の行で`jiro = nil`としているのに`deinit`は呼ばれていません。これは、jiroがmeowから強参照されているためです。

## weakとunowned
`weak`と`unowned`はオブジェクトの参照方法を明示的に指定することができるSwiftのキーワードです。主に以下の特徴があります。

| キーワード | ARCカウント | いつ解放される？| Optional |
|:-----------|------------|-----------|------------:|
| `weak`     | されない     |参照先が解放されると解放|Yes
| `unowned`  | されない     |参照先が解放されたらクラッシュする|No

`weak`を使って参照している場合、参照先のメモリが解放されると、自動的に弱参照が消えます。そのため、`weak`を使うことでRetain Cycleを防ぐことができます。
`weak`を用いて上記のコードを修正してみます。

```swift
class Person {
    var name: String
    var pet: Cat?

    deinit {
        print("\(name)は解放されました！")
    }
}

class Cat {
    var name: String
    weak var owner: Person? // // 循環参照を防ぐためweakを追加

    deinit {
        print("猫の\(name)は解放されました！")
    }
}

var jiro = Person(name: "じろう")
var meow = Cat(name: "ミャオ")

jiro.pet = meow
meow.owner = jiro

jiro = nil  // 🔄 このとき Pet → Cat の strong参照がなくなり、Personも解放される
            // ⭕️ "じろうは解放されました！"
            
meow = nil  // 🔄 これで Cat も解放される
            // ⭕️ "ミャオは解放されました！"
```

一方で`unowned`を使って参照している場合、もし参照先のオブジェクトが先に解放されると、アプリがクラッシュしてしまいます。
`unowned`を使うべきなのは、「参照先が自分よりも先に解放されない」ことが保証されているときです。
例えば、アプリ起動中ずっと存在し続けるような `RootView` のようなオブジェクトに対しては、`unowned`での参照が適しているケースがあります。

## まとめ
- Swiftではデフォルトで「強参照（strong）」が使われ、これがRetain Cycleの原因になることがあります

- Retain Cycleとは、2つのオブジェクトが互いに強参照し合うことでメモリが解放されなくなる現象です

- `weak` は参照先が解放されると自動で `nil` になり、循環参照を防げます（Optional型）

- `unowned` は非Optionalで使える反面、参照先が先に解放されるとクラッシュするため、使い所に注意が必要です

- Retain Cycleのリスクがある場面では、`weak` もしくは `unowned` を適切に使うことで安全なメモリ管理が可能になります

## さいごに

お読みいただきありがとうございました！
この記事がSwiftでのメモリ管理やRetain Cycleの理解に少しでも役立てば嬉しいです。
私自身もまだ勉強中の身ですので、もし内容に誤りや不明点があれば、ぜひご指摘いただけると助かります。
一緒に成長していきましょう！💪


## 参照
https://qiita.com/toya108/items/872568c1c9837caf3dfe#%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF%E3%81%AE%E6%A4%9C%E7%9F%A5%E6%96%B9%E6%B3%95

https://www.youtube.com/watch?v=VcoZJ88d-vM&t=274s&ab_channel=SeanAllen
パワーポイントのVBAでコメントを取得する

パワーポイントのVBAでコメントの**返信**を取得する方法が分からなかったのでその方法です。
エクセルVBAと同じようにできると思い込んで余計な検索をしてしまっていました。

# 環境
- パワーポイント2024
- windows11

# コメントを取得
- 以下でパワーポイントすべてのコメントを取得する
- これだとコメントへの**返信**は取得できない


```vb
Sub GetAllComments()

    Dim ppt As Presentation
    Dim slide As slide
    Dim comment As comment
    Dim shape As shape
    
    Set ppt = ActivePresentation

    For Each slide In ppt.Slides
        For Each comment In slide.Comments
            Debug.Print "スライド " & slide.SlideIndex & ": " & " - " & comment.Text
        Next
    Next

End Sub

```

# 新しいコメント
- 返信は最近のofficeの機能で**新しいコメント**というもの
- エクセルだと**CommentThreaded**で取得できるようです
- ただこのオブジェクトはパワーポイントには存在しなかった

# xmlファイルから探す
- pptmをzipにしてxmlファイルを見てみました
- パワポ.zip > ppt > comments > modernCommentxxxxx.xml
- このファイルでcmLstの中にreplyLstというのがあり、これが**返信**の内容になっていました
- オブジェクトブラウザーで探してみるとcommentのメンバーに**Replies**がありました
- 返信が取得できそうです
- [Comment.Replies プロパティ (PowerPoint)](https://learn.microsoft.com/ja-jp/office/vba/api/powerpoint.comment.replies)

```
Property Replies As Comments
    読み取り専用
    PowerPoint.Comment のメンバー
```


# 返信Repliesの取得
- これで返信の内容も取得できました！
- 返信の返信とかはネストして追加できないようなので、ここまで取得できたら終わり！
- 検索するとエクセルのCommentThreadedが出てきてRepliesに気付くまで時間がかかりました

```vb
Sub GetAllComments()

    Dim ppt As Presentation
    Dim slide As slide
    Dim comment As comment
    Dim shape As shape
    Dim re As comment
    
    Set ppt = ActivePresentation

    For Each slide In ppt.Slides
        For Each comment In slide.Comments
            Debug.Print "スライド " & slide.SlideIndex & ": " & " - " & comment.Text
            For Each re In comment.Replies
                Debug.Print "返信：" & re.Text
            Next
        Next
    Next

End Sub
```

# ハイライトの文字
- 文字を選択してコメントを入れた時に、そのハイライトされた文字を取得したかった
- けどこれは簡単にはできないようでした
- ワードの場合はScopeというので取得できるようでした
- [Comment.Scope プロパティ (Word)](https://learn.microsoft.com/ja-jp/office/vba/api/word.comment.scope)
  
- PowerPointもXMLファイルからなら取得できるようです
- comment.xmlファイルのcpとlenからわかるようです
- コメントがあるshapeの5文字目から4文字分がコメント対象のハイライトされた文字になる
```xml
<ac:txMk cp="5" len="4">
<ac:context len="83" hash="1992710558"/>
</ac:txMk>
```


# 参考
- [Comment.Replies プロパティ (PowerPoint)](https://learn.microsoft.com/ja-jp/office/vba/api/powerpoint.comment.replies)
- [Excel VBAのCommentとCommentThreadedのプロパティ＆メソッドを比較する一覧](https://www.relief.jp/docs/excel-vba-list-comment-commentthreaded.html)
ずっと「チータ」だと思ってたQiitaで、git add .でハマった話

# ずっと「チータ」だと思ってたQiitaで、`git add .`でハマった話

こんにちは、Next.jsでインターン（まだ学習生段階）やってる学生エンジニアの卵です。
Qiitaのアカウント作るまでずっと読み方「チータ」だと思ってましたが、正しくは「キータ」なんですね。この読み間違いは**結構あるある**のようですね。
chatGPTに「チータ」って言ったら訂正せず「チータ」のまま返事してくるから多分あれは接客業経験してると思います。

そんな私が`git add .`でちょっとハマった話です。


## 結論

**変更点がきちんと保存されていなかった。
`Ctrl + S`や、`Save`では今開いているファイルしか保存されないため、`Ctrl + K` → `S`や`Save All`で全保存する必要がある。**


## 起きたこと

lefthookのエラー箇所を修正し、いざ
```bash
git add .
git commit -m "修正しました"
```
実行せしめん！と思ったのですが、**なぜか修正したはずのファイルが変更されていない。**
`Ctrl + S`で保存したのに。


## 原因：保存は今開いているファイルだけだった

VSCodeなどでは、`Ctrl + S`は今開いているファイルのみを保存する仕様でした。
そのため他のタブにあるファイルの変更は保存されていませんでした。

最初に`git add .`した時はこまめに`Ctrl + S`をしていたからうまく変更が保存されていたようです。

## 解決策：ちゃんと保存しよう

### エディタのメニューバーから全保存
  - `File` > `Save All`

### ショートカット
  - **VSCode** : `Ctrl + S` → `K`
  - **Cusor** : `Ctrl + M` → `S`

これで**すべてのタブが保存されます。**
全保存後に再度
```bash
git add .
git commit -m "○○を修正しました"
```
を実行するとちゃんとエラー箇所が修正されていました。


## 補足：自動保存をオンにしておくと安心

VSCodeなどでは、設定方法は
- `File` → `Auto Save`

これにチェックを入れておけばいいです。


## Qiita初投稿に寄せて

**チータじゃなくてキータ**、
ワイヤレス充電のQiは「チー」、難しいですね。
大初心者ですがこれから技術ログや詰まったところなどを発信していきます！
デザイナーが学習歴3ヶ月でミニアプリを開発してみた【React × TypeScript】

## はじめに

初めまして、UX/UIデザイナーとして活動しているKikoといいます。
デザインエンジニアになることを目標に今年の1月からReactの勉強を始めました！

自分の簡単な自己紹介はこちら👇

https://qiita.com/kikotkk/items/b702b6c3a227690eeec6



## 3ヶ月でやったこと
ReactとTypeScriptを使ってミニアプリを開発し、最終的には CI/CD の構築まで行いました。
1-2ヶ月目はCSS などの装飾を行わず、React の基本を押さえたシンプルなアプリを作成しました。
そして今回はそのベースをもとに、React Hook Formや React Testing Libraryなどを取り入れながら、実践的な機能を段階的に追加していきました。

![1-ezgif.com-video-to-gif-converter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977506/68f069c5-8c31-4ebc-bef6-79a0eaede19e.gif)


#### 使用言語
- React
- TypeScript

#### バックエンド / DB
- Supabase

#### テスト
- Jest
- React Testing Library

#### UI / フォームまわり
- Chakra UI
- React Hook Form

#### ビルド / 開発環境
- Vite
- Firebase Hosting


## 苦戦したこと
TypeScript のtypeやclassといったオブジェクト指向の概念を理解するのに苦労しました。

また、テストを進める段階で設計の甘さに気づきテスト直前で慌ててリファクタリングを行うなど、見直しが多く発生しました。

しかし**突然サービスを終了しても依存が少ないUIを提供できるように設計する** という開発においてかなり大事なことが早い段階で学べて良かったです。こういった体験はコミュニティに所属する恩恵だと感じました。

![スクリーンショット 2025-04-13 19.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977506/4866b648-3507-48ab-910b-366acd168af8.png)


## 課題での気づき

この課題を進める中での気づきは初歩的なものであっても、随時記事にまとめていきました。

https://qiita.com/kikotkk/items/e5995e5764914a09a791

https://qiita.com/kikotkk/items/f075295497535a1b9e58



## AIとの向き合い方
今回もがっつりAI（chatGPT4o）を使いました。
React専用のGPTsを作り、キャンバスでラリーをしながらコードを書いていきました。
![スクリーンショット 2025-03-06 8.30.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977506/ec448a25-99e6-4749-a758-aba9a0e6c925.png)

AI補助無しでやるのもありだと思いますが、プログラミング経験のあまりない初学者には**現状の自分では辿り着けない概念を使わなければならない場合もある**ので、その点においては諸学者がAIを導入することはやはり欠点より利点の方が優ると思いました。とんでもない方向で進めてしまってスタックし、モチベーションが下がることを回避できるからです。

とはいえ何でもかんでもAIに聞くと身にならないので、悩む時間は決めてから（私の場合は15分）取り組みスタックしたらAIへ聞くようにしました。

## Next Step
いよいよ次回から個人開発を見越して、自分の作りたいアプリの像を詰めていくことになります。
なので少しずつでも運用前提で設計できるように意識していきます。開発は誰かが使ってくれることがゴールなので、少しずつ練習から本番へとマインドセットをシフトさせていきたいです。


## JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！

https://projisou.jp/
新卒1年目がClaudeを使ってみた（第2回）

株式会社テンダに入社した新卒社員が、話題の生成AIである「Claude」を使ってみました。

本記事では「Claude」の活用にあたり他の生成AIとの比較から検証結果などを紹介致します。 
利用にあたっての必要な前準備や登録方法、実際の使用感などは第1回にて紹介しておりますので、下記のリンクからご確認下さい。 

[新卒1年目がClaudeを使ってみた（第1回） #生成AI - Qiita](https://qiita.com/SK_12/items/5759679b873c54caf147)

# 目次
- [憲法AIとは](#憲法AIとは)
- [他の生成AIとの比較](#他の生成AIとの比較)
- [検証](#検証)
- [まとめ](#まとめ)


# 憲法AIとは
第1回で概要や特徴についてご紹介しましたが、Claudeには大きな特徴がもう1つあります。それが「憲法AI」です。

**憲法AIとは**
「憲法AI」の原則は国連の世界人権宣言やGoogle DeepMindなど他のAI企業が提案するガイドラインを基に構成されており、生命、自由、個人の安全を尊重し、不適切、無神経、嫌悪感を与えるコンテンツを避けるよう設計されています。Claudeは、人間からの直接のフィードバックの代わりに、これらの原則に基づいて別のAIモデルが生成した回答例を使用して訓練されています。<br><br>

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/3ad38bfe-b2bc-462f-91f4-a0da52157c23.png)
実際に上記の様なプロンプトを送ってみたところ、回答を避けられました。

# 他の生成AIとの比較
|            | Claude      | ChatGPT | Gemini        |
|------------|------------|---------|--------------|
| **開発元**　| Anthropic  | OpenAI  | Google       |
| **最新版** 　| Claude3    | GPT-4   | Gemini 2.0 Flash　 |
| **利用形態** | Web/API   | Web/API | Web/API      |
| **基本料金** | 月額/従量制 | 月額制  | 月額制       |
| **日本語対応** | 〇        | 〇       | 〇           |

※記事公開時点

実際にClaudeに上記の表を図解して貰いました。
![ai-comparison-chart (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/461c621a-39cb-4c4d-bcdb-f2994ed99dba.png)
表の内容を正確に把握して視覚的にも分かり易くまとめられています。 

# 検証
今回は、実際に第1回の原稿をClaudeに送り、図解を用いてまとめて貰いました。
送ったプロンプトは以下の通りです。 

「こちらのファイルの内容を図解して分かり易くしてください。」 

するとこの様な内容が返ってきました。 
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/0e867ba3-d300-414d-b83e-930199c39467.png)

「新卒1年目がClaudeを使ってみた（第1回）図解」の内容は以下の様になりました。 
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/c59a5b22-8d60-4cab-83a7-b9acc4180c00.png)

比較の為に、ChatGPTとGeminiにも全く同じプロンプト送りました。 
ChatGPTの場合は、以下の様に返ってきました。 
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/3f06f06b-0261-4c04-bb6f-3455d01f2772.png)

Geminiの場合は、以下の様に返ってきました。 
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3988411/5c3be5c6-5fa8-4655-bffe-e6706012cdb8.png)

3つの内、Claudeだけが**文書ファイルを要約した内容を図解化**してくれました。この事から、Claudeは他の二つに比べて、多機能なだけでなく文書への理解度が高い事が伺えます。 

# まとめ
Claudeは、Anthropic社が開発した生成AIです。特に、「憲法AI」と呼ばれる倫理的な原則に基づいて設計・訓練されている点が大きな特徴です。生命、自由、個人の安全を尊重し、不適切な内容を避ける様に設計されています。 

今回の検証では、Claudeが文書の内容を正確に把握し、様々な図解を行える事が確認出来ました。ChatGPTやGeminiなどの他のAIとの比較においても、Claudeの優れた性能が示されています。 

近年は、AIの悪用による権利の侵害が問題となっています。権利侵害をさけるためにも、Claudeの様なAIを使用することをお勧めします。 

# さいごに 
テンダでは、「こんなプロジェクトに挑戦したい」「こんなチームで働きたい」「理想のチームを創りたい」と願う仲間を求めています。 
カジュアル面談も随時受付中です。ぜひ一度お話ししましょう。 

[募集職種一覧](https://hrmos.co/pages/tenda/jobs)
[カジュアル面談の申込](https://hrmos.co/pages/tenda/jobs/031002/apply)
[テンダで働く人や社風について](https://note.com/tenda_recruit)
[テンダのMicrosoftサービス](URL：https://mssp.tenda.co.jp/)
【iOS】【Windows】WindowsでiOS Safariのインスペクターを使う方法

# はじめに

皆さんこんにちは、株式会社KANGEN Holdingsに所属するフルスタックエンジニアのA.K.です。
**本投稿は、元A.K.チームのメンバーからの内容です。
ご本人のプライバシーに配慮し、ご希望により代理で投稿させていただいております。**

https://github.com/HimbeersaftLP/ios-safari-remote-debug-kit

以前、UbuntuでiOS SafariのWebインスペクタを実行するツールの動作手順の記事を書きましたが、今回は同ツールのWindows版での手順を紹介します。

## 検証動作環境・必要なツール

今回の記事向けに、自宅PCとiPhoneSE2で試しました。

- PC
    - GoogleChrome
    - Node.js
    - git (あれば尚良し)
- iPhoneSE2 (iOS18.3.1)


:::note warn
注意点
- iOS・Windows・Chromeのバージョンアップによって動作しなくなる場合もあるかもしれません
- ツールのバージョン更新が停止する可能性もあるので、当記事の閲覧時点で利用できないかもしれません
:::

## 準備

#### 1. **事前に必要なアプリケーションやツールのインストール**
インストール方法は検索で沢山出るので、今回は省略します。

- GoogleChrome
- Node.js
- iTunes (Apple Mobile Device USB Driverが必要なため)

#### 2.ios-safari-remote-debug-kitのインストール・初期設定

① ios-safari-remote-debug-kitを、gitからcloneする。

```
# コマンドプロンプト(ターミナル)上で操作
cd <任意のディレクトリパス>
git clone https://github.com/HimbeersaftLP/ios-safari-remote-debug-kit
```
:::note
gitを入れてない場合は、下記ページから「<> code ▼」→ 「Download ZIP」でダウンロードを実行して、任意のディレクトリに解凍する。

https://github.com/HimbeersaftLP/ios-safari-remote-debug-kit

:::

② エクスプローラー上で「ios-safari-remote-debug-kit」のディレクトリに移動し、その中の「src」フォルダーを開く。

③ 「generate.ps1」を右クリックでコンテキストメニューを開き、「PowerShell で実行」を選ぶ

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/eb1552ac-d481-4bff-b09e-acbdc67e225d.png)

④ 動作に必要なファイルが自動でダウンロードされ、「Choose iOS version」の入力画面で、iOS端末側のiOSバージョンを入力する。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/70fbb028-1f7b-4eb1-a8e8-5316b04da23c.jpeg)

⑤「Finished!」が出れば完了　

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/aa62da1c-3054-452a-9a89-bccd1d6cf2ff.png)

⑥ コマンドプロンプト(ターミナル)を開き、以下コマンドを実行する

```
npm i -g http-server
```

⑥ コマンドプロンプト(ターミナル)を開き、以下コマンドを実行する


![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/726b9e5c-edd8-45f1-a808-25b36cf8b1c9.png)


## iOS端末を接続し、動作確認

① iOS端末をUSB接続する。
接続したら、iOS側で「このデバイスに写真やビデオへのアクセスを許可しますか?」と出るので「許可」を選択。

②「start.ps1」を右クリックでコンテキストメニューを開き、「PowerShell で実行」を選ぶ

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/a7daeef8-f47f-4f33-9781-17daa4c8b65c.png)

ps1スクリプトを実行すると、ios-safari-remote-debug-kit.exeとPowerShellのウィンドウが表示される。

③ios-safari-remote-debug-kitのウィンドウで、「Connected :9222 to <デバイス名>・(<UUID>)」が表示まで待つ
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/1ebc4f1c-ca8e-497b-9299-8acc04338f55.png)

④上記が表示されたら、PowerShellのウィンドウで「using it to serve the WebInspector」表示されることを確認できたら、

>You can then open http://localhost:8080/Main.htmlws=localhost:9222/devtools/page/1

と表示されている箇所のURLをコピーする。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/f12dd460-ff96-4452-a4ea-407e808ec048.png)

⑤GoogleChromeを開き、コピーしたURLを貼り付け実行。
インスペクタが表示されればOK

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505467/c7bab20c-a6d8-4859-9888-6a0d7643ae99.png)
【EC-CUBE4.3】product テーブルにカラムを追加する　その1

【EC-CUBE】product テーブルにカラムを追加する　その1

## 目的
製品（dtb_product）にもフリガナを登録できるようにしたいとのこと。

## やること
公式ドキュメントを参考に追加してみる。
https://doc4.ec-cube.net/customize_entity

## 手順

### 1. ProductTrait.php を作成
```php
<?php

namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation\EntityExtension;

/**
 * @EntityExtension("Eccube\Entity\Product")
 */
trait ProductTrait
{
    /**
     * @ORM\Column(type="string", nullable=true)
     */
    public $kana;

    public function getKana(): ?string
    {
        return $this->kana;
    }

    public function setKana(?string $kana): self
    {
        $this->kana = $kana;
        return $this;
    }
}

```

### 2. Proxy クラスを生成
```bash
bin/console eccube:generate:proxies
```

### 3. 生成後、定義をデータベースに反映
```bash
bin/console cache:clear --no-warmup
bin/console doctrine:schema:update --dump-sql --force
```

### 4. マイグレーションファイルを作成
```bash
php bin/console doctrine:migrations:generate
```

### 5. dtb_product に kana カラムを追加
作成されたマイグレーションファイルに sql を記述。
```php
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * Auto-generated Migration: Please modify to your needs!
 */
final class Version20250414022130 extends AbstractMigration
{
    public function getDescription(): string
    {
        return '';
    }

    public function up(Schema $schema): void
    {
        $this->addSql("ALTER TABLE dtb_product ADD kana VARCHAR(255) DEFAULT NULL AFTER name");
    }

    public function down(Schema $schema): void
    {
        $this->addSql("ALTER TABLE dtb_product DROP kana");
    }
}

```
### 6. マイグレーション実行
```
php bin/console doctrine:migrations:migrate
```
データベースに「kana」が追加される。（name の後ろ）

### その他
先にデータベースの用意をしておいた方がいいかも？
Copilot演習シナリオ：マーケティング用画像の生成

#### Copilot無償版
## 演習シナリオ
あなたは広告代理店の従業員です。
新しいインターネット接続サービスの販売拡大計画を作成している最中であり、サービスのコンセプトにあった画像を作成する必要があります。
Copilotを活用して画像を生成し、反復対話スキルを使って画像をよりコンセプトに沿うように改善してみます。
## 操作手順
次のようなインターネット接続サービスの広告案を作成しています。
サービス名: SkyNet Connect
ビジョン: SkyNet Connectは、インターネット接続の新しいスタンダードを確立し、誰もがどこでも快適にインターネットを利用できる未来を目指します。
コンセプト: SkyNet Connectは、超高速でどこでもつながる、手ごろな価格の無線インターネット接続サービスです。都市部から田舎まで、どこにいても安定したインターネット接続を提供します。
次のプロンプトを実行して、画像を生成してみましょう。
~~~
私は広告代理店で、新しいインターネット接続サービスの広告を作成しています。
新しいインターネット接続サービスのイメージ画像を生成してください。
"""
サービス名: SkyNet Connect
ビジョン: SkyNet Connectは、インターネット接続の
新しいスタンダードを確立し、誰もがどこでも快適にインターネットを
利用できる未来を目指します。
コンセプト: SkyNet Connectは、超高速でどこでもつながる、
手ごろな価格の無線インターネット接続サービスです。
都市部から田舎まで、どこにいても安定したインターネット接続を提供します。
"""
~~~
次のような画像が生成されました。
![SkyNet Connectは、インターネット接続の新しいスタンダードを確立し、誰もがどこでも快適にインターネットを利用できる未来を目指します。超高速でどこでもつながる、手ごろな価格の無線インターネッ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781299/d3e11ce8-e8ff-4ea2-87f5-d439800daeeb.jpeg)
プロンプトに足りない情報があったため、自分のイメージとかけ離れている画像が生成されています。
サービスコンセプトに沿って、情報を追加します。
~~~
画像のイメージが私の希望とあっていませんでした。
次の情報を取り入れて、画像を修正してください。
・フレーム分割していない1枚絵にしてください
・基本カラーは青系のグラデーションにしてください
・画調は日本の浮世絵に近づけてください
・人間を書くときは楽しそうな表情にしてください
~~~
次のような画像が生成されました。
![フレーム分割していない1枚絵、青系のグラデーション、日本の浮世絵スタイル、楽しそうな表情の人間.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781299/af296397-3eb7-472c-9bc8-a55409b3eeb1.jpeg)

画風や色彩はイメージに近づきましたが、
インターネット接続要素が欠けていることに気が付きます。
次のプロンプトを実行します。
~~~
人物にスマートフォンを持たせてください
~~~
次のような画像が生成されました。
![フレーム分割していない1枚絵、青系のグラデーション、日本の浮世絵スタイル、楽しそうな表情の人間、スマートフォンを持たせた人物.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781299/d0360ca0-3f62-42b9-9eb2-a73ac19e5141.jpeg)

イメージに近い画像が生成されれば、採用してください。

この演習はこれで終了です。
PythonでGUIプログラミング！「無料講座」

こんにちは、韓国在住のsanaです！

先週の金曜日にPython関連おすすめ講義を紹介したところ、多くの方が関心を持ってくださってすごく嬉しく思ったと同時にこんなにも多くの方がITを学んでることを実感し私自身もまだまだ頑張らないといけないなと改めて思いました。

金曜日に紹介した講座の中でPython無料講義（活用編１）があったのですが、今日は1に続き活用編２を紹介しようと思います:star:

活用編２ではGUIプログラミングで複数の画像をまとめるプログラムを作成する講座になります！４時間で習得でき、完全無料講座です!!

GUIはパソコンで使うアプリやゲームを作るときに、ボタンや文字を画面に表示させて、マウスやタッチで操作できるようにする方法でテキストだけのCLIと違って、GUIは見た目でわかりやすいので、誰でも簡単に使えるようになります:point_up:

多くの方がPythonの基礎まではスムーズに学べますが、

:one:初心者レベルから中級者レベルへのステップアップが難しい、
:two:Pythonを使って何ができるかわからない

この2つでPythonの難しさを経験していると思います。

この講座で中級者にステップアップしましょう！:smile::sparkles:


https://u.inf.run/3G9y1M2


（勉強したい分野・特化させたい分野があればそれらの勉強法にあった講義をおすすめします！気軽にコメントください:open_hands_tone1:）

今週も頑張りましょう！　ファイティン～！
PL/I 初心者

programming language oneの略

IBMによって開発された、科学技術計算と業務処理の両方に対応できる汎用プログラミング言語

## 基本構文
```
   /* ファイル定義 */
   DCL IN_FILE  FILE INPUT;
   DCL OUT_FILE FILE OUTPUT;

   /* レコード定義 */
   DCL 1 IN_REC,
         2 ID     CHAR(5),
         2 NAME   CHAR(20);

   DCL 1 OUT_REC,
         2 ID     CHAR(5),
         2 NAME   CHAR(20);

   /* キー・フラグ等 */
   DCL WK_KEY CHAR(5) INIT('');
   DCL HIGH_VALUE CHAR(5) INIT('ZZZZZ');

   /* 開始処理 */
   CALL INIT;

   /* メイン処理 */
   CALL PROCESS;

   /* 終了処理 */
   CALL FINAL;

END MAIN;
```

### PL/Iのデータ型
整数型( Integer )	
　整数値を表現するためのデータ型
	
浮動小数点型( Floating Point )	
　実数値を表現するためのデータ型
	
文字型( Character )	
　文字や文字列を表現するためのデータ型
	
配列型( Array )
　複数の要素を持つデータの集合を表現するためのデータ型
	
構造体型( Structure )	
　異なるデータをまとめて管理するためのデータ型
	
ポインタ型( Pointer )	
　メモリ上の別のデータへの参照を表現するためのデータ型
【AZ-900】スキマ時間で合格した方法

# 初めに
2025/4/12に「Microsoft 認定: Azure Fundamentals(AZ-900)」 試験に合格したので、私の勉強方法を残しておきます。

![スクリーンショット_14-4-2025_164849_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4061134/2a116eed-38d6-441f-88a8-3b427a154248.jpeg)


# 前提知識
__・業務経験3年　Azure、AWS等の開発経験なし__
__・AWSソリューションアーキテクト – アソシエイト（AWS SAA）保有　2022年12月取得__
2年半ほど前にAWSの資格は取得していましたが、残念ながらクラウドの業務経験を積めませんでした、、


# 参考にしたもの
以下の二つです。
__・Udemy　対策講座__
__[合格への近道！Azure Fundamentals AZ-900 試験対策講座](https://www.udemy.com/course/microsoft-azure-az900-video/)__

__・Udemy　問題集__
__[【9万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）](https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/?couponCode=25BBPMXPLOYTRMT)__



Udemyは高頻度でセールをしているので、セールの時に買っておくのがいいと思います。半額くらいになります！
私が買おうと思ったタイミングは定価でしたが、1週間くらい待ったらセールになってたのでAZ‐104の講座と問題集も一緒に購入しておきました。

# 勉強時間
講座と問題集合計で20時間程度です。
4月は転職や引っ越しで、まとまった時間が確保できない中、３週間くらいかけてスキマ時間に解いていました。
__・Udemy対策講座 4時間51分__
  　一通りみて、Azureのサービスについて学習しました。
  
__・Udemy問題集 12～15時間__
 　すべての演習が90%前後とれるようになるまで繰り返しました。（1演習3～4回くらい）
  ![スクリーンショット_14-4-2025_161253_www.udemy.com.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4061134/790ce31f-7237-4833-9e33-186fa1d95763.jpeg)


# 試験本番
見直しの時間含めて30分程度で終了しました。
本番の難易度はUdemyの問題集よりやや簡単だった印象で、Udemyの問題集とほとんど同じ問題も5割程度出題されていたと思います。
AzCopy等の個別サービスについて深く問われる問題が出題されましたが、よくわかりませんでした。
試験終了後は終了ボタンを押すとすぐに点数が画面に出ます。


# 最後に
仕事などでまとまった勉強時間が確保できない中でも、最短で合格ラインに到達できる方法だと思います！
次はAZ-104に挑戦してみようと思います。
「２つの角が60度の三角形は。」をAI先生に聞きました。


???・ Sympy コード（余弦定理で証明）
# ChatGPT先生へ
#### 質問リスト
・質問リストの追番は無視して下さい。１個ずつです。途中の回答表示は省略しています。
```
# 質問リスト  
1. ２つの角が60度の三角形は。  
2. すべての辺の長さがなるのはどうしてですか。  
3. sympy のソースコードで教えて下さい。  
4. 私の質問をMarkdown形式でリスト化して出力して。Markdown形式でリストからアスタリスクは削除して。  1行目に、# 質問リスト　の文字を出力して。
```
>結論
したがって、3つの角がすべて等しい三角形では、3つの辺の長さも自動的に等しくなる、というわけです。これが「正三角形」です。
もっと言えば、これは「三角形の合同条件の逆」でもあり、角が等しいなら辺も等しいという対称性に基づいています。


sympy のソースコードで教えて下さい。
Sympy コード（余弦定理で証明）
```python
from sympy import symbols, cos, Eq, simplify, solve, pi

# 辺の長さを記号で定義（a, b, c）
a, b, c = symbols('a b c', positive=True)

# 各角が 60 度（ラジアンで π/3）
angle = pi / 3

# 余弦定理: c^2 = a^2 + b^2 - 2ab*cos(C)
# 各辺に対して適用（ここでは仮に角が全部60度であるとして）

# 余弦定理の3式（C, A, Bの向かいの辺）
eq1 = Eq(c**2, a**2 + b**2 - 2*a*b*cos(angle))
eq2 = Eq(a**2, b**2 + c**2 - 2*b*c*cos(angle))
eq3 = Eq(b**2, a**2 + c**2 - 2*a*c*cos(angle))

# cos(60度) = 1/2
# 簡単化して辺の等しさを調べる
simplified1 = simplify(eq1.subs(cos(angle), 1/2))
simplified2 = simplify(eq2.subs(cos(angle), 1/2))
simplified3 = simplify(eq3.subs(cos(angle), 1/2))

print("式1:", simplified1)
print("式2:", simplified2)
print("式3:", simplified3)

# 例えば、simplified1 から a = b = c となるか調べる（解を求める）
sol = solve(simplified1, c)
print("c の解:", sol)
```

出力イメージ（一部）
```
式1: Eq(c**2, a**2 + b**2 - a*b)
c の解: [sqrt(a**2 + b**2 - a*b)]
```

# Gemini先生へ

# copilot先生へ

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

https://qiita.com/mrrclb48z/items/b6351b48e47bcf6265c0

# いつもと違うおすすめです。
### wikipedia

https://en.wikipedia.org/wiki/Equilateral_triangle

https://ja.wikipedia.org/wiki/
【Power Automate】よくあるエラー「Apply to each」でつまずくポイントと対処法まとめ

# :cactus: はじめに

Power Automateを使って「自動化」デビュー！…したはいいものの、  
「**Apply to each（それぞれに適用）**」が勝手に出てきてよく分からない…  
そんな経験ありませんか？

この記事では、初心者が**つまずきやすい「Apply to each」問題**と、  
**すぐに使える対策＆簡単な実例**をセットで紹介します！

## ✅ そもそも「Apply to each」って何？

Power Automateでは、**複数のデータを1つずつ処理する**ときに
「Apply to each（それぞれに適用）」が使われます。

たとえば：
- Excelの表にある「顧客リスト」
- SharePointの「タスク一覧」
- Formsの「回答一覧」

などを **`1件ずつ処理したい`** ときに使われます。


## ⚠️ 初心者がつまずきやすいポイントとその対策


### ① 勝手に「Apply to each」が挿入されてしまう

#### よくあるシチュエーション

Excelからデータを取得して、その中の「メールアドレス」列を使ってメールを送りたい…  
→ **動的な値を選んだ瞬間、勝手にループが挿入される！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/dd569d39-7c48-4cbc-9762-d54e92260428.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/362a8e07-f6bb-40ad-a86f-30ee10956fc7.png)


#### 🎯 原因

Power Automateは「**これは配列だ！**」と判断すると、自動的にループを挿入します。

#### ✅ 対策：1件だけ取り出すには `first()` を使う

```ruby:変数の値に入れる式
first(outputs('表内に存在する行を一覧表示')?['body/value'])?['メールアドレス']
```

先ほどの変数の値を格納する場所で動的なコンテンツではなく `式` を選択して
上記の `first()` の関数を入力しOKを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/e5520548-f0e2-4638-b548-92da6b79e518.png)

1件だけ取り出す関数を入力したので先ほどと違い
勝手にループが挿入されることがなくなりました！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/fe348f7d-9c74-4ea5-b237-7c459ab4f226.png)

### ② 「Apply to each」の中でしか使えない値がある

#### よくあるシチュエーション
+ Excelで顧客データを取得（複数行）
+ Apply to each で1人ずつ処理 　- 名前を取得 　- 条件に合う人だけメール送信
+ 処理した名前をあとでまとめて通知したい

でも「名前」などの動的な値が Apply to each の外に出せない！！
式に選んでもエラーになるか、空になる:sweat_drops:

#### 🎯 原因
Apply to eachは、1件ずつ処理する「ループ」スコープの中で動的な値を生成しています。
そのため、その中で得た「Current item（現在のアイテム）」などの値は、ループの中でしか使えません。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/4c6a22ec-5f49-49c6-a255-fcc36aebcbd1.png)

#### ✅ 対策：変数に格納する
Apply to each の中で動的な値を変数に入れておけば
ループの外でも使えるようになります。

**フローの最初にアレイ型の変数を初期化しておく。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/55a1cf82-d5db-4248-a244-313f8f2179b7.png)

**Apply to each の中で変数に値を追加していく**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/41b6470c-94c8-4567-b1e9-027ac0d0751b.png)

**追加した値を結合させて、出力した値をTeamsの本文に添付する**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/3f510f20-1205-4078-82f5-83c3bdef5a56.png)

#### :bulb: おまけ：ループには必ず名前をつけましょう
ループが増えてくると、どの「Apply to each」が何の処理かわからない問題が出てきます。
そんな時は「…」メニューから名前変更をしておくのがオススメです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/22fee9b6-ab37-4906-9b4f-4a4535ba2153.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/b7fb0080-e9b6-4aad-872d-755e9fa096b6.png)

これを行っておくだけでフローが読み返しやすくなります:blush:

### :cactus: おわりに
最初は少しとっつきにくい「Apply to each」ですが、
ポイントさえ押さえておけばとても強力な味方になります！

「なんか勝手にループされる…」と思ったら、
まずはデータの中身が「配列」かを確認しましょう！
【React】Supabaseテーブルに保存した画像を公開URLに変換する方法について

# はじめに
Supabaseのテーブルに保存した画像を表示する際に公開URLに変換する方法でつまずいたため記事にします。
前提条件として当初テーブルに画像を公開URLのまま保存していましたが、テーブルにproject-idが表示されてしまうことから、公開URLではなくファイル名でテーブルへ保存する方法に変えようとしております。

# 解決方法
mapで画像URLだけ取出しsupabaseの公開URL形式に変換する

```.tsx
export const supabaseUrl = process.env.VITE_SUPABASE_URL
```

```.tsx
const SUPABASE_STORAGE_URL = `${supabaseUrl}/storage/v1/object/public/post-images`;


const {data, error} = await supabase
          .from('posts').select('id, title, content, image_url, movie_url').order('created_at', { ascending: false });
        if (error) throw error;

        const postsWithUrls = data.map((post) => ({
          ...post,
          image_url: `${SUPABASE_STORAGE_URL}/${post.image_url}`
        }));

```


# おわりに
これでうまく取得できるようになりました。

<br>

[<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3707255/8bfacf61-7d8d-6d27-cb07-98d1f8f27fcd.png"  width=100%>](https://projisou.jp)
Gatsbi 2.0：論文執筆・技術交底書作成を加速するAIツールを試してみた

## はじめに
研究や開発に関わっていると、こんな悩みはありませんか？

アイデアはあるけど、論文としてまとめるのが大変

新しい研究テーマのブレストに時間がかかる

特許や技術交底書のフォーマットが面倒

Google Scholarで文献を探すのに時間がかかる

そんな時に出会ったのが「[Gatsbi 2.0](https://www.gatsbi.com)」というAIベースの研究支援ツールです。
実際に使ってみて、思っていた以上に“使える”と感じたので、Qiita向けに紹介記事を書いてみました。
## 🔧 Gatsbi 2.0 とは？
Gatsbiは、研究テーマを入力するだけで、構成済みの論文や技術文書を生成できるAIツールです。
Google Scholarと連携し、最新の研究トレンドをリアルタイムに取得、さらにTRIZなどの思考法をベースに、15以上のイノベーション提案を出力できます。
## 🧪 主な機能と特徴
| 機能名 | 内容 |
|--------|------|
| **Gatsbi Innovator** | テーマを入力すると、関連文献を参照しつつ、複数の研究アイデア・新規性を提案 |
| **Gatsbi Writer** | 概要やメモを入力すると、論文構成（概要・関連研究・方法・結果・考察など）を自動生成 |
| **特許モード** | 技術内容をもとに、交底書ドラフトを生成。特許文書の構成や言い回しも自動化 |
| **Google Scholar連携** | 最新の論文を取得し、要約・引用リストに自動反映 |
| **Webベース対応** | ダウンロード不要。ブラウザ上でそのまま使える。英語・日本語対応あり |
## 👨‍🔬 実際の使い方（例）
### テーマを入力
- 例：「大規模言語モデルにおける長期記憶の保持メカニズム」
### 出力例（Gatsbi Innovator）
- 記憶効率向上のための階層構造提案
- エピソディックメモリと注意機構の融合モデル
- 外部メモリとのI/O最適化による推論速度向上

![Gatsbi-innovation-process.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4061170/e84024fa-7cb6-4c1b-b369-497bb3a204b5.gif)
### ワンクリックで草稿生成
![paper.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4061170/e1ee638b-43da-466f-8b3b-db06e40b567a.gif)
### 特許ドラフトモード
- 要素分解 → 問題→ 解決手段 → 効果
- 法的観点に配慮した記述に自動変換
## 💬 使ってみた感想
- 正直、以下の3点がとても助かりました：
- 調査＋構想＋下書きまでを一気にできる
- 構成が論理的で、手直しが少ない
- 面倒な図表・参考文献の自動生成が便利
とくに研究初心者や、「1週間で論文を出したい」という状況では非常に重宝すると思います。
## 📌 注意点・向いていないケース
- 機械的な出力なので、最終的な人間のレビュー・修正は必須です
- データ分析・実験結果の「捏造」はもちろんNG（Gatsbiは補完はしますが、事実に基づくデータは提供しません）
- 新規性や文献の質を判断する力は、ユーザーに求められます
## 🔗 まとめ
- Gatsbi 2.0は、“考える時間”を最大化するためのAI共著者ツール
- テーマから論文草稿までを一気通貫で生成可能
- 技術交底書や特許文書にも対応し、研究だけでなく実務にも使える
- 気になった方は、Web版をぜひ試してみてください（Proプランで無制限利用可能）。
👉 [gatsbi.com](https://www.gatsbi.com)
Pandasの基本的な使い方

# はじめに
`pandas`とは、データ分析やデータ操作に用いられる`Python`のライブラリの一つです。この記事では`pandas`の基本的な使い方を簡単にまとめました。

# Pandasのインストール
まずはインストールからです。
ターミナルを起動し、下記のコマンドを実行します。
```python:install
pip install pandas
```
これでインストールが完了しました。
簡単ですね。
では、ちゃんとインストールされているか確認してみましょう。
```python:Mac&Linux
python -c "import pandas as pd; print(pd.__version__)"
```
```python:Windows
python -c "import pandas as pd; print(pd.__version__)"
```
上記を実行し、バージョンが表示されたらインストール完了しています。
# Pandasの使い方
準備出来たので早速やってみましょう。
pandasを使用する為に`import pandas as pd`でインポートをします。
```python
import pandas as pd
```
pandasは様々な形式のファイルからデータを読み込む事が出来ます。試しにCSVファイルを読み込み、データの確認をしてみましょう。
```python
# CSVファイルの読み込み
df = pl.read_csv("data.csv")

# データの確認
print(df.head())
```
特定の行を表示することも可能です。
```python
# 最初の5行を表示
print(df.head())

# 最後の5行を表示
print(df.tail())
```
そして、特定の列のデータを抽出したり、データのフィルタリングをする事も出来ます。
```python
# 'sample'列のデータを表示
print(df['sample'])

# 条件に基づいてデータを抽出
filtered_df = df[df['sample'] > 10]
```
加工したデータを新規保存するには下記を実行する事で保存出来ます。
また、Excelファイルとして保存する事も可能です。
```python
# データを新しいCSVファイルに保存
df.to_csv('output.csv', index=False)

# Excelファイルに保存
df.to_excel('output.xlsx', index=False)
```
# まとめ
少々駆け足になりましたが、以上が`pandas`の基本的な使い方になります。
`pandas`はExcelの様にデータ操作が出来るので表形式のデータ処理が簡単かつ膨大なデータ量にも対応出来る優れたライブラリです。
`pandas`を使いこなして、効率的なデータ分析を行っていきましょう。
MCreator/防具

#前の記事:https://qiita.com/yt365/items/420b6ccf2ce3a59b3b4d
今回は、MCreatorで防具を作っていきます。
## テクスチャ
リソースから新規作成→防具のテクスチャを作成を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/cbcb41a4-d04b-4c0e-a531-32a7d985dc30.png)
防具の形や色を選んだら、右上の保存ボタンを押します。
![2025-04-14_16h19_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/ce6ba8d9-89f1-4a0c-9281-4d32a9cc33c4.png)
保存したらアイテムのテクスチャと防具テクスチャが追加されます。
![2025-04-14_16h20_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/92fdd0eb-6055-4ebf-b781-2c4aa4522575.png)
## modの要素
modの要素から＋ボタンを押して防具を選びます。
![2025-04-14_16h21_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/d38ed296-19df-497e-b1b4-cfa61f7f69e4.png)
名前を入力したら、防具を手で持った時のテクスチャを設定します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/1d9328c9-cb12-4e8b-8856-87174512f88d.png)
プロパティから防具を装備した時のテクスチャや防具の防御力を設定します。
![2025-04-14_16h33_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/f4b8f1dc-00c0-4b6b-a175-cf8870eaf584.png)
右上の保存ボタンを押します。
## 試してみる
右上の再生ボタンから、マイクラを立ち上げます。
作った防具があるか確かめてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/65e46f96-0107-41f8-8660-929129eb099e.png)
## 終わりに
これで防具を作れるようになったと思います。
テクスチャとか変えれば、模様が違う防具も作れると思います。
#次の記事：https://qiita.com/yt365/items/319e30666113cc9640e2
Ansible学習メモ①（LVM作成、ユーザ管理）

業務で最近Ansibleを使い始めました。私自身はエンジニア職ではないので普段コーディングをほとんどしないです。少しAnsibleがわかるように学習し始めています。

### Ansibleとは
対象マシンの各ソフトウェアのインストール、設定ファイルの編集、パッチ適用などを自動化できるツールです。

### Terraformとの違いに関して
AnsibleとTerraform両製品は、Devops用の自動化ツールとしてコードに基づき、自動的にインフラ構築～構成管理を実現できるという点でほぼ同じのように見えますが、実は得意とする領域が異なります。

Terraformはクラウドインフラの構築に優れていうことに対して、Ansibleの場合対象インフラ上にソフトウェアやファイルの構成管理が得意なようです。

### Ansible使用例
今回Linux上にAnsibleを実施、対象マシンのOSも同じLinux。

#### 1.LVMパーティションを作成
使用するモジュール：community.general.parted
※こちらのモジュールを使用する前に以下のcollectionをインストールする必要がある。

```
ansible-galaxy collection install community.general
```

マニフェストファイルを以下のように作成
```
---
- name: disk demo
  hosts: all
  become: true
  tasks:
    - name: create partition
      community.general.parted:
        device: /dev/sdb
        number: 1
        flags: [ lvm ]
        state: present

```
マニフェストを実行する。
```
ansible-playbook -i inventory 15.yaml
```

#### 2.Linuxマシン上のユーザ管理
使用するモジュール：ansible.builtin.user

##### 2-1 ユーザ作成
マニフェストファイルを以下のように作成した。
注意事項：Linuxユーザのパスワードは暗号化されるハッシュ値にする必要がある。
```
---
- name: create user account
  hosts: all
  become: true
  tasks:
     - name: create user example
       ansible.builtin.user:
         name: example
         password: "{{ 'password' | password_hash('sha512', 'mysecretsalt') }}"
         groups:
           - wheel
         state: "present"
         shell: "/bin/bash"
         system: false
         create_home: yes
         home: "/home/example"
         comment: "Ansible example"
         generate_ssh_key: true
```

##### 2-2 グループ作成
```
---
- name: create group in linux
  hosts: all
  become: true
  tasks:
    - name: create group in linux
      ansible.builtin.group:
        name: 'example'
        state: present
```

##### 2-3 ユーザのPrimaryグループを変更
```
---
- name: user primary group change
  hosts: all
  become: true
  vars:
    myuser: "example"
    mygroup: "example"
  tasks:
    - name: change primary group
      ansible.builtin.user:
        name: "{{ myuser }}"
        group: "{{ mygroup }}"
```

##### 2-4 ユーザのSecondグループを変更

appendというパラメータですが、groups パラメーターと併用する
yesの場合、
ユーザーアカウントを groups パラメーターに指定したグループに追加する
no　←　defaultの場合、
ユーザーアカウントを groups パラメーターに指定したグループだけに所属
させ、他のグループから削除する

```
---
- name: user second group change
  hosts: all
  become: true
  vars:
    myuser: "example"
    mygroups:
      - adm
      - sys
  tasks:
    - name: change second groups
      ansible.builtin.user:
        name: "{{ myuser }}"
        groups: "{{ mygroups }}"
        append: true
```
AXI Timerで時間測定

# Zynq上で動作させる関数の実行時間を測定したい
- タイマーIPを自作する
- XTime_GetTime関数 
- AXI Timer IP

あたりが挙げられる。ここではAXI Timer IPを用いた実行時間測定の例を紹介する。

## なぜAXI Timer IP
XTime_GetTime関数を以下のように使用すると上手く測定できなかった。常に0しか返らないという現象が発生していたため、PSではなくPLでクロックをカウントしよう、と思った。
一度タイマーIPを自作しようと頑張ったものの、PL側からAXI Slaveの抱えるレジスタに値を書き込むことが出来なかったため既存のAXI Timer IPを使用することに決めた。　手順についてのメモ。

## 実装手順
1. Vivadoでブロックデザインを作成 (zynqとaxi timerを追加したら後は自動で配線してくれる。)
![Screenshot_2025-04-14_16-14-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531876/ee5a55e2-6986-4305-99dc-7ae7f6efcc0c.png)

1. bitstream生成・XSA生成 (GPIOやPL側のクロックは使用していないためxdc不要)
1. vitis起動・プロジェクト作成・プラットフォーム作成・アプリケーション作成
1. 以下のコードをビルド・実行 (一度ビルドしたらエラー表示は消える)・シリアルモニタを確認
```c
#include "xil_printf.h"
#include "xtmrctr.h"
#include "xparameters.h"

XTmrCtr TimerCounterInst;

int init(){
	int Status;
	Status = XTmrCtr_Initialize(&TimerCounterInst, XPAR_AXI_TIMER_0_BASEADDR);
	if (Status != XST_SUCCESS) {
		printf("Timer Initialize Error\n\r");
        return XST_FAILURE;
	}
	XTmrCtr_SetOptions(&TimerCounterInst, 0, XTC_AUTO_RELOAD_OPTION);
	XTmrCtr_Start(&TimerCounterInst, 0);
    return XST_SUCCESS;
}

int main()
{
    int CLKFREQ = 50000000; // 50MHz
    int res;
    res = init();
    if(res)return 0;

    u32 tStart, tEnd;    
    for(int i=0; i<10; i++){
        tStart = XTmrCtr_GetValue(&TimerCounterInst, 0);
        msleep(i);
        tEnd = XTmrCtr_GetValue(&TimerCounterInst, 0);
        // printf("End - Start = %u\n\r", (unsigned int)(tEnd - tStart));
        printf("Time = %.2f us\n\r", 1.0 * (unsigned int)(tEnd - tStart) / CLKFREQ * 1000000);
    }

    return 0;
}
```
## 実行結果
微妙な誤差があるが、許容範囲内。
![Screenshot_2025-04-14_16-18-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531876/cc0fe403-2af5-4d2e-bf8f-3f1f5c5eb7d0.png)

使用するクロック周波数によって修正する必要があるので注意。今回はPSの50MHzを使ったため50Mで除している。除したあとの単位はsのため1000000倍してμsにした。見やすい。

## 参考
https://taltalp.hatenablog.jp/entry/2017/11/10/161512

https://marsee101.blog.fc2.com/blog-entry-3848.html
JSでループ/連番配列作成の書き方

## はじめに
JavaScript でとりあえずループさせたい、とりあえず連番の配列を作成したいという備忘録です。

## forEach
```js
[...Array(4)].forEach((_, i) => { console.log(i); });
```

log
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/ccbe3e07-4164-418c-8c64-dea34bba830c.png)

## 連番配列作成

```js
[...Array(4).keys()]
```

log
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/4e37c704-3faf-4e8a-91df-306d4f1c8a57.png)

```js
[...Array(4)]
```
とすると、配列の中身がundefinedになるので注意！

log
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/de645107-b482-4837-a07c-21abdc2d49b6.png)
rex0220 計算式プラグイン テーブル行IDをセット

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、文字列項目にテーブル行IDをセットしてみます。

# 概要

kintone のテーブル行には、レコード保存時に id が設定されます。
この id は、アプリ内でユニークな値です。
[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、レコード保存時に文字列項目へテーブル行IDをセットします。

※ Ver.89 以降は、ROWID()で行IDを取得できます。

![2025-04-14_15h57_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7a12b83e-2308-4d2b-be9f-090004d4827a.png)

# 操作例

![2025-04-14_16h06_56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5429716c-631c-42b4-a869-75a564cb27bd.gif)


# 計算式プラグイン設定

計算式に「更新日時」を指定することにより、レコード保存後イベントで計算式が実行されます。

![2025-04-14_16h00_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/70f3bc61-4eff-477f-9cf5-2bce1ee2112b.png)


Ver.89 以降：　ROWID()で行IDを取得できます。

```javascript:
// テーブル.番号 NUMBER
ROWNO(テーブル)+1

// テーブル.ID SINGLE_LINE_TEXT
ROWID()
```

Ver.88 以前：

```javascript:
// テーブル.番号 NUMBER
ROWNO(テーブル)+1

// テーブル.ID SINGLE_LINE_TEXT
LET(
  rowid, DIC_ITEM(ARRAY_GET(テーブル,ROWNO(テーブル)),"id"),
  IF(AND(更新日時,rowid!="null"),rowid)
)
```
Feature Flagとは何か知ろう！

## このテーマを扱うきっかけ

私のインターン先でFeature Flagの運用が始まったので、ちょっと触れてみます！

## Feature Flagのメリット

**（1）より早く、ストレスレスで開発できる**

- トランクベース開発が行える

**（2）本番環境でのテストが可能になる**

- カナリアリリース
- ベータリリース
- ダークローンチ
- ドッグフーディング
- ABテスト

[フィーチャーフラグ（Feature Flag）はなぜ必要なのか？](https://codezine.jp/article/detail/14114?p=2)

## Feature Flagのデメリット

- コード量の増加
- フラグの管理コスト
- フラグ同士が依存してしまう

[フィーチャーフラグ（Feature Flag）はなぜ必要なのか？](https://codezine.jp/article/detail/14114?p=3)

## Feature Flag使用時の注意点

- 1つのフィーチャーに関するフラグを複数のレイヤーに挿入することは避ける
- 振る舞いを切り替えたい箇所からフィーチャーフラグへの依存を分離する
- 役割を終えたフィーチャーフラグを削除する仕組みを作る

[フィーチャーフラグ（Feature Flag）導入と運用のベストプラクティス](https://codezine.jp/article/detail/14442?p=4)

## Feature Flagには4種類ある

https://speakerdeck.com/revcomm_inc/feature-flagnituiteben-qi-chu-sitekao-eteshi-jian-sitemita?slide=43

↓XPの有名人マーティン・ファウラーさんの元資料
https://martinfowler.com/articles/feature-toggles.html


### Feature Flagの種類まとめ

| **Toggleの種類** | **目的** | **主なユーザー** | **持続期間** |
| --- | --- | --- | --- |
| **Release Toggle** | 機能の段階的リリース | 開発者 | 短期（数日〜数週間） |
| **Experiment Toggle** | A/Bテストなどの実験 | プロダクトチーム | 短期（数日〜数週間） |
| **Ops Toggle** | システム運用の制御 | 運用チーム・SRE | 中〜長期（数週間〜数ヶ月） |
| **Permission Toggle** | ユーザーごとの機能制御 | サポート・管理者 | 長期（数ヶ月〜年単位） |

| **軸** | **デプロイごとに変更** | **リクエストごとに変更** |
| --- | --- | --- |
| **変更タイミング** | アプリのデプロイ時 | リアルタイム |
| **実装方法** | 設定ファイル・環境変数 | DB・キャッシュ・API |
| **対象のトグル** | Release Toggle, 一部のOps Toggle | Experiment Toggle, Permission Toggle, 一部のOps Toggle |
Claude Desktopで「spawn node ENOENT」

　Nodeでmcpサーバーを作成していたところ、spawn node ENOENTエラーで引っかかり。。


https://github.com/modelcontextprotocol/servers/issues/760

などを確認するに、nodeの場所がわからずに、エラーになっていた模様。


$ which node

    "mcp-server-sample": {
      "command": "/Users/username/.nodebrew/current/bin/node",
      "args": [
        "/Users/username/github-repos/demo/build/index.js"
      ]
    }

上記のように設定すると動きましった。
【ゲーム制作】マップを歪めてランダム感を出してみた

## はじめに
　先日、ダンジョンマップをランダム生成する記事を書きました。今回の記事は、その続きの内容となっています。

https://qiita.com/Prosamo/items/40f3847240f473edb209

## 概略
　今回の内容に入る前に、前回の記事の概略を説明します。前回の記事では、マップをグリッドに分割し、それを深さ優先探索することで、マップを生成しました。生成されるマップは以下のような見た目です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922095/45cfb214-8315-4f80-9fe1-e04e90412eaf.png" width=500>


　スタート地点からゴール地点までのルート自体はランダムに生成されていますが、グリッドは正方形の形を取るので、規則正しさが出てしまっています。今回は、生成後にこれを「歪める」ことによって、よりそれっぽいマップを作っていきます。

## 手法
　では歪め方について説明します。マップのタイル情報は、二次元リストに格納しているので、以下のようにすることで、縦横にずらすことができます。

```python: 縦にずらす
column = [row[x] for row in map_data]  # x列を抽出
shifted_column = column[n % len(column):] + column[:n % len(column)]  # 縦にn個シフト
for i in range(len(map_data)):
    map_data[i][x] = shifted_column[i]  # 元の列を更新
```

```python: 横にずらす
row = map_data[y]  # y行を抽出
shifted_row = row[n % len(row):] + row[:n % len(row)]  # 横にn個シフト
map_data[y] = shifted_row  # 元の行を更新
```

このずらし方を上手く組み合わせることで、地形っぽさを出すことができます。どんな地形にするかによって`n`の決め方を工夫することで、ある程度調整が可能です。

### テクニック
　ただランダムに`n`を選ぶだけでは、あまり地形っぽさが出ないので、2つテクニックを紹介します。
#### 一段ずつずらす
```python
a = min(1, n + 1)
b = max(-1, n - 1)
n = random.choice([a, b])
```
純粋に`-1`～`1`のランダムから選ぶよりも、隣の列とのズレは1になるように調整することで、より地形っぽさが出ます。

#### 複数行をまとめてずらす
```python
for y in range(0, len(map_data)-m, m):
    n = pyxel.rndi(0,1)
    for i in range(m):
        row = map_data[y+i]
        shifted_row = row[n % len(row):] + row[:n % len(row)]
        map_data[y+i] = shifted_row
```
`for`で行を取り出す時点でm行ごとに取り出し、起点からm行を同じ方向にずらすことで、縦と横の両方を毎行ずらすよりも、地形っぽさが出ます。

　以上のテクニックを組み合わせて出来たマップは、こんな感じの見た目になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922095/e955015c-699c-46d3-8388-6726ac30e849.png" width=500>

## 利点
　生成する段階でランダム性を持たせるよりも、ある程度大枠を作ってから歪める方が、実装が簡単でした。また、大枠を生成する段階で、一番遠い行き止まりをゴールとするようにしてあるので、歪めた後の一見ランダムなマップでも、ある程度の長さが担保されます。当然、ゴールにたどり着けることも保証できます（歪め方には限度がありますが）。また、自分で調整しながら歪められるので、複数のタイルで壁の模様を構成するような場合にも適用が可能です。例えば森のステージなどを作る際に、2x2の木を歪めずにランダムなマップを一から生成するのは困難に思うので、この点は大きい利点だと考えています。

## 最後に
　ここまで読んで下さりありがとうございました。今回考えた方法以外にも、地形らしさを出しながら、マップを自動生成する方法はたくさんあると思います。アプローチの一つとして捉えていただければと思います。
関数型言語の視点から見るReact

## 関数型言語ってそもそも何？

[**関数型プログラミングとは？**](https://terupro.net/react-functional-programming/#rtoc-1)

- 手続き型言語
    - 文で記述する
    - 何をするか、を記述する
- 関数型言語
    - 式で記述する
    - <font color="Red">何であるか</font>、を記述する

## Reactが関数型言語の思想を受け継いでいるメリット

- htmlの形式に近いJSXで返すのでわかりやすい（何であるか、が記述されている）
    
    https://zenn.dev/ababup1192/articles/ebc5ff81f92a88#react%E3%81%AE%E9%96%A2%E6%95%B0%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%92%E6%8E%A1%E7%94%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E9%83%A8%E5%88%86


    
- propsの値が不変であること（イミュータブル性）
    
    https://terupro.net/react-functional-programming/#rtoc-5
    

## Reactの参照透過性

関数型言語には参照透過性という同じ引数であればいつでも同じ値を返すという特徴がある

- React公式でも純粋関数にすることが望まれているが、実は副作用も認めている
    
    https://ja.react.dev/learn/keeping-components-pure#side-effects-unintended-consequences
    

<aside>

**useEffectを避けるべき理由は関数型言語の思想にあり！**

</aside>
TIPS:BlockNoteを使ったときにSuggestionMenuのMediaを消したいとき

BlockNoteを使ってますか？

https://www.blocknotejs.org/docs/ui-components/suggestion-menus

Notionみたいに書けて、ユーザーフレンドリーで素晴らしいOSSですよね。
これを使って機能提供したいけど、スモールスタートしたくて、ファイルアップロード系のMenuを消したなぁと思ったので、無理矢理やってみました

## Sample

```typescript
import { BlockNoteEditor, filterSuggestionItems } from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import {
  DefaultReactSuggestionItem,
  getDefaultReactSlashMenuItems,
  SuggestionMenuController,
  useCreateBlockNote,
} from "@blocknote/react";

// defaultのSlashMenuItemsからMedia Groupに所属するものを排除します
const getCustomSlashMenuItems = (
  editor: BlockNoteEditor,
): DefaultReactSuggestionItem[] =>
  getDefaultReactSlashMenuItems(editor).filter(
    (item) => item.group !== "Media",
  );


export const Sample = () => {
  const editor = useCreateBlockNote();

  return (
    <BlockNoteView editor={editor} theme="light" slashMenu={false}>
       <SuggestionMenuController
          triggerCharacter={"/"}
          getItems={async (query) =>
              filterSuggestionItems(getCustomSlashMenuItems(editor), query)
          }
        />
    </BlockNoteView>
  )
};


```

デフォルトのItemsからMedia Groupを抜き、カスタマイズの設定しています。
他にいいやり方もなかったので、このような方法を無理矢理とっています。
Fivetran にて Databricks （クラウド DWH）に書き込む際のステージングストレージに関する注意事項

## 概要
Fivetran の SaaS Deployment で Databricks を Destination として使用する場合、Fivetran 管理下のストレージにデータが配置される点に注意が必要です。セキュリティポリシーに照らし合わせ、この動作を事前に許容できるかどうか確認してください。同様の仕様は Fivetran に限らず他のサービスにも存在するため、運用開始後にセキュリティ違反が発覚する事態は回避しなければなりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/89bacd86-6c66-4091-ada5-f7d36485ccb8.png)

本記事は下記記事の一部です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d5372a04-4384-4eb1-8120-075f8cbbb7e6.png)

出所：[フルマネージドなデータ連携：データ統合の自動化を実現する Fivetran の全貌 #fivetran - Qiita](https://qiita.com/manabian/items/2a760238d3fc1021aae7)

## 詳細
Databricks を Destination として運用する場合、Databricks のクラスター実行履歴を確認すると、Fivetran 管理下のストレージから COPY INTO が実行されていることがわかります。パフォーマンスの観点から推奨される方法ですが、データのソースとなるストレージはあくまで Fivetran 管理下のものが利用されている点に留意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/89bacd86-6c66-4091-ada5-f7d36485ccb8.png)

この挙動は SaaS Deployment 固有のもので、ユーザー自身が管理するストレージを利用したい場合は Hybrid Deployment もしくは Self-Hosted Deployment を選択する必要があります。これら 2 つのモデルを利用する際はプラン変更が必要になる可能性もあるため、導入前にセキュリティ要件とあわせて検討を行う必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/20a40b6b-542e-42e6-aaf6-69b9bbddc034.png)

出所：[Fivetran for Databricks \| Destination Setup Guide](https://fivetran.com/docs/destinations/databricks/databricks-setup-guide#configureexternalstagingforhybriddeployment_1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e78b678a-1221-46be-a7ea-72c5004aef83.png)

出所：[Staging for Databricks - HVR 6 \| Fivetran Documentation](https://fivetran.com/docs/hvr6/requirements/source-and-target-requirements/databricks-requirements/databricks-as-target/staging-for-databricks)

また、Snowflake や BigQuery のセットアップ手順でも同様の記述が見られるため、同様に注意が必要です。

- [Snowflake data connectors by Fivetran \| Destination Setup Guide](https://fivetran.com/docs/destinations/snowflake/setup-guide#optionalconfigureexternalstorageforhybriddeployment)
- [Fivetran for BigQuery \| Destination Setup Guide](https://fivetran.com/docs/destinations/bigquery/setup-guide#optionalvpcserviceperimeterconfiguration)
[Vue.js] v-htmlで挿入されたHTMLに対してあとからJSを適用する

WordPressのフロントエンドにVuejsを利用するに当たって、読み込んだPOSTにあとからスクリプトを適用することを試みました。
コードの部分について、WordPressからは、classによるlanguage設定がないすっぴんの状態（```<code><pre>hogehoge</code></pre>```）で出力されるようにしています。
Twitter Widgetのスクリプトは読み込み済みである前提です

```typescript:コンポーネント内
<script setup lang="ts">
// APIのURLを定義したファイル（/src/config.ts）をインポート
import { API_URL } from "@/config";

// highlight.jsをインポート
import hljs from "highlight.js";
import "highlight.js/styles/github.css";

// ルーティング
import { useRoute } from "vue-router";

import { ref, watch, nextTick } from "vue";

// 要素を参照
const htmlRef = ref<HTMLElement | null>(null);

// ポストをREST APIから読み込む
onMounted(async () => {
	const slug = route.params.postSlug;
	try {
		const res = await fetch(`${API_URL}posts?slug=${slug}`);
		if (!res.ok) {
			error.value = `ステータスエラー: ${res.status} ${res.statusText}`;
			return;
		}

		const data = await res.json();

		if (data.length === 0) {
			error.value = "該当する記事が見つかりません";
		} else {
			post.value = data[0];
		}
	} catch (e) {
		error.value = `通信エラー: ${e.message}`;
		console.error("Fetch error:", e);
	}
});

watch(
	() => htmlRef.value,
	() => {
		if (htmlRef.value) {
			// Highlight.js
			hljs.highlightAll();
			console.log("Highlight.js 適用");
			// twitter widgets
			window.twttr.widgets.load();
			console.log("Twitter widgets 適用");
		}
	},
	{ immediate: true },
);
</script>

<template>
	<main class="container mx-auto max-w-6xl px-4">
		<div v-if="post">
			<h1 v-html="post.title.rendered" class="mb-4 text-2xl font-bold" />
			<div
				v-html="post.content.rendered"
				ref="htmlRef"
				class="wp-post-content"
			/>
		</div>
		<div v-else-if="error" class="text-red-600">{{ error }}</div>
		<div v-else>読み込み中...</div>
	</main>
</template>
```

```ts:/src/types/twitter.d.ts
export {};

declare global {
	interface Window {
		twttr?: {
			widgets: {
				load: (el?: Element) => void;
			};
		};
	}
}
```
正確なパフォーマンスを測定するために架空のファイルを作成して転送を試す方法

ディスクやNWの性能(速度)がどのぐらい出るかわかりやすくやる方法
大まかにはファイルをコピーしながらタスクマネージャーやパフォーマンスモニターを見ながらやることがおおい

数百GB以上のテストファイルを作成して厳密にやろうとするとき便利な方法として
"fsutil.exe"というコマンドを使用して作成することができる

# コマンド(用途説明)

fsutil file createnew ＜ファイル名＞ ＜サイズ＞
＜ファイル名＞： 作成したいファイルの名前。すでに同名のファイルやフォルダが存在しているとエラーなので、必要ならあらかじめ削除しておくこと
＜サイズ＞： 作成するファイルのサイズ。10進数か、「0x」で始まる16進数形式で指定する。指定可能な最大サイズは対象となるファイルシステムや空き領域サイズによる

# 使用方法

※10進数指定の場合
fsutil file createnew testfile 107374182400

※16進数指定の場合
fsutil file createnew testfile 0x1900000000

# 実例
①コマンドプロンプトを起動する

![fsutil1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827128/2e57ceff-e37e-4e2e-8fb3-abb76a9158ce.jpeg)

②Dドライブ直下に100GBの空白ファイルを作成する
"fsutil file createnew testfile 102400000000"

![fsutil2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827128/b95871a5-c78e-47cc-9de4-5c19ddc2578f.jpeg)

③作成されたファイルを確認する
以下の画像の通りになっていれば成功となる。

![fsutil3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827128/85a24cce-1e19-4316-8ef4-8c2ca86c1d27.jpeg)

プロパティのｇ
![fsutil4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827128/cfe7097a-1be8-4ebe-9b41-2a39cff39e0c.jpeg)