OmniAICreator/Qiita-1.07M huggingface dataset:
デイトラ「Web制作コース」　受講内容をアウトプット 24日目


学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース中級編」　JavaScript・jQuery学習編
②・jQueryとはJavaScriptのライブラリの一つ
　・jQueryを使うメリット
　　⇒短いコードで簡単にかける
　　　ブラウザごとの対応がいらない
　　　便利なライブラリがたくさんある
　・jQueryのポイント
　　1）$マークで始まり
　　2）②function()で囲む
　　3）$("主語").動詞("補語")の文法ルールで書く

　・jQueryの代表的なメソッド一覧

　　.text()　テキストを取得する
　　.text('変更したいテキスト')　テキストを' '内の文字列に変更する
　　.html()　HTMLを取得する
　　.html('変更したいHTML')　HTMLを' '内のHTMLに変更する
　　.click()　対象要素をクリックする
　　.prepend('要素')　要素の先頭にHTMLを挿入する
　　　例：$('#lists').prepend('< li >先頭に追加するリスト< /li >')
　　.append('要素')　要素の最後にHTMLを挿入する
　　　例：$('#lists').append('< li >最後に追加するリスト< /li >')
　　.remove()　要素を削除する
　　.attr('属性')　指定した属性の値を取得する
　　　例：$('a#special-link').attr('href')
　　.attr('属性', '値')　指定した属性の値を変更する
　　　例：$('a#special-link').attr('href', 'https://xxxx.com')
　　.removeAttr(属性名)　指定した属性を削除する
　　.addClass(class属性値)　class属性を追加する
　　　例：$('#button').addClass('active')
　　.removeClass(class属性値)　class属性を削除する
　　　例：$('#button').removeClass('active')
　　.css(プロパティ名)　指定したCSSプロパティの値を取得する
　　　例：$('#logo').css('color')
　　.css(プロパティ名, 値)　指定したCSSプロパティの値を設定する
　　　例：$('#logo').css('color', 'red')
　　val()　フォームの入力値(value属性の値)を取得する
　　　例：$('input#name').val()
　　val('入力値')　フォームの入力値(value属性の値)を設定・上書きする
　　　例：$('input#name').val('tofuri')

③なし
④なし
⑤なし
⑥なし
「ゼロから作る　Deep Learning」　1章　学習内容アウトプット　3日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①１章　Python入門

②


③なし
④なし
⑤なし
⑥なし
EC2インスタンスにログインする4種の方法

EC2を起動したのち、Teratermで接続するの面倒だなあと思っていたら、現在は下記の4種の方法で接続できるとのこと。

- SSHクライアント
- セッションマネージャー
- EC2 Instance Connect
- EC2 シリアルコンソール

せっかくなので、全部試してみた結果をまとめました。

# 動作環境
- AMI：amzn2-ami-minimal-hvm-2.0.20230207.0-x86_64-ebs（ami-07a9088aa34ad4545）
- インスタンスタイプ：t3.nano
- AWSマネジメントコンソールには、Administrator権限でログイン

Amazon Linux 2のminimalイメージを使用します。（＝通常のAmazon Linux2には入っていないものが多々あります）また、EC2 シリアルコンソール利用時にAWS Nitro System に対応しているインスタンスタイプを選択する必要があるため、t3.nanoを選択しています。

# SSHクライアント
まずは、Teraterm等のコンソールでSSH接続します。
注意点は、セキュリティグループでアクセス元のIPからの通信を許可するくらいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/3368d609-6107-6a6a-e6ae-7aa7265ccf39.png)

# セッションマネージャー
さて、ここからが本題です。次はセッションマネージャーでログインを試みます。マネジメントコンソールより、セッションマネージャーで接続しようと下記のエラーが出ますので、解決していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/b2b21a73-7349-219b-cfe5-84c93664b64b.png)
まず、minimalイメージを使用する都合上、SSMエージェントは入っていませんので、 SSM エージェント をインストールします。[（参考）][1]`systemctl`で確認して、起動していなければ起動しておきます。
```
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo systemctl status amazon-ssm-agent
```
次に、インスタンスに```AmazonSSMManagedInstanceCore```ポリシーを含むIAMロールをアタッチします。以下の画像は事前に作成してあるIAMロールをアタッチしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/45c03737-bf7e-9875-ceae-a641779a4e7c.png)

ここまで出来たら接続を試します。以下のような画面で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/15cd7a9c-23aa-7177-78d0-9847176c5956.png)

# EC2 Instance Connect
次はEC2 Instance Connectで接続を試みます。こちらもminimalイメージを使用する都合上、まずはEC2 Instance Connectをインストールします。
```
sudo yum install -y ec2-instance-connect
```
また、[こちら][2]のページに記載のあるIPアドレスからのSSHのインバウンドを許可しておきます。今回は面倒なので`0.0.0.0/0`で指定してしまいました。

接続すると以下のような画面で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/43586f3a-fa0d-2140-31cb-3d9946acb9e6.png)

# EC2 シリアルコンソール
最後にEC2 シリアルコンソールにて接続を試みます。接続自体はすぐにできるのですが、パスワードにてログインする必要があります、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/e57cbd18-28f3-6328-e0f5-1a372a1072e2.png)

そのため、下記記事を参考にrootアカウントにパスワードを設定します。

https://qiita.com/shanonim/items/5496e0c6f6bf09e76f7c

パスワードを設定したら、再度ログインを試みます。無事ログインに成功しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/ccd2ecb8-7920-8d7d-e13d-3236d2360669.png)

# 感想
TeraTermがなくても、多岐にわたる方法でログインできることがわかりました。EC2 Instance ConnectはSSH接続に近い考え方で、設定さえしてしまえば気軽に使えるので便利だと思います。シリアルコンソールは、事前に設定しておくことでSSHできなくなった時の回避策として使えそうです。

[1]:https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-manual-agent-install.html
[2]:https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html?_fsi=2y2i1jYx
godocのインストール　go 1.20以降

Goのgodocを使うとエラーが出るので再インストールしました。
しかし、従来のインストールだとエラーが出てしまう。
調べたらインストール方法が変わっていました。

１．godocの最新版が利用可能かどうかを確認します：
```   
go list -u -m -versions golang.org/x/tools/cmd/godoc

```
2.最新版が入手できない場合は、特定のバージョンの godoc をインストールしてみることができます。例えば、バージョン v0.1.2 をインストールするには、以下のコマンドを実行します：
```
   go install golang.org/x/tools/cmd/godoc@v0.1.2

```
最新版の godoc をインストールする場合は、コマンドの最後にあるドットを必ず削除してください。正しいコマンドは
```
go install golang.org/x/tools/cmd/godoc@latest
```
しかし、インストールは完了したのですが
エラーが出てしまいます。
```
(base) PS > godoc os/user Current
Unexpected arguments. Use "go doc" for command-line help output instead. For example, "go doc fmt.Printf".
usage: godoc -http=localhost:6060
  -goroot string
        Go root directory (default "C:\\Program Files\\Go")
  -http string
        HTTP service address (default "localhost:6060")
  -index
        enable search index
  -index_files string
        glob pattern specifying index files; if not empty, the index is read from these files in sorted order
  -index_interval duration
        interval of indexing; 0 for default (5m), negative to only index once at startup
  -index_throttle float
```
調べたら　コマンドの使い方が前と変わっていました。
```
go doc <package-name>
```
これで正常にコマンドが実行できました。
【AWS】CloudFormationで必要最低限なCLIをまとめてみた

CloudFormaitonのスタック作成はAWSコンソールからだとポチポチが必要な以上、少し手間だったりします。特にスタック作成がうまくいかないときのやり直しはけっこうしんどいです。なので**Terraformライク**を目指して、CLIのコマンドをまとめてみました。なお、コマンドは**重要度の高い順**で記載してます:pencil:

※GUIでのスタック作成はこちら↓

https://qiita.com/hiyanger/items/3a47c39bddd8ccd99f64

## deploy
まずはデプロイからです。**create-stack**だと、スタックがあると実行できませんが、こっちの**deploy**なら削除せずに更新が可能です。Terraformの**apply**的な使い方ができます。ただし更新内容などは表示されず、**コマンド一発で更新がかかる**のでそこだけ注意しましょう。（更新は次の項で説明するオプションで回避可能です）
```
aws cloudformation deploy --stack-name test-stack --template-file template.yaml --parameter-overrides $(cat parameter.yaml)
```
パラメータの引数は単にコマンド上で記載できますが、あえて外だししています。記述の仕方は単に**パラメータを縦に並べる**だけでOKです。下記はキーペアとIPをパラメータに指定した場合の記述例です。

```yaml:template.yaml
KeyName=test-stack
MyIP=192.168.1.1/32
```

