OmniAICreator/Qiita-1.07M huggingface dataset:
基本設計とは？

基本設計書は何を書くべきなのかまとめました。

# 基本設計とは
システムを作るために何を作るかを決める作業の内、要件定義と詳細設計の間にあたる行程。結合テストを対になる。
![テストと行程の図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689380/9af02b3b-5593-40e2-932e-d84cd77c8a02.png)

基本設計を作る上でのインプットは要件定義書であり、
アウトプットした基本設計書は詳細設計のインプットとなる。
![設計書と行程の関係.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689380/3442f963-25cb-4a91-0ee4-3899b34ee954.png)

#### 行う作業
- 画面や帳票、バッチ処理など作るべき機能を洗い出す
- 作る機能がどんなものなのか明確にする
- 機能間の関係性や入出力するデータを明確にする
- データをどういう形式、項目として扱うか決める
- 既存システムとどんなデータのやり取りをするか決める
- どんなミドルウェアやハードウェアを組み合わせれば要件が実現できるか考える

# 外向けと内向けの区分
基本設計はお客様と意見をすり合わせる最後の機会でもあり、開発要員に設計を伝えるものでもある。
伝える相手と目的の違いで「外向け」と「内向け」に分けることができる。
![基本設計書の種類.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689380/aae4de04-1071-305b-a91e-a5e22b7865e3.png)
### 外向けの設計
##### お客様がこうに使えるものだと認識するもの
- 画面遷移
- 出力される帳票のレイアウト
- 関連するシステムとのデータのやり取り
- システムを使った業務の流れ（使い方？）
など
### 内向けの設計
##### システムの作られ方に関するもの
- 画面を表示するプログラム
- データベース
- アーキテクチャ
など


# 基本設計で作るもの

|用途  |つくるもの  |
|---|---|
|全体を把握する|機能一覧、業務フロー図、状態遷移図、データフロー図、入出力関連図|
|画面を決める|画面一覧表、画面遷移図、画面設計書（レイアウト）|
|帳票を決める|帳票一覧表、帳票設計書（レイアウト）|
|バッチ処理を決める|バッチ処理一覧表、バッチ処理フロー図、バッチ処理設計書|
|データベースを決める|テーブル一覧表、テーブル設計書、ER図、CRUD図|
|入出力を決める|ファイル一覧表、ファイルレイアウト、外部IF一覧表、外部IFレイアウト|
|その他決めること|項目定義書、コード定義書、メッセージ一覧表|
|物理構成や運用方法|システム構成図、運用設計書|

### 全体を把握する
基本設計ではまず、要件定義から機能を分割・分類し、機能レベルで何を行うかを考える。
最初に作るものがいくつかるのか、数を把握する。
この時、機能の「単位」は様々であり、画面、帳票、バッチ処理、APIなど同じものの単位で一覧を作るのは普通である。また、もっと上の「業務」でグループ化し、その中にどんな画面、帳票、バッチ処理、APIがあるかでまとめることもよくある。
##### 最初から全ての機能を一覧にすることはできない
要件定義書を見ながら検討や試行錯誤しながらだんだん育てていく。
![機能一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689380/148e8e48-e552-7eab-008b-0bf5ee9b84da.png)

### 画面設計
- どういう画面があるのか
- その画面は何ができるのか
- どういう項目があってどうに表示されるのか
- 画面間の繋がりはどうになっているのか

画面レイアウトやクリックアクション、画面遷移を明示する。
UIの専門家やUXの専門家も交えて議論を行う。

### 帳票設計
ここでいう帳票は、受注伝票や入金伝票などの業務上必要になるものやPDFなどで売上高の集計値が分かるもの。
- いつ
- 誰が
- どんな情報を
- どういう形式で
- どこから出力するか

帳票は画面で入力する検索条件やデータベース設計にも密着していて、関連する機能を一緒に考えながら徐々にブラッシュアップしていく。

### バッチ処理設計
画面や帳票以外の処理、いわゆるバッチ処理がある。目には見えないところで行う処理。
- どういうバッチ処理があるか
- どういう情報を入力し、何を出力するか
- どういうタイミングで動くのか
- バッチ処理同士の前後関係
- バッチが途中で終了したらどうフォローするか

バッチ処理を考える上で大事なのは全体視点。一つ一つの処理は入出力や処理がわかりやすいように上手に分割して、それをうまく組み合わせて大きな一つの処理結果をどうやって作っていくかを考える。

### データベース設計
システムで使うデータをどのように保存し、検索処理などによってどのように提供するかを考える。
- どのような種類のデータベースを使うか
- どのようにデータを管理するか
- どのような項目を持つか
- インデックスにはどのような項目を使うか
- テーブル間の関係

### システム構成
システム構成は、アプリケーション側とサーバなどのインフラストラクチャ（インフラ）側の２つの領域から作られる。
アプリケーション側とインフラ側の担当者が、どのようなハードウェアやネットワークの構成にすれば、要件定義で決められた処理性能や可用性や運用性などのいろいろな要件・非機能要件を満たすことが出来るかを考える。また、それにかかるコストも検討する。

# 基本設計をする上で大事なこと
### 全体視点
使う側の視点、開発者としての視点、設計者としての視点、保守・運用する側の視点などさまざまな立場での視点のこと。
要件を形にするだけでは「使える」ものではない。
### 要件定義とずれないこと
基本設計は要件定義の「翻訳」をする。
基本設計で要件定義とずれてしまうと、成果物がずれてしまう。
システムで分からないことがあれは、基本設計に返る。運用する時も、障害が起きた時も、改修する時も、作業者が変わったときも常に基本設計があり続ける必要がある。
### 実際に作れるものであること
「こういうことができたらいいな」ではなく、「こうすればできる」「こうでなければならない」という明確な根拠ありきで進める。
その根拠は、設計の意図を他者に伝えることにもつながる。
### 設計の手戻りは必ずある
手戻りがあることを前提に取り得る選択肢や代替え案を考えておく。
設計上のリスクは設計の段階でお客様に合意をとっておくのも大事。

設計後に設計上の問題を見つけたとしても、絶対に基本設計を変えてはいけないわけではない。
設計は都度変わっていくものであり、準備はしておかねばならない。

# 参考
https://www.bold.ne.jp/engineer-club/basic-design
DataGridViewのクリックとダブルクリック判定

## 説明
タイマーコントロールを使います。
clickした時にダブルクリックの判定時間間隔のインターバルでtimer1をstartする。
【DoubleClickだった場合】
　DoubleClickイベントでtimer1をstopすることでOnTick_FormsTimer1がcallされない。
　その後にDoubleClickイベント内でdgv_doubleClickがcallされる。
【singleClickだった場合】
　OnTick_FormsTimer1がcallされて、そのままdgv_singleClickがcallされる。



```vb:VB.NET
Public Class Form1

    'タイマーコントロール作成
    Private timer1 As Timer = New Timer() With {.Enabled = False}

    ''' <summary>
    ''' Formロードイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'タイマーイベントを追加
        AddHandler timer1.Tick, AddressOf OnTick_FormsTimer1

    End Sub

    ''' <summary>
    ''' ダブルクリック判定用のタイマー処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Public Sub OnTick_FormsTimer1(sender As Object, e As EventArgs)
        'タイマーを停止
        timer1.Enabled = False
        timer1.Stop()
        'マウスクリックの処理をここで行う
        dgv_singleClick()

    End Sub

    ''' <summary>
    ''' DGVクリックイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub DataGridView1_Click(sender As Object, e As EventArgs) Handles DataGridView1.Click
        'タイマー開始
        timer1.Enabled = True
        'システムに設定されたダブルクリックの判定時間間隔を取得
        timer1.Interval = SystemInformation.DoubleClickTime
        timer1.Start()

    End Sub

    ''' <summary>
    ''' DGVダブルクリックイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub dgv1_DoubleClick(sender As Object, e As EventArgs) Handles DataGridView1.DoubleClick
        If timer1.Enabled Then
            timer1.Enabled = False
            timer1.Stop()
        End If

        'ダブルクリックの処理を実行する
        dgv_doubleClick()

    End Sub

    ''' <summary>
    ''' DGVクリック時の処理
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub dgv_singleClick()
        'ここにクリック時の処理を書く
        MessageBox.Show("single click")
    End Sub


    ''' <summary>
    ''' dgvダブルクリック時の処理
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub dgv_doubleClick()
        'ここにダブルクリック時の処理を書く
        MessageBox.Show("double click")
    End Sub

End Class

```
~オレ流~ 勉強のモチベの上げ方

## はじめに

技術的な勉強がめんどくさいなど感じたことはありませんか？  
過去に一緒に仕事したエンジニアに「KJ さんのいう勉強を勉強だと思ったことないです。」というプログラミングが大好きすぎて楽しくコーディングしてたら朝になっているというような人に出会ったことがあります。  
その方のようであれば何にも苦ではありませんが、「勉強しなければならない！でもやる気が起きない！」という時、私がモチベを上げるためにやっていることを共有したいと思います。  
※ プログラミングは好きだけど、趣味にするほど好きではないって方向けの内容かもしれません。

