OmniAICreator/Qiita-1.07M huggingface dataset:
10年放置した expressアプリの修復　前編

## 昔書いた小さなアプリの件
- excelが得意だが、壊れるとわかって信用してないエライ人に「DBにデータを入れてほしい」と頼まれる
- Accessでいいか？　→　現場PCが何かと壊れる劣悪環境なのでサーバに入れよう
- nodejs とか遊んでみたい→そうなんね？やってみよーか？

# expressjs+knexjs->postgresql 
* knexjs は 良かったんだが、0.x からバージョンが上がったらなんやら仕様が変わって動かない。
* PHPで書いてたクセで非同期苦手。多重技術債務者として抱えきれない→ご破産(rewrite)。
* pg-promise で書き直す。どうにか動いていた。
* エライひと退職→Excelでいいじゃんね→オレのアプリは業務から外れ放置され１０年経過。

## そもそも ES5以前 (2015年に書かれた)ものを、2025年に動かせるのか
* 異世界転生オジサンなみに古く使い物にならない
* promise周りがダメ。バージョンが飛びすぎて全部書き直しか？
* ほんとに簡単なものなので残念すぎる　→ 直すのも勉強？経験？

## 取り敢えず取り組んでみた
* pg-promise だけでも動かないの？というテスト
* 素のまま、ubuntu24.04 で展開。元はFreeBSD9.3 とかで、実は動いていたサーバそのものが存在しない。
* FreeBSD10.xが最古の環境で、 13.x/14.2 が普通の世界では node version 5 とか化石すら発掘されず、再現環境すらなかった。
* この時点でゴミ箱行きだが、こういう負の遺産を抱えた場合の返済方法ってのがあるのか知りたい
* OSコンポネント系の負の遺産、PHP系ではクソな案件であろうと債権整理（言い方！言い方！）

## 謎現象発生
* pg-promise 依存するページが刺さる現象。
* 最初はDB読めてない？DBのmigration/seed したし、psqlで手動で取れるからおかしい。
* pg-promise のサンプルコードを実行。query.js　とか。 最初は動いて sql通っていた。
* pg-promise の学習サンプル：　ES6/Promise を ES7対応にする bluebird がのモジュールが必要なサンプルコードだった。
* いろいろ動かない理由を探って、古いモジュールたちのバージョンをゴロゴロ押し上げていたら、pg-promise そのものが止まった？？
* デバッグしやすいようサーバを別なとこにおいて tcpdumpしたらアクセスしてない→Ubuntu作業環境が悪いのか
* 環境がなんやら壊れたと感じて、FreeBSDサーバに node/npm を入れて pg-promiseテスト：動く　👀
* node/npm の moduleとか、pg系がなにか引っかかるものがあるの？　→　イマココ


時間切れにてココまで。
社内システムのLDAP認証：基礎知識とログインの仕組みを体系的にアウトプットしてみた

## はじめに
LDAP認証は、多くの企業やシステムで利用されているユーザー認証の仕組みです。

:::note info
**特に、社内のシステムやネットワークに統一された認証を提供するために広く活用されています。**
:::

***本記事では、LDAP認証の基本的な流れを、社内システムにログインするイメージをもとに整理し、わかりやすく解説します。***

## LDAP認証とは？
LDAP（Lightweight Directory Access Protocol）は、ディレクトリサービスにアクセスするためのプロトコルで、認証や情報管理に広く利用されています。

![Screenshot 2025-02-03 at 11.07.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/9d29b3bc-00a9-06c4-26ab-77235a868edb.png)
引用画像：https://it.impress.co.jp/articles/-/23320

LDAP認証は、ユーザーがシステムやアプリケーションにログインする際に、LDAPサーバー（ディレクトリサーバー）を利用してユーザー認証を行う方式です。

## LDAP認証の仕組み

LDAP認証の基本的な流れは以下のようになります。

```markdown
① ユーザーが社内システムにログイン
   （Webアプリ、Linuxサーバー、VPN など）
       │
       ▼
② 社内システムがLDAPサーバーに認証リクエストを送信
       │
       ▼
③ LDAPサーバーがLDAPディレクトリにユーザー情報を問い合わせ
       │
       ▼
④ LDAPディレクトリが認証結果をLDAPサーバーに返す
       │
       ▼
⑤ LDAPサーバーが認証成功/失敗を社内システムに通知
       │
       ▼
⑥ 社内システムがログインの許可または拒否をユーザーに通知
```

## さらに補足

**1. クライアントが認証情報を入力**
- ユーザーがシステムにログインしようとする（例：Webアプリ、Linuxサーバー、VPNなど）。
- ユーザー名とパスワードを入力。

**2. LDAPサーバーに問い合わせ**
- クライアント（システム）が、LDAPサーバーに認証リクエストを送信。
- **Bind（バインド）** と呼ばれる処理で、LDAPサーバーにユーザー情報を問い合わせる。

**3. LDAPサーバーが認証を確認**
- ユーザーの情報が **LDAPディレクトリ内に存在するか** チェック。
- **パスワードが一致するか** を確認（通常はSHA-256やSSHAなどでハッシュ化されている）。

**4. 認証結果をクライアントに返す**
- **認証成功** → ユーザーを許可。
- **認証失敗** → ユーザーを拒否。

**5. ユーザーがシステムにログイン**
- 認証に成功した場合、ユーザーはアプリケーションやOSにログインできる。

:::note warn
**このように、ユーザーがログインを試みると、LDAPサーバーを介して認証が行われ、最終的に認証結果に基づいてアクセスが許可または拒否される流れになります。**
:::

## LDAP認証のメリット

✅ **ユーザー管理の一元化**  
LDAPを使うことで、複数のシステム（Linuxサーバー、Windows、Webアプリなど）で**共通のユーザー認証**を行うことができる。

✅ **シングルサインオン（SSO）との連携**  
LDAPは **SSO（シングルサインオン）システム** と統合しやすく、Google Workspace、Microsoft Azure AD、Okta などと連携可能。

✅ **スケーラビリティが高い**  
**大規模なユーザー管理** が可能で、企業内の数千～数百万のユーザーを管理することもできる。

✅ **アクセス制御がしやすい**  
LDAPのディレクトリ構造を利用して、グループごとに **アクセス制御（RBAC: Role-Based Access Control）** を行うことが可能。

## LDAP認証のデメリット

❌ **セットアップが難しい**  
LDAPの設定は **複雑** で、適切なスキーマやセキュリティ設定（SSL/TLSの設定など）が必要。

❌ **学習コストが高い**  
LDAPの **ディレクトリ構造（DN、OU、CN など）** やアクセス制御の仕組みを理解する必要がある。

❌ **パフォーマンスの最適化が必要**  
大量の認証リクエストが発生する環境では、適切な **キャッシュやレプリケーション設定** をしないとレスポンスが遅くなる。

## まとめ

- **LDAP認証** は、ユーザー情報を一元管理し、複数のシステムで **統一されたログイン** を可能にする。  
- 社内システムが **LDAPサーバーに認証リクエスト** を送り、ユーザー情報とパスワードの照合を行う。  
- **認証に成功すればログインが許可され、失敗すればアクセスが拒否** される。  
- **企業や大規模ネットワーク** では、LDAP認証を活用することで、**セキュリティと運用の効率を向上** できる。  

:::note info
**LDAP認証の仕組みを理解することで、社内システムの認証管理をよりスムーズに設計・運用することが可能になります。**
:::
Vite＋React基本メモ

# 構築直後
今回は、Viteを使用して環境構築をした。
フレームワークは、React
言語は、JavaScriptを選択している。

index.html
![スクリーンショット 2025-02-03 120051.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/2ca7e6a5-03b4-53ff-f7b5-f5e9a0d8f5c5.jpeg)

index.htmlを見てみると、srcフォルダのmain.jsxを表示していることが分かる。

main.jsx
![スクリーンショット 2025-02-03 120323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/94d4dbfb-d189-cce4-36ad-2cda54234321.png)

main.jsxでは、\<App />を呼び出して使用していることが分かる。
上部のimportを確認すると、
```
import App from './App.jsx'
```
と記述がある。
つまり、Appの中身は、App.jsxに記載されているということだ。

App.jsx
![スクリーンショット 2025-02-03 120911.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/0c7f5414-99b5-e8e2-3d11-d8206e6201b9.png)
Appというファンクションを使用した際に、returnの中を返す。
```
export default App
```
で、デフォルトでAppを表示する。

# 関数の使用
先ほど見ていったように、関数を定義し、呼び出して使用することができる。
始めてReactを使用した際に、私が抜けてしまった点も踏まえて基本的な関数の使用についてメモしておく。

まずは、関数を定義。
returnとexport default 関数名
を忘れずに。
![スクリーンショット 2025-02-03 121810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/205db125-bd28-6cb6-695c-874f98e38740.png)

次に、使用する側（今回はmain.jsx）で、インポートして使用する。
また、今回は、propsで変数を使用したため、呼び出し内で変数を定義している。
![スクリーンショット 2025-02-03 121913.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/917fde52-f9c6-6e68-b731-57941c2e17db.png)

#
自分がニワトリ頭すぎるので、備忘録として。順次更新予定。
こんな基礎的なこと、と思うけれど、ふとした瞬間に抜けてしまうんですよね。
これからReact勉強頑張ります。
【Git】WindowsでGitの認証がうまくいかないときに確認すること

# はじめに
Gitを利用していてリモートリポジトリと急につながらなくなることがあると思います。
原因は様々あると思いますが、何を確認すれば接続できるようになるかをよく忘れるので備忘録として残そうと思います。

## 接続先の確認
リモートリポジトリのURLが正しいかを確認します。
意外と誤字っているだけのことも多いのでまずURLを確認します。

## Windows資格情報の確認
Windowsの情報に古いデータが残っていて接続できないことがよくあります。
資格情報マネージャーを開き、Web資格情報または、Windows資格情報のGitやGitHubの接続情報を一度削除してからもう一度接続するとつながることがあります。

