OmniAICreator/Qiita-1.07M huggingface dataset:
pyqtgraphを使ってみる

## pyqtgraphとは?
pyqtgraphとはPyQtというGUIツールキットで使うグラフ描画ライブラリです。
pyqtgraphはグラフのプロットが高速という点で優れたライブラリです。
Pythonのグラフ描画ライブラリではmatplotlibがよく使われていますが、動作は速くありません。
pyqtgraphの方が高速に処理ができるため、リアルタイムにデータをプロットさせる場合にはpyqtgraphがむいています。
なぜpyqtgraphの処理が高速かというと、pyqtgraphはQt(キュート)をベースにしていることが理由の一つになります。
QtとはC++で開発されたクロスプラットフォームフレームワークのことを言います。クロスプラットフォームとは異なるプラットフォームやデバイス上で動作するソフトウェアを開発するためのフレームワークを言います。
このQtはC++がベースになっているので処理が高速です。
もう一つの理由としては、PyQtGraphは数値計算をNumpyに依存している点です。NumPyは高性能な数値計算ライブラリであり、これを使用することでデータの処理が高速に行えます。
## pyqtgraphを使う環境構築
pyqtgraphは、PyQt上で動作します。まずPyQtをインストールします。
```
python -m pip install PyQt5
```
次にpyqtgraphをインストールします。
```
python -m pip install pyqtgraph
```
### anaconda環境でpyqtgraphを使う場合
現在の仮想環境がbase(root)の場合は元からpyqtが入っているのでインストールする必要はないようです。

:::note warn
AnacondaでSpyderを利用している人は注意点があります。
SpyderがPyQt5を利用していて、PyQt5を更新するとSpyderが起動しなくなる可能性があるとのことです。
:::

現在の仮想環境にpyqtが無い場合は次のようにしてpyqtを入れます。
```
conda install -c conda-forge pyqt
```

pyqtgraphをインストール
```
conda install -c conda-forge pyqtgraph
```
## pyqtgraphのサンプルを起動する
pyqtgraphのサンプルを見てみましょう。
```
import pyqtgraph.examples
pyqtgraph.examples.run()
```
実行すると以下のウィンドウが開きます。
このウィンドウではpyqtgraphを使用したサンプルを実際に動作させて見ることができます。

左のリストからサンプルを選択し、左下の「Run Example」ボタンでサンプルを実行できます。


![ pyqtgraphのサンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148557/bb078f1e-e2f0-fc6a-fdbe-6ae2cf574a50.jpeg)

以下はサンプルの「Basic Plotting」を実行した画面になります。↓

![Basic Plotting](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148557/7c6ea520-c681-8814-c900-06423d8b2e43.jpeg)
## まとめ
今回はpyqtgraphのサンプルを使ってみるという記事でした。サンプルを動かしてみると面白いものがいろいろあったので是非試してみると良いと思います。
## 参考文献
https://watlab-blog.com/2019/10/20/pyqtgraph-install/

https://self-development.info/pyqt5%e3%81%ae%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%80%90python%e3%81%a7gui%e3%82%a2%e3%83%97%e3%83%aa%e4%bd%9c%e6%88%90%e3%80%91/#Pyqt5%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
【TailwindCSS】対応デバイスでのみhoverを適用する方法

`hover:`を設定した要素をスマートフォンなどでタップすると他の要素がタップされるまで`hover:`で設定されたスタイルが適用され続けます。
`tailwind.config.js`に以下の記述を追加することでタップで`hover:`のスタイルが適用されなくなります。

```js:tailwind.config.js
/** @type {import('tailwindcss').Config} */

module.exports = {
  future: {
    hoverOnlyWhenSupported: true,
  },

  // ...
}
```
[Python][Julia]Project euler5 (プロジェクトオイラー5)

#### Project euler Ploblem 5 (プロジェクトオイラー5)
[Smallest Multiple](https://projecteuler.net/problem=5)

備忘のために残しておく。


## 問題
#### 問題文 (意訳)
1~20の全ての数字で割り切れる最小の数は？
(1〜20の最小公倍数は？)

原文
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20 ?

## 解答
答え<b>232792560</b>

最小公倍数を計算するだけ

#### Pythonのコード
```Python:Python Ploblem5
# SymPyモジュールで最大公約数、最小公倍数を計算する
import sympy
print(sympy.lcm(range(2,20+1)))
```
```Python: Python
# 愚直に計算する
def lcm(list_l: list) -> int:
    greatest = max(list_l)
    i = 1
    while True:
        for j in list_l:
            if (greatest * i) % j != 0:
                i += 1
                break
        else:
            return greatest * i
lcm((range(1,20+1))

```

#### Juliaのコード
```Julia: Julia Ploblem5
# lcm関数を使う
println(lcm(1:20))
```
```Julia
#　愚直に計算する
function lcm_h(list_l)
    greatest = maximum(list_l)
    i = 1
    while true
        flag = false
        for j in list_l
            if (greatest * i) % j != 0
                i += 1
                flag = true
                break
            end
        end
        if flag
            
        else
            return greatest * i

        end
    end
end

println(lcm_h(collect(1:20)))
```
LINE CLOVAを改造した話。


# はじめに

今年は、LINE CLOVA にとっては悲しい年になってしまいました。
そう、３月末をもってサービス終了になったのです。日本発の(メーカーは韓国?) AIスピーカとして、外資系 AIスピーカと並んで頑張っていたのですが・・・
中々サービスだけでは採算取れなくて、負けちゃったのですかね。

# デバイスは文鎮化する⁉

サービス終了後どうなるかをよく読んでみると、Bluetoothスピーカとしてしか使用できないとの事。LINE CLOVA は、頭脳を殆どサーバー側に持っていたのでしょうがないですよね。
しかしデバイスを買って使い続けているユーザーにとってはいきなり使えなくなるって悲しすぎるでしょう。

という訳で改造が出来ないか分解して改造してみました。

# 先ずは改造してみる。

分解から始まり、徹底的な信号の解析、そして使える部分は使って、頭脳（コンピューターとソフト)を入れ替えて何とか動く様にしてみました。コンピュータは元々は ARMベースで Android OS 上で動いていたのですが、ブラックボックス状態のソフトを改造するのはほぼ不可能なので、ラズパイと音声系回路を全て置き換え、ソフトの方は１から作りました。といっても AIの部分は大部分を OpenAI の API つまり ChatGPTの機能を使ってリプレースした感じです。

詳しくはこちら▼の記事を見てください。

