OmniAICreator/Qiita-1.07M huggingface dataset:
【Go】WebフレームワークをGorillaMuxからGinに移行するメリットと実装例

こんにちは！フリーランスエンジニアのこたろうです。
今回は、GorillaMuxからGinへのフレームワーク移行について、実践的な知見を共有します。

## Webフレームワークの選択

### Gorilla Muxの特徴
- 標準パッケージ（net/http）との高い互換性
- シンプルなルーティング機能
- カスタマイズ性の高さ
- 学習コストの低さ

### Ginの主な利点

1. **高いパフォーマンス**
   - ルーティングの高速化
   - メモリアロケーションの最適化
   - 並行処理の効率化

2. **充実した機能**
   ```go
   // パラメータのバインディング
   var json struct {
       User string `json:"user" binding:"required"`
       Pass string `json:"pass" binding:"required"`
   }
   // 自動的にバリデーション
   if err := c.ShouldBindJSON(&json); err != nil {
       c.JSON(400, gin.H{"error": err.Error()})
       return
   }
   ```

3. **便利なミドルウェア**
   ```go
   // ログ出力
   r := gin.New()
   r.Use(gin.Logger())
   
   // リカバリー（パニック処理）
   r.Use(gin.Recovery())
   
   // カスタムミドルウェア
   r.Use(AuthMiddleware())
   ```

4. **エラーハンドリングの改善**
   ```go
   // Ginの場合
   c.JSON(http.StatusBadRequest, gin.H{
       "error": "Invalid parameter",
       "details": errors,
   })
   
   // Gorilla Muxの場合
   w.Header().Set("Content-Type", "application/json")
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
       "error": "Invalid parameter",
       "details": errors,
   })
   ```

## パフォーマンスの比較

```plaintext
ベンチマーク結果（リクエスト/秒）
- Gin: ~93,000
- Gorilla Mux: ~65,000
```

## 開発効率の向上

1. **コードの簡潔さ**
   ```go
   // Ginの場合
   r.GET("/user/:id", func(c *gin.Context) {
       id := c.Param("id")
       c.JSON(200, gin.H{"id": id})
   })
   
   // Gorilla Muxの場合
   r.HandleFunc("/user/{id}", func(w http.ResponseWriter, r *http.Request) {
       vars := mux.Vars(r)
       id := vars["id"]
       w.Header().Set("Content-Type", "application/json")
       json.NewEncoder(w).Encode(map[string]string{"id": id})
   }).Methods("GET")
   ```

2. **デバッグのしやすさ**
   - 詳細なエラーメッセージ
   - リクエスト/レスポンスのログ
   - パニックからの自動リカバリー

## まとめ

Ginへの移行メリット：
1. パフォーマンスの大幅な向上
2. 開発効率の改善
3. コードの可読性向上
4. エラーハンドリングの簡素化
ubuntu20.04複数PHPインストール及びディレクトリ毎バージョン指定

ubuntu20.04にて複数のPHPをインストールし、ディレクトリ毎にバージョンを指定する開発環境の設定に今回挑戦しましたので、覚書を記することにしました。
特に、バージョン毎のphp.iniを有効にする為の設定が大変でした。
/etc/php直下に今回は、PHP7.3とPHP8.3がインストールされます。
apt install -y php7.3
apt install -y php8.3
上記インストール等はすでに以前に投稿済です。
https://qiita.com/shinsakujazzbass/items/f9dc26c1bd0bb94eca18

それぞれのバージョンのphp.iniをfindにて確認すると下記の様に配置されています。
```
/etc/php/8.3/fpm/php.ini
/etc/php/8.3/cli/php.ini
/etc/php/8.3/apache2/php.ini
/etc/php/7.3/fpm/php.ini
/etc/php/7.3/cli/php.ini
/etc/php/7.3/apache2/php.ini
```
次にPHP-FPMの有効化で次のコマンドで現在、有効になっているApacheのモジュールを確認します。
一覧に「proxy_fcgi_module」の表示がなければ、次のコマンドで有効にします。
```
a2enmod proxy_fcgi
systemctl restart apache2 //設定後apache再起動
```
またphpinfo()にブラウザから確認すると。
php7.3有効なディレクトリでは下記のパスにてphp.iniが設定。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/14dedfed-2e0f-8de2-d5ac-500cbe9ca0b6.png" width="50%">
.htaccessにより、下記設定されたディレクトリでは、
```
.htaccess
<FilesMatch "\.php$">
  SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/f428011f-8904-6c2b-d704-ebd08f9011e6.png" width="50%">

ここで、php8.3有効ディレクトリでphp.ini変更を、反映させるには、
php8.3-fpm.serviceを再起動する必要があるようだ。

```
systemctl restart php8.3-fpm
```
今回は、upload_max_filesize をdefault 2Mを50Mに変更した結果を反映できました。
Raspberry Pi Zeroの開発環境

私はPython OnlyなのでPythonの開発環境が必要です。
もうやっている方も多いでしょうけど、自分のためにです。
# 前置き
今までのRaspberry PiはVScodeのsshを使ってプログラムを書いたりしていたのですが、Zeroではアーキテクチャ(対応してないっぽい　誰か教えて...)がないとかでsshでアクセスできません。
ってことで少し考えてみました
# 開発環境
結論から書きます
**sambaで作業フィいるなどを取得できるようにします。そこをVScodeとかで編集すればリモートでできます**
 WindowsだったらエクスプローラーとVS(sshも)をいい感じに配置してThonnyみたいにもできます。
# 実際にやってみた
![スクリーンショット 2025-02-03 193658.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3994157/7be6393e-5c48-20d7-ad2e-e613a4a0e14e.png)
こんな感じでそれっぽい環境ができます。
# デ・メリット
メリット
・編集にVisual studio codeを使っているのでいつも通りつかえる
→編集できるものなら何でもいいのでさくらでもいいです
・sambaで作業ディレクトリを作ったりできるのでアップロードも簡単←渡しの場合
デメリット
・VScodeなのでコードの実行ができてしまう
→押したときには、「あーあ↓」ってなります
対策としてはコードの実行機能がないエディタを使うことです。(補正は利きません)
・ssh,smbファイル(エクスプローラー),エディタの3つを同時に使うので多くのリソースを消費する。（いちいち起動するのが面倒→バッチ作れば解決）
・エラーなどが出たとき長文のコードだと探すのが面倒。
・目があっち行ってこっち行ってと大変
# 最後に
これは個人によると思いますが、とりあえずこれで開発を進めたいと思います。
RPi Zeroのおすすめ環境があったら教えて下さい
【Study Crewで実践！】大学生の課題克服をサポートするDiscord Bot開発体験

![2025-02-03-191257_887x951_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271608/35046d58-39c8-67ea-47b5-c64c8fb695c8.png)
## はじめに
このブログ記事では，私たち4人のチームが取り組んだ「Study Crew」というDiscord Botの開発プロジェクトについて，プロダクトの概要，チームの役割分担，秋学期中の開発の軌跡，そして私個人のふりかえりをお伝えします．

## 1. 開発したプロダクト：Study Crewとは？
### 概要
Study Crewは，授業課題を余裕をもってこなしたい，課題を先延ばしにしがちな大学生向けに開発されたDiscord Botです．

### 目的
大学生が課題に取り組む際に，友人と進捗を共有・記録し，モチベーションを保ちながら効率的に学習するためのサポートツールとして設計しました．
### 特徴
リアルタイム共有：既存のStudy plusとは異なり，友達の取り組み状況をリアルタイムで把握できる機能が備わっています．
記録機能：取り組んだ内容を記録することで，後から振り返りやすく，達成感を感じられる仕組みを導入しました．
### 使い方
DiscordサーバーにBotを追加する．
各ユーザが自分のタスクや取り組み状況を入力する．
![2025-02-03-192759_567x332_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271608/50849de4-19de-9900-8f17-3e30b34e722f.png)

リアルタイムで友達の進捗が確認でき，互いにフィードバックや励まし合いが可能に．
授業ごとにチャンネルが分割されており，自分が履修している授業の課題を友人がどの程度終わらせているのかを確認することができます．
![2025-02-03-192942_576x384_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271608/a54ce491-4a7f-da52-b93a-3b8e4115ca33.png)

進捗共有では，自分が課題を終わらせたタイミングで全員にどの時間にどの課題を終わらせたかを知らせることができます．
![2025-02-03-192624_521x175_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271608/3ce5ab3a-58d8-dbb0-41b5-76b44a1032af.png)

## 2. チーム体制
Study Crewは，合計4人のメンバーで進められました．

- こいで（私）：開発者として，主にプログラミングやシステムの設計を担当．
- こんどう：開発者として，機能の実装やコードのレビューを行いました．
- もりしん：スクラムマスターとして，プロジェクトの進行管理，ミーティングのファシリテーション，チーム全体のモチベーション管理を担当．
- りくと：プロダクトオーナーとして，Gitリポジトリによるプロダクトの管理，及びプロダクトのビジョンやユーザ要求の整理，機能優先度の決定を行いました．
## 3. 秋学期中のプロダクト・チームの軌跡
私たちは，常にMVP（Minimum Viable Product）の考え方を意識しながら，ユーザが抱える課題を解決するためのシンプルで効果的な機能の実装に注力しました．

### 各スプリントの取り組み
ユーザ視点の重視：各スプリントごとに実際のユーザ（チーム内のメンバーやテストユーザ）に使用してもらい，感想や改善点をフィードバックとして取り入れました．
### レビューと振り返り
毎回のレビューで実際に使ってみた感想を元に，次のスプリントでの改良点を具体的に洗い出し，素早く実装に反映するサイクルを確立しました．
### 柔軟な対応
開発中に出てきた予期せぬ課題に対しても，MVPの精神を忘れず，必要最低限の機能でユーザに価値を提供することに徹しました．
## 4. 個人的なふりかえりと学び
今回のプロダクト開発を通じて，私は以下のようなことを学びました．

### ユーザの視点の重要性
開発者主体のアプローチではなく，常にエンドユーザの利便性を最優先に考えることが，プロダクトの成功に直結すると実感しました．
### スクラム開発の実践
定期的なレビューやフィードバックの収集，そして柔軟な対応が，プロジェクトを円滑に進めるために非常に有効であることを学びました．
### 今後の展望
今後の開発では，この経験を活かし，さらにユーザ中心のアプローチを徹底していきたいと考えています．特に，ユーザからの直接のフィードバックを取り入れた機能改善や，新たな価値の創出に注力する予定です．
## おわりに
夏休みの後半から始まったチーム開発もいつの間にか4ヶ月が経過しました．途中で2回のプロダクトの方針転換やチームメンバの離脱等がありましたが，常にユーザのニーズに答えることを第一に考え，毎回のレビュー時に動くプロダクトによる生きたレビューをもらえることを意識していました．
Study Crewの開発を通して，チーム全体でユーザの課題に真摯に向き合い，必要最低限の機能で価値を届けることの大切さを学びました．この経験は，今後のプロジェクトに必ず活かせると確信しています．今後もさらなる改善と新たなチャレンジを続け，より多くの大学生が快適に課題に取り組める環境を提供していきたいと思います．
Vite環境でのSupabaseクライアントの設定

Supabaseを利用するにはまず「クライアントの初期設定」を行う必要があります

これにより、SupabaseのAPIを使ってデータベースの操作や認証機能を利用できるようになります。この記事はVite環境でSupabaseを使ってDB設計する基礎的な内容について触れます

## クライアントとは何か

クライアントとは、SupabaseのAPIとアプリをつなぐための「窓口」となるもの

例えば、データベースにアクセスしたり、認証機能を利用したりするためにはクライアントを通じてAPIを呼び出す必要があります。

---

## なぜクライアント設定が必要なのか

Supabaseは、API経由でデータベースや認証、ストレージといった機能を提供しています。このAPIとアプリをつなぐための「窓口」がクライアントです。クライアント設定をすることで、以下のようなことが可能になります

- データベースのデータを取得・追加・更新
- ユーザー認証（サインアップ、ログインなど）
- ストレージの利用（画像やファイルの保存）

例えばReactアプリからデータを取得したり、ユーザーを認証するにはこのクライアントが必須となります

## クライアントの設定手順

### 1. **ライブラリをインストール**

Supabaseを使うための公式ライブラリ `@supabase/supabase-js` をインストールします。

```bash
npm install @supabase/supabase-js
```

### 2. **クライアント設定ファイルを作成**

プロジェクト内にクライアントを設定するためのファイルを作成します。

1. プロジェクトの `src` フォルダ内に `supabaseClient.js` を作成。
2. 以下のコードを記述します：

```javascript
import { createClient } from '@supabase/supabase-js'