## 何に憧れてエンジニアになったか思い出せ！

私は IT = キラキラしている！や綺麗なオフィスで働いている！というイメージを持っていました。  
当時の環境はそのイメージとは程遠い環境で働いていたと思います。いわゆる The 日本企業のオフィスのような、、、  
ある日 Youtube で「A day in the life of enginner」というタイトルの動画を見つけました。  
そこでは海外のエンジニアの 1 日を上げているいわゆる Vlog だったのですが、そこには私が思い描いていた綺麗なオフィスなどが広がっていました。  
それをみて、「勉強して技術力つけてモダンな自社開発企業に転職すればこの世界に行ける！」とモチベが上がったことを今でも覚えています。  
なので、モチベを上げる時は今でも Youtube で「A day in the life of enginner」と検索して動画を見てモチベを上げています！  
個人的におすすめは[こちら](https://www.youtube.com/watch?v=rqX8PFcOpxA)の動画

## お高いデバイスを買ってしまえ！

まぁこれは衝動買いになってしまうのであまりおすすめの方法とは言えませんね w  
ある PJ に参画していた際、私の後の師匠に当たる方に指摘をもらい落ち込みながら電車で帰っている時、「向いていないのかなぁ」とエンジニアから逃亡しようかと思いましたが、いかりしんじくんモードが発動してしまい逃げられないよう環境を改善することにしました。  
そこで瞬時にプログラマー御用達キーボードの PFU 製 HHKB をポチりました。(3 万円)  
たかがキーボードに 3 万円も出したからそのお金がもったいなくてやめられないという私の貧乏性をくすぐる方法です w  
結果は大正解で静電容量キーボードの押し心地の気持ちよさに酔いしれてしまい、勉強でのタイピングが楽しくなりかなり効果的だと感じました。  
(今では沼にハマり REALFORCE for MAC に 4K モニターに Gpro ワイヤレスと破産寸前でぇーす。)

・・・

(昇降デスク？48000 円？？？ぽちぽちぽち)

・・・

こうしてデバイス沼にハマっていくのでした。。。

ちょっと本題とはずれ気味ですが、要するに「こんなに自己投資したのだから頑張らないと」という気持ちをデバイスを購入することで高めました。

その数ヶ月後 28 万円の MacBookPro 16inch を購入するのであった、、、、

## 最後に

あまり参考にならなかったらすみません。  
最近エンジニアになった方や、新卒でエンジニアになったけどプライベート時間の勉強がつらいと感じた方の参考になれば幸いです。  
今回 Qiita 初投稿ですが、ここまで閲覧くださりありがとうございます！  
今年度から都内でフリーランスとして活動を始めました。  
ただまだまだペーペーなのでカテゴリ問わずずアウトプットや情報発信できればと思います!　　
エンジニアツイッターアカウントも作成したので、[こちら](https://twitter.com/kj_guitar001)もよろしければフォローくださると泣いて喜びます！
【python】playwrightでパラメータテストする方法

# 1.やりたいこと
playwrightで作ったテストをデータ駆動でテスト実施できるようにします。
これを実現するためにpytestを活用して実現したいと思います。pytestの「@pytest.mark.parametrize（）」は、対象のテスト関数にパラメータを渡し、パラメータセットの分だけ繰り返しテストをする仕組みです。

# 2.環境
playwrighとpytestが入っている環境を用意します。環境構築方法は、[別記事][link-2-2]に記載しています。
　・macOS 12.4(monterey)
　・Python 3.7.6
　・pip 22.1
　・pytest 6.2.5
　・playwright 1.16.2

| フレームワーク |内容 |
|:-----------|:------------|
|[Playwright][link-1-1]| マイクロソフト社が作っているブラウザを自動で操作する|
|[pytest][link-1-2]|Pythonで書いたプログラムをテストする|
# 3.環境設定
rootフォルダの直下に実行ファイルを作成します。
※ 実行ファイルのファイル名は、pytestの仕様上「test_xxx.py」としてください。
>root
>｜－　test_sample.py

# 4.コード
実行ファイルに下記のようなプログラムを書きます。
自動操作対象のWebサイトは、[UI Test Automation Playground][link-4-1]を利用します。

```ruby:test_sample.py
from playwright.sync_api import Page
import pytest

# パラメータセット
@pytest.mark.parametrize("target_Button,expected_result",[
("text=Click","Click"),
("text=Dynamic ID","Dynamic ID")
])

# テスト関数
def test_click(page: Page, target_Button, expected_result):
    page.goto("http://www.uitestingplayground.com/")
    #pytest.mark.parametrizeのtarget_Buttonの値をクリックする
    page.click(target_Button)
    #pytest.mark.parametrizeのexpected_resultの値があるか確認する
    assert page.inner_text("xpath = /html/body/section/div/h3") == expected_result
```
# 5.実行
ターミナルを起動後rootフォルダーに移動し、「test_sample.py」を実行します。
<dt>実行結果</dt>
test_sample.pyのtest_click()が２回テストを行い、その結果が返ってきました。

![スクリーンショット 2022-05-20 13.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667601/a30befbd-aec0-2f63-c112-7aa6a54ce3ac.png)

# 6.関連記事
・[【python】playwrightでE2E評価環境を作る][link-9-1]
・[【python】playwrightの実行中の操作を録画する方法][link-9-2]
・[【python】playwrightでログイン処理省略する方法][link-9-3]

[link-1-1]: https://playwright.dev/
[link-1-2]: https://docs.pytest.org/
[link-2-2]: http://qiita.com/
[link-4-1]: http://www.uitestingplayground.com/
[link-9-1]: https://qiita.com/ryuusen999/items/4642cc03095e29bed0e9
[link-9-2]: https://qiita.com/ryuusen999/items/ec3b95f1c2e2aa4f5856
[link-9-3]: https://qiita.com/ryuusen999/items/59c7416876f9b0d92a72
bai 2

リストとは

4

• 任意のデータを順番に格納することができる

• [ ] (角カッコ)の中に 「

, 」(カンマ)区切りで書く

• リストには、文字列の他に色々な型のデータを
入れることができる
append - リストに追加
✔︎ リストの末尾に追加できる
pop - リストから削除
リストの末尾から削除できる
remove - リストから削除

4

✔︎ リストから指定した文字などを削除
del - リストから削除

4

✔︎ リストからインデックス番号で指定して削除
clear - リストを空にする
ROS2チュートリアルの翻訳(Actionの定義)

## はじめに
チュートリアルが一番わかり易いので翻訳します。
https://docs.ros.org/en/galactic/Tutorials/Actions/Creating-an-Action.html


Action定義の作成方法
==================

**目標:** Ros2 Packageの中にAction定義を追加できるようになる

**難易度:** 中

**時間:** 5 分


背景
----------

先のチュートリアル
(https://docs.ros.org/en/galactic/Tutorials/Understanding-ROS2-Actions.html) 
ですでにActionについては学んだかと思います。
メッセージ定義(topics/msg)やサービス定義(services/srv)がカスタマイズできたように、
Action定義についても、カスタマイズすることができます。
このチュートリアルでは、どのように定義し、どのようにBuildするかについて、説明します。
Action ServerとAction Client の作成方法については、次のチュートリアルで解説します。

前提条件
-------------

1. ros2とcolconをインストールしていること
2. ``action_tutorials_interfaces``という名前でパッケージを作成していること


~~~
mkdir -p action_ws\src
cd action_ws\src
ros2 pkg create action_tutorials_interfaces
~~~

やり方
-----

1 actionの定義。


actionは ``.action`` という拡張子で下記のように定義していきます:



    # Request
    ---
    # Result
    ---
    # Feedback

3つのメッセージを ``---`` で分けて定義します。

- Request：Action ClientからAction Server に送信され、Serverの応答が開始されます。
- Result：応答が終了するとがAction ServerからAction Clientに送信されます。
- Feedback：定期的にAction ServerからAction Clientに対して、応答が今どうなっているかについてのメッセージが送られます。


ここからフィボナッチ数列 を計算するAction定義を作成してみます。


``action_tutorials_interfaces``のパッケージ直下に 
``action``フォルダを作成します。:


      cd action_tutorials_interfaces
      mkdir action

``action`` フォルダの中に　
``Fibonacci.action`` というファイルを作成し、
下記のように定義情報を書きます。:

~~~
  int32 order
  ---
  int32[] sequence
  ---
  int32[] partial_sequence
~~~

Requestは、フィボナッチ数列の項数とします。 
Resultは、フィボナッチ数列
Feedbackは、計算途中のフィボナッチ数列とします。

2 action定義のビルド


ここからはビルドする方法について説明します。

``action_tutorials_interfaces`` パッケージ内、
 ``CMakeLists.txt`` の中の 
``ament_package()`` の記載の前に
下記コードを追記します。

    find_package(rosidl_default_generators REQUIRED)

    rosidl_generate_interfaces(${PROJECT_NAME}
      "action/Fibonacci.action"
    )

更に　``package.xml``の中に、下記を追記します。:


    <buildtool_depend>rosidl_default_generators</buildtool_depend>
    <depend>action_msgs</depend>
    <member_of_group>rosidl_interface_packages</member_of_group>

Actionの定義の中にはメタデータが(例えば goal IDs)が含まれているため、
action_msgsに依存する必要があることに注意してください。

これでPackage内に ``Fibonacci`` actionの定義ビルドできる状態となりました。

    # Change to the root of the workspace
    cd ~/action_ws
    # Build
    colcon build

慣習として、actionという文言がパッケージ名の前につけることが多く、
Fibonacci actionを参照したい場合は、下記のように書きます。

``action_tutorials_interfaces/action/Fibonacci``.

ちゃんと使える状態になっているかを確認するために、下記のようなコマンドが利用できます。


~~~
ros2 interface show action_tutorials_interfaces/action/Fibonacci
~~~

Fibonacci action の定義を確認できます。

まとめ
-------

このチュートリアルでは、Action定義の構造について学びました。
また、この定義を利用できる状態にするために 
``CMakeLists.txt`` と ``package.xml`` を変更する必要があることを学びました。
うまくできたかを確認する方法について学びました。

次のステップ
----------

次は、この定義を使って、ServerとClientをどのように作るかを学びます。

関連の資料
---------------

ROS Actionの詳細が知りたい場合は、 
http://design.ros2.org/articles/actions.html
を見てください。
SPSS Modelerをチームで使うときのポイント

ちょっとしたデータ分析だと一人で完結すると思いますが、規模が大きくなるとチームを組んでSPSS Modelerを使ってデータ分析することも多いのではないでしょうか。
一人で作業しているときは特に問題ありませんが、数人のチームでSPSS Modelerを使ってデータ分析をするようになると、何かしらルールを決めておかないとぐちゃぐちゃになってしまいます。
チームで作業をするというのは、Aさんが途中まで作成したSPSS Modelerのストリームを、Bさんが引き継いで残りを完成させる、Bさんが作成したストリームをベースにしてCさんが少しカスタマイズしたストリームを作成するなど、いろいろなパターンがあると思います。
過去の経験を踏まえて、未来の自分のためにも、チームで作業するときの4つのポイントをまとめました。
1. ストリーム名の命名規則を決める
1. 入出力ファイルのエンコードを揃える
1. 入出力ノードのフォルダ揃える
1. スーパーノードを活用する

## 1. ストリーム名の命名規則を決める
ストリームを他人と共有するなら、ばらばらの名前だと管理しずらいです。
例えば、ストリームのファイル名に日付を付加する場合も、先頭に入れる人と末尾に入れる人が混在していると、わかりにくくなります。
20210101_aaaprj_anomaly1.str
aaaprj_anomaly2_20210101.str

プロジェクト名＋分析カテゴリ＋日付.strなど、命名規則をプロジェクト初期に決めておくとよいです。

## 2. 入出力ファイルのエンコードを揃える
入出力がCSVファイルということは結構多いと思います。
チームメンバーが全員Windowsで入力ファイルを出力するシステムもWindowsサーバの場合はSJISで統一されると思うので、そのままデフォルトで問題ありません。
また、チームメンバーが全員Macのときもデフォルトで問題ありませんが、チームメンバーがWindowsとMacが混在することも多いと思います。
Windowsの人とMacの人で作業する場合、UTF-8に揃えておいた方がよいです。
デフォルトではシステムのエンコード(Windowsの人はSJIS、Macの人はUTF-8)になっていると思うので、下記リンク先手順を参考にUTF-8に揃えましょう。

https://qiita.com/kawada2017/items/643311fcfd5bf7eca596

https://qiita.com/tokamo10/items/a25781495703744ed42c

## 3. 入出力ノードのフォルダ揃える
別の人が作成したストリームを動かすときに、毎回必ず入出力ノードのファイルパスを変更しないといけないと大変ですよね？
各自のPCローカルで動かす場合は、入出力ファイルのパスもルール化してプロジェクト初期に決めておくとよいです。
後続フェーズでSPSS Modeler Server上で動かすことが決まっている場合は、サーバー上のファイル配置パスを同じ構造にしておくのがよいでしょう。

各自のPCローカルで動かす場合は、例えば以下のような感じでルールを決めておきます。
|配置パス種別|具体的なフォルダのパスの例|
|-----------|--------------------|
|入力ファイル|/work/プロジェクト名/data/input|
|出力ファイル|/work/プロジェクト名/data/output|
|ストリーム  |/work/プロジェクト名/stream|

https://qiita.com/kawada2017/items/3b3ef5d5e476159163ee

## 4. スーパーノードを活用する
よく使うノードのセットをスーパーノードにしておくことで、他のストリームにも組み込みやすくなります。
パターン化できるものはスーパーノードにしてチーム内での再利用を心掛けましょう。

https://www.ibm.com/blogs/solutions/jp-ja/spssmodeler-push-node-20/
【UE4】音量を0にすると再度音量を上げても音楽が流れなくなるのを防ぐ方法

音量調節機能を作っている際に、一度BGMの音量を0にすると、再度音量を上げて設定しても音楽が流れなくなる事態に遭遇し、ちょっとしたことですが忘れないように残しておくことにしました。
# なぜ音楽が流れなくなるのか
UE4のサウンドは音量を0にすると再生停止するという機能があり、これによって一度BGMを音量0にすると再生されなくなるようです。
## ループがオフになっていないか
BGMのように繰り返し流す場合は、サウンドウェーブにもLoopingの設定がありますが、このサウンドウェーブからキューを生成した際にキューではLoopingがFalseのままになっているのでTrueにしておきます。
![Looping設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671215/d711bfed-a3e5-a6d3-2d91-50aec4332aec.png)
サウンドキュー上でLoopingをTrueにすることで、BGMを0から再度音量上げても再生されるようになります。しかし、このままだと再度音量を上げた際にBGMがまた最初から再生されてしまいます。
## ボイス管理をPlay when Silentにする
サウンドキューのボイス管理のVirtualization Modeが初期ではRestartになっていますが、Play when Silentに変更すると、BGMを0にしても再生停止しないようにできます。これで音楽が流れなくなるのを防ぐことができます。
![ボイス管理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671215/c7ea67bc-4a33-7d3a-97ec-bfaab62648a1.png)

自分用のメモなので、もしかしたら間違っているかもしれません。もし詳しい方がいらっしゃったら回答お願いします。
たんたいてすとのかんたんな勉強会資料(Service)

## これはなんですか

Java - Spring Boot の単体テストについて、勉強会の資料。しゃべることをまとめたもの。

## 世間一般で言うところの単体テスト

単体テスト（ユニットテスト、略してUTと呼ばれることもあります）は、プログラムを構成する比較的小さな単位（ユニット）が個々の機能を正しく果たしているかどうかを検証するテストです。 通常、関数やメソッドが単体テストの単位（ユニット）となります。

## なぜテストを書くのか＆費用対効果の話
1. 主に反復型開発において、既存のメソッドの挙動を担保しつつ、新しい機能を盛り込んでいく過程でバグの発見することが容易になる
1. よく書かれたテストはそれだけでクラスの取り扱い説明書になる

事情は多々あると思いますが、ぱっと見で単体テストを書くコストが高くつくからです。（ついているように見えるだけですが）

このコストをどう捉えるか？単体テストにどのような意味をもたせるかは会社やプロジェクトの方針に依るところが大きいと思います。
私の私見では、部分的でも８割位のプロジェクトでは書いたほうがよいと思いますが、２割位は書いても意味のない状況というのは確実に存在するので、一度は対コストのことを考えてもよいと思います。

単体テストを残すかどうか、どの程度残すかは、プロダクトの品質と、コストの話なので、スクラムでいうところのプロダクトオーナーが判断すべきか、開発チームの自治としてスクラムメンバーが判断するか、きっとお話し合いだろうなー、と思います。

## Javaでいうところの単体テスト

実装したクラスが正しく動作するかを裏打ちするための実装のこと。

古くから JUnit という仕組みが用いられており、クラス単体ではなくクラスの複合的なテストも書くことができる、が、それを単体テストと呼ぶかどうかは知らない。（連結テスト、インテグレーションテストっぽいなにかだと思う）

単体テストを書くコストは、初級者で被テストクラスを実装した時間的なコストで３倍、なれてくると同時にテストを書くようになるので等倍近くなります。
時間的なコストで1.5倍を切ったらまあ合格にしてあげてもよくってよ。

## 単体テストが「たんたい、Unit」と呼ばれる理由

最小の集合あるいは機能の単位であるクラスについてテストを行うからです。
このテストを行うための決まり事がいくつかあります。

1. 他のクラスの挙動にテスト結果が左右されない
1. カバレッジが１００％である（必要はないと個人的には思うけどそれなりに高い）こと
1. 値範囲に網羅性があること

## 具体的に何書くんじゃい
では、今回 Spring Boot をUTを例にしてみます。
おおよそ単体としては３種類のテストがあり、それぞれのテストをサポートするツールやライブラリがあります。
（依頼主から答えは見つけさせてと言われてるので、何を使うかは言わないことにします）

1. Controller
1. Service
1. Repository

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570665/a77318d0-d486-ba74-6ab4-ca4172ca0ecc.png)

### Controller
Controller はリクエスト及びレスポンスの処理について責任を追うもので、リクエストのバリデーションのバリエーションやレスポンスがきちんと機能しているかを見るものです。
そのため、Spring Bootというフレームワークの特性も含めテストします。
厳密には「単体」ではないのですが、単体テストに含めて運用したほうが効率がよいです。
これを実現するためには、コントローラーだけをテストできる仕組みが必要になります。

### Service
主に「書いてあること」が仕様どおりであるかをテストします。
詳しくは後述。

### Repository
レポジトリがたとえばDBに書き込まれたり読み出せるかをテストするものです。
厳密にはデータベースなどと連携した挙動をテストするため、「単体」ではないのですが、単体テストに含めて運用したほうが効率がよいです。
これを実行するためにはテストの中で完結するインスタントなDBが必要になります。

### Serviceについてちょっと深堀り

こんなかんじのクラスがあったとしましょう。

```
@RequiredArgsConstructor
@Service
public class SomeService {
  
    private final RepositoryA repositoryA;
    private final RepositoryB repositoryB;
    private final UtilServiceA utilServiceA;
    private final AutoOrderRepository autoOrderRepository;

    public void savePrice(int id, int price, int length) {
        DtoObject dtoObject = new DtoObject();
        dtoObject.setId(id);
        dtoObject.setPrice(price);
        dtoObject.setLength(length);
        repositoryA.insert(dtoObject);
    }
}
```

`savePrice ` というメソッドの責任は、`レポジトリAのPK idに対し、priceとlengthをレポジトリに渡すこと` になります。
これをテストする場合、はたしてどうすべきでしょうか。

（つづく）
Mapboxアカウントの作成方法

# はじめに

今回はMapboxを始めるにあたり、会員登録をする方法をご紹介します。
会員登録やSDKダウンロード、サンプルのビルドと実行は`全て無料`で実行できます。

## 会員登録

１）[Mapbox](https://www.mapbox.jp/) へアクセスし、「サインアップ」を押す。`Create your Mapbox account` の画面が表示されたら、Username、Email、Passwordなどを入力し、Mapboxの利用規約とプライバシーポリシー(Terms of Service and Privacy Policy)に同意してNext Stepボタンを押し、次のページで「Get Started」を押します。
![スクリーンショット 2022-05-20 13.05.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/d4a9fae0-2141-0eed-6aae-4ac3aff09c1e.png)



２）`Check your email` 画面が表示されますので、メールボックスに認証用メールが届いているのを確認します。


３）メールボックスに、`no-reply@mapbox.com` から `Verify your Mapbox email` というメールが届いてるのを確認し、本文のリンクをクリックします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/d1808d6b-ecce-d46f-8ffe-8a2f4e292cc3.png)

４）設定したパスワードを入力し、ログインします。

５）ログインに成功すると `Dashboard` ページが表示されます。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/88b50ba3-6076-3dfa-a939-d8bc2118e91c.png)

## アクセストークンを確認する

会員登録を終えてアカウントページにアクセスすると、`pk.` から始まる文字列が確認できます。これは`Default public token` と呼ばれるアクセストークンです。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/afb0d1e6-25c3-a043-656a-dcc5d71dac27.png)

