OmniAICreator/Qiita-1.07M huggingface dataset:
PowerBI 過去60日間の偏差値を出す

#PowerBIで偏差値をだす
PowerBIで偏差値を出すにはDAX関数の__STDEV.P__で可能だが、
自分は「昨日の実績を基準にした過去60日間の偏差値」が見たく、
上記関数ではうまく実現できなかったため自己流で対処した。

何がしたいかというと、よくある成績表の、日付版のようなものを出したい。
![excel1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217989/ce79ff17-8818-b9ec-2f37-d2bc7451757f.png)

#データを用意する
日付テーブルと、実績テーブルを用意して、リレーションしておく。
![excel2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217989/7644ff03-d885-59dc-682b-9d9f50e79a7f.png)


#偏差値の出し方
（得点 - 平均点）÷標準偏差×10＋50　なので、

(1)得点　(2)平均点 (3)平均点2　(4)標準偏差　(5)標準偏差2　に分けてメジャーを用意してみる。

```
(1)得点--好きなように計算する
メジャー名(得点) = SUM('実績テーブル'[得点])  

(2)平均点--60日間の平均を求める
メジャー名(平均点) =
CALCULATE(
        AVERAGEX('日付テーブル', [メジャー名(得点)]), 
        DATESINPERIOD('日付テーブル'[date], 
        MAX('日付テーブル'[date]), -60, DAY)
        )

(3)平均点2--昨日時点の平均だけを取得
メジャー名(平均点2) = 
CALCULATE(
        [メジャー名(平均点)], 
        '日付テーブル'[date] = TODAY()-1
        )

(4)標準偏差--同じく60日
メジャー名(標準偏差) = 
CALCULATE(
        STDEVX.P('日付テーブル', [メジャー名(得点)]), 
        DATESINPERIOD('日付テーブル'[date], 
        MAX('日付テーブル'[date]), -60, DAY)
        )

(5)標準偏差2
メジャー名(標準偏差2) = 
CALCULATE(
        [メジャー名(標準偏差)], 
        '日付テーブル'[date] = TODAY()-1
        )
```

(3)の式の中に(2)を入れればよいのでは？(5)の式の中に(4)を・・・。
とも考えたが、正しく計算されなかったため、メジャーを分けた。



これをテーブルに反映させ、条件付き書式をつけて完成。
拡張ビジュアルの「Bic Calender」でも利用できると思う。
![pbi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217989/7057b9ab-730d-c38e-a9c9-39a81efb801e.png)

#結果
正直なところ、ただ最大・最小を条件付き書式で見るのと
視覚的意味合いはあまり変わらないことに気づいた。
もっとスマートな方法があるのではないかと思う。
InDesign JavaScript 検索結果を一覧を表示

検索結果を一覧を表示するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
このスクリプトを利用して起こった不具合の責任は取れません。
ご了承下さい。

更新 2021/010/27
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "検索結果を一覧を表示";