#### --no-execute-changeset（オプション）
deployコマンドは自動的に変更セットを更新しますが、このオプションを付ければ更新されなくなります。要するに**更新内容の確認ができる**ということです。Terraformでいう**plan**をイメージしていただければよいです。
```
aws cloudformation deploy --stack-name test-stack --template-file template.yaml --parameter-overrides $(cat parameter.yaml) --no-execute-changeset
```


基本的にこの**deploy**コマンドをメインにすればよいですが、一応スタンダードは**xxx-stack**コマンドです。また、スタックが失敗した場合にdeployは流せなくなるので、**delete-stack**は必須なコマンドになります。

## xxx-stack
####  create-stack
その名の通りスタックを作成するコマンドです。
```
aws cloudformation create-stack --stack-name test-stack --template-body file://template.yaml --parameters file://parameter.yaml
```

こちらの場合のパラメータは以下のような形式で作成します。
```yaml:parameter.yaml
[
  {
    "ParameterKey": "KeyName",
    "ParameterValue": "test-stack"
  },
  {
    "ParameterKey": "MyIP",
    "ParameterValue": "192.168.1.1/32"
  }
]
```

#### delete-stack
スタックを削除するコマンドです。
```
aws cloudformation delete-stack --stack-name test-stack
```

#### list-stacks 
スタックの一覧を取得するコマンドです。
```
aws cloudformation list-stacks --query "StackSummaries[].{StackName:StackName,CreationTime:CreationTime,StackStatus:StackStatus}" --output table
```
一覧だと大量でてしまう場合などは、**stack-status-filter**オプションを使いスタックのステータスで絞ることも可能です。以下のコマンドではステータスを**CREATE_COMPLETE**に絞っています。
```
aws cloudformation list-stacks --query "StackSummaries[].{StackName:StackName,CreationTime:CreationTime,StackStatus:StackStatus}" --output table --stack-status-filter CREATE_COMPLETE
```
なお、スタック名でも絞ったり出来たりしないかなと思ったのですが、該当するオプションはなさそうでした。

## validate-template
テンプレートファイルのチェックが可能です。VSCodeの拡張機能などを使っていればチェック必要性はないかもしれませんが、パラメータも出力できるのでパラメータのチェックにも使えます。
```
aws cloudformation validate-template --template-body file://test-stack.yaml
```

以上です。これでCloudFormationもCLIで流せるようになるでしょう:sparkles:

## 参考にさせていただいた記事
https://dev.classmethod.jp/articles/aws-all-iac/

https://dev.classmethod.jp/articles/read-aws-cli-cfn-options/#toc-8

https://blog.serverworks.co.jp/2020/08/14/190000
VisualStudioの「親またはプロジェクトの既定値から継承」ってどこから参照しているの？

## きっかけ
先日仕事でPythonをC++からビルドする必要があり色々問題にぶち当たっていくうちにふと疑問に思った。
「VisualStudioの親またはプロジェクトの既定値から継承」ってどこから値をとってきているのだろう？
プロジェクトの既定値というのはVisualStudio側で予め用意されている値で、プロジェクトの設定をおこなう上で便利な値の集合体というのはなんとなくわかるし特に弄ることもないのではないと思うが、継承ってどう設定すればいいんだ？というのがきっかけ。
調べていくうち継承元の値の確認方法、どのように設定されているのか等が判明したので備忘録として残しておく。

## 継承元の値を確認したり編集したりする
そもそも継承元の値ってどこにあってどういったものなの？というところから実際に追加や編集していく方法を書いていく。

### 確認手順

今回はPythonのソースコードをダウンロードしてPCBuildのソリューションファイルを開いたところから始める。(このあたりのセットアップ手順は割愛)

1. ソリューションを開くといつもの画面が表示され、ウィンドウ右側にソリューションエクスプローラーが表示される。
1. ソリューションエクスプロラーの中からプロジェクトを右クリックし、プロパティをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329073/6d599700-6944-0dd2-9f00-edd20928849d.png)
1. 開いたウィンドウから C/C++ > 追加のインクルードディレクトリ > 編集 > 追加のインクルードディレクトリウィンドウを開く

これまでの手順で開いた「追加のインクルードディレクトリ」ウィンドウの一番下に表示されている「継承の値」とういのが今回キモとなる項目。ほか項目でも継承元の値を参照している箇所は複数あり、Pythonをビルドするに当たって必要となる共通パラメータが設定されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329073/cbd796cd-379c-c4a9-e3f1-6c0e8e353b39.png)

今回Pythonプロジェクトを開いた段階で既に追加されているもので、編集や追加・削除等はできないようになっている。が、これらの値が別ライブラリを追加した際に何かしらの弊害になっていることがあったりするかもしれない。というか実際自分はあった。

### 継承元の値はどこに保持されているか

結論から言うと*.propファイルに記載があった。

Pythonプロジェクトの場合pyprojct.props。
前述したインクルードディレクトリで使用されていた PySourcePathほにゃらら なんかもここに記載があり、このpyproj.propsを参照して多数あるプロジェクトの設定を共通化しているようだった。

```xml
  <ItemDefinitionGroup>
    <ClCompile>
      <!--↓ここに書かれてる-->
      <AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>

      <Optimization>MaxSpeed</Optimization>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <StringPooling>true</StringPooling>

```

ということはこのpyproject.propsを編集すればPCBuildで参照されている全プロジェクトの「継承元の値」が編集できそう。

### 対象プロジェクトにインポートされている*.propsファイルを編集する

1. プロパティマネージャーを開く(表示 > その他ウィンドウ > プロパティマネージャー)
1. プロパティシートのプロパティウィンドウを開く(プロジェクト一覧から対象のプロパティシートを右クリック > プロパティ)
1. 設定したい内容を編集して適用をクリック

上記手順でインクルードディレクトリを編集してみたところ、pyproject.propsが適用されている全てのプロジェクトに無事変更が反映されていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329073/0d8020d5-de40-5e92-40f7-bd0e4df49f23.png)
testdirが追加されている。

## まとめ
*.propsの共通項をファイル化して設定を一括反映できるのは結構便利そう。最近VisualStudio単体でがっつり使うこととかあんまり無いけどライブラリ自作する時とかに使えそうだから覚えておこう。

プロパティの継承についての詳しい情報は↓
https://learn.microsoft.com/ja-jp/cpp/build/project-property-inheritance?view=msvc-170
CSS 擬似要素と擬似クラス

# 擬似要素とは
擬似要素とは，要素の一部に対してスタイルを適用できる指定方法である．擬似要素を利用することで，HTMLを変更することなく，要素内の特定の部分にスタイルを適用させることができる．

# 擬似要素の基本構文
```css
セレクタ:擬似要素{
    property: value;
}
```
セレクタと擬似要素を，コロン``：``を2つで繋ぎ，適用したいプロパティを記述することで利用することができる．

# 擬似要素のメリット
先ほど述べたように，擬似要素を使うことでHTMLを変更することなく特定の部分にCSSを適用させることができる．以下の２つのコードはどちらも同じ結果を出力する．擬似要素を利用することで，HTMLの簡略化ができていることがわかる．

**◯擬似要素を利用しない場合**
```html
<!-- html -->
<p><span>最</span>初の文字だけ赤色です．</p>
<!-- css -->
<style>
    span{ color: red;}
</style>
```
**◯擬似要素を利用した場合**
```html
<!-- html -->
<p>最初の文字だけ赤色です．</p>
<!-- css -->
<style>
    p::first-letter{ color: red;}
</style>
```
↓結果
![擬似要素.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/8d479d43-c8bf-dacc-3b34-cd592889f704.png)

# 主要な擬似要素
ここでは，代表的な擬似要素を挙げる．他のもたくさんある．

||機能|
|:--:|:--:|
|::after|選択した要素の直後にスタイルを適用した要素を付け加える|
|::before|選択した要素の直前にスタイルを適用した要素を付け加える|
|::first-letter|要素の一番最初の文字に対してスタイルを適用する|
|::first-line|要素の最初の行に対してスタイルを適用する|

``::after``と``::before``はどちらも新たに付け加える内容を書く必要があるため，``content: ;``というプロパティが必ず必要となる．

# 擬似クラスとは
擬似クラスとは，選択された要素に対して，特定の状態である場合にスタイルを適用できる指定方法である．ユーザの動きに対してもデザインを変化させることができ，擬似要素と同様に，HTMLに一切変更を加える必要がないというメリットがある．

# 擬似クラスの基本構文
```css
セレクタ:擬似クラス{
    property: value;
}
```
擬似要素と異なり，セレクタと擬似クラスをコロン``：``を１つで繋ぎ，適用したいプロパティを記述することで利用することができる．


# 代表的な擬似クラス
**１．:hover**
``:hover``はマウスカーソルが要素の上に乗った時にスタイルを適用する．
```css
element:hover{
    property: value;
}
```

**２．a:link(a:visited)**
``a``タグに対して，そのリンクが未訪問の状態である場合にスタイルを適用する．逆に訪問済みの状態を指定する場合は``visited``にすることでスタイルを適用できる．
```css
a:link{ property: value;}
a:visited{ property: value;}
```