### アクセストークンについて

Mapbpxはアクセストークンごとに各機能の利用（スコープ）を設定し管理することができます。Default public tokenは地図の閲覧やスタイル切り替えなど基本的な閲覧機能を提供するトークンです。各種スコープを変更することはできません。

それに対し、`Secret Token`と呼ばれるアクセストークンでは、Mapboxで提供されている各サービスの利用可否を設定できます。使わない機能を外しておくことで、例えば不用意なアクセスにより意図しない料金が発生するなどの事故を防ぐことができます。


### アカウントの二段階認証の設定をしておきましょう

Mapboxはサイトにログインする時の `二段階認証` が設定できるようになっています。Google AuthenticatorやMicrosoft Authenticatorを使って設定をしておきましょう。

１）ログインして画面右上から `Settings` を選択します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/759b4949-88b3-cb60-53e6-ffccdc98a479.png)

２）左メニューから `Security` を選択し、`Two-factor authentication` のスイッチをONにします。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/57af1ea8-93a7-baaf-d01a-3c7b3949bd59.png)


３）QRコードが表示されるのでGoogle AuthenticatorやMicrosoft Authenticatorを使って認証コードを用意し、画面に入力してください。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516459/d30ce945-20da-aa60-63c2-38a5e24f52e3.png)
【BizRobo!】ループステップを使わず対象を特定する！