// Create a single supabase client for interacting with your database
export const supabase = createClient(
    import.meta.env.VITE_SUPABASE_URL,
    import.meta.env.VITE_SUPABASE_ANON_KEY
);
```

https://ja.vite.dev/guide/env-and-mode.html#env-files

- **`supabaseUrl`** と **`supabaseKey`** の取得方法:
  - Supabaseダッシュボードにログイン。
  - 「Settings > API」にアクセスし、Project URL と anon key をコピーします。

## .envでシークレット情報を管理

APIキーや機密情報を環境変数で管理することで、コード内に直接書かずに安全に取り扱うことができます。

### 1. **.envファイルを作成**

プロジェクトのルートディレクトリに `.env` ファイルを作成し、以下のように記述します。
私はここで間違って階層をsrcファイル内に設置してしまい、エラーになりましたので気をつけてください。

```
VITE_SUPABASE_URL=your-supabase-url
VITE_SUPABASE_ANON_KEY=your-anon-key
```

### 2. **.gitignoreに追加**

`.env` ファイルはバージョン管理に含めないように `.gitignore` に追加します。

```
.env
```

これにより、誤ってAPIキーを公開リポジトリにアップロードするリスクを防げます。

----

またsupabaseのRLSが有効だと認証なしでは Supabaseのデータを取得できないので、エラーが起きた場合そこも確認が必要です。


これでSupabaseクライアントの初期設定が完了です！
PHPの配列の話

## 配列の使い方
配列を使うには、以下のコードを記載する。
```php
$array = array('文字1', '文字2', '文字3');
```
## 表示する方法
以下のコードを記載する。
```php
foreach ($array as $output) {
    echo $output;
}
```
出力は、以下になる。
```
文字1文字2文字3
```
## `foreach`無しで`echo`した結果
以下のエラーが表示される。
```php
PHP Warning:  Array to string conversion in パス on line 行
```
今回の話は結構適当な話である。
ありがとうございました。
megacmdインストール後にapt updateするとエラーが出るのを直す。

公式の方法でインストールすると、`apt update`でエラーが出るので、調べてみた。
```sh
wget https://mega.nz/linux/repo/xUbuntu_24.04/amd64/megasync-xUbuntu_24.04_amd64.deb &&\
sudo apt install "$PWD/megasync-xUbuntu_24.04_amd64.deb"
```

`/etc/apt/sources.list.d/megasync.list`をみると`xUbuntu_${RELEASE}`の部分でリリースバージョンが15になっていて、リポジトリには存在しない。
ので、任意のバージョンに変更する。
```sh
RELEASE=$(lsb_release -rs) && \
echo "deb [signed-by=/usr/share/keyrings/meganz-archive-keyring.gpg] https://mega.nz/linux/repo/xUbuntu_${RELEASE}/ ./" \
| tee /etc/apt/sources.list.d/megasync.list
```

おわり。

追記:
インストールスクリプトはこんなかんじ。
```
apt-get update && apt-get install -y lsb-release curl gnupg &&\
    RELEASE=$(lsb_release -rs) &&\
    echo "deb [signed-by=/usr/share/keyrings/meganz-archive-keyring.gpg] https://mega.nz/linux/repo/xUbuntu_${RELEASE}/ ./" | tee /etc/apt/sources.list.d/megasync.list &&\
    curl -sLf --retry 3 --tlsv1.2 --proto "=https" "https://mega.nz/linux/repo/xUbuntu_${RELEASE}/Release.key" | gpg --dearmor -o /usr/share/keyrings/meganz-archive-keyring.gpg &&\
    apt-get update && apt install -y megacmd

```
【ちょいメモ】overflow: hidden;とは？

```css
html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
```

overflow: hidden; は、要素のコンテンツが指定されたサイズ（この場合は width: 100% と height: 100%）を超えた場合に、はみ出た部分を非表示にするというCSSプロパティ。

この具体的な例では、

html, body に対して指定されているので、ページ全体に適用される。
width: 100% と height: 100% で画面いっぱいのサイズを指定し、
overflow: hidden で、そのサイズを超えるコンテンツは表示されなくなる。

実際の効果としては、
- スクロールバーが表示されなくなる。
- ページの縦横のスクロールができなくなる。
- コンテンツが画面サイズを超えた場合、超過部分は切り取られて見えなくなる。

これは以下のような場合によく使用される
- モーダルウィンドウを表示する時に背景のスクロールを防ぐ。
- 特定のレイアウトデザインを実現する。
- 意図しないスクロールを防止する。

デフォルトでは overflow は visible（はみ出た部分も表示する）に設定されています。
現在開発中のUCCScript　開発段階でできること

　最近、自作の構文解析用言語のParserScriptが使いづらくなってきた……。

　ということで、UCCScript（Universal Compiler Creation Script Language（であってほしい））の開発を始めました。

開発段階のUCCScript：[UCCScript-UnderDevelopment](https://github.com/MueLangDeveloper/UCCScript-UnderDevelopment)

# 現状今できること
　GitHubにコードが何を表すかを詳しく解説します。
　
　現在、ほとんどの機能が実装され、制御機能をつけています。具体的に書くと、任意のアンカーへの移動（Pattern：`'`（アンカー）、`m"p:index"`、`m"r:index"`　Result：`'`（アンカー）、`MoveP[index]`、`MoveR[index]`）、BeMatch文（アンカーを使用して再マッチングを行わせる）、グローバル変数とGlobalLoad文を実装する予定です。

　
--追記
・現在、`m"p:index"`、`m"r:index"`（Pattern内）と`MoveP[index]`、`MoveR[index]`（Result内）を実装し、`ret`（Pattern内）、`Ret`（Result内）を実装しており、問題がないか確認する予定です。
・`'`は基本スルーされますが、スルーせずに`j`に飛ぶ`j`を実装することにしました。

　
--追記の追記
・MoveRの動作テストを行った際、プログラムが一向に終わらないバグが発生し、同様に`m"p:index"`も終わらなくなり、原因不明のため、`m"r:index"`改め`m(index)`（または`M(index)`（`()`は見ずらいのでわかりやすくしています））、`MoveP[index]`改め`Move[index]`のみとします。
・全ての機能を実装しました。[UCCScript](https://github.com/MueLangDeveloper/UCCScript)
　

　使うことのできる制御機能はIf文、For文、ForB文、While文です（For文はRustやF#、ForB文はCやC#と機能は同じ）。また、変数のためのLoad文があります。

# サンプル
以下は、`a`と`b`のみで構成された入力の内、`a`を`国語辞典`、`b`を`饗宴`に置き換えるコード
```ucc
First Sample End
$Sample In { <{ ( "a" | "b" ) }> }
        Is (For[0 $0+[0] 1 - 1][ (If[@1[0 `] "a" =][ "国語辞典" ] ElseIf[@1[0 `] "b" =][ "饗宴" ] Else[]) ]) End
```
```ucc
First Sample End
$Sample In { <{ ( "a" | "b" ) }> }
        Is (ForB[0 1][` $0+[0] <][ (If[@1[0 `] "a" =][ "国語辞典" ] ElseIf[@1[0 `] "b" =][ "饗宴" ] Else[]) ]) End