**３．:nth-chile(n)**
親要素内のn番目の要素に対して，スタイルを適用させることができる．
```css
element:nth-chile(n){ 
    property: value;
}
```

他にも，文書の言語や時間によってスタイルを変える擬似クラスもある．必要に応じて調べるのが良い．
社内でElm勉強会をやってみた

# はじめに
自分がプライベートでElmを触り始め、公式チュートリアルを一通り終えて「Elmめちゃくちゃ面白え～～～～～」となり、開発途中の個人開発アプリをReactからElmにリプレイスしたりしていました。
そんなタイミングで、社内の若手でテーマを出し合って勉強会をしようという話になり、Elm勉強会を立ち上げてみました。
一旦キリの良いところまで終わったので、振り返りたいと思います。

# 参加者のレベル感
入社1年未満～2, 3年ぐらいの若手を対象にした勉強会でした。
1人はHaskell経験者で、他は関数型言語未経験者でした。
（なお、候補者10名弱に対し、参加希望者は3人でした...(´・ω・｀)）

いずれも前職などである程度開発経験があり、かつ言語仕様などをしっかり勉強する傾向のある人が集まりました。

# やったこと
[公式チュートリアルの日本語版](https://guide.elm-lang.jp/)を見ながら、私が説明していきました。
ハンズオン等はやっていません。
(チュートリアル内で出てきたコードの実行や書き換えなどはした)

週1回、1時間程度時間を取り、チュートリアルの以下を読み進めました。
- はじめに
- 言語の基礎
- 型
- The Elm Architecture
- エラーハンドリングのMaybeのみ
- 付録
また、公式チュートリアルではありませんが、Cmdの説明をしたかったので以下記事も説明させて頂きました。
https://qiita.com/ababup1192/items/2b86ade96651716fc3a8

目論見としては、まずはWebアプリケーションや各副作用を学ぶ前の下地を整えようと思っていました。

# 工夫点
自分がプライベートでElmチュートリアルを進めていて詰まった点などを回避したり、詳細に説明するようにしました。

### 読む順番
私の時は最初横メニューの上から順番に見ていったのですが、「言語の基礎」の後に「TEA」の内容があり、
言語の基礎で基本的な文法は見たものの、型の定義や読み方などは全く分かっておらず読み進めるのに苦労していました。
なので、勉強会では「言語の基礎」の後に「型」を説明し、Elmのコードがある程度読めるようになってから「TEA」をやりました。
これは割と良かったと思います。

### Elmの思想を伝える
私自身Elmの思想に共感したため個人で勉強する気になった部分もあったので、最初にElmとはどういう思想のもと作られた言語なのかを説明しました。
また、チュートリアルを読み進める中でも「こういう思想だからこういう仕様になっているんだよ」みたいな話をしました。
ただ説明するだけでなく、「なぜそのような仕様になっているのか」という部分を理解してもらうことで、今後Elmをやらないにしても他言語でElmの思想を活かして貰えたらいいなと思っていました。

### 積極的に寄り道をする
チュートリアルの途中で付録へのリンクが貼ってある部分は、参加者が興味ありそうであればそちらへの寄り道を実施しました。
また、「この関数の実装ってどうなってるの？」という質問があればパッケージのドキュメントを一緒に読んだり、
「こういうコード書いた時はどんなコンパイルエラーが出るの？」という疑問があればEllieで書いてみたりしました。

### 勉強会の区切り
やったことにも書きましたが、意図的に各副作用(HTTP, JSON, Random, Time)やWebアプリケーションまで進めませんでした。
これも私がチュートリアルを駆け抜けたときに、CmdやJsonDecoderあたりでかなり脳に負荷を感じたためです。
これらを飲み込む下地を整えるため、その手前までのチュートリアルを理解してもらおうと思っていました。

# 今後
今後は副作用、Webアプリケーションのところも読み進めていきたいと思います。
それが終わったら以下などをしようかな～と思っています。
- [Elm-drill](https://github.com/jinjor/elm-drill)やってみる
- [プログラミングElm ~安全でメンテナンスしやすいフロントエンドアプリケーション開発入門](https://www.amazon.co.jp/dp/4839970041)の読書会
※[基礎からわかる Elm](https://www.amazon.co.jp/dp/4863542224)は、未読ですが目次を見る限りではチュートリアル+上記の本でカバーできるのではと思ったので一旦候補から外しました
- なにか作ってみる
- 私の個人開発アプリのソースを読む
- 便利そうなパッケージを勉強してみる

# 感想
好きな言語のことを喋るのはかなり楽しかったです。
参加者も積極的に質問等してくれて嬉しかったです。
Elmには、意識が高い(というと語弊があるが)人が勉強したくなるような魅了があるな～と感じました。
仕事でElm使いたさが高まりました。
Next.jsでFontAwesomeを使うときにエラーになる

Next.jsでFont Awesomeを使うときに、アイコンが一瞬大きく表示される。
Font AwesomeのCSSが遅れて読み込まれることが原因。
解決するためには設定が必要だがそのコードを検索して書いたらエラーになった。

<h2>今回起こったこと</h2>

/pages/_app.jsに下記のコードを追加したがエラーになった。
~~~_app.js
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
~~~

Nextのバージョンは以下の通り。

~~~package.json
"dependencies": {
    "next": "13.4.2",
    "react": "18.2.0",
    "react-dom": "18.2.0"
  }
~~~


<h2>解決策</h2>

<a href="https://fontawesome.com/docs/web/use-with/react/use-with#next-js" target="blank">Fontawesomeのトラブルシューティング</a>によると、Next.js の新しいバージョンでは、このエラーが発生する可能性があるようだった。
2行目の@fortawesome/fontawesome-svg-core/styles.cssのインポート方法を変更することで解決。

~~~_app.js
import { config } from '@fortawesome/fontawesome-svg-core'
import '../node_modules/@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
~~~

これでエラーが解決された。
smbcontrol コマンドの書式とオプション

●smbcontrol
smbcontrolは、Sambaの主要なデーモンであるsmbd、nmbd、winbinddにメッセージを送ることができるプログラム。

コマンドの書式とオプション

smbcontrol [対象] [メッセージタイプ]

●主な対象
・all　smbd.nmbd,winbinddのすべてのプロセスにブロードキャスト※Samba3.3より前は全てのsmbdのみ
・<デーモン名>または<PID>　smbd.nmbd,winbinddのいずれか指定されたデーモンのpidファイルに記載されたプロセスID、または直接指定したプロセスIDにメッセージが送られる


●主なメッセージタイプ
・close-share　指定した共有をクローズ※対象はsmbdのみ
・reload-config　指定したデーモンに設定の再読み込みをさせる
・kill-client-ip　指定したIPアドレスのクライアントを切断※対象はsmbdのみ
・ping　指定した対象にpingし、応答(pong)が来た対象のPIDを表示I
MySQLのIN句は遅くなりやすい

# はじめに
医療系クラウドサービスを提供しているレイヤードという会社で働いています。

あるサービスのMySQLデータベースにおいてslowqueryが多発して、CPU使用率も99.8%まで爆上がりするという事件が起きましたので、その時の調査した内容の共有です。
<img src='https://i.gyazo.com/4056f39d5e27c9837a8f6bfde7feba33.png' >

# 1.IN句で指定する値の数が多いとヤバい
今回の事件はコーディングミスによりIN句で指定する値の数が1.5万個にもなるコードを混入させたのが原因でした。以下はスローログの画面です。
<img src='https://i.gyazo.com/0075da09ebf836ad1b3a3a9ee3f84d38.png' >

### DB周り
- エンジンバージョン：8.0.mysql_aurora.3.02.2
- インスタンスクラス：r5.2xlarge
- 対象テーブルのレコード数：1,000万レコード

### 発行したクエリ
IN句で指定したidの数は15,000個程度
``` SQL
SELECT COUNT(*) FROM patients WHERE id IN (1,2,3,4...)
```

### 検証
同DBに以下のSQLを投げてみた。
※書き込み等が頻繁に発生してる実運用中のDBだともっと劣化すると思います。
- IN句で指定するidの数を15,000個で4.43s秒程度
- IN句で指定するidの数を7,000個で0.22s程度
- IN句で指定するidの数を1,000個で0.10s程度

### 考察
- 7,000個と15,000個の間で大きく劣化する事が分かった
- slowlogの画面を見ると、当該クエリが終わる前に次のクエリが発行され時間経過と共に同時実行数が増えていった
- 当該クエリの同時実行数が増えると共にパフォーマンスが劣化し、自身のクエリ及び他のクエリも含めて全体的にどんどん遅くなっていくという悪循環に陥っていったと思われる

### 対応
- そもそもコーディングのミスだったので（1.5万個もid指定する必要無い）ので普通に修正
- IN句を利用する時は想定個数を最大7,000個で考える（検証結果を見る限り1万個には近づきたくない）
- 7,000個を超える場合はクエリを分割して複数回実行するようにする

※基本方針としてなるだけDBのチューニングはしない方針です

# 2.JOINと一緒にIN句を使うと適切なインデックスが選ばれない場合がある
データを集計す為に実行したクエリがやたら遅い（タイムアウトする場合も多々ある）ので調査しました。

### DB周り
- エンジンバージョン：8.0.mysql_aurora.3.02.2
- インスタンスクラス：r5.2xlarge
- インデックス：複合index（sheets.hospital_id,sheets.created_at）、他
- 対象テーブルのレコード：1,000万レコード
- カウント結果：18万個
- 実行時間：ほぼタイムアウトする

### 発行したクエリ
``` SQL
SELECT
 count(*) 
FROM
 sheets LEFT JOIN hospitals ON sheets.hospital_id=hospitals.id
WHERE
  sheets.hospital_id IN (1,2,3,4,5...)
AND
  sheets.created_at BETWEEN '2023-4-01' AND '2023-4-30 23:59:59'
AND 
  hospitals.summary_flg=1
```

### 検証
- 上記クエリ（IN句で指定したidの数は700個程度）をexplainすると割と無関係なindexが採用されていました
- hospital_idを`IN`で指定する個数を2個にしても割と無関係なindexが採用されました
- hospital_idを`IN`ではなく`=`にすると目的のindexが採用されました
- hospitalsテーブルのJOINをやめて2回のクエリに分けると、`IN`句を利用しても目的のindexが利用されました

### 考察
- id2個でも目的のindexを採用してもらえなくなったので`eq_range_index_dive_limit`は関係なさそう

### 対応
- 今回は単純にJOINとIN句を併用すると適切なインデックスが選ばれなくなるので、クエリを分けて運用する事にしました（Railsだと以下のような感じ）
```Ruby
hospital_ids = Hospital.where(id, [1,2,3,4...]).where(summary_flg: 1)
sheets = Sheet.where(hospital_id: hospital_ids).where("created_at BETWEEN ? AND ?", '2023-4-01 00:00:00', '2023-4-30 23:59:59')
```

# 参考
- freeさんの記事が大変参考になりました
https://developers.freee.co.jp/entry/large-in-clouse-length-cause-full-scan
profile-gpt を試行する

# 概要
chatGPTの対話ログから、自身の性格などを考察してくれます


# offiial
https://github.com/sahbic/profile-gpt



# 実行環境
- m1 mac moterey
- python 3.10 
- openai api key 発行は以下方法などを参照されたし
    - https://qiita.com/Satoshi_Numasawa/items/8ab455ef0f97e61ae0e5 




# install
``` bash
git clone https://github.com/sahbic/profile-gpt.git
cd profile-gpt
pip install -r requirements.txt
```


# api key 設定
``` bash
cp .env.example .env
vi .env
```

以下へ api key を書き込む
``` python
OPENAI_API_KEY=
```


# 実行
以下を実行するとでブラウザで画面が開く

``` bash
streamlit run dashboard.py
```

 

 
# chatGPT log を取得
- chatGPT の画面を開く
- 画面左下から setting 画面を開く
    ![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/52f6ae3c-6336-125d-a760-872a9160973f.png)


- settings を選択
![020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/07c0a320-665f-0031-44a9-6613b3c22371.png)


- data control から export を選択
    ![030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/6eda1092-50e4-ea1e-57da-91dd06e260f9.png)


- confirtm export を選択
    ![040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/66fbe77c-a724-574b-78c4-07a2f4bc1b8a.png)


- 登録した mail address へ mail が届く
- mail から圧縮ファイルを DL する




# 性格解析を実行する
- ブラウザへ戻る
- 左下の `browse files` から DL した file を選択する
- `Start Analysis` から実行する
- 初回 token 超過 error が出たが, 二回目では実行できた
    ![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/57e6c3db-f76b-def8-15e4-7a8c687d11b5.png)



# 解析結果
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/2ad99ef0-f265-bbcb-0715-71ca109e5af3.png)

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/38669c50-6d77-e4a6-c169-b5c60d627f2a.png)


# 解析結果 : 翻訳
```

# ライフサマリー
チャットボットに送信されたメッセージから、ユーザーのライフサマリーは、
個人史、学歴、仕事、家族について語られなかったため、不明です。


# 趣味・関心事
会話タイトルとそれに対応するメッセージトピックのリストに基づき、
ユーザーの趣味・関心は、文学、心理学、AI技術、プログラミング、
日本語・日本文化、ビデオゲーム、メディア分析に要約されます。


# 性格診断
ユーザーは、好奇心と分析力に富み、AI、文学、プログラミングなど
様々なテーマに強い関心を抱いているようです。
ZoomインタラクションやRuby on Railsなど、技術的な分野にも
精通している。
一方で、ユニークな思考回路を優先し、フォロワーというよりは、独立
したクリティカルシンカーである。一般的に、メッセージの内容から内
省的で知的、分析的であるように見えます。


# メンタルヘルスの評価
ユーザーの精神的な健康状態は、精神的な健康上の問題を示唆す
るような特別な話題はなく、正常であると思われます。


# 未来予想図
ユーザーのメッセージから、人工知能、日本文化、SFに関連するトピ
ックに高い関心があると予測します。
複雑で抽象的な概念を探求するのが好きで、テクノロジーの未来に
深い関心を持つ、オープンマインドな人である可能性が高いです。
キャリアについては、AI分野への興味から、ソフトウェア開発やデータ
分析など、関連する業界で働くことが考えられます。知的好奇心が旺
盛で、技術に対する情熱があり、それが自分の職業を極めようとする
意欲につながっているようです。
人間関係では、感情的な書評に興味を持ち、人間の行動心理に興味
を持つことから、他者との有意義なつながりを重要視していると思わ
れます。また、自分だけでなく、周りの人を理解しようとする内省的で
共感的な性格の持ち主である可能性が高いです。


# ユーザーからのメッセージに基づくMBTIテスト結果の可能性
内向性（I）/外向性（E） 感覚（S）/直感（N） 思考（T）/感情（F） 判断（J）/知覚（P） MBTIタイプ
51% i 55% n 53% t 58% p intp


# ユーザーのメッセージから推定されるビッグファイブ性格特性結果
特性スコア レベル 性格特性
開放性 7 中 好奇心
良心的 4 低 自発性
外向性 2 低 予約性
同意性 3 低 クリティカルシンキング
神経質 7 中
```

# 所管
- 面白い
- ログ自体が少ないので偏りがある気がするが, 大きなズレは感じない
    - ログが溜まり, GPT4 api を使用できたらもっと精度が上がりそう
- MBTI は実際のテスト結果のINTP と合致している 
    - ビッグファイブは不明
- 稀に実施させられる適正検査みたいなものが, GPTでも出来そう
ubuntu上でreveal.jsを構築

公式ドキュメントから
```
apt -y update
apt -y install nodejs npm
```

reveal.jsのダウンロードと起動
```
git clone https://github.com/hakimel/reveal.js.git
cd reveal.js && npm install
npm start
```

エラーがでた場合は以下を実行
```
cd reveal.js
npm config set unsafe-perm=truesu otheruser
npm i -g puppeteer --unsafe-perm
npm install
npm start
```

## markdownを読み込む
bodyのdiv class="reveal"内で以下のように記述することで、md/slide.mdを読み込んでくれます。
```
<body>
ここから
<pre style="display:none"><code></code></pre>
<div class="reveal">
  <div class="slides">
    <section data-markdown="md/slide.md" data-separator="^\n---\n$" data-separator-vertical="^\n>>>\n$"></section>
  </div>
</div>

                <script src="dist/reveal.js"></script>
                <script src="plugin/notes/notes.js"></script>
                <script src="plugin/markdown/markdown.js"></script>
                <script src="plugin/highlight/highlight.js"></script>
                <script>
                        // More info about initialization & config:
                        // - https://revealjs.com/initialization/
                        // - https://revealjs.com/config/
                        Reveal.initialize({
                                hash: true,

                                // Learn about plugins: https://revealjs.com/plugins/
                                plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
                        });
                </script>
ここまで
</body>
```



## 他のホストにも公開する
今のままだと、localhost以外からはアクセスが出来ない。

### reveal.js/gulpfile.js
以下のlocalhostを0.0.0.0に変更
変更前
```
const host = yargs.argv.host || 'localhost'
```
変更後
```
const host = yargs.argv.host || '0.0.0.0'
```

##### 参考文献
https://yoghurt1131.hatenablog.com/entry/2016/02/11/222840
https://mebee.info/2020/03/02/post-5261/
https://qiita.com/t-kusakabe/items/725e7438892bba395062
https://zatsugaku-engineer.com/html-css-javascript/reveal-js/#i-3
https://tech-blog.rakus.co.jp/entry/20191127/tool-introduction/reveal.js?amp=1
https://revealjs.com/markdown/
https://revealjs.com/transitions/
https://revealjs.com/auto-animate/
[メモ] PowerShellでかな文字列を平仮名全角清音に変換

PowerShellで、ひらがな、カタカナ、半角カナ交じりの文字列に対して以下の変換を実施する。

* すべてひらがなにする
* 濁音、半濁音を清音にする（"ば"や"ぱ"→"は"）
* 小さな文字（拗音、促音文字）を大きな文字にする。

```powershell
$str = "ヴぁーちゃﾙグルーぷ"

# 清音化とひらがな化
# 一度半角カナにして濁点、半濁点を置換削除するバッドノウハウを使用
[reflection.assembly]::LoadWithPartialName("Microsoft.VisualBasic") | Out-Null
$str = [Microsoft.VisualBasic.Strings]::StrConv($str, [Microsoft.VisualBasic.VbStrConv]::Katakana)
$str = [Microsoft.VisualBasic.Strings]::StrConv($str, [Microsoft.VisualBasic.VbStrConv]::Narrow)
$str = $str -replace "[ﾞﾟ]", ""
$str = [Microsoft.VisualBasic.Strings]::StrConv($str, [Microsoft.VisualBasic.VbStrConv]::Wide)
$str = [Microsoft.VisualBasic.Strings]::StrConv($str, [Microsoft.VisualBasic.VbStrConv]::Hiragana)

# 小さい文字（拗音、促音）を大きな文字に
# ここは単純に一つずつ置換
$from = "ぁぃぅぇぉゃゅょっ"
$to = "あいうえおやゆよつ"
0 .. ($from.Length - 1) | %{ $str = $str -replace $from.Chars($_), $to.Chars($_) }

return $str
```

# 参考

`strConv`関数を使う方法と、引数などについては以下を参考にしました。

* [半角→全角、全角→半角の数値変換スクリプト](https://social.technet.microsoft.com/Forums/ja-JP/fce782d5-2e86-440e-994d-6c033c457d69/21322352828594208403528212289208403528285942132235282123982596?forum=powershellja)
* [StrConv 関数 (Visual Basic for Applications) | Microsoft Learn](https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/strconv-function)

清音化を、一度半角カナにして濁点と半濁点を置換削除で行うのは、昔ながらのバッドノウハウ。最後の拗音、促音の置換をループでやるのも、昔ながらの普通の文字列処理技（だと思う）。
UFWによるNAT＋ファイアーウォール構築

この様な環境を構築する

![演習環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/9475de6f-11ed-82c6-3db1-9ab3cd5ebab6.png)
今回はここのFWのルールを設定する

上から評価される。デフォルトのルールは一番最後に適用される

NATの設定

```=bash
nano /etc/default/ufw
```



```
nano /etc/ufw/before.rules
```
以下を追加
```
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT


#########################################33
nano /etc/ufw/before.rules
# NAT rules
*nat

:POSTROUTING ACCEPT [0:0]
-F
-A PREROUTING -p tcp --dst 10.0.2.22 -m multiport --dports 22,80 -j DNAT --to-destination 192.168.40.19
-A POSTROUTING -p tcp --dst 192.168.40.19 -m multiport --dports 22,80 -j SNAT --to-source 192.168.40.18
-A POSTROUTING -s 192.168.40.0/24 -o enp7s0 -j MASQUERADE
-A POSTROUTING -s 192.168.50.0/24 -o enp7s0 -j MASQUERADE
-A POSTROUTING -s 192.168.60.0/24 -o enp7s0 -j MASQUERADE
COMMIT
#############################################




ufw allow ssh
ufw allow http

ufw route allow from 192.168.40.0/24 to 10.0.0.0/16
ufw route allow from 192.168.50.0/24 to 10.0.0.0/16
ufw route allow from 192.168.60.0/24 to 10.0.0.0/16


ufw route allow from 192.168.50.0/24 to 192.168.60.0/24
ufw route allow from 192.168.60.0/24 to 192.168.50.0/24
ufw route allow from 192.168.40.19 to 192.168.50.45
ufw route allow from 192.168.50.45 to 192.168.40.19


ufw route allow in on enp10s0 out on enp7s0 to 0.0.0.0/0
ufw route allow in on enp8s0 out on enp7s0 to 0.0.0.0/0
ufw route allow in on enp9s0 out on enp7s0 to 0.0.0.0/0
```



##### 参考文献
- https://server-network-note.net/2022/07/ubuntu-server-22-04-lts-firewall-ufw/
- https://qiita.com/tukiyo3/items/56525cb1b30cdd19fade
- https://www.server-world.info/query?os=Ubuntu_22.04&p=ufw&f=2
- https://qiita.com/RyoMa_0923/items/681f86196997bea236f0
- https://rohhie.net/ubuntu20-04-use-ufw-to-make-a-router/
- https://hico-horiuchi.hateblo.jp/entry/20141128/1417161916
- https://ubuntu-nikki.hatenadiary.org/entry/20100921/1285077768
Cloud9での開発環境構築

https://dev.classmethod.jp/articles/how-to-use-aws-cloud-9-with-vscode-remote-ssh/


https://dev.classmethod.jp/articles/cloud9-terraform/

https://qiita.com/hayate_h/items/93273285cdc7372ae569



```
#!/bin/bash

# コピー元のS3バケット名とプレフィックス
source_bucket="your-source-bucket"
source_prefix="your-source-prefix/"

# コピーする日付（YYYY-MM-DD形式）
copy_date="2023-05-31"

# コピー元のS3バケットから指定日付以降のオブジェクトをローカルにコピーする
aws s3api list-objects --bucket $source_bucket --prefix $source_prefix --output json --query 'Contents[?LastModified>=`'"$copy_date"'T00:00:00`].{Key: Key}' | jq -r '.[].Key' | xargs -I {} aws s3 cp "s3://$source_bucket/{}" "{}"
```
KVMにOVAをインポートする方法

## 手順
### 必要なパッケージをインストール
```
apt -y update && apt -y install qemu-utils
```

## コマンド体系
```
qemu-img convert [-f format] [-O output_format] <input_image_file> <output_image_file>
```

### OVAイメージの展開
```
tar -xvf ovaファイル.ova
```
### 
```
qemu-img convert -f vmdk -O qcow2 vmdkファイル.vmdk 任意の名前.qcow2
```

##### 参考文献
https://jp7fkf.hatenablog.jp/entry/20200125/1579879934
https://access.redhat.com/ja/articles/1454433
【Docker】プロジェクト名を指定する方法

## デフォルト
`docker compose build`などを実行する際に特に何も設定していない場合にはカレントディレクトリ名がプロジェクト名となります。
例えばカレントディレクトリが`sample-app`であった場合、プロジェクト名も`sample-app`となります。

## プロジェクト名の設定方法
プロジェクト名は以下の方法で設定できます。

### `-p`オプションを使用
`docker compose`コマンドを実行する際に`-p`または`--project-name`を使用することでプロジェクト名を指定できます。
```:ターミナル
$ docker compose -p プロジェクト名 build 

$ docker compose --project-name プロジェクト名 build
```

### 環境変数で設定する
環境変数`COMPOSE_PROJECT_NAME`にプロジェクト名を設定することでプロジェクト名を指定できます。
```:ターミナル
$ COMPOSE_PROJECT_NAME=プロジェクト名　docker compose build 
```
または
```.env
COMPOSE_PROJECT_NAME=プロジェクト名
```
```:ターミナル
$ docker compose build 
```

### トップレベルの`name`で設定
`compose.yml`に以下のように記述することでプロジェクト名を指定できます。
```compose.yml
name: プロジェクト名
services:
  db:
    image: mysql:8.0.30
    <以下略>
```

## 補間
`compose.yml`でプロジェクト名を補間するためには`${COMPOSE_PROJECT_NAME}`のように記述します。
```compose.yml
name: プロジェクト名
services:
 api:
    build:
      context: .
      dockerfile: ./docker/api/Dockerfile
    volumes:
      - .:/${COMPOSE_PROJECT_NAME}
```

## 優先順位
複数の方法でプロジェクト名を指定した場合、以下の順位で適用されます。

1. `-p`オプションを使用
2. `COMPOSE_PROJECT_NAME=プロジェクト名　docker compose build`を実行
3. `.env`ファイルに`COMPOSE_PROJECT_NAME=プロジェクト名`を記述
4. トップレベルの`name`プロパティ
拡散モデル本3章の個人的理解用メモ

参考：[岡野原大輔, 拡散モデルデータ生成技術の数理](https://www.iwanami.co.jp/book/b619864.html)
# 確率微分方程式
**微分方程式**
普通の方程式は$x^2-4x+4=0$のような形になっており、$x=2$のような数値が答えとなる。
一方、微分方程式は$\frac{dx(t)}{dt}=f(t, x(t)), x(0)=x_t$のように、ある時刻tで決まる値xの微分が、tとx(t)の関数であらわされる形になっている。このような関係を満足する関数が答えとなる。

- [微分方程式](https://ja.wikipedia.org/wiki/%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B%E5%BC%8F)
- [うさぎでもわかる微分方程式　Part00　微分方程式ってなに？](https://www.momoyama-usagi.com/entry/math-ode00#i)

**確率過程**
時間などで変化する確率変数の系列。株価の上下など。

- [確率過程](https://ja.wikipedia.org/wiki/%E7%A2%BA%E7%8E%87%E9%81%8E%E7%A8%8B#:~:text=%E7%A2%BA%E7%8E%87%E8%AB%96%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E3%80%81%E7%A2%BA%E7%8E%87%E9%81%8E%E7%A8%8B,%E3%81%A8%E3%81%97%E3%81%A6%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82)

**確率微分方程式**
微分方程式の一つ以上の項が確率過程になっており、解$f(x)$自身も確率過程になるもの。

- [確率微分方程式](https://ja.wikipedia.org/wiki/%E7%A2%BA%E7%8E%87%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B%E5%BC%8F)

**ブラウン運動、標準ウィーナー過程**
時刻t=0で値が0の後、正規分布から得られる乱数を足していった確率過程。乱数を足していくので、色々な値をとっていく。

- [Pythonを用いた確率過程のプログラミング 〜ブラウン運動、ポアソン過程 etc〜](https://www.hello-statisticians.com/python/stat_program1.html)

**確率微分方程式(3.1)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138090/fdb9701b-ff11-90d7-c718-46116b076e85.png)

**確率微分方程式(3.2)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138090/9920d435-8572-9463-c802-544485b42ce2.png)

# SDE表現
**一次近似その1**
```math
\sigma(t)^2=u(t)
```
とする。テイラー展開すると、
```math
\displaylines{
u(t+\Delta t) =u(t)+\frac{du}{dt}(t)\Delta t+\frac{1}{2}\frac{d^2u}{dt^2}(t)\Delta t^2+...
}
```
$\Delta t<<1$より二次以降を無視すると、
```math
\displaylines{
u(t+\Delta t) =u(t)+\frac{du}{dt}(t)\Delta t  \\
u(t+\Delta t) - u(t)=\frac{du}{dt}(t)\Delta t \\
\sigma(t)^2=u(t)より　\\
\sigma(t+\Delta t)^2 - \sigma(t)^2=\frac{d[\sigma(t)^2]}{dt}\Delta t
}
```
**一次近似その2**
マクローリン展開すると、
```math
(1+x)^n=1+nx+\frac{n(n-1)}{2!}x^2+...
```
$n=1/2$で、$x=\beta(t+\Delta t)\Delta t$であり、$\Delta t<<1$より$x^2\simeq0$、よって
```math
\sqrt{1-\beta(t+\Delta t)\Delta t}
\\
=1-\frac{1}{2}\beta(t+\Delta t)\Delta t
```
**DDPMのSDE**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138090/3179bb12-cf0a-c3fe-870d-2f40a8da067a.png)
# DDPMの逆拡散過程
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138090/9ff24069-1c64-23f1-de2d-c13c0a4106e7.png)
# サンプリング
```math
x:=x-[f(t_i)x-g(t_i)^2s_\theta(x, t_i)]\Delta t_i+g(t_i)\sqrt{|\Delta t_i|}z_i
\\
=x-f(t_i)x\Delta t_i+g(t_i)^2s_\theta(x, t_i)\Delta t_i+g(t_i)\sqrt{|\Delta t_i|}z_i
```
$s_\theta(x, t_i)\approx \nabla _x logp_t (x)$なので、やはりサンプリング時はスコアをが増える方向でやっているので、上記の逆拡散過程は0→T?

# 確率フローODE
**ニューラルODE**
ResNetは入力に対する変化を学習していく（$H(X)=F(X)+X$）。これを何層にも積み重ねる。ここで、各層を時刻1, 2, 3...のデータへの変化量ととらえると、時間を離散的でなく、連続的にとらえたらどうなるのか？という発想になる。連続時間をtにすると、$z_t=f(\theta, z_{t-1})+z_{t-1}$となる。これは$\frac{dz(t)}{zt}=f(\theta, z(t), t)$となり、イコール微分方程式(ODE)となる。ニューラルネットでODEをといているので、ニューラルODE。
Idracのファームウェアアップデートの方法

## 手順
### ファームウェアダウンロード
弊社DELL EMCサポートページにアクセスします。
https://www.dell.com/support/home/jp/ja/jpbsd1
1. サービスタグを入力
2. キーワードにidracを入力

### ダウンロードしたexeを実行
「payload\ firmimgFIT.d9」
上記のファイルが発見出来たら、idracにアクセスする

### idracへログイン
1. メンテナンスタブから、システムの更新プログラムを選択
1. ファイルを選択
1. firmimgFIT.d9をアップロード
1. アップデート前後のiDRACバージョンを確認し「インストール」ボタンを押下します。
1. ポップアップ画面が表示されます。「ジョブキュー」ボタンを押下します。

大分時間がかかる



##### 参考文献
https://www.dell.com/support/kbdoc/ja-jp/000134013/idrac-%E3%82%92-%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6-%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0-%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88-%E3%81%AE-%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2-%E3%82%92-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88-%E3%81%A7-%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B-dell-poweredge
【備忘録】luxonとタイムゾーン

# はじめに

日時の表現はややこしい。特に手元の開発環境(PC)と実行環境(クラウドやコンテナ)でタイムゾーンが異なっていると厄介だ。
業務使っているTypeScript・luxonでどう書いたら何が返ってくるのかを備忘録としてまとめた。

### 実行環境

- Node 18.13.0
- TypeScript 5.0.4
- luxon 3.3.0

# 実行内容
## 前提：タイムゾーンの設定

Nodeのタイムゾーンは環境変数`TZ`で設定できる。未設定の場合はホストマシンのタイムゾーンが使われている模様。

https://codenote.net/nodejs/5400.html

今回はpackage.jsonのスクリプトに直接記述する方法をとり、2つのコマンドの使い分けでタイムゾーンを変更できるようにした。

```json:package.json
{
  "scripts": {
    "dev-jst": "TZ=Asia/Tokyo ts-node src/main.ts",
    "dev-utc": "TZ=UTC ts-node src/main.ts"
  }
}
```

```ts:src/main.ts
console.log(process.env.TZ);
```

```zsh:実行結果
% pnpm run dev-jst
Asia/Tokyo
% pnpm run dev-utc
UTC
```

## タイムゾーン情報なし

luxonにタイムゾーンの情報を与えていない場合、Nodeのタイムゾーンで出力される。
入力文字列にタイムゾーン情報が含まれている場合、入力文字列の時刻をNodeのタイムゾーンで表現したものが出力(※)される。
※`toString`で出力される文字列

```ts:TZ=Asia/Tokyoの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
const dtObj = DateTime.fromObject({ year: 2023, month: 4, day: 1, hour: 12 });
// -> 2023-04-01T12:00:00.000+09:00 (fromISO, fromObjectとも)
const dtWrittenInJst = DateTime.fromISO("2023-04-01T12:00:00+09:00");
// -> 2023-04-01T12:00:00.000+09:00
const dtWrittenInUtc = DateTime.fromISO("2023-04-01T12:00:00Z");
// -> 2023-04-01T21:00:00.000+09:00 ※UTCの１２時はJSTの21時
```

```ts:TZ=UTCの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
const dtObj = DateTime.fromObject({ year: 2023, month: 4, day: 1, hour: 12 });
// -> 2023-04-01T12:00:00.000+00:00 (fromISO, fromObjectとも)
const dtWrittenInJst = DateTime.fromISO("2023-04-01T12:00:00+09:00");
// -> 2023-04-01T03:00:00.000+00:00 ※JSTの12時はUTCの3時
const dtWrittenInUtc = DateTime.fromISO("2023-04-01T12:00:00Z");
// -> 2023-04-01T12:00:00.000+00:00
```

## 後からタイムゾーンのみ変更

インスタンス作成後に`setZone`でタイムゾーンを設定すると同じ絶対時刻で出力時のタイムゾーンのみを変えることができる。なお、setterのようなメソッド名だが実際には新しいインスタンスを返却する非破壊的なメソッドである。

```ts: TZ=Asia/Tokyoの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
// -> 2023-04-01T12:00:00.000+09:00
const dtIsoToUtc = dtIso.setZone("utc");
// -> 2023-04-01T03:00:00.000Z ※JSTの12時はUTCの3時
```

```ts: TZ=UTCの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
// -> 2023-04-01T12:00:00.000+00:00
const dtIsoToJst = dtIso.setZone("Asia/Tokyo");
// -> 2023-04-01T21:00:00.000+09:00 ※UTCの１２時はJSTの21時
```

## インスタンス生成時にタイムゾーンを指定

インスタンス生成時のオプションとして`zone`を指定すると、**入力した日時の解釈と出力する文字列の両方に**そのタイムゾーンが適用される。

```ts:TZに関わらず同じ結果
const dtJst = DateTime.fromISO("2023-04-01T12:00:00", { zone: "Asia/Tokyo" });
// -> 2023-04-01T12:00:00.000+09:00
const dtUtc = DateTime.fromISO("2023-04-01T12:00:00", { zone: "utc" });
// -> 2023-04-01T12:00:00.000Z
```
LinuxまたはUNIXのマニュアルページセクション（例：crypt(3) ）

LinuxやUNIXのマニュアルやヘルプを参照すると、`crypt(3)`のような表記を見かけることがあるかと思います。
ここで`(3)`は**セクション番号**です。セクション番号は、そのドキュメントのカテゴリを示します。
`(3)`はライブラリ関数（C言語のライブラリ関数）のカテゴリとなります。

具体的には、次のようなセクション番号が一般的に使用されます。

|セクション番号|内容|
|:---:|:---|
|(1)|だれもが実行できるユーザーコマンド|
|(2)|システムコール（カーネルが提供する関数）|
|(3)|ライブラリ関数（C言語のライブラリ関数）|
|(4)|デバイス（/devディレクトリのスペシャルファイル）|
|(5)|ファイルフォーマットの説明（例：/etc/passwdなど）|
|(6)|ゲーム（Unix/Linux上で実行できるゲーム）|
|(7)|その他のマニュアルページ：マクロパッケージやプロトコル、コンセプトに関連する情報|
|(8)|管理コマンド（管理者や特権ユーザーが使用するコマンド）|
|(9)|Linux独自のカーネルルーチン用ドキュメンテーション|
|(n)|新しいドキュメンテーション（将来的には、適した場所に移動される）|
|(o)|古いドキュメンテーション（猶予期間として保存されている）|
|(l)|独自のシステムについてのローカルなドキュメンテーション|

---

以上
EC-CUBE4で外部メールアドレスを使う

# about

EC-CUBE4系でドメイン外のメールアドレスを利用する方法

# 詳細

EC-CUBE4系を利用している店舗からの相談でした。
ショップオーナーが`ECのドメイン外のメールアドレス(OCN)`を連絡用メールアドレスに設定してしまい、注文確認メールが届かない事象が発生していました。

また、プロバイダのメールアドレスを昔から利用しており、独自ドメインのメールアドレスとの2重管理が面倒なので、独自ドメインのメールは廃止したいとのこと^q^;ﾅﾝﾀﾞｯﾃｰ

EC-CUBEと同じサーバでSMTPサーバが動いている間は、@localhostで認証レスなのですが、外部のメールアドレスを利用するには、外部のSMTPサーバと認証する必要があるのが原因でした。


# 忙しい人向け

以下のフォーマットで認証情報を記述すればOKです

```./.env
MAILER_URL=smtp://{smtp}:{port}?encryption=ssl&auth_mode=login&username={mail}&password={passwd}
```


# refs

調べて見かけたのは以下の記事でしたが、
user:passwd@host:portの記述ではうまくいきませんでした。

https://yoo-s.com/topic/detail/885

http://unithink.jp/2019/08/07/eccube4%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%8C%E5%B1%8A%E3%81%8B%E3%81%AA%E3%81%84/


# 具体的には

一般的な回答の範囲で記載

今回 (OCNメール) の場合
26行目辺りのMAILER_URLから始まる行をauth_mode=loginに変更
認証情報を以下のフォーマットで入力

```./.env
MAILER_URL=smtp://smtp.ocn.ne.jp:465?encryption=ssl&auth_mode=login&username=****@****.ocn.ne.jp&password=****
```


# その他
2024.01月現在まだEC-CUBE5はリリースされていないようです

https://www.ec-cube.net/press/

EC-CUBEは、カスタマイズ費用はもちろん、メンテコストもそれなりに掛かるシステムです。
BASEやshopifyといったクラウドサービスを利用するのが、トータルではうまくいくと思います。
GoogleDriveからwgetによってファイルダウンロード

サーバー上での作業などで，とりあえずcurlとかwgetでGoogle Drive上の一般公開されているデータをダウンロードしたいといったときの対処方法です．

## 小さいファイルの場合
ファイルを右クリック > 共有可能なリンクを取得 > FILE_ID("id="以降の文字列)を取得
```
wget "https://drive.google.com/uc?export=download&id=<FILE_ID>" -O <FILE_NAME>
```


## 大きいファイルの場合
以下のシェルスクリプトを実行
```
curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=<FILE_ID>" > /dev/null
CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"  
curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=<FILE_ID>" -o <FILE_NAME>

```

###### 参考文献
https://qiita.com/namakemono/items/c963e75e0af3f7eed732
Micrisoft Excelの便利なショートカットキーのメモ

Microsoft Excelの便利なショートカットキーのメモです。
便利だと思ったら、追記していきたいと思います。

# ショートカットキー一覧
|目的|ショートカットキー|備考|
|:---|:---| :---| 
|行選択|Shift + Space|IMEがオフ（半角英字）になっている必要がある|
|列選択|Ctrl + Space|-|
|行挿入<br>列挿入|Ctrl + Shift + 「+」|行選択状態で実施すると行挿入<br>列選択状態で実施すると列挿入|
|行削除<br>列削除|Ctrl + 「-」|行選択状態で実施すると行削除<br>列選択状態で実施すると列削除|

---

以上
Heroku CLIでメモリ量を抑えたい

# 前提
アプリケーションを開発済み ※今回はフロントエンドをReact+TypeScript，バックエンドをNode.jsで実装
Herokuのアカウントを作成し，ログイン済み
ビルドファイルを作成済み `yarn build`

# 問題点
特にmaterial-uiなどのパッケージをheroku側でbuildしたとき，メモリの容量を大幅に超えてしまった．

## 補足 
dynoのBasicを使用しているため最大メモリ量は512MB．しかし以下の図の左側のように大幅に超えてしまいました．そこで，先にbuildを行ってからHerokuにpushすることで右側のようにメモリ量を抑えることができました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/7a56349e-9c1b-ac5b-02b3-07142ebdb472.png)


# 手順
まず，サーバを立てるためのコマンド実行．npmを使用している方は変更してください．
```
yarn add serve

serve -s build // serveが正常に動作するか，ローカルで確認したいときはこのコマンド
```
※serveインストール時，globalを追加してしまうとうまく動作しなかった

さらに，package.jsonの`scripts`を以下に変更
```typescript
...
  "scripts": {
    "start": "serve -s build"
  },
...
```

ここまで出来たらHeroku CLIにpushしていく
```
git add .
git commit -m "first commit"
git push heroku master
```

logに以下が表示されたら成功
```
remote: -----> Compressing...
remote:        Done: 〇〇M
remote: -----> Launching...
remote:        Released v24
remote:        https://アプリ名 deployed to Heroku
remote:
remote: Verifying deploy... done.
```

***デプロイの停止/再開コマンド***
```
heroku ps:scale web=0 // 停止
heroku ps:scale web=1 // 再開
```




# ぶち当たったエラー例
## その１
### 問題
package-lock.jsonとyarn.lockが混在している．

```
-----> Build failed
 !     Two different lockfiles found: package-lock.json and yarn.lock
       Both npm and yarn have created lockfiles for this application,
       but only one can be used to install dependencies. Installing
       dependencies using the wrong package manager can result in missing
       packages or subtle bugs in production.
```

### 解決策
今回は`yarn`を使うためpackage-lock.jsonを消した．


## その２
### 問題
以下のようにリモートリポジトリを指定していない 
```
fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

### 解決策
herokuをリモートリポジトリに追加
```
heroku git:remote -a アプリ名
```

## その３
### 問題
buildディレクトリがpushできない
### 解決策
.gitignoreファイルから`/build`を削除
【5週目】Python【スパルタコーディングクラブ】

・AWSの加入
→クラウド環境の仮想サーバーを提供している

・バケットリストの作成（bucket）

・ファンページの制作
→プロジェクトファイルを作成⇨仮想環境の生成⇨パッケージの設置⇨app.pyにコーディング⇨index.htmlにコーディング⇨MongoDBへアクセス⇨OpenAPIを活用してパーツ機能を実現⇨POST方式でAPIを作る⇨GET方式でAPIを作る⇨プロジェクトをサーバーに載せアクセスできるようにする
indexOf()メソッドの使い方と小技

indexOf()メソッドは、配列中から、指定した値を持つ要素を探し、最初に見つけたインデックスを返します。見つからなかった場合は1-を返します。検索は配列の先頭から末尾方向に処理します。lastIndexOf()メソッドというのもあり、これは逆に末尾から先頭方向に検索します。
```js
let a = [0, 1, 2, 1, 0];
a.indexOf(1);     // 1
a.lastindexOf(1); // 3
a.indexOf(3);     // -1
```
##### 小技
次の関数は、配列bから指定した値xを持つすべての要素を検索し、インデックスを配列形式で返します。第２引数をうまく使って、最初に見つかった要素の先も検索できます。
```js
function findall(b, x) {
  let resulets = [],
    len = b.length,
    pos = 0;
  while (pos < len) {
    pos = b.indexOf(x, pos);
    if (pos === -1) break;
    resulets.push(pos);
    pos = pos + 1;
  }
  return resulets;
}
```

#### 学習本
https://www.amazon.co.jp/JavaScript-%E7%AC%AC7%E7%89%88-David-Flanagan/dp/4873119707
CoreDNSを構築する

## ファイル構造
- docker-compose.yml
- Dockerfile
- volumes
  - config
    -  Corefile
    -  hosts

## docker-compose.yml
```=yml
version: '3.1'
services:
  coredns:
    build: .
    container_name: coredns
    restart: always
    expose:
      - '53'
      - '53/udp'
    ports:
      - '53:53'
      - '53:53/udp'
    volumes:
      - './volumes/config:/etc/coredns'
```

## Dockerfile
```=yml
FROM coredns/coredns:1.7.0

EXPOSE 53
EXPOSE 53/udp

ADD volumes/config/ /etc/coredns/

ENTRYPOINT ["/coredns"]
CMD ["-conf", "/etc/coredns/Corefile"]
```

## Corefile
```=yml
. {
    whoami
    forward . 172.24.2.51:53
    errors
    log . "{proto} {remote} is Request: {name} {type} {>id}"
    hosts /etc/coredns/hosts {
        fallthrough
    }
    reload
}
```

## hosts
```=yml
172.24.20.25 kakocloud.tmcit.sho
```
[Bardに聞く]WEBスクレイピングで子ページにある情報を検索

前稿「[[Bardに聞く]VS CodeではじめてのWEBスクレイピング](https://qiita.com/ginger_ale/items/e0f964f8f2b086d44020)」で簡単なWEBスクレイピングを実行しました。

当たり前ですが私が欲しかった情報は「WEBスクレイピングの実行方法」ではありません。
WEBスクレイピングは大量アクセスを行うとサーバー負荷がかかるため迷惑行為になりますが、
少量であればHTMLを読む人間にとっては、
**自分の作業を減らすことができる**自動化ツールです。

# 目的
企業の中途採用情報ページで、子ページにある情報を検索し、該当ページを一覧取得する

と、いいますのは、類似する職種の募集が同一企業内で複数部門にあるとき
企業内の組織情報でページが分かれていることが多く、
社内をよく知らない応募者からは、見付けるのが大変です。
（転職情報サイトは検索機能が便利ですが、企業公式ページを参照する場合とします。）

そこでWEBスクレイピングです。
外部の人間がDBにアクセスしてSQLで抽出できるはずもありませんが、
本当は情報はDBに入っていて固定レイアウトに表示しているなど、
大抵は子ページの構成が同じであるため、一覧取得は簡単です。

・よくある中途採用ページ構成
![02_draw_io_target_structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972909/ecf13097-de1f-bb18-12b3-8da4366587e9.png)

このような構成になっているページ内で、
募集タイトルにエンジニアを含み、就業場所に大阪が含まれる募集の一覧取得を行います。
（企業様によっては都道府県だけはタイトルに書かれていたり、絞込み可能になっていたりしますが、それが無い場合とします。）

# 対応
Bardに聞いてみる。
https://bard.google.com/
~~~
以下の処理をPythonで記載してください。

１）親ページ内で各募集のタイトルとリンクを取得
２）募集タイトルに「エンジニア」が含まれなければ次の募集へ
３）子ページのURLを取得
４）子ページへアクセス
５）就業場所の文字列に大阪が含まれなければ次の募集へ
６）出力用配列に情報追加

この内容でループし、最後に出力用配列を出力します。
~~~
なんと！前稿の続きであることを理解したようなソースが出てきます。
ループする範囲も合っています！
「募集」と「子ページ」に曖昧さがありますが、解決した上に名前がjob！Bardさん賢い！
URLやclass名など、必要箇所を修正します。
出力はコンソールで見るため、改行するpprint.pprintに変更します。

ソース
~~~
import requests
from bs4 import BeautifulSoup
import pprint

# 親ページの URL を指定
url = 'https://***/jobs'

# 親ページを取得
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')

# 募集のタイトルとリンクを取得
jobs_all = soup.find_all('li', class_='jsc-joblist-cassette')

# 募集タイトルに「エンジニア」が含まれる募集のみを抽出
jobs_selected = [job for job in jobs_all if 'エンジニア' in job.find('h2').text]

# 出力用配列を初期化
output = []

# 各募集についてループ
for job in jobs_selected:
    # 子ページの URL を取得
    url = job.find('a').get('href')

    # 子ページにアクセス
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')

    # 就業場所の文字列を取得
    location = soup.find('section', class_='pg-descriptions').find('li').text

    # 就業場所の文字列に「大阪」が含まれる募集のみを出力用配列に追加
    if '大阪' in location:
        output.append({
            'title': job.find('h2').text,
            'link': url,
            'location': location
        })

# 出力用配列を出力
pprint.pprint(output)
~~~
実行結果
![02_output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972909/bcf76f51-4779-a517-efbd-5f7fe62d0e4e.png)

大阪のエンジニア募集の一覧が出力されました！正にイメージ通りの出力です。
私の環境での実行時間は15秒でした。
簡単ですが、様々なページで使えそうです。

ところで、Beautiful Soup4で構築したため、親ページ内募集一覧の形式によっては使えない場合があります。
こちらはまた機会があれば投稿させていただきたいと思います。

# 最後に
繰り返しますが、WEBスクレイピングは大量アクセスを行うとサーバー負荷がかかるため**迷惑行為**になります。
禁止されているサイトもございます。ご注意ください。
Goプログラミング実践入門を読んで[随時更新]


## Db.Where("author = &1", "俺やろ").First(&readPost)でエラー

### エラー内容
```go
[2023-06-01 22:46:17]  pq: operator does not exist: & integer 
panic: runtime error: index out of range [0] with length 0
```

### 問題のコード
実行環境は、PostgreSQL14
プレースホルダーの問題の様でGoでは$1ではなく?で基本的にコーディングすればよい
```go
// 動かない
Db.Where("author = $1", "俺なのか").First(&readPost)

// 動く
Db.Where("author = ?", "俺なのか").First(&readPost)

```




## 対応リポジトリ
https://github.com/lemon-solt/learn-golang-book
FSのAPの設定方法

FSのAPの設定方法に手こずったのでメモ

## 手順
1. fsAP　- スイッチ(PoE) - PC
    のネットワーク接続 
2. PCに192.168.1.2のIPを設定
3. http://192.168.1.1/　にアクセス
4. リダイレクト先設定
    1. チェックをいれる
    2. リダイレクト先のIPを入力(192.168.100.1)
6. 初期設定
    1. SSIDとPasswordの設定
    2. DHCPの設定(DHCPサーバを指定)
7. 設定の適用後WIFiに接続できる
8. 接続して動作確認(対外へ)
9. fsAP ルータをスイッチで接続

## 困ったところ
- ルータ、APの順で設定したらDHCPが降ってこない
    初期IPが固定されているので降らない
    初めにAPの設定をしてDHCPサーバを指定すること
    
- 謎のページ、以下の設定しか出てこない
![](https://hackmd.io/_uploads/HyWC3dVrn.png)
    リセットして上記手順の初期からやったほうがいい
WindowsでKMS認証の通し方

ライセンスサーバーから、認証を通す場合はwindowsのisoは公式が公開しているものではなく、所属組織が配布しているisoを使用しなければならない
#### WindowsのKMS認証の方法
1. 管理者権限でコマンドプロンプトを開く
2. 下記のコマンドを実行
slmgr.vbs /skms 任意のサーバー:1688
slmgr.vbs /ato
Systemdによるディレクトリ監視

## 手順

### ファイル作成
.pathと.serviceの前の文字列をそろえる。
```
cd /etc/systemd/system/
test.path
test.service
```
### service編集
```
nano /etc/systemd/system/test.service
```
下記を追加
```
[Unit]
Description=DesktopSample

[Service]
WorkingDirectory=/home/takuya/Desktop
ExecStart=/bin/echo Hello From Service 

[Install]
WantedBy=default.target
~/.config/systemd/user/desktop.path
```

```
nano /etc/systemd/system/test.path
```
下記を追加
```
[Unit]
Description=DesktopSample

[Path]
## PathModified と PathChanged は別物
## 再帰的( recursively ) にパスの監視はできない。
## inotify をベースにしている
PathChanged=/home/takuya/Desktop
#PathModified=/home/takuya/Desktop
[Install]
WantedBy=default.target
```

### ロードする
```
systemctl daemon-reload

systemctl enable desktop.service
systemctl enable desktop.path

systemctl restart desktop.service
systemctl restart desktop.path
```

###### 参考サイト
https://takuya-1st.hatenablog.jp/entry/2019/10/27/171941