# はじめに
現在、RAPを実務で行っていますが、まだまだまだまだ経験が浅く、日々勉強中です。
本記事については、自身の備忘録も含め同じ様な所で頭を抱えている方に対して、
少しでもヒントになり、先に進める力となれれば良いなと思い記事にしましたーー！

## 今回のTips
業務中に例えば、毎月値を入れていくようなExcelファイルがあって、
そこから、ロボットで稼働月の該当セルの値を取得する様なオペレーションが存在した場合、
よくある方法としては、以下の様に該当行をループし、値の取得➡値の判定の様に、
一つずつ判定し、該当の月まで来たら、値を取得する方法が定番なのではないかと思います。
![ループステップを使わずに、対象の特定①.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/2ce50623-545e-e9df-1adc-5d007d39deef.png)

ループステップを使っても、
要件を満たす事は、もちろん出来ると思うのですが、
今回は、一発で該当のセルの値を取得する方法について、記事にします！

## Tips概要
今回は、「名前付き範囲」と「セル値取得」を使用して、該当セルの値を取得します。

## Tips詳細
まずは、通常通り対象のExcelファイルをロボットで読み込んで頂いて、
ビューに表示されたら、一発検索したい行を右クリック➡その他➡名前付き範囲として設定を選択します。
![ループステップを使わずに、対象の特定②.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/060f0da6-e575-af4b-f11f-8831aaa85871.png)

設定すると、「Set Name Range」ステップが追加されるので、
アクションタブから、範囲名を自動➡名前付きに変更、入力欄にはわかりやすい名前を入力します。
![ループステップを使わずに、対象の特定③.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/b3be2bfb-7949-b1cc-e745-a9d4e7c50c2f.png)

次に、ビューのどこのセルでも大丈夫なので、値を取得するステップを追加します。
その作成した値取得ステップの「ファインダー」を修正します。
![ループステップを使わずに、対象の特定④.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/9f5e6c9d-e95f-52c5-10b9-66df3607095d.png)
↓
![ループステップを使わずに、対象の特定⑤.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/a2eabe2c-4bcc-5012-cdc8-cf5826e6c1d1.png)
※ヘッダーパターンは直接入力をしていますが、実際に業務で使用する場合は変数を指定する形が良いと思います。

上記の様に、値取得ステップのファインダーを修正する事で、
該当セルの値を一発で取得する事が出来ます。
![ループステップを使わずに、対象の特定⑥.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715221/827e4d8a-e718-c15e-d285-1d45a506a9b1.png)


## まとめ
今回は、該当月の値を取得するのを例にご説明しましたが、
いろんなケースに流用できるステップ構成だと思いますので、いろいろ試して頂ければと思います！
Psi4でUHF、UDFT計算

Psi4で非制限HF計算をする際にちょっと詰まったのでメモしておきます。結構使う手法なわりにマニュアルをたどるのが面倒だったので。

```
molecule {
1 2 # charge mult
... # xyz
}
set reference UHF
set basis def2-svp
energy('b3lyp')
```
ちなみに、電荷、多重度の指定は以下でもできます。
```
molecule mol {
... # xyz
}
mol.set_molecular_charge(1)
mol.set_multiplicity(2)
```
Eslintのエラーについて

### 概要
webpackを利用してjQueryを記述中にeslintのエラーが出たので、エラーの意味と解決策

①
```javascript
var storyTitle = $(".p-story").find(".js-blockTitle--scroll").html();
var storyTitleTrim = $.trim(storyTitle);
var newHtml2 = "";
storyTitleTrim.split("").forEach( v => {
  newHtml2 += "<span>" + v + "</span>";
});
$(".p-story").find(".js-blockTitle--scroll").html(newHtml2);
```
```
error  'storyTitle' is assigned a value but never used  no-unused-vars
```
→変数定義の際にvarを使用するのは望ましくないからconstかletで定義しようというエラー
varをconstもしくはletに変更するだけで解決。