```
後者は条件を繰り返す度、再計算するので前者の方が良い

　
　
以下は二つの正の整数の入力`Number1`と`Number2`を受け取り、`Number1`を何倍すれば`Number2`で割り切れるかを出力する

入力
```
Number1
Number2
```
コード
```ucc
First Sample End
$Sample In <( Number )> "\n" <( Number )>
        Is (Load Num1[@0[0] Num ~]) (Load Num2[@0[1] Num ~]) (Load Count[1])
           (While[\Num1 \Count * \Num2 % 0 = !][ (Load Count[\Count 1 +]) ]) \Count End
```
# 現在発生中のバグ
　現在、対応に追われているバグは以下の
```ucc
First Test End
$Test In { <o "+-"> ( "+" | "-" ) <o "*/"> ( "*" | "/" ) }
      Is (If[?[0] ?[1] &][ (For[0 $0+[0] 1 - 1][ @1[0 `] ]) (For[0 $0+[1] 1 - 1][ @1[1 `] ]) ] Else[]) End
```
　というコードを書き、
```
+*-/
```
　という入力を与えると
```
+-*/
```
　という結果が返ってきてほしいのですが
```
+-+*/
```
という結果が返ってきます。

--追記
・このバグはUCCScriptの仕様によるもので、解決のしようがないものでした。
# 終わりに
　ほかにもバグがあると思います。実装予定のものはあくまで、高速化などを目的にしているため、開発途中の（予定のものを除けば、完成した）ものを公開しています。使うときは、**必ずREADMEを読んでください** 。
CDK はインフラ初心者にも優しいのか

私「インフラは昔よりも簡単になっているらしい。」

# AWS CDK とは？
- インフラをコードとして定義するためのツール（IaC）
- AWS CloudFormationテンプレートにコンパイルしてデプロイするためのフレームワーク
- 直感的かつ効率的にAWSインフラのプロビジョニングを行う


私「インフラをコードで管理が、時代の流れなんだな。」

## 他に似たようなのは？
- Teraform
- Serverless Framework

私「テラフォームは、何かのニュースで聞いたことある。使ってみよう」

# 前提を揃える
AWS CLI を使える必要がある（Macの場合）

```
% brew install awscli
```

バージョン確認
```
% aws --version      
> aws-cli/2.23.11
```
OK

#### まず管理者権限
以降はAWSの管理者権限が使える必要あります。
チームで使っている環境ではできないので個人の環境を使います。
※もちろん具体的なキーは伏せてあります。

#### AWS環境変数を設定する

```
% export AWS_ACCESS_KEY_ID=""
% export AWS_SECRET_ACCESS_KEY=""
% export AWS_SESSION_TOKEN=""
```

#### ~/.aws/credentials を開いて記入する

```
[AdministratorAccess]
aws_access_key_id=
aws_secret_access_key=
aws_session_token=
```


#### サービスクライアントにアクセスキーを追加

```
% aws configure
AWS Access Key ID [None]: 
AWS Secret Access Key [None]:
Default region name [None]:
Default output format [None]: 
```

私「output format? って何だろな」


# 開発言語

開発する言語、TSをインストールする。
```
% npm -g install typescript
```
バージョン確認

```
% tsc -v                   
> Version 5.7.3
```
OK

# CDK CLIをインストールする

```
% npm install -g aws-cdk
```

バージョン確認
```
% cdk --version
> 2.177.0
```
OK

# なにかリポジトリを用意
勉強用のリポジトリを `git clone` しました。

```
% git clone （your Repository）
```

JSで書かれてたので、中身に、package.json があります。
ということは `node_modules` が必要だと思います。

```
% npm install
```

# CDK.json
cdk.jsonを使って構成を管理するものらしいです。

```
cd /path/to/cdk.json
```
※正確には、cdk.jsonがある所まで行かないと、cdkコマンドは動かない。

# CDK bootstrap
最初に初期設定を作っておく。
```
% npx cdk bootstrap --context environment=dev

CDKToolkit: creating CloudFormation changeset...
Environment aws://xxxxxxxxxxxxx/xx-xxxxx-1 bootstrapped.
```

# デプロイ
cdk.json で設定された通りの構成

```
% npx cdk deploy --context environment=dev

Do you wish to deploy these changes (y/n)? y

Deployment time: 160.29s
```

デプロイされた

# AWS CloudFormationを見に行く

テンプレートに変換され、いろいろなAWSのサービスに
インスタンスが立ち上がったりしている。

# 停止方法
止め方わかんないな。AWSのBillingが心配だ。

```
% npx cdk destroy --context environment=dev
```

これで止まる。間違えて、本番環境のKeyを持っている時に
destroy を使わないようにしましょう。

# 結論
AWS CDK　めっちゃ使いやすい。
管理者権限が付与されていないWindows PCでもPlantUMLを使いたい

結論から言うと、ローカル プログラム フォルダー(C:\Users\hoge\AppData\Local\Programs）を使いましょうというお話。
# 管理者権限がない
そもそも限定的な状況かもしれませんが、、、
自社の貸与PCでもコンプライアンス的に厳しかったり、または他社案件に参画していて客先からPCを貸与されている場合などで、Windows PCの自分のログオンアカウントが管理者権限を持っていない場合が多々あると思います。それでも諸事情でローカルPCにVSCodeを入れてUMLで業務フローや状態遷移図を描いてプレゼンしないといけないような場合、ありませんか？
私はあります。普段は管理権限を与えられたVDI環境で資料作成してますが、VDI経由でTeams会議に参加すると音声品質が激マズだったりするのでローカルPCで会議に入ってプレゼン資料も共有したいし、なんなら客先にPCを持参してWifiがない状況で資料をディスプレイに映して説明したりしないといけません。
# UMLはVSCodeで
皆さんきっと同じだと思いますが、UMLはVSCodeでPlantUML拡張機能入れていると思います。UML記述をプレビューするにはJavaとGraphvizのインストールが必要で、よく見かけるインストール手順ではどちらも管理者権限が必要です。つまり、管理者権限がない貸与PCではPlantUMLのプレビューができないので、打合せの場で修正してもその結果をプレビューできないことになります。
# 管理者権限がなくても実行ファイルを置ける場所
Windowsには管理者権限がなくてもプログラムを配置できる場所があります。VSCodeも「System Installer」と「User Installer」があり、「User Installer」は管理者権限がなくてもインストールできて、それはユーザープロファイルの中にインストールされます。
###### ※ユーザープロファイルの中のProgramsの正式名称はよく分かっていませんが、Copilotに訊いたら「ローカル プログラム フォルダー」だと教えてくれました。
なので、JavaやGraphvizもこの「ローカル プログラム フォルダー」の中に置けば良いんじゃね？という話です。
# インストール手順
- Javaのインストール
  - ライセンス的に問題がなさそうなOpenJDKディストリビューションのzipをダウンロードします。私は[このあたり](https://docs.aws.amazon.com/corretto/latest/corretto-21-ug/downloads-list.html)からWindows-x64用をDLしました。
  - zipをダウンロードした時点ではファイルのプロパティを見ると「このファイルは他のコンピューターから取得したものです・・・・」となっていて「許可する」のチェックボックスがOFFになっています。このままだと色々と厄介なのでチェックボックスをONにして「適用」「OK」とします。
  - zipを展開したら「jdk21」とかの適当な分かりやすいフォルダ名に変えて、ローカル プログラム フォルダー（C:\Users\hoge\AppData\Local\Programs\）の中に移動します。
- Graphvizのインストール
  - こちらも同様で適当なバージョンのWin64用のzipをダウンロードします。
  - 「許可する」をONにしてzip解凍し、「Graphviz12」とかの適当な分かりやすいフォルダ名に変えて、ローカル プログラム フォルダーの中に移動します。
- 環境変数の設定
  - コントロールパネルを開き、「ユーザーアカウント」→「ユーザーアカウント」とクリックするとサイドメニューに「環境変数の変更」が現れるのでクリックします。
  - 「hogeのユーザー環境変数」の中にある「Path」を選んで「編集」をクリックし、ダイアログで「新規」をクリックしたら「java.exe」があるフォルダ（C:\Users\hoge\AppData\Local\Programs\jdk21\bin\など）を指定し、「OK」します。
  - 「環境変数」の画面に戻ったら「新規」をクリックし、変数名「JAVA_HOME」に↑と同じフォルダ（C:\Users\hoge\AppData\Local\Programs\jdk21\bin\など）を指定し、「OK」します。
  - 再度「環境変数」の画面に戻ったら「新規」をクリックし、変数名「GRAPHVIZ_DOT」に「dot.exe」のパス（C:\Users\hoge\AppData\Local\Programs\Graphviz12\bin\dot.exeなど）を指定し、「OK」します。
# 確認
おそらくこの状態でPlantUMLの拡張機能を入れたVSCodeで、UML記述をプレビューできるはずです。
もしダメなら環境変数の設定が間違ってないか確認し、PC再起動してからプレビューしてみてください。
それでもダメな場合は、自分では解決できないものとして諦めてください。
Udemyクーポンコード一覧

<h1>2025.5/29更新!!!</h1>

私が公開しているUdemy講座のクーポンコード付きリンクです。
こいつでもお得な価格でご利用いただけるので、ブックマークしておいてください！

----

<h2>これだけでOK！【KCNA-JP】認定Kubernetesクラウドネイティブアソシエイト模擬試験問題集（5回分300問）

https://www.udemy.com/course/kcna-jp_kubenetes/?couponCode=202505

勉強方法、資格対策はこちら：
https://qiita.com/hashitaka_jp/items/439f6205cedf6283a65c

----

<h2>HashiCorp Certified: Terraform Associate 厳選・模擬試験問題集

https://www.udemy.com/course/hashicorp-certified-terraform-associate-jp/?couponCode=202505

----

<h4> AWS  Certified Advanced Networking Specialty （ANS-C01）問題集

https://www.udemy.com/course/aws-advanced-networking-specialty-jp/?couponCode=202505

----


<h4> AWS Certified DevOps Engineer - Professional 試験問題集 (6回分450問)

https://www.udemy.com/course/aws-devops-engineer-professional-6480/?couponCode=202505

勉強方法、資格対策はこちら：
https://qiita.com/hashitaka_jp/items/30b597d00f1216a82ff1

----

<h4> これだけでOK！AWS Certified Machine Learning Engineer Associate問題集


https://www.udemy.com/course/aws-machine-learning-engineer-associate/?couponCode=202505


----

<h4>これだけでOK！AWS Certified AI Practitioner（AIF-C01） 実践問題集【390問】

https://www.udemy.com/course/aws_ai_prac/?couponCode=202505
Microsoft Teams 管理センターのUIを日本語にしたい

**Microsoft Teams 管理センター** の英語ＵＩを日本語化する方法。
ユーザー設定や MS365 管理センターの設定は何をやってもだめで、直接 Azure AD の属性パラメータを PowerShell で更新するしかない様です。マジか... (TдT)

## 設定手順

 `Azure Active Directory モジュール` を使用した情報をかなり見かけるが、2025.2.4 現在ではもう出来ない方法っぽい、代わりに `Microsoft Graph モジュール` を使用して行った。
 
- [ Microsoft Graph - Update-MgUser ](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.graph.users/update-mguser?view=graph-powershell-1.0)

***PowerShell起動（管理者として実行）***
```powershell:Teams 管理センター日本語化