## アクセストークンの確認
アクセストークンを利用してリモートリポジトリに接続しているのでアクセストークン周りを確認します。
### アクセストークンの期限が切れていないか
GitHubのユーザ設定からアクセストークンの有効期限を確認します。
期限が切れている場合は新しくアクセストークンを発行して接続できるようにしています。

### 想定したアクセストークンを利用しているか
`git config --list --global`コマンドでアクセストークンを確認し、自分が想定しているアクセストークンを接続に利用しているかを確認します。

# おわりに
私がよく出くわすものをリストアップしましたが、ほかにも確認していることがあれば教えていただけると嬉しいです。
Brotato Modding Guide 【環境構築】

# はじめに

最近始めたBrotatoというゲームでModdingを始めるにあたり、Godotの基礎知識やBrotatoのModLoaderの仕様などでいくつか詰まったところがありました。そのため、自分自身のための備忘録も兼ねて、Moddingを考えている方に向けて記事を書くことにしました。

# 本記事について

私自身Godot初心者であるため、間違いや誤った認識が多々あると思います。ご了承ください。
今回は環境構築なので、こちらの[ModdingGuide](https://steamcommunity.com/sharedfiles/filedetails/?id=2931079751)を参考に作成しています。詳しくはこちらをご覧ください。

# 必要なもの

- Brotato (Epic版、Steam版どちらもOK、著者はEpic版を使用)
- GodotSteam 3.x系 ([DL](https://github.com/GodotSteam/GodotSteam/tree/v4.12-gde))
- GDRETools ([DL](https://github.com/GDRETools/gdsdecomp))

# 1. Brotatoを逆コンパイル

ダウンロードした `GDRTTools` を展開して、exeファイルを実行します。実行するとウィンドウが表示されるので、 `RE Tools -> Recover project...` をクリックします。

![GDRE Tools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656709/e113b1dc-15ae-767b-0f51-a9260249c131.png)

ウィンドウが表示されるのでBrotatoが入っているディレクトリ内のpckファイルを選択して `Open` をクリックします。

![GDRE Tools2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656709/05bc1d14-26fa-91dd-7fed-ee1d4f0ef630.png)

また別のウィンドウが表示されるので、 `...` をクリックして同様に逆コンパイルしたゲームデータの保存先を指定し、 `Extract` をクリックします。

![GDRE Tools3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656709/82e72fcf-e7e8-2194-2359-3c7b56db468c.png)

展開が終わると、 `OK` と表示されるので、表示されたらクリックします。

## steam_data.jsonの追加(Steam版のみ)

ゲーム本体のディレクトリ内にある `steam_data.json` を逆コンパイルしたゲームデータの保存先のディレクトリ直下にコピペする必要があるようです。

# 2. GodotSteamの起動と実行

ダウンロードした `GodotSteam` を展開して、 `editor` と入っているexeファイルを実行してください。
実行後、 `インポート -> 参照` をクリックして、逆コンパイルしたゲームデータの保存先のディレクトリにある、 `project.godot` ファイルを選択して、 `インポートして編集` をクリックします。
するとエディタが立ち上がるので、右上の実行ボタンをクリックしてゲームが起動するか確かめます。正常にゲームが起動したら環境構築完了です。うまく動かなかった場合はGodotSteamのバージョンを変更することで解決するかもしれません。

# おわりに

以降はModの作成部分に関するポイントをいくつか書いていくと思います。いくつか読んでいただけると幸いです。

## 次回リンク

- [Brotato Modding Guide【Modファイル作成】](https://qiita.com/makizakao/items/c21962c050ba4e3c5b4c)
【Ruby】include vs extend

モジュールを取り込む時に使う`include`と`extend`の違いについて理解が曖昧だったため整理。

includeとすると、インスタンスメソッドとしてモジュール内の関数が取り込まれる。
一方、extendとすると、クラスメソッドとしてモジュール内の関数が取り込まれる。

```ruby
module MyModule
  def my_method
    "Hello"
  end
end

# includeの場合
class ClassA
  include MyModule
end

# extendの場合
class ClassB
  extend MyModule
end

# 使用方法の違い
ClassA.new.my_method  # includeはインスタンスメソッドとして追加
ClassB.my_method      # extendはクラスメソッドとして追加
```
みんなでVimやろう！(小技編)

ノベルワークスのとっしー([@tossy](https://x.com/A1vbzr4SVP8))です.

　前回, Vimの簡単な操作とモードについて, そして, 少しの小技を紹介しました. 小技の方は単語間のジャンプと削除だけだったので少し物足りなかったかのではと思います. そこで, 今回もう少し小技を補足したいと思います. また, 前回ノーマルモードと挿入モードがあることをご紹介しましたが, 今回はノーマルモードでの小技をご紹介します.

**< 前回記事 >**

https://qiita.com/hashimotot/items/bf74441150a10ff63056

# 小技 <其の一> ドットコマンドでラクをする

　前回 `daw` というVimのコマンド(※1)を紹介しました. 
これは単語を削除するコマンドで, 現在のカーソルが当たっている単語全体を削除するものです.

それでは, 次のような文を考えます.

```
Edit and delete words.
```

　この文を, `delete words.`にするためにはどうしたらいいでしょうか？Vimを知っている皆さんにとっては簡単ですね. `daw`を2回適応するだけです.
　しかし, 実はもっと簡単な方法があるのです. その鍵となるのが, 今回ご紹介する**ドットコマンド**です.


**(※1)** 正確にいうと, `daw`は単なるコマンドでなく, "コマンド" と "モーション" の組み合わせで構成されています. 具体的には, `d`(削除コマンド)と`aw` (a word=単語全体を対象とするモーション)です.
　このように「操作コマンド + モーション」の組み合わせによって, どの範囲にどの操作を行うかを指定します.
 

## ドットコマンド
　ドットコマンドはドットキー("."キー)押すと実行されます. ドットコマンドは前に行った操作(アクション)を繰り返します. `daw`などもその対象であり, 一度`daw`と打つとその操作がドットコマンドに記憶され, あとは対象にカーソルを合わせて"."キーを押すだけで単語削除出来ます.

先程の文を再掲します. `Edit and`を削除したいとします.
 
```
Edit and delete words.
```

　ドットコマンドを習得した今では, `daw .`と打つだけですね.
(2単語消すだけでは少し物足りないですか？続きはぜひ, 皆さんの実践で試してみてください！）



 # 小技 <其の二> 行と仲良くなる
 
　この小技は, かゆいところに手が届くといった感じです.
　まずは, 行頭・行末にジャンプする方法についてです. 行頭に"1."などの項目入れたり, プログラマであれば行末に";"を入れたりする機会がよくあるのではないでしょうか.

### 行頭・行末ジャンプ
`^` : `行頭に飛ぶ`
`$` : `行末に飛ぶ` 

:::note info
(小ネタ)
これは正規表現の行頭・行末に対応しています.
正規表現でパターンを書く際に, 以下のように`^`や`$`を指定します.

> 行頭のパターン: ^abc（行の先頭でabcにマッチ）
行末のパターン: abc$（行の末尾でabcにマッチ）
:::


　`^`や`$`でも十分に便利なのですが, さらに便利なコマンドがあります.
それは`A`と`I`コマンドです. 大文字なことに注意してください.
　このコマンドはそれぞれ`^`と`$`に加えて, 「挿入モードに入る」というところまでやってくれます.

### 行頭・行末ジャンプから挿入モード

`I` : `行頭に飛んで挿入モードに入る`
`A` : `行末に飛んで挿入モードに入る`

　勘がいい方は気がついているかもしれませんが, これは前回説明した, ブロックカーソルから挿入モードに入る時の`i`, `a`コマンドに対応しています. iを押せばブロックカーソルの手前に入って挿入モード, aを押せばブロックカーソルの後に入って挿入モードになりました. これが大文字になると, 行単位で手前と後に入って挿入モードに入ってくれる訳です.

もう少し「操作 + 挿入モードに入る」という枠組みで, `o`(小文字)と`O`(大文字)コマンドを紹介します.
このコマンドは行の前後に文を追加する時に重宝します.

### 行追加
`o`(小文字) : `現在のカーソルの行の下に, 新たに行追加し挿入モードに入る`
`O`(大文字) : `現在のカーソルの行の上に, 新たに行追加し挿入モードに入る`

　この章で, いくつか行に関するコマンドを紹介しました.これらのコマンドを駆使することで, 行単位での編集がとてもラクになります. 
　とくにプログラマの方は, `A`や`o`コマンドが重宝するのではないでしょうか. もちろんこれらのコマンドにおいても色々な発展があるので, 是非Vimを勉強してこれらの操作に磨きをかけてみてください.
 
# 小技の合わせ技

最後に, さっきの小技の合わせ技を披露したいと思います. 次のような文(コード)を考えます.

```js
function greet() {
    console.log("Hello")
    console.log("world")
    console.log("!")
}
```

　console.logの末尾に";"を付け加えたいとします. これを, さっきの小技を使って鮮やかに編集してみましょう.
 `A`コマンドを用いて行末で挿入モードに入り, ";"をタイプして`esc`で抜ける. あとはドットコマンドで繰り返すことで実現できます.

### 合わせ技をやってみる

　まずドットコマンドに正しくアクションを記憶させる準備として, ノーマルモードに入り, 1行目の`console.log("Hello")
`にカーソルを合わせます.(カーソル位置はどこでも大丈夫ですが, 試しに行頭にセットしておきます)
　次にドットコマンドの記憶を初期化するために`esc`を押します. これでドットコマンドに操作w記憶させるための準備は完了です.
 では, ドットコマンドに一連の操作(アクション)を記憶させます. 
 　`A`で行末に飛んで挿入モードに入り, ";"をタイプします. そして, `esc`で挿入モードを抜けます. `esc`を押した時点で, この一連の操作がドットコマンドに記憶されます.
  後は, 各行に対して同じ操作をドットコマンドを用いて各行に適応するだけです. `j.j.`と繰り返すことで, 全ての`console.log()`の末尾に";"が追加されたはずです. もしやりすぎてしまった時は`u`(undo)コマンドで元に戻せます.
  どうでしょうか, あまりの簡単さに少し驚いた方もいるのではないでしょうか. このようにドットコマンドと操作を組み合わせることで, 面倒な編集が, とても簡単になることがあるんです.

　今回ご紹介した小技だけでもかなり編集がラクになると思いますが, 他にも もっとたくさんの便利な技があります. 宜しければ皆さんもまた, 一緒にVimを学んでいきましょう.
【Ruby】特異メソッドはあるオブジェクトだけが持つメソッドである

特異メソッドとは特定のオブジェクト一つだけが持つメソッドのこと。

```ruby
class Dog
  def bark
    "Woof!"
  end
end

# 2つのインスタンスを作成
dog1 = Dog.new
dog2 = Dog.new

# dog1にだけ特異メソッドを定義
def dog1.jump
  "Jump high!"
end

# 実行結果
dog1.bark  # => "Woof!"
dog2.bark  # => "Woof!"
dog1.jump  # => "Jump high!"
dog2.jump  # => NoMethodError (未定義のメソッド)
```

以下のような実装も特異メソッド。

```ruby
class Dog
  def self.species
    "Canine"
  end
end

# 実行してみると
Dog.species        # => "Canine" （クラスメソッドとして実行可能）
dog = Dog.new
dog.species        # => NoMethodError （インスタンスからは実行できない）
```

この実装では、Dogのインスタンスがすべて`species`を実行できるため、特異メソッドではないように見えるが、クラスメソッドはクラスオブジェクトの特異メソッドとして定義されるからこれらも特異メソッドと捉えることができる。
【Unity初心者】Unityでネットゲームを作りたい【16】謎のエラーで悩む～パネルでボタンを押したら、このパネルを消して別パネル表示

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
### 謎のエラーで悩む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/c39c8663-9cc1-1919-b551-eb62ff6ceaea.png)
なあにこれ？
調べてみる
なんか中国語の言語がうんたらかんたら...
ｳﾑｰ
ランゲージを英語にしたり日本語にしたりUnityをもっかい立ち上げたり
そうするとエラーが出たりでなかったり

テキストに漢字を入力すると表示されたりされなかったり...

エラーが消えた時に保存して、出たら保存時に戻ってってやってました
漢字入力の時は気を付けたほうがいいかも

次
nullreferenceexception: object reference not set to an instance of an object![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/778bd828-1e2a-df20-c478-65db9bbb21c6.png)

このエラー
さっきいじるまで普通に動いてたのに！！ってなる

これはホント悩んで調べて、何しても消えなかったり
結局エラー出てないアセットをコピペしてとりあえず解決とかしてました

進めていたら、どうもコピペしたパネルとか画像とかテキストとかボタンとかに張り付いてたスクリプトもそのままコピーして悪さしてたんじゃないかと推測
いらないのは削除したりして、出なくなった
コピペの時は気を付けないとだわ
___
### パネルでボタンを押したら、このパネルを消して別パネル表示
複数のパネルを同じシーンで出したり消したりしたい
前は、どちらかのパネルを表示すればよかったが、今回は入れ替え
```
using UnityEngine;
using UnityEngine.SceneManagement;

public class Irekaesentaku1 : MonoBehaviour
{
    public GameObject Panel;
    public GameObject Panel1;
    
    public void Clickhereire()
    {
        Panel.SetActive(false);
        Invoke("Hhhh", 0.1f);
    }
    void Hhhh()
    {
        Panel1.SetActive(true);
    }
}
```
同時だとうまくいかなかったので、Invoke("Hhhh", 0.1f);でほんのちょいと遅らせたら成功
これをボタンに放り込んでパネル切り替えができた

シーンのメイン画面にあるボタンが邪魔すぎるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/24932441-6275-f5fe-46b7-3304b0b4f5cf.png)
Buttonじゃないのは許して
パネル表示時に、非表示にして解決
←前  [【Unity初心者】Unityでネットゲームを作りたい【15】複数のPanelの表示を制御したい～数字ランダム](https://qiita.com/ysyss5500/items/6883a0c358cf3e645809)

[【Unity初心者】Unityでネットゲームを作りたい【17】パネル間でデータの引継ぎをしたい～どのボタンが押されてるか判断して次のパネルへ～Jsonファイルの読み込みが早すぎる？](https://qiita.com/ysyss5500/items/9be5fba0737d5f4ccd64)　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
React環境構築（Windows）

# 手順 1: Node.js をインストール
Reactを動かすには Node.js が必要です。
以下の手順でインストールします。

Node.jsの公式サイトにアクセス。

https://nodejs.org/ja/

推奨版 (LTS) をダウンロードしてインストール。
以下のコマンドでインストールを確認。

```powershell
node -v
npm -v
```

それぞれ、バージョンが表示されればOK。


# 手順 2: Reactプロジェクトの作成
Reactアプリを作成する方法は大きく2つあります。

### 方法 1: Create React App (初心者向け)
簡単な設定で環境を構築できます。

```pwershell
npx create-react-app （任意のアプリ名）
例）
npx create-react-app my-app
```
これで、my-appが作成されました。
次に、アプリのディレクトリに移動して、ブラウザを起動します。
```powershell
cd my-app
npm start
```
→ ブラウザが自動で開き、http://localhost:3000 でアプリが動作します。

### 方法 2: Vite（高速で軽量）
最近はViteの方が人気です。

```powershell
npm create vite@latest my-app
```
使用するフレームワークなどを選択後、アプリの作成開始。
```powershell
cd my-app
npm install
npm run dev
```
→ http://localhost:5173 にアクセスするとアプリが確認できます。

# 手順 3: CRA（Create React App）と Viteのコマンド表
| 動作 | CRA | Vite |
|:-:|:-:|:-:|
| 開発サーバーを起動  | npm start  | npm run dev  |
|  本番ビルド | npm run build  |  npm run build |
| ビルド後のプレビュー  | npx serve -s build  | npm run preview  |
|  依存関係のインストール | npm install  |  npm install |
| パッケージ追加  | npm install package-name  | npm install package-name |
|  パッケージ削除 | npm uninstall package-name  |  npm uninstall package-name |



# 手順 3: 開発環境のセットアップ（おまけ）
開発をしやすくするために、以下のツールを用意すると便利です。

VS Code のインストール
公式サイト からダウンロード。

<ul>
    <li>ES7+ React/Redux/React-Native snippets（Reactのスニペット）</li>
    <li>Prettier（コード整形）</li>
    <li>ESLint（コードチェック）</li>
</ul>
Python3.13.1 on AmazonLinux 2023（ESXi）

Python3.10以降をインストールする際に、openssl関連でパッケージなんだっけ？OS毎に異なるっけ？となるので、備忘録です。

# 前提
OS：Linux amznlinux2023 6.1.124-134.200.amzn2023.x86_64

# 1. 必要packageのインストール
ビルドに必要となるpackageを入れておきます。
```bash
yum install -y bzip2 bzip2-devel gcc git libffi-devel readline readline-devel sqlite sqlite-devel zlib-devel libdb-devel gdbm-devel xz-devel tk-devel uuid-devel libuuid-devel
yum install -y openssl-devel 
```

公式サイトからPython-3.13.1.tgzをダウンロード。
```bash
wget https://www.python.org/ftp/python/3.13.1/Python-3.13.1.tgz
tar xzvf Python-3.13.1.tgz
cd Python-3.13.1
./configure --enable-optimizations
make
make install
```

バージョン確認
```abl
[root@xxxx ~]# exit
[root@xxxx ~]# sudo su -
[root@xxxx ~]# python3 -V
Python 3.13.1
[root@xxxx ~]# pip3 -V
pip 25.0 from /usr/local/lib/python3.13/site-packages/pip (python 3.13)
```

OVAファイルからESXiの仮想マシンとして起動した場合、ホストとの時刻同期がデフォルト有効となります。ホスト側が9時間ずれているなどあれば、以下記事を参考にしてください。

https://qiita.com/nw-engineer/items/05268f718378b8e1a7dc
pdf2txt.sh: PDF からテキスト抽出するシェルスクリプト

![250203_pdf2txt_rd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/742bc8b1-b476-0eda-b0c8-c4fc62388da8.png)


## 概要

このスクリプトは、PDF ファイルからテキストを抽出し、`.txt` ファイルへ出力します。  
利用ツールは `mutool` と `sed` です。



## スクリプト配置について

本体は `development` フォルダに配置、シンボリックリンクを `~/bin` に作成しています。  
`~/bin` は PATH に含まれているため、どこからでもコマンドとして利用可能です。

## スクリプト内容

以下が `pdf2txt.sh` の内容です。

```bash
#!/bin/bash
# 引数が1個でなければ使用方法を表示して終了
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 input_file"
    exit 1
fi

input="$1"

# 入力ファイルが存在するか確認
if [ ! -f "$input" ]; then
    echo "Error: File '$input' not found."
    exit 1
fi

# 入力ファイル名から拡張子を除いた部分に .txt を付けた出力ファイル名を作成
output="${input%.*}.txt"

# mutool draw でテキスト抽出し、sed で前後の空白削除と空行削除を行う
mutool draw -F txt -i -- "$input" | sed 's/^ *//;s/ *$//;/^$/d' > "$output"

echo "Output written to '$output'"
```

:::note
いろいろいい感じに加工します
- 各行の先頭・末尾の空白を削除
- 空行を除去
- 元のファイル名（拡張子除く）に .txt を付与したファイルへ出力
:::

## 使い方

1. **スクリプトの保存**  
   `development` フォルダ内に上記内容を `pdf2txt.sh` として保存します。

2. **シンボリックリンクの作成**  
   `~/bin` にシンボリックリンクを作成することで、どこからでも実行できるようにします。  
   例えば、以下のコマンドを実行します。

   ```sh
   ln -s /path/to/development/pdf2txt.sh ~/bin/pdf2txt.sh
   ```

   ※ `/path/to/development` は実際の `development` フォルダのパスに置き換えてください。

3. **実行権限の付与**  
   スクリプトに実行権限を与えます。

   ```sh
   chmod +x /path/to/development/pdf2txt.sh
   ```

4. **スクリプトの実行**  
   PATH が通っているので、どこからでも以下のように実行できます。

   ```sh
   pdf2txt.sh sample.pdf
   ```

   → すると、`sample.txt` という名前のテキストファイルが生成され、抽出したテキストが格納されます。

## 補足

- **エラーチェック**  
  入力ファイルが存在しない場合や、引数が不足している場合にエラーメッセージを表示して処理を終了します。

- **使用ツール**  
  - [mutool](https://mupdf.com/docs/commands.html) を使用して PDF からテキスト抽出  
  - [sed](https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html) によるテキスト整形

## 環境

- **OS:** macOS Sequoia 15.2  
- **ハードウェア:** MacBook Pro (14-inch, 2021)
【Unity初心者】Unityでネットゲームを作りたい【15】複数のPanelの表示を制御したい～数字ランダム

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
### 複数のPanelの表示を制御したい
これと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/f3dca825-ee76-2623-1b7f-ea49ea4b571e.png)
これ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/99b09c21-7961-b65e-b425-e8890cc3297a.png)

３０％の確率で失敗、他成功　としたい
それぞれ、Panel（デフォ）とPanel2と名付けて、初のパネル作り

いままでオブジェクトを探してそこの値を変えてきたので（モンスター画像等）
同じようにしたけど、ダメだた
そして調べまくる

[Unityでオブジェクトの表示/非表示を切り替える](https://qiita.com/mizuki170817/items/e8695ff9bb9d2eeda008)こちらでお勉強
ああ、そっか　public GameObject _testPanel;こうやって最初設定するんね
そういえばどっかででてきたような...

でもやってみると..動かねー

ｳﾑｰ

色々いじってると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/29abc9c6-5be4-9d48-80da-5bb668159c6a.png)
これに気が付きます
ここで放り込んでおかないと認識してくれんのね

成功！
理解するまですげー時間かかった(-_-;)


```
using UnityEngine;
using UnityEngine.SceneManagement;

public class Panelsentaku : MonoBehaviour
{
    public GameObject Panel;
    public GameObject Panel2;
    
    public void clickhere()
    {
        int rnd = UnityEngine.Random.Range(1, 10);
        if (rnd < 3) 
        {
            Panel2.SetActive(true);
        }
        else 
        {
             Panel.SetActive(true);
        }
    }
}

```
こんな感じ
両方とも最初は非表示にしてます

んで
戻るボタンでpanel消しまして、もっかい起動
数字が同じです
１度やったプログラムの数字がそのまま

リセットで数字0にしてみたけど、なってない
ホント毎回何かで躓くｗ

下のメニューの捜索をもっかい押したら
最初から動き出してくれた（リセットできた）ので
　戻る　に同じな「いらない」に放り込んだ
ら、正常起動！これも結構時間かかった
慣れればこういうのもすぐわかるんだろね

ちなみに、メイン画面の上にPanel作ってボタン置く場合
メイン画面でのボタンの上（同じ場所）にパネルのボタンを設置すると反応しません
重なってない所だけOKになる
ボタンを結構配置するなら、別シーンにしちゃったほうがいいかもだ
___
### 数字ランダム
１～１００とかで乱数発生させたい
調べたらいっぱいあったけど、どれもエラー...ﾑｳｰ

[Unityのランダム値生成における注意点](https://qiita.com/makiT/items/1c353c5b920b8dea5df1)こちらでお世話になりました
ただの　Random　じゃだめみたい　C＃なら大丈夫なのか？
Unityでは　UnityEngine.Random　こうするみたいね
何かと競合してるみたい

無事乱数発生できました

←前  [【Unity初心者】Unityでネットゲームを作りたい【14】メニューバー作成～表示順序](https://qiita.com/ysyss5500/items/710aead57fa0ca186248)

[【Unity初心者】Unityでネットゲームを作りたい【16】謎のエラーで悩む～パネルでボタンを押したら、このパネルを消して別パネル表示](https://qiita.com/ysyss5500/items/6b939c5f2badfef63812)　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
Shadcn/uiのdialogをcloseしたときにbodyにpointer-event:none;が残ってしまう対処法

## 結論
DialogContentに**onCloseAutoFocus**を追加して、明示的にスタイルを削除する
```TypeScript
...
    <DialogContent
        onClick={(e) => e.stopPropagation()}
        onCloseAutoFocus={(event) => {
            event.preventDefault();
            document.body.style.pointerEvents = '';
        }}
        className="focus:outline-none"
    >
...
```
参考になれば幸いです。（もっと早くGitHubのissuesで検索すればよかった・・・）

## 参考サイト
[Shadcn/ui　Dialog](https://ui.shadcn.com/docs/components/dialog)
[解決法があったIssues](https://github.com/radix-ui/primitives/issues/1241)
[Radix UIのDialogページ](https://www.radix-ui.com/primitives/docs/components/dialog)
2025年2月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。


広告(スポンサー)と広告以外の表示順が元にもどりましたね。上位に広告(スポンサー)の検索結果が表示され、その後に広告以外が表示されています。


# 2025年2月3日の検索結果 (広告(スポンサー))

![スクリーンショット 2025-02-03 104643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/064e775d-8b48-d278-78f2-270f439c19c2.png)

* Dynatrace
* Splunk
* ServiceNow
* IBM

今月は Dynatrace が TOP で、Splunk と ServiceNow が続いています。

先月の結果はこちら --> [2025年1月 AIOps 定点観測](https://qiita.com/mkodera/items/c8b145c6e535b1d04cf1)



# 2025年2月3日の検索結果 (広告以外)

![スクリーンショット 2025-02-03 104720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/fa6c672e-ad24-6fea-6c66-5990bc18beb1.png)

* HPE
* AWS
* Splunk
* 日立ソリューションズ・クリエイト
* IBM

今月は HPE が TOP で、AWS と Splunk が続いています。

先月の結果はこちら --> [2025年1月 AIOps 定点観測](https://qiita.com/mkodera/items/c8b145c6e535b1d04cf1)
読書メモ 『Tidy First?』

# 引用

全て以下より引用

https://www.oreilly.co.jp/books/9784814400911/

具体的なtidyする方法は、リーダブルコードに書いてあるような内容(不要なコメントをなくす、説明変数を加える等)だったので、tidyとは、という本書の中心部分をメモした。
薄くて読みやすい本。
1時間後に効果が出る、とある通り、リーダブルコードより即効性がある感じだった。

# ボーイスカウトルール

>次の人のために少しだけコードを整頓しておこう。
全員がこのボーイスカウトルール（来たときよりも美しく)に従えば、そのうちにより扱いやすいコードになっていくであろう。

p.114


# Tidy

>整頓はリファクタリングのサブセットだ。整頓は可愛くてふわふわした小さなリファクタリングなので、誰も嫌いなれないはずだ。

p.7

# 整頓用のプルリクエスト

>整頓はどこかに入れなければならない。さもないと整頓しない。ではどこに入れればいいだろうか？結論。整頓ははそれ用のプルリクエストに入れる。整頓はプルリクエストごとにできるだけ少数にする。

p.45


# 整頓は赤ちゃんのよちよち歩きのようなミニリファクタリング

>第一部　整頓
整頓は赤ちゃんのよちよち歩きのようなミニリファクタリングだ。それぞれの短い章が、１つの整頓になっている。該当しているコードを見たら説明しているように変える。それから本番環境に投入する。

p.xvi

# はるか先の未来を見据えたものではない

>整頓ははるか先の未来を見据えたものではない。整頓は当面のニーズに対応するものだ。

p.55

# 先に整頓するか？という問いに答える

タイトルにある通り、この問いに、経験主義的に答える、という本書のスタンス。

>コスト:整頓によってコストが小さくなったり、コストが発生する時期が遅くなったり、コストが発生する時期が遅くなったり、コストが発生する可能性が低くなったりするか?
収益:整頓によって収益が大きくなったり、収益を手にする時期が早くなったり、収益を生む可能性が高くなったりするか?
結合:整頓によってより少ない要素の変更になるか?
凝集：整頓によって変更が必要な要素が、より小さく、もっと集中した範囲になるか？

p.115
【電脳少女プログラミング2088 ─壊レタ君を再構築─】D:カジノをやってみた。

# はじめに
paizaの新作プログラミングゲーム【電脳少女プログラミング2088 ─壊レタ君を再構築─】カジノ（paizaランク：D相当）をやってみました。

https://ppg.paiza.jp/denno2088/areas/12

# 問題
 あなたはカジノにやってきました。
カジノで使われるチップは 1 ドルのもの 5 ドルのもの 10 ドルのものがあるようです。

各チップの枚数が 1 ドル, 5 ドル, 10 ドルの順で改行区切りで与えられるので合計で何ドルかを出力してください。


# 解答

**単純な書き方**

```go
package main

import "fmt"

func main() {
    var n [3]int
    fmt.Scan(&n[0], &n[1], &n[2])
    fmt.Println(n[0] + 5*n[1] + 10*n[2])
}
```

**解説**

- `fmt.Scan()`を使用して、標準入力から3つの整数を読み取ります。
  - `n[0]`：1ドルチップの枚数
  - `n[1]`：5ドルチップの枚数
  - `n[2]`：10ドルチップの枚数
- 合計金額を計算するために、それぞれのチップの枚数にその価値を掛けます。
  - 1ドルチップ：`n[0] * 1`
  - 5ドルチップ：`n[1] * 5`
  - 10ドルチップ：`n[2] * 10`
- それらを合計し、`fmt.Println()`で出力します。

**bufioを用いて入力を行う場合**

```go
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)

    var n [3]int
    for i := 0; i < 3; i++ {
        scanner.Scan()
        n[i], _ = strconv.Atoi(scanner.Text())
    }
    
    fmt.Println(n[0] + 5*n[1] + 10*n[2])
}
```

**解説**

- `bufio.Scanner`を使用して、標準入力から行単位でデータを読み取ります。
- ループを使って3回`scanner.Scan()`を呼び出し、それぞれの入力行を取得します。
- `strconv.Atoi()`で文字列を整数に変換します。
- 合計金額の計算と出力は前の例と同じです。

# 今回学んだこと

- **標準入力からの値の受け取り方法**
  基本的な`fmt.Scan()`に加え、
  `bufio.Scanner`での入力受取を実装した。
  実装速度において、小規模データではほぼ同じだが、大規模データ（数百〜数万の入力）では、bufioが数倍〜数十倍高速になる。

↓ fmtとburioの違い
  
https://qiita.com/maooz4426/items/4e70baae712c9e19300e
  
- **文字列から数値への変換**
    文字列→数値：`strconv.Atoi()`
    数値→文字列：`strconv.Itoa()`

https://qiita.com/quicksort/items/c9522793a941edf074fd
Python+REST APIでkintoneのアプリからフィールドコードの一覧を取得する。

# kintoneのフィールドコードをPythonで読み込む
kintoneのアプリのフィールドコードの一覧を取得するコードです。
Copilotに出力させたコードだと動かなかったのは、get分の書き方が違っていたようです。

```python: GetKintoneFieldCode.py
import requests

# kintoneの設定
subdomain = 'SUBDOMAIN'
app_id = 'APPID'
api_token = 'APITOKEN'

class KINTONE:
    def GetKintoneFields(self):
        # URL
        url = f'https://{subdomain}.cybozu.com/k/v1/app/form/fields.json'

        # ヘッダー
        headers = {
            'X-Cybozu-API-Token': api_token,
            'Content-Type': 'application/json'
        }

        # ボディ
        body = {
            'app' : app_id
        }

        # リクエストを送信
        # Copilotのコード
        # response = requests.get(url, headers=headers, params=body)
        response = requests.get(url, headers=headers, json=body)
        
        return response

if __name__ == '__main__':
    knt=KINTONE()
    resp=knt.GetKintoneFields()

    # レスポンスをJSON形式で取得
    fields = resp.json()

    # Field codeを表示
    if 'properties' in fields:
        for field_code, field_info in fields['properties'].items():
            print(f"Field Code: {field_code}, Field Name: {field_info['label']}")
    else:
        print(fields)
```
サーバーサイドとクライアントサイドの違い

## サーバーサイドとクライアントサイドの違いってなんぞや
next.jsに移行してから、サーバーサイドとクラインアントサイドの違いに気を使うようになったのでまとめます。

### サーバーサイド（SSR）
処理場所: **サーバー（Node.jsなど）**
リクエストが来たら、サーバーでデータを取得・レンダリングしてHTMLを生成し、クライアントに送信する。
初回表示が速い（クライアント側でレンダリングする負担が少ない）
SEOに強い（検索エンジンがHTMLを取得しやすい）
一方でリクエストごとに処理するため、サーバー負荷がかかる場合もある
つまりリクエスト毎にデータを取得し、ページをレンダリングするということ！

### クライアントサイド（CSR）
処理場所: **ユーザーのブラウザ（JavaScript実行環境）**
最初は軽いHTML（骨組み）を送り、JavaScriptでデータを取得＆レンダリング
インタラクティブなUIを作りやすい
ページ遷移が高速（SPAのような動作）
ただし、データ取得やレンダリングをブラウザが担当するため、初回表示が遅くなることもある
初回は「Loading...」が表示され、データ取得後に画面が更新されるイメージ！

## Next.jsとサーバーサイド、クライアントサイドの関係性
じゃあなぜNext.jsに移行してからサーバーサイド、クライアントサイドが気になるようになったかというと、Next.jsの特徴というか強み(?)として、ページごとにSSR（サーバーサイド）かCSR（クライアントサイド）かを選べることができるのです。なのでページごとにどっちを使えばいいのかと考えて適用させていくという工程が必要。

#### サーバーサイド（SSR）が向いているケース
初回表示を速くしたい（SEOが重要な記事ページなど）
リクエストごとに最新データを取得したい（管理画面など）

#### クライアントサイド（CSR）が向いているケース
ユーザーごとに動的なデータを扱う（ダッシュボードやユーザー専用ページ）
何度もデータを更新するようなページ（チャットアプリなど）



## 自分的総括
現在の担当プロジェクトではNext.jsのapp/ディレクトリ（App Router）を使用していて、これはデフォルトがサーバーコンポーネント（厳密にいうとSSRとは違うけどまあほぼ一緒という理解）です。なので、seoとかを定義しているpage.tsxはSSRでそのpage.tsxで呼び出しているコンポーネントの中で必要なものはCSRへ変更しています。クライアントで動的処理をしたいコンポーネントには "use client" をつけてあげる感じだね。基本的な考えとしては、
①useState / useEffect を使う
②onClick などの イベントハンドラー を使う
③localStorage / window / document など ブラウザAPI を使う
以上のものに関してはCSRへ変更してあげるという感じで実装しています。
Dockerfile、docker-compose.ymlを作るときの備忘録

# この記事のポイント
Dockerを使ってコンテナで開発環境を作るに当たり、微妙にハマった箇所や情報が見つけにくかったポイントを、自分の備忘録としてまとめています。

# 想定対象
基本的には個人用の備忘録ですが、なんとなくDockerを使っているけど、細かいポイントが抑えきれていない、という方には参考になる情報もいくつか出てくるんじゃないかと思います。
誤りや説明の不足と思われる箇所がありましたらご指摘お願いします。 m(__)m

# 前提
```bash
% docker -v
Docker version 27.4.0, build bde2b89
```

作っている環境としては nginx+php-fpm+Laravel+MySQL の、PHPを動かす環境です。

# 以下、ハマったポイントを順不同に箇条書き

## 1. volumesのパス
プロジェクトのフォルダ構成はだいぶ省略していますがこんな感じ。
```plaintext
root
┝ php-fpm        // PHP関連の設定ファイルが置いてあるフォルダ
│  ┝ php.ini     // php設定ファイル
│  └ Dockerfile  // php用コンテナのDockerfile
┝ nginx          // Webサーバ用の設定ファイルなどがおいてあるフォルダ
│  ┝ default.conf  // nginx用設定ファイル
│  └ Dockerfile  // nginx用コンテナのDockerfile
┝ src            // Laravelのプロジェクトソースが置いてあるフォルダ
│  └ public/     // Laravelのpublicフォルダ
└ docker-compose.yml  // docker compose の設定ファイル
```


docker-compose.yml を使って `docker compose` コマンドでビルドをする場合、docker-compose.yml でのvolumesの書き方によって、Dockerfileでのカレントディレクトリの位置が変わる＝Dockerfile内で記述する相対パスの書き方が変わる。

### Dockerfileではカレントディレクトリの上位フォルダへの参照不可。
表記の通り、例えば php-fpm/Dockerfile 内で各種パスを記述する際、 `../php.ini` のように、rootフォルダ配下にphp.iniが配置されたりしていると、参照することはできない。
このため、通常COPY対象となる設定ファイルなどはDockefileと同じまたはそれより下のフォルダに配置するのが一般的。
```Dockerfile
COPY ./php.ini /usr/local/etc/php/php.ini
```



### docker-compose.yml でカレントディレクトリを指定する。
しかし、docker-compose.ymlの中で対象コンテナのvolumesを指定する際に
```yaml
  php-fpm:
    build:
      context: .
      dockerfile: ./php-fpm/Dockerfile
```
のように `context` で `.` を指定することで、 `docker compose` コマンドを実行しているカレントディレクトリを、イメージビルド時のカレントディレクトリとして扱うことができる。
この場合、Dockerfile内のCOPYコマンとの記述としては
```dockerfile
COPY /php-fpm/php.ini /usr/local/etc/php/php.ini
```
のような形で、rootディレクトリが `docker compose` コマンドの実行ディレクトリとなる。
この形なら、もしphp.iniがroot直下に配置されている場合でも
```dockerfile
COPY /php.ini /usr/local/etc/php/php.ini
```
のようにコピーすることが可能。

ただし、この場合、Dockerfileの指定が、標準名でおいてあるフォルダ指定では効かなくなる。
通常
```yaml
  php-fpm:
    build: ./php-fpm
```
とだけ指定すれば良いものがエラーになるため、上の例のように `Dockefile` とファイル名まで明示的に指定しなければエラーとなる。

自分がやりたいことに合わせた書き方の組み合わせで記述する必要あり。

--- 

## 2. delegate などのオプションを long syntax で書く場合は `consisttency`
```yaml
  volumes:
    - ./src:/var/www/html/:delegated
```
のように short syntaxで書くことが多いかと思いますが、これを一つ一つ名称を指定する long syntax で書くと
```yaml
    volumes:
      - type: bind
        source: ./src
        target: /var/www/html
        consistency: delegated
```
`consistency` というキーワードが意外と探しても見つからなかったので。

--- 

## 3. nginxの環境設定について
dockerとは少しズレますが、nginxの環境設定についてもハマったので記載しておきます。

nginx.conf などで作成するnginxの設定ファイルですが、nginxの公式dockerイメージを使うと、1.9以降から、デフォルトで環境変数への差し替えを行うようになっているとのこと。（ [参考記事](https://egashira.dev/blog/how-to-set-env-into-nginx-container) ）

このとき、ハマったのがファイル名の命名規則です。
コンテナ内の `/etc/nginx/templates/` 配下に、 `*.conf.template` の命名ルールに沿った形でファイルを配置して置かなければ処理対象となりません。
例えば `default.template` としていたり、または `/etc/nginx/conf.d/default.conf.template` などだと、処理対象とならないため注意が必要です。

--- 

ひとまずここまで。
作業続けてポイントになりそうなものが出てきたら、随時更新していきます。
初心者でも10分で完了！DeepSeekモデルを無料でデプロイする手順  

---

# **初心者でも10分で完了！DeepSeekモデルを無料でデプロイする手順**  
## 〜ローカル環境でAIを動かす最速ガイド〜  

---

### 🚀 ローカルデプロイの3大メリット  
1. **コストゼロ**：クラウド課金不要、オフライン利用可能  
2. **高速処理**：GPU不要のCPU最適化設計  
3. **プライバシー保護**：データが外部サーバーに送信されない  

---


### 🚀 手順概要  
1. Ollamaのダウンロードとインストール  
2. コマンドラインでの動作確認  
3. DeepSeek-R1モデルの選択と実行  

---

### 📥 ステップ1：Ollamaのダウンロード  
1. **[Ollama公式サイト](https://ollama.com)にアクセス**  
![微信图片_20250203073450.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000801/050dbe5b-30b5-d595-87ec-0c6806cd9755.png)
   > 「Download」ボタンをクリック  

2. **OSに合わせてインストーラーを選択**  
   ![微信图片_20250203073518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000801/021d0d58-ca39-2305-5c1a-58e9b60ed189.png)

   - Windows：`Download for Windows`  
   - macOS/Linux：対応するタブを選択  

---

### ⚙️ ステップ2：インストール  
3. **ダブルクリックでインストール**  
   - ダウンロード完了後、インストーラーを実行
  
   - 全てデフォルト設定で「Next」を連続クリック  

4. **インストール完了確認**  
   ```bash  
   # Windows：Win+R → cmd 入力  
   ollama --version  
   ```  
   > バージョン情報が表示されれば成功  
![微信图片_20250203074729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000801/635939f7-568c-a159-6524-e270a9808e0c.png)

---

### 🔍 ステップ3：DeepSeek-R1モデル実行  
5. **利用可能なコマンド確認**  
   
   ```bash  
   ollama list        # モデル一覧表示  
   ```
   ![微信图片_20250203080218.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000801/267fce17-6d69-ad70-e9d7-18c0fe167f3f.png)

   ```bash  
   ollama run <モデル名> # モデル実行  
   ```
![微信图片_20250203075943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000801/4d72fea4-9484-e7a2-53fc-f219f4082b93.png)

6. **モデル検索と選択**  
   ```bash  
   ollama search deepseek-r1  
   ```  
     
   - **推奨モデル**：  
     - `deepseek-r1:70b`：高精度向け（VRAM 20GB以上推奨）  
     - `deepseek-r1:32b`：バランス型（VRAM 12GB以上）  

7. **モデルダウンロード＆実行**  
   ```bash  
   ollama run deepseek-r1:32b  
   ```  
   > 初回は自動ダウンロードが開始  

---

### 📊 モデル仕様比較表  
![モデル仕様](mmexport1738541498351.png)  
| モデルサイズ | 必要VRAM | 推奨用途 |  
|-------------|----------|----------|  
| **32b**     | 20GB     | 汎用タスク |  
| **70b**     | 43GB     | 研究開発 |  

---

### 🛠️ トラブルシューティング  
- **ダウンロードエラー時**：  
  ```bash  
  ollama pull deepseek-r1:32b  # 手動ダウンロード再試行  
  ```  
- **メモリ不足時**：  
  ```bash  
  export OLLAMA_NUM_GPU=0  # CPUモード強制（Linux/macOS）  
  ```  

---

### 🌟 応用例  
```python  
# Python連携サンプル  
from ollama import Client  
client = Client()  
response = client.generate(model='deepseek-r1:32b', prompt='AIの未来について')  
print(response['text'])  
```  

---
【Revit】Revitのダウンロード方法 (Autodeskのアカウントを持っている状態から)

# 概要
AutodeskのWebサイトからRevitをダウンロードする方法をまとめました。
簡単な手順ですが、数年に一度ダウンロードする際に自分がよく忘れるので備忘録として記載しました。
※恐らく記載した手順以外にも方法はあるかと思います。

:::note
- Autodeskのアカウントを持っており、Revitをインストールできる条件であることが前提です。
- 2025年2月時点の内容です。
:::

# 手順
1. [こちら](https://www.autodesk.com/jp)からAutodeskのWebサイトを開く
1. 右上の「サインイン」からサインインする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/f7d7c03b-86d9-1d32-be8d-be68d21191a3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/5be27635-fb74-ab7d-178a-8baf9f2ea2de.png)<br><br>
1. 「製品」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/de0b9398-9786-2539-eecb-8ca4704c2958.png)<br><br>
1. ソフトウェアのダウンロードを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/bf4acbb4-82f4-181f-a6f4-3864b67562a1.png)<br><br>
1. 左部の「製品とサービス」から「すべての製品とサービス」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/3e9919e8-18e1-ad7c-1a66-087d96c812ad.png)<br><br>
1. 一覧からRevitを探す。(ここからダウンロード可能)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/ff4ce677-ff30-53ef-5101-4dc0e5c0233d.png)

:::note
西暦が記載されているプルダウンを押下すると、インストールするRevitのバージョンが選択できます。
現座は2022まででしたので、2021以前はダウンロードできなくなっているのかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/158679d0-cbbd-eebc-baf9-d4dd840bbc51.png)
:::

# 終わりに
過去のRevitバージョンは数年経つとすぐにダウンロードできない (サポート切れ？) の状態になっていたので、[こちら](https://qiita.com/MetroOsamu/items/4c8ac37dc3e65b150a8b)でまとめたようにアドイン開発中にRevitのバージョンをアップする機会は意外とありそうかと思われました。
GPTBotの暴走でサイト停止…サイト運営者は要注意！

個人開発で「[転職DB](https://www.jobchangedb.com/)」というサイトを運営しているのですが、
ある日突然サイトが落ちて、焦って調べたらGPTBotの大量アクセスが原因でした。

「GPTBotって、OpenAIのクローラー？」
そう思いつつログを見てみると、
DDosさながらの連続アクセスでMicroCMSのHobbyプランのデータ容量上限（20GB）に達し、APIが停止されてしまった感じです。

（実際のユーザーより先にBotに来られても困る…）

# 何が起こったのか
### 容量が一瞬で20GBに
以下の画像が、停止したときのMicroCMS管理画面（容量のグラフ）です。
容量の推移が異常に跳ね上がっていて、ほぼ瞬間的に20GBを超えました。

![スクリーンショット 2025-01-31 23.44.50のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/4627faa0-872d-3bab-5453-505ab52af3d7.png)

### GPTBotのアクセスログ
さらにサーバーのログを見ると、
存在しないページにも連続リクエストが飛んできていて、
とにかく挙動が謎すぎる状態に。

![スクリーンショット 2025-02-01 0.08.09のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/3119c5e7-940a-bd15-36d0-51bfc397b01b.png)
![スクリーンショット 2025-01-31 23.45.39のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/de30ae24-2ff4-d2ab-1fbf-ab1f5b0e13fa.png)


普通のクローラーは、
- robots.txtを一応見てくれる
- サイトマップを辿る
など一定のルールでアクセスしてくるものですが、
GPTBotは（現時点では）まるでDDosのようにやってくる印象でした。

# 対策：robots.txtでブロック
当面、最も手っ取り早い方法は**robots.txt**でブロックすることです。
以下を追加するだけで、少なくとも「ブロックしますよ」と明示できるのでおすすめです。

```robots.txt
User-agent: GPTBot
Disallow: /*
```
MicroCMSのHobbyプランのように転送量に上限がある場合は特に要注意です。

# 宣伝: 転職DB
[転職DB](https://www.jobchangedb.com/)は個人ブログやnote、Wantedlyなどに散在する転職体験談を要約・検索して閲覧できるプラットフォームです。

![スクリーンショット 2025-01-30 22.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/b78ea3fa-8572-c1ca-f8a5-08d84a19bf8c.png)

企業ごとの退職者、転職者の評価や転職理由などキャリアを考える上で参考になる情報が集まっています。
興味のある方は、ぜひサイトを検索してみてください。
![スクリーンショット 2025-01-29 23.11.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/9613cfc6-5499-3e3b-68fe-c0e7a8cb11e9.png)

[転職DB](https://www.jobchangedb.com/)


# まとめ
1. GPTBotが大量アクセス → MicroCMSの転送量20GB超え → API停止
2. 存在しないページへのリクエストも多く、挙動が謎
3. robots.txtでブロックするのが一番手っ取り早い対策

個人開発に限らず、小規模のサイトでも似たようなことが起きる可能性は十分あると思います。
「突然サイトが落ちて原因がわからない」という方は、
ぜひ一度GPTBotのアクセスを疑ってみてください。

# 筆者のX
筆者は主にWeb開発・個人サービス運営系の話題をつぶやいています。
よろしければフォローよろしくお願いします！
[bani24884](https://x.com/bani24884)
[GAS] input要素のvalue属性に複数の値を設定する

## やりたいこと
GASで作成したHTMLにチェックボックスをチェックしたらスプレッドシート上の関連する複数の値を関数に渡したいが、input要素のvalue属性には、複数の値は設定できない＞＜

## 解決方法
複数の値をカンマ(,)区切りなどで単体の値として読み込み、
取り出すときにカンマ(,)区切りで取り出す

## コード
~~~Javascript
    const itemHoge = item['アイテム１'];
    const itemFuga = item['アイテム２'];
    const itemPiyo = item['アイテム３'];
    <input type="checkbox" value="${itemHoge},${itemFuga},${itemPiyo}" onchange="inputChange(this.value)">;

function inputChange(value){
    result = value.split(",");
    console.log("itemHoge = result[0]");
    console.log("itemFuga = result[1]");
    console.log("itemPiyo = result[2]");
}
~~~
📚 LeetCode - 26. Remove Duplicates from Sorted Array ソート済み配列の重複を削除する方法

# 📌 問題の概要
整数の配列 `nums` が **昇順（小さい順）にソート** されています。  
この配列から **重複を削除** し、各要素が **一度だけ登場するように** 変更してください。

# ✅ 条件
- 配列を「その場で」（**in-place**）変更すること。
- **元の並び順を維持** すること。
- **ユニークな要素の数 `k` を返す** こと。
- `k` 以降の配列の要素は何が入っていてもOK！

# 🌟 例
### 🎯 **例1**
**入力:**  
```plaintext
nums = [1,1,2]
```
**出力:**  
```plaintext
2, nums = [1,2,_]
```
**説明:**  
- `1` が2回あるので1つ削除。
- `nums = [1, 2, _]` となり、`k = 2` を返す。

### 🎯 **例2**
**入力:**  
```plaintext
nums = [0,0,1,1,1,2,2,3,3,4]
```
**出力:**  
```plaintext
5, nums = [0,1,2,3,4,_,_,_,_,_]
```
**説明:**  
- `0, 1, 2, 3, 4` の **ユニークな要素を前に詰める**。
- `k = 5` を返す。

## 🛠 解き方（Two Indexes Approach）
### 🤔 **考え方**
1. **配列はソート済み！** ➝ つまり、重複する要素は **連続して並ぶ**。
2. **2つのインデックスを使う**：
   - `insertIndex` 👉 **書き込む場所**
   - `i` 👉 **現在の位置（読み取り用）**
3. **`i` が進みながら、前の値と違う要素があれば `insertIndex` に格納**！

# 🔥 アルゴリズム（流れ）
1. `insertIndex = 1`（書き込む位置）を設定。
2. `i = 1` からスタートしてループ。
3. `nums[i] != nums[i-1]` なら、`nums[insertIndex] = nums[i]` とする。
4. `insertIndex` を1つ進める。
5. 最後に `insertIndex` を返す（ユニークな要素の数）。

# 💻 コード（Python）
```python
from typing import List

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        size = len(nums)
        insertIndex = 1  # 先頭は常にユニーク

        for i in range(1, size):  # 1からスタート
            if nums[i - 1] != nums[i]:  # 直前の値と異なる場合
                nums[insertIndex] = nums[i]  # 重複しない要素を前に詰める
                insertIndex += 1  # 書き込み位置を1つ進める

        return insertIndex  # k（ユニークな要素の個数）を返す
```

# 🔄 **処理の流れ**
### **🌟 例**
#### `nums = [0,0,1,1,1,2,2,3,3,4]`
| `i` | `insertIndex` | `nums` |
|----|-------------|-----------------|
| 1  | 1 | `[0,0,1,1,1,2,2,3,3,4]`  |
| 2  | 2 | `[0,1,1,1,1,2,2,3,3,4]`  |
| 5  | 3 | `[0,1,2,1,1,2,2,3,3,4]`  |
| 7  | 4 | `[0,1,2,3,1,2,2,3,3,4]`  |
| 9  | 5 | `[0,1,2,3,4,2,2,3,3,4]`  |

最後に `k = 5` を返す！ 🎉

## 📈 時間・空間計算量
- **時間計算量:** `O(n)`（ループ1回）
- **空間計算量:** `O(1)`（追加の配列を使わない）


## 🎯 まとめ
✅ **2つのポインタ（insertIndex, i）を使う**  
✅ **ソート済みであることを利用し、前の値と比較**  
✅ **追加の配列を使わずに `O(n)` の時間で処理！**  

これで `nums` の重複を削除できる！🚀🔥
# 🚨 UiPath Cloudで発生した障害（2025年1月31日）【復旧済み】

## 📝 概要  
2025年1月31日、UiPathのクラウド環境において **Orchestrator Cloud（cloud.uipath.com）への接続遅延** が発生（高レイテンシー）し、一部のユーザーが影響を受けました。本記事では、障害の概要、影響範囲、復旧状況、今後の対策についてまとめます。

---

## 🛠 **障害の概要**
- **発生日時**：2025年1月31日 05:12 UTC（日本時間 14:12）
- **復旧完了**：2025年1月31日 05:52 UTC（日本時間 14:52）
- **影響地域**：
  - **インド（India）、シンガポール（Singapore）、日本（Japan）**
- **影響範囲**：
  - **Orchestrator Cloud**（cloud.uipath.com）へのアクセスが遅延
  - **Studio、Assistant、Robotのクラウド連携機能が影響を受ける**
  - **ジョブ実行、ログ取得、パブリッシュ処理の遅延**
  - **APIリクエストのレスポンスが不安定になる**

---

## 🔍 **障害の詳細**
### **「断続的な高レイテンシー」とは？**
今回の障害では、**クラウドサービスへのリクエスト処理が通常よりも遅くなったり、一時的に接続が途切れたりする現象(高レイテンシー)** が発生しました。

影響を受けたユーザーでは以下のような問題が発生していた可能性があります：
- **Orchestratorへのログインに時間がかかる、または接続できない**
- **ジョブの実行開始が遅れる、またはタイムアウトする**
- **ログの取得やパブリッシュの処理が異常に遅くなる**
- **APIを利用した連携機能が一部失敗する**

---

## ✅ **対応と復旧状況**
| **時刻（UTC）** | **対応状況** |
|----------------|------------|
| 05:12 | **障害を検知**、影響範囲を調査開始 |
| 05:44 | **問題の原因を特定し、修正作業を開始** |
| 05:52 | **シンガポール、日本は完全復旧**、インド地域の復旧作業継続 |
| 06:30 | **すべての地域でサービスが完全復旧** |

![20250131.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654526/674f04f0-95fb-9996-1055-44b328024a81.png)

現在、**すべての地域で正常稼働が確認されています**。

---

## 💡 **今後の対策と開発者へのアドバイス**
**クラウド依存のシステム開発では、突発的な障害に備えた運用設計が重要です。**  
特にRPA開発では、以下のような対応を検討することで、障害発生時の影響を最小限に抑えることができます。

### ✅ **開発者向けの対策ポイント**
1. **Orchestrator Cloudのステータスを定期的に確認**  
   → UiPathの公式ステータスページ（[status.uipath.com](https://status.uipath.com/)）で、障害情報を随時チェック

2. **ジョブ実行スケジュールに余裕を持たせる**  
   → クラウドサービスの一時的な遅延を考慮し、**処理のリトライ設定や待機時間を適切に調整**

3. **クラウド環境とオンプレミス環境を使い分ける**  
   → 重要なプロセスは、**ローカル実行のバックアップフロー** を用意することで、クラウド依存を減らす

4. **APIリクエストのタイムアウト処理を適切に設定**  
   → レスポンス遅延に備え、**APIリクエストのタイムアウト値を適切に設定**

5. **障害時の影響を最小限にする通知フローを確立**  
   → 影響を受けるチームがすぐに対応できるよう、**社内で障害発生時の通知ルールを明確にする**

---

## 📢 **コメント募集中！**
- 今回の障害で影響を受けましたか？  
- Orchestrator Cloudへの依存についてどう思いますか？  
- **障害対策として有効な方法** について意見を共有したい方は、ぜひコメントでお知らせください！📢✨

---

## 🔗 **関連情報**
- [UiPath公式ステータスページ](https://status.uipath.com/)  
- [UiPathフォーラム 障害報告スレッド](https://forum.uipath.com/)  
- [UiPath Cloud Orchestratorドキュメント](https://docs.uipath.com/orchestrator)  

---

💡 **クラウドサービスを利用する開発では、障害に備えた運用設計が欠かせません。**  
今回のような影響を最小限に抑えるためにも、適切な対応策を検討しておきましょう！
JSONの型定義を宣言する（メモ）

# 定義

ないなら作る

```ts
// JSON.d.ts

export type JSON = JsonPrimitive | JsonArray | JsonObject;

export type JsonObject = {
  [key: string]: JSON;
};

export type JsonArray = JsonPrimitive[] | JsonObject[] | JsonArray[];

export type JsonPrimitive = string | number | boolean | null;
```

# Usage

```ts
import type { JSON } from "./JSON.d"

const json: JSON = {
    "文字": "abc",
    
    "数値": 123,
    
    "真偽": false,

    "NULL": null,

    "配列": [
        "a", "b", "c",
        
        1, 2, 3,
        
        true, false,
        
        ["a", "b", "c"],
        
        [1, 2, 3],
        
        [true, false],
        
        [null],

        {
            "プロパティ": "値",
            
            "配列": [
                // ... (略) ...
            ]
        }
        // ... (略) ...
    ],
    
    "物体": {
        "プロパティ": "値",
        
        "配列": [
            // ... (略) ...
        ]
        
        "プロパティ": {
            // ... (略) ...
        }
    }
}

```

了
[GAS] YouTubeのサムネイル画像をWordPressのサムネ画像にする方法

## きっかけ
私は、好きなYouTube動画を自分用でまとめてるWordpressブログを持ってます。
あの日見た動画をもう一度見たいって思っても、探し出せないことがあるんですよね！
履歴辿ったり、再生リストに入れたりしても、もしその動画が消えていたりしたら分かる術があまりないので、Wordpressブログにまとめてます。
WordPressでまとめれば好きなカテゴリやタグも自由に設定できるし、自分が見た日付も記録されるので便利です。

## どうやるか？
YouTubeから直接Wordpressに画像をアップロードすることはできなさそうなので、一度GoogleDriveに保存して、それをWordpressにアップロードします。

YouTube → GoogleDrive → WordPress

GoogleDriveに画像がどんどん残りますが、残したくなければWordPressにアップロードしたら削除するようにすればＯＫ

## サンプルコード
### 前提条件
- YouTubeのサムネイル画像はサイズによって複数あるのですが最大サイズ（maxresdefault.jpg）が存在している前提です。
参考：YoutubeサムネイルURL取得
- なぜかYoutubeのサムネによってはGoogleDriveからWordpressへのアップロードに失敗する。ですが、ローカルに落としてペイントで編集したものをGoogleDriveにアップロードして↓のコードで実行すると成功する・・・謎。
- レンタルサーバー側のWAFを無効化する必要がある。

### コード
~~~ Javascript
function getMediaID(youtubeId) {  
  // 保存場所、ファイル名、対象画像URL
  const folderId = 'GoogleDriveのフォルダID'; // ./Media
  const fileName = `GoogleDrive保存時のファイル名`;
  const imageUrl = `https://img.youtube.com/vi/${data['youtubeId']}/maxresdefault.jpg`;

  // ====== Google Drive に保存 ==============
  // 画像をダウンロード
  let responseImg = UrlFetchApp.fetch(imageUrl);
  let imageBlob = responseImg.getBlob().setName(fileName);

  // Googleドライブに保存
  let folder = DriveApp.getFolderById(folderId); // 保存先フォルダを指定
  let file = folder.createFile(imageBlob); // 保存したファイルを取得
  let fileId = file.getId();

  // ====== Google Drive から WordPress ==============
  // 一度変換と再変換を噛ます（なぜかそのままはWPへUPできない＞＜）
  const targetFile = DriveApp.getFileById(fileId);
  const targetFile_PNG = targetFile.getAs(MimeType.PNG);   // png→jpeg　に変換
  const converedFile = targetFile_PNG.getAs(MimeType.JPEG); // jpeg→png　に再変換
  targetFile.setTrashed(true);

  let newFile = DriveApp.getFolderById(folderId).createFile(converedFile); 
  newFileId = newFile.getId();
  let newFileName = newFile.getName();

  // WordPressにUPするために変換後のファイル(newFile）だけ共有設定を行う
  // リンクを知っている全員が閲覧可
  newFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  // Googleドライブ上で共有設定した時の画像ファイルのURL
  let newFileUrl = 'https://drive.google.com/uc?export=view&id=' + newFileId;


	let headers = {
		// 'Content-Type': 'image/png',
		'Content-Disposition': 'attachment;filename='+newFileName+'.jpg',
		'accept': 'application/json',
		'Authorization': 'Basic ' + Utilities.base64Encode(BLOG_USER + ":" + BLOG_API_PASSWORD)
	};

	let options = {
		'method': 'POST',
		'muteHttpExceptions': true,
		'headers': headers,
		'payload': UrlFetchApp.fetch(newFileUrl)
	};


  let response = UrlFetchApp.fetch(BLOG_URL + '/wp-json/wp/v2/media', options);
  let responseJson = JSON.parse(response.getContentText());

  // ====== UpしたメディアIDを返す ==============
  return responseJson.id
}
~~~
### 概説
getMediaID関数は、youtubeId（Youtubeの動画ID）を引数として受け取り、WordPressのメディアIDを返します。
途中、GoogleDriveにUPしたり変換したりしてます。

## 所感
WAFを無効化するのはちょっと怖い・・・。
YouTubeのサムネ画像によって挙動が変わって四苦八苦した。
最大サイズがない場合の処理は追加で実装する必要あり！
文章の質を安定させよう

# この記事の目的
文章の質を安定させる修正方法を理解する

# 目次
▼[推敲、校正](#推敲校正)
▼[更新を伴う修正](#更新を伴う修正)

# ▼推敲、校正
一般的に、人は書く力より読解力のほうが優れていると言われている。また、文章作成後すぐに読み返すより、少し時間を置いたほうが、客観的にいろんな点に気づく。
## 注意すべき視点
- 意図した内容が表現できているか
- 簡単に読め誤解されないか
- 漏れはないか
## 考え方
- 矛盾がないかを確認
たとえば、システムの設計書を書き始めた当初は、理解が浅い状況であったが、書いているうちに理解が深くなっていくことがある。その場合は、書き始め部分の情報に、矛盾がないか確認することが重要である。
- 途中の修正を即時に反映させる
文章を書いている途中で、仕様の追加や変更した場合は、全体への反映を後回しにしない。早いうちに、全体の確認と反映を行うことで、大きな戻りやミスが起きなくなる。

# ▼更新を伴う修正
新規商品などの説明より、既存商品などの更新情報を説明することが多い。その場合、関連情報も修正する必要が発生する。

## 修正順序
### 作業内容を確認する
文面に間違いがないか確認する
### 作業範囲を洗い出す
校正支援ツールなどを活用する
### 作業を計画する
誤字の修正だけなのか、文章の構造も修正するのかなど、広い視点で計画を立てる
### 作業を実行する
実行した後は、かならず読み返す

# 参考文献
[日本語スタイルガイド（第3版）](https://jtca.org/learn-tc/publication/guide_jsg/)
[GAS] 複数のシートを読み込む方法

## やりたいこと
複数のシートがあるスプレッドシートのシート名を順に読み込む

## コード
~~~javascript
function getSheetName() {
  let activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  let sheetLength = activeSheet.length;
  let sheetLists = [];

  for(var i=0; i < sheetLength; i++){
    sheetLists.push(activeSheet[i].getSheetName());
  }
  console.log(sheetLists);
}
~~~
【社会勉強】バックオフィス World 2025 に行ってみました

### バックオフィス World 2025
https://www.bizcrew.jp/expo/back-office-tokyo
> 人事・経理・総務・法務向けのサービス・ソリューションが一堂に集うバックオフィス向けの総合展です

上記のような社内業務に携わる担当者とサービス出展企業のマッチングを目的とした展示会です。想定される来場者ではありませんでしたが、上長のすすめもあり、自分が知らない製品の勉強のため参加してみました。
振り返りをかねて、お邪魔した出展企業様のなかから気になったサービス・製品についてまとめます。

### Helpfeel　生成AIを活用したFAQシステム
https://www.helpfeel.com/

実際に検索するところの画面を見せていただいて、一文字打つたびの予測回答の検索スピードと、曖昧な言葉でも適切な回答を導く精度に驚きました。例えば「つながらない」「LAN」「回線」「ワイワイ」のようなワードでも「社内Wi-Fiに接続する方法」というよくあるお問い合わせにたどり着けてしまいます。

### Attuned　AI×心理学のHRツール
https://www.attuned.ai/jp/

従業員が重視する仕事に関する価値観を11のモチベーターによって可視化、従業員に適した環境づくりや従業員の早期離職防止をサポートします。ツールを利用して、内定者が社員のモチベーターの傾向にどれくらい近いか確認する企業もあるようです。
社員が相互に自己開示することが前提のツールで、コンセプトとしては「本音」「真の声」という言葉がキーワードになっているように感じました。例えば上司と部下のモチベーターを比較することで仕事に対する価値観の違いを可視化し、より最適な1 on 1を実現します。上司から部下への声かけをコミュニケーションAIが検討し、部下の価値観に合った伝え方をアドバイスしてくれます。

### X-point Cloud　まるで紙のような使い心地
https://www.atled.jp/xpoint_cloud/?utm_source=google&utm_medium=cpc&utm_campaign=XP&gad_source=1&gclid=CjwKCAiAzPy8BhBoEiwAbnM9O7RwZEtK1wfoAtusWcB3AerLJHD-WL4h9HmfulzLPJoiKfA409yhnhoC8BUQAvD_BwE

社内で使用している稟議書のフォーマットをそのまま再現、ユーザーが直感的に操作しやすいUIを提供します。承認印まで再現されたインパクトの強い画面に吸い寄せられて、ブースにお邪魔しました。ServiceNow導入案件で、ServiceNowに移行してもハンコでの承認をしたいというお客様が過去にいらしたため、需要については想像に易いです。
これまでの紙の稟議書と同じように使いたいというユーザーの要望に応えたサービスですが、一方で業務フローの改善提案などは難しそうだと感じました。既存のフローを正として開発を進めることになるため、例えばitil準拠のフローへの改善などは提案しづらいかもしれません。
担当者様によると、病院や学校ではとくに根強い需要があるそうです。

### 楽々清算
https://www.rakurakuseisan.jp/lp/name/index.php?utm_source=google&utm_medium=cpc&utm_campaign=00_name&utm_content=rakurakuseisan&utm_term=%E6%A5%BD%E3%80%85%20%E7%B5%8C%E8%B2%BB&saf_src=google_g&saf_pt=&saf_kw=%E6%A5%BD%E3%80%85%20%E7%B5%8C%E8%B2%BB&saf_dv=&saf_cam=104495525&saf_grp=5067488765&saf_ad=681106751979&account_id=7494984024&saf_acc=7494984024&gad_source=1&gclid=CjwKCAiAzPy8BhBoEiwAbnM9O1JALG-Pw-h7b54KGIE5gfccYIbZad2ufHxrIYiFJdx4ft9CKbikbxoCQrUQAvD_BwE

領収書読み取り機能や交通系ICカード取込機能などで手入力によるミスを防止します。システム内で乗換案内を確認できるのは便利だと思いました。自社で利用している勤怠管理ツールでは勤務時間と交通費は手入力なので、入力するのもチェックするのも大変です。導入してほしい。

### Mental Battery　従業員のメンタル状況を可視化
https://www.mentagraph.com/products-mentoring

指輪型のデバイスを勤務中に装着することで、従業員のメンタル状況を可視化します。従業員には自分のメンタル状況を自覚し罪悪感なく気兼ねなく休憩できるように、管理者には従業員のストレスを把し休職や離職リスクを未然に防ぐことをサポートします。
実際に装着させていただいたところ大きさが少し気になりました。軽量化に向け今後も改良を続けるとのことです。

### さいごに
こういった展示会には参加したことがなかったため、とても勉強になりました。
AIを活用した技術や導入スピードが売りのノーコードツールの展示が多く、トレンドを肌で感じることができました。システムに任せられることの比率がますます増えていき、人が本当にやるべきことに集中できる仕事環境が実現しつつあると思います。
人がするべき仕事が限定されていくのはSEも同じ、今後も様々な技術が登場するなかで、人間だからこそできる仕事とそれに必要なスキルを見極めていく必要があると、身が引き締まる思いです。

### 余談
会場に入った瞬間左右から手が伸びてきて、各社のパンフレットが、ノベルティのバッグが、キットカットが渡されてびっくりしました。大学のサークルの新歓を思い出しました。