②
```javascript
const storyTitle = $(".p-story").find(".js-blockTitle--scroll").html();
const storyTitleTrim = $.trim(storyTitle);
const newHtml2 = "";
storyTitleTrim.split("").forEach( v => {
  newHtml2 += "<span>" + v + "</span>";
});
$(".p-story").find(".js-blockTitle--scroll").html(newHtml2);
```
```
error  'newHtml' is already defined                     no-redeclare
```
→「const newHtml2 = "";」はconstで変数宣言しているため、変数の再定義は不可というエラー
varだとまたエラーが出てしまうため、letにて変数宣言することで解決。


③
```javascript
const storyTitle = $(".p-story").find(".js-blockTitle--scroll").html();
const storyTitleTrim = $.trim(storyTitle);
let newHtml2 = "";
storyTitleTrim.split("").forEach( v => {
  newHtml2 += "<span>" + v + "</span>";
});
$(".p-story").find(".js-blockTitle--scroll").html(newHtml2);
```
```
error  Unexpected string concatenation  prefer-template
```
→「newHtml2 += "<span>" + v + "</span>";」の記述について、javascriptの言語機能であるテンプレートリテラルにて記述しようというエラー。
newHtml2 += `<span>${v}</span>`;と記述することで解決。
nvidia Jetson × opencv問題

# Jetsonとopencvでエラー発生
散見されるJetson×opencv問題:imp: 

Jetsonを使っている方々に少しでもためになればと思い書きました．
nvidia jetsonシリーズで，既存ライブラリをCMakeなどでビルドしたときにこんなエラーが出たことはないでしょうか？

```
fatal error: opencv2/core/core.hpp: No such file or directory
 #include <opencv2/core/core.hpp>
```
**opencv2/core/core.hpp**と同様に，**opencv2**のincludeパスが見つからないというエラーが出たときはこちらの記事で解決できます．

includeパスでエラーが出ているようなので/usr/includeの中身を見てみると...
![Screenshot from 2022-05-20 12-43-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633039/f29d016a-9472-0f1e-bb2c-30b4e5f76f0c.png)

opencv2という名前のフォルダがなく変わりにopencvという名前のフォルダがありました
なぜだnvidiaさん...

更に```ls```コマンドで調べてみると...
opencvという名前のフォルダが
/usr/include/opencv4/opencv2フォルダのシンボリックリンクになっているようです．
```
ls -l /usr/include

#　以下結果
lrwxrwxrwx   1 root root     29  1月  9 16:44 opencv -> /usr/include/opencv4/opencv2/
```

つまりなぜエラーが出ているかというと...
<font color="red">opencvのもともとのincludeパスは opencv2/... (例 opencv2/core/core.hpp) なはずなのに，jetsonのデフォルトではinclude直下のシンボリックリンクのフォルダ名が opencv となっていて，デフォルトのままではincludeパスを /opencv/... (例 opencv/core/core.hpp)にしないとbuildできない</font>
って感じです
そこはopencv2にしといてくださいって感じですホント

シンボリックリンクのお話はこちらがわかりやすいかと思います
https://qiita.com/go_astrayer/items/ab993cdc420d4f7f50d4


# 解決策
ファイルのインクルードパスを変えるのはさすがにきつすぎる...
ということで
opencvフォルダと同様に，opencv2という名前で/usr/incude/opencv4/opencv2のシンボリックリンクを作成します．
```
cd /usr/include
sudo ln -s /usr/include/opencv4/opencv2 opencv2
```

作成後，opencv2のフォルダが作成されてそこから/usr/incude/opencv4/opencv2に飛ぶことができます


実行後のusr/includeフォルダはこんな感じ

![Screenshot from 2022-05-20 13-09-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633039/dfed50b7-2d4a-e613-bb9c-f400a14fc479.png)


opencv2に入ると中身は/usr/incude/opencv4/opencv2と一緒です
![Screenshot from 2022-05-20 13-13-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633039/942537fd-abce-7142-c52d-ac504d48df3a.png)

これでビルドしてもエラーが出なくなりました！！
Databricksワークスペース検索機能の強化

これまではノートブック名による検索しかできませんでしたが、今回のエンハンスでノートブックの中身に対しても検索ができるようになりました。

https://qiita.com/taka_yayoi/items/e469dded5ee83ae42d24#%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%AE%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E6%A4%9C%E7%B4%A2

:::note info
**プレビュー**
本機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。
:::