[ラズパイ化CLOVA-パート１（ガチの改造編）](https://elchika.com/article/1c5edcc4-701c-4a10-9e71-435ded8ba2be/)

# 改造の難易度を下げる為に

前回の改造CLOVAをいくつかのコミュニティーでお披露目してみたのですが、やってはみたいけど改造方法が複雑すぎると言われました。
そこで、専用基板を作ってみました。元基板の頭脳(コンピュータ)や音声系の主要部品が載っているマザーボードを、丸ごと入れ替えることにしました。基板を置き換えるにはその基板の形もさることながら、コネクターも同じにしないとそのまま置き換えるのは困難です。
何とかコネクターの種別を探し当てて同じのを使って基板を作成しました。

詳しくはこちら▼の記事を見てください。

[ラズパイ化CLOVA-パート2（専用基板編）](https://elchika.com/article/38d8127b-7cb4-44b9-ae63-ece591d777f9/)

# CLOVA mini の方がユーザーが多い。

そして、今度こそと思って見せてみると、CLOVA の長い方は持っていないよ。自分のは mini だよ。mini の方も欲しいなぁといった声が聞こえてきました。

という訳で CLOVA mini の方も開けてみたのですが、ラズパイが入るサイズではありませんでした。という訳で NanoPi という Linux系の超小型ボード(ubuntuベース) で基板を作り直すことになりました。
音声回路も含めてコネクターの形状はもちろん LED やスイッチ等も構成が全く違うので、全て位置から設計のやり直しでした。
こちらの方も、最終基板とソフトの方の検証まで出来ているのですが、まだ記事を作成できていません。（出来たら更新します）

# そしてコンテストに挑戦

いつも参加している[ヒーローズリーグ](https://heroes-league.net/)というコンテストに応募しました。

詳細は▼こちら。
[サービス終了になった LINE CLOVA 達に第二の人生を歩ませる](https://protopedia.net/prototype/3761)

結果部門賞２つ、個人賞２ついただけました。
[ヒーローズリーグ2023](https://protopedia.net/event/hl2023)
評価コメントを見ていると、サービス終了になったハードを何としてでも復活させようという執念と、流行りの Chat GPT をうまく組み合わせて、AIスピーカーとして生まれ変わらせるところまで完成させたところが評価されたようです。

# LINE APIを使っていない⁉

で、振り返ってみると、LINE API が一切出てこない記事になってしまっています。
LINE DC に出禁なったらどうしようという感じではあります…
とはいえ、一応ラズパイが入っているので LINE Messaging API を使う事もできます。一応 LINEメッセージの送受信が出来るところまでは検証出来ていますが、ソフトの整備はまだ出来ていない感じです。

# さいごに

今年は主にハードの改造が主になってしまいました。ソフトの方もαテスト版レベルです。実は基板を配布していて、ソフトの方も githubで公開しているので、何人か使おうとしてくださっている方はいるのですが、ソフトのアップデートが追いついていなくて申し訳ないです。来年こそは mini の記事の公開、ソフトの整備を真剣にやっていこうと思っています。
チャットGPTについて考えた

# 0.はじめに
本記事は エーピーコミュニケーションズ Advent Calendar 2023 20日目の記事です。
https://qiita.com/advent-calendar/2023/ap-com

私自身は、2度目の投稿になります。（前回は2022アドベントカレンダー）
本記事は、筆者が調べた内容であり、独断と偏見が入っている場合がありますので、ご注意ください。

# 1.歴史
チャットGPTは、2022年11月30日にリリース開始して、約1年が経ちました。
サービス開始当初から名前を聞くことも多く、世界中が注目していたといっても過言ではありません。
国が使用を禁止しているところもあります。

また、同様の対話型AIサービスも開始されましたが、現状はチャットGPTがダントツ1位といった状況です。
チャットGPTを題材とした記事や著書も多く存在し、まだまだ目が離せません。

# 2.チャットGPTの得意なところ
これだけ注目されているチャットGPTで、企業で利用しているところもあるようですが、実は、得意分野と不得意分野が存在します。

## 2-1.簡単に始められる
・手軽に始められるため、とっつきやすい。
　複雑なことをするのでなければ、アカウント登録すればすぐに使用可能
　（アカウント登録方法や設定はネットで検索願います。）

　と思っていたら、サービス開始当初から数か月の間は無料枠があったようですが。
　今は、実際に使おうとすると、API費用の支払いが必要でした、、、クレジットカードの登録と、初期費用として１０ドル（今後上がる？）必要とのこと。
![APIキー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/bd815281-ebc0-bdfd-fc8b-fedae9bf5ba8.png)
　ここまでは進められるけど、課金していないと、APIがエラーを返すそうです。

　また、１０ドル固定ということではなく、今は「1000トークンあたり0.002ドル」だそうです。これを使い切ったらさらに課金が必要になる。

・PCにインストールして、何か作ろうとしたら課金が必要。だった。
・スマホにChatGPTをインストールしたら簡単に使えました。最初は５ドル無料で使わせてくれるらしい！！

## 2-2.文章の自動生成が得意
・詩やブログ記事等の元となる文を作成することができる。
　ChatGPT 3.5で試してみた。
![Screenshot_20231231_223609_ChatGPT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/d4fe19e2-a296-69c3-9479-71079312144a.jpeg)
　思った以上に簡単に使えた！少し感動（IT系の人間かよ？ｗ）


# 3.チャットGPTの問題点
・前述では、良いところばかりに見えるチャットGPTですが、そんなAIにも実は問題点があるようだ。

## 3-1.しれっと嘘をつく
・誤った情報を伝えることがある
　とある中学生が授業で使った時のお話で、某県の特産品を間違えたという。
　これは、自身の持っているデータベースやインターネットから情報を取ってくることが原因で、その内容が正しいという検証がされないからだそうだ。

・試しに地元のことを聞いてみた。
![Screenshot_20231231_223636_ChatGPT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/fb771e3d-124c-d88b-53cf-287903b09b59.jpeg)
　うどんは香川ですし、これは間違ってますね。
　それ以外は、新鮮な魚介類、今治タオル、今治城、しまなみ海道サイクリング。すべて正解！大体のところはあってるけど、一部間違ってますね。残念。。


## 3-2.何が問題か
・チャットGPTの答えを鵜呑みにすると危険
　これはインターネット上で言われていることが全て事実ではないということにも類似する。
　大体のことは、間違っていない情報を伝えてくれるのだろうが、その内容は最新になっていない場合がある。
　昨今、インターネットで調べれば大体のことがわかる時代ですが、ニュース記事であったり、ブログの情報にも間違いはあるためである。（こちらはチャットGPTに限ったお話ではないが）

# 4.仕事にどう活かせるか
・ここまで1年間使われてきた実績や経験から、チャットGPTについて考えたが、我々の仕事ではどのように活かせるのか。（以下を実施する場合は、課金だけでなく、情報入力が必要）

## 案1：対話型適正部署診断
・その名の通り、対話をしていく中で、質問と会話を繰り返し、社内部署のどの部署が合いそうか（あくまで指標）を見つけ出す機能はどうか。
　イメージとしては、年齢、職歴、保有資格、等を入力すると、ここが向いている？ということを教えてくれる。
　⇒パターン入力や、情報入力が大変そう。
　⇒性格のあうあわないまでは診断できない。
　⇒１会社で実行するには、データ量が足りなすぎると思われる。

## 案2：対話型適正職診断
・案1とかぶってくるかもしれないが、こちらは社内に限らず、IT系で働く人に対して問答(会話)を繰り返し、その人が一番合うと思われる職種を教えてくれる機能はどうか。
　⇒結局案１と同じでデータが足りない。


# 5.最後に
・今回は簡単に使ってみたり、今更だけどチャットＧＰＴを使ってみたりしました！今後、仕事をするうえで、業務を行うためのツールとして使うこともあるのでしょうか。

・最後の試しに、Pythonを学習したい人だとこんな質問もあるのかなと試してみた。
![Screenshot_20231231_224639_ChatGPT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988431/ac59031b-8267-9f00-c4fd-78c2c316de32.jpeg)
　文字化けしてしまったけど、サンプルプログラムが表示されている。
　もっと難しいことにも対応できるのなら凄く使えるのかもしれない・・・。
　ほんと、大部分で人がいらなくなるのではないか。。
　と少しの不安を覚えながら、２０２４年を迎えようと思います。
Raspberry Piを用いてカーテンを動かしてみた

こんにちは、皆さんは家にIoTを導入されておりますでしょうか。
本投稿では、Raspberry Pi 4とステッピングモータを用いてカーテンを動かすまでをご紹介したいと思います。

具体的に実施した事項は下記画像の通りです。
Raspberry PiにNode-REDを入れ、Node-RED上でAPIサーバを立てます。APIサーバへのデータ入力についてはスマホアプリ(PCも可)から実施し、モータを回転させてカーテンを動かしています。同時にIoTクラウド(NTTコム提供のThings Cloud)にもデータを送ることでクラウドログに記録しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663352/09fae941-1fa1-6837-7630-3269927d7aa2.png)

今回使用した機器は、
・Raspberry Pi 4
・モータドライバL298N(Amazon)
・ステッピングモータ(Amazon)
です。


構造としては下記画像のように、回転させたい向きのアプリ上のボタンを押すことでAPIをたたき、ステッピングモータを指定した向きに回転させています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663352/9ddd6b19-d39c-4b6e-15bc-256efff69b65.png)

Node-REDフローは下記の通りです。スマートフォンアプリ上で指定した回転向きに対応する入力フローに入り、pythonファイルを読み込み可能なexecフローを使用しGithubプログラムを動かし、http通信ノードによってモータを回転させています。templeteノードは、IoTクラウドへの送信データ用、s/usノードはIoTクラウド(Things Cloud)へのMQTT通信用です。（本投稿ではThings Cloudに関する内容は対象外としたいと思います。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663352/2aa5792f-8016-4486-74a1-03c60d632467.png)

具体的なコードは、下記サイトを参考にしています。
・https://qiita.com/zoo_dj/items/0c7f632967e266bac64a
・https://github.com/gavinlyonsrepo/RpiMotorLib（上記Qiita記事内で紹介）

これらのプログラムをRaspberry Pi, Node-REDフローに書き込むことによって、アプリ上で指定した向きにステッピングモータを回転させることができ、釣り糸で引っ張ることでカーテンを動かすことが可能になりました。

今後は、APIサーバとなるRaspberry PiとIoT ReceiverとなるRaspberry Pi PicoをBluetoothなどの無線で繋ぎ、カーテン側のデバイスの縮小化を図っていきたいです。また、現在ローカルネットワーク内を想定したシステム構成だったので、インターネットを通した制御を可能にしたいと思っています。

今回の記事がQiitaへの初めての投稿になりました。先日のIoTLT(2023/12/26開催)で初登壇をした際、IoTLTのアドベントカレンダーへのコントリビューションということで背中を押してくださいました。いつもQiitaには閲覧のみでお世話になっていましたので、背中を押していただき感謝を申し上げたいと思います。
Erlangのコンパイルオプション/パラメータをまとめて確認したい

# はじめに

Erlangには大量のコンパイルオプション/パラメータがあります。ErlangVMのチューニングや細かいセッティングをする際には、これらのオプションが重要になってきます。

ただ、どの様なオプションや環境変数があるのかについてまとまったドキュメントは[公式のドキュメント](https://www.erlang.org/doc/installation_guide/install)くらいしかありません。

もし手元にErlangのソースコードがあれば、configureからオプションやパラメータをまとめて出力できるので、いざという時のために覚えておくと良いでしょう。

# 確認コマンド

Erlangの[ソースコード](https://github.com/erlang/otp)をgit cloneして、[configure](https://github.com/erlang/otp/blob/master/configure)を以下の様にhelp指定で実行してみてください。

```
./configure --help=r
〜略(各パッケージのオプション/パラメータなど)〜
```

また、特定のパッケージに関するオプションを確認したい場合は、以下のディレクトリに入ってから`configure --help`すれば、そのパッケージに関するヘルプ（とオプション)が確認できます。

* [erts](https://github.com/erlang/otp/tree/master/erts)
* [lib/common_test](https://github.com/erlang/otp/tree/master/lib/common_test)
* [lib/crypt](https://github.com/erlang/otp/tree/master/lib/crypto)
* [lib/megaco](https://github.com/erlang/otp/tree/master/lib/megaco)
* [lib/odbc](https://github.com/erlang/otp/tree/master/lib/odbc)
* [lib/snmp](https://github.com/erlang/otp/tree/master/lib/snmp)
* [lib//wx](https://github.com/erlang/otp/tree/master/lib/wx)

例えば、wxに関するオプションを確認したい場合は、`lib/wx`にはいってから、`configure --help`すればOKです。

```
$ cd lib/wx
$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

〜略〜

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data 

〜略〜

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  CPP         C preprocessor

〜略〜
$
```

# まとめ

ビルド時のパラメータや環境変数、オプションを知りたい場合は、この方法を知っておくと確認が簡単にできます。
取得したページネーション内のデータを逆順で表示したい

### 取得したページネーション内のデータを逆順で表示したい

ページネーションしたデータの、中身を逆に表示したいとき、つまり下を最新のチャット、上を古いチャットにしたい時の方法です。

```ChatController.php
$chats = Chat::where('channel', $chid)
        ->orderBy('created_at', 'desc')
        ->paginate(10); // 1ページあたり10件のメッセージを表示
```
これでデータを取得してBladeに渡します。

bladeでは表示の際に、

```chat.blade.php
@foreach ($chats->reverse() as $chat)
    <!-- ここにチャットメッセージの表示ロジックを記述 -->
@endforeach
```

foreachの中でreverseをするのですね。

#### よく考えると、、
ただよく考えると、foreachの中で$chatを上に追加していけばいいのかと。

参考：ChatGPT
Tytan SDKは使いやすい上に量子コンピュータの勉強の取っ掛かりに最適なシミュレーターか？？

この記事は[量子コンピュータ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/quantum) 25日目の投稿です。

# 概要
Tytan SDKという量子シミュレーターについてまだ1報も記事が投稿されていないようなのでこれを記念すべき最初の記事に。

# 事の起こり
これまで勉強しようと思い、専門書を手に取るも挫折するということを数回繰り返した量子コンピュータ。まだまだ実用化は先の話と言われつつ、量子機械学習なる技術も出てきており、機械学習と関わりも。。。筆者としては理解したいと思いつつ、重ね合わせぐらいの所で沈黙してしまうという現状を何とか脱したいと切に願っていました。そんな時、Tytan SDKというOSSのシミュレーターを用いて組み合わせ最適化問題を解くという6回構成のセミナーに出会いました。そこで、セミナーを受講しつつ、シミュレーターを使ってみることにしました。

# Tytan SDKとは？
公式GitHubより
> 大規模QUBOアニーリングのためのSDKです。QUBOを共通の入力形式とし、複数のサンプラーから選んでアニーリングできます。入力は、数式を記述する方法、QUBO行列を入力する方法、QUBO行列をcsv読み込みする方法があります。結果を自動で多次元配列に変換する機能を搭載。短いコードで確認できます。

https://github.com/tytansdk/tytan

ということで、アニーリング方式(量子コンピュータ)のシミュレーターです。作者の方曰く、他のシミュレータ(blueqat等)とも互換性を考慮して開発されているとのこと。組み合わせ最適化問題を解く為の立式は覚えなければならない部分が少し有りますが、以下のチュートリアルが公開されており、チュートリアルを時ながら覚えることが出来ます。

https://github.com/tytansdk/tytan_tutorial?tab=readme-ov-file

セミナー情報は参考までにCompassのリンクを記載しておきます。

https://jqca2023.connpass.com/

# どうやって量子コンピュータを学ぶか？
一先ず難しい理論、数式は置いておいて、Tytan SDKのチュートリアルに挑戦してから量子コンピュータの専門書を読み直せば、挫折することは避けられるのではと思い、挑戦中です。Tytan SDKに関連した認定試験も有るようです。2023年12月現在合格するまで何度でも(無料で)挑戦できるそうです。

https://www.jqca.org/certificate

# まとめ
本来は検証を終えてから記事を執筆したかったのですが、なかなか時間が取れず、一先ず記事で検証内容を投稿することとし、次回検証結果を述べる方式にしようと思い投稿しました。後、Tytan SDKについての投稿記事がQiitaに無かったので投稿してみたかったという理由も有ります。
２０２３年のニコ生ゲーム制作についての振り返り

# 今年作成したゲーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158551/e35537f5-21b5-fd80-2d05-568cccc948eb.png)

ほぼ月１でゲームをかんせいさせて投稿した自分をまずは褒める！
よっ！偉い！すごい！素晴らしい！

まだ賞は発表されていませんが、自作ゲームフェス2023というイベントに投稿している作品もあります。１つの目標でもあるのでなにかしらの賞がもらえると嬉しいな！

執筆中に気づいたけどqiitaって接続詞も指摘してくれるの良いね。文章考えるの苦手なので勉強になる！

では1つずつ。

# No1:   2023/01/04　【MoveBlock】
このゲームはtiktok見てたときに、こんなゲームがあるんだ～って思って再現したくてやってみました。ブラウザやスタンドアロン的なゲームではなく、体験型？みたいなゲームでした。
評価的には新感覚って言われてたので嬉しかった記憶があります。

# No2:   2023/01/16　【ニアセナスロット２】
パチンコ作りたくて、でも難しそうでスロットならできそうって思い制作に取り掛かりました。
youtubeでワンピースのスロット作ってる人がいて、それを参考にしながらつくりました。
でもリールをまわして画像の判定の表現が難しかったので順番に切り替わるようにして再現しました。

現時点だと別作者さんのスロット「ニャースロ」が素晴らしいですね。
自分もあんなふうに作れるようになりたい。

# No3:   2023/02/06　【天国と地獄】
ニコ生ゲームの逆引きリファレンスを見てるときにSVGファイルってなんだろうって思って、とりあえず使って作ってみよう的な感じでちゃちゃっとつくりました。
読み込みが特殊？だったようで苦戦した記憶があります。
でもドラッグで拡大しながらゲーム画面上で生成するって処理は初めてしたので楽しかったです。

# No4:   2023/03/22　【桜アツメール】
4月に行われるイベントで遊ばれる？みたいな予告があったと思います。
なので配色に特に気をつけて作成しました。当時アツマールが終了告知もあったので、タイトルをそれに交えた感じで命名しました。配信者が選ぶ時間もあって、それに選ばれたときは嬉しかったです！
また同じイベントがあれば選ばれると良いなあ。

# No5:   2023/04/15　【二アセナちゃんは仲直りがしたい】
これは、なぜ作ろうと思ったか正直覚えてません。
でも作成時から頭を使う感じにしようって思って作りました。
結果的に理解するまでが大変かもしれません。
気をつけます。

# No6:   2023/04/17　【２Dでクルーンを作ろうとした結果何故かこうなったゲーム】
犬夜叉のクルーンを再現したくて作成開始しました。
でもうまく行かなかったのでとりあえず運が絡むようにしました。

# No7:   2023/05/03　【メイドはニコニコテレビちゃんを集めたい】
カービィのけんけんレース的なものを作る予定でした。
でも下に飛び越す時の判定が思いつかなかったので縦スクロールのゲームにしました。

# No8:   2023/05/05　【カウントどんどん】
ポケモンスタジアムのピィとププリンのカウントゲーム的なものが作りたかったです。

# No9:   2023/06/17　【早押しゲーム：短時間Ver】
パチンコ演出で簡単に作れそうと思ってゲーム化しました。
集中力が試されるように通常版は制限時間1分でしたが、不評だったため短時間VERを作成しました。
短時間のほうは制限時間20秒です（説明時間もいれると30秒）


# No10:  2023/07/18　【爆弾と花火】
夏イベントが近かったので花火を打ち上げるイメージでつくりました。
正直ゲームより花火に力を入れました。
花火エフェクトはEffekseerで作成し、FrameSpriteで表示しています。
早くなるごとに目が痛くなるとの意見もあったので気をつけます。

# No11:  2023/09/18　【悪マーモ君でポン！】
コイキングのハネルでポンを意識しました。
ジャンプタイミングは難しいかもです。

# No12:  2023/10/03　【悪マーモ君の食べ物大作戦！】
ラッキーのタマゴ大作戦を意識しました。
時間が経過するにつれて画面が見えにくくなります。

# No13:  2023/11/18　【じゃんけんホッケー】
おはじきみたいに弾くやつ作りたいなあっておもいながら作った記憶があります。
じゃんけん＆ホッケーの組み合わせアイデアを運営さんに褒めてもらえたのがすごく嬉しかったです！
ユーザーさんに回転する棒がいい味出してるって言われたのも嬉しかったです。

# No14:  2023/12/16　【悪マーモランナー】
昔あったウィンドランナーを作りたかったです。似ても似つかないけど自分的にはお気に入りの作品です。アイテム（クリスタル）は3DモデルをBlenderで作成し、EffekseerでアニメーションさせてFrameSpriteで表示して疑似3Dみたいな表現をさせています。

# No15:  2023/12/22　【メイドの飾り付け】
クリスマスなので、釣りっクリスマスや、クリスマス釣り～みたいなタイトルだったんですが、
時間がなくてこうなりました。

# No16:  2023/12/30　【マーモ玉ゲーム】
レトロゲームを動画でたまたま見た際に再現できそうってなったので作りました。
やはり、途中が難しいらしいので難易度を下げるかもしれません

# No17:  2023/12/31　【BONNOU108】
本日12/31になにか作りたくておもいついたのが108の煩悩を消すってことで作り始めました。
マウスジョイントを多分初めて使いましたが、まだ良く理解できてません。がんばります。

# 今年良かったこと

たぶんメイドの飾りつけ？くらいからTypeScriptを使うようになりました。
いままでjavascriptでやってたんですが、VSCODE上でエラーが先にわかるのは便利ですね。

ただES5やES2015？などで困ることがあります。今のところクイックフィックス　か　BingAi君に相談して解決してます。AIって便利ですね！

でも一番はニコ生ゲーム制作の運営さんと関われるようになったことですね。
運営さんにも助けてもらっていますし、ユーザーさんにも助けてもらっています。

ニコ生ゲームの交流サーバーなど貴重なスペースを用意してくださりとても感謝しています。

来年もゲーム制作含め、クリエイター活動を頑張ってまいりますのでよろしくお願い致します！


楽曲収益化サービスの四半期報告そろそろくるかなあ？
GitHubに1年毎日草生やせなかった


# はじめに

[こちらの](https://zenn.dev/keisuke90/articles/7585bcd4dcedfc)記事に感化されて 2023 年 1 月 1 日から毎日 GitHub に草を生やそうと頑張っていました。
ルールはゆるく、プログラミング以外にも学んだことなどのメモも ok にして行いましたが、結果から言うと 9 割ほどしか草を生やせませんでした。

![github-kusa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/194fd6ae-5172-5dc4-a0d1-aaf727d8f9f0.png)

## なぜ 9 割ほどしか達成できなかったのか?

4 月 7 日なぜか commit できておらず、草をはやし忘れました。
ここからガタッと崩れた感じがあります。

毎日草はやしが達成されなくなったので

- 体調が悪かったらしょうがない
- 飲み会で遅くなったからしょうがない
- 旅行だからしょうがない

などなどの言い訳が正当化されいくつかの日も達成できなかったと思います。。。

## 反省点

草を生やすこと自体が目的になっていました。
例えば以下のように本当に意味がある草はやしだったのかどうかが怪しい日もあり、本当に草を生やすことだけが目的になってしまっていたな〜と思います。

- 今日の学びを 1 行書いただけ
- ファイルを新規作成しただけ
- 簡単な修正をするだけ

また、技術力の向上や転職活動のアピールなど明確な目的があれば、4 月 7 日のミスだけで済んでいたのかもしれませんが、草はやし自体が目的だったため、1 日できなかっただけでガタッと崩れてしまったのかと思います。

## よかったこと

### 学んだことをメモ化する癖がついた

前までは学んだことメモすることは少なかったのですが、草を生やすためにメモ化することが増えました。
メモ化することで、いつどこからでも情報を読み直せることは大きな恩恵と感じました。
また、インプットした後に自分の言葉で書き直すことの強力さも知ることができました。

### プログラミングは。。。

いくつかのツールを書きましたが、書くのが上手くなったかはわからないです。。。
書籍を参考に TDD や関数型の考え方などを取り入れるなど実践してきて、スキルアップを感じたことも多いですが、
「草をはやし続けたからプログラミングがよくなった」という感じではないのでなんとも言えないかなと思っています。。。

### 何かの制約や強制に自分が弱いことがわかった

これは資格勉強などでも感じることなのですが、するべきこと(草はやしや資格勉強など)とやりたいこと(読書、技術調査など)があると

- やりたいことが気になってするべきことができない
- するべきことが頭の中にあるのでやりたいことがやりにくい

という勿体無いジレンマに陥ってしまうことがわかりました。
これは単純に私が甘いだけかもしれませんが、何も手につかないというのは本末転倒なので、今後の自主活動は基本的にやりたいことをやる！がいいのかなと思える様になりました。
(もちろん業務等では気持ちよりも優先順位が重要です！笑)

## 来年は？

多分意識して草はやしをやることはないと思います。
毎日草を生やすことより、読書や技術捜査などやりたいことが出てくると思うからです。
毎日技術に触れていくつもりですが、その達成方法は本当に自分がやりたいことじゃないと難しいとわかりました。
ただ、毎日の取り組みでスキルアップしているかどうかはわかっておくべきなので、やったことの記録や qiita などへのアウトプットをしていって、自分がスキルアップしてるのかしてないのかを測定できればと思います。
Kafkaとkafka-uiをMinikubeで動かしてみる

# TL;DR

Kafkaとkafka-uiをMinikubeで動かしてみました。
この記事では実際にKafkaとkafka-uiが動くまでの過程について記載します。

GitHub: https://github.com/cacapouh/kafka-ui-k8s

# Minikubeを起動

[Strimziというツールを動かす](https://strimzi.io/quickstarts/)関係で、
起動時にメモリ割り当てを4GB以上にして起動する必要がありました。
因みにですが、Minikubeのデフォルトのメモリ割り当ては2GBです。

```
minikube start --memory=4096
```

# Strimziのデプロイ

Kafkaをk8sにデプロイするためにStrimziというツールを使います。

そのため、まずStrimziをデプロイする必要がありますが、
Strimzi側で用意されているマニフェストを単に適用するだけで、デプロイできました。
以下は実際に実行したコマンドになります。

```
kubectl create namespace kafka
kubectl create -f 'https://strimzi.io/install/latest?namespace=kafka' -n kafka
```

## Kafkaクラスタのデプロイ

こちらも同様に、単にStrimziの方で用意されているサンプルのマニフェストファイルを適用するだけで、デプロイできました。

以下、デプロイおよび動作チェック用のコマンドになります。

マニフェスト適用:

```shell
kubectl apply -f https://strimzi.io/examples/latest/kafka/kafka-persistent-single.yaml -n kafka 
```

起動するまで待つ:

```shell
kubectl wait kafka/my-cluster --for=condition=Ready --timeout=300s -n kafka 
```

メッセージの送信:

```
$ kubectl -n kafka run kafka-producer -ti --image=quay.io/strimzi/kafka:0.39.0-kafka-3.6.1 --rm=true --restart=Never -- bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic my-topic
If you don't see a command prompt, try pressing enter.
>Hello strimzi!
>Hoge!
```

メッセージの受信:

```
$ kubectl -n kafka run kafka-consumer -ti --image=quay.io/strimzi/kafka:0.39.0-kafka-3.6.1 --rm=true --restart=Never -- bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic my-topic --from-beginning
If you don't see a command prompt, try pressing enter.
Hello strimzi!
Hoge!
```

# kafka-uiのセットアップ

以下の自作のマニフェストファイルを用いて、kafka-uiをデプロイしました。

https://github.com/cacapouh/kafka-ui-k8s/blob/main/kafka-ui.yml

マニフェスト適用:

```
kubectl apply -n kafka -f kafka-ui.yml
```

ブラウザからアクセス:

```
minikube service kafka-ui-service -n kafka
```

![スクリーンショット 2023-12-31 22.21.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422592/e8a47539-4b1e-f8de-e295-b5e2c00ae312.png)

![スクリーンショット 2023-12-31 22.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422592/398442d9-b129-7306-6ee2-2ea13ba794be.png)

# おわりに

kafka-ui以外は、Strimzi側で用意されているマニフェストファイルを適用するだけでデプロイできました。簡単でしたね :thumbsup:
public, private, protected

# それぞれの違い
## Public
Publicメソッドは、クラスの外部から自由にアクセス可能です。
これらはクラスのインターフェースを形成し、外部のコードから利用されることを意図しています。
Rubyでは、クラスで定義されたメソッドはデフォルトでpublicです（ただし、initializeメソッドは例外で、常にprivate）。

## Private
Privateメソッドは、そのクラスのインスタンスからのみアクセスできます。
これらのメソッドは、外部のクラスやサブクラスからは直接呼び出すことができません。
Privateメソッドは、レシーバを指定せずに呼び出す必要があります。つまり、selfを明示的に使用してはいけません。
これは、クラスの内部実装の詳細を隠蔽し、外部からの不要な干渉を防ぐために使用されます。

## Protected
Protectedメソッドは、同じクラスまたはサブクラスのインスタンスからアクセスできます。
これらは、外部のクラスからは直接アクセスできませんが、同じクラスまたはサブクラス内の他のインスタンスからはアクセス可能です。
Protectedメソッドは、特に比較操作など、インスタンス間での情報の共有が必要な場合に役立ちます。

# コードによる違い
```ruby
class MyClass
  # Publicメソッド
  def public_method
    'This is a public method'
  end

  # Privateメソッドを定義
  private
  def private_method
    'This is a private method'
  end

  # Protectedメソッドを定義
  protected
  def protected_method
    'This is a protected method'
  end
end

# クラスのインスタンスを作成
instance = MyClass.new

# Publicメソッドの呼び出し
puts instance.public_method # => "This is a public method"

# Privateメソッドの呼び出しを試みる（エラーが発生するはず）
begin
  puts instance.private_method
rescue => e
  puts e.message # => "private method `private_method' called for #<MyClass:0x0000>"
end

# Protectedメソッドの呼び出しを試みる（エラーが発生するはず）
begin
  puts instance.protected_method
rescue => e
  puts e.message # => "protected method `protected_method' called for #<MyClass:0x0000>"
end
```
Reactでコンポーネントのテストを実施する(Step1: Testing Libraryを活用する)

## はじめに
TestingLibraryを用いて、Reactのコンポーネントのテストを実施します。

https://testing-library.com/

## 成果物
![countup.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/9ad6c02f-b0be-3481-f86b-71e336ef934e.gif)
今回はよくあるカウントアップをテスト対象とします。

## ソースコード

https://github.com/kouji0705/react_test_library

```shell:ディレクトリ
~/develop/react/react_test_library$ tree -I node_modules 
.
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.tsx
│   ├── components
│   │   ├── Counter.test.tsx　←テストコード
│   │   └── Counter.tsx   ←テスト対象
│   ├── index.tsx
│   ├── logo.svg
│   ├── react-app-env.d.ts
│   └── setupTests.ts
├── tsconfig.json
└── yarn.lock

4 directories, 17 files
```

### プロダクトコード

```tsx:src/App.tsx
import React from 'react';
import Counter from './components/Counter'

function App() {
  return (
    <Counter />
  );
}

export default App;
```

```tsx:src/components/Counter.tsx
import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>カウントアップ</button>
    </div>
  );
};

export default Counter;
```

### テストコード

```tsx:src/components/Counter.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

describe('Counter コンポーネント', () => {
  test('初期状態でカウントは0である', () => {
    render(<Counter />);
    expect(screen.getByText('0')).toBeInTheDocument();
  });

  test('ボタンをクリックするとカウントが1増加する', () => {
    render(<Counter />);
    fireEvent.click(screen.getByText('カウントアップ'));
    expect(screen.getByText('1')).toBeInTheDocument();
  });
});

```

### テスト実行
```shell:テスト実行
~/develop/react/react_test_library$ yarn test Counter
 PASS  src/components/Counter.test.tsx
  Counter コンポーネント
    ✓ 初期状態でカウントは0である (14 ms)
    ✓ ボタンをクリックするとカウントが1増加する (5 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.387 s, estimated 1 s
Ran all test suites matching /Counter/i.

Active Filters: filename /Counter/
 › Press c to clear filters.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press o to only run tests related to changed files.
 › Press q to quit watch mode.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press Enter to trigger a test run.
```
依存関係逆転の原則

依存関係逆転の原則（Dependency Inversion Principle、DIP）は、ソフトウェア設計の原則の一つ。高レベルモジュールが低レベルモジュールに直接依存しないように設計することを意味する。代わりに、両方が抽象化に依存する。これにより、モジュール間の結合が緩やかになり、保守性や拡張性が向上する。

```ruby:依存関係逆転の原則を使用していない
class EmailService
  def send_email(user_email)
    # 電子メール送信の実装
  end
end

class UserAuthentication
  def initialize(user_email)
    @user_email = user_email
    @email_service = EmailService.new
  end

  def authenticate
    # 認証ロジック
    email_service.send_email(@user_email)
  end
end
```

```ruby:依存関係逆転の原則を使用
# インターフェース
module EmailNotifier
  def send_email(user_email)
    raise NotImplementedError, "send_email must be implemented"
  end
end

# 具体的な実装
class EmailService
  include EmailNotifier

  def send_email(user_email)
    # 電子メール送信の実装
  end
end

class UserAuthentication
  def initialize(user_email, email_service)
    @user_email = user_email
    @email_service = email_service
  end

  def authenticate
    # 認証ロジック
    email_service.send_email(@user_email)
  end
end

# 使い方
email_service = EmailService.new
authenticator = UserAuthentication.new("user@example.com", email_service)
authenticator.authenticate
```
インターフェイス分離の原則

インターフェイス分離の原則（Interface Segregation Principle, ISP）は、ソフトウェア設計の原則の一つで、SOLID原則の一部である。この原則は、「クライアントは使用しないメソッドに依存するべきではない」という考え方に基づいている。つまり、大きくて汎用的なインターフェイスよりも、小さくて特定のクライアントに特化したインターフェイスを設計するべきであるという原則です。

```ruby:違反している
class DocumentGenerator
  def generate_pdf
    # PDFドキュメント生成のロジック
  end

  def generate_word
    # Wordドキュメント生成のロジック
  end

  # 他のドキュメントタイプの生成メソッドもここに含まれる
end

```
違反理由
DocumentGeneratorクラスにgenerate_pdfとgenerate_word というメソッドが両方とも含まれている場合、特定のレポート（例えばPDFレポート）にのみ関心があるクライアントが Report クラスのインスタンスを使用するとき、そのクライアントは理論上、generate_word という使用しないメソッドにも間接的に依存することになります。

```ruby:遵守している
module DocumentGenerator
  class PdfDocument
    def generate
      # PDFドキュメント生成のロジック
    end
  end

  class WordDocument
    def generate
      # Wordドキュメント生成のロジック
    end
  end

  # 他のドキュメントタイプも同様に定義
end
```
PdfDocumentはpdfの生成にのみ関心があるクラスである
リスコフの置換原則

# リスコフの置換原則とは？
リスコフの置換原則（Liskov Substitution Principle, LSP）は、オブジェクト指向プログラミングにおける重要な原則の一つで、サブクラスはいつでもそのスーパークラスの代わりとして使用できるべきであるという規範のこと。これは、サブクラスがスーパークラスの契約を変更しないようにすることを意味する。

```ruby:リスコフの置換原則を使用した例
# 基底クラスの作成
class Payment
  # このメソッドはすべての支払い方法で共通です。
  # 各支払い方法はこのメソッドを実装する必要があります。
  def process
    raise NotImplementedError, "process method must be implemented"
  end
end

# サブクラスの作成
class CreditCardPayment < Payment
  def process
    # クレジットカードでの支払い処理のロジック
    "Processing credit card payment..."
  end
end

class PaypalPayment < Payment
  def process
    # PayPalでの支払い処理のロジック
    "Processing PayPal payment..."
  end
end

# LSPの適用
def process_payment(payment)
  # このメソッドはPaymentクラスのインスタンスを受け取りますが、
  # 実際にはそのサブクラスのインスタンスが来ることを期待しています。
  puts payment.process
end

# クレジットカード支払いのインスタンスを作成して処理
credit_card_payment = CreditCardPayment.new
process_payment(credit_card_payment)

# PayPal支払いのインスタンスを作成して処理
paypal_payment = PaypalPayment.new
process_payment(paypal_payment)
```

# 継承とリスコフの置換原則はどう違うの？

継承はプログラミング言語の機能です。これを使用して、新しいクラス（サブクラス）が既存のクラス（スーパークラス）の特性を継承し、拡張することができます。

リスコフの置換原則は、継承を使用する際の設計原則の一つです。これは、サブクラスがスーパークラスの完全な置換として機能するべきであるという原則を表しています。LSPは、オブジェクト指向設計における「良い」または「適切な」継承の方法をガイドします。

要するに、継承は「何ができるか」を提供し、LSPは「どうやるべきか」を指導します。LSPは継承の機能を拡張または制限するものではなく、継承を使用して安定的で保守しやすいソフトウェアを設計するための原則を提供します。
オープン・クローズドの原則

# 概要
オープン・クローズドの原則の定義は「拡張に対して開かれているべきであり、変更に対しては閉じているべき」と、よくそのように言われます。

しかし、一見すると主語が書いてないので、拡張も変更も同じ主語を持つとした場合、矛盾してしまいます。

これは厳密にいうと、既存のコードの変更に対しては閉じているべき(=変更せずにいられるべき)で、拡張に対して開かれているべき(=新機能の追加をしやすくあるべき)である。つまり、既存のコードを変更せずに、新しい機能を追加できるような設計が望ましいということです。

# つまり、どういうことだってばよ？
## ダックタイピングで実装した例
```ruby:オープン・クローズドの原則に違反した実装（変更に閉じていない）
class PaymentProcessor
  def process_payment(payment_type, amount)
    case payment_type
    when :credit_card
      # クレジットカードでの支払い処理
    when :paypal
      # PayPalでの支払い処理
    # 他の支払い方法が追加されたら、ここにコードを追加する必要がある
    end
  end
end
```

```ruby:オープン・クローズドの原則を遵守した実装
class PaymentProcessor
  def process_payment(payment_processor, amount)
    payment_processor.process(amount)
  end
end

class CreditCardPayment
  def process(amount)
    # クレジットカードでの支払い処理
  end
end

class PayPalPayment
  def process(amount)
    # PayPalでの支払い処理
  end
end

# 他の支払い方法が追加されたら、新しくクラスを追加すればいい
# 他の支払い方法が追加されても、process_paymentは変更する必要がない
```
単一責任の原則

# 1. 序論
## 単一責任の原則とは？
Wikipediaによると
> 単一責任の原則 (たんいつせきにんのげんそく、英: single-responsibility principle) は、プログラミングに関する原則であり、モジュール、クラスまたは関数は、単一の機能について責任を持ち、その機能をカプセル化するべきであるという原則である。モジュール、クラスまたは関数が提供するサービスは、その責任と一致している必要がある。

単一責任の原則の説明としてよく用いられる例が十徳ナイフなので、十徳ナイフを用いて単一責任の原則の説明を行う。

十徳ナイフ
![166003020_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270132/298d5f48-d910-20c3-3c7d-2da83d89b37f.jpeg)


十徳ナイフはナイフに缶切り、マイナスドライバーに栓抜きと、多機能に展開されている。これをソフトウェア設計の視点で見ると、十徳ナイフという1つのオブジェクトに対して責任(=役割)が複数存在することになる。これはソフトウェア設計上望ましくない。

単一責任の原則として見たときは、以下の画像のように、1つのオブジェクトに対して責任(=役割)が1つのみというのが望ましい。

![202301271305_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270132/bc941de7-8178-061a-55dc-7c631141da67.jpeg)

## なぜ十徳ナイフだと良くないの？

### 1. 理解の難しさ（可読性の低下)
複数の機能を一つのクラスやモジュールに詰め込むと、そのコードを理解するのが難しくなる。新しい開発者がそのコードを見たとき、どの機能がどのように実装され、互いにどのように影響し合っているのかを把握するのが困難になるため。

### 2. 保守の複雑化
「十徳ナイフ」型のクラスやモジュールでは、一つの機能に変更を加えることが他の機能に予期せぬ影響を及ぼす可能性がある。これはバグを引き起こすリスクを高め、保守作業をより複雑にするため。

### 3. 再利用性の低下
単一責任の原則に反する設計では、再利用性が低下します。例えば、ある機能を別のプロジェクトで再利用したい場合に、不要な依存関係や余計な機能が組み込まれているために再利用が困難になるため。

### 4. テストの難易度増加
複数の機能が一つに組み込まれていると、それぞれを個別にテストすることが困難になります。単一の変更が複数の機能に影響を与える可能性があり、テストの複雑さが増すため。テストを書くのが億劫になる理由の1つでもある。

### 5. 拡張性の問題
システムが成長し、新しい機能が必要になった場合、既存の「十徳ナイフ」型の設計に新しい機能を追加することは困難である。これは、新しい要件を満たすためには大規模なリファクタリングが必要になることを意味する。

## ソースコードで学ぶ単一責任の原則
```ruby:単一責務の原則に違反(十徳ナイフ)
class User < ApplicationRecord
  # ユーザーを保存した後、ウェルカムメールを送信
  after_create :send_welcome_email

  private

  def send_welcome_email
    # メール送信のロジック
    # 例: ActionMailerを直接呼び出してメールを送信
    ActionMailer::Base.mail(from: "noreply@example.com", to: self.email, subject: "Welcome!", body: "Welcome to our platform!").deliver_now
  end
end
```


```ruby:単一責務の原則を遵守
# app/models/user.rb
# Userモデルはユーザー情報の責任を持つ。
class User < ApplicationRecord
end


# app/mailers/user_mailer.rb
# UserMailerはメール送信の責任を持つ。RailsのActionMailerを使用して、メール関連のロジックをカプセル化する。
class UserMailer < ApplicationMailer
  def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome to Our App')
  end
end


# app/controllers/users_controller.rb
# UsersControllerでは、UserモデルやUserMailerの橋渡しをしている。
class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      UserMailer.welcome_email(@user).deliver_later
      redirect_to @user, notice: 'User was successfully created.'
    else
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
```
既存のGASプロジェクトをローカル環境でも管理する

# 記事概要
既存のGASプロジェクトをローカル環境に持ってきて、VScode等でファイルを編集したり、Gitで管理等する。

# 方法
claspというnodeのパッケージを利用する。

- ➀ インストール
    ```shell
    npm install -g @google/clasp
    ```
- ➁ ログイン
    ```shell
    clasp login
    ```
    ※認証が求められる
- ➂ clone
    ```shell
    clasp clone "スクリプト ID"
    ```
    ※プロジェクトの設定から、スクリプトIDを取得<br/>
    ![2023-12-31_22h10_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184925/64da8855-20b2-b206-74eb-4312ba565bfb.png)

# ☆ソースを変更した時
- ローカルのソースを変更
    pushして、クラウドのソースを変更
    ```shell
    clasp push
    ```
- クラウドのソースを変更
    pullして、ローカルのソースを変更
    ```shell
    clasp pull
    ```

# 参考
<a href="https://github.com/google/clasp" target="_blank">https://github.com/google/clasp</a>
金子勇とWinnyの夢を見た 目次

2023年のアドベントカレンダーで作成した『金子勇とWinnyの夢を見た』の目次です。

|No.|題名|
|--:|--|
1|[はじめに](https://note.com/fukuy/n/ne1f8d04c1896)
2|[経歴　その１](https://note.com/fukuy/n/nddcc047aa4d5)
3|[経歴　その２](https://note.com/fukuy/n/n8173d6880326)
4|[経歴　その３](https://note.com/fukuy/n/nbd16eb3218a9)
5|[経歴　その４](https://note.com/fukuy/n/n93f70350b55f)
6|[経歴　その５](https://note.com/fukuy/n/n39e045c74897)
7|[フリーソフト](https://note.com/fukuy/n/nfca21224eedc)
8|[ファイル共有ソフト](https://note.com/fukuy/n/n6670b0970482)
9|[Winnyの技術](https://note.com/fukuy/n/n0c2b637f5f7a)
10|[裁判　その１](https://note.com/fukuy/n/na7d925eb905d)
11|[裁判　その２](https://note.com/fukuy/n/n12cd5148ebf4)
12|[裁判　その３](https://note.com/fukuy/n/ndd6786eab0a9)
13|[裁判　その４](https://note.com/fukuy/n/n6ec9b0039a1e)
14|[裁判　その５](https://note.com/fukuy/n/nfe3062065914)
15|[サイバー犯罪対策課](https://note.com/fukuy/n/ne00f401da51c)
16|[未踏](https://note.com/fukuy/n/na8d77ef3e5a0)
17|[登大遊とSoftEather](https://note.com/fukuy/n/nc87304737adf)
18|[デジタル・コンテンツ](https://note.com/fukuy/n/n33466be80758)
19|[デジタル・コンテンツ](https://note.com/fukuy/n/nea8fdd64aa28)
20|[杉浦隆幸とネットエージェント](https://note.com/fukuy/n/n0d4ec7793db3)
21|[ＩＣＴ研究と開発への影響](https://note.com/fukuy/n/ncc0a7203a07b)
22|[清水亮と第参回天下一カウボーイ大会](https://note.com/fukuy/n/ndbefb3e21b2d)
23|[経歴　その６](https://note.com/fukuy/n/n0694ed8f9c38)
24|[Skeed](https://note.com/fukuy/n/nec75839260e8)
25|[おわりに](https://note.com/fukuy/n/n10c649c3464c)
Erlangのビルドを速くしたい

# はじめに

Erlangをビルドする際に「すごい時間がかかる・・・」と思ったことはありませんか？
Erlangにはビルドを高速にするためのいくつかのオプションがあるのでそれについて紹介します。

# 並列化による高速化

Erlangをビルドする際の、configureとmakeの実行は、環境変数`MAKEFLAGS`を指定する事で並列化する事ができます。
例えば、4コア（もしくはハイパースレッドによる4並列)のマシンの場合、

`MAKEFLAGS=-j4`

とする事でconfigureとmakeを並列実行する事ができ、ビルドを高速化できます。

# コンパイルサーバーによる高速化

標準ライブラリやOTPはErlangのプログラムで実装されているので、当然Erlangのビルドの際にはErlangのコンパイルが実行されます。ErlangのコンパイラはErlangで実装されているので、コンパイルが実行されるたびに、Erlangのシステムが起動されます。この時、[コンパイルサーバー](https://www.erlang.org/doc/man/erlc.html#compile-server)を利用する事で、コンパイル対象のファイルごとにErlangシステムを起動する事が不要になるのでErlangプログラムのコンパイルが高速化されます。

コンパイルサーバーを有効にするには環境変数`ERLC_USE_SERVER`をtrueにしてください。

`ERLC_USE_SERVER=true`

# まとめ

Erlangのビルドを高速化するTIPSを紹介しました。
asdf等で複数のバージョンのErlangを扱う場合には入れておく事で、ビルドが時短されるかもしれません。
興味本位で大学院の授業潜ったらボコボコにされた話

## はじめに
情報系の学科で学部１年をしていますminです。クリスマスも終わり、仕事（バイト）納めも終わったということでためにためたアドベントカレンダーを書いていきます。ほんとそういうとこだよ私って毎回思う。無理なスケジュールは立てるなよな。

## ボコボコにされた経緯
大学の先生が「機械学習と音楽生成に関する授業を開講する、希望者がいれば履修対象者でなくても授業を潜ることが出来る」とのお知らせを学科全体に発信しており、私はまんまと引っかかってしまいました。もともと音楽が好きなのもあり、また興味のあることはやるに越したことはないだろうという脳筋の精神から「潜りたい！！」と即レス。ちなみにその授業が大学院のものだったことは後から知りました。ちゃんと先生の文章を読もう。そして自分のキャパを考えようね。

## お前はそこで何を学んだん？
機械学習による音楽生成について学びました。といっても、コードもまともに（いや、まったく）かけない私が学べたことはほとんどありません。また、この授業は水曜日5,6限だったのですが丁度サークルのライブ練習（不定期）と被ってしまいほとんど対面で参加できませんでした､､､なら潜るなよな。
- Googleコラボの使い方
- MIDIファイルの仕様
- MuseScoseの大まかな使い方
- エラーを吐かれることの恐怖
- ほうれん草の重要性
- マウントの仕方

については基本的な知識を得ることができました。（ほんとか？？？）

## ボコボコにされる流れ
そんなこんなで潜っていた私ですが、とうとうやってきました。**最終発表会！！！**
二人一組になって成果物を作ります。テーマは特になし。さあ困った。

## 何を作ったん？？？
なんとか相方は見つかったのですが、なんと相方は当日予定あり。困りました。さあ授業資料を見返します。
>- ソプラノパートが与えられ、アルト・テノール・バスパートを作る
入力：ソプラノ → 出力：アルト・テノール・バス
いわゆるソプラノ課題
これも自動編曲と考えることが多い
>> 第3回授業資料より

お、これは気になる。やってみたい。
「そろそろクリスマスだし、ジングルベルでも作ろう」ということでジングルベルでソプラノ課題に挑戦することにします。

### さあ、ジングルベルのメロディーを用意しよう。
「うーーーーん、とりあえずジングルベルのメロディーは手打ちでいいか」
ということで手打ちしました。機械学習じゃないんかい。

![課題研究-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637943/a5ea6267-a4a5-5517-d2f1-45fc69296e77.png)

カス。あまりにもカスなので音色はかわいいシロフォンにしました。
とりあえずできた。

### ついでに、ピアノロールも出してみよう。

- pretty_midiをインストールします。
``` Python:pretty_midi
!pip install pretty_midi
```

- 次に自分のデバイスからさっきのMIDIファイルを持ってきます。
:::note warn
マウントを忘れない。
:::

``` Python:import pretty_midi
midi = pretty_midi.PrettyMIDI("drive/MyDrive/chorales/midi/000101b_.mid")
notes = midi.instruments[0].notes
print(notes)
```
- ピアノロールを出力
``` Python:import matplotlib.pyplot as plt
pianoroll = midi.get_piano_roll()
plt.matshow(pianoroll[:, 10000:10400])
```

出力されたものがこちら。
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637943/b81bb805-b7fa-10ba-3c1c-60ab2702c1d1.png)
ん？？？？？？？？？
なんでこんなに音が重なっているの？？？？？
多分事故った。おそらくファイルの挿入がうまくいっていない。

### ソプラノ課題をやってみよう
と思ったもののうーーーーーんわからん。ああ困った､､､とここで時間切れ。もう発表するしかありません。さらに、相方は音信不通。とにかく発表スライドを作ります。音信不通なので相方のことをスライドでボコボコにします。

### スライドを作ろう
何とかスライドも作成。

カススライドの一部。

![機械学習.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637943/48d41a25-8c4b-7669-facf-5d75c5e62da6.png)
連絡つかないからってこんなに弄り倒してごめん（あとでちゃんと謝りました）。


![機械学習2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637943/db0768cc-69bc-b0d9-9118-d7eb3f317ba2.png)
うさぎが腹立つ。


![機械学習3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637943/0e140ffd-fd0d-f413-76af-2030728e937c.png)
最終発表にお前の想いはいらない。結果を出しな。


## まとめ
とまあなんとか「できませんでした」を最終発表することができました。本当に良くない。そして、「B1なのによくやった」「逃げなくてえらい」と評価されるまで落ちぶれてしまい情けない。この情けない経験は一生忘れずにしたい。
Shell 「bash」でawsのs3ファイルのサイズ、トータルを抜き出す

## Shellを全く触ったことがない➡理解するようになるまで
今回調べたこと
----

#### ● shellの基礎知識
まず最初にShellとは？は調べたら簡単にたくさんの記事がでてきます。
<h5>オススメ引用元</h5>

https://qiita.com/katsukii/items/383b241209fe96eae6e7
#### ● 引数
<h5>オススメ引用元</h5>

https://qiita.com/kentaro/items/db9944429ef160987b3a
#### ● 絶対パス・相対パス
<h5>オススメ引用元</h5>

https://www.ycomps.co.jp/staffblog/16101
#### ● 配列
<h5>オススメ引用元</h5>

https://syutaku.blog/bash-array/
#### ● 変数
<h5>オススメ引用元</h5>

https://qiita.com/a_yasui/items/ec4f75b300410af8958d
#### ● ループ
<h5>オススメ引用元</h5>

https://qiita.com/tamurashingo@github/items/54b25acc93e37580989d
#### ● 配列とループの併用
<h5>オススメ引用元</h5>

https://qiita.com/ytyng/items/d7afe80ef9da7aa8b721
#### ● 連想配列
<h5>オススメ引用元</h5>

https://qiita.com/YutaSaito1991/items/c7c6bacb916f41ef1471

https://future-architect.github.io/articles/20210401/

引用先は自分自身が調べていて分かりやすかったものになります。
初心者や未経験の方のお力になればと思って載せました。


基礎理解後
---------
<h3>書き始め</h3>

`#!/bin/bash`  【**シバン**】で検索すると意味が調べられます。
```
#sh ./test.sh
```
※必ず `sh` をテキストの前につけないとエラーが出る

➡`./example.sh`はエディターの現在開いているファイルの事
【**絶対パス、相対パスの違い**】
`./`は省いている部分【**相対パス**】になります。

コマンド `pwd` を実行してみると自分がどこにいるのか分かります。
パスの住所みたいなものです。

shellの引数の作成
----
`sh ./example.sh 〇〇 〇〇〇`
【必ずスペースをあけて記述、これで引数になります。※〇の部分に引数を記述してください】
````
echo "$1"
echo "$2"
````
これで出力できます。`echo`は出力する意味

配列を作成
----
配列は、【**Shell 配列**】 などと検索するとたくさん出てきます。
```
example=(
    "hoge"
    "fuge"
    )
```
変数と代入を行います。【**シェル変数 代入**】と検索すればたくさん出てきます！
```
#日付設定
yyyy-mm-dd="$1" 

#2つめの日付設定
yyyy-mm-dd_2="$2"

#時間設定
HH-MM="$3"
```
すべて`引数`で設定しています。

`````
for e in "${example[@}"; do
echo $e
done
`````

出力結果は
```
hoge
fuge
```
となります。
今回はaws s3の中身を見てファイルのサイズとトータルが欲しいとします。
<h5>オススメ引用元</h5>


https://dev.classmethod.jp/articles/s3-objects-list-aws-cli

`````
for e in "${example[@}"; do

aws s3 ls s3://testtest-test2/"$e"/ #日付設定 / #2つめの日付設定 / #時間設定 --recursive --summarize --human-readable

# 日付や時間部分は代入を行っています。

echo $e "$日付設定" "$2つめの日付設定"

# echoは出力するのみなので、順番を入れ替えての出力も可能です。 
done
`````

echo 後の`＄e "$日付設定"`の間はスペースを行っていますが`(／や，)`を指定すると
```
e/日付設定
e,日付設定
```
と出力されます。

後は`tailコマンド`を使用して末尾の2行を抜き出します。
コマンドの詳細に関しましてはたくさんの記事がありますので、調べてみる事をお勧めします。
<h5>オススメ引用元</h5>

https://qiita.com/sakito/items/7f65e16f10b3d754f307

`awkコマンド`を使用し抜き出して出力する
<h5>オススメ引用元</h5>

https://qiita.com/yamazon/items/563af1b485ff413d381f

aws s3を引数に設定していきます。
<h5>オススメ引用元</h5>


https://qiita.com/If_it_bleeds-we_can_kill_it/items/3e0c19f4563a839f6186

```
例)
example=`aws s3 ls ${BUCKETDIRNAME} --human-readable | tail -n (抜き出したい行数) | awk '{ print $5 }'`
```

あとは`echo`で出力したい順番に記述
```
echo "$e" "$example"...
```
上記のように記述し最後に`done`を書きます。


引用記事も多く読みにくいと思いますが、今回勉強したことをまとめてみました。
実際に記述してどのように動くかを試してみることで勉強になりますので、是非勉強してみてください。初めての経験で自信がつくようになりました。
それでは失礼します。
Micro:bitをLINE Beaconとして利用する 

:::note
本記事は2020年1月26日に公開したものです。
:::

こんにちは。今回は、BBC Micro:bitとLINE Beaconについて学んでいきたいと思います。

## 動機

昨年度の文化祭より、Google Formでアンケートフォームの運用を開始したのですが、流入点を文化祭ウェブサイトに限っていたこともあり、芳しい結果を得ることができませんでした。

そのため、LINE Beaconを校門に設置し、入場時にはパンフレットなどのメッセージを、退場時にはフォームリンクを配信するようにすれば、タッチポイントを増やすことができ、当課題を解決できるのではないかという推測から、LINE Beaconについて勉強することにしました。

## サービス比較

### iBeacon

> iBeaconは、Bluetooth Low Energyビーコンの一種で、低電力、低コストの通信プロトコル、またはその技術です。

https://developer.apple.com/ibeacon/

iBeaconは、以下のような不利な点を持っています。

- アプリケーションのインストールが必須である
- Android OS向けの開発が難しい

今年度の文化祭では、モバイルアプリケーションを開発する予定は無く、また、クロスプラットフォームに対応することが難しいため、本件においてはiBeaconを利用しないことにしました。

### LINE Beacon

> LINE Beaconは、ビーコンと呼ばれるBluetooth発信機器からのLINE向けの信号を受信する機能です。

https://developers.line.biz/ja/docs/messaging-api/using-beacons/

iBeaconと同様に、BLE（Bluetooth Low Energy）端末を利用することができます。BLEとは、消費電力の低さを特徴とする、Bluetoothの規格の一部です。

- 基本的に、LINEがインストールされた端末であれば利用できる
- クロスプラットフォームに対応しているといった利点があり、LINE Beaconを採択しました。

### BBC Micro:bit

> BBC Micro:bitは、1980年代に情報教育のために英国放送協会が開発したBBC Microが各学校で使用されたように、英国の11歳と12歳の小学生全員に配布される低消費電力、低コストのシングルボードコンピュータ。

https://microbit.org/

## 開発

下の記事で、Micro:bitをBLE端末として使えることを知ったので、Micro:bitを利用することにしました。

https://qiita.com/poruruba/items/a28476ad53b2232c789d#line-beacon%E3%81%8B%E3%82%89%E3%81%AE%E9%80%9A%E7%9F%A5%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B

上の記事を参考に、Micro:bitをLINE Beaconとして設定しました。

https://qiita.com/pepix/items/96adce12b90d98cdff40

LINE@からLINE 公式アカウントへのブランド再編があったため、最新版である上の記事を読んでいきます。上の記事では、Node.jsとngrokを利用した方法を提示しています。ここで、個人的な注意点があります。`CHANNEL_ACCESS_TOKEN` は、チャンネルID（Channel ID）ではありません。LINE Developers コンソールから「チャネルアクセストークン（ロングターム）」を発行し、得られる文字列です。

Messaging API > Webhookの利用をオンにし、Webhook URLの検証を行い、成功したら、次の段階に進みます。

### Google Apps Script （GAS）

> Google Apps Scriptは、G Suiteプラットフォームでの軽量なアプリケーション開発のためにGoogleが開発したスクリプトプラットフォームです。

https://developers.google.com/apps-script?hl=ja

ローカルでサーバを常時起動しておくのは、現実的ではないので、Google Apps Scriptでコードのデプロイを行います。

https://github.com/yuzuafro/raspi_line_beacon/blob/master/docs/linebot.md

上の記事を参考に進めていきます。

:::note warn
前節で記述したスクリプトは利用しません 🙇‍♂️
:::

記事ではNode.jsを利用しておりませんので、静的デプロイができます。

注意点として、記事内では環境変数を直書きしていますが、GASの「プロパティーストア」という機能を利用して、環境変数をより安全に扱うことができます。

https://tonari-it.com/gas-property-store/

`CHANNEL_ACCESS_TOKEN` を次のように置換します。

```diff_javascript
- const CHANNEL_ACCESS_TOKEN = 'xxxxxxxx';
+ const CHANNEL_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('CHANNEL_ACCESS_TOKEN');
```

LINE Developers コンソールで、Webhook URLを置き換え、テストします。

ビーコン（Micro:bit）に近づくと…

![picture_pc_a693a8fad241e04830a40f989feb5d6f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332413/0c15afe5-c6da-4e1a-bbec-1d88436729ea.png)

動きました 🙌

## おまけ

たまに「応答メッセージ」機能をオフにする必要があるといった記事を見ますが、私の環境ではその必要がありませんでした。
Erlangのリポジトリとブランチ運用

# はじめに

Erlangのソースコードを読む時、どのブランチを読めばいいか、どの様に運用されているか、コントリビュートする際にはどこから手をつければいいか。
このあたりが疑問だったので、まとめてみました。

# Erlangの開発リポジトリ

Erlangの開発リポジトリは[ここ](https://github.com/erlang/otp)です。
githubで運用されているので、まずはこれをgit cloneしましょう。

# Erlangのブランチ構成と運用

ブランチを見てみると、

* Master
* Maint
* Maint-xxx

という構成になっています。
これらはどう使い分けられているのでしょうか？

[ここ](https://github.com/erlang/otp/wiki/Branches)に運用方法が記載されていました。

Masterブランチは次のメジャーリリース（OTP-XX.0)のリリースに利用されます。このブランチには次のメジャーリリースに含まれる全ての機能が含まれます。新しい機能を追いたい場合はこのブランチをチェックするのがよいでしょう。

Maintブランチは次に来るであろうマイナーリリース(OTP-XX.Y)のリリースに利用されます。このブランチには新機能は含まれず、バグ修正と改善のみです。バグや改善に関する変更を追いたい場合はこのブランチをチェックしましょう。

Maint-◯◯ブランチはパッチリリース(OTP-XX.Y.Z)を追跡するために利用されます。重要な壊れた挙動を修正する事が決定されたパッチがこのブランチに含まれます。重要なパッチについて追いたい場合はこのブランチをチェックしましょう。

# まとめ

Erlangのリポジトリのブランチ運用について紹介しました。
Erlangのソースコードを追う際に、何を目的にするかでどのブランチをみるべきかが変わってくるので参考になれば幸いです。
EPSS分析環境を作る、hogehuga/epss-dbの使い方

# 本記事について

EPSS(The Exploit Prediction Scoring System)について、ローカルで分析ができるようにmysqlにすべてのデータを保管するための、docker imageを作りました。これの使い方を簡単に解説します。

## waht is EPSS?

FiRSTが管理する、脆弱性悪用スコアリングのシステムです。
- https://www.first.org/epss/

使い方の説明記事であるため、EPSSを知っていることを前提としています。
- 今後、弊勉強会である"脆弱性対応勉強会"でもEPSSについても話すと思います。
    - https://zeijyakuseitaioukenkyukai.connpass.com/

# 概要

github.com/hogehuga/epss-db で作ってありますが、DockerHubにイメージを用意しました。通常はDockerHubのイメージを使ってください。
- イメージを自分で作りたい人は、docker/ 内にDockerfileが置いてあるので、これを修正してbuildしてみてください。
    - `$ docker build -t customImage ./` 等

Docker上でmysqlコンソールから使う想定であり、状況によりcsvなりでデータを出すことになると思います。その為、share/ ディレクトリを擁してあります。
- `docker container run`の`--mount`オプションで、ホストと共有するディレクトリを指定してください。

データ数がそれなりに多いので、遅いかも。indexを張った後に"1日分のデータ"を追加すると、10分くらいかかります。
- index無しだと2分くらいでした。弊環境では。
- 以前のSQLite3バージョンだと、2時間くらいかかってました。mysqlで速度は改善しましたね。

# 簡単に使う

説明便宜上、共有ディレクトリの説明は面倒なので、mount自体を省略します。実際に使う時にはmountしておいた方が楽だと思います。

## 1. Docker imageを使ってrunする

`$ docker container run --name <yourContainerName> -e MYSQL_ROOT_PASSWORD=mysql -d hogehuga/epss-db`

- `--name`や`MYSQL_ROOT_PASSWORD`はご自由に設定ください。 

## 2. 対象containerにログインする

`$ docker exec -it <yourContainerName> bash`

- そんなに頻繁に使うものでもないので、containerにログインして使います。

## 3. EPSSデータをmysqlに入れる

`# cd /opt/epss-db`
`# ./epss-init-getdata.sh`(25分程度かかる)
`# ./epss-init-preprocess.sh`(15分以下程度かかる)
`# ./epss-init-import.sh`(30分程度かかる)

- `github.com/hogehuga/epss-db` を `/opt/epss-db` にcloneしてあります。
- `./epss-init-getdata.sh`は、FiRSTのサイトから`*.csv.gz`のオリジナルデータをwgetし、`/opt/epss-db/epss-data`以下に配置します。
    - 時期によりデータ構造が違うので、`1st``2nd``3rd`のディレクトリ事で分けています。詳細はスクリプトを見て。
- `./epss-init-preprocess.sh`は、ダウンロードしたデータを、現在の項目一覧に標準化します。
    - `1st`はCVE-ID/epss、`2nd`はCVE-ID/epss/Percentile、`3rd`はCVE-ID/epss/Percentile/model_versionが含まれています。一番データ項目の多い3rdに合わせてデータ補完しています。
- `./epss-init-import.sh`は、mysqlにデータを入れています。
    - それなりにデータ数が多いので、indexの無い状態でデータを入れ込みます。

## 4. indexを付ける

`# ./epss-init-createindex.sh`

- 大量データ投入が終わったら、indexを張ります。
    - indexが無いと検索に耐えられないので、indexは必要です。ですが、indexがある状態だとデータ投入に時間がかかるため、import後にindexを張ります。
- 利用するクエリに合わせて調整してください。
    - 一般的に必要と思われる、各カラムに対してindexを付けています。

# 5.使う

`$ docker -it <yourContainerName> bash`でログイン後に`mysql --defaults-extra-file=/opt/epss-db/my.cnf -u root epssdb`などで対話的に。

- 適当に使ってみてください。
- おそらく、これを必要とする人は少ないと思います&目的があると思うので、思い思いに使ってください。
    - 必要ならSIEMに入れてグラフ化してもいいかもしれません。講演などでは使えそう。

# 6.前日のデータを入れる

`$ ./epss-add.sh -d "2023-12-31"`

- 2022-02-04以降のデータは、このコマンドで日付指定で追加可能です。
- 用途としては、epss-db構築後、FIRSTで毎日公開される`*.csv.gz`をmysqlに追加することを目的としています。
    - といいながら、cronでのバッチ処理は意識していない、対話的な作りです。勝手に弄ろう&PullRequest下さい。

# 終わりに

EPSSのデータはどう使えるのか、を考えるには、EPSSデータの分布や状況を核にする必要があります。その為のツールとして作りました。必要な人には有用ですが、そうでない人にはどうでもいい(むしろSIEMで作れ)というものです。
必要な人が手間をかけずに使える、が目的です。

とりあえず使ってみるとよいかもしれません。

以上。