//スクリプトの動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名）
app.doScript(function () {

    // ダイアログ
    var dialogueFlg = confirm("「検索と置換」の　『正規表現』　での検索の値で検索した結果を表示します。"
    ,"", scriptName);

    // Noの場合
    if (dialogueFlg == false) {

        // 終了
        exit();
    }

    // ドキュメント全体から検索
    grepResultArray = app.activeDocument.findGrep();
    
    // 検索結果のコンテンツ
    resultContentsArray = [];
    
    for(var i = 0; i < grepResultArray.length; i++){
    
        // 結果のコンテンツを収集
        resultContentsArray.push(grepResultArray[i].contents);
    }
    
    /* 表示 */
    // ダイアログX座標
    var dialogWidthXCoordinates = 0;

    // ダイアログY座標 
    var dialogWidthYCoordinates = 0;

    // ダイアログ幅
    var dialogWidth = (app.activeDocument.layoutWindows[0].bounds[3] - app.activeDocument.layoutWindows[0].bounds[1]) / 2

    // ダイアログ高さ
    var dialogHeight = (app.activeDocument.layoutWindows[0].bounds[2] - app.activeDocument.layoutWindows[0].bounds[0]) / 2

    // 段落スタイル選択用ダイアログ作成
    var textWindow = new Window("dialog", scriptName, [dialogWidthXCoordinates, dialogWidthYCoordinates, dialogWidthXCoordinates + dialogWidth, dialogWidthYCoordinates + dialogHeight]);

    // エディットテキスト追加
    textWindow.add("edittext",[ 20, 20, dialogWidth - 20, dialogHeight - 20],resultContentsArray.join("\r"),{readonly:true,multiline:true});

    // 中央に
    textWindow.center();

    // 表示
    textWindow.show();
    /* ここまで */

//スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);
~~~
開発中の npm モジュールを試す方法

npm モジュールをローカルで開発中に試す方法をメモしておきます。


## 手順

`example-cli` を開発しているとします。下の手順を実行して下さい。

```
cd example-cli
npm run build //ビルドする
npm install -g . //グローバルインストール
```

これで、`example-cli` を使えます。

## 開発が終わったら

開発が終わったら下の手順で綺麗にしておきましょう。

```
npm uninstall -g .
```
GitHubを用いたファイル管理

###目次
***
・GitHub でファイルを管理する方法

###GitHubでファイルを管理する方法
***
大まかな流れは以下の通りです。

・GitHub にリモートリポジトリを作成
・hello フォルダ内にローカルリポジトリを作成
・hello ファイル内のファイルをインデックスに登録
・インデックスに登録されたファイルをコミット
・ローカルリポジトリのファイルをリモートリポジトリにアップロード

|gitコマンド|役割|
|:---|---:|
|git init|ローカルリポジトリの作成|
|git add | ステージング |
|git commit | コミット |
|git push |リモートリポジトリにアップロード|

## GitHubにリモートリポジトリを作成
まず[GitHub](https://github.com/)のトップページからリモートリポジトリを作成します。
「Create　repository」をクリック

ファイル名を入力し、パブリックリポジトリを選択して、新規作成します。

パブリックリポジトリとは、全員が公開されるリポジトリです。非公開にしたい場合は、プライベートリポジトリを選択しましょう。

##ローカルリポジトリへのコミット
次にローカルリポジトリを作成して、フォルダの中身をコミットしていきます。

ターミナルを開き、カレントディレクトリをデスクトップに作成したフォルダディレクトリに変更します。
####ローカルリポジトリを作成
```
git init
```
####ステージング
```
git add .
```
git add . の . はカレントディレクトリに変更があったファイルを意味します。基本的にステージングするときは、git add . としましょう。

####インデックスに登録されたファイルを確認
```
git status
```
####ローカルリポジトリにコミット
```
git commit -m "first commit"
```
-m "コメント" とすることで、コミット時にコメントを残せます。変更した内容などコメントを残すことで変更履歴がよりわかりやすくなります。

##GitHubにファイルをアップロード
最後にローカルリポジトリの中身を GitHub に作成したリモートリポジトリにアップロードします。
まずローカルリポジトリとリモートリポジトリを紐付ける作業をします。
####ローカルリポジトリとリモートリポジトリを紐づけ
```
git remote add origin https://github.com/アカウント名/ファイル名.git
```

次はリモートリポジトリにファイルをアップロードします。
####リモートリポジトリにアップロード
```
git push -u origin main
```
ユーザー名が求められるため、GitHub アカウントのユーザー名を入力して、Enter キーを押しましょう。
次にパスワードが求められるため、パスワードを入力します。パスワードは入力しても画面には表示されないので注意してください。 入力できたら、Enter キーを押しましょう。

リモートリポジトリに作成したファイルがアップロードされれば成功です。Git コマンドと GitHub を使うことで、Web 上でファイル管理できるようになりました。
Cannot import cv2 module. 

# ことの始まり
enrootコンテナ等でGPUを使ったプログラムを動かそうとしていた時に起きたエラー


```shell:出てきたエラー
RuntimeError: Cannot import cv2 module. Please install OpenCV-Python to use WarpFrame.
```
# 解決に至ったコマンド
`apt-get update`
`apt-get install libgl1-mesa-dev`
上記２つのコマンドを入力し、cv2がimportできるか確認したらできた。
それまでに色々入れていたので、もしかしたらそれが効いたかも
また同じ方法でコンテナを作って確認したい。


# やったこと

まずpythonのREPLでcv2がいけないのかを確認
`>>> import cv2`
すると出るエラー

```shell:コマンドライン
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/conda/lib/python3.8/site-packages/cv2/__init__.py", line 5, in <module>
    from .cv2 import *
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
```

なのでこのエラー文をググったら以下のサイト様に辿り着いた
https://cocoinit23.com/docker-opencv-importerror-libgl-so-1-cannot-open-shared-object-file/
このサイト様通りにやったら治り、プログラムも動いたのでokとした。
Dataverse for Teams 環境にソリューションをインポートする

Dataverse for Teams で作成したアプリはソリューションとして ZIP ファイルにエクスポートし、別のチーム（環境）に展開することが可能です。
本エントリーでは、 Webinar で紹介させていただきましたサンプルアプリの提供および展開方法について説明します。

ファイルについては以下にあります。
https://github.com/satoshyteams/WebinarSample/

「お問い合わせアプリ拡張版.zip」をダウンロードいただき、1回解凍してください。
（中にさらに zip ファイルがありますが、こちらはそのまま使います）

1. Teams を起動します。
2. 新しいチームを作成します。![qiita211027_01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/c4032abe-cee3-63c8-efe5-dd6bf8e393d8.jpeg)

3. [最初から]-[パブリック（またはプライベート）]を選択しチーム名を入力します。![Qiita211027_02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/66680a2f-2939-5559-f5c3-f99d8981ed15.jpeg)

4. [作成]をクリックするとチームが作成されます。
5. 作成されたチームの一般チャネル（または新しく作ったチャネル）のタブにある「＋」をクリックします。![Qiita211027_03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/7b3d79d1-ed94-f8e7-4112-6bb0aea2b737.jpeg)

6. Power Apps を選択します。![Qiita211027_04.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/20ba781b-9eaf-9ff1-d088-207f0ac8c00e.jpeg)

7. [追加]をクリックします。
8. [Power Apps でアプリを作成します]をクリックします。![Qiita211027_05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/1ea6a869-45ee-61cd-4647-75ed9bde4053.jpeg)

9. 準備しています　というポップアップが出たらしばらく待ちます。
![Qiita211027_06.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/802d7c5d-ebe3-459b-e200-91906b80672e.jpeg)

※ここで Dataverse for Teams 環境が作成されています。

10. Power Apps 編集画面が表示されたら適当に名前を付けて保存します。![Qiita211027_07.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/65aed3ae-dd41-7879-e73a-de5164f3c639.jpeg)

11. [ホーム]をクリックします![Qiita211027_08.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/234f9036-f9ef-73bd-60cd-041ef8ad6d90.jpeg)

12. [さらに表示]をクリックします。![Qiita211027_09.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/6868ac39-c50a-c6d2-6a16-059b3eb7b833.jpeg)

13. 左ペインでチームを選択し [ すべて表示 ] をクリックします。![Qiita211027_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/ee05da2a-8704-0947-80ef-b99fad63f9cd.jpeg)

14.[インポート]をクリックし、 DV4Tお問い合わせ_export.zip を選択します。![qiita211027_11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/a6320998-28ca-d41d-166d-b4c3fdd90d96.jpeg)

15. インポートするアイテムを変更(User, Chatbot, Model-Driven App User Settingをはずす）[インポート]ボタンをクリックし、しばらく待ちます。![Qiita211027_12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/23fa445a-f789-d352-b828-1b21d8f1fff2.jpeg)


※ファイル名を変更しているとインポートに失敗することがあります。
※インポートするアイテムを変更しないとインポートに失敗することがあります。

インポートが完了すると当該環境に「DVお問い合わせアプリ担当者」「DVお問い合わせアプリ拡張版」というアプリと「お問い合わせ」「お問い合わせ詳細」というテーブル（データベース）が作成されます。

これらのアプリの利用方法につきましては Webinar で解説した通りです。
では、実際に何をしているのか？など動作詳細については次回以降で触れていこうと思います。
VMware Workstation 16 Pro / Player で Windows 11 をインストール／使用する

ブログでも書いていますが、ダイジェストをこちらにも投稿しておきます。
オリジナルの記事はこちらです。
[VMware Workstation 16 Pro / Player で Windows 11 をインストール／使用する](https://imaisato.hatenablog.jp/entry/2021/10/26/103657)

# Windows 11 を仮想マシンで使うときの課題

みなさんもご存じの通り、Windows 11 をインストールするハードウエアの条件が厳しくなって、それに伴って仮想マシンにいストールするのに苦労されていると思います。例えば、

* VMware Workstation 16 Pro では、TPM やディスクの暗号化を使わない Windows 10 までの仮想マシン構成では Windows 11 がインストールできない。
* VMware Workstation 16 Player では、そもそもディスクの暗号化や TPM の設定ができないので Windows 11 を扱うことができない。
* VMware vSphere Hypervisor だけでは vTPM が使えないので、Windows 11 の仮想マシンをインストールできない。
* vSphere 6.5 までの環境では vTPM 無いので Windows 11 は使えない。

などが代表的です。
これらは vSphere 6.5 以前のようにそもそも機能がない場合は問題外ですが、、それ以外ではごにょごにょすることでインストールと実行ができることは前回6月の記事でご説明しました。
[VMware Workstation 16 Pro / Player で Windows 11 受け入れ準備をするには](https://qiita.com/inasato/items/7eb66cd51c17c133f844)
でも、vSphere 7.0 Update 2 以降、VMware Workstation 16.2.0 Pro / Player では、実はそんなに難しく考えることなく Windows 11 をれることができます。これは前回の記事時点では vSphere 7.0 Update2 は出ていたのですが、VMware Workstation 16.2.0 Pro / Player は出ていなかったので気づかなかったことなのですが、簡単にできるので紹介します。

# VMware の仮想環境に Windows 11 をインストールしてみる
ここ Qiita では文字だけですが、先にご紹介したブログでは画面キャプチャもありますので、併せてご覧ください。
## Software TPMを有効にして仮想マシンを作成
まずいつもの通りに仮想マシンを作成していきます。注意点は以下の通りです。

* 仮想マシンのハードウエア互換性の選択は「Workstation Beta」を選ぶ必要があります。「Workstation 16.x」にしてしまうと仮想ハードウエアバージョンが 18 になってしまうのでこの機能が使えません。「ESXi 7.0」を選択すると仮想ハードウエアバージョンがもっと古い 17 になってしまいますので注意が必要です。
* ゲスト OS の選択は Windows 11 がありませんので、そのまま Windows 10 x64 を選びます。これを選択すると「guestOS = "windows9-64"」が仮想マシンに設定されます。
* ファームウエアは Windows 11 で必要な UEFI を選択します。ここで vTPM では必須だった「セキュアブート」はチェックを入れません。
* セキュアブートしない

そして、仮想マシンができたら仮想マシンの作成が完了後はすぐに起動しません。起動してしまうとここまでやったことが「無駄」になることがあるので、作成したら VMware Workstation 16.2.0 Pro をすぐに終了します。
次に

* 作成した仮想マシンの .vmx ファイルを編集し、以下の 1行を追記します。
```
managedvm.autoAddVTPM = "software"
```

追記が終わったら VMware Workstation 16.2.0 Pro を起動します。自動的に Trasted Platform Module が追加されていれば成功です。この後は普通に仮想マシンを起動し、Windows 11 のインストールをするだけです。

## VMware Workstation 16.2.0 Player での動作は？
VMware Workstation 16.2.0 Pro で作成した仮想マシンを、そのまま VMware Workstation 16.2.0 Player で開けば使えます。簡単ですね。

# vSPhere 7 での動作は
同じようにやれば動くと思います。なので、個人で無償の vSphere Hypervisor を使っている場合で Windows 11 を使いたい人も、この手順でチャレンジしてみてください。

# Windows 10 からのアップグレードでは？
ここの手順のままでできます。設定で TPM 有効にするためにディスクの暗号化をしなければならないということは全くなく、既存の Windows 10 仮想マシンの .vmx に先の 1行を追記したあとに、仮想マシンを起動してアップグレードするだけです。

Windows 11 を仮想マシンにインストールしたい人、ぜひチャレンジを。
【Sentry】Reactプロジェクトで本番環境のみエラー監視を行う

#はじめに
作成したプロジェクトでフロントエンド側のエラー監視にSentryを導入したのでメモを残します。

#実装
大体は公式Docs通りなのですが、ステージング環境のエラーも検知してしまうのが煩わしかったので、`if (process.env.NODE_ENV === 'production')`で本番環境のみ`Sentry.init()`を行うようにしました。

`Sentry.setUser()`には、エラーが起こったユーザの`id` `username` `email`が入ってくるようにしました。

SPA全体のエラーを検知するように、`<Router>`以下で`<Sentry.ErrorBoundary>`をラッピングするようにしました。
エラーを検知した際に表示される画面として`<Fallback />`というコンポーネントを作成し、エラー内容が表示されるようにしました。

```tsx:App.tsx
import * as Sentry from '@sentry/react'
import { Integrations } from '@sentry/tracing'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

// 本番環境のみエラーを送信する
if (process.env.NODE_ENV === 'production') {
  Sentry.init({
    dsn: SENTRY_PUBLIC_DSN,
    integrations: [new Integrations.BrowserTracing()],
    tracesSampleRate: 1.0,
    environment: process.env.NODE_ENV,
  })
}

const Fallback = ({ error }: { error: Error }) => (
  <div className='container' style={{ fontSize: 18, marginTop: 50, marginBottom: 500 }}>
    {error.toString()}
  </div>
)

const AppRouter = () => {
  const { data, loading } = useInputQuery()

  if (loading || !data) return <ContentLoader />

  Sentry.setUser({
    id: data.u_uid,
    username: data.u_name ?? '',
    email: data.u_mail,
  })

  return (
    <Router>
      <Sentry.ErrorBoundary fallback={({ error }) => <Fallback error={error} />}>
        <Switch>
          <Route path='/1'>
            <ComponentOne />
          </Route>
          <Route path='/2'>
            <ComponentTwo />
          </Route>
          <Route>
            <NotFound />
          </Route>
        </Switch>
      </Sentry.ErrorBoundary>
    </Router>
  )
}

if (document.getElementById('app')) {
  ReactDOM.render(
        <AppRouter />,
    document.getElementById('app')
  )
}
```

#参考資料

https://docs.sentry.io/platforms/javascript/guides/react/
ESXi Arm Edition version 1.6 — Oct 6, 2021 の登場

VMware Flings で提供されている、ESXi Arm Edition の最新版、ESXi Arm Edition version 1.6 Build 18427252 が公開されました。
1.5 からの変更点は軽微で、新しいハードウエアをサポートしたことがメインで、特に機能の追加や変更はありません。追加された新しいハードウエアのサポートは以下の通りです。

* Oracle Cloud InfrastructureのAmpere Altraベース BM.Standard.A1.160 の実験的サポート
* Marvell Armada A8040 / Octeon TX2CN9132チップセットの実験的サポート
* Socionext SynQuacer Developerboxの実験的サポート

私のようにラズパイ使いの人には影響ない修正です。
詳細はこちらのブログに書きました。
[ESXi Arm Edition version 1.6 — Oct 6, 2021 の登場](https://imaisato.hatenablog.jp/entry/2021/10/27/095212)
tmux

#コマンド
|やりたいこと|コマンド|
|--|--|
|使い方|prefixはctrlからのbからの〇〇
|
|セッション削除|tmux kill session -t 番号|
|全てのセッション削除|tmux kill-server|
|新しいウィンドウ作成|prefix c|
|||
|||
|||
|||
|||
|||
|||
|||
|||
|||
|||

ウィンドウ削除
prexif &
ウィンドウ一覧表示
prefix w
ペイン分割
prefix %
ペイン切り替え
prefix o
ペイン前のに戻る
prefix ;
配置変える
prefix スペース
設定ファイルのリロード
tmux source-file ~/.tmux.conf
終了
exit
Selenium SelectでSelectタグが選べないときの対処法

#実現したいこと
webサイトのドロップダウンから特定の選択肢を選択する

#実現するための案
そのドロップダウンリストにselectタグがついていたので

```python
from selenium.webdriver.support.select import Select

dropdown = driver.find_element_by_css_selector(
        'select.クラス名')
    select = Select(dropdown)
    select.select_by_value('1')
```
といった感じでオプションタグを選択する

#困ったこと
selectタグがついているにも関わらず、エラーが発生する

```python
selenium.common.exceptions.NoSuchElementException: Message: no such element: 
Unable to locate element: {"method":"css selector","selector":"select.クラス名"}
```

#対処法
`driver.find_element_by_css_selector`で直接選択肢をクリックするようにした。
つまり、

```python
driver.find_elements_by_css_selector('option.選択肢のクラス名')[3].click()
```
とした。`[3]`としているのは同一のクラス名が複数あったから。chromeのコンソールを見ていると上から4番目だったので指定した。

#原因
はっきりしたことはわからない。しかし別のselectタグで、name属性があるものはselectで選択することができた。

```python
dropdown = driver.find_element_by_name(
        'select.name属性')
    select = Select(dropdown)
    select.select_by_value('1')
```
このことから、`css_selector`でクラスを指定するところで何かうまくいっていないのかとは思った
GitHubにSSH接続してみた

#なぜSSH接続するのか
HTTP形式やHTTPS形式などGitHubで使える通信規格は何種類かあり、
一般的にはHTTP、HTTPS形式が使われています。
しかし、SSHプロトコルを使うことで、リモートサーバーや各種サービスへの接続や認証が可能となり、GitHubに接続する際にユーザー名などを省略することができます！
#接続方法
GitHubにSSH接続するためには、鍵の登録が必要となります。

#公開鍵、秘密鍵を作成する

鍵とは公開鍵と秘密鍵のことです。公開鍵は一般に公開するもの、秘密鍵はほかの人に見られてはいけません。
そのため秘密鍵は自分で保持し、公開鍵は相手（今回であればGItHub）に送ります。
#公開鍵と秘密鍵のペアを生成
まずは鍵を作成するため、鍵を入れるフォルダーに移動します。

```
$cd ~/.ssh
```
初めて鍵を作成するときには何も入っていない状態です。
次のコマンドで鍵を作成します。

```
$ssh-keygen -t rsa 
``` 
作成する際にいろいろ聞かれますが、そのままEnterを押すと、id_rsaとid_rsa.pubの二つの鍵が生成されます。

```
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

:::note info
すでに鍵を生成している場合、上書きされるので注意してください(以下）
:::

```
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
/home/user/.ssh/id_rsa already exists.
Overwrite (y/n)?
```

#GitHubに公開鍵をアップする
[https://github.com/settings/ssh](https://github.com/settings/ssh)

で公開鍵を設定できます。

画面右上の「Add SSH key」のボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2219999/291dd439-8f66-2db1-fdd3-830e582d292a.png)

「title」に公開鍵名、「key」に公開鍵の中身を入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2219999/a3d66320-5c10-d9d8-2956-d03574d022c6.png)

鍵の中身のクリップボードへのコピーは

Macの場合

```
$ pbcopy < ~/.ssh/id_rsa.pub
```

Windowsの場合

```
$ clip < ~/.ssh/id_rsa.pub
```

Ubuntuの場合

```
$ cat ~/.ssh/id_rsa.pub | clip.exe
```

でコピーできます。

#接続を確認する

ターミナルに戻り、以下のコマンドを打って確認してください。

``` 
$ ssh - T git@github.com
```

```
Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
``` 
と返ってきたら成功です！！

しかし...

鍵を作成する際に、名前を指定していない場合はうまくいかないかもしれません。
理由として、
ssh接続を行う際、「~/.ssh/id_rsa」、「~/.ssh/id_dsa」、「~/.ssh/identity」しかデフォルトでは見にいかないからです。

これに対応するためにsshディレクトリ内にconfigを作成します。

```
~/.ssh/config
```
configフォルダに

```
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/id_git_rsa #ここに自分の鍵のファイル名
  User git
```

を作成し、再び接続すると成功します。

再び接続

```
$ssh -T git@github.com
```

```
Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
```

今度こそSSH接続が成功しました！

#GitLabなどにもSSH設定したい場合

自分の場合はGitLabにもＳＳＨ設定していたため、Configファイルにそれぞれ設定してあげる必要がありました。

以下

```
Host gitlab 
		HostName gitlab
		User UserName
    identityFile ~/.ssh/id_rsa
	
Host github
       HostName github.com
	   User UserName
	identityFile ~/.ssh/id_rsa	
	User git

```
Azure仮想マシンをMAC環境で作成したら＠が入力できなくてハマった

#問題点
MACからAzure仮想マシンにリモート接続しているが、＠を入力すると［となってしまう。

#環境
・M1 MacBook Air
・Microsoft Remote Desktop
・Azure仮想マシン（Windows10 Pro）

#やったこと
Azure仮想マシン作成直後はWindowsの設定が英語となっていたので、
関連する設定を全て日本語へ変更したがどうしても@のキー入力だけは治らなかった。

#解決策
Microsoft Remote DesktopではなくParallels Clientを使用してAzure仮想マシンにリモート接続する。

#原因
Microsoft Remote Desktopだと接続時にキーボード情報を英語キーボード固定で送信しているらしい。
詳しくは[こちらのサイト](https://qiita.com/hidecha/items/33624f6ae57d41f3cd86)を参照して下さい。
failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount****/Dockerfile: no such file or directory の対処法

#はじめに
ものすごい初歩的な内容となっております。ただ、こんなことでつまづいて時間を使ってほしくはないために書きました。


#問題

docker build しようとしたらタイトルのエラーが発生しました。

```
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount****/Dockerfile: no such file or directory
```


#原因

ビルドしようと試みた、現在のディレクトリにはDockerfile がないことが原因のようです。

#対処法

Dockerfile のあるディレクトリに移動してビルドすれば解決です。
【JavaScript】関数とオブジェクト⑫　instanceof



#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/1bc515e893737530167d

#目的

* 関数とオブジェクトについての理解を深める

#本題
###1.instanceof

どのコンストラクターから生成されたオブジェクトなのかを確認する

####前提

````js
// 関数Fをコンストラクターとして定義
function F(a,b){
    this.a = a;
    this.b = b;
}

F.prototype.c = function(){}
// インスタンス化
const instance = new F(1,2);
// F {a: 1, b: 2}と出力
console.log(instance);
`````

これがどのコンストラクターから生成されたものなのかを確認するためにinstanceofを使用する

####例1


````js
function F(a,b){
    this.a = a;
    this.b = b;
}

F.prototype.c = function(){}
const instance = new F(1,2);
// instanceofを追加
// tureと出力される
console.log(instance instanceof F);
`````

####例2

戻り値を設定して、Fにオブジェクトが返ってくるようにするとどうなるか

```js
function F(a,b){
    this.a = a;
    this.b = b;
    // 戻り値を設定
    return {a: 1};
}

F.prototype.c = function(){}
const instance = new F(1,2);
// Fはfalseと出力される
// つまり「関数Fから生成されたインスタンスではない」という結果になる
console.log(instance instanceof F);
```

####例3

例1の結果と例2の結果の違いを確認する

````js
function F(a,b){
    this.a = a;
    this.b = b;
    // 戻り値を設定
    return {a: 1};
}

F.prototype.c = function(){}
const instance = new F(1,2);
console.log(instance instanceof F);
// instanceに格納されている__proto__とFのprototypeに等価性があるか確認する
// 結果はfalse
// returnでオブジェクトが返ってきているので,instanceには{a:1}が入っている
console.log(instance.__proto__ === F.prototype);
``````

``````js
function F(a,b){
    this.a = a;
    this.b = b;
    // return {a: 1};　これを省略せずに書くと下記のとおりとなる
    // インスタンス化してresultに格納
    const result = new Object();
    // aに１代入
    result.a = 1;
    // returnでObjectが入ったresultをFに返す
    return result;
}

F.prototype.c = function(){}
const instance = new F(1,2);
console.log(instance instanceof F);
// console.log(instance.__proto__ === F.prototype);
// コントラクター関数からFの値の中身はnew FではなくObjectとなる
// 下記の実行結果はtrueが返ってくる
console.log(instance.__proto__ === Object.prototype);
`````

####例4

このinstanceofで何ができるようになるのか

````js
// 関数を用意
// 引数にargをもたせる
// argには配列もしくはオブジェクトが渡ってくるものとする
function fn(arg){
    // 配列として渡たす場合はpushメソッドを使用
    arg.push("value");
    // オブジェクトとして渡す場合
    arg["key"] = "value";
}
``````

作成元のコンストラクターによってinstanceofを使用して、条件分岐を作ることができる

```js
function fn(arg){
    if (arg instanceof Array){
        // 条件分岐でArrayが配列の場合
        arg.push("value");
    } else {
        // 条件分岐で配列以外の場合（オブジェクト）
        arg["key"] = "value";
    }
    // argの結果が返ってくるように設定
    console.log(arg);
}
// 配列の場合：['value']と出力され0番にvalueが入っている
fn([]);
// オブジェクトの場合：{key: 'value'}と実行されオブジェクトにkey: "value"と値が入っている
fn({});
`````




今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
Starletteで作る Simple Web Server

Starlette は軽量な**ASGI** framework/toolkit です。それによって高速な**asyncio** servicesを構築することが可能になります。

[Starlette 公式サイト](https://www.starlette.io/)


【過去記事】
[Python Asyncio入門](https://qiita.com/sand/items/0e445a13d81d20ea33c3)
[Aiohttpで作るSimple Web Server - Qiita](https://qiita.com/sand/items/971c851598ff59c1c905)
[Starletteで作る Simple Web Server - QIita](https://qiita.com/sand/items/dd622ce4f9249399974c)


```
pip install starlette
```


Web Applicationはstarlette が分担しますが、ここでASGI serverもインストールします。uvicorn, daphne, や hypercornなどがありますが、uvicornがポピュラーなようです。

```
pip install uvicorn
```

公式サイトからのコピペです。

```python:example.py
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route


async def homepage(request):
    return JSONResponse({'hello': 'world'})


app = Starlette(debug=True, routes=[
    Route('/', homepage),
])
```

以下のように起動します。

```
$ uvicorn example:app
```


starletteは以下のような特徴を持つフレームワークです。

* Seriously impressive performance.
* WebSocket support.
* In-process background tasks.
* Startup and shutdown events.
* Test client built on requests.
* CORS, GZip, Static Files, Streaming responses.
* Session and Cookie support.
* 100% test coverage.
* 100% type annotated codebase.
* Few hard dependencies.


このままstarletteの特徴を負うのも良いのですが、最近はstarlette上に構築された **FastAPI** を使うのが流行りのようです。次回は**FastAPI**を見ていきたいと思います。
WSL2でKubernetes v1.21のkindクラスタ作成に失敗する場合の対処MEMO

Docker Desktopの有料化の発表に伴い、自宅のWindows10マシンのDocker環境をWSL2 + Dockerに移行したところ、kindクラスタの作成に失敗したので対処MEMOを記載しておきます。

ちなみにkind v0.12がリリースされたら問題は修正されるはずです。

## 事象

WSL2でkind v0.11.1を使用して`kind cluster create`を実行した場合、Kubernetes v1.21.1のクラスタ生成が行われますが"Starting control-plane"のところで固まり以下のエラーが発生します。（再現性が100%なのかは不明）

```
ERROR: failed to create cluster: failed to init node with kubeadm: command "docker exec --privileged kind-control-plane kubeadm init --skip-phases=preflight --config=/kind/kubeadm.conf --skip-token-print --v=6" failed with error: exit status 1
Command Output: I1016 08:52:21.466228     216 initconfiguration.go:246] loading configuration from "/kind/kubeadm.conf"
...
I1016 08:53:02.942960     216 round_trippers.go:454] GET https://kind-control-plane:6443/healthz?timeout=10s  in 0 milliseconds
[kubelet-check] Initial timeout of 40s passed.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
...
```

## 原因

以下のIssueが原因です。

https://github.com/kubernetes-sigs/kind/issues/2323

詳しくは説明しませんが、ざっくりと言うと「WSL2ではsystemdが動作しておらず、これが原因でkubelet起動に失敗する」ようなバージョンの組み合わせがあるため、kindクラスタ作成に失敗します。Issueを見る限りはv1.21以外では発生しないようです。


既に対処PRもmasterブランチにはマージされていますが、後述するように現時点ではリリースはされていません。

https://github.com/kubernetes-sigs/kind/pull/2390


## 対処方法

kind v0.12のリリースで対処PRが盛り込まれる予定ですが、現時点ではv0.12はリリースされていません。もしkind v0.11.x以下のバージョンで問題を回避したい場合は、以下のように**kindクラスタ作成時に`--image`オプションで対処PRで作成されたイメージのタグ(v1.22.1)とハッシュを指定します。**

> NOTE: kindでは各バージョンでkindクラスタ向けのイメージのタグおよびハッシュが固定されているため、タグだけではなくハッシュも含めて指定が必要となります。

```
kind create cluster --image kindest/node:v1.22.1@sha256:e0bf222d7dd1589075117c51740903017b328c59ffb0c3d97187a2b3de1f92b3
```

ちなみにv1.17等のv1.21未満のバージョンであれば本問題は再現しなかったため、古めのバージョンでも問題なければ古いバージョンを指定することでも対処できるようです。
指定可能なバージョンのイメージ情報はkindのReleasesページの各リリースに掲載されているのでそちらを参照してください。

https://github.com/kubernetes-sigs/kind/releases
rospy.loginfo関数を使ってPrint


rospy.loginfoを使用するとプリントされる情報に現在時間がつき便利なときがあります.

1,2,3という3つの数値をloginfoで出力するサンプルは以下のようになります.

```python:loginfo.py
import rospy

rospy.init_node('loginfo')

r = rospy.Rate(10)
while not rospy.is_shutdown():

  rospy.loginfo("num: %s, %s, %s",1, 2, 3)

  r.sleep()
```

実行結果は以下です.

```bash:実行結果
[INFO] [1635289935.448486]: num: 1, 2, 3
[INFO] [1635289935.549028]: num: 1, 2, 3
[INFO] [1635289935.648756]: num: 1, 2, 3
[INFO] [1635289935.749015]: num: 1, 2, 3
[INFO] [1635289935.849047]: num: 1, 2, 3
...
```

- other log level

```
rospy.logdebug(msg, *args)
rospy.logwarn(msg, *args)
rospy.loginfo(msg, *args)
rospy.logerr(msg, *args)
rospy.logfatal(msg, *args)
```
参考
現在時刻をloginfoで出力しているサンプルあり
http://wiki.ros.org/ja/rospy_tutorials/Tutorials/Logging
WSL2でWindowsホストのDNS設定を参照する

## はじめに
:::note warn
2023.11.12追記
**Windows11のWSL2**にてDNSの不調を感じる場合、Windowsのレゾルバを直接参照する機能が提供されているのでそちらをご利用ください。
[利用方法]
1. WSLを最新にアップデート
    ```powershell
    wsl --update; wsl --update --pre-release
    ```
2. .wslconfigに設定を追記
    ```:c:\Users\<ユーザー名>\.wslconfig
    [wsl2]
    dnsTunneling=true
    ```
参考) [WSLでの詳細設定の構成](https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config)

:::
WSL2でDNSサーバを見失った場合、外部の public DNSを指せば良いよというtipsを時折見かけます。
ただ、筆者はこの問題に遭遇したことがないのでそれ自体はよくわかっていません。

別件として、WSL2が参照するDNS proxy(=Windowsホスト)はTCPフォールバックをサポートしていないようです。おそらくこのDNS proxyが搭載された時期の仕様に従っているようで一部DNSサーバと通信できない場合があります。

こうした場合、/etc/resolv.conf に別のDNSサーバを追加してあげればよいのですが、Windowsホストと同様に設定したほうがなにかと都合が良い場合があります。そこで、public DNSではなく、Windowsホストが参照している情報を入手する方法を考えます。


## WindowsのことはWindowsに聞け

Windowsの情報を参照するには PowerShellが役立ちます。
今回知りたいことは2点です。

1. Windowsホストが参照しているDNSサーバ
2. Windowsホストのドメインサーチサフィックス


###DNSサーバを取得する

WindowsのDNSサーバは接続毎に管理されているので現在有効な(=デフォルトゲートウェイになっているインタフェース)のDNSサーバを取得します。

```powershell:DNSサーバの取得
Get-NetRoute -DestinationPrefix '0.0.0.0/0'|Get-DnsClientServerAddress
```

人間が見るにはこれでよいのですが、機械的に処理するには余計な情報が多いので少し加工します。

```:powershell:DNSサーバの取得(抽出情報)
Get-NetRoute -DestinationPrefix '0.0.0.0/0'|Get-DnsClientServerAddress|%{echo "nameserver $($_.ServerAddresses)"};
```

% は foreach の aliasです。取得したDNSサーバオブジェクトをforeachで回して ServerAddress のみを取得します。余計な "nameserver" という文字を付けた理由は後ほど。


###サーチサフィックスを取得する

同様にサーチサフィックスを取得するのですが、以下のオブジェクトを参照することで、DNSサーバから取得したサーチサフィックスとプライマリドメインサフィックスとしてドメインから、あるいは明示的に設定した情報をまとめて取得できます。

```powershell:サーチサフィックスの取得
(Get-DnsClientGlobalSetting).SuffixSearchList|%{echo "search $_" };
```

これらのサフィックスにさらに mshome.net(Hyper-V仮想マシンに付けられるドメイン名)も加えておけば接続環境でのサーチサフィックスは一通りそろいます。


##まとめ

ここで得られた情報を加工して /etc/resolv.conf に追加情報として反映するようにしておけば出来上がりです。
wsl.conf でインスタンス起動時に実行すればと思ったのですが、現状では~/.profile等に記述してログイン時に処理するのがよさそうです。wsl.conf [boot]の記述を処理するタイミングではまだWindowsコマンドを呼び出す相互運用の準備ができていないようですね。

先ほどnameserver や searchという識別子を付けておいたのは、これら二つをひとまとめにして powershell.exe を呼び出したいからです。WSLからWindowsコマンドを呼び出すのはコストが高い(PowerShellが遅いだけ？)ようで筆者環境でおおむね 0.6秒程度かかります。できるだけひとまとめにしてPowerShellを呼び出して時間を節約したいので、実行後にテキスト抽出しやすいようにマーカーを付けています。
Dart Sass 使用時のmap.getの使い方について

##　Dart Sass 使用時のmap.getの使い方について

###マップ型の呼び出しは map-get から map.get へ

get-mapから、map.getに変更されたので使用方法についてのメモ。

自分の使用方法は、「FLOCSS」をベースに、変数settinng用のファイルを作り、それを参照している。


```sass:sass(変数管理用ファイル)
@use "sass:map";

$layer: (
  drawer: 40,
  sp-menu: 30,
  header: 20,
  default:1,
)

```

@use "sass.map" を記入してあげる。


```sass:sass(変数を呼び出しているファイル)
@use "../global/" as global;
@use "sass:map";

.l-header {
    z-index: map.get(global.$layer, header) ;
}

```
@use "../global/";で変数を管理しているパーシャルの指定をします。
ファイル名は名前空間となって、実際に指定したい箇所で パーシャル名.変数名 と続けて記述します。
コチラにも@use "sass.map" を記入。

ここで

**map.get(パーシャル名.$layer, キー)**



```css:css
.l-header {
  z-index: 20;
}
```

これで使えた。
MAX IIでシリアル通信

FPGAの大変良い記事がありMAX IIで試してみました。

https://www.acri.c.titech.ac.jp/wordpress/archives/123

SystemVerilogはQuartusでもサポートされています。Verilogを拡張したもののようです。

FPGAの記事ですが小規模な実験なのでCPLDでも入りました。

```
Fitter Status : Successful - Wed Oct 27 05:42:31 2021
Quartus II 64-Bit Version : 13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition
Revision Name : hello
Top-level Entity Name : hello
Family : MAX II
Device : EPM240T100C5
Timing Models : Final
Total logic elements : 53 / 240 ( 22 % )
Total pins : 3 / 80 ( 4 % )
Total virtual pins : 0
UFM blocks : 0 / 1 ( 0 % )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/15bff056-001a-32a5-15fa-954d352d4182.png)

クロックが半分なのでボーレートが57600になっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c3cf2055-6ac7-608c-9cd7-d84d9681583e.png)

クロックが良くないのか、所々文字抜けがあります。
ATtiny13Aを使ったボトルイルミネーションライトの作製

空いたペットボトルにLEDストリングを入れてきらきら光らせる装飾品です。
電源は単4電池1本を昇圧してマイコンとLEDの駆動に使います。ペットボトルのふた部分にプッシュスイッチを付けて、押したら点灯・点灯モード変更して、一定時間がたつと消灯するようにしました。
LEDストリング2本を交互にフェードイン・フェードアウトさせてゆらゆら光っている感じを出すようにしました。

【部品】
・LEDストリング：USB LED Micro Rice Wire Copper String Fairy Lights (中華) 25cm程度 2本
・昇圧モジュール： DC-DC 0.9-3.3V to 3.3V 500mA 0.9-5V to 5V Mini Step Up Boost Power Module DC to DC For Arduino Voltage Converter Module (中華) 1個
・マイコン：ATTiny13A 1個
・トランジスタ： 2sc1815 2個
・抵抗： 1KΩ 2個 （ベース電流制限用）

【注意点】
今回使用した昇圧回路は安かろう悪かろうなので注意が必要です。最初に使用したモジュールは漏電していたため、スリープモードにしていても1週間もしないで電池がなくなってしまいました。モジュールを取り替えたら数か月スリープさせていても電池は消耗しておらず、スイッチを押せば光ります。

そのうちに写真も載せます。

```arduino:ibottle_llumination.ino
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define SW   2
#define LEDa 0
#define LEDb 1
#define MAX 127 // 最高輝度を50%（127/256）に制限
#define LIFE 9000 // タイムアウトを定義
#define BLINK 4 // 明るさ3段階＋ゆらゆらモード
char mode;
int i, j, k, l, phase;

void setup() {
  // ピンモード初期化
  pinMode(LEDa, OUTPUT);
  pinMode(LEDb, OUTPUT);
  pinMode(SW, INPUT_PULLUP);
  digitalWrite(LEDa, LOW);
  digitalWrite(LEDb, LOW);
  // その他変数初期化
  i=LIFE;
  mode=0;

  //スリープのための設定
    // set timer to 0.5s
  WDTCR |= (0<<WDP3) | (1<<WDP2) | (0<<WDP1) | (1<<WDP0);
  // Set watchdog timer in interrupt mode
  WDTCR |= (1<<WDTIE);
  WDTCR |= (0<<WDE);
  /* 省電力のために設定したかったけどメモリが足りなかったので諦め
  //ADCSRA &= ~(1 << ADEN); // disable ADC
  //ACSR |= _BV(ACD); //Disable analog comparator
  */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sei(); // Enable global interrupts
  sleep_mode();
}

ISR(WDT_vect) {
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(SW)==LOW){
    analogWrite(LEDb, 10);
    //analogWrite(LEDa, 10);
    do{
      delay(10);
    }while(digitalRead(SW)==LOW);
    mode=(mode + 1) % (BLINK+1);
    i=LIFE;
  }
  
  if(mode==0){
    i=0;
    j=0;
    k=0;
  }else if(mode<BLINK){ // 一定の明るさで点灯 3段階切り替え （段階数はBLINKで定義）
    j=constrain(i/10, 0, MAX >> (BLINK - mode));
    k=j;
  }else if(mode==BLINK){ // ゆらゆら光らせるモード
    l=MAX;
    phase=abs((i % 101) - 50);
    j=(phase*l)/50;
    k=l-j;
  }
  analogWrite(LEDb, j);
  analogWrite(LEDa, k);
  
  if(i>0){
    i--;
    delay(20);
  }else{ // タイムアウトしたら初期化してスリープする
   setup();
  }
}
```
ImtStateMachineについて、2018年12月版と2021年10月版の比較

# この記事について

現在 Qiita 内でキーワード ImtStateMachine にて検索するとこちらの記事がトップに出てくる。
- [ステートマシン実装の決定版ImtStateMachineについて語り尽くす](https://qiita.com/BelColo/items/a94c9ccc2d5174dc29a3)
2021年10月現在ではこちらの記事に書かれたものと若干 ImtStateMachine の内容が変わっているようなので、ここにメモを残しておく。
- [GitHub上の最新版](https://github.com/SinoalmondUnityPackage/IceMilkTea/blob/develop/Packages/IceMilkTea/Runtime/Core/StateMachine.cs)

なお、ImtStateMachine のファイル内にバージョン表記が見受けられなかったため、便宜上前述の記事で使われているものを ```2018年版``` と呼ぶ（2018年に書かれた記事であるため）。最新のものは ```2021年版``` と呼ぶ。この呼称は一般のものではなくこの記事内に限定したものである。

ソースを目視で見て確認しているだけなので間違ってたらごめんなさい。

# 主な差分
## 変更
- ファイル名変更
  - 2018年版: ```ImtStateMachine.cs```
  - 2021年版: ```StateMachine.cs```
      - ただしクラス名は ImtStateMachine のまま。
- クラス定義の型パラメータ変更
  - 2018年版: ```public class ImtStateMachine<TContext>```
  - 2021年版: ```public class ImtStateMachine<TContext, TEvent>```
      - ただし 2021年版を基底クラスとして、TEvent を int で固定して従来と同じ型パラメータにした派生クラスが互換性のため(?)に作られている。
      - ```TEvent``` は ```AddTransition<TPrevState, TNextState>(TEvent eventId) ``` や ```SendEvent(TEvent eventId)``` で使われている引数。2018年版では int で固定されていたが、2021年版では任意の型を使えるようになった。
- ステートクラスのインスタンスは2018年版では内部で作成していたが、2021年版では新規追加されたメソッド ```RegisterStateFactory(Func<Type, State> stateFactory)``` によって、生成する Func を登録できるようになった。これにより既存のインスタンスをステートクラスとして使用することができると思われる。多分。
  - Factory でも生成できなかった場合は ```protected virtual TState CreateStateInstance<TState>()``` にてインスタンス化をするので、これを override して任意のインスタンスを使えるように書き換えられるかもしれない。

## 追加
- 最後に受理された eventId が ```public TEvent LastAcceptedEventID```プロパティから取れるようになった。

## 廃止
- 可変長引数で一気に遷移構造を登録できる ```AddTransitionRange()``` が廃止された。
- ```SetStartState``` の非ジェネリクス版 ```SetStartState(Type startStateType)``` が廃止された。ジェネリクス版の ```SetStartState<TStartState>()``` を使おう。
- クラス ```ImtSynchronizationStateMachine<TContext>``` の廃止。SynchronizationContext は使ったことが無いのでわからない。

# まとめ

廃止されたメソッドやクラスがありますが、概ね互換性は維持されているように見えます。よかったよかった。
SQL文でよく使うコマンド

## SQL文でよく使うコマンド
### データベースの参照
```
mysql> show databases;
```
データベースがたくさんあるときは、

```
mysql> use データベース名
```

でデータベースを選ベる。

```
mysql> show tables;
```
データベースを選んだ後その中のテーブルが見れる。
[基本情報技術者]AIについて

# はじめに
本記事では、`基本情報技術者`で出題される`AI`についてまとめます。

# AIとは
Artificial Intelligenceの略。
人が行うような学習や認識などの知的操作をコンピューターにさせる技術のことです。

## 機械学習
機械学習とは、IoTの普及などで生まれた、
大量のデータをコンピューターに解析させ、`コンピューター自らが予測や判断などができるように学習させること`です。

以下のような学習方法があります。

### 教師あり学習
あらかじめ問題（データ）と正解をコンピューターに提示し、誤りを提示したりすることで、
コンピューター自らがそれらの特徴を学習します。
正解が与えられています。

```
大量の犬の画像に、「犬」のラベルをつけ提示し、
特徴などをコンピューターに学習させることで、
ラベルがなくても「犬」を判断できるようにする。
```

### 教師なし学習
教師あり学習とは`異なり`、正解は提示されていません。
コンピューター自らが統計的性質やある種の条件に従い、
データのグループ分けや、情報の集約を行います。

### 強化学習
試行錯誤して、報酬や評価がもっとも多く得られた方策を学習します。
これはゲーム用の人工知能に応用されます。

以上です。

# 終わりに
就職活動を始めそろそろ2ヶ月経過し、終わりを迎えています。
近日中に、結果報告の記事を書こうと考えております。
[vba]VBAの代入ステートメントは二種類ある。

VBAは文法上値を代入できる普通の代入ステートメントと、オブジェクトの代入ができるSetを使った代入ステートメントと二種類ある。

```vb:substitute.vba
Dim x As Long: x = 10
Dim y As Long: y = 9
```

```vb:setObject.vba
Dim wb As Workbook: Set wb = ThisWorkbook
Dim rng As Range: Set rng = ActiveCell
```

一方は
＜変数名＞　＝　＜値＞
もう一方は
Set ＜変数名＞　＝　＜オブジェクト＞
と、非対称なやりかたで覚えにくいなと思っていた。ところが、実は上の普通の値を代入するステートメントは省略した形だと判明した。
本来はこう書くべきものらしい。

```vb:Let.vba
Dim x As Long: Let x = 10
Dim y As Long: Let y = 9
```

流石に、いちいち値の代入でこんな冗長な表現をとるのは煩わしいので、こんな書き方をする人はいないと思うが、一つ謎が解消された。

出典：[パーフェクトExcel VBA](https://www.amazon.co.jp/dp/4297108755) pp.80-84
大事なのは正しく伝わる事

最近ちょっと人と話す事がありまして、
突然聞かれて咄嗟に答えた事なんですが、

質問：大事にしてる事は何？

と言う割とザックリした聞き方の話で
何も考えてない状態で口から出たのが

回答：正しく伝わる事。でした。

おそらく本心でそう思っている。

デザイナーは当たり前と思うかもしれないが
言葉は意外と受け取り方次第な部分がある。

「鏡を見た方が良いよ」
と言われてどう言う意味なのか考えこむより、
「鼻毛が出てるよ」
とズバリ言ってもらった方がいっそ清々しい。

一日に使える脳みそのキャパは
限られていますし、

つまりどう言う事ですか？と意味を正すのは
相手と対等かそれ以上の関係性でないと難しいです。関係性によっては失礼になったりする。

含みを持たせてきた当の本人からも「飲み込みが遅いなー」とイライラされる事もあります。

相手にも同じ思考フレームワークが入っていれば
理解し合える速さが違うかも知れません。でも相手が勉強してなかったら意味ない。

かと言って、素養に関わる部分にダメ出しをするのははばかられる。（※そんな事も知らないのか？的なマウンティングをしてしまう事になりかねない）

なので平易な言葉とか、似たもので表現する事になりノイジーな会話が増える。

思考フレームワークをサイレントに仕込んでいくような、そう言う事で会議や仕事全般のコミュニケーション効率が上がらないかな、と思ったりしてるです。
リーダブルコード

リーダブルコードを読んだ

## 理解しやすいコード
コードは他人に理解しやすいものであるべきである。他人が理解しやすいコードとは、他の人が最短期間で理解できるということ。

では、最短期間で理解するにはどのようなコードが良いのかをいかに記す。

### 読みやすいコード
- 短いコードは読む時間を短くし、理解にかかる時間を減らす

## 名前に情報を埋め込む
- 変数名は短いコメントで汎用的な名前を避ける。
- 値の場合は、単位などを入れるといい。
- 同じ処理を行う場合、関数化することで見やすいコードにする事も可能であり、テストの追加も楽になる。

## 美しさ
インデントが整っていたり、段落分けが綺麗なものは見やすく、理解しやすい。

## コメントすべきことを知る
コメントは必要のない自明なことは書かない。全体像、ハマりそうな罠の告知に使う。（読み手の立場になろう！）

### 価値のないコメントとは
- コードからすぐにわかることを書いている

### 価値のあるコメントとは
- 監督コメンタリーを入れる。コードの背景を入れることで思考の流れを手助けする。
- コードに欠陥があることを認め、どのように直したいのかを書いておく。
- 定数にはなぜその値なのかメモしておく。

コメントは正確で簡潔に書くべきで、コードに対して長すぎるコメントは読み手を混乱させてしまう。

## 制御フローをわかりやすくする
一行で書こうとするのは良くない。
もしそれが読み手にとって読むのが困難でなければ良いが、複雑な場合は変数を使って分割を行ったり、階層を増やして分かりやすい物にする。

## 巨大な式を分割する
変数を増やすことで読みやすいコードを実現できても、変数が多すぎることで逆に辛くなることもある。
また、変数のスコープが大きいことも読みづらいことの原因になる。だから、一度しか使わなかったものなどはわざわざ変数にする必要がない。

一つの関数には一つの役割をもたせることで、単純明快なコードを実現することができる。

## 変数と読みやすさ
変数には代入する回数を一回にできるように実装を行う。

```
static const int NUM_THREDS = 10;
```
このようなコードは`NUM_THREDS`について多くのことを考える必要がない。

変数の中身が何度も変わることは混乱につながる。`const`などを積極的に使っていく。

## コードの再構成
コードを書いていてそのうち使わなくなってしまったものが出てくる。
これをコメントアウトなどで残しておきたくなるが、結局それは使わないものなので削除してしまう方が得策である。

ライブラリの作成ができると他のプロジェクトでも汎用的なコードとして再利用ができる可能性がある。

## まとめ
これらのことは、実際に自分でコードを書くことで気づくところも多いと思う。
また、リーダブルコードに書いていないことでもさらにコードを良くすることが出来る点があるはずである。

そのため、何度も自分で書くコードを見返したり、他の人のコードの観察をすることで実際に良いコードとはどういうものなのか自分の目で確かめていく。

# 変数名には想いを込めよう！！
Spot VMの登場でGCPがどう変わるか

結論を3行で

- 新しいSpot VMは価格が変動するよ
- プリエンプティブルVMの料金も変わるよ
- 試しに使ってみたら9割引されてたよ

## はじめに

先日、GCPでの新しいVMのオプションであるSpot VMが発表されましたね。

https://cloud.google.com/spot-vms

GCPにはすでに類似の役割を担っているプリエンプティブルVMが存在する訳ですが、何故今更Spot VMが出てきたのでしょうか？

## 目次

1. Spot VMとは？
2. プリエンプティブルVMとの違い
3. プリエンプティブルVMの今後
4. Spot VM使ってみた
5. まとめ・VM運用の将来

## 1. Spot VMとは？

Spot VMは先日発表されたVMの新しいオプションであり、標準のVMよりも低価格で利用できます。
現在はまだプレビューであり、以下のリージョン・マシンタイプでしか対応していません。
![スクリーンショット 2021-10-26 11.21.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79302/dafccb4f-3ac4-a2ef-c7f6-a203d65cbd72.png)


そして、以下のような制限があります

- GCP側の都合で停止される可能性がある
- 必ずVMを確保できるわけではない
- サービスレベル契約の対象外であり、Compute Engine SLA から除外されている
- 他にもいくつか

基本的にはプリエンプティブルVMと同様の制限があると考えていいでしょう。

## 2. プリエンプティブルVMとの違い

今回発表されたSpot VMには、従来のプリエンプティブルVMにはない**大きな特徴が二つ**あります。それは、最大起動時間と価格の変動です。

### 最大起動時間

プリエンプティブルVMの最大起動時間は24時間であり、24時間経過すると強制的に終了されてしまいます。これに対して、Spot VMには起動時間の制限は特にありません。
例えば自分はこれまでGKEでプリエンプティブルVMを利用する際には、起動時間をずらすために[preemptible-killer](https://github.com/estafette/estafette-gke-preemptible-killer)のようなOSS使っていましたが、この辺が必要なくなるのは良いですね。


### 価格の変動

従来のプリエンプティブVMはマシンタイプ/リージョンごとに割引率が固定でしたが、Spot VMは価格が変動します。公式のドキュメントによると、「60%〜91%の割引が適用され、料金は30日に1回まで変更される可能性がある」とのことです。

具体的な料金は以下のページで確認できます。
https://cloud.google.com/compute/vm-instance-pricing
ただし、現状は対応しているリージョンが少ないので、未対応のリージョンの料金は従来のプリエンプティブルVMの料金になっているようです。

## 3. プリエンプティブルVMの今後

ここからが重要です。
私はSpot VMの発表を見たときに、**「これまでのプリエンプティブVMとは別に、新しくSpot VMも選択できるようになる」**と、思っていました。

しかしSpot VMとプリエンプティブVMのドキュメントをよく見てみると、そんなに簡単な話ではなさそうでうす。

プリエンプティブVMのドキュメント([ここ](https://cloud.google.com/compute/docs/instances/preemptible))を見ると、冒頭に以下のような文言が書いてあります。

> Preemptible VMs continue to be supported for new and existing VMs, and preemptible VMs now use the same pricing model as Spot VMs.

どうやらプリエンプティブVMの料金モデルはSpot VMの料金モデルと同じになるようです。
つまり、これまで固定の割引率(だったよね？)ではなく、Spot VMと同じく価格が変動するようになります。

## 4. Spot VM使ってみた

せっかくなので、実際にGKEでSpot VMを使ってみました。
GKEでSpot VMのnode poolを作成するには、`gcloud beta`コマンドを使用します(GCPのコンソールからは作成できません)。

https://cloud.google.com/kubernetes-engine/docs/how-to/spot-vms#create_a_node_pool_with_enabled

今回は、東京リージョンで対応してる`c2-standard-4`を使用しました。
実際に発生する料金を観測するために数日間立てっぱなしにしてみましたが、通常のVMと比較して**90% off**の請求額となっていました(安い！)。

今はプレビュー段階なので上限に近い割引率となっているのだと思われますが、正式公開後にどうなるかのかは未知数ですね・・・

## 5. まとめ・VM運用の将来

Spot VMのファーストインプレッションをお届けしましたが、重要なのは以下の点ですね。

- Spot VMは24時間の起動制限がない
- Spot VMの料金は30日に1回変動する可能性がある
- プリエンプティブVMの料金体系もSpot VMに準拠するようになる

つまり、今後GCPでプリエンプティブルVM(とSpot VM)を運用する際には、インスタンスタイプ・リージョンごとに価格の変動を意識する必要が出てくるでしょう（まあそこまで細かく意識しなくていいかもですが・・・）。

とはいえ価格が変動するという特徴はAWSのSpot instanceと同じなので、AWSと似たようなVM運用をすればいいってだけの話ではあるんですけどね。

個人的にはプリエンプティブルVMのシンプルな料金体系を好ましく思ってたので、この変更は少し残念かな・・・
ローカルからgithubのmasterもしくはmainブランチへpushさせないようにする設定


## GitHubに任せられるものは任せよう

今までgithooksのprepushとかでshell組み込んで対応していたが、github上でできるとのことなので時代の進化に合わせるでがんす。

`Require a pull request before merging`にチェックをつけると良い。

![FireShot Capture 003 - Branch protection rule - github.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125469/6b46c6b7-2bd3-d91b-5b2a-7db7f4e33793.png)

早漏なのか以下の記事見てガンガンいこうぜモードで試してみたらmasterにpushできてしまった...

https://zenn.dev/shimotaroo/articles/71f10e7e76ecb3

ちょっと下にある`Include administrators`にチェックつけたらmasterにpushできなくなった。
めでたしでめたし。

![スクリーンショット 2021-10-27 0.17.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125469/ff2eb13a-b726-c34d-ecfc-a9527cb6bbac.png)

`Include administrators`にチェックをつけた場合、リポジトリ管理者はローカルからmasterへのpushができず、GitHub 上でのマージもapproveをもらわないとできなくなります。

`Include administrators`にチェックをつけなかった場合、リポジトリ管理者はローカルからmasterへのpushもできて、gihub上でのマージもapproveをもらっていなくてもできるようになります。

ここまでは普通ですが最後、番外編。

**ポジトリ管理者でも何者であってもローカルからmasterへのpushは絶対できず、gihub上でのマージは管理者であればapproveをもらっていなくてもできるようにしたい。**

こんな需要は弊社だけかもしれん。
このケースの場合は、やはりgithookを使うしかないと思います。
githubの設定による制限と、githookによる制限の合わせ技的な感じです。

そもそもmasterに直pushしてしまうような人は管理者として設定すべきではないけど、少なくとも緊急でmasterにマージしたいお！
って要望は少なからずあると思う。

~~こういう場合でも最低限githubでPR作ってPR経由ということなら管理者であればapproveもらってなくてもmergeしてもいいよ。
って運用にしたかったのです。~~

~~流石に管理者なら直pushOKにしてたら、、、横着する人続出する火種になりそうな気がしたからですw~~

↑こういう逃げ道用意してるからダメなんだよ、って読み返してて思いましたw
緊急だろうがなんだろうが、ちゃんとプロセスを経て業務に取り組むような体制を確立する方が大事ですね。
これは無視してくださいw

まぁでもそんなこともできるよってことで知見にしていただければと思います。

尚、タグはmasterに付与してもpushできるようです。
ファイルに差分発生させてpushしようとすると上記スクショのエラーがでたのでタグだけはOKということがわかりました。



## ちょっと寄り道

ちなみに今まで、`lib_git-hooks`なるprivateリポジトリを作ってそこにgithookで使うshellを用意して、`composer install`をすると、対象の場所にコピーするようなライブラリを作っていた。
あとは必要なリポジトリでcomposerでinstallしてshellを実行すればpre-pushが生成されるような感じです。

もうこんなことしなくて良いが、せっかく作ったってこともあるしリポジトリ削除するのもなぁ...
ということでどんなものだったかは社用個人のgithubリポジトリに譲渡しておくので気になる人は見ていってください。

https://github.com/GILD-MasayaGoto/lib_git-hooks

composerで自作ライブラリ化できればリポジトリ横断して同じようなもの作らなくて良くなるので保守管理のキャパは強くなります。
【AWS/cloud9】SQL起動方法と簡単な使い方

#データベースサーバの起動と停止

＊MySQLは最初からCloud9に導入されているからインストールは不要。

####サーバーの起動
```sudo service mysql start```

####サーバーの起動状態確認
```sudo service mysql status```

####サーバーの停止
```sudo service mysql stop```

####サーバーを再起動
```sudo service mysql restart```

####データベースサーバへの接続
```sudo mysql -u root```

そうすると、、、
```mysql>```
が表示される

####データベースサーバからの切断
```mysql> exit```


#データベースの使い方

####データベースを作成する
まずbookstoreというデータベースを作成する。
```CREATE DATABASE データベース名;```
これでデータベースが作成される。

####データベース一覧の確認
```show databases;```
コマンドにデータベース一覧が表示される。


####データベースの削除
```DROP DATABASE データベース名```
これで削除される。

###データベースを操作する
```USE bookstore```
MySQLサーバーに接続した後に上記のコマンドを実行
データベースを指定する為に必ずやる


####データの作成と保存


Insert構文
```INSERT INTO テーブル名（カラム名）　VALUES (値)；```
データに追加できる。


####データの取得
```SELECT カラム名　FROM テーブル名;```
これでデータを取得できる。

####データの更新
```UPDATE テーブル名　SET カラム名１ = 値1, カラム名2 = 値2```
備忘録~BootstrapをSassでカスタマイズする方法~

##PHP（7.4）・Bootstrap（v4.5）・Scssphp(Sass)(v1.81) Windows 10 Home



##Bootstrapとは
世界で最も人気なHTML、CSS、JavaScriptのフレームワーク
メリット：①CSSを一から書かなくてよい。
　　　　　②レスポンシブデザインに対応している。
　　　　　③統一感のあるデザインが簡単にできる。

今回はComposerを用いてインストールした。
![Bootstrapインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/cd98bb87-a93a-e114-c3fb-116df58ac97a.png)

するとVendorというフォルダが作成される。
CSSで使うには、Vendor/twbs/bootstrap/dist/cssのフォルダの中の

bootstrap.css：ローカル環境向き
bootstrap.min.css：本番環境向き

この二つのうちどちらかをHTMLに読み込む。



```
<link rel="stylesheet" href="ファイルのパスを指定">
```
##BootstrapをSassでカスタマイズ
###・Sassとは
CSSをより効率的に書けるようにした言語
Syntacically Awesome Stylesheetsの略である。
メリット：①ネスト（入れ子）ができる。
　　　　　②変数が使える
　　　　　③四則演算ができる。

SassとScssの二つをSassというが、一般的にはよく使われているScssのことを指す。
####SassにBootstrapを読み込み、それをCSSにコンパイルして使うと効率的。
###①ネスト（入れ子）ができる。

SASS↓　　　　　　　　　　　　　　CSS↓　　　　左のCSSで装飾しているHTML↓　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/83963eea-101f-bf2d-c2bf-49b74b3271b9.png)
(参照:https://www.youtube.com/watch?v=_Dl1y2DXONQ&list=LL&index=1)
###②関数に引数を取ってパーツごとに指定できる。
↓の場合だと色だけ変えてる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/5481da81-bf19-51b6-e7d0-12864894a48a.png)
(参照:https://www.youtube.com/watch?v=_Dl1y2DXONQ&list=LL&index=1)
###③四則演算が使える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/dab02481-caf2-6d4c-2351-872c5eb8758a.png)
(参照:https://www.youtube.com/watch?v=_Dl1y2DXONQ&list=LL&index=1)

・$mainColor:#a00（メインカラー）とかサブカラーとかをまとめてvariable.scssファイルにまとめ、それらを読み込んで使うと管理がしやすい。読み込むときは

```
@import "variavle.scss";
```
を使う。

##カスタマイズ方法、使い方
https://scssphp.github.io/scssphp/
にしたがってrequireコマンドでSassをインストール。

#####流れとしては上述のとおり、SassにBootstrapを読み込み、それをCSSにコンパイルして使う。
stylesheetフォルダをつくり、その中にscssとcssのフォルダ、それぞれにapp.scss、app.cssを作る。
app.scssファイルにvendor/bootstrap/bootstrap.cssを読み込む。

```
@import '/var/www/html/vendor/twbs/bootstrap/scss/bootstrap(.scss');
```
scssの拡張子は省略可能。
これでScssにBootstrapの読み込みが完了。
次はそれをコンパイルする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/f3a71283-aafb-6ce1-463e-b3fe8bed2961.png)
上記の様にコンパイルのためのファイルが用意されている。これはCSSを返してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773238/c757daf7-0309-33ed-b6bd-2088a243fa22.png)
コマンドラインからコンパイル。app.scssをapp.cssにコンパイルしますという意味。
最後にCSSをHTMLに読み込む。

```
<link rel="stylesheet" href="stylesheets/css/app.css">
```
以上。

###おまけ
スーパーリロードとは
Windows:Shift+F5
Mac:ctrl+Shift+R

キャッシュを使用しないで、もう一度画面を読み込みなおすこと。
パソコンがWebサーバーからページを取得する際、パソコン内にそのページのコピーを取っておく。（キャッシュ）
次にこのページを見たいとき、そのキャッシュを利用して表示する。（サーバーから持ってくる手間はぶける）
それをキャッシュを消してもう一度もってこさすのがスーパーリロード。
【Java SE Bronze】インターフェースというもののイメージを掴みたい。


入社して2年経ち、今更ですが資格の勉強に意識が向いてきたので、JavaSE Bronzeの学習に取り組み始めました。
定着のためのアウトプットの場として、書かせていただきます。
認識違いが多々あると思いますので、若い子がなんとやっとるわぁくらいの感覚で読んでいただければと思います。


# インターフェースとは
>Javaプログラミング言語のインターフェースは、クラスが実装しなければならない動作を指定するために使用される抽象型です。それらはプロトコルに似ています。インターフェイスは、インターフェイス キーワードを使用して宣言され、メソッド シグネチャと定数宣言のみを含むことができます。
https://en.wikipedia.org/wiki/Interface_(Java)

んんん、難しい。
もっと噛み砕いた解説を見てみると



>Javaで使われるインターフェースとは、クラスに含まれるメソッドの具体的な処理内容を記述せず、変数とメソッドの型のみを定義したものです。以下のようにインターフェースを宣言および実装を行います。 
https://www.internetacademy.jp/it/programming/java/difference-between-interface-and-abstract.html

なんとなくイメージが沸いてきました。テンプレートとかルールのようなものかな・・？

民主主義というインターフェースには、選挙というメソッドが実装されていて
各国によって選挙の方法が違う。日本だと比例代表制と小選挙区制があるみたいな・・・？？




# インターフェースの記述の仕方
```java
interface Animal{
  String NAME = "タマ";
  void eat();
}

class Cat implements Animal{
  public void eat()  {
    System.out.println(NAME + "はチュールを食べる");
  }
}

//実行
class Main{
  public static void main(String[] args)  {
    Cat cat = new Cat();
    cat.eat();
  }
}
```

```java
//実行結果
タマはチュールを食べる
```

こんなかんじ。
正直、どのような設計をすればインターフェースのメリットを引き出せるのかがピンと来ていません。。。




```java
interface Animal{
  String NAME = "タマ";

  static void eat(){
    System.out.println(NAME + "はチュールを食べる");
  }
}

//実行
class Main{
  public static void main(String[] args)  {
    Animal.eat();
  }
}
```

```java
//実行結果
タマはチュールを食べる
```

static を使えば、インスタンスは必要ありません。







分かりやすい例があったので引用させてもらいます。
>家電製品を考えてみます。
>【問題になるようなパターン（インターフェースなし）】
１．ドライヤーを作った
２．電子レンジを作った
３．冷蔵庫を作った
それぞれは共通のコンセントを持っていますので、一つの電源タップで利用することができるとします。

>４．新しい電化製品、テレビが発明された。
ここでこのテレビという製品は、新製品であるがためにコンセントの形が独自に作られていたとします。
そうすると従来の電源タップで使うことができません。変換機を買ってきたり、場合によっては家を工事する必要があるとします。
せっかくの新製品なのに、うまく使えず家庭の皆さんはさぞ怒ったことでしょう。また売るほうとしても工事が必要とあっては売れ行きに響くかもしれません。
これがインターフェースが統一されていないということです。

>【上記問題を解決するようなパターン（インターフェースあり）】
０．コンセントの規格が決まり、電化製品は基本的にはその規格に沿ったコンセントを作る必要があることになった（インターフェース）
１．ドライヤーを作った
２．電子レンジを作った
３．冷蔵庫を作った
４．テレビが発明された
ここで上記の家電製品のコンセントの形が全て統一されていれば、全て同じ電源タップが使えますね。変換機を買ってきたり、工事をしてコンセントの形を変えたりなどということは不要になります。
逆に言えば、家電製品の開発者は「コンセントの形を統一する必要性に迫られる」ということになりますが、それがインターフェースの本質です。
https://teratail.com/questions/70213?link=qa_related_pc
Springerのreferenceをsn-basicかつ番号順にする方法


## 概要
Springerのジャーナルに論文を投稿しようと思った際に、referenceで詰まったので、備忘録件、対応記事としてまとめます。初投稿です。

## この記事の内容
Springerの中の幾つかのジャーナルでは、referenceの書き方の指定があり
- 参考文献の書き順を[著者][年号][タイトル][会議、論文誌名][...]のようにする。(sn-basic.bst)
- 本文中では[1]や[2-4]のように数字でソートして表示する。
の2つが提示されています。
しかし、Springerの公式latexテンプレートのsn-basicを指定するだけでは、本文中での引用部が[年号、著者名]となってしまうため、これを修正する方法を本記事では説明します。

参考にした記事
[Springer Basic Reference Style and natbib options issues](https://tex.stackexchange.com/questions/618340/springer-basic-reference-style-and-natbib-options-issues)
[Problem with Springer bibliography style(spbasic + natbib)](https://tex.stackexchange.com/posts/312878/revisions)

環境 : overleaf

## 全体の流れ
1. 参考文献の書き順をsn-basicにする
2. 本文中での書き方を[authoryear]から[numberにする]
3. 番号を並び替える

## 参考文献の書き順をsn-basicにする
Springerのテンプレートをダウンロードしたとき、初期のスタイルがsn-basicでない時は、sn-basicに変える必要がありますが、この時\bibliographystyle{sn-basic}とするだけでは反映されない場合があります。そんな時は\documentclassを\documentclass[sn-basic]{sn-jnl}に変更しましょう。そうするとreferenceの並び順が変わって[著者][年号][タイトル][会議、論文誌名][...]のようになります。

## 本文中での書き方を[authoryear]から[numberにする]
この段階ではまだ、本文中で参考文献を引用した箇所が[author year]の形になっていると思います。これを[number]に直してあげるために、sn-jnl.clsを開いて、1658行目の
\usepackage[authoryear]{natbib}を
\usepackage[numbers,sort&compress]{natbib}に変更してあげましょう。
これをすることで、本文中の引用部が番号に変化したはずです。
![スクリーンショット 2021-11-15 23.38.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2288752/886c182b-996c-d9d2-1eac-998a04ab65ed.png)



## 番号を並び替える
この段階では、番号にはなったもののソートがなされていないと思います。これをソートするためにはsn-basic.bstファイル内のSORT(大文字であるところに限る)の2行を消しましょう。すると番号順にソートされます。以上で正しいreferenceが作成できたと思います。
![スクリーンショット 2021-11-15 23.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2288752/2f7c13a6-d685-cedb-de88-f000a5917473.png)

## おわりに
texに不慣れなものでたどり着くのに時間がかかってしまいました。Springerも指定するならちゃんとしたテンプレートを作って欲しいものです笑