# Microsoft Graph PowerShellのインストール
Install-Module Microsoft.Graph -Scope CurrentUser

# インストール後、モジュールをロード
Import-Module Microsoft.Graph

# Microsoft Graph を MSアカウント へサインインさせる（権限スコープ：ユーザー設定）
Connect-MgGraph -Scopes "User.ReadWrite.All"
# -----------------------------------
# ブラウザが開いたらMSアカウントでログイン
# -----------------------------------

# 対象ユーザーのpreferredLanguage属性をja-JPに設定
Update-MgUser -UserId "hoge@example.com" -PreferredLanguage "ja-JP"

# 設定されていることを確認
Get-MgUser -UserId "hoge@example.com" | Select-Object PreferredLanguage

PreferredLanguage
-----------------
ja-JP

```

---

### 変更前
![スクリーンショット 2025-02-03 185616.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/ba9a97b0-0529-6aa1-3175-cf55c1a903df.png)

### 変更後
![スクリーンショット 2025-02-03 185540.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/95891b2b-e37b-b18c-c55a-c6b2f8a4914b.png)

以上でした。ユーザー設定見てよ～って感じです。
SSL証明書の基本と発行プロセスのメモ

SSL証明書って期限が切れる時にしか触らないので、どういう仕組みだったかよく忘れてしまいます。
いつも他の方のブログなどを見て「あ〜そうだったな」と思ってるのですが、いい加減自分で覚えたいのでここに書いておきます。

# SSL証明書とは
そもそも「SSL証明書（SSLサーバ証明書）」とは、HTTPS通信（HTTP通信を暗号化）するために必要な電子証明書のこと。
SSL証明書(CRT)には、以下の情報が入っている。
* サーバの所有者の情報
* サーバの公開鍵(CSR)
* 証明書を発行した認証局(CA)の情報（署名）

署名は、証明書を発行する「CA」が、「CSR」の情報を元に行う。

# SSL証明書発行の流れ

1. 自分のサーバーで公開鍵(CSR)と秘密鍵(KEY)を作成
2. CSRを認証局(CA)へ送信して証明書の発行を申請
3. CAから電子署名された証明書(CRT)を受け取る
4. 受け取った証明書類をWebサーバーへ設置する

## SSL証明書のレベル
SSLの証明書には「DV」「OV」「EV」の3つのレベルがある。
上から、レベルが高い順。
* EV（Extended Validation）
  企業・団体の所在地まで確認したのちに証明書を発行。書類送付による所在地確認が入る
* OV（Organization Validation）
  実在する企業・団体のみに証明書を発行。電話での実在確認が入る
* DV（Domain Validation）
  SSLの申請者がドメインの所有者であるということを証明するもの。実在性は確認されない

EV,OVは普通にお金がかかる。が、DVは無料なことが多い。（有料のものも存在する）

無料のSSL認証局として有名なのが、[Let's Encrypt](https://letsencrypt.org/ja/)。
なぜ無料で使えるかというと、「SSLを全世界に普及させる！」というコンセプトに賛同した世界の大手企業がスポンサーとして支援しているから。
Let's Encryptでは、申請の受付から証明書の発行まで、すべて自動で行われる。
Let's Encryptでの証明書作成は、「[Certbot](https://certbot.eff.org/)」というツールを使って簡単にできる。
Microsoftアカウントに失敗して657rxが表示されてしまう事象の解消手順

# どんな時に発生したのか

先日開発用PCにログインしようとしたらパスワードをド忘れ！！
アカウントロックされちゃったのでパスワードリセットをしてログインしたはいいものの、TeamsやExcelとかのデスクトップアプリでログインするとエラーが表示される事態になりました・・・。
今回はその時に行った対処を共有がてらメモりました。

OS：Windows11
エラーコード：**657rx**
※こんな感じの画面に上のコードが表示されました
（日本語でぽい画面がなかったので英語で勘弁・・・）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894538/30cf76c9-e267-7b04-9d1e-1c711400f072.png">

# 解消手順

1. まずブラウザやデスクトップアプリなどMicrosoftアカウントでログインしているものからログアウト
1. ログアウトしたブラウザやデスクトップアプリを閉じる
    ※タスクマネージャーからアプリが終了していることを確認してください！
1. エクスプローラーで下記のフォルダを開く
    ```C:\Users\<ユーザ名>\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin_cw5n1h2txyewy```
1. フォルダ内のものをすべて削除！
    ※アプリを終了できていないと削除できないファイルがあります。
    ※必ずすべて削除してください。
1. 再度ブラウザやデスクトップアプリにログイン

# おまけ

私が探した限り、エラーコードで調べて出てきたサイトで有用なのは一つだけでした。
だれかの助けになればと思います。
元サイトのLiweiTianさんありがとう！:hugging:


# 引用
> https://learn.microsoft.com/en-us/answers/questions/2108548/how-to-fix-something-went-wrong-(657rx)
CLINEの仕組みを解析してみる

ジークスの酒井です。

今話題になっているCLINEで色々プロジェクトを作ってみたのですが
vscodeを勝手に操作されていったり、人間にも質問してきて、人間が部品の一つになっている感じが
すごい衝撃的でした。

今までのAIツールはあくまで人間の補助として動いていましたが
人間の上に立とうとする下剋上的な可能性を感じたので
いったいどういう仕組みで動いているのか非常に興味を感じました。

中身を解析してみたので共有します。

## ソースコード
https://github.com/cline/cline

こちらのソースから始めます。Roo Codeなどforkも出てきていますが
まずは本家の解析です。

https://github.com/cline/cline/blob/main/src/api/transform/o1-format.ts
プロンプトに渡す文字列を探してみると、ここのソースで定義されていました
他にもgeminiやopenaiなど他のAIエンジン向けのソースがありますが、
全部o1-format形式に変換しているようでした。

### 初期設定
```
# システムプロンプト

${システムプロンプト}

# 回答を作成するための手順

少なくとも 1 つのツール呼び出しを使用して、ユーザーの要求に応答する必要があります。応答を作成するときは、次のガイドラインに従ってください。

