OmniAICreator/Qiita-1.07M huggingface dataset:
初めてWindowsServerを構築した時の考察

# 背景
先日vSphere環境のwindowsサーバの構築を初めて行いました。

自分で手順を作成し、自分で作業をしましたが、想定した通りにいかないことが多く、その場で臨機応変に対応しました。
その際に再鑑者にもご迷惑を掛けてしまいました。
手順は誰が実施しても同じ結果にならないといけないと思っているので、手順としてはダメだと思います。

上記を踏まえて備忘録と今後について書きました。
経験浅めの低レベルが書いた記事です。
陥った点とか共感していただけるかもしれませんし、そんなことねーよと思う人の方が多いかもしれません。

# 作業で実現したいこと
◆vSphere環境のwindowsサーバのOS更改
◆用意されたパラメータシート（CPU、メモリ、ディスク、IPアドレス、etc)にそって構築する。パラメータシートの範囲外は現行環境を確認して、それを踏襲する。
vSphereで下記を行う
①仮想マシン作成
②OS設定（ホスト名、IPアドレス、ドメイン参加、サービスの設定など）
③セキュリティソフト、バックアップソフトのインストール

# 起きたこと
#### 1.パラメータシートの範囲外の設定がわからない
仮想マシンのHW設定で指定がない部分（ネットワークアダプタ、ディスクのプロビジョニング、既存のOUへの配置など）の現行の設定を確認しておらず、戻りの作業が発生。
#### 2.コンソール画面での作業が長い
RDPログインを序盤で設定する手順にしていないので、PowerShellで確認した結果をローカルに持ち込めないし（テキストに書いておいて、のちにRDPで持ってきた）、あとなにかと作業がしずらい。
#### 3.再起動作業が多い
OS設定の中で再起動が発生する変更作業（ホスト名の変更、WindowsUpdate,VMwareToolsの導入）のタイミングを考えておらず、再起動した回数が多くなった。
#### 4.サーバ用の更新プログラムをインストールできない
ドメインに参加後にWindowsUpdateを実施したら、更新プログラムをダウンロードできない事象が起きました。（WSUSの設定でクライアント端末用の更新プログラムしか持ってこないことがわかった）
#### 5.不要な待ち時間の発生
WindowsUpdateをOS設定の終盤に行うことにしていたのでWindowsUpdateをMicrosoftから持ってくる待ち時間が発生

# 原因
<font color="Red">**確認不足、調査不足!**</font>

# 今後の対策
#### 1.しっかりと検証せよ
お客様と同じ環境を作って検証しましょう。頭の中で行うことと実際に試して確認することの大きな違いを実感しました。

#### 2.何をどのように設定するのかしっかりと洗い出すこと
上記と被りますが、検証を行う中で指定された範囲外も設定しないといけない場面が出てくるかもしません。どのように設定するか事前に取り決めが必要です。
要は**しっかりと検証しろ**ということです。

#### 3.甘えがあった
これが本当の**根本的な原因**かも
今回は内部レビューでOKをもらえました。自分の気持ちとしては”現場猫”そのものであって、手順書できた！軽く自分で確認したしヨシ！みたいな甘い考えでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209826/328014dc-39c0-1e80-a392-dc115e845396.png)
from [からあげのるつぼ@karaage_rutsubo](https://twitter.com/karaage_rutsubo/status/1601724146681249792)

# 手順書について

#### パラメータを参照して、手順に組み込むようにしよう
手順書内の「ここで192.168.100.100を入力」などの文章は数値をそのまま入力していたので下記のようにExcelに入れておいたら、別のサーバでも使いやすいと思いました。
```
="ここで"&TEXT(B15)&"を入力"
```
#### 画像をもっと盛り込む
今回は自分で手順書を作成し、実行するので頭の中で何をするかを理解していました。
他の人が作業する場合だと困惑す場面が多いかもと思いました。あと、バージョンの齟齬があるとGUIとかも変わったりするのでそれも注意したいです。

:::note
オペレータ時代に運用SEが作った手順が想定どおりではない時に結構電話などで確認していたので、自分のためにも分かりやすい手順が必要だと思います。
:::

# 最後に
初めて手順作成、内部レビュー、お客様にて手順確認、作業実施といった流れを踏んでサーバを構築しました。
自分で検証して確認することの重要性を改めて感じた次第です。
ここまでお読みいただきありがとうございました。
電動航空機産業の概観 - 市場編


# はじめに

時間軸で考えたものは以下の記事で紹介している。

https://qiita.com/is_it_stable/items/fed61673783185908aee

# 電動航空機-産業分析
* 市場力学
    * 促進要因
    * 抑制要因
    * 機会
    * 課題
* 不況の影響分析
* ポーターのファイブフォース分析
* 業界動向
    * (後述)
* 市場魅力度分析

:::note
# バリューチェーン分析
:::

## バリューチェーン分析
以下の記事を参考にしてください。

https://www.meti.go.jp/meti_lib/report/2022FY/000143.pdf

![Screen Shot 2023-10-29 at 9.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555842/6df49d09-3a5c-d8d0-e4fb-236afff4c49a.png)



* 原材料分析
    * 原材料リスト
    * 原材料メーカーリスト
    * 主要原材料の価格動向
* 潜在的バイヤーのリスト
* マーケティングチャネル
    * ダイレクトマーケティング
    * インダイレクトマーケティング
    * マーケティングチャネル発展動向
* 市場エコシステムマップ
* 顧客ビジネスに影響を与える動向と混乱
* 貿易データ分析
* 技術分析
* 航空宇宙産業の関税・規制状況
* 平均販売価格分析
* 市場規模データ (数量ベース)
* 主な利害関係者と購入基準
* 主な会議とイベント (2022年～2023年)
# 業界動向
* イントロダクション
* 電動航空機市場における技術進歩
    * アーバンエアモビリティ (UAM)
    * エネルギーハーベスティング (環境発電)
    * 高出力バッテリー・モーター
* サプライチェーン分析
* ユースケース

# 電動航空機企業の競合情勢
* 電動航空機市場の競合
* 提携・協力・合意
* 合併・買収
* 新製品発表
* その他の開発
* 市場シェア分析 (2021年)
* 収益分析
* 企業評価クアドラント
* スタートアップ/中小企業の評価クアドラント
* 競合シナリオ
    * 資本取引

# 電動航空機の世界市場分析：タイプ別
* タイプ別概要
* 実績データと予測データ
* タイプ別分析
* 固定翼
* 回転翼
* ハイブリッド翼
# 電動航空機の世界市場分析：システム別
* システム別概要
* 実績データと予測データ
* システム別分析
* バッテリー
* 電気モーター
* 航空構造
* アビオニクス
* ソフトウェア
* その他
# 電動航空機の世界市場分析：技術別
* 技術別概要
* 実績データと予測データ
* 技術別分析
* CTOL (従来型離着陸)
* STOL (短距離離着陸)
* VTOL (垂直離着陸)
# 電動航空機の世界市場分析：プラットフォーム別
* プラットフォーム別概要
* 実績データと予測データ
* プラットフォーム別分析
* 地域輸送機
* ビジネスジェット機
* 軽飛行機・超軽量機
    * 一般機(ジェネラルアビエーション機)
    * 練習機
    * UAVS(無人偵察機)
    * AAM (高度エアモビリティ)
# 電動航空機の世界市場分析：用途別
* 概要：用途別
* 実績データと予測データ
* 分析：用途別
* 民間/商業
* 軍事
# 電動航空機の世界市場分析：地域別
* 地域別展望
* イントロダクション
* 地域別
    * 米国
    * 欧州
    * 中国
# 電動航空機企業の競合情勢
* 電動航空機市場の競合
* 提携・協力・合意
* 合併・買収
* 新製品発表
* その他の開発
* 市場シェア分析 (2021年)
* 収益分析
* 企業評価クアドラント
* スタートアップ/中小企業の評価クアドラント
* 競合シナリオ
    * 資本取引
# 企業プロファイル
* 企業シェア分析
* 市場集中度
* Airbus SE（France）
* Eve Air Mobility（Brazil）
* Joby Aviation（US）
* Vertical Aerospace（UK）
* Lilium N.V.（Germany）
samba でパーミッションエラー

Ubuntu の ファイルマネージャ Nautilus で、ネットワーク上のファイルを閲覧するのに smb 共有を使っている。

Nautilus では以下のようにして共有ができていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9eeb436f-a662-d8a6-faaa-3e786730a097.png)

共有ポイントの設定を変更したら以下のエラーが出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ec06994e-41c3-2b38-2bf6-a5f4ec07834a.png)





# 環境
- samba サーバ 側
  -  Ubuntu 22.04 LTS
  -  samba Version 4.15.13-Ubuntu

- ゲスト側
  -  Ubuntu 22.04 LTS
  -  Nautilus 42.6

# smb.conf

```
[global]
   workgroup = WORKGROUP
   server string = %h server (Samba, Ubuntu)
   log file = /var/log/samba/log.%m
   max log size = 1000
   logging = file
   panic action = /usr/share/samba/panic-action %d
   server role = standalone server
   obey pam restrictions = yes
   unix password sync = yes
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
   pam password change = yes
   map to guest = bad user
   usershare allow guests = yes

[MainImage]
path=/samba/MainImage
writable = yes
guest ok = yes
guest only = yes
force create mode = 777
force directory mode = 777
```