:::note info
**注意**
ここで説明する検索機能は、[暗号化に顧客管理キー](https://docs.databricks.com/security/keys/customer-managed-keys.html)を用いているワークスペースではサポートされていません。これらのワークスペースにおいては、サイドバーの**Search**をクリックし、![](https://docs.databricks.com/_images/search-icon.png)**Search Workspace**フィールドに検索文字列をタイプします。タイプするたびに、名前に検索文字列を含むオブジェクトが一覧されます。ワークスペースでオブジェクトを開くには名前をクリックします。
:::


1. サイドメニューの**検索**をクリックします。
![Screen Shot 2022-05-20 at 12.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8a1dc2c8-1348-8111-646e-f5e69ab927f0.png)

1. 検索ダイアログが表示されます。
![Screen Shot 2022-05-20 at 12.43.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c0604193-58bf-c0c8-cb78-6262ce7a6d42.png)

1. 検索キーワードを入力しEnterを押すと、検索結果が表示されます。名称をクリックすることでオープンすることができます。
![Screen Shot 2022-05-20 at 12.43.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a63b7031-6dab-4d6a-af98-e18f33f80959.png)

1. ドロップダウンから種別(Type)を選択することで絞り込みを行うことができます。
![Screen Shot 2022-05-20 at 12.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e79364b4-b659-0744-ea93-434b9221dcc8.png)



### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
サイバー攻撃

## サイバー攻撃
<b>インターネットなどを通じてコンピュータシステムに侵入し、情報の盗聴や窃盗、データの改竄や破壊などのクラッキングを行うこと。
## 標的型攻撃
<b>特定の官公庁や企業など、標的を決めて行われる攻撃。
<font color = blue>APT攻撃</font> - 特定の組織を標的に、複数の手法を組み合わせ、執拗に攻撃を繰り返すこと。
<font color = blue>水飲み場型攻撃</font> - よく利用される企業などのWebサイトにウイルスを仕込み感染させるもの。
## パスワードクラック攻撃
<b>パスワードを割り出し、解析すること。
<font color = blue>辞書攻撃</font> - 利用者IDを一つ定め、辞書にある単語やその組合せをパスワードとして試行するもの。
<font color = blue>ブルートフォース攻撃(総当たり攻撃)</font> - 利用者IDを一つ定め、文字を組合せたパスワードを総当たりして試行するもの。逆に、パスワードを一つ定め、文字を組み合わせた利用者IDを総当たりして、ログインを試行することを<font color = blue>リバースブルート攻撃(逆総当たり攻撃)</font>
<font color = blue>パスワードリスト攻撃</font> - 不正に取得した他サイトの利用者IDとパスワードの一覧表を用いてログインを試行するもの。
### パスワードクラック対策
回数制限、使い回しを避ける等がある。
## サービスを妨害する攻撃
<b><font color = blue>Dos攻撃</font>とは、特定のサーバなどに大量のパケットを送りつけることで想定以上の負荷を与え、サーバの機能を停止させる攻撃。また、これを複数のコンピュータから一斉に攻撃するのは<font color = blue>DDos攻撃</font>という。 
### Dos・DDos攻撃の対策
<b>不正な通信を検知して管理者に通報する<font color = blue>IDS</font>、検知だけでなく遮断まで行う<font color = blue>IPS</font>

詳しくは↓

https://qiita.com/Un-s/items/31e1b6a804ab12a2cae0

https://qiita.com/Un-s/items/ad23d48f8ae542e9575c

## 不正な命令による攻撃
### クロスサイトスクリプティング
<b>利用者の入力データをそのまま表示する脆弱なWebサイトに対して、悪意のあるスクリプトを埋め込んだ入力データを送ることによって、利用者のブラウザで実行させる攻撃。
### 対策
<b>有害な入力を無害化する<font color = blue>サニタイジング</font>をする。
その一つとして、<font color = blue>エスケープ処理</font>がある。
### SQLインジェクション
<b>攻撃者が、脆弱性のあるWebアプリケーションの入力領域に悪意のある間合せや操作を行う命令文を注入することで、管理者の意図していないSQL文を実行させる攻撃。
### 対策
<b>有害な入力を無害化する<font color = blue>サニタイジング</font>をする。
<font color = blue>WAF</font>を導入する。これは、Webアプリケーション専用のファイアウォール。

## なりすましによる攻撃
<b>攻撃者が正規の利用者を装い、情報資産の窃盗や不正行為などを行う攻撃。
<font color = blue>セッションハイジャック</font> - セッションIDを窃盗してなりすます
<font color = blue>DNSキャッシュポイズニング</font> - DNSサーバに偽のドメイン情報を注入して、利用者を偽装されたサーバに誘導する。
<font color = blue>SEOポイズニング</font> - 検索結果の上位に表示にされるようにする
<font color = blue>IPスプーフィング</font> - 送信元IPアドレスを詐称する
<font color = blue>Evil Twins攻撃</font> - 正規のアクセスポイントになりすます。
### ディレクトリトラバーサル
<b>攻撃者がパス名を使ってファイルを指定し、管理者の意図していないファイルを不正に閲覧する攻撃。
### 対策
<b>上位ディレクトリを指定する文字(../)を含むときは受け付けないなど。
## その他の攻撃
<b><font color = blue>ドライブバイダウンロード</font> - Webサイトを閲覧したとき、マルウェアをダウンロードさせる。
<font color = blue>フィッシング</font> - 企業になりすまし電子メールを送り、偽のWebサイトにアクセスさせ、個人情報を騙し取る。
<font color = blue>バッファオーバフロー攻撃</font> - 入力用のデータ領域を超えるサイズのデータを入力することで、想定外の動作をさせる。
<font color = blue>クリックジャッキング攻撃</font> - 著名なサイトのボタンを透明化して配置し、意図しない操作をさせる。
### Webビーコン
Webページなどに埋め込まれた小さな画像のこと。
## 攻撃の準備
<b>攻撃対象に突いての情報収集をすることを<font color = blue>フットプリンティング</font>という。
その一つに<font color = blue>ポートスキャン</font>がある。解放されている攻撃できそうなサービスがあるかを調査する行為のこと。
### ディジタルフォレンジクス
<b>コンピュータ犯罪の証拠となる電子データを集め、解析すること。
podman で、他のコンテナにサービス名でアクセスできないとき

podman-compose や docker-compose から podman を使用していて、network を共有しているはずなのに、あれれ隣のコンテナにサービス名でアクセスできないぞって時の話。

OSはRHEL8で podman は下記の環境で確認しました。

```bash
$ podman version
Version:      3.2.3
API Version:  3.2.3
Go Version:   go1.15.7
Built:        Tue Jul 27 03:29:39 2021
OS/Arch:      linux/amd64
```

## podman-plugin が入ってるかどうか

podman v3 はデフォルトでコンテナ間の通信をサービス名でできないらしく、dnsname というプラグインが必要だそう。下記のコマンドで入れます。

```bash
dnf install podman-plugins
```

## `.dns.podman` domain を付けてアクセスしてみる

大体のケースは先述の plugin で解決すると思うのですが、特定のコンテナでのみ、他コンテナにアクセスできないことがありました。

```bash
# wget http://node-exporter:9100/metrics
wget: bad address 'node-exporter:9100'
```
ですが、 `.dns.podman` domain を付与してアクセスしたところアクセスできることができました。

```bash
# wget http://node-exporter.dns.podman:9100/metrics
Connecting to node-exporter.dns.podman:9100 (10.88.2.53:9100)
saving to 'metrics'
```

よく見ると、[plugin の README](https://github.com/containers/dnsname/blob/main/README_PODMAN.md#example-container-name-resolution) にも記載されていました :sweat_smile: 

```bash
sudo podman run -dt --name web --network foobar quay.io/libpod/alpine_nginx:latest
5139d65d22135e9ecab511559d863754550894a32285befd94dab231017048c2
                                                                                                   ↓ここ
sudo podman run -it --name client --network foobar quay.io/libpod/alpine_nginx:latest curl http://web.dns.podman/
podman rulez
```

ググってもあまり出てこなかったので、メモしておきます :innocent:
【Android Studio】RenderScriptが非推奨になったのでその対応策

# はじめに
[公式から対応策が出ている](https://developer.android.com/guide/topics/renderscript/migrate?hl=ja)が、ライブラリの追加方法に少し手間取ったので、そこを含めて説明。
公式では、

1. スクリプトを Vulkan に移行する
2. 置換ツールキットを使用して組み込み関数から移行する

方法の2つが書かれているが、ここでは2番目の方法について説明。

https://developer.android.com/guide/topics/renderscript/migrate?hl=ja

# 方法
## 1. リポジトリをClone

下記コマンドでツールキットをclone

```
git clone https://github.com/android/renderscript-intrinsics-replacement-toolkit
```

## 2. ビルド

下記コマンドでリリース版をビルド

```
./gradlew :renderscript-toolkit:assembleRelease
```

※デバッグ版をビルドをしたい場合、下記コマンドでビルド

```
./gradlew :renderscript-toolkit:assembleDebug
```

すると、以下の場所にaarファイルが作成される。
```
renderscript-intrinsics-replacement-toolkit\renderscript-toolkit\build\outputs\aar\renderscript-toolkit-release.aar
```

<img width="300" alt="aar" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/af623d0b-146b-060d-7340-943e33abd0e5.png">

## 3. toolkitの使用

組み込みたいプロジェクトの直下(appと同列部分)にsdk-coreフォルダを作成し、その中に先ほど生成されたaarをコピー。
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/d6852942-40cf-919a-c9fc-4326300ca74e.png)

sdk-coreフォルダの中に以下のようなbuild.gradleファイルを新規追加。
``` build.gradle
configurations.create("default")
artifacts.add("default", file('renderscript-toolkit-release.aar'))
task testClasses {}
```

プロジェクトフォルダ直下の```settings.gradle```にincludeするフォルダ名を追記。
``` settings.gradle
include ':app', ':sdk-core'
```

build.gradle(:app)に以下の文を追加。
```build.gradle
dependencies {
	//(省略)
	implementation project(':sdk-core')
}
```

参考サイト: [Android Studio で AARファイルを作って読み込む](https://qiita.com/izuki_y/items/bd61a2cf8473bf6bd9fb)

https://qiita.com/izuki_y/items/bd61a2cf8473bf6bd9fb
DatabricksノートブックにおけるSQLセルとPythonセルのデータのやり取り

本記事で説明しているノートブックはこちらです。

https://github.com/taka-yayoi/public_repo/blob/main/interaction%20between%20SQL%20and%20Python/Interaction%20between%20SQL%20and%20Python.py

SQLを用いてデータをロードし、Pythonを用いて結果を探索したいと思うかもしれません。Databricksノートブックの新機能としてSQLセルとPythonセルでネイティブにデータのやり取りが行えるようになりました。

DatabricksのPythonノートブックでは、SQL言語セルから得られるテーブルの結果は、自動的にPythonデータフレームとして利用できるようになります。Pythonデータフレームの名前は`_sqldf`となります。

https://qiita.com/taka_yayoi/items/dfb53f63aed2fbd344fc#%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E3%81%ABpython%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6sql%E3%82%BB%E3%83%AB%E3%81%AE%E7%B5%90%E6%9E%9C%E3%82%92%E5%8F%82%E7%85%A7

# データロード

Sparkデータフレームとしてデータをロードし、一時ビューとして登録します。

```py:Python
path = "/databricks-datasets/learning-spark-v2/flights/departuredelays.csv"

df = spark.read.option("inferSchema", True).option("header", True).csv(path)
df.createOrReplaceTempView("departure_delays")
```

# SQLからのアクセス

データは一時ビューとして登録されているのでSQLでアクセスできます。SQLで集計を行います。

```sql:SQL
%sql
SELECT origin, destination, count(*) as num_flights
FROM departure_delays
GROUP BY origin, destination
ORDER BY num_flights DESC
```

結果が以下のように表示されます。SQLの実行結果は`_sqldf`というSparkデータフレームに格納されます。

> SQL cell result stored as PySpark data frame `_sqldf`

![Screen Shot 2022-05-20 at 12.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/49b0d789-2f4a-342a-272c-ca725aaec7db.png)

# Pythonからのアクセス

Pythonセルからデータフレーム`_sqldf`にアクセスします。

```python:Python
display(_sqldf)
```

![Screen Shot 2022-05-20 at 12.06.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b4f89bc5-93fe-caba-ea0a-b4b524be7e79.png)

pandasデータフレームに変換して、matplotlibを用いた可視化を行います。

```py:Python
pdf = _sqldf.toPandas()
```

```py:Python
import matplotlib.pyplot as plt

# 出発地がLAXの上位5件に限定
lax_pdf = pdf[pdf["origin"]=="LAX"][0:5]

x = lax_pdf['destination']
y = lax_pdf['num_flights']
label_x = lax_pdf['destination']

# 中央寄せで棒グラフ作成
plt.bar(x, y, align="center")           
plt.xticks(x, label_x)  # X軸のラベル
plt.show()
```
![Screen Shot 2022-05-20 at 12.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1cc6df88-89e5-bac8-6729-c91791bf2ce4.png)

これまで以上に、SQLが得意とする処理はSQL、Pythonが得意とするPythonと棲み分けをしながらシームレスにロジックを記述できるようになりました！

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
[Git] コミットを修正する

# 直前のコミット

## commit --amend

```zsh
git commit --amend
```

### reset-author

コミットの作者もリセットできる

```zsh
git commit --amend --reset-author
```

# 古いコミット

## rebase -i

```zsh
git rebase -i HEAD~n 
```

コマンドで、デフォルトのテキストエディタに直近 n コミットの一覧を表示できる
修正したいコミットの前の`pick`の文字を`edit`に変更して保存・終了する

内容修正した後

```zsh
git add .
git commit --amend
git rebase --continue
```

# Reference

https://backlog.com/ja/git-tutorial/stepup/28/

https://backlog.com/ja/git-tutorial/stepup/33/
databricksのクラスターが勝手に消えてしまうときは

# databricksのクラスターが勝手に消えてしまう

databricksで作成したクラスターをしばらく使わずに放置していると、
勝手にクラスターが削除されていました。。。

ライブラリやinit Scriptなどを再設定しなおさないといけないので困りました。

# 原因

オールパーパスクラスターは未使用期間が30日にあると削除されるようです
（ジョブクラスターは除く）

> 30 days after a cluster is terminated, it is permanently deleted. To keep an all-purpose cluster configuration even after a cluster has been terminated for more than 30 days, an administrator can pin the cluster. Up to 100 clusters can be pinned.
> [Manage clusters \| Databricks](https://docs.databricks.com/clusters/clusters-manage.html#pin-a-cluster)

# 解決法

オールパーパスクラスターは「ピン」しておけば勝手に削除されなくなります
ピンが明るいオレンジ色になっていればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022607/b9d09cb1-d85b-b5dd-57f2-c831ff71899b.png)
社内NASサーバーをGitのリポジトリにする方法

## 経緯
社内の文化としてSVNを使っているが、どうにも使い勝手が悪くGitに移行したいと考えていた。
しかし、Gitを導入するには社内サーバーに環境構築 or Github等を会社で契約する必要があり面倒。。
そこで、社内NASサーバーにGitのリポジトリを登録することにした。

## 前提条件
- git bashがインストールされていること
- 開発メンバーがNASにアクセスできること

## 手順
1. NASの任意の場所にリモートリポジトリになるフォルダを作成
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280004/c6a09c77-7ca6-cd28-5b96-95a14732ab54.png)

2. 作成したフォルダに移動し、右クリック>Git Bash Hereを押下
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280004/82cc2f81-db7c-9c35-da34-421626689abe.png)

3. 以下コマンドを実行(リモートリポジトリの作成)
  ※「bare」オプションをつけることで、更新情報だけを持つディレクトリになる。そのため、リモートリポジトリを手動で書き換えられるということはなくなる。
  ```bash
  $ git init --bare
  ```

4 . 既存ローカルプロジェクトのディレクトリに移動し、以下コマンドを実施
```bash
$ git init
$ git remote add origin {手順1で作成したディレクトリのパス}
```

5 . 以下コマンドを実行し、リモートリポジトリに登録
```bash
$ git add .
$ git commit -m "Initial commit"
$ git push origin master
```

## まとめ
アクセス権や保守性など突っ込みどころ色々あると思うが、、小規模プロジェクトの開発とかでは使ってみるのもありだとは思う。
リモートリポジトリ作成時はbareオプションを忘れずに。
phpunit のメモ

## 繰り返しのテスト
`@dataProvider`

```php
/**
 * @dataProvider testData
 * @params int  $year1
 * @params int  $year2
 * @params bool $expected
 */
public function testGroupNameValidate($year1, $year2, $expected)
{
    $this->assertSame($expected, $year1 === $year2);
}

public function testData()
{
    return [
        [2022, 2022, true],
        [2022, 2023, false],
        ...
    ];
}
```

## 繰り返しが少なければ
`@testWith`

```php
/**
 * @testWith [2022, 2022, true]
 *           [2022, 2023, false]
 */
public function testGroupNameValidate($year1, $year2, $expected)
{
    $this->assertSame($expected, $year1 === $year2);
}
```

## 例外のテストで例外発生後にDBチェックとか別のアサートしたい
try~catch と `assertInstanceOf()`　で例外を検証すればよい

```php
try {​
    $class->execute();
    $this->fail('例外発生なし');
}​ catch (\Exception $e) {​
    $this->assertInstanceOf('App\Exceptions\CustomException', $e);
    $this->assertEquals($expectedMsg, $e->getMessage());
}​
```
Terraformオプション

### terraform initオプション
```
-backend=false         この設定に対してバックエンドまたはTerraform Cloudの初期化を無効にし、代わりに以前に初期化されたものを使用します。
                       エイリアス: -cloud=false

-backend-config=path   設定ファイルの 'backend' ブロックにあるものとマージされる設定です。
                       キー/バリューを割り当てたHCLファイルへのパス(terraform.tfvarsと同じ形式)か、'key=value'の形式で、複数回指定することができる。
                       バックエンドの種類は設定自体に含まれている必要があります。

-force-copy            新しい状態のバックエンドを初期化する際に、状態データのコピーに関するプロンプトを出さないようにする。
                       これは、すべての確認プロンプトに対して「yes」を提供することと同じです。

-from-module=SOURCE    初期化する前に、指定されたモジュールの内容をターゲットディレクトリにコピーします。

-get=false             この構成でモジュールのダウンロードを無効にします。

-input=false           対話式プロンプトを無効にします。
                       対話的なプロンプトを必要とするアクションがあり、入力が無効になっているとエラーになることに注意してください。

-lock=false            バックエンドの移行中に状態をロックしないようにします。
                       これは、同じワークスペースに対して他の人が同時にコマンドを実行する可能性がある場合、危険です。

-lock-timeout=0s       状態ロックを再試行する時間。

-no-color              指定すると、出力に色を付けません。

-plugin-dir            プラグイン・バイナリを含むディレクトリ。
                       このフラグは、プラグインのデフォルトの検索パスをすべて上書きし、プラグインの自動インストールを防止します。
                       このフラグは複数回使用することができます。

-reconfigure           バックエンドを再設定し、保存されている設定を無視します。

-migrate-state         バックエンドを再設定し、既存の状態の移行を試みます。

-upgrade               設定された制約の中で許可された最新のモジュールとプロバイダーのバージョンをインストールし、依存関係のロックファイルに記録されたバージョンを正確に選択するというデフォルトの動作をオーバーライドします。

-lockfile=MODE         依存関係のロックファイルモードを設定します。
                       現在、"readonly" のみ有効です。

-ignore-remote-version Terraform Cloudとリモートバックエンドにのみ使用されるレアなオプションです。
                       これを設定すると、ローカルとリモートのTerraformのバージョンが互換性のある状態表現を使用しているかどうかのチェックを無視し、不一致の可能性がある場合でも処理を続行させることができます。
                       詳細はTerraform Cloudを使ったTerraformの設定に関するドキュメントを参照してください。
```
Googleブログデータを取得するサンプルコード(blogId,apiKey)

# 概要
単に、ブログデータだけを取得するのであれば、Googleログインは不要で、$.ajax()を使用して取得できることを確かめました。ブログの投稿、更新、削除するには、GoogleログインしてOauth2認証をする必要があると思います。

``` 
<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8" />
    <script src='https://code.jquery.com/jquery-1.12.4.js'></script>
  </head>
  <body>
      <h1>ブログデータの取得サンプル(ログインなし)</h1>
      <h3>
単に、ブログデータのみを取得するには、Googleログインは不要であることを
確認するためのサンプルです。</h3>
      
    <script type="text/javascript">
      /**
       * getPost()
       * ブログの取得、表示
       */
      getPost();
      //************************************************************************
      //単に、ブログのデータを取得するのみであれば、
      //Googleログインは不要
      //ブログIDとapiKeyがわかっていれば、OK
      //************************************************************************
      function getPost() {
                  //blogger API を実行し、全ての記事を取得する
                  //一回で50件を取得 非同期
                  //apiKeyが必要
                  $.ajax({
                      type: "GET",
                      url: "https://www.googleapis.com/blogger/v3/blogs/6823772994948811867/posts?maxResults=50&key=AIzaSyBSddAs9z_DsY75AxeOv83s1AGHMP_6-vM",
                      cache: false,
                      scriptCharset: 'utf-8',
                      success: function (data) {
                         //dataオブジェクトで、ブログデータを取得
                         //このサンプルのブログIDは「いやし音楽(スマホ)サイト(https://sma-easy.blogspot.com/)のIDを使用
                         //apiKeyは、サイト運用者側で取得したもの。
                         alert("取得完了　"+data.items[0].title); 


                      }

                  });
    }
    </script>
  </body>
</html>

``` 
[getPost()サンプル](https://blog-tool.tecoyan.net/gsi_no_login.html)



# 確認したかったこと
このサンプルで確認したかったことは、ブログデータの取得には、Googleログインが不要なことです。　特に認証は求められません。そのため、二つのパラメータがわかれば、だれでも取得できるということです。
上記のjavascriptコードの$.ajax()リクエストだけで、ブログデータを取得できます。
サンプルでは4件のブログしか登録していませんが、nextTokenを使えば、何件でも繰り返し
リクエストできます。一回のリクエストではMax50件です。

# あとがき
大変短い記事ですが、とりあえず、確認したかったことの一点に絞りました。
あとあと、補足して行きたいと思います。










#
特定のページだけをwordpress化する（下層ページ）

＃＃ 1ページだけの場合、独自テーマ作ってその中にpage.phpを入れる。

##　ルート直下のhtaccessをindex.htmlを優先してみるように記述（これでトップページはindex.htmlを参照してくれる。）

## 固定ページで新規ページを作成し、（任意のページの名前でいい）パーマリンク設定から、recruitなど、固定ページのurlを入力

## サブディレクトリのwordpressをルートに移動する方法で手順を行う。

https://dezanari.com/wordpress-to-root/
PHP_CodeSnifferの導入方法と解説

## はじめに
今回は、コーディング規約に[CakePHP Code Sniffer](https://github.com/cakephp/cakephp-codesniffer)を使用します。

## PHP_CodeSnifferとは
PHP_CodeSnifferとは、**指定したコーディング規約に沿った構文チェック**を行ったり、
違反があったら**自動で修正することが出来る静的解析ツール**のことです。

https://github.com/squizlabs/PHP_CodeSniffer

https://github.com/cakephp/cakephp-codesniffer

## インストール
```
$ composer require --dev cakephp/cakephp-codesniffer
```
## パスをセット
```
$ set PATH=C:\work\test\my_app_name\vendor\bin;%PATH%
$ set PATH
Path=C:\work\test\my_app_name\vendor\bin;
```

パスはプロジェクトによって違うため、**phpcsファイルの場所を指定**してください。
また、あとで**環境設定でパスを通してください。**
## コーディング規約のリストを表示
```
$ phpcs -i
The installed coding standards are MySource, PEAR, PSR1, PSR12, PSR2, Squiz, Zend, CakePHP and levomatCodingStandard
```
## オプションの表示
```
$ phpcs -h
```
- --standard 規約をセット
- --colors 色を表示
- -p 実行の進行状況を表示
- -s すべてのレポートにスニフコードを表示
## コーディング規約を指定して実行
```
$ phpcs --colors -p -s --standard=CakePHP src/ tests/
```
:::note warn
コードをCakePHPコーディング規約と照合する場合は、--standardコマンドライン引数を使用します。
上記ではCakePHPを使用しています。
:::

## 実行
#### composerにPATHを通している場合
```
$ composer cs-check
```
#### 上記以外
```
$ phpcs --colors -p -s --standard=CakePHP src/ tests/
```
## 実行結果
```
> phpcs --colors -p -s --standard=CakePHP src/ tests/"
. 1 / 1 (100%)

FILE: ...tdocs\project\src\Model\Table\ArticlesTable.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------
 109 | ERROR | Double space found
 185 | ERROR | Double space found
----------------------------------------------------------------------
Time: 506ms; Memory: 12MB
```

## コーディング規約のカスタマイズ
こちらに記載いたしました。

https://qiita.com/Ken_tk/items/eacc18958e41716bed78

## 最後に
導入すればコーディング規約に沿ってるかどうか簡単に検知してくれるため
非常に便利です。是非、使ってみてください。
paiza cloudを使ってみてのAWSとの違い

この前、Paiza cloudのベーシックプランに登録し（無料から移行）、数日使った感想をお伝えします。

# 登録した目的
UdemyのLaravel講座をやっていて（とことんやってみようLaravel）、その講座でPaizaCloudを使っていたことから。

# 感想
## エディタ
エディタへのコードの記述はAWSと大差ありません。
## コンソール（ターミナル）
画面が大きく出るので、使いやすい部分はある。（AWSも画面を広げれば同じ）
## 操作性
UIはPaizaのほうが見やすい。ただし、プロジェクト作成時にウィンドウが複数開くので、その部分がマイナス。
機能もAWSに軍配。
## 総合的に
どちらも長短あるので、どちらがいいとは言えない。
使ている人の感じ方に依存すると思います。

以上が感想です。
StripeのPayment Linksで、UTMコードを設定してGoogle Analyticsでキャンペーンデータを収集をする


広告やSNSでのキャンペーンでは、Google Analyticsを利用した効果測定を行うことがあります。

https://support.google.com/analytics/answer/1033863

この記事では、StripeのPayment Linksを利用した決済で、URLにキャンペーンパラメータを追加してトラッキングする方法を紹介します。

## トラッキングをするために必要な、Payment Linksの設定

Payment Linksで支払いリンクを作成する場合、Google Analyticsでのトラッキングは「注文完了後のページ」で実施します。

そのため、支払いリンクを作成する際には、[Stripeが用意する確認ページ]を**表示しない**設定にする必要があります。

![スクリーンショット 2022-05-16 15.15.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/9e87d43d-c4c7-8445-727e-b61c66865c5b.png)

キャンペーンデータの文字列は、「アクセスがあったURLにデータが含まれていれば、それを自動的に追加」します。

そのため、設定画面では`utm_xxx`を事前に登録する必要はありません。


## トラッキングの流れ

決済や申し込みが完了すると、リダイレクト先として指定したURLに、キャンペーンデータのクエリ文字列が追加された状態でリダイレクトされます。

```bash
// 支払いリンクのURL
https://buy.stripe.com/test_xxxx?utm_medium=earned-email&utm_source=marketo&utm_campaign=campaign-a&utm_content=content-b&utm_term=click-link-c

// 決済完了後に移動するURL
https://example.com?utm_medium=earned-email&utm_source=marketo&utm_campaign=campaign-a&utm_content=content-b&utm_term=click-link-c
```

Google Analyticsでは、「リダイレクト先に指定したページへのアクセス」でトラッキングや分析を行いましょう。

### (2022/5時点)コンビニ決済では、トラッキングができません

Google Analyticsでのトラッキングには、決済完了後にリダイレクトさせる必要があります。

そのため、「コンビニ決済での支払い方法ページ」にリダイレクトされてしまう「コンビニ決済」では、このトラッキング方法が利用できません。

## サポートしているパラメータ

2022/5時点でサポートしているには、以下の項目です。

- utm_source
- utm_content
- utm_medium
- utm_term
- utm_campaign

それぞれの値については、[Google Analyticsのヘルプ記事](https://support.google.com/analytics/answer/1033863)をご確認ください。


## [PR] Stripe開発者向け情報をQiitaにて配信中！

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について週に２〜３本ペースで更新中です。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)
APIの通信準備

# 初めに
今回は、API通信のために必要なRetrofitとOkHttpの実装方法を紹介していこうと思います
ライブラリの準備自体は調べればいくらでも出てくるので簡潔になるように実装部分のみを記載していこうと思います

### 実装方法
```kotlin
    private val httpBuilder: OkHttpClient.Builder
        get() = if (BuildConfig.DEBUG) {
            OkHttpClient.Builder()
                .addInterceptor(
                    HttpLoggingInterceptor().apply {
                        level = HttpLoggingInterceptor.Level.BODY
                    }
                )
                .writeTimeout(writeTimeout.first, writeTimeout.second)
                .readTimeout(readTimeout.first, readTimeout.second)
        } else {
            OkHttpClient.Builder()
                .writeTimeout(writeTimeout.first, writeTimeout.second)
                .readTimeout(readTimeout.first, readTimeout.second)
        }

    @ExperimentalSerializationApi
    fun provide(): ApiClient {
        val contentType = "application/json".toMediaType()
        val format = Json { ignoreUnknownKeys = true }

        return Retrofit.Builder()
            .client(httpBuilder.build())
            .baseUrl(BuildConfig.API_ENDPOINT)
            .addConverterFactory(format.asConverterFactory(contentType))
            .build()
            .create(ApiClient::class.java)
    }

    companion object {
        private val writeTimeout = 30L to TimeUnit.SECONDS
        private val readTimeout = 30L to TimeUnit.SECONDS
    }
```

`addInterceptor`は発信要求と着信応答をログに記載するためのものです

上記の`provide`メソッドをDagger Hilt等でDIすることで使用することができます

### 最後に
自分が初心者の頃にAPIの実装が右も左も分からないことが多かったので何かの役に立てれば幸いです
macos に homebrew で openssl 覚え書き

```
-zsh ~ % which openssl
/usr/bin/openssl
-zsh ~ % openssl version
LibreSSL 2.8.3
-zsh ~ %
```

```
-zsh ~ % brew install openssl
(snip)
openssl@3 is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides LibreSSL.

If you need to have openssl@3 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zshrc
(snip)
-zsh ~ % /opt/homebrew/Cellar/openssl@3/3.0.3/bin/openssl version
OpenSSL 3.0.3 3 May 2022 (Library: OpenSSL 3.0.3 3 May 2022)
-zsh ~ % which openssl
/usr/bin/openssl
-zsh ~ %
```

```
-zsh ~ % echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zshrc
-zsh ~ % source ~/.zshrc
-zsh ~ % which openssl
/opt/homebrew/opt/openssl@3/bin/openssl
-zsh ~ % openssl version
OpenSSL 3.0.3 3 May 2022 (Library: OpenSSL 3.0.3 3 May 2022)
-zsh ~ %
```