1. 通常のテキストで回答を開始し、自分の考え、分析、または行動計画を説明します。
2. ツールを使用する必要がある場合は、通常のテキスト説明の後に、すべてのツール呼び出しをメッセージの最後に配置します。
3. 必要に応じて複数のツール呼び出しを使用できますが、それらはすべてメッセージの最後にグループ化する必要があります。
4. ツール呼び出しを配置し​​た後は、通常のテキストを追加しないでください。ツール呼び出しは、メッセージの最終的なコンテンツである必要があります。
```

最初は初期設定のための文章が並びます。ここで衝撃を受けたのは書式などに関する指定しかしてなくって
プログラム言語の話は一切出てきてないという部分です。

### ツールの初期設定
```
回答が従うべき一般的な構造は次のとおりです。

\`\`\`
[あなたの考えや行動を説明する通常のテキスト応答]

[ツールコール1]
[必要に応じてツールコール2]
[必要に応じてツールコール3]
...
\`\`\`

覚えて：
- タスクと提供されたツールの説明に基づいて、最も適切なツールを選択します。
- 各ツールに指定された XML 形式を使用して、ツール呼び出しを作成します。
- 通常のテキストで、実行しているアクションと特定のツールを使用する理由を明確に説明します。
- ツール呼び出しがメッセージの直後に実行され、次の応答でその結果にアクセスできるかのように動作します。
```
clineからツールを使うための設定が書かれています。
AIが使えるツールは8個あり、この後で指定されています。

1. コマンド実行
　CLIコマンドを実行します
2. ファイル一覧
　プロジェクトの指定したフォルダ内のファイル一覧を表示します
3. コード定義名のリスト
　指定したフォルダのソースコード内の定義名（クラス、関数など）を一覧表示します。
4. ファイル検索
　指定したフォルダで正規表現による検索を実行します。
5. ファイル読み取り
　指定したファイルを読み取ります。
6. ファイル書き込み
　指定したファイルに書き込みをします。
7. フォローアップの質問
　人間に質問を表示して、回答を収集します。
8. 結果表示
　タスクが完了したらこのツールで結果をユーザーに表示します。

これらのコマンドを使ってばりばりvscodeをいじって結果に近づいていきます。
情報が足りなければ7番を使って人間に質問し、答えによって行動が変化していきます。

完了したら8番を実行して、人間に結果を表示して終わります。
人間が結果に満足しない場合はフィードバックのテキストを入力し
そのテキストを受けて再実行する事もできます。

ここまで解析してきて、プログラム言語の話が一切出てきていない事にびびります。
今まで色々なプログラミングパラダイムがありましたが
まったく新しいナニカが始まっている予感がしました

百聞は一見に如かずといいますが、このclineも一度使ってみると
わかりやすいと思うので、ぜひ試してみてください！！
EC-CUBEがテンプレートを探す順番

1）eccube-root/app/template/　→このディレクトリ以下を参照する
2）eccube-root/src/Eccube/Resource/template/　→このディレクトリ以下を参照する
3）eccube-root/app/Plugin/[PluginName]/Resource/template/　→このディレクトリ以下を参照する

# EC-CUBEインストール時
2のみにファイルが存在する

1）eccube-root/app/template/　→このディレクトリ以下を参照する
**2）eccube-root/src/Eccube/Resource/template/　→このディレクトリ以下を参照する**
3）eccube-root/app/Plugin/[PluginName]/Resource/template/　→このディレクトリ以下を参照する

# プラグインインストール時
2，3にファイルが存在する

1）eccube-root/app/template/　→このディレクトリ以下を参照する
**2）eccube-root/src/Eccube/Resource/template/　→このディレクトリ以下を参照する**
**3）eccube-root/app/Plugin/[PluginName]/Resource/template/　→このディレクトリ以下を参照する**

# 管理画面から編集後
1、2，3にファイルが存在する

**1）eccube-root/app/template/　→このディレクトリ以下を参照する**
**2）eccube-root/src/Eccube/Resource/template/　→このディレクトリ以下を参照する**
**3）eccube-root/app/Plugin/[PluginName]/Resource/template/　→このディレクトリ以下を参照する**

# 参考記事
https://qiita.com/haruna-nagayoshi/items/27108c75eaf9511f3524
https://qiita.com/takeruun/items/70533d0cad9dfc786162
軽量・プライバシー重視のCLIでWebをデスクトップアプリに

## Webアプリを手軽にデスクトップアプリに変換