# 症状
 とすると、 /samba/MainImage はゲストで共有できるのだが、
以下のようにリンクすると共有できない。


```
lrwxrwxrwx  1 nanbuwks nanbuwks   69 10月 12 21:23 MainImage -> /home/nanbuwks/Downloads/docker-mirakurun-epgstation/media/tv_current
```


# 解決

以下はパーミッションが 775 や 755 。

- /home/nanbuwks/Downloads/docker-mirakurun-epgstation/media/tv_current
- /home/nanbuwks/Downloads/docker-mirakurun-epgstation/media/
- /home/nanbuwks/Downloads/docker-mirakurun-epgstation/
- /home/nanbuwks/Downloads/
- /home/nanbuwks

これらを全て 777 にすると解決。うーむ。
ABC326回答メモ

# 0.はじめに
　最近は、デイリートレーニングにも手を出してますが
  それほどレベルアップした感はありません・・・。
　Aから躓きつつ、なんとかCまではいけましたが
　Dはワンチャンイテレータごり押しで行けるかと思いましたが
  そんなことは無くTLEに阻まれ、その後解説読んでも今一でした。
  Aでの失敗もひびき、レートは-2となりました。


# 1.A - 2UP3DOWN
　問題名で気づくべきでしたが、上下移動共に3段までと
　誤認して回答してしまいWAを出してしまいました・・・。 
　閾値テストとかするべきですね・・・。

　https://atcoder.jp/contests/abc326/submissions/47003579

# 2.B - 326-like Numbers
　Nを数値でインプットしてfor文の起点にしつつ
  文字に変換して１・２・３桁目を取り出し
  また数値に戻して計算するという
  忙しい感じで実装してACでした。

　https://atcoder.jp/contests/abc326/submissions/47000301


# 3.C - Peak
　いもす法で行けるかなと試してみましたが、10**9の
　リストがメモリオーバーで作れず 断念。
  リストを頭から読んでいくオーソドックス(?)な方法でチェレンジ。

  【実装】
  　1.N・Mを読み込む
    2.Mを-0.5する(以下の実装だと、こうしないとずれる)
    3.リストAを読み込み昇順でソート
  　4.以下定義
   　-p(リストを移動した時点でのプレゼント数)を0に
   　-pre(リストの前の数字の時にプレゼントゲット範囲だったアドレス)を-1に
     -now(現在の位置)を0に
   　-ans(pの最大値)を0に
    5.リストAを先頭から見ていく(インデックスi)。
    　5-1.nowをA[i]の値に
      5-2.pに1加算
      5-3.preがー1の時(最初の数字の時)
      　5-3-1.preにiをセット
      5-4.preがー1ではない時
      　5-4-1.A[pre]+Mがnow以上になるまで以下繰り返し
       　　　　(nowの位置からプレゼント範囲ではない間)
           5-4-1-1.pから1減算
           5-4-1-2.preに1加算
      5-5.ansにansとp大きい方をセット
    6.ansを出力
 

　https://atcoder.jp/contests/abc326/submissions/47021139

# 4.D - ABC Puzzle
　イテレータを使って、N*Nの組み合わせを全種類作るようにしたところ
 　N=4までは何とかなりそうでしたが、N=5は無理でした。
   1つずつ条件を設定していく方法では、N=3までで飽きてしまいました。
   解説を理解して実装できるようにしないといけなそうです。
   折を見てリベンジ予定


以上
バスパワーUSBハブとオーディオアンプの相性が良くなかったか

# はじめに
以前から、動画の音声出力にCDコンポのスピーカを使用してきました。その時に使用していたオーディオアンプがNobsoundです。これは、小型でもかなりハイパワーです。50Wx2の出力です。
パソコンのUSB端子にバスパワーUSBハブを接続して、NobsoundとBlueTooth接続、USBケーブル接続、auxケーブル接続ができます。
これらの接続でyoutube動画を再生しているとグルグルが出て再生がストップしてしまいます。CDコンポのスピーカー(15Wx2)でなく、ヘッドフォンまたはイヤフォンで接続したときは問題なく再生しています。原因は何だろうかと長らく不思議でした。それまで、あまり深く考えてはいませんでした。USBハブを外して、長いUSBケーブルで接続して再生していました。原因がまさかバスパワーUSBハブとは気が付きませんでした。以降で、その解決に至った経緯について記述したいと思います。
# 解決に至った経緯
#### (1) 機器構成
今回の機器構成は、以下の通りです。
・パソコン(Dell Inspiron620S)
・バスパワーUSBハブ(4口) SANWA USB-HUB253BK
・Nobsoundオーディオアンプ　AC-DCコンバーター(出力 DC 9V～24V)
・CDコンポのスピーカー(左右) Panasonic SB-PM510 SPEAKER SYSTEM 15W 6Ω　x 2

#### (2) あるときからyoutube再生でグルグルが出るようになった
かなり前からときどき、出ていました。スピーカーを接続したり、ヘッドフォンやイヤフォンで聴いたりしていました。Nobsoundは通常ではBlueToothで接続していました。バスパワーUSBハブはつけたり、外して直結したりしていました。原因がわからないまま、接続方法をいろいろ変えながら再生していました。ネットワークもLanケーブルやら、Wi-Fiにしたみたりと試しました。メモリ不足なのかとも考えました。

#### (3) 何が問題だろうかと考えてみた
動画の再生中に出たので、ネットワークの問題かなと当初は思っていました。LANケーブルにしたり、Wi-Fiにしたりしてみましたが、結果は同じでした。メモリ不足も思いましたが、メモリは大丈夫そうです。WindowsのタスクマネジャーでCPUを大量に使用しているタスクを見つけました。Tiworker.exeというプロセスです。ネットで調べてみると、Windows Updateのモジュールのようです。これは、停止させない方がいいらしいです。ただ、よく調べてみると、停止させることもできるようです。この件は、今回のグルグルとは別問題のようなので、いったん保留にします。今回の件は、バスパワーUSBハブを使用しないと、グルグルは出ないようなので、このことに絞って調査します。
#### (4) なぜ、USBハブを外すとグルグルはでないのか
このUSBハブはバスパワーというマザーボードのバスから電源を取っています。そのため、ハブ側で電力を消費すぎると電力不足になりそうです。このタイプのUSBハブは、小電力のデバイス用とのことです。もしかしたら、Nobsoundに接続したスピーカーを駆動するため、電力をハブの限界(100mA程)を超えたのかもしれません。
#### (5) USBハブにUSBケーブル、BlueTooth audio tranmiterを接続してテスト
このいずれのケースでもグルグルは発生しました。要はバスパワーUSBハブでこのNobsound経由のスピーカーを使用すると発生します。
これらの事象から、バスパワーUSBハブとNobsound(スピーカー)の相性が悪いのではと理解しました。今回使用したバスパワーUSBハブの電力容量がNobsound(スピーカー)側の電力容量を超えてしまったということだと思います。そのため、パソコンのシステムで、USBの電力不足をキャッチしたため、接続を切断したと思います。
その後は、再接続を待っている間、グルグルを表示しているのだと理解しています。
#### (6) セルフパワーUSBハブでためしたい
次回は、電源を持っているセルフパワーUSBハブで試したいと思っています。

# あとがき
動画の再生中にグルグルが表示され、再生がストップしてしまうのは結構ストレスになります。いつか元に戻るだろうと待っていても一向にもどりません。仕方がなくUSBコネクターを抜き差ししてみます。するといったんは戻るのですが、すぐ再びグルグルが出ます。USBハブをやめてパソコンのUSBソケットから直接、ケーブル接続したり、BlueTooth接続してみます。すると再生ができます。
USBハブの問題だったとは、中々、気づきませんでした。

参考元
[やってはいけないPCの...](https://blog.goo.ne.jp/tanuki-02/e/e7148b294196de97c74bc25d87779b4e)
ターミナルを再起動したらflutterコマンドが使えなくなる問題

# 背景
flutterの環境構築が完了したあとに、ターミナルを再起動すると``flutter doctor``などのコマンドが使用できなくなりました。

#### 開発環境 
MacBook Pro CPU: intel 
macOs: Sonoma14.1
````
 $ flutter doctor
zsh: command not found: flutter
````
再起動するまえは、ちゃんとコマンドが通ってたのですが・・・

# 対策
おそらく再起動したときにflutterのPATHがリセットされてるんだと思います。
そこで、**.zshrc**ファイルに直接PATHを書き込みます。
※ flutterのPATHは人の環境次第で違うと思いますが、私の場合は
``/Users/ホームディレクトリのユーザー名/flutter/bin``ですね。

````
~ $ echo 'export PATH="/Users/ホームディレクトリのユーザー名/flutter/bin:$PATH"' >> ~/.zshrc
````
これでターミナルを再起動して、もう一度``flutter doctor``を実行すると

````
~ $ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.13.9, on macOS 14.1 23B74 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] IntelliJ IDEA Community Edition (version 2023.1.3)
[✓] VS Code (version 1.83.1)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!
````