ohyは、Rustで構築された軽量なコマンドラインツールで、Webアプリケーションをデスクトップアプリケーションに変換します。データプライバシーの分離、複数の同時実行インスタンス、簡単なデプロイなどの機能により、移行プロセスを簡素化し、効率的なリソース使用とユーザーデータの安全性を各プラットフォームで確保します。[ohy project github](https://github.com/ohyfun/ohy/)

## 主な特徴

* **小さな単一実行ファイル**: サイズは5MB未満
* **データプライバシーの分離**: 接続アドレスとアプリケーション名に基づいて分離します
* **複数のインスタンス**: アプリケーションは、セッションデータを分離した状態で同時に実行可能（デフォルト設定）
* **簡単なデプロイ**: バイナリファイルをコピーするだけで使用可能；`sudo` 権限は不要です
* **自動アイコン取得**: アプリケーションのアイコンを自動で取得します
* **集中型キャッシュ**: ローカルキャッシュデータは固定ディレクトリに保存され、システムディレクトリを散らかす分散書き込みを回避します

## 使用方法

```bash
使用方法: ohy --url <url> [-n <name>] [-w <width>] [-h <height>] [-a <user-agent>]

オプション:
  --url             URL例 https://www.github.com
  -n, --name        名前
  -w, --width       幅 (デフォルト: 1200)
  -h, --height      高さ (デフォルト: 780)
  -a, --user-agent  ユーザーエージェント
  --help, help      使用情報を表示
  ```

## 例
 qwenチャット用のデスクトップアプリケーションを作成するには:
 ```bash
 ohy --url https://chat.qwenlm.ai -n qwen
 ``` 
 
 ## インストール
 1. Cargoを使ってアプリケーションをインストールする
 ```bash
 cargo install ohy
 ```
 
 ## 利点
* 軽量で効率的なリソース使用
* セッション分離によるプライバシー向上
* シンプルで直感的な設定
* クロスプラットフォーム対応

## スクリーンショット
### linux
![qwen](https://github.com/user-attachments/assets/eec15bdd-f1fa-4364-bd5c-e6229b70a46b)
![qwen-dark](https://github.com/user-attachments/assets/02eeba87-62b8-420a-a727-b8033a5c1bc0)
![ohy-icon](https://github.com/user-attachments/assets/fc092cdd-005b-4d81-9525-c0e92dfedd7b)
> linux app cache data directory `$HOME/.config/ohy/*`

![app-context-dir](https://github.com/user-attachments/assets/c7297da3-9335-4d6b-b3f8-d27216557624)

### windows
![app1](https://github.com/user-attachments/assets/1a5d86a9-0408-4fe3-b380-87635d7d44cd)
![app2](https://github.com/user-attachments/assets/07fa2e21-d825-44d7-bd87-4009db4dd388)
![app3](https://github.com/user-attachments/assets/73c990ca-719b-4696-ae98-105e52012ef7)
![dark-mode](https://github.com/user-attachments/assets/8585f8ca-7e50-42c8-a520-df9bca5b3691)
![icon](https://github.com/user-attachments/assets/d6897c82-8df1-43e2-8c0c-6a0e2dd8ce21)
> windows app cache data directory `C:\Users\$USER_NAME\AppData\Roaming\ohy\*`

![web-content](https://github.com/user-attachments/assets/3c4a20d8-17d9-48c6-8259-36de75380772)
macでdotnetがインストールされるパスがちょっとちらかるので備忘録

### macでdotnet開発行うとインストール方法によっていろんなパスにちらかってしまっていた
ので、ほぼ自分的備忘録

#### 開発環境は
* rider
* mac(m1)

### dotnetのインストールはざっくりと
- 公式のインストーラ
- Homebrew
- dotnet-install　コマンド
- riderにバンドルされてるdotnetコマンド（←ほぼ使わないけどあるにはあるみたい）

#### 公式インストーラからいれると
公式より
https://learn.microsoft.com/ja-jp/dotnet/core/install/how-to-detect-installed-versions?pivots=os-macos
`/usr/local/share/dotnet/dotnet`
に入ってくる。
なお、x64用のコマンドは
`/usr/local/share/dotnet/x64/dotnet`
にあったりする（インストールしていれば）

#### Homebrewだと
`/opt/homebrew/bin/dotnet`
（私の環境では

#### dotnet-installだと
https://learn.microsoft.com/ja-jp/dotnet/core/tools/dotnet-install-script
`~/.dotnet/dotnet`
に入ってくる。

#### riderバンドル
`~/Applications/Rider.app/Contents/lib/ReSharperHost/macos-arm64/dotnet/dotnet`
たぶんResharperまわりなので実際の用途はよくわからず。
ただここにある、ってことだけはわかった。

#### いろんなところからインストールしてしまうとworkloadとかtoolsとかもどの場所にあるかわからなくなるので注意する
特にriderでdotnetパスをカスタマイズするときはきをつけよう
watsonx.ai Studio notebookの作成・操作

watsonx.ai Studio (旧Watson Studio)でnotebook(Jupyter notebook)の作成方法です。
[過去にも書いている](https://qiita.com/nishikyon/items/6c5bc873e2ac7f1e5fb7#3-notebook%E3%81%AE%E4%BD%9C%E6%88%90)のですが、もうGUIがぜんぜん違うので書き直します。


# 0. 前提はwastonx.ai Studioのプロジェクトが作成済みであること
前提は既にwastonx.ai Studioのプロジェクトが作成済みであることです。もしまだ作成済みでなく、方法がわからない場合は

* [wastonx.ai Studio サービスとプロジェクトの作成](https://qiita.com/nishikyon/items/55b2b71eed9996f82d42/)

を参考にまずプロジェクトを作成してから以下を開始してください。

# 1. notebookの新規作成
### 1-1. プロジェクトを開く
作成済みプロジェクトを開いてください。

方法がわからない場合は
「[wastonx.ai Studio サービスとプロジェクトの作成 - 4. プロジェクトの開き方](https://qiita.com/nishikyon/items/55b2b71eed9996f82d42#4-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E9%96%8B%E3%81%8D%E6%96%B9)」を参考にして開いてください。

### 1-2. 「資産」タブをクリックし、「新規資産」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8501393c-bf83-90a8-49ed-3159d2eb0f9d.png)

### 1-3. 左側のナビゲージョンから 「モデルの処理」をクリックし、「Python または R notebooks でのデータおよびモデルの処理」のタイルをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/47c57d4f-69ea-9ed5-c505-84e62eea3c34.png)

### 1-4. 「Python または R notebooks でのデータおよびモデルの処理」の画面で必要事項をセットし、「作成」をクリック

- 必須は「名前」です。ファイル名になります。拡張子は不要です。

- pythonの場合はとりあず名前だけ入れれば、OKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/cb7168e7-8534-7973-86d4-acab7d9cc521.png)

notebookが開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a6d8180c-f37b-3b78-be38-baaa78178a6b.png)


# 2. 作業が終わったら

### 2-1. Notebookを保存する場合は、右上の保存アイコンをクリックして保存してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/05bb1150-4ec5-207a-1679-6d91d00079f4.png)


### 2-2. プロジェクトの画面に戻る場合は、右上のプロジェクト名をクリックしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e735a357-e895-96dc-431a-ed474fcd711e.png)


### 2-3. Notebookを開いたままでプロジェクトの画面を表示するには、上部のプロジェクト名を右クリックし、「新しいタブで開く」でプロジェクトを新しいタブで開いてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/b3b0cf42-72f8-4e07-d45f-d1d1ca606a0c.png)


# 3. 既存のnotebookを開く
既に作成済みのnotebookを「実行できる状態」で開くには以下の方法で開きます。
### 3-1.　「資産」タブをクリックし、「すべての資産」または　資産タイプ「Notebooks」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e59ec3ca-38de-a924-a78d-3db354be26fd.png)

### 3-2. 開きたいnotebookの右側の3点メニューをクリックし、「編集」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ef3c1ffb-e924-ae94-4928-09ef47c4caf8.png)

「実行できる状態」で開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/defba0d4-ca4b-b142-0d3f-c0de42dcc623.png)

### 3-3.　もしファイル名をクリックして参照状態で開いてしまい、 「実行できる状態」で開きたい場合は、鉛筆アイコンの編集をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4c4bbbbf-b2b0-d136-f042-8499a283060a.png)

以上です。
【備忘録】phpspreadsheet ファイル形式またはファイル拡張子が正しくありません。

個人用備忘録



すごく久しぶりにPHPを触る事になったものの、Laravel一強になった現状、完全に浦島太郎である。

どうにかPhpSpreadsheetをcomposerからインストールしたものの
「ファイル形式またはファイル拡張子が正しくありません。」と出てExcelが開けない。
libzipを入れるらしいけどyumコマンドの記事しか見つけられなかった。検索のやり方が下手。

*****
【環境】
　Windows
　PHP：8.3
　開発環境：Laragon 
*****
1. 以下urlからDownloads列のDLLをクリック、対応するPHPバージョン・ビット数のリンクをクリックしてzipファイルを入手
https://pecl.php.net/package/zip
　
2. zipを開いて[php_zip.dll]を使用したいPHPバージョンの[ext]フォルダに入れる。
:::note info
LaragonをWindows10,11などにデフォルトインストールしている場合、こんな感じになると思う
C:\laragon\bin\php\[phpバージョン]\ext\php_zip.dll
:::
　
3. 一階層上がってPHPフォルダの[PHP.ini]を編集、extensionを有効にする。
```php.ini
;extension=zip
extension=zip
```

*****

php_zip.dllがなぜか入ってたので合わないバージョンを過去に突っ込んだだけだｔかもしれない。
Pyinstallerでexe化したファイルに好きなアイコンを付ける！

最近初めてPyinstallerを使用してPythonプログラムをexe化したのですが、その時ふと思いました。
「exeファイルの見た目ってどうやって変えるんだ・・・？」
少し調べてみたところ、どうやら画像の拡張子が重要らしく、「ico」の形式のものを使用するとの事でした。
しかし、自前のペイント画像等の拡張子を「ico」に変更してみても反映されない！
そんな時に便利なアイコン作成サイトがありましたのでご紹介します。

## アイコンコンバーターで画像をアイコン化
https://service.tree-web.net/icon_converter/

上記サイトで手軽にアイコン用の画像を作成することができます。
使い方もとても簡単です。
1. 「ファイルを選択」ボタンを押下し、使用したい画像を選ぶ
2. 「変換ボタン」を押下する
3. 下記のような一覧が表示されるので、「アイコン形式一覧」の中から使用したいサイズを選び「Download」を押下
![アイコン形式一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2150221/426473a8-aed8-4ef3-cab2-a7cb367bf57e.png)
4. 表示された画面で「名前を付けて画像を保存」で画像を保存する

以上でアイコン用の画像は作成完了です！

## おまけ：Pyinstallerでアイコンを反映させる際のコマンド
Pyinstallerを使用している方向けの話にはなってしまいますが、アイコンを反映させる際のコマンドもついでにご紹介します。
今回はアイコンコンバーターの紹介がメインなので、Pyinstallerについてはまた別の機会に記事にできればと！
Pyinstallerでexeファイルを作成する際の基本コマンドは下記のようになります。
```Python
pyinstaller ファイル名.py --onefile
```
アイコンを反映させるには「--icon=ファイル名.ico」というコマンドを追加します。
```Python
pyinstaller ファイル名.py --onefile --icon=ファイル名.ico
```
これでexeファイルの見た目を変更できました！

***
オブジェクティブグループではXの投稿も平日毎日行っています！
IT関連の小ネタや便利技から、日常のアニメ・ゲーム布教なども幅広く投稿してるので、
ご興味のある方は是非フォロー・いいねをお願いします。
https://x.com/obg_ocr
BoothにGoogleアナリティクスを登録してみた。

# はじめに
私はBoothにて3Dプリント品を販売しています。

先日、ショップ情報を編集している際に、Googleアナリティクスを登録できることに気が付きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/db6d0ae7-5f57-7098-08b9-42665dc24d7c.png)

どのくらいお客さんがページを見に来ているのか、どの経路でサイトにアクセスされることが多いのか、気になったので登録してみることにしました。

# 本編
まずBoothのGoogleアナリティクスの設定項目の下のリンクから、Googleアナリティクスのページに飛びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/a63a12b9-16e2-607c-8628-4824ef17d4dd.png)

右上の「さっそく始める」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/2f3007aa-8667-9bcb-e461-98df43ec0883.png)

すると、登録画面が出てくるので、記入していきます。

アカウントの登録とストリームの作成を終えると以下のようなページに切り替わります。

上部にポップアップが出ているので「ストリーム設定に移動」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/c083b3e6-3ca4-d1b3-3af8-ac2af57ea2a1.png)

今回設定するBoothはwebのみの販売プラットフォームのため、「ウェブ」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/d4ab9c2b-a712-4bc8-842b-1bbea39321cb.png)

URLとストリーム名(表示名)を入力し、「作成して続行」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/1af09be0-0488-7865-1bcc-3c9a64e242a4.png)

すると、測定IDが発行されます。画面右側の「G-XXXXXXXXXX」をコピーしてBoothのGoogleアナリティクスの欄にペーストします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/8f53d06b-8936-9832-971a-afccb9cac550.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/95b2699d-e5a9-f8a4-1f28-c353da687519.png)

これで登録完了です。

画面左のタブの「ホーム」または「レポート」から情報を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/284c84de-7b45-1b5b-04d9-c1daa6cd2944.png)


試しに、シークレットウィンドウを開いて自分のBoothのページにアクセスしてみると、「アクティブユーザー」の数値が増えているのが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587155/4f4255d7-e05a-1bbe-c6f7-7c7b4890f354.png)

# おわりに
今回はBoothにGoogleアナリティクスを設定してみました。

どの商品ページへのアクセスが多いのかを確認して、需要の調査や在庫数の調整に活用していきたいです。
laravel sail でデバッグ実行する

laravelプロジェクトで
ブレークポイントをおいてデバッグ実行する方法が
直感的にわからなくて
手順がほしかったときに書いたものです

# 環境
macOS Sonoma v14.5
docker desktop for mac v4.37.2
vscode

# 前提
- sailを利用してプロジェクトが作成済みであること
プロジェクト作成についてはこちらを参考にしました
https://laravel.com/docs/11.x/installation#sail-on-macos

https://laravel.com/docs/11.x/installation#sail-on-macos

- コンテナを起動していないこと
:::note
コンテナを起動していた場合、コンテナは削除する
```sh
# 起動しているコンテナ一覧
docker ps
# コンテナ削除
sail down
```
:::

## デバッグ実行する
#### 1. vscode拡張機能をインストール

https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug

#### 2. .vscode/launch.jsonを作成
以下を追加
```json:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "stopOnEntry": false,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}"
            },
        },
    ]
}
```

#### 2. .envに追加する
```diff:.env
+ SAIL_XDEBUG_MODE=debug
```

#### 3. コンテナを起動する
```sh
sail up -d
```

#### 4. デバッグできることを確認する
テストコードにブレークポイントを置く
行左端をクリックして赤丸が表示されるとブレークポイントが置けた状態です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979573/e2cd939e-2545-77da-0677-aa1ed21e4490.png)

テスト実施
```
sail debug test ./tests/Feature/ExampleTest.php
```

ブレークポイントで止まります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979573/8fecb643-7a4b-5196-6be3-f6401d6428fa.png)


## 補足
1. .vscode/launch.jsonに記載した`pathMappings`をもとにデバッグするため、vscodeで開いているフォルダがlaravelプロジェクト直下(この場合、example-appフォルダ)
でない場合、ブレークポイントで止まらないです。 
なおターミナル上でフォルダ移動してもブレークポイントが止まらないです

2. それでもブレークポイントが止まらない場合、
launch.jsonのpathMappingを変更してみるとうまくいくことがあります

    ```diff
    // 絶対パスを直接入力
                "pathMappings": {
                　// "コンテナ側のパス": "ローカル側のパス"
    +                "/var/www/html": "/your/work/path/to"
                },
    ```



3. `debug`と指定せずに実行するとデバックモードに関係なく、ブレークポイントで止まらず実行されます

    ```sh
    # デバックモードで起動中のコンテナに対してステップ実行せずにテストする
    sail artisan test ./tests/Feature/ExampleTest.php
    ```



:::note warn
`workspaceRoot` は非推奨となったようです
https://code.visualstudio.com/docs/editor/variables-reference#_why-isnt-workspaceroot-documented

```diff
    "pathMappings": {
        // "コンテナ側のパス": "ローカル側のパス"
+          "/var/www/html": "${workspaceRoot}"
    },
```
:::
MySQLのDuplicate Entryのエラーを簡単にエラーハンドリングする方法[Go]

DB設計において、主キーを設定して重複を防ぐことがあると思います。

そこからアプリケーションでDBからデータを取り出して、データを整形して、ハンドラーでJSON等でデータを返したりすると思います。

その中でもエラーの内容によって、JSONによって表示させるエラーの内容を分岐させたいという時に、Goでは下のようにエラーハンドリングを行うと思います。

```go
if err != nil {
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, custom_error.NewNotFoundError(custom_error.NotFoundRecord)
	}
	return nil, custom_error.NewInternalServerError(custom_error.InternalErrorInternal, err.Error())
}
```

例えば、gormでのデータベース操作でデータが見つからなかったときに`gorm.ErrRecordNotFound`というカスタムエラーを返してくれます。

https://pkg.go.dev/gorm.io/gorm#pkg-variables

そのエラーを受けとったら、JSONで返す内容のテンプレートを使用して、フロントエンドにレコードがないことをわかりやすく伝えます。

上の例ではレコードが存在しないErrNotFoundですが、それ以外にもデータの重複等のエラーを出すことが必要になってくると思います。

gormの先ほど紹介したカスタムエラーには、入力データがすでにあるデータであることを表す`Duplicate entry`を表すエラーがないので、別の方法でエラーハンドリングをする必要があります。

今回は、そのようなORMライブラリ等で準備されていないエラーを対処する方法を紹介したいと思います。

# mysqlパッケージのMySQLErrorを使う

Duplicate entryのエラーコードは1062です。
このエラーコードを簡単に取り出す方法として、goの標準パッケージにmysql向けのエラーコードやメッセージを扱いやすくするMySQLErrorの構造体が準備されています。

https://pkg.go.dev/github.com/go-sql-driver/mysql#MySQLError


## アプリケーションコード内での使用例

アプリケーションコード内では、返ってきたエラーをMySQLErrorに変換してエラーハンドリングを行います。


```go
var mysqlErr *mysql.MySQLError
if ok := errors.As(err, &mysqlErr); ok {
		if mysqlErr.Number == 1062 {
			return repository.ErrDuplicateEntry
		}
}
```

`mysql.MySQLError`型の変数を準備して、errorsパッケージのAsメソッド使用してエラーを`mysql.MySQLError`型の変数に格納しています。

https://pkg.go.dev/errors#As

:::note
### errors.Asについて
Asメソッドは、エラーが別の第二引数に指定してる変数に代入可能かどうかboolとして結果を返しつつ、第二引数に結果を代入します。
```go
var pathError *fs.PathError
if errors.As(err, &pathError) {
	fmt.Println("Failed at path:", pathError.Path)
} else {
	fmt.Println(err)
}
```

このもう一つ別のメソッドとしてIsメソッドが使われることが多いです。
```go
if errors.Is(err, fs.ErrNotExist) {
	fmt.Println("file does not exist")
} else {
	fmt.Println(err)
}
```

Isメソッドは、エラ-が同じかどうかを調べることができます。
エラーは、エラーチェーンと呼ばれるエラーをどんどんラップしていくことができ、子メソッドで起きたエラーも親メソッドで見ることができます。

:::

## テストコードでの使用例

テストコードで該当エラーが返ってくるかどうかを調べるには下のように使います。

```go
wantErr := &mysql.MySQLError{
				Number:  1452,
				Message: "Cannot add or update a child row: a foreign key constraint fails (`report_generator_test`.`blueprints`, CONSTRAINT `fk_users_blueprints` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))",
}

err := repo.Create(ctx, value)

assert.ErrorIs(t,err,wantErr)
```

testifyパッケージのassertのErrorIsでMySQLのエラーコードを扱いたいときには、MySQLError型で変数を作成します。

ErrorIsの引数にはerrorインターフェースが満たされているものであれば設定することができます。

MySQLErrorはerrorインターフェースを実装しているため、引数として当てることができます。

# まとめ

MySQLErrorを使用することでORMライブラリに標準で準備されていないエラーを簡単にハンドリングすることができます。

こうすることで、string型のエラーメッセージの一致でハンドリングするなどの難しいことを考えず、エラーコード等で簡単にハンドリングできるようになるのでおすすめです。

ぜひ参考にしてください。
kafka

```sh

/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic <mytopic>
```

```yml
version: "3.8"
services:
  kafka:
    image: apache/kafka:3.7.2
    hostname: kafka
    mem_limit: 2G
    user: "1000:1000"
    cpus: 1.0
    ports:
      - "9092:9092"
      - "9093:9093"
    environment:
      CLUSTER_ID: "trading"
      KAFKA_BROKER_ID: 1
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: "broker,controller"
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093"
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT"
      KAFKA_LISTENERS: "EXTERNAL://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,INTERNAL://kafka:29092"
      KAFKA_ADVERTISED_LISTENERS: "EXTERNAL://localhost:9092,INTERNAL://kafka:29092"
      KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
      KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_NUM_PARTITIONS: 1
      KAFKA_DEFAULT_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: "/var/lib/kafka/data"
      KAFKA_LOG_DIR: "/var/lib/kafka/data"
    volumes:
      - type: bind
        source: ${HOME}/docker/kafka/data
        target: /var/lib/kafka/data

        bind:
          create_host_path: true
    networks:
      - kafka-net

networks:
  kafka-net:
    name: docker-kafka-net
    external: true 
```
SAPシステムの玄関番！インターネット通信マネージャ（ICM）を徹底解説🚪✨

SAPシステムと外部の世界をつなぐ、超重要な役割を担う**インターネット通信マネージャ（ICM）**。
例えるなら、SAPシステムの玄関番！🏠✨

今回は、ICMの仕組みや設定方法などを、初心者🔰さんでもわかるように、具体例も交えつつ、絵文字たっぷりで解説しちゃいます！🎉

### ICMってなに？🤔

ICMは、SAPシステムがHTTPやHTTPSなどのWebプロトコルを使って、外部と通信するための仕組みです。🌐
外部からのアクセスを受け付けたり、SAPシステムから外部へデータを送信したりする際に、ICMが超重要な役割を果たします。💪

例えば、あなたがAmazonで商品を購入する🛒時、
あなたのPC💻からAmazonのサーバー🖥️へHTTPリクエストが送信されます。
この時、SAPシステム（Amazonのサーバー）側では、ICMがリクエストを受け取り、処理を行うことで、
商品情報や購入手続きなどのデータがやり取りされるわけです。

### ICMのアーキテクチャを見てみよう👀

ICMは、まるで優秀なチームのように、複数のコンポーネントから構成されています。