異常なく起動できました。
【Ruby】Array.newによる配列の生成

# はじめに

プログラミング問題で遊んでいた時のことです。

2次元配列を生成して、条件を満たしている要素を書き換えていこうとしたところ、

「ん？思ったのと違う要素まで書き換えられてるやん。あ〜、他の行と同じ配列を参照してるからか。」

と気がつくことはできたものの、いざ、それぞれの行で独立した配列を生成しようとすると手が止まる…

その時は力技で凌ぎましたが、もう少し綺麗に書きたいなと思い、調べた時のことをまとめておきます。

# 結論

縦2 × 横3の配列であれば、次のように生成します。

```ruby
array = Array.new(2){ Array.new(3) }
```

# 各行が独立していない配列の生成

はじめに試して、うまくいかなかった配列の生成方法です。

`new`メソッドの第1引数で1次元目（縦）の要素数を、第2引数で2次元目（横）に入る配列（=生成した配列）を指定しています。

```ruby
array1 = Array.new(2, Array.new(3))
p array1 # => [[nil, nil, nil], [nil, nil, nil]]

array1[0][1] = 1
p array1 # => [[nil, 1, nil], [nil, 1, nil]]
```

上記のとおり、`array1[0][1]`を書き換えたいだけなのに、`array1[1][1]`が一緒に書き換えられてしまっています。

1行目と2行目が同じ配列を参照しているということを`object_id`で確認してみます。

```ruby
p array1[0].object_id # => 60
p array1[1].object_id # => 60
```

**`Array.new(3)`は1度だけ実行**されて、その評価結果（=同じオブジェクト）が各行に入るので、このような結果となります。

# 各行が独立している配列の生成方法（力技）

実際に問題を解いている時は時間的なこともあり、いい方法をすぐに見つけられなかったので、すぐに思いついた次の方法で配列を生成しました。

```ruby
array2 = []
2.times{ array2 << []}
array2.each do |val|
  3.times{ val << nil }
end
```

空の配列を作成→さらにその中に空の配列を作成→要素を1つずつ入れていくという流れです。

結果は意図どおりになっていますが、今あらためて見てもイケてない…

というわけで、もう少し綺麗に書きたいという今回の記事に繋がりました。

```ruby
p array2 # => [[nil, nil, nil], [nil, nil, nil]]

array2[0][1] = 1
p array2 # => [[nil, 1, nil], [nil, nil, nil]]

p array2[0].object_id # => 60
p array2[1].object_id # => 80
```

# 各行が独立している配列の生成方法

冒頭の結論に書いているとおり、こちらの方法で生成します。

```ruby
array3 = Array.new(2){ Array.new(3) }
```

最初の方法との違いは、2次元目の配列を第2引数ではなく、ブロックで渡していることです。

**ブロックは要素ごとに実行**され、その評価結果が各行に入る、つまり各行には違うオブジェクトが入るということになります。

（公式リファレンスの[ここ](https://docs.ruby-lang.org/ja/latest/class/Array.html#S_NEW:~:text=%E9%95%B7%E3%81%95%20size%20%E3%81%AE%E9%85%8D%E5%88%97%E3%82%92%E7%94%9F%E6%88%90%E3%81%97%E3%80%81%E5%90%84%E8%A6%81%E7%B4%A0%E3%81%AE,%E3%82%92%E3%81%82%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E8%A4%87%E8%A3%BD%E3%81%AB%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)に書かれているので、あわせてご参照ください。）

確認すると、次のとおり意図した結果が出力されます。

```ruby
p array3 # => [[nil, nil, nil], [nil, nil, nil]]

array3[0][1] = 1
p array3 # => [[nil, 1, nil], [nil, nil, nil]]

p array3[0].object_id # => 60
p array3[1].object_id # => 80
```

# さいごに

私の結論としては「2次元目の配列をブロックで渡す」ということになりました。

「もっといい方法知ってるよ！」「こんな方法もあるよ！」という方がいらっしゃいましたら、ぜひ教えてください！
video,canvas要素のスクリーショットを撮るライブラリを作った（WebGL対応）

video,canvas要素のスクリーンショットを撮る非常にシンプルなライブラリです。
canvasのcontextTypeがwebglでも期待したスクリーショットが取得できます。

https://matometaru.github.io/video-canvas-screenshot/

## なぜ作ったのか？

1. 今動いている2つのサービスで使う予定でライブラリ化するメリットがあるから。
2. contextTypeがwebglの時のスクリーショットが撮れないと困っている人が自分以外にもいたから。

## canvasのcontextTypeがwebglの時にスクリーショットが空になる問題

（出力が画像がpngなら透明、jpegなら真っ黒の画像になります。）

https://stackoverflow.com/questions/26431862/three-js-canvas-todataurl-sometimes-blank

上の記事の回答にあるように、Three.jsでは`preserveDrawingBuffer: true`にすることで、空ではないスクリーショットが撮ることができます。

Three.jsの説明ではpreserveDrawingBufferについてこう書かれています。

> preserveDrawingBuffer - 手動でクリアまたは上書きされるまでバッファを保存するかどうか。デフォルトはfalseです。

バッファを保存しないのでtoDataURL()をしたタイミングにより空の画像が出力されます。タイミングによっては期待した画像が出力されこともあります。

`preserveDrawingBuffer: true`にすることでパフォーマンスも落ちてしまいますので、できればtrueにするのは避けたいですね。

## 解決策

canvas(contextType: webgl) -> canvas(contextType: 2d) にデータをコピーしcanvas(contextType: 2d)からtoDataURLを行っています。

詳しくは作成したライブラリのコードを見ていただければと思います。
https://github.com/matometaru/video-canvas-screenshot

## 参考

ライブラリの環境は以下の記事を参考にさせていただきました。非常に分かりやすかったです。

https://blog.hey3.dev/posts/vite-lib-mode-to-publish-npm
Pythonで「三連引用符を使った複数行の文字列の記述」の動作を確認してみた

# 概要

Pythonで「三連引用符を使った複数行の文字列の記述」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index3.html

# 実装

以下のファイルを作成しました。
```sample.py
msg = """\
こんにちは。
今日のミーティングですが"予定通り"の時間に行います。
何か変更があれば連絡してください。"""

print(msg)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
こんにちは。
今日のミーティングですが"予定通り"の時間に行います。
何か変更があれば連絡してください。
```

# まとめ

何かの役に立てばと。
「Step #2 - "build": ERROR: failed to initialize analyzer: getting previous image」の解決法

## この記事は

```
Step #2 - "build": ERROR: failed to initialize analyzer: getting previous image: getting config file for image "us.gcr.io/xxxxxx/gcf/us-west1/xxxxxxxxxxxxxxxxxxx:latest
```

すっごい久々にGoogle Cloud PlatformのCloud Functionにデプロイしていた関数を更新しようとしたら以下のエラーが出て困った。
この問題を解決する方法について書きます。

（参考までにログ全体。ひみつのところはxxxxxxxxってしてます。）

```
{
insertId: "xxxxxxxxx"
labels: {2}
logName: "projects/xxxxxxxx/logs/cloudbuild"
receiveTimestamp: "2023-10-28T16:10:01.718867346Z"
resource: {2}
severity: "INFO"
textPayload: "Step #2 - "build": ERROR: failed to initialize analyzer: getting previous image: getting config file for image "us.gcr.io/xxxxxxxx/gcf/us-west1/xxxxxxxxxxxxxxxxxxxxxx:latest": GET https://storage.googleapis.com/us.artifacts.xxxxxxxxxxx.appspot.com/containers/images/sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?access_token=REDACTED: unexpected status code 404 Not Found: <?xml version='1.0' encoding='UTF-8'?><Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Details>No such object: us.artifacts.xxxxxxxxxxxx.appspot.com/containers/images/sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</Details></Error>"
timestamp: "2023-10-28T16:10:01.419947150Z"
}
```

## 先人のトラブルシュート

https://stackoverflow.com/questions/77181996/gcloud-build-failure-error-failed-to-initialize-analyzer-no-such-object

このスタックオーバーフローページで同じエラーメッセージへの対処が報告されています。
それによると、一番簡単な解決方法はArtifact-registryに移行することだそうです。

### Artifact Registry

Artifact RegistryについてはこちらのGoogle Cloud公式記事で解説されています。

https://cloud.google.com/blog/ja/products/application-development/understanding-artifact-registry-vs-container-registry

https://cloud.google.com/artifact-registry/docs/transition/transition-from-gcr?hl=ja

> 2023 年 5 月 15 日より、Container Registry は非推奨になっています。現在 Container Registry を使用している場合は、Artifact Registry に移行できます。

Container Registryは既に非推奨なので、古いCloud Function関数をこれまでの設定で使っているとこういうエラーが起こっちゃうことがあるのだな、と自分は解釈しました。
というわけで、エラー解決のためにArtifact Registryへの以降を試みます。

## 手順

もしかしたらこのうちいくつかの手順は必要ないかもしれません。とりあえず自分がやった手順ということでご理解ください（そんなにGoogle Cloud Platform使い慣れてないので…）

### 1. Artifact Registryにリポジトリを作る
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189424/767b853d-d538-01f9-abbe-a5c448f64893.png)