*   **スレッド制御**: HTTPリクエストを受信し、ワーカースレッドに処理を依頼します。まるで、受付係のようですね！💁‍♀️
    *   例えば、あなたがWebサイトの「お問い合わせフォーム」✉️からメッセージを送信したとします。
        この時、ICMのスレッド制御がリクエストを受け取り、担当のワーカースレッドに処理を依頼します。
*   **ワーカースレッド**: HTTPリクエストを処理し、SAPシステムに転送します。まさに、縁の下の力持ち！💪
    *   ワーカースレッドは、受付係から受け取ったリクエストを処理します。
        例えば、お問い合わせフォームの内容をSAPシステムに登録したり、
        Webサイトの情報を検索してあなたに返したりします。
*   **ウォッチドッグ**: ワーカースレッドの状態を監視し、処理が遅延している場合はタイムアウト⏱️させます。
    *   もし、ワーカースレッドが長時間処理に時間がかかっている場合、
        ウォッチドッグが「大変！時間切れです！」と警告します。
*   **シグナルハンドラ**: OSからのシグナルを処理します。
*   **接続情報**: ネットワーク接続の情報を管理します。
*   **メモリパイプ**: ICMとABAPワークプロセスの間でデータをやり取りするための仕組みです。まるで、情報伝達のパイプ🚰

### インターネットサーバキャッシュ（ISC）とは？

ISCは、ICMの一部で、Webページや画像などのコンテンツをキャッシュ（一時的に保存）することで、Webサイトの表示速度を向上させる機能です。
よく見るWebページや画像などを一時的に保存しておけば、次回アクセス時にサクサク表示できます！🚀

例えば、あなたがよく見るWebサイトのロゴ画像🖼️があるとします。
この画像をISCがキャッシュしていれば、
次回アクセス時にサーバーから再度読み込む必要がなく、
キャッシュから直接表示できるため、表示速度が速くなります。

### ICMの起動と監視方法

ICMは、AS ABAPの起動時に自動的に起動します。
ICMの状態を確認したり、再起動したりする場合は、トランザクションコードSMICMを使用します。💻

### ICMの設定方法

ICMの設定は、プロファイルパラメータで行います。
主なパラメータとしては、ポート番号の設定やISCの設定などがあります。⚙️

### ICMでのSSL設定方法

SSL（Secure Sockets Layer）は、インターネット上での通信を暗号化するためのプロトコルです。🔒
ICMでは、SSLを使用することで、SAPシステムと外部との通信を安全に保護することができます。🛡️

例えば、クレジットカード情報💳️などを送信する際に、
SSLで暗号化することで、第三者に情報を盗まれるのを防ぐことができます。

### Web管理インタフェースを使ってみよう💻

Web管理インタフェースは、WebブラウザからICMを管理・監視するためのツールです。
ICMの状態確認や再起動など、様々な操作を行うことができます。🖱️

### まとめ

ICMは、SAPシステムと外部の世界をつなぐ、と〜っても重要な役割を担っています。🤝
ICMの仕組みや設定方法を理解することで、より安全で快適なSAPシステム運用が可能になります。💯

この記事を通して、ICMについて少しでも理解を深めていただけたら嬉しいです😊

**さらに詳しく知りたい方は、以下の記事も参考にしてください。📚**

*   SAP Help Portal - インターネット通信マネージャ
*   SAPナビ - SMICMの活用術
Excel VBA パワーポイントの情報をエクセルに書き出す

### はじめに
過去のパワポデータの有効利用を目的にエクセルシートへの書き出しを行う

### プロシジャーの説明
ExportAllPowerPointDataToExcelで実行
folderPathに対象フォルダパスを設定
### 作成したエクセルマクロ
注意．パワポの環境がない為に実際の動作は未確認。
このコードをベースにいろいろカスタマイズしないといけないです。
``` VB
Sub ExportAllPowerPointDataToExcel()
    Dim pptApp As Object
    Dim pptPresentation As Object
    Dim pptSlide As Object
    Dim pptShape As Object
    Dim ws As Worksheet
    Dim i As Integer
    Dim row As Integer
    Dim folderPath As String
    Dim file As Object
    Dim fso As Object

    ' フォルダパスを指定
    folderPath = "C:\path\to\your\folder\"

    ' ファイルシステムオブジェクトを作成
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' Excelのアクティブシートを設定
    Set ws = ThisWorkbook.Sheets("Sheet1")
    ws.Cells.Clear ' シートの内容をクリア
    row = 1

    ' PowerPointアプリケーションを起動
    On Error Resume Next
    Set pptApp = GetObject(, "PowerPoint.Application")
    If pptApp Is Nothing Then
        Set pptApp = CreateObject("PowerPoint.Application")
    End If
    On Error GoTo 0

    ' フォルダ内の各パワーポイントファイルをループ
    For Each file In fso.GetFolder(folderPath).Files
        If LCase(file.Name) Like "*.ppt*" Then
            ' パワーポイントのプレゼンテーションを開く
            Set pptPresentation = pptApp.Presentations.Open(file.Path)

            ' 各スライドをループ
            For Each pptSlide In pptPresentation.Slides
                ' 各スライドのテキストをエクセルに書き出す
                For Each pptShape In pptSlide.Shapes
                    If pptShape.HasTextFrame Then
                        If pptShape.TextFrame.HasText Then
                            ws.Cells(row, 1).Value = file.Name
                            ws.Cells(row, 2).Value = pptShape.TextFrame.TextRange.Text
                            row = row + 1
                        End If
                    End If
                Next pptShape
            Next pptSlide

            ' プレゼンテーションを閉じる
            pptPresentation.Close
        End If
    Next file

    ' PowerPointを終了
    pptApp.Quit

    ' オブジェクトを解放
    Set pptShape = Nothing
    Set pptSlide = Nothing
    Set pptPresentation = Nothing
    Set pptApp = Nothing
    Set fso = Nothing
End Sub

```
Git LFSの使い方

備忘録としてGit LFSの使い方をまとめます。
当記事はMac環境で実施した内容を基にしています。

# 作業の流れ

- LFS用のGit CLI拡張をインストール
- LFSの初期設定
- 対象ファイルの定義
- 対象ファイルの追加とプッシュ


## LFS用のGit CLI拡張をインストール
以下のいずれかの方法でインストールします。

1. 以下からzipをダウンロードし、シェルを使用してインストールする
https://git-lfs.com/

2. Homebrewを使用してインストールする

3. MacPortsを使用してインストールする

`/usr/local/bin/git-lfs`にインストールされます。

## LFSの初期設定
ローカルのリポジトリのルートディレクトリで初期設定を行います。
初期設定で実行するコマンドは`git lfs install`です。
CLI拡張のインストールとは別の手順となりますので注意が必要です。

```
sampleuser@MacBook-Pro sampleproject % git lfs install

Updated Git hooks.

Git LFS initialized.
```
これにより関連するGit hookがリポジトリに追加されます。
※この手順は1アカウント内で1度だけ実行します。

## 対象ファイルの定義
LFSの対象にしたいファイルを定義します。
PDFのファイルをLFSの対象とする場合の例を以下に示します。

```
sampleuser@MacBook-Pro sampleproject % git lfs track "*.pdf*"

Tracking "*.pdf*"
```

これにより（既存のものが無い場合は）`.gitattribures`ファイルが作成されます。
.gitattributesファイルの中身は以下の様になっています。

```
*.pdf* filter=lfs diff=lfs merge=lfs -text
```
※この手順はリポジトリごとに実施します。

## 対象ファイルの追加とプッシュ
LFSで管理したいファイル（例：Book1.pdf）をローカルリポジトリに追加します。
Book1.pdfと.gitattributesファイルを追跡対象に追加します。
```
git add .
```

コミット、プッシュします。
```
git commit -m "PDFをLFSで追加"
git push origin main
```

# 参考URL
https://git-lfs.com/
ReactでWEBアプリ作成

## はじめに
初めまして、ゆうです。

久しぶりにReact触ろうとしたが、CRAは非推奨ということでReact with Viteで環境構築をしていきたいと思います。FirebaseでReactのWebアプリをデプロイした時の自分用のメモです。簡略化してわかりにくいかもしれません。

## プロジェクト作成
Vite でプロジェクトを作成を作成していきます。
```
npm create vite@latest project_name
```
上記のコマンドを入力するとframeworkの設定が求められます。今回はReactに設定し、言語をJavaScriptにします。
```
> npx
> create-vite wedding-app

✔ Select a framework: › React
✔ Select a variant: › JavaScript

Scaffolding project in /home/username/React/project_name...

Done. Now run:
```
これでプロジェクト作成できました。
以下のコマンドを入力しましょう。
```
  cd project_name 
  npm install 
  npm run dev 
```
開発サーバーを起動して、プロジェクトが正しくセットアップされたことを確認します。
![react-vite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000962/f9ed7016-741b-feae-4de0-1f98f818c19a.png)

## FireBase
FireBaseの登録をします。
https://firebase.google.com/

firebaseでプロジェクトを作成した後、ターミナルで以下を入力します。
```
npm install firebase
npm install -g firebase-tools
firebase login
```
FirebaseHostingの設定をしていきます。
```
firebase init hosting 

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? dist
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? No
i  Skipping write of dist/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!
```
ビルドして、デプロイします。
```
npm run build
firebase deploy
```
URLが返ってくるのでアクセスするとビルドができているか確認してください。