Container Registryのページを開くとこんなWarningが出てきたので、GCR.IOリポジトリを作成ボタンを押してまずは作っておきます。

### 2. Artifact Registryへのルーティング設定を行う
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189424/efda34da-8a55-0808-3580-d07fc9b75814.png)

ルーティングのためには権限の変更が必要でした。必要に応じて、サービスアカウントにロールをアタッチして、この設定を完了させておきます。

### 3. Cloud Functionをデプロイする
デプロイの際に、Artifact Registryを使うように設定を変更します。

[Runtime, build, connections and security settings]->[SECURITY AND IMAGE REPO]

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189424/0760f422-df38-34ca-4004-22c68d282247.png)

一番下までスクロールダウンして…

[Image repository]で[Google managed Artifact Registry]を選択

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189424/1854e577-0cbf-94be-64c7-d9281cf2e8bd.png)

この状態でビルドしたら成功しました。やったー。
JavaScriptでの幅取得

Javascriptで横幅、縦幅を取得する方法と、その違いについてメモ。
この記事では横幅だけ書いていますが、縦幅でも考えは同じです。

```js
console.log(window.outerWidth);
console.log(window.innerWidth);
console.log(document.documentElement.clientWidth);

// 1828
// 1229
// 1229
```

Macでコンソールログを開いた時に上記の数値が表示されました。
`window.outerWidth`はブラウザ自身の幅
`window.outerWidth`はそのブラウザにコンテンツが表示される幅
`window.outerWidth`はそのブラウザにコンテンツが表示される幅 - スクロールバーの横幅を引いた時の幅となっています。
最初`innerWidth`を使用して開発していました。Mac環境で開発しているので、Windows環境で動作させた時に、動作が違ってました。


#### 参考
https://www.javadrive.jp/javascript/webpage/index6.html
APIまとめ（どんどん更新）

# はじめに
API（Application Programming Interface）は、ソフトウェア間のインターフェースとして機能し、異なるソフトウェアやサービスが互いにコミュニケーションするための方法を提供します
種々のAPIの概要を調べたものをまとめました。

# RESTful API
- 概要
一般的にHTTP/HTTPSを通じてアクセス
CRUD操作（Create, Read, Update, Delete）にHTTPメソッド（POST, GET, PUT, DELETE）を利用
ステートレス性を持つ
- 具体例
GitHub API: リポジトリ情報、ユーザー情報などの取得・操作が可能。
Twitter API: ツイートの取得、ツイートの投稿、フォロワー情報の取得など。
# GraphQL API
- 概要
クエリ言語を利用してデータを取得・操作
必要なデータのみを取得するための柔軟なクエリが可能
エンドポイントが1つだけで、クエリによって返すデータを動的に決定
- 具体例
GitHub GraphQL API: リポジトリやユーザー情報など、必要なデータを効率的に取得。
# SOAP API
- 概要
XMLベースのメッセージングプロトコルを使用
セキュリティやトランザクションといった機能が強化されている
- 具体例
PayPal SOAP API: 金融トランザクションのための高度なセキュリティ要件を持つAPI。
# [WebSockets](https://qiita.com/mt_tashi/items/9b90e39e0ecc1f2d532f)
- 概要
リアルタイムの双方向通信を提供
サーバーからのプッシュ通知が可能
- 具体例
Slack Real Time Messaging API: リアルタイムでのメッセージの送受信が可能。
# [RPC (Remote Procedure Call) API](https://qiita.com/mt_tashi/items/10fd418822727414298a)
- 概要
遠隔での関数/手続き呼び出しを実現するためのプロトコル
gRPC（Googleが開発したRPC）などのバージョンも存在
- 具体例
Google Cloud APIs: 多くのGoogle CloudサービスはgRPCを基盤として提供。
# Streaming API
- 概要
データの連続的なストリームを提供
リアルタイムのデータアップデートや分析に利用
- 具体例
Twitter Streaming API: リアルタイムでのツイートのストリームを提供。
SwiftでViTPoseのランタイムを書いたので精度を確認する

[先日作成した姿勢推定のコード](https://qiita.com/mbotsu/items/f1eb6dcd2b7da6489e35)の動作確認にval2017で精度を評価した。
精度の評価には[cocoapi](https://github.com/cocodataset/cocoapi/)に姿勢推定の結果を評価する[サンプルコード](https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb)があるので、評価データをJSONで出力するコードを実装した。

## データセットのダウンロード

今回は、val2017で評価したいので[COCO DATASET](https://cocodataset.org/#download)から下記の二つのデーターセットをダウンロードした。

- 2017 Val images [5K/1GB]
- 2017 Train/Val annotations [241MB]


## 評価用のJSONを作成するコードの実装

ダウンロードしたval2017の画像をXcodeに手動で追加後、画像から姿勢推定の結果をJSONに保存するコードを実装した。

https://github.com/otmb/TopDownPoseEstimation/blob/main/TopDownPoseEstimation/ValTest/ValTestView.swift

### JSONのフォーマット

``` swift
struct CocoKeyPoint: Encodable {
  var image_id: Int
  var category_id: Int
  var keypoints: [Double]
  var score: Double
}
```

cocoapiには[JSONのサンプル](https://github.com/cocodataset/cocoapi/blob/master/results/person_keypoints_val2014_fakekeypoints100_results.json)が用意してある。

サンプルデータを見れば大体予想がつくが、キーポイントは長いのでわかりにくい。
`keypoints`にはMS COCOの17のキーポイントの並び順で、x, y, score を17x3=51になる配列を作成すればよい。

JSONが作成できればcocoapiにある[評価用のコード](https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb)を実行すればよい。

一応書いたコードも備忘録として残しておく。

https://github.com/otmb/TopDownPoseEstimation/blob/main/tools/coco_eval.py

## 精度評価結果 (MS COCO val2017)

| Models | AP |
|--|:--|
| yolov7-tiny_fp16 + vitpose-b256x192_fp16.mlmodel | 0.589 |
| yolov7-tiny_fp16 + vitpose_s256x192_wholebody_fp16.mlmodel | 0.579 |
| yolov7-tiny_fp16 + vitpose_b256x192_wholebody_fp16.mlmodel | 0.600 |

iPhoneの実機でそれなりの精度が出ているので正常に動いてそうだ。
ここに出てくるwholebodyは17キーポイントのみの評価としている。

[詳細](https://github.com/otmb/TopDownPoseEstimation/blob/main/tools/README.md)
【GitHub】organizationのメンバー権限のユーザがcommitできないように設定する方法

# 背景
GitHubのorganizationにおいて、organizationのメンバー権限の方が**commit**をできないように制限の設定を行った。
本記事では上記権限の設定方法を記載しています。

# 達成したい事
organizationのメンバー権限のユーザがコミットをできないように制限したい。

# 結論
GitHubのorganizationのowner権限のユーザが、organizaitonのSettingから`Member privileges`における`Base permissions`の項目を**read**に変更する。

# 確認日
- 2023/10/26

# 対象の方
- GitHubのorganizatinのowner権限を持っていらっしゃる方
- GitHubのorganizatinにおいてメンバー権限のユーザがcommitを行えないように制限を加えたい方
- タイトルに興味を持たれた方 

# 本記事で検証したテストのためのorganizationの体制
- organizationメンバー2人
  ├自分（owner権限）
  └もう1名（Member権限）

# organization側の設定（変更前）
制限を加える前の状態としては以下のようにorganizationの`Member privileges`における`Base permissions`の項目を`admin`権限に設定していた。
他の項目はデフォルトのままである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/41f1e52e-d630-8962-2df4-c6534bc15b6c.png)

次にorganizationの`Member privileges`の`Base permissions`を**admin**・**read**・**write**権限に変更し、メンバー権限のユーザができる事の違いを見ていく。

# ①. Base permissionsをadminにした場合（organizationの設定）
organizationの**メンバー権限**のユーザは以下のようにリポジトリの上部に「Setting」
タブが表示されており「Setting」をクリックすると以下のようにリポジトリのSettingページに遷移できた。またリポジトリの設定も一部変更できる状態であった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/1dcd52e4-a22c-68d0-3574-e7903ea9d0ef.png)


さらに、同じリポジトリにおいて下記画像のように「Add file」から「Create new file」で新しいファイルを作成しコミットできる状態であった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/86e7c677-0f7b-28d4-8009-3bc0dc69ab2b.png)


# ②. Base permissionsをreadにした場合（organizationの設定）
Base permissionsが**admin**の時に表示されていたリポジトリの「Setting」タブが表示されなくなった。よってorganizationのメンバーの方はリポジトリの設定を変更できなくなったと思われる。
また、**①**のようにBase permissionsが**admin**の際は「Create new file」から新しくファイルを作成できたが、Base permissionsがreadの場合は「Go to file」の表示となり、organizationのメンバー権限のユーザーはファイルが作成できなくなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/eb4bc522-880b-9d4c-3a71-5e31ab709d8f.png)


# ③. Base permissionsをWriteにした場合（organizationの設定）
②のBase permissionsが**read**の時と同様にリポジトリの「Setting」タブが表示されず、organizationのメンバー権限のユーザはリポジトリの設定を変更できないと思われる。
また、Base permissionsが**read**の時とは違い、**write**の時は以下画像のようにorganizationのメンバー権限のユーザは「Add file」から「Create new file」で新しいファイルを作成しコミットできる状態であった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/721d8831-7a32-5f0d-ab1e-372c01ba4b3e.png)

# まとめ
以上のことからorganizaitonの`Member privileges`における`Base permissions`の項目を**read**に変更する事で、organizaitonのメンバー権限のユーザがコミットする事を制限できると思われる。
休憩

<!--
2023/10/30
-->
[picoCTF][General Skills][Obedient Cat]

# Writeup 1
* 休憩
![screenshot 23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/c7d6b21a-5195-2065-6e9e-809a157e2da7.png)
<br>

* 行番号も出せるのね。勉強になる。
![screenshot 37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/3285adc7-35f6-19be-762f-91ac750c1432.png)

----
<!--
2023/10/31
-->
[picoCTF][Web Exploitation][MatchTheRegex]

# Writeup 2
* タイトルから、正規表現を使いそうなので、フラグの形にmatchするように入力。
無事にフラグをゲットできました。
![screenshot 24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/9a7962c4-2a5c-afb4-13b3-e48ef8bd3c54.png)
<br>

* 以上です。
セッターインジェクションについて


# セッターインジェクションとは
セッターインジェクションとは、依存オブジェクトをクラスのセッターメソッドを使用して注入する手法です。これは、コンストラクタインジェクションとは対照的に、オブジェクトのインスタンス化の後でも依存性を変更または追加できるメリットがあります。

# なぜセッターインジェクションなのか
柔軟性: すでにインスタンス化されたオブジェクトの依存性を変更できます。
オプショナルな依存: すべての依存関係を必須にする必要はありません。一部の依存関係はオプショナルとして扱うことができます。
# 実装例
Pythonを使用した簡単な例を以下に示します。

```python
class Engine:
    def start(self):
        return "Engine started!"

class Car:
    def __init__(self):
        self._engine = None

    # セッターを使用してエンジンを注入
    def set_engine(self, engine):
        self._engine = engine

    def start(self):
        return self._engine.start()
```
この例では、CarクラスがEngineクラスの依存関係を持っていますが、セッターメソッドset_engineを使用して注入します。

# いつセッターインジェクションを使用するべきか
セッターインジェクションは以下の場合に特に有用です。

- 依存性がオプショナルである場合。
- ランタイム中に依存性を変更する必要がある場合。

# ランタイム中に依存性を変更する場合とは？

「ランタイム中に依存性を変更する」とは、アプリケーションが実行中（ランタイム中）であっても、オブジェクトの依存関係や機能を動的に変更または置き換えることを指します。

シナリオ
ある車のソフトウェアシステムがあり、この車にはいくつかの異なるエンジンタイプが搭載されています（ガソリン、ディーゼル、電気）。このシステムの目的は、適切なエンジンタイプに基づいてエンジンの動作を制御することです。

車が起動したときには、ガソリンエンジンがデフォルトで搭載されています。しかし、運転手がシステムに介入してエンジンのタイプを変更することができるようにしたい場合（例えば、都市部では電気エンジンに切り替えるなど）、ランタイム中にこの依存性（ここではエンジンの種類）を変更する必要があります。

実装例
```python
class Engine:
    def start(self):
        pass

class GasolineEngine(Engine):
    def start(self):
        return "Gasoline Engine started!"

class ElectricEngine(Engine):
    def start(self):
        return "Electric Engine started!"

class Car:
    def __init__(self):
        self._engine = GasolineEngine()

    def set_engine(self, engine):
        self._engine = engine

    def start_engine(self):
        return self._engine.start()
```
このシステムでは、set_engineメソッドを使用して、ランタイム中に車のエンジンの種類を動的に変更することができます。

```python
Copy code
car = Car()
print(car.start_engine())  # "Gasoline Engine started!"

# ランタイム中にエンジンの種類を電気エンジンに変更
car.set_engine(ElectricEngine())
print(car.start_engine())  # "Electric Engine started!"
```
gnome dash to panel & 日付書式

gnomeの拡張機能で、Dash to Panelを利用しています。
左側にPanelを配置した場合に、日付表示が時間のみとなっていました。
スペースが狭いので仕方がありませんが、日時や曜日も表示させたいなと思って、対応している拡張機能を探してみました。

次の拡張機能が改行（\n）も使えるので、とりあえず狭いスペースでも日付と曜日と時間を表示させることができました。
[Date Menu Formatter](https://extensions.gnome.org/extension/4655/date-menu-formatter/)

localeが日本語だから、曜日も漢字で表示してくれますが、日付にも「月」や「日」がつきますね。
曜日だけ日本語で、日付は数字のみにできる拡張機能があれば、更に良いのですが。
また、時間があれば、探してみよう

でも、デスクトップに表示していれば、それでいい気もします。
[Desktop Clock](https://extensions.gnome.org/extension/5156/desktop-clock/)
繰り返し処理の使い分け

# はじめに
この記事は、私がRuby初学者であり、技術的な知識を向上させることを目指して書かれています。
Rubyの繰り返し処理には多くの種類があるので、基本的なものをまとめて使用例を挙げています。
適所で使い分けをしてコードの効率性、可読性、保守性を向上するのが狙いとなります。

# 使用例と構文

## each文
**配列、範囲オブジェクト、ハッシュの要素**に対して、繰り返し処理を行う時に使います。

```each.rb
#基本的な書き方
'対象のオブジェクト'.each do |'変数'|
 #処理内容
end

#使用例
numbers = [1, 5, 10, 15] #繰り返し処理の対象

numbers.each do |num|
 puts num
end

#出力結果
#=> 1
#=> 5
#=> 10
#=> 15
```
## for文
each文と同じく配列、範囲オブジェクト、ハッシュの要素対して、繰り返し処理を行う時に使います。

:::note warn
Rubyではeachの使用が推奨されています
:::
```for.rb
# 基本的な書き方
for '変数' in '範囲' do
    # 処理内容
end

# 使用例
for i in 1..3 do
    puts "#{i}番目"
end

#出力結果
# => 1番目
# => 2番目
# => 3番目
```

## while文

指定した条件が **満たされている間** 繰り返し処理が行われます。
``` while.rb
# 基本的な書き方
while '条件' do
    # 処理内容
end

#使用例
count = 5

while count > 0 # ここの条件がtrueの間、繰り返しを行います。　今回の場合は０より上という条件になります。
  puts "カウントダウン: #{count}"
  count -= 1
end

puts "カウントダウン終了"

#出力結果
# => カウントダウン: 5
# => カウントダウン: 4
# => カウントダウン: 3
# => カウントダウン: 2
# => カウントダウン: 1
# => カウントダウン終了
```
## until文

whileとは逆に指定した条件が **満たされないの間** 繰り返し処理を行います。
``` until.rb
# 基本的な書き方
until '条件' do
    # 処理内容
end

#使用例
count = 1

until count > 5 # ここの条件がfalseの間、繰り返しを行います。　
  puts "カウントアップ: #{count}"
  count += 1
end

puts "カウントアップ終了"

#出力結果
# => カウントダウン: 1
# => カウントダウン: 2
# => カウントダウン: 3
# => カウントダウン: 4
# => カウントダウン: 5
# => カウントアップ終了
```

## loop文

`loop do`...`end`の間にある処理を繰り返し行う。
途中でbreakを挟んでループを中断する条件を入れる。

::: note warn
braekを入れ忘れると無限ループしてしまうので注意！！
:::
``` loop.rb
# 基本的な書き方
loop do
    # 処理内容
    break # 無限ループを終わらせるために条件を持たせ挟む
end

#使用例
counter = 0

loop do
  puts "これは無限ループです。"

  counter += 1
  if counter >= 5
    break  # カウンターが5以上になったらループを終了
  end
end

puts "無限ループを終了しました。"

#出力結果
# => これは無限ループです
# => これは無限ループです
# => これは無限ループです
# => これは無限ループです
# => これは無限ループです
# => 無限ループを終了しました
```

## times文

任意の回数だけループさせます。
```loop.rb
# 基本的な書き方
'任意の数'.times do |'0から順に指定した数まで入る'|
    # 処理内容
end

# 使用例
5.times do |count|
  puts "Count: #{count + 1}"
end

#出力結果
# => Count:1
# => Count:2
# => Count:3
# => Count:4
# => Count:5
```

## upto,downto文

指定した数に達するまで変数に加算(減算)し続けます。
```upto.rb
1.upto(5) do |number|
  puts "Number: #{number}"
end
```
```downto.rb
5.downto(1) do |number|
  puts "Number: #{number}"
end
```

## 所感
Rubyを学ぶにあたり、繰り返し処理の使い分けを理解するために記事を作成しました。
繰り返し処理はプログラミングにおいて基本的かつ、避けては通れない要素なので
しっかりと習得をしていきたいと思った次第です。
また、適切な処理を選べることでコードの効率性、可読性、保守性を高めれると思いました。
将来的にも綺麗なコードが書けるよう意識して書き分けたいです。
余談ですが、自分の場合はwhile文を使うと、いつも条件を反転させてしまうのでちゃんと理解しないとですね。
【個人開発】グラフ生成サイト「ぐらふつくーる」を公開しました！

## 背景
- ITエンジニアとして個人開発で何かのサービスを公開するというは一つの夢みたいなところがあると思います。
- 今回私が初めて個人開発で作成したグラフ生成サイト「[ぐらふつくーる](https://graph.takuma-tech.com/)」を紹介します。

## アイデアの着想
- 学生・社会人問わず、ちょっとしたデータをパッとキレイに可視化したいシーンはよくあると思います。
- 基本的にグラフを作成しようとすると、ExcelかGoogle スプレッドシートもしくは`python`が使用できれば`matplotlib`などが選択肢となると思います。
- ですが、ExcelかGoogle スプレッドシートのデフォルトのグラフは壊滅的に見づらいですし、かといって`matplotlib`で作成するには手間がかかるという課題があります。
- そこで、webで簡単にちょっとしたデータをパッとキレイなグラフで出力できるのには一定のニーズがあるのではないかと考え、「[ぐらふつくーる](https://graph.takuma-tech.com/)」を作成しました！

## 見た目と使い方
- 「[ぐらふつくーる](https://graph.takuma-tech.com/)」の見た目は下記の通りです。
- 左側にデータを入力するテーブルがあり、それがリアルタイムで反映される棒グラフが右側にあります。
- データを入力して反映された棒グラフを「PNGでグラフをダウンロード」ボタンを押すことでPNGファイルとしてダウンロードできます。

![ぐらふつくーる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/aa2e6216-b69a-04d9-fb69-a185c3c442d0.png)

## 技術スタック

- React: フロントエンドのフレームワーク
- TypeScript: 型安全なコーディングを実現
- Recharts: グラフ生成ライブラリ

## 今後の開発方針
- 現状ではデザインも酷いし、機能も少なすぎると考えています。
- そこで今後は、
	- 色々なグラフが生成可能（円グラフ・折れ線グラフ等）
	- グラフの設定機能（色や大きさ線の太さなど）
　等の機能を追加していくつもりです。
- できればお小遣いチャリンチャリンしたいので、開発を進めて人気が出てきたら月額300円〜500円ぐらいのサブスクサービスにしたい。

## お願い
- 自分でもどんな機能が追加されていければ嬉しいかわからないので、ご意見ありましたらコメント欄に記載していただけると嬉しいです！

## 参考資料

- [Recharts公式ドキュメント](https://recharts.org/)
- [React公式ドキュメント](https://reactjs.org/)
- [TypeScript公式ドキュメント](https://www.typescriptlang.org/)

## 最後に
 - [こちら](https://graph.takuma-tech.com/)からサイトにアクセスできます。ぜひ、使ってみてください！
CyberChef

<!--
2023/10/26
-->
[picoCTF][Cryptography][ReadMyCert]

## Writeup
* ファイルの確認して、とりあえずstringsしてみた。
![screenshot 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/cf4a4778-ff5c-54eb-987b-269a50ccb886.png)
<br>

* 末尾が「=」なので、base64っぽい。
CyberChefでデコードしてみた。
![screenshot 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/104fd4a9-ac01-d0bf-1725-6882e19bdc83.png)
<br>

* 以上です。
BurpSuite２

<!--
2023/10/29
-->
[picoCTF][Web Exploitation][GET aHEAD]

# Writeup
* 通信内容を確認
```GET```と```POST```で異なるようだ。
![screenshot 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/3b74a210-1a25-ba25-c050-9600cf36dfab.png)
<br>

* 問題タイトルに従って、```HEAD```に書き換えてみる。
![screenshot 22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/21aad4b3-debc-78e8-dc74-ca48fcf39299.png)
<br>

* フラグが返ってきた。
![screenshot 21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/64569759-7ec5-66be-a389-479b5777bfcf.png)
<br>

* 以上です。
BigQueryのfederated queriesでConnection Errorが発生した場合の対処法 

BigQueryのfederated queriesを試していたところ、以下のエラーに遭遇。

```
Invalid table-valued function EXTERNAL_QUERY Failed to connect to MySQL database. 
```

公式ドキュメントに記載の通り、Cloud SQL への初回接続時に自動作成されるService Account(BigQuery Connection Service Agent)に対し、以下の権限を付与すれば解決する。

- cloudsql.instances.connect
- cloudsql.instances.get

```
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=serviceAccount:SERVICE_ACCOUNT_ID \
    --role=roles/cloudsql.client
```

https://cloud.google.com/bigquery/docs/connect-to-sql?hl=ja#access-sql
WebSocket + FastAPI + Chat GPT + Chrome拡張機能

![qqq_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11030/280a16cf-5f57-7a8c-4366-1494580ed89f.png)

今回はChrome拡張機能を使い、業務効率化のツールを作ったためその主な動作を説明します。

# ツール作成のきっかけ

ブラウザ上で情報を入力したり、記事を読んでいる時、訳を理解するためにどんな場合でも別画面でGoogleを検索したり、Chat GPT の画面をわざわざ開くことに煩わしさを感じ、業務の効率化を図るための方法として、このツールを考えるきっかけとなりました。

また、他の人がこのツールを使いたい場合、自身のAPIキーを他の人に共有してブラウザ側に保存するのはセキュリティ上良くないと感じ、APIキーをサーバー側に保存することとしました。


# ツールの使い方

このツールでできることは以下です。

※公開しているツールは [コチラ](https://chrome.google.com/webstore/detail/quick-query-question/gcnknkigeobkiihifkfeeklkpkaflgil)
![qqq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11030/d8f560d1-15b2-c80a-1892-42ce0a2141f9.png)

利用者がChatGPTのAPIキーを持っていれば、それをこのツールに設定することができます。
また、開発のための特定のサーバーがある場合は、そのサーバーのウェブサイトのアドレスをこのツールに入力することもできます。
WSS:// で始まるWebSocket用のURLを設定すると、リアルタイムでこのツールとやりとりすることもできるようになります。

また、ツールがデフォルトで提供している設定（プロンプトと呼びます）も変更や追加をすることができます。
使うときの手順としては、まずツールに問い合わせたい言葉や文章を選びます。

その後、ツールの小さい開いたウィンドウ（ポップアップ画面と呼びます）を確認すると、先ほど選んだ言葉や文章がそのまま問い合わせ内容として表示されます（※もし、表示されなければ、ウェブブラウザをもう一度読み込むことで解決するかもしれません。

開いたウィンドウで、設定（プロンプト）を使いたい場合は適当なところに挿入し、「生成」ボタンを押します。
すると、数秒から数分後にツールがあなたの問い合わせに対する答え（レスポンス）が表示されます。


# ツールの仕組み

このツールの基本的な動作フローです。
![chat-gpt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11030/8f7caa26-bcca-f158-bd88-2c892560a140.png)

1. Chrome Extension：　ユーザーが情報を入力すると、このChromeの追加機能がその内容をChatGPTに送信するための情報としてキャッチします。
2. WebSocket：　Chromeの追加機能からの情報は、HTTPSまたはWebSocketという通信手段を用いて送信されます。
3. Nginx：　入力内容を受け取った後、Nginxというサーバーがこの情報をFastAPIというアプリケーションに転送します。
4. FastAPI と ChatGPT：　FastAPIは受け取った情報を元に、ChatGPTとの対話を開始します。このとき、WebSocketを活用している場合、対話の結果はリアルタイムでユーザーのブラウザ画面に表示されることとなります。

このような流れを通じて、ユーザーはブラウザ上で簡単に情報の入力とChatGPTとの対話を行うことができるようになりました。
これにより、情報の検索や翻訳作業の効率を大幅に向上させることができるようになりました。

次回もう少し内部の動きを掘り下げて解説します。
MeCabの「-Ochasen」使用時にエラーが出る場合

## エラー内容
```: ERROR内容
前略

issueを英語で書く必要はありません。

------------------- ERROR DETAILS ------------------------
arguments: -Ochasen
error message:  [!tmp.empty()] unknown format type [chasen]

---------------------------------------------------------------------------
```

こんなエラーで悩んでいませんか？
私が解決した方法を共有します。

## 解決方法

ipadicをインストールします。
```:cmd
>>pip install ipadic
```

あとは下記の様に指定します。

```Python:test.py
import MeCab
import ipadic

CHASEN_ARGS = r' -F "%m\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[4]\t%f[5]\n"'
CHASEN_ARGS += r' -U "%m\t%m\t%m\t%F-[0,1,2,3]\t\t\n"'

tagger = MeCab.Tagger(ipadic.MECAB_ARGS + CHASEN_ARGS)

print(tagger.parse("私がリンゴを食べました"))
```


## 参考元
今回はGithub([ページ]("https://github.com/SamuraiT/mecab-python3/issues/54"))にて記載していたエラー解決方法です。
中々見つからずいつも困っていたので備忘録として記録しました。
CaboChaをPython64bit版で使う方法

## 前置き
今回はまず私が開発していないことをご承知おきください。
また本物のCoboChaではありません。
有志の方がCoboChaを再現したものの紹介となります。

##  方法
まず初めに[こちら](https://srad.jp/~yasuoka/journal/634415/ "UniDic2UDによるCaboChaエミュレータと本物のCaboChaとの違い")をご確認ください。
2019年にyasuoka様によって公開されたUniDic2UDというライブラリを使用します。

いつものごとく...
```cmd:cmd
>>pip install unidic2ud
```
これでインストール完了です。
後は下記の様にインポートして使えます。

```Python:test.py
import unidic2ud.cabocha as CaboCha

省略
```


yasuoka様、感謝感謝です。
[PHP入門] 抽象クラスとインターフェース

PHPにおいてポリモーフィズム実現のために使われる抽象クラスとインターフェースですが、勉強していてややこしいなと感じたのでアウトプットを兼ねて記事にまとめます。


# 抽象クラス
抽象クラスとは、処理が記述されていないメソッド(抽象メソッド)を持つクラスのことです。クラス名と抽象メソッドの前にabstractと宣言することで定義できます。
### 特徴
- 通常のクラスと同様に処理を記載したプロパティやメソッドを定義できる(アクセス修飾子も自由)
- 抽象プロパティは定義できない
- 抽象メソッドのアクセス修飾子はpublicかprotected
- クラス名と抽象メソッドの前にabstractを宣言
- 直接インスタンス化できない
- extendsを使って継承
- 抽象メソッドは必ずオーバーライドしなければならない
### 使い方
```php:AbstractAnimal.php
abstract class AbstractAnimal
{
    // 通常のクラスと同様に処理を記載したプロパティやメソッドを定義できる(アクセス修飾子も自由)
    private $weight = 10; // 継承しなければならないためprivateは基本使われません
    protected function eat($food)
    {
        return "{$food}を食べる";
    }
    // 抽象プロパティは定義できない
    //abstract public $height = 30;

    // 抽象メソッド(処理は書かない)
    // アクセス修飾子はpublicかprotected
    abstract public function run($distance);
}

```
```php:Dog.php
// 抽象クラスは直接インスタンス化できない
// $animal = new AbstractAnimal();

// extendsを用いて継承すればインスタンス化できる
// その際、必ず抽象メソッドをオーバーライドして処理を書かなければならない
class Dog extends AbstractAnimal
{
    public function run($distance)
    {
        return "{$distance}を走る";
    }
}

$dog = new Dog();
```
# インターフェース
インターフェースとは、処理が記述されていないメソッド(抽象メソッド)と定数のみで構成されたもののことを指します。クラス名の前にinterfaceと宣言することで定義できます。
### 特徴
- 抽象メソッドと定数のみしか定義できない
- アクセス修飾子はpublicのみ
- クラス名の前にinterfaceを宣言
- 直接インスタンス化できない
- implementsを使って「実装」
- 抽象メソッドは必ずオーバーライドしなければならない
- 複数のインターフェースを指定して実装できる
### 使い方
```php:Cat.php
interface Cat
{
    // 抽象メソッドと定数のみを定義
    const CUTENESS = "overloaded";
    // アクセス修飾子はpublicのみ
    public function eat();
    public function run($distance);
}
interface Munchkin
{
    const SHORTLEGS = true;
}
```
```php:Tama.php
// インターフェースも直接インスタンス化できない
//$cat = new Cat();

// 複数のインターフェースを指定して実装できる
class Tama implements Cat, Munchkin
{
    // 抽象メソッドはオーバーライドして処理を書かなければならない
    public function eat()
    {
        return "食べる";
    }
    public function run($distance)
    {
        "{$distance}を走る";
    }
}

$tama = new Tama();
```
【Next.js】Not Foundページを表示する方法

## ページを作成する

`page.tsx`を以下のように作成します。

```tsx:page.tsx
async function getData() {
  const res = await fetch('https://api.example.com/...')

  return res.json()
}
 
export default async function Page() {
  const data = await getData()
  if (!data) {
    notFound()
  }
 
  return <main></main>
}
```

## Not Found画面を作成する

`pages.tsx`と同じ階層に`not-found.tsx`を作成します。

```tsx:not-found.tsx
import { useEffect } from 'react'
 
export default function NotFound() {
  return (
    <div>
      <h2>ページが見つかりませんでした。</h2>
    </div>
  )
}
```

上記のように記述すると`page.tsx`の`notFound()`が実行されると`not-found.tsx`が表示されるようになります。
QA業務の大まかな流れ

こんにちは！

私は以前、QA(テストエンジニア)をしていたことがあるのでここに、その経験から得た知識をここに記したいと思います！

## QAエンジニアとは？

QAエンジニアは主に動作確認テストを行うエンジニアです。ここの画面遷移がおかしい？とか、ここのデータのやり取りがうまくいっていない？などリリース前にサービスが不具合を起こしていないかをチェックする最終段階のエンジニアです。そのため、決済の際にコマンドを使うことがあるかな？など、、コードを書くことが他のエンジニアに比べると必然的に少なくなってしまいます:sweat:

バリバリコードを書きたい人にはあまりお勧めできません、、、

とはいえ、個人で開発物を作成した際には必ずリリースする前にテストが必要となりますよね？そんなときのためにここではQA業務の流れに関して説明したいと思います。

## QA業務の手順

上流階層から開発プロダクトの大まかな完成形のイメージを共有してもらいます

　　　　　　　　　　　　　　　　　↓
サービスの改修などによる影響範囲を検討します。(ここでは、コードを読んで考えることもしばしば、、、。)

　　　　　　　　　　　　　　　　　↓

次にテスト用のチェック項目に関してのシートを作ります。　　(媒体は何でもいい
と思いますが、個人的にはGoogleスプレッドシートがおすすめです！！)

　　　　　　　　　　　　　　　　  ↓

後は実際に新機能や新プロダクトがリリースされるまで待ちます。

## QAテストシートの作成

次にテストシートの作成段階に入っていきます！


### 正常系
テストシートの作成の仕方はまず、正常系と異常系に分けます。正常系と異常系とはいったい何なのか？と思う方もいらっしゃると思います。正常系は普段皆さんが利用しているサービスなどを常識的に利用するときに予想される操作に対して不具合が出ないかどうかを確認します。

### 異常系
異常系とは何でしょうか？

異常系とは普段の使用の仕方では考えられない操作をすることに対して不具合が出ないかどうかを確認します。

たとえば

- ページをリロードしまくる
- 画面内にあるボタンを連打する
- 良いねのクリックを連続で行う

など、少しいたずら的な操作に対しても不具合が出ないかを確認します。これが異常系のテストです。

### 実際にテストシートを作成するにあたって

テストシートの作成にあたっては各まとまりをもったテスト項目を記載するということです。

例えば、

***
**課金ユーザーの権限でログインする**

↓

**画面のリンクにアクセスする**

↓

**画面内の細かい動作に関していじる**

↓

**さらにその画面の中で遷移する先の動きに関してテストする**
***

こんな感じて大きい項目から遷移していくような操作をスプレッドシートで作成して対応したりすることができます！！



### 良いQAテストシートとは？

ここの内容に関しては多く議論されていることですが、いいテストシートとは単に隅々までテストを行うということと対応していません、、。

いいテストシートとは**漏れなく、ダブりなく**これにつきますね、、。

影響範囲を網羅できていてかつダブりの項目がなく、テスト実施のボリュームが軽く済む！これがいいテストシートです！

様々な要素が相互に影響してしまうことが多いので、このダブりなくが本当に難しいですっ！私もここに関してほんとに苦労していました。

QAとはいえ、なかなか難しいことが多いので試行錯誤して頑張ってくださいね！！

この記事を通して少しでも皆さんの力になれるとうれしいです！！
非同期処理の使い分け コールバック関数,Promise,async/await 

これまでの投稿でコールバック関数、Promise、async/awaitについてまとめてきました。
最後にこれら３種類の非同期処理の使い分けについて、本記事で整理します。


▼過去の記事

* [JavaScriptの非同期処理の変遷 ① コールバック関数の登場とその課題](https://qiita.com/yusuke2310/items/534a007836089eebb2f4)
* [JavaScriptの非同期処理の変遷② Promiseを利用することで改善できたこととは？](https://qiita.com/yusuke2310/items/134b8484d3e0cb0b8d14)
* [JavaScriptの非同期処理の変遷③ async/awaitはなぜ同期処理のように書けるのか](https://qiita.com/yusuke2310/items/b2dbe85c966bb14268eb)
* [TypeScriptでの非同期処理　戻り値の型どうする？ Promise<T>](https://qiita.com/yusuke2310/items/ed68b1e214520117d75b)
* [[JavaScript]Promiseからasync/awaitへの書き換え](https://qiita.com/yusuke2310/items/206526f0de393e2b28e1)

---
##### async/awaitの利点
非同期処理を同期処理とほぼ変わらない文法で、とても簡単に記述できる。

##### async/awaitの注意点
* 単なるPromiseの糖衣構文ではない
※糖衣構文：プログラミング言語において、読み書きのしやすさのために導入される書き方

##### Promiseについて
* そもそもasync/awaitはPromiseオブジェクトを使いやすくするための構文なので、Promiseについての理解は必須。
* Promiseを返す非同期処理関数を自分で実装する場合、Promiseの理解は必ず必要。
* 複数の非同期処理を並列実行する場合、asnyc/awaitだけでは対応できないので、Promise.all()のような待ち合わせ関数が必要。

##### コールバック関数について
* 複数回呼ばれる可能性のある処理にはコールバック関数が必要。
* 以下のようなケースでは、コールバック関数を使った方が扱いやすい。
    * あくまでもサブ的な処理であり、他にメインの処理がある
    * 頻繁には呼ばれず、せいぜい終了時に1回呼ばれる程度
    * イベントが発生するタイミングが局所的ではなく、プログラム実行中のいろいろなタイミングで発生する可能性がある

---




▼参考文献

https://gihyo.jp/magazine/SD/archive/2023/202309
【Windows】yarnを最新バージョンにアップデート際に実施した手順

## 経緯

npmなど更新頻度の高いミドルウェアで実行したことをメモしたおいて見返せるようにしたい


## バージョンアップ手順

### npm バージョンアップ

node.jsのバージョンアップが必要なケースもあるので定期的に新しいバージョンにアップデートしておく
Windowsの場合は下記サイトからMSIインストーラでインストールするほうが個人的には楽

https://nodejs.org/en/download


今回はnpm@10にアップデートしようとしたところnodejs16をサポートしていないため18以上へのアップデートが必要だった。
```console
C:\Users\masas>npm install -g npm@10.2.1 
npm WARN cli npm v10.2.1 does not support Node.js v16.16.0. This version of npm supports the following node versions: `^18.17.0 || >=20.5.0`. You can find the latest version at https://nodejs.org/.
npm ERR! code EBADENGINE
npm ERR! engine Unsupported engine
npm ERR! engine Not compatible with your version of node/npm: npm@10.2.1
npm ERR! notsup Not compatible with your version of node/npm: npm@10.2.1
npm ERR! notsup Required: {"node":"^18.17.0 || >=20.5.0"}
npm ERR! notsup Actual:   {"npm":"10.2.1","node":"v16.16.0"}

npm ERR! A complete log of this run can be found in: C:\Users\masas\AppData\Local\npm-cache\_logs\2023-10-28T12_44_58_217Z-debug-0.log
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89244/b03a7e9c-9e85-5643-30d9-d1c7bb23f24d.png)


MSIインストーラでインストールした場合はCドライブの`C:\Program Files\nodejs`にインストールされるため
コマンドプロンプト、PowerShellは管理者権限を使ってアプリを起動する。

バージョンを確認方法
```
PS C:\Users\masas> npm -v
10.2.1
```

### yarn バージョンアップ

yarn set コマンドで最新バージョンにアップデートする。

```
C:\Users\masas>yarn set version latest #最新はVer4
➤ YN0000: Downloading https://repo.yarnpkg.com/4.0.0/packages/yarnpkg-cli/bin/yarn.js
➤ YN0000: Saving the new release in .yarn/releases/yarn-4.0.0.cjs
➤ YN0000: Done in 0s 453ms

C:\Users\masas>yarn --version
4.0.0
```

https://yarnpkg.com/cli/set/version
MQのバックアウトとは

## MQのバックアウトの動作について

### 現在の自分の理解

処理の中断して、元の状態に戻すこと
ロールバック
または
Undoの処理と同義？



https://e-words.jp/w/%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88.html

https://qiita.com/piko_piko_pico/items/3b770ee097b917d91e03
整列

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/906206d9-6f0a-d846-1ebc-9390c80bff47.png)
１：整列アルゴリズム
　「代表的な整列アルゴリズム」
①交換法（アルゴリズム）：手順の概要は隣同士を比較して、順序関係が逆であれば、入れ替える処理を繰り返す。
 時間計算量：O(n2)
②選択法（アルゴリズム）：手順の概要は最大値（最小値）を順次取り出す。時間計算量：O(n２)
③挿入法（アルゴリズム）：手順の概要は整列済み要素の適切な位置に、未整列要素を挿入する処理を繰り返す。
時間計算量：O(n２)：
④クイックソート（アルゴリズム）：手順の概要は基準値よも大きなグループと、小さなグループに分ける。その後、各グループごとに、同様の処理を繰り返し適用する。時間計算量：O(nlog n)
⑤マージソート（アルゴリズム）：手順の概要は整列済みの２つの配列を併合することを繰り返す。整列するデータの1/2を一時的に格納するための作業用領域が必要である。時間計算量：O(log　n)

※試験の出題例：「対象集合から基準となる要素を選び、これよりも大きい要素の集合と小さい要素の集合に分割する。この操作を繰り返すことで、整列を行う。」方法はクイックソートである。
Node-REDとQLabを組み合わせて効果音ポン出し

# はじめに

以前、Node-REDで効果音ポン出しシステムを作って、オンラインイベント参加者に使ってもらいました。

https://qiita.com/kitazaki/items/a2cf839def4c72c69ca5

# ハッカソン

ハッカソンで作ったゲームの開始・終了時の声出しや、ゲーム中に音楽を流すことを考えました。

https://protopedia.net/prototype/4727

短い音声や効果音であれば途中で再生を止める必要はありませんが、ゲーム中の音楽はゲーム終了時に再生を止める必要があり、Node-REDの以下のノードではできないことがわかりました。

- node-red-dashboard (audio outノード)
- node-red-contrib-play-audio
- node-red-contrib-play-audio-file
- node-red-contrib-play-sound

![スクリーンショット 2023-10-28 22.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/77ea474e-a342-acce-4bdd-f759fcd432b5.png)

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/cd390e1b-f641-5f06-bbe4-294ee0f64db7.png)

# QLab

音声、映像のポン出しソフトウェアとしてQLabがあることを知りました。

https://qlab.app/

Node-REDからQLabを操作するノードがあります。

- node-red-contrib-qlab

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8e17ec89-17c0-824b-7591-a9c7e8791278.png)

## QLabのCue登録

QLabに効果音を登録します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b494f3aa-4d8a-a4c4-f193-9faffe8d472b.png)

リモートからOSCで制御できます。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d8735487-0e08-718f-c2d2-1b0b723376a6.png)

## 再生

QlabをNode-REDと同じPC(macOS)で動かす場合の設定です。
Qlabに登録した効果音を再生するコマンドは、/cue/[登録番号]/goです。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5d1b6c3a-5810-cae7-1b67-9dae447bedc4.png)

![スクリーンショット 2023-10-28 22.26.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/c20c758b-f4d9-7e46-51fb-a03fbb59fda8.png)

![スクリーンショット 2023-10-28 22.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/c6ab4766-38ea-f937-0b99-bf1a8610896c.png)

## 再生停止

再生を停止するコマンドは、/panicです。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1b4fc9a4-1e59-eb26-4b48-93f087e40005.png)

![スクリーンショット 2023-10-28 22.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/eefe1ca4-31e9-a7b9-dba4-4a868ad1f9c1.png)

# 発電力王ゲーム

手回し発電機で発電量を競うゲームです。

![スクリーンショット 2023-10-28 20.29.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b4ee9017-0a37-7370-6d34-3e97991a0c0b.png)

ダッシュボードで「カウントダウン」ボタンを押すと、カウントダウンの音声が再生され、ゲームが開始すると音楽が再生されます。ゲームが終了すると音楽の再生が停止し、勝者が宣言(音声が再生)されます。

![スクリーンショット 2023-10-28 22.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1653aa23-74b7-f07e-6a0b-884c688b972e.png)

![スクリーンショット 2023-10-28 20.29.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/6ff3726e-ee3c-0534-12b8-ddb3754d755c.png)

(動画)

https://video.twimg.com/amplify_video/1716755167100715008/vid/avc1/1280x720/6f9RrBhWmM1McIWa.mp4
Docker環境でLaravelを使った時のDBの設定

# Docker環境でLaravelを使った時のDBの設定 #

## 使用したDocker Image ##
php:8.2-apache

## 発生した問題 ##
docker composeを使ってlaravelアプリケーションを作成し、マイグレーションを反映させるときに以下のエラーが出ました

```
php artisan migrate;
```
を実行すると

```
could not find driver
```
といったエラーが表示されます。

## 原因 ##
laravelを使う際にはpdo_mysql、mysqliの拡張機能が有効になっている必要がある

## 解決方法 ##
コンテナ内に入り拡張機能をインストールし、設定を反映させる必要があります。以下のコマンドでインストールを行い、その後apacheを再起動させれば設定は反映されます。

```
docker-php-ext-install pdo_mysql;
docker-php-ext-install mysqli;
/bin/bash -c 'cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini';
/bin/bash -c 'echo extension=mysqli >>  /usr/local/etc/php/php.ini';
/bin/bash -c 'echo extension=pdo_mysql >>  /usr/local/etc/php/php.ini'
```

※補足として、php8.2-apacheでは、php.iniがないので、/usr/local/etc/php/php.ini-productionをコピーして、そのファイルに書き込むことで設定を反映させます。


## 解決で使用した便利コマンド ##
- pdo_mysqlが有効か確認
    - ```php -m | grep pdo_mysql;```
- mysqliが有効か確認
    - ```php -m | grep mysqli;```
- php.iniのパスを確認
    - ```php --ini```
- phpのキャッシュをクリア
    - ```php artisan cache:clear; php artisan config:clear; php artisan route:clear; php artisan view:clear;```