OmniAICreator/Qiita-1.07M huggingface dataset:
[C#][備忘録]Task.Start、Task.Run、TaskFactory.StartNewの違い

# はじめに

処理を別スレッドで行う際によく使用するTaskクラスがあります。
普段業務でTaskを実行するメソッドとしてTask.Run()をよく目にしますが、たまたま最近Task.Start()を利用している箇所を見つけました。
Taskを実行するメソッドで、Run()メソッド以外(たぶん)使ったことが無く、知らなかったためどんな違いがあるのかまとめました。

# Task.Run、TaskFactory.StartNew、Task.Startについて

- [Task.Run()](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run?view=net-7.0)

まず、Task.Run()についてです。
タスクのインスタンス化と実行をまとめてできるメソッドです。
マイクロソフトの文書中に、以下の記載がありましたので、TaskFactory.StartNew()についても調べました。
> Runメソッドは、既定値を使用してタスクを簡単に開始できるようにする一連のオーバーロードを提供します。これは、StartNewオーバーロードの軽量な代替手段です。

- [TaskFactory.StartNew()](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskfactory.startnew?view=net-7.0)

こちらもタスクのインスタンス化と実行をまとめて記述できる書き方です。
[こちら](https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/)の記事によると、Task.RunとTaskFactory.StartNewの大きな違いは、メソッドの引数の複雑さのようです。
Task.RunはTaskFactory.StartNewと同じロジックで実装されていますが、StartNewメソッドで必要な引数を指定しなくても、デフォルトの設定でタスクを実行できるようになっているようでした。

また、記事に以下の記載がありましたので、単純なユースケースの場合はTask.Runを、高度にタスクスケジューラを制御し、パフォーマンスを調整したい場合は、TaskFactory.StartNewを利用するという使い分けのようでした。
> In this way, Task.Run can and should be used for the most common cases of simply offloading some work to be processed on the ThreadPool (what TaskScheduler.Default targets).  That doesn’t mean Task.Factory.StartNew will never again be used; far from it.  Task.Factory.StartNew still has many important (albeit more advanced) uses.  You get to control TaskCreationOptions for how the task behaves.  You get to control the scheduler for where the task should be queued to and run.  You get to use overloads that accept object state, which for performance-sensitive code paths can be used to avoid closures and the corresponding allocations.  For the simple cases, though, Task.Run is your friend.
（このように、Task.Run は、ThreadPool 上で処理される作業を単純にオフロードする最も一般的なケース（TaskScheduler.Default が対象）に使用できますし、使用する必要があります。 だからといって、Task.Factory.StartNew が二度と使われなくなるわけではありません。 Task.Factory.StartNew には、（より高度ではありますが）まだ多くの重要な用途があります。 タスクがどのように動作するかについて、TaskCreationOptions を制御することができます。 タスクがどこにキューイングされ、実行されるべきかについて、スケジューラを制御することができます。 オブジェクトの状態を受け取るオーバーロードを使うことができます。これは、パフォーマンスに敏感なコードパスのために、クロージャとそれに対応するアロケーションを避けるために使うことができます。 しかし、単純なケースでは、Task.Runはあなたの友人です。）

・[Task.Start()](https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.task.start?view=net-7.0)

Taskインスタンスをコンストラクタで作成した場合に、そのタスクを実行するためのメソッドです。
上記二つはTaskの作成と実行をまとめているのに対し、こちらは分けたいときに使用するメソッドです。
マイクロソフトの文書に以下の記載がありましたので、Taskの作成と実行を分けたい特別な理由が無いのであれば、Task.RunやTaskFactory.StartNewを使用するのが良さそうです。
>For the more common case in which you don't need to separate task instantiation from execution, we recommend that you call an overload of the Task.Run or TaskFactory.StartNew method.
(タスクのインスタンス化と実行を分離する必要がない一般的なケースでは、Task.RunまたはTaskFactory.StartNewメソッドのオーバーロードを呼び出すことをお勧めします。)

# さいごに

TaskFactory.StartNewというメソッドがあることは知りませんでした。
また、基本的にはこれからもTask.Runメソッドを使用すれば大体のケースで大丈夫そうだということがわかってよかったです。
勉強になりました。
KiCadの3Dビューアを古いIntel HD GraphicsのWindows上で動かす小技


Windows版のKiCadのPCBエディタから3Dビューアを起動しようとするとき、
https://www.kicad.org/discover/3dviewer/
```console
サポートされていないOpenGLのバージョンです。最低限必要なバージョンは1.5です。
```
```console
You OpenGL version is not supported. Minimum required is 1.5.
```
のメッセージが出て、動作しない場合があります。これはIntelが古いCPUなどのデバイスドライバのOpenGL対応を放棄しているのが原因です。OpenGLの別の実装であるMesa3Dを使うと、OpenGLの版数を新しいものにすることができます。

ガーバー ビューアではつぎの警告が発せられる事があります。
```console
Information
Could not use OpenGL, falling bck to software rendering
OpenGL 2.1 r higher is required!
```


https://fdossena.com/?p=mesa/index.frag
から
MesaForWindows-x64-20.1.8.7z をダウンロードしてきて、中にある
```file
opengl32.dll
```
をKiCadのbinフォルダにコピーして、KiCadを再起動すれば動かすことができます。

なお、設定でシンボル エディタ、回路図エディタ、フットプリントエディタ、PCBエディタ、ガバナ ビューアー、図形シート エディタなどの３Ｄビューア以外の表示オプションのレタリングエンジンはすべて代替グラフィクスに設定変更しておかないとすべてのレタリングを上記が計算するので作画が非常に遅くなる。

参考にした情報
https://forum.kicad.info/t/kicad-5-1-9-1-working-with-virtualbox-vm-windows-7/28444

https://forum.freecadweb.org/viewtopic.php?f=4&t=36087&sid=6bbd799816d193147d046dae8d35244f&start=20
enumとThymeleafを使用した画面表示

## 背景
enum（定数）のフィールドを持ったドメインの要素を画面に表示したいため実装しました。
本記事に記載した方法は保守性などの観点からよくないという意見もあるため、仕様や実現したいことから実装方法を選定してください。
参考サイトは最後にまとめております。

## 環境
macOS Monterey / バージョン12.0.1
Spring Boot 2.7.7
IDE Eclipse
openJDK11
Maven3.8.6
Thymeleaf3

## 実現したいこと

enumクラスにて設定した定数をhtml、Thymeleafを利用して画面で表示する

Itemドメインにcolorというフィールドがあり、それを定数クラス群に設定する

~~~Item.java
public class Item {
	/** ID */
	private Integer id;
	/** 商品名 */
	private String name;
    /** 商品カラー */
	private Integer color;  //これを定数とする.
}
~~~

~~~Color.java
public enum Color {
    RED("red", 1),                  //定数名（key,value),フィールドはいくつでも設定可能
    BLUE("blue", 2),
    GREEN("green", 3);

    private final String key;
    private final int value;

    //コンストラクタの設定（アクセス修飾子はprivate）
	private Condition(final String key, final int value) {
		this.key = key;
		this.value = value;
	}

     /**
	 * カラーのIDから一致するインスタンスを返すメソッド.
	 * 
	 * @param id カラーID
	 * @return 一致するインスタンス
	 */
	public static Color of(int value) {
		for (Color color : Color.values()) {     
			if (color.getValue() == value) {
				return color;
			}
		}
		throw new IndexOutOfBoundsException("The value of color doesn't exist.");
	}

	public int getValue() {
		return value;
	}

	public String getKey() {
		return key;
}
~~~

~~~enum.html
//画面表示
//クラス名はColor
//itemはControllerクラスなどでmodelに格納されているとする

<span th:text="${T(パッケージ名.クラス名).of(item.color).getKey()}"></span>

//セレクトボックスの作成
<select name="color">
	<option th:each="color : ${T(パッケージ名.クラス名).values()}"
            th:value="${color.getValue()}"
            th:text="${color.getKey()}" >
    </option>
</select>
~~~

## 参考

https://qiita.com/n_slender/items/d0e2a861dcc806b5882e

https://springhow.com/enums-in-thymeleaf/

https://www.baeldung.com/thymeleaf-enums

https://stackoverflow.com/questions/68686397/how-to-use-variables-from-a-constants-class-in-thymeleaf-numbers-sequence-meth

https://stackoverflow.com/questions/24937441/comparing-the-enum-constants-in-thymeleaf
RailsでCapybaraのSystemテストが不規則に落ちる問題の解決策

## 概要

### 背景
- railsでアプリを作っているときにシステムテストを頻繁にするけど、不規則でテストが落ちたり落ちなかったりする

###### エラー内容
- `$ rails test xxxxx_test.rb`で単一ファイルでテストするとGreenになるので`checkbox "公開設定"`は存在するし、しっかりクリックもできます。
- `$ rails test:system`で全部のテストファイルを一括テストするときによく（不規則に）Redになります。
   - たまに調子の良い時は全てGreenになったりもします。
- テストを実行するたびにエラーの数もバラバラな状態です。
- テストが他のテストに依存するような処理は書いていません。
```
Minitest::UnexpectedError:
Capybara::ElementNotFound:
Unable to find checkbox "公開設定" that is not disabled
```


### 原因
- Capybaraの操作速度がChrome（ブラウザ）の操作速度を上回ってしまってる。
  - ex. 画面遷移した後にチェックボックスをチェックしようとしたけど、表示が遅すぎてチェックできずにエラー（チェックボックスは存在するのに涙）


## 解決策
- 画面操作を正確に行うために、Timeoutを設定してあげる
   1. デフォルトのtimeoutを10秒に設定してあげる
   1. よく落ちる処理（落ちた処理）にtimeoutを設定してあげて、成功するまで同じ処理をループしてあげる

###### test/test_helper.rb
```diff
class ActiveSupport::TestCase
  parallelize(workers: :number_of_processors)
  fixtures :all
+  Capybara.default_max_wait_time = 10
end
```
```ruby
test 'タイムアウト処理' do
  Timeout.timeout(Capybara.default_max_wait_time) do
    loop until (target = find('a.footer-link', text: text = '新規カテゴリ作成')).visible?
    target.click
  end
end
```

## トレードオフ
- この方法で10回ほどテストしても全部Greenだったので今後これでやっていこうと思いますが。
- 普通にRedのテストでも10秒処理しちゃうところが残念なところですね。
- そんなデメリットを差し置いても、気まぐれに正しいテストがRedになるよりはマシかなと思います。
- もし他の良いアイディアがある方がいらしたら、ぜひ教えていただければと思います><

## 参考記事
- [こちらの記事](https://koheisg.dreamin.cc/system_spec/random-failures)を参考にさせていただきました！大変わかりやすい記事でした^^
python maya pymel 開始フレーム終了フレームを取得して、カメラにアトリビュート追加

```python
first_frame = int(pm.Env().getMinTime())
last_frame = int(pm.Env().getMaxTime())
pm.addAttr(new_cam, longName = 'first', attributeType = 'short')
pm.addAttr(new_cam, longName = 'last', attributeType = 'short')
new_cam.first.set(int(first_frame))
new_cam.last.set(int(last_frame))
```
AWS EventBridge S3のバケットとフォルダを指定してオブジェクトの作成イベントをキャッチする

# 概要

- EventBridgeにて、S3のバケットとフォルダを指定してオブジェクトの作成イベントをキャッチする方法を簡単にまとめる。

# 情報

- 今回、オブジェクトの作成イベントをEventBridgeでキャッチする方法をまとめる。
    - 詳細な情報をまとめておく
        - バケット名：Foo
        - フォルダ名：/look
        - EventBridgeルール名：s3-upload-rule
        - EventBridgeのターゲット：下記記事で作成したSNSトピック

https://qiita.com/miriwo/items/12d42dfb71294a2b557e

# 方法

1. AWSにログインし、EventBridgeのホームまで移動する。
1. 左サイドバーで「ルール」をクリックする。
1. 遷移先ページで「ルールを作成」をクリックする。
1. 下記の様に設定して「次へ」をクリックする。

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | 名前 | s3-upload-rule |  |
    | 説明 | 未記入 |  |
    | イベントバス | default |  |
    | ルールタイプ | イベントパターンを持つルール |  |

1. 下記の様に設定して「次へ」をクリックする。

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | イベントソース | AWSイベントまたはEventBridgeパートナーイベント |  |
    | サンプルイベント | 記載しない |  |
    | 作成のメソッド | スキーマを使用する |  |
    | スキーマタイプ | スキーマレジストリからスキーマを選択する |  |
    | スキーマレジストリ | aws.events |  |
    | スキーマ | aws.s3@ObjectCreated |  |
    | モデル | bucket・keyをそれぞれ設定 | 下記画像で補足 |

    - バケット名の設定

        ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e1f6e621-3425-9f46-2648-4deae3204405.png)
    
    - フォルダ名の設定

        ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/95be7efc-a3e4-b666-3bf7-f99376b43990.png)

1. モデル登録部分下部の「JSONでイベントパターンを生成する」をクリックする。

    ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2b479ebf-eebb-0b93-2c89-4ddb238713ea.png)

1. 生成されたjsonのdetailより前の部分に下記の2行を入れる。

    ```json
    "source": ["aws.s3"],
    "detail-type": ["Object Created"],
    ````

1. 記入後jsonはおそらく下記の様になる。

    ```json
    {
      "source": ["aws.s3"],
      "detail-type": ["Object Created"],
      "detail": {
        "bucket": {
          "name": [{
            "prefix": "Foo"
          }]
        },
        "object": {
          "key": [{
            "prefix": "look"
          }]
        }
      }
    }
    ```

1. 下記の様に設定して「次へ」をクリックする。（こちらは皆さんのターゲットに合わせて適宜変更する）

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | ターゲットタイプ | AWSのサービス |  |
    | ターゲットタイプの選択 | SNSトピック |  |
    | トピック | sns-test |  |

1. タグは特に設定しない。
1. 内容を確認し「ルールの作成」をクリックする。

# 確認

- S3のFooバケットのlookフォルダにファイルをアップロードしEventBridgeがイベントをキャッチするか確認する。
Pyhtonで重回帰分析を使ってモデルを作りたい（予測したい）ときはどうしたらいいの？

# はじめに
備忘録です
青チャート見たいな感じで記事を書く試みをします！

# 問題
+ Pyhtonで回帰分析を使ってモデルを作りたい（予測したい）ときはどうしたらいいの？

# 解法・方針
scikit-learnのsklearn.linear_model.LinearRegressionを使おう！

大まかな流れ
+ 回帰分析のオブジェクトを作成する
+ データを用意する
+ データでトレーニングする
+ 実際に値を当てはまてみる

# 解答例

~~~python

from sklearn.linear_model import LinearRegression ##インポートする

lm = LinearRegression() ##オブジェクトを作成する

X = df[['hoge', '', '', ]] ## Xのデータを用意する ここに複数のデータを入れるのがカギ！
Y = df['hoge'] ## Yのデータを用意する

lm.fit(X,Y) ## トレーニングする。要するに回帰分析して、モデルを作る

Yhat=lm.predict(X) ## 実際にXを当てはめて予測してみる
Yhat[0:5] ## 予測結果をちょっと表示する はじめから5つ

lm.intercept_ ## 一応最後に、切片と
lm.coef_ ## 傾きを確認する

~~~

# 参考文献
[https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)
AWS SNS Chatbot Slackに通知を行う

# 概要

- AWSのSNSとChatbotを使って任意のSlackワークスペースのチャンネルに通知を送る方法を簡単にまとめる。

# 情報

- 筆者は下記の情報で実施する。
    - SNS
        - トピック名：sns-test
    - Chatbot
        - チャンネル設定名：notice-test
        - チャネルロール名：notice-test
    - Slack
        - パブリックチャンネル名：notice_test

# 方法

1. Slackの準備
    1. 自身がオーナー権限やそれに近い権限を持っているSlackワークスペースを用意する。
    1. 通知チャンネルの作成をする。
1. SNSの設定
    1. AWSにログインし、SNSのホームまで移動する。
    1. 左サイドバーの「トピック」をクリックする。
    1. 遷移先のページで「トピックの作成」をクリックする。
    1. 下記の様に設定して「トピックの作成」をクリックする。（記載されていない内容は特に設定しない。）

        | 項目 | 情報 | 備考 |
        | --- | --- | --- |
        | タイプ | スタンダード |  |
        | 名前 | sns-test |  |
        | 表示名 | sns-test |  |

1. Chatbotの設定
    1. AWSにログインし、chatbotのホームまで移動する。
    1. 「新しいクライアントを設定」をクリックする。
    1. 「チャットクライアントを選択」のプルダウンで「Slack」を選んで「設定」をクリックする。
    1. リダイレクト先の画面でnotice_testチャンネルが存在するSlackワークスペースを選択し「許可する」をクリックする。

        ![AWS_Chatbot_が_miriwo-notice_Slack_ワークスペースにアクセスする権限をリクエストしています___miriwo-notice_Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c5d73eb8-6a07-9a7d-be4c-f13609bcf0ad.png)

    1. 左サイドバーにSlackワークスペース名が表示されるのでクリックし、遷移先ページで「新しいチャンネルを設定」をクリックする。
    1. 下記の様に設定して「設定」をクリックする。

        | 項目 | 情報 | 備考 |
        | --- | --- | --- |
        | 設定名 | notice-test |  |
        | チャネルタイプ | パブリック |  |
        | パブリックチャンネルを選択 | notice_test | プルダウンで選択 |
        | ロール設定 | チャネルロール |  |
        | チャネルロール | テンプレートを使用してIAMロールを作成する |  |
        | ロール名 | notice-test |  |
        | ポリシーテンプレート | デフォルトの「通知のアクセス許可」 |  |
        | ポリシー名 | AmazonSNSReadOnlyAccess |  |
        | SNSトピック・リージョン | sns-testトピックのリージョンを指定 |  |
        | トピックを選択 | sns-testを選択 |  |

# 確認

1. Chatbotの画面に移動し、左サイドバーのSlackワークスペース名をクリックする。
1. 先に作成したnotice-testチャネルを一覧の中から選択する。
1. 「テストメッセージを送信」をクリックする。
1. 下記の様にSlackにテストメッセージが送られる。

    ![99_notice_aws_sns_test_-_miriwo-notice_-_Slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5b90c6ed-1018-95ea-8f82-c1bff75b3eda.png)
Pyhtonで回帰分析を使ってモデルを作りたい（予測したい）ときはどうしたらいいの？

# はじめに
備忘録です
青チャート見たいな感じで記事を書く試みをします！

# 問題
+ Pyhtonで回帰分析を使ってモデルを作りたい（予測したい）ときはどうしたらいいの？

# 解法・方針
scikit-learnのsklearn.linear_model.LinearRegressionを使おう！

大まかな流れ
+ 回帰分析のオブジェクトを作成する
+ データを用意する
+ データでトレーニングする
+ 実際に値を当てはまてみる

# 解答例

~~~python

from sklearn.linear_model import LinearRegression ##インポートする

lm = LinearRegression() ##オブジェクトを作成する

X = df[['hoge']] ## Xのデータを用意する
Y = df['hoge'] ## Yのデータを用意する

lm.fit(X,Y) ## トレーニングする。要するに回帰分析して、モデルを作る

Yhat=lm.predict(X) ## 実際にXを当てはめて予測してみる
Yhat[0:5] ## 予測結果をちょっと表示する はじめから5つ

lm.intercept_ ## 一応最後に、切片と
lm.coef_ ## 傾きを確認する

~~~

# 参考文献
[https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)
畳み込みニューラルネットワークのメモ

CNNに関してとても参考になったサイトがあった。一部ピックアップして解釈の上、メモ。できれば本家の英語サイトをみてほしい。他の情報も結構勉強になったし。英語のサイトはこれほどにも、有益なのか。これからは英語でも、頑張って読みたいなと思った。

https://cs231n.github.io/convolutional-networks/

## 一般的なCNNの構造
「畳み込み層-Relu層」のセットを繰り返して、その後にプーリング層を重ねる。なぜなら、プーリング層で情報が失われる前に、複数の畳み込み層を重ねることで、複雑な特徴を見出せるから。

## 大きなサイズの1フィルタより、小さなサイズの複数フィルタで畳み込むほうが良い
大きなサイズの1フィルタを用いた畳み込み層1つよりも、小さなフィルタを用いた畳み込み層を複数重ねる。なぜなら、キャッチできる領域が同じでも、非線形変換を含む分、特徴を見出しやすいから。パラメータ数も小さいフィルターを重ねる方が少ないから。ただし、畳み込み層の結果を保持するために、メモリ消費UPの可能性あり。

## 入力層に関する一般的な経験則
2の〇乗ピクセルが良い。たとえば、CIFAR-10は32×32、STL-10は96x96となっている。

## 畳み込み層に関する一般的な経験則
畳み込み層では、3x3フィルターでストライド1がおすすめ。パディングを利用して、次元を変更しない方がよい。

## プーリング層に関する一般的な経験則
プーリング層では2x2サイズでストライド2がおすすめ。

## 畳み込み層のストライドは、なぜ1なのか？
より小さなストライドの方が経験的にうまく機能する。ストライド1により、ダウンサイズはすべてプーリング層に任せたいから。畳み込み層は深さ方向にボリューム変換するだけ。

## 畳み込み層で、なぜパディングを使うのか？
畳み込み後のダウンサイズを防ぎたいから。実際にパフォーマンスも上がるケースが多い。パディングせずに畳み込んだ場合、橋の情報が失われるリスクもある。

## VGGNetのケーススタディ
ネットワークの深さが優れた性能のための重要な要素であることを示した。畳み込み層は3x3フィルタで、プーリングは2x2サイズで一貫している。極めて均質なアーキテクチャの事例。畳み込みネットワークでは一般的だが、メモリと計算時間のほとんどは初期の畳み込み層で使われ、パラメータのほとんどは最後の全結合層で使われている。

## なぜ畳み込みネットワークのフィルタの重みとバイアスは、なぜ同じなのか？（深度方向には異なる）
特徴量の検出能を維持できるという仮説のもと、パラメータ数を激減させれると分かったから。
Windows Server 2012 R2 FSR -> DFSR移行

# 移行手順
富士通の移行手順そのままでした。あと、公式も読んだ方がいいです。

富士通　Windows Server 2019 / 2022 Active Directory 移行の手引き
https://jp.fujitsu.com/platform/server/primergy/technical/construct/pdf/win2019-active-directory01.pdf

MS公式　FRS から DFSR への移行 (SYSVOL)
https://learn.microsoft.com/ja-jp/archive/blogs/jpntsblog/frs-dfsr-sysvol

# 確認手順
富士通のマニュアルだけだと不安でしょうがなかったので下記を実施しました。

(1)`net share`コマンドを実行
- 実行結果から、「共有名」の列に「NETLOGON」と「SYSVOL」の共有が出力されることを確認
します。
- SYSVOL 共有が SYSVOL フォルダではなく SYSVOL_DFSR に変更されている事を確認します。

(2)ADどれかのSYSVOLにファイルを配置してレプリケーションされることを確認します。

(3)`repadmin /syncall`を実行します。

(4)`repadmin /replsummary`コマンドを実行します。
実行結果から、「失敗/合計」の列で失敗の数 (「/」の左側の数) が 0 であること、「最大デルタ」
の列で最近複製されたことを確認します。

(5)`dcdiag /v | findstr "エラー error failure"`でエラーがないか確認

(6)`Dcdiag /e /test:sysvolcheck /test:advertising` sysvol周りのテストを念のため確認

(7)PCから認証確認 `nltest /dsgetdc:ドメイン名`

(8)PCからDC確認 `nltest /dclist:ドメイン名`

(9)PCからAD参加状況確認 `nltest /sc_verify:ドメイン名`

(10)PCからクライアントログイン確認 `whoami /fqdn`

(11)PCからGPO適用確認 `gpupdate /force`
【Laravel】自分で追加したファサードをFeatureテストでモックする方法

# 環境
Laravel 8

# 結論
以下のマニュアルの通り
デフォルトのファサードと何ら変わらない

https://readouble.com/laravel/8.x/ja/mocking.html#:~:text=%27process%27)%3B-,%E3%83%95%E3%82%A1%E3%82%B5%E3%83%BC%E3%83%89%E3%81%AE%E3%83%A2%E3%83%83%E3%82%AF,-%E5%BE%93%E6%9D%A5%E3%81%AE%E9%9D%99%E7%9A%84

以下は/users実行時にCacheファサードを利用する場合の例
```php:Test.php
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

class UserControllerTest extends TestCase
{
    public function testGetIndex()
    {
        $uri = "/users"
        Cache::shouldReceive('get')
                    ->once()
                    ->with('key')
                    ->andReturn('value');

        $response = $this->getJson(
            $uri,
            [
                'id' => 24,
            ],
            []
        );
        
    }
}
```
※パラメータなどは適当

/usersをリクエストすると、内部でCacheファサードのget()を実行する想定
1. shouldReceive()でCacheファサードのget()をモック
2. getJson()でAPI実行
3. /usersリクエスト時、内部で実行されるCacheファサードのgetメソッドは'value'を返す

という流れ

外部APIの実行結果をモックする場合も使える

https://maasaablog.com/development/backend/php/laravel/2805/
neosでlogix その104

# 概要
neosでlogixやってみる。
Set Local Transformノード使ってみた。

# Set Local Transform

```
Inputs
 	Impulse	Set
 	Slot	Instance
 	Float3	Position
 	FloatQ	Rotation
 	Float3	Scale
Outputs
 	Impulse	OnDone
```

# 俺コード

```
a = AxisAngle 1,0,0 45
RootSlot
|> FindChildByName "Box"
|> SetLocalTransform pulse 0,0,0 a 1,1,1

```

# 写真

![2023-01-31 00.10.00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cd66628e-6575-353f-81fa-878796dc381d.jpeg)



以上。
AWS CloudShell がデフォルトだと時刻表示(JST)がなく見づらい

# 課題
AWS Cloudshell のプロンプトがデフォルトだと時刻表示(JST)がなく見づらい
```shell-session
[cloudshell-user@ip-10-2-43-180 ~]$ ← このような表示
```
# 実装の流れ
1. .bashrc の編集

# 手順1 .bashrc の編集

■バックアップ作成
```shell-session
[cloudshell-user@ip-10-2-43-180 ~]$ ls -la .bashrc*
-rw-r--r-- 1 cloudshell-user cloudshell-user 314 Jan 31 04:21 .bashrc
[cloudshell-user@ip-10-2-43-180 ~]$ 
[cloudshell-user@ip-10-2-43-180 ~]$ cp -ip .bashrc .bashrc.`date +%Y%m%d`
[cloudshell-user@ip-10-2-43-180 ~]$ 
[cloudshell-user@ip-10-2-43-180 ~]$ ls -la .bashrc*
-rw-r--r-- 1 cloudshell-user cloudshell-user 314 Jan 31 04:21 .bashrc
-rw-r--r-- 1 cloudshell-user cloudshell-user 314 Jan 31 04:21 .bashrc.20230131
[cloudshell-user@ip-10-2-43-180 ~]$ 
```
■編集
```shell-session
[cloudshell-user@ip-10-2-43-180 ~]$ vim .bashrc
```
(編集画面に遷移)
矢印キーで末尾まで移動。
o を押します。(挿入モードになります)
以下を追記する。
```shell-session
# add
PS1='[\t \[\e[36;40m\]$LOGNAME\[\e[0m\]@\h] \W \$ '
export TZ="Asia/Tokyo"
```
:qw を入力してvimから抜ける
もし間違えてしまっていたら :q! で抜けれます。(未更新状態に戻る)

■差分の確認
```shell-session
[cloudshell-user@ip-10-2-43-180 ~]$ diff .bashrc .bashrc.20230131 
14,17d13
< 
< # add
< PS1='[\t \[\e[36;40m\]$LOGNAME\[\e[0m\]@\h] \W \$ '
< export TZ="Asia/Tokyo"
[cloudshell-user@ip-10-2-43-180 ~]$ 
```

■反映
```shell-session
[cloudshell-user@ip-10-2-43-180 ~]$ source .bashrc
[13:42:28 cloudshell-user@ip-10-2-43-180] ~ $ 
```

# 実装後
```shell-session
[13:42:28 cloudshell-user@ip-10-2-43-180] ~ $ 
```
次回からもログイン時は時刻表示されている状態のプロンプトになります。
新規タブを立ち上げたりして確認してみてください。
Jupyter上でのデバッグのための判定用フラグ

# 用途
私はPythonの独自モジュールを作る際に、Jupyter上でコーディングして、出来上がったら"Executable Script"としExportして使っている。
こういうやり方をしている時に、Jupyter上で作成時には、確認やデバッグ用のコードを書いたセルを含む。
これを、Export前に消す、あるいは``if True:``と書いておいて、Export前に``if False:``に書き換えるなどとしていたが、それなりに面倒だ。

その解決方法を確認したので、以下に示す。

# 判定用フラグ
先頭の方のスクリプトに以下を書き、フラグ``OnJupyter``を設定する。

```python:
import sys
OnJupyter = __name__ == '__main__' and "ipykernel" in sys.modules
```
このフラグは、Jupyter上で直接実行されているノートブック上のコードでのみ``True``となる。作成したモジュールをJupyter上でimportしても、そのモジュール上では(``__name__``が``__main__``ではないので)``False``となる。

# デバッグ用セル
デバッグ用のセルは、以下の例の様に先頭でフラグをチェックするように書けば良い。

```python:
if OnJupyer:
    print("This is a debug code")
```
HTMLのパースにjsoupを使って見た

# HTMLをパースするライブラリ
今回あるサイトのHTTPのレスポンスのHTMLをパースする必要がありました。HTMLは基本はXMLなので色々なパーサがありますが、jsoupを使ったら意外とよかったのでそれを紹介したいと思います。

## そもそも・・・なんでHTMLをパースする必要があるのか？
今、開発しているアプリがAndroid端末内でCSVファイルを作ってそれをWebサイトにアップロードする仕組みなんですが、そのWebサイトがWEB APIを提供していなくて、（おそらく、１０年以上前に作った、そのまま）普通のブラウザからHTMLでのアップロードのインタフェースしか提供していません。
1. ログイン。
1. CSVを添付して送信。この時正常か、エラーになる
1. 送信結果を過去の履歴も含めて取得
1. ログアウト

という、一連の流れになっています。こんなの、APIあれば一発なのに・・・と思うのが普通でしょうが。各リクエスト/レスポンスのやり取りで、ブラウザから来る前提なので、結果のレスポンスは全てHTMLです。そのHTMLの中の特定のタグの値を見て正常か、失敗かを判定する必要があります。

# jsoupを使って見る
[jsoupのホームページ](https://jsoup.org/)

## 依存ライブラリの追加
まず、ライブラリの依存性を追加します
```gradle:build.gradle
dependencies {
    ・・・
    implementation 'org.jsoup:jsoup:1.15.3'
}
```
## パース機能の呼び出し方
パースはString型を引数にorg.jsoup.Jsoup#parseを呼ぶと、org.jsoup.nodes.Document型が返ってきます。簡単ですね。
```kotlin
val doc = Jsoup.parse(response)
```
このorg.jsoup.nodes.Document型がHTMLの全ての情報がパースされて格納されています。ここなら目的の箇所を探し当てて、値を取得します。この方法ですが、いくつかあります。

* Document#getElementById(String id) 
HTMLのid="・・・"で探す
* Document#getElementsByTag(String tag) 
Tagで探す。"table"とか、"input"とか
* Document#getElementsByClass(String className) 
HTMLのclass="・・・"で探す
* Document#getElementsByAttribute(String key)
属性で探す。"href"とか。

この結果にorg.jsoup.select.Elements型が返ってきます。上のいずれの方法で探しても、HTMLの中に複数個所該当する場合があります。

org.jsoup.select.Elementsの中にorg.jsoup.nodes.Elementを複数繰り返しで持っています。
```kotlin
elements.forEach { element ->
    println(element.text())
}
```
HTMLなので当然階層構造になっているので、org.jsoup.nodes.Elementには子要素が存在します。
```kotlin
val elements =  table.children()
```
子要素も複数のElementの繰り返しの可能性があるので、org.jsoup.select.Elementsで返ってきます。これらをforEach等で繰り返しながら、目的のElementを探し当てます。

目的のElementを探し当てたら、そのElementのデータを取得します。これも取得するデータによってメソッドが分かれています。

* Element#attr(String key) 属性
* Element#attributes() 全ての属性
* Element#id() id="・・・"
* Element#className() class="・・・" 複数の場合はスペース区切り
* Element#classNames() class="・・・" Set<String>で返ってくる
* Element#text() テキストの部分 
* Element#html() HTMLの形で返ってくる
* Element#outerHtml() 外側のHTMLが返ってくる
* Element#data() データ、例えばScriptタグの内側
* Element#tag() タグが返ってくる。Tag型
* Element#tagName() タグ名が返ってくる。String型

例えば、探し当てた目的のElementが
```html
<input type="hidden" id="xxxx_key" name="xxxxx_key" value="20221216195944675">
```
だったら、value="・・・" の部分を取得したければ、

```kotlin
var val = element.text()
```
と言った感じになります。

## joupを使って、直接送信
jsoupは上の例のようにHTMLパーサとして使えますが、HTTPで送信する機能も持っています。ただし、非同期ではなく同期なので、Androidから送信する場合は非同期の部分はcoroutineなり、RxJavaなりで自分で実装する必要があります。
```kotlin
val document = Jsoup.connect("http://www.google.co.jp").get()
println(document.html())
```
リクエストパラメータを付けることもできます。
```kotlin
val doc = Jsoup.connect("http://example.com")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  .timeout(3000)
  .post()
```
Python self

以下はPythonにおける「self」の使い方を示す例。

```python
class MyClass:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hello(self):
        print(f"Hello, I am {self.name} and I am {self.age} years old.")

my_object = MyClass("John Doe", 30)
my_object.say_hello()
```

この例では、「MyClass」というクラスを定義しています。このクラスは、名前(name)と年齢(age)を持つインスタンスを生成することができます。

```python
my_object = MyClass("John Doe", 30)
```
この行では、「MyClass」クラスから新しいインスタンスを生成しています。このインスタンスは、名前が「John Doe」で年齢が30歳であるというプロパティを持っています。

```python
def say_hello(self):
    print(f"Hello, I am {self.name} and I am {self.age} years old.")
```
このメソッドは、自分自身のプロパティ(self.nameとself.age)を使って「Hello」というメッセージを出力することができます。
```python
my_object.say_hello()
```
この行では、生成されたインスタンスの「say_hello」メソッドを呼び出しています。このメソッドは、「Hello, I am John Doe and I am 30 years old.」というメッセージを出力することができます。

```python
print(person.name) # Output: Jane
```

値を取得する際はプロパティ名を指定します。
AWSアカウント同士でS3バケットを共有する

他AWSアカウントとS3バケットを共有する状況（＝「S3を提供するAWSアカウント」と「S3を利用する（提供される）AWSアカウント」が居る状況）になったとする。
そのような場合、こんな感じで設定しておくと良いのではないか。

## S3バケットを提供する側

* お互いのAWSアカウントID（数字12桁のもの）を共有する
* S3バケットを用意する
  * 【オプション】S3バケットに[S3アクセスポイント](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-points.html)を追加する
    * 【オプション】断固拒否したいアクションをアクセスポイントのリソースポリシーにて設定しておく
      * ※例：読み込み専用にしたいので「`s3:Delete*`」と「`s3:Put*`」を「`Deny`」する
  * 【オプション】リクエスト時に[リクエスタが料金を支払う](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/RequesterPaysBuckets.html)かどうかを指定する
* S3バケット名をS3利用側に連絡する
  * 【オプション】S3バケット名ではなく[S3アクセスポイントエイリアス](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-points-alias.html)名（もしくはS3アクセスポイントARN）を連絡する
  * ※注：S3利用側が利用側自身のアカウント内でアクセスポイントを作成し利用する形の管理方法も有り
* S3を利用できる権限を持ったIAMロールを用意し、S3利用側に提供する
  * 許可するアクションを設定する
    * `s3:GetObject`等
  * [External ID](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)を設定する
    * S3利用側より指定してもらう
  * 対象リソースとしてS3バケットを指定する
    * 【オプション】S3バケットではなくS3アクセスポイントを指定する

## S3バケットを利用する（提供される）側

* お互いのAWSアカウントID（数字12桁のもの）を共有する
* External IDを決めS3提供側に連絡する
* S3提供側よりIAMロールの提供を受ける
  * 提供されたIAMロールをAssumeできるのは特定のIAMだけ、というIAMポリシーを設定する
    * 【オプション】CloudTrail追跡のため、STSロールセッション名にてIAMユーザー名などの識別情報の入力を必須とするように設定する
* 提供されたIAMロールのAssumeRole時に
  * External IDを指定する
  * 【オプション】AssumeRole時にSTSロールセッション名を指定する
* S3アクセス時に
  * [Expected Bucket Owner](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucket-owner-condition.html)を指定する
  * 【オプション】S3アクセス時にリクエスタ支払い了承の旨を指定する
GAME言語でFibonacci数を求める


GAME言語でFibonacci数を求めるプログラムです。

```fibonacci.gm
#!/usr/bin/gamelinux
10*Fibonacci数を求める
100 "Input n of fibonacci(n):" N=?
110 A=0 B=1
120 ;=N=0 ?=A / #=-1
130 I=1,N-1 T=A A=B B=T+B @=I+1
140 ?=B /

```
【CloudFormation | Serverless Framework】RefとSubの使い分け

## はじめに

普段から`ServerlessFramework`を用いてデプロイしていますが、
その中で`!Ref`と`!Sub`の使い分けについて整理したのでこちらにもまとめます。

## 結論

表記の違いと、結合できるかどうか

## 1. 表記違い

~~~yml
!Ref MyBucketName
# ⇒ "hoge-bucket"

!Sub ${MyBucketName}
# ⇒ "hoge-bucket"
~~~

`Sub`は`${}`で囲む必要がある

## 2. 結合できるかどうか

~~~yml
!Ref MyBucketName-dev-assets
# ⇒ error

!Sub ${MyBucketName}-dev-assets
# ⇒ "hoge-bucket-dev-assets"
~~~

`Ref`で結合をしたいときは`Join`を使う必要がある

~~~yml
!Join
  - '-'
  - !Ref MyBucketName
  - dev
  - assets
# ⇒ "hoge-bucket-dev-assets"
~~~

## 3. 結論

単純に論理値変換で使うのであれば`${}`を忘れやすいため 、`Ref`を使い
結合とかしたいときは`Sub`を使う。

というのが良さそうです。
phpで、サラからapiを実装する方法を調べてみる

# RestAPIサンプル
https://www.php.net/manual/ja/function.file-get-contents.php

https://ondotori.webstorage.jp/docs/api/reference/api_sample.html

https://forsmile.jp/development/php/1709/

https://www.wakuwakubank.com/posts/430-php-json/

https://chaika.hatenablog.com/entry/2020/07/24/120000

https://hidashun.hatenablog.com/entry/20110510/1305035652

https://qiita.com/KNR109/items/d3b6aa8803c62238d990

https://zenn.dev/yu1ro/articles/4c73274383b676
[C#] ダイアログOKボタン押下時にエラー処理を行う


自分メモ。ダイアログでOKボタン押下時にエラー処理を行ってエラーがあった場合はダイアログを閉じないようにする方法。

```
private void MyDialog_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.DialogResult != DialogResult.OK) {
        // OKボタン以外でダイアログが閉じる場合は無条件で閉じる。
        return;
    }

    // ・・・なんらかのエラー処理・・・・
   
    if (hasError) {
        // エラーがあった場合はダイアログを閉じる処理をキャンセルする
        e.Cancel = true;
    }
}
```
Verilator 5をGitHub Actionsで動かす方法〜self-hosted runnerで高速化

SystemVerilogのCI環境の構築で，今度はself-hosted runnerを使ってみたいと思います．

Verilator 5 を使う利点について

https://qiita.com/zacky1972/items/5062e599a447ab529880

> Verilatorのいいところは，macOSでも使える点と，GitHub ActionsでCIを組める点です．
Verilator 5になって，--timingオプションが使えるようになり，テストベンチで #10; すなわち10クロック待つ，みたいな記述ができるようになり，SystemVerilogでテストベンチが完結できるみたいです．それ以前のVerilatorだとCプログラムでテストベンチを書く必要がありました．(とはいえ，記述できるのは，ディジタル回路設計とコンピュータアーキテクチャ第2版にあるような，自己点検テストベンチまでで，テストベクタファイル付きテストベンチは意図通りにファイルを読み込めなかったのですけど)

下記のようにDockerを使って高速化しましたが，CIで常用するにはまだまだ速度が足りないと思っていました．

https://qiita.com/zacky1972/items/d0054b6d8567162898dd

Self-hosted runnerを使うことで，プライベートネットワーク上のリソースを使うことができます．今回の場合だと，環境をあらかじめセットアップしてDockerイメージ取得の時間を削減するのと，CPU資源とメモリ資源を潤沢に使って並列コンパイルをすることで，ビルドを高速化できる期待を持っています．

Self-hosted runnerに関する公式ドキュメント

https://docs.github.com/en/actions/using-github-hosted-runners/connecting-to-a-private-network

今回参考にした記事はこちらです．

https://devops-blog.virtualtech.jp/entry/20220926/1664160391

GitHubレポジトリ上の Settings > Actions > Runners で`New self-hosted runner`ボタンを押し，その手順にしたがって，環境を構築します．

ただし，最後の `./run.sh` をするかわりに，次のコマンドを入力します．

```bash
sudo ./svc.sh install $USER
sudo ./svc.sh start $USER
```

これでバックグラウンドでランナーが起動します．

今回，Ubuntu20.04に環境を構築しました．Verilator 5をインストールする手順は基本的には次の手順です．

https://verilator.org/guide/latest/install.html

ただし，不足しているのは，まず`help2man`のインストールです．

```bash
sudo apt install help2man
```

それから，Clang 9を用いるようにしないとエラーになります．Clang 9のインストールは下記です．

```bash
sudo apt install clang-9
```

`./configure` を実行する際に，次のようにして Clang-9 を用いるように設定します．

```bash
CXX=clang++-9 LINK=clang++-9 ./configure
```

あとは前述の手順の通りです．

GitHub Actionsのymlは次のようにします．

```yaml:verilator_on_local.yml
# This is a basic workflow to help you get started with Actions

name: Verilator on Rigel

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "main" branch
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: self-hosted

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      # Run compiling and testing
      - name: Run compiling and testing
        run: |
          make -j$(nproc) -f Makefile.verilator clean test
```

`make -j$(nproc)`とすることで，マシンのポテンシャルをめいいっぱい使い切って並列ビルドします．また，Verilator 5環境構築済みなので，Dockerイメージの取得が不要です．

この変更により，ビルドとテストが数倍高速化され，ほとんど待たずに終了するようになりました！

20240210追記:

本記事から大幅アップデートした手法について，[FPGAマガジン特別版No.2で紹介しております https://fpga.tokyo/no2-2/](https://fpga.tokyo/no2-2/)

大変光栄なことに，トップを飾っております．

> 第1章　Verilator 5とGitHub Actionsによるテストベンチ自動検証

他にも有用な記事が満載ですので，ぜひこの機会にInterfaceを定期購読ください！
文字を1文字ずつ配列に格納する(Powershell)

**Powershell**で文字を1文字ずつ配列に格納するスクリプトを実装しました。


```Powershell
    #文字の入力
    $str = Read-Host("文字を入力してください")

    #1文字ずつ分割して配列に格納する
    $str_array = $str.ToCharArray()

    #配列を取り出す
    foreach ($msg in $str_array) {
    	Write-Host $msg
    }
```

```powershell
変数.toChararray()
```

**ToCharArray メソッド**を使います。
Scrapyとは？Python、webスクレイピング

# はじめに
備忘録です。

# Scrapyとは？
フレームワークのこと。
webスクレイピングやクローリングするときに使われる。
Beautiful Soupとかを使い慣れた次に勉強するといいと思う。

公式ドキュメントによれば次の通り　Google翻訳を使用した

> Scrapy は、高速で高レベルの Web クロールおよび Web スクレイピング フレームワークであり、Web サイトをクロールし、そのページから構造化データを抽出するために使用されます。データマイニングからモニタリング、自動テストまで幅広い用途に使用できます。

## 具体的なメリットは？
+ 同じような処理を書かなくて済む
    + スクレイピングをしていたら同じような処理を何度も書くことがあると思う
    + ウェブサイトごとの違いに専念して書くことが出来る
+ robots.txtとかを考慮してくれる
    + robots.txtとは、スクレイピングされるサイトからのお願い
    + これはしてもいいよとかこれはだめだよって書いている
+ ほかにもいっぱいあるらしい
    + 勉強していきます(__)

# 参考文献
[https://docs.scrapy.org/en/latest/](https://docs.scrapy.org/en/latest/)
pythonで履歴書と職務経歴書pdf化を自動化してみた。 

転職活動中に応募書類をpdfで求められることが多くExcelやWordのファイルをいちいち最新の日付にしてpdfに変換という作業が面倒だったので自動化してみました

↓とりあえず必要なライブラリと日付情報たちを変数に入れていきます
```Python
import openpyxl
import os
import datetime
import win32com.client
import docx



#日付を取得
today = datetime.date.today()
year_jp = str(int(today.strftime('%Y')) - 2018)#令和用
year_ad = today.strftime('%Y')
month = str(int(today.strftime('%m')))
day = str(int(today.strftime('%d')))
```
↓ここからファイル操作です
履歴書がexcelで職務経歴書がWordなので微妙に処理が違います
```Python
#excel操作
rasume = "履歴書.xlsx"
wb = openpyxl.load_workbook(rasume)
sheet = wb['sheet1']
sheet['V9'].value = f'　令和　　{year_jp}年　　{month}月　　{day}日現在'

#excel保存
wb.save(rasume)
wb.close

#word操作
word = docx.Document("職務経歴書before.docx")#編集前原本
para1 = word.paragraphs[0]
t = para1.text
t = t.replace("date",f'{year_ad}年　{month}月　{day}日')#原本の日付部分を"date"にしている
para1.text = t
word.save("職務経歴書.docx")
```

続いてpdf化操作です
何故かexcelは絶対パスじゃないとファイルを読み込んでくれませんでした
```Python
#excel→pdf変換 win32com相対パス使用不可
os.remove("履歴書.pdf")#pdfファイルがあると何故かexcelが保存できないため泣く泣く一旦削除してからpdf化
excel = win32com.client.Dispatch("Excel.Application")#pdf変換用ライブラリ
excelFile = excel.Workbooks.Open("C:/Users/name/Documents/src/python/RasumeDateChange/履歴書.xlsx")
excelFile.Worksheets("sheet1").Activate()
excelFile.ActiveSheet.ExportAsFixedFormat(0,"C:/Users/name/Documents/src/python/RasumeDateChange/履歴書.pdf")
excelFile.Close()
excel.Quit()

#word→excel変換
wdFormatPDF = 17
readFile = os.path.abspath("職務経歴書.docx")
saveFile = os.path.abspath("職務経歴書.pdf")
word = win32com.client.Dispatch("Word.Application")#pdf変換用ライブラリ
wordFile = word.Documents.Open(readFile)
wordFile.SaveAs(saveFile,FileFormat=wdFormatPDF)
wordFile.Close()
word.Quit()

```

このプログラムをタスクスケジューラで定期起動させ常に最新の日付のpdfファイルが保存されるようにしました
nuxt3,chart.js4系で円グラフ内に文字を表示する

chart.js4系で円グラフ内に文字を入れる

いつものようにyarn add
```
yarn add chart.js vue-chart-3
```

templateに描画するcomponentを追加
nuxtなのでインポートしなくても自動で読み込み
```
<template>
  <div class="canvas-area">
    <div>
      <DoughnutChart :chartData="chartData" :options="options" />
    </div>
  </div>
</template>
```

カスタムプラグインをChartに登録する
```
<script setup lang="ts">
import { DoughnutChart } from 'vue-chart-3'
import { Chart, registerables, ChartOptions } from 'chart.js'

Chart.register(...registerables)

const chartData = {
  datasets: [
    {
      data: [70, 5],
      backgroundColor: ['#FF5541', '#D2D2D2'],
    },
  ],
}

// ドーナッツの中央に文字を表示する
const customPlugin = {
  id: 'customTextDraw',
  afterDraw(chart: Chart) {
    const ctx = chart.ctx
    const chartArea = chart.chartArea
    const width = chartArea.right - chartArea.left
    const height = chartArea.bottom - chartArea.top
    const fontSize = (height / 184).toFixed(2)
    ctx.font = `${fontSize}em sans-serif`
    ctx.textBaseline = 'middle'

    const text = 'hogehoge率'
    const textX = Math.round((width - ctx.measureText(text).width) / 2)
    const textY = height / 2.4
    ctx.fillStyle = '#333333'
    ctx.fillText(text, textX, textY)

    const text2 = '70%'
    const fontSize2 = (height / 74).toFixed(2)
    ctx.font = `bold ${fontSize2}em sans-serif`
    ctx.fillStyle = '#FF5541'
    ctx.textBaseline = 'middle'
    const textY2 = (height / 4) * 2.5
    ctx.fillText(text2, textX, textY2)
  },
}

Chart.register(customPlugin)

const options = ref<ChartOptions<'doughnut'>>({
  cutout: 80,
  responsive: true,
})
</script>
```

以上
PHP8でPOP3

pear がなかったからpearからインストール

```ruby:
# yum install php-pear
# pear install NET_POP3
```

接続だけ書いてみてテスト
```ruby:test.php
<html>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<body>
<?php
ini_set('display_errors', 'On');
require_once('Net/POP3.php');
$pop3 = new Net_POP3();
 
$ret = $pop3->connect("ssl://pop.lolipop.jp", 995 );

if ( $ret === true ) {
    print "OK\n";
}else {
	print "NG\n";
	exit;
}
```

で、エラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209422/0e92356e-00d5-4c6f-e6e0-d53bc762b5d9.png)

念のためyahoo.co.jpとか、自分の会社のアドレスとかテストしてみてもダメっぽい

どうも、環境によって使えないとか...。PHP8系だとダメってことなのかな。

直接、POP3.phpを修正してしまう。
（＊下記修正は、自己責任です。）

~~~ruby:
--- POP3.php_org        2023-01-31 10:57:01.710200202 +0900
+++ POP3.php    2023-01-30 17:15:29.303882260 +0900
@@ -51,9 +51,9 @@
 * For usage see the example script
 */

-define('NET_POP3_STATE_DISCONNECTED',  1, true);
-define('NET_POP3_STATE_AUTHORISATION', 2, true);
-define('NET_POP3_STATE_TRANSACTION',   4, true);
+define('NET_POP3_STATE_DISCONNECTED',  1);
+define('NET_POP3_STATE_AUTHORISATION', 2);
+define('NET_POP3_STATE_TRANSACTION',   4);

 class Net_POP3
 {
@@ -141,6 +141,13 @@
     var $_capability;


+       public function __construct() {
+        $this->_timestamp =  ''; // Used for APOP
+        $this->_maildrop  =  array();
+        $this->_timeout   =  3;
+        $this->_state     =  NET_POP3_STATE_DISCONNECTED;
+        $this->_socket    = new Net_Socket();
+       }

    /**
     * Constructor. Sets up the object variables, and instantiates
@@ -149,11 +156,13 @@
     */
     function Net_POP3()
     {
+/*
         $this->_timestamp =  ''; // Used for APOP
         $this->_maildrop  =  array();
         $this->_timeout   =  3;
         $this->_state     =  NET_POP3_STATE_DISCONNECTED;
         $this->_socket    = new Net_Socket();
+*/
         /*
         * Include the Auth_SASL package.  If the package is not available,
         * we disable the authentication methods that depend upon it.
@@ -1214,4 +1223,4 @@

 }
~~~

PHP8で、defineのtrueはいらなくなったらしい。
$thisの宣言の位置をコンストラクタにいれる。

とりあえず、通ったけど、Class "Auth_SASL" not foundでエラーがでる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209422/68ffae8e-424e-468a-1ec1-4d6d2af3c98f.png)

171行目の@include_once 'Auth/SASL.php';
が読み込まれていないみたいなので、constructに入れてみる。

~~~ruby:再修正
    144         public function __construct() {
    145                 $this->_timestamp =  ''; // Used for APOP
    146                 $this->_maildrop  =  array();
    147                 $this->_timeout   =  3;
    148                 $this->_state     =  NET_POP3_STATE_DISCONNECTED;
    149                 $this->_socket    = new Net_Socket();
    150                 @include_once 'Auth/SASL.php';
    151         }
~~~


分かりやすいように、POP3.phpのdebugをtrueにする
~~~ruby:
    /**
    * To allow class debuging
    * @var boolean
    */
    var $_debug = true;
~~~

Noticeが出たけど、
「+OK Logged in. C: STAT S:+OK 0 0」まで表示できたので、この修正POP3.phpを使ってみる。
DockerでWordPress起動し投稿したときに、「公開/更新に失敗しました。 返答が正しい JSON レスポンスではありません。」が出る

# 環境

- ホスト：Windows10Pro
- Dockerバージョン：Docker Desktop for Windwos v4.15.0
- Docker Image: WordPress:latest (v6.1.1)、mysql:5.7.36

# 現象
開発環境として上記で環境構築し、初期設定後に固定ページを作ったら「公開に失敗しました。 返答が正しい JSON レスポンスではありません。」とのこと

# 解決
ググると色々出てくるけど、結局のところドキュメントルートの .htaccessファイルがおかしかった。chmodで権限渡してもうまく書いてくれないので、docker-compose.yml でVolumesに.htaccessを追加して、直接以下を書いたファイルを事前に用意。
``` docker-compose.yml
volumes:
  - ./wordpress/.htaccess:/var/www/html/.htaccess
  - ...
```

``` .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
```
これで解決した。

ちょっと前まではこんなことなかったけどなー。。。と思いつつ、今後は発生したらこれで凌ごうと思う。

誰かの役に立ったならうれしい。
エンジニアインターン9日目

今日はスクレイピングをするための環境構築を行った。awsのアカウントを作ったり、データベースに接続して、今までとはまた違ったことをやった。新しいことだらけで難しいが、いろんなとこに触れることができ、確実にためになっていると思う。新しいことをたくさん教えていただけて、自分が確実に成長できる環境だと思う。これからも勉強することの連続だが、新しいことを学ぶことに楽しさを覚え、エンジニアになるために毎日進歩していきたい。
【Mysql】Mysqldumpでデータの入っていないテーブルを取得する方法

# Mysqldumpでデータの入っていないテーブルを取得する方法

## 発端
データインポートのテスト用にデータの入っていないからのテーブルが欲しかった

## 解決策
-d オプションを使用する
```sql
mysqldump -u root -p 落としたいDB名 -d > ファイル名
```
Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「Azure RBAC」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「Azure RBAC」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure での ID とガバナンスの管理](https://learn.microsoft.com/ja-jp/training/paths/az-104-manage-identities-governance/)
◇対応するモジュール
[ロールベースのアクセス制御を実装する方法](https://learn.microsoft.com/ja-jp/training/modules/configure-role-based-access-control/2-implement)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「Azure Policyの作成手順」](https://qiita.com/fsd-jume/items/2dc2ebb326afa77afbc3)

## Azure RBAC
AZ-900の学習まとめでも扱っておりますので、復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：Azure の基礎: Azure のアーキテクチャとサービスについて説明する「Azureのロールベースのアクセス制御」](https://qiita.com/fsd-jume/items/d316d6b979d97c6fa6e3)

### Azure RBAC
・ARM上に構築された承認システム
・Azureリソースにアクセスできるユーザを管理可能
・ユーザがリソースに対して実行できる操作を制御可能
・ユーザがアクセスできる領域を管理可能
・リソースへのアクセス制御にはAzureロールの割り当てが必要

**◆Azure RBACでできることの例**
・あるアプリに、リソースグループ内のすべてのリソースへのアクセスを許可
・あるユーザに、リソースグループ内のすべてのリソースの管理を許可
・あるユーザにサブスクリプション内のVM管理を許可し、別のユーザにVNetの管理を許可
・データベース管理者(DBA)にサブスクリプション内のSQLデータベースの管理を許可

### Azure RBACの概念
**◆セキュリティプリンシパル**
・リソースへのアクセスを要求しているものを表すオブジェクト
　-ユーザ
　-グループ
　-サービスプリンシパル(アプリケーションのID)
　-マネージドID(サービスプリンシパルの一種)

**◆ロールの定義**
・実行できる操作が登録されたアクセス許可のコレクション
・組み込みロール(一例)
　-所有者：リソース管理のためのフルアクセス
　-共同作成者：リソース管理のためのフルアクセス(ロール割り当ては不可)
　-閲覧者：読み取り専用
　-ユーザアクセス管理者：リソースに対するユーザアクセスを管理

**◆スコープ**
・アクセスが適用されるリソースのセット
⇒要求されるアクセスレベルの境界
　-管理グループ
　-サブスクリプション
　-リソースグループ
　-リソース

**◆割り当て**
・特定のスコープでセキュリティプリンシパルにロール定義をアタッチするプロセス
・割り当ての作成でユーザにロール定義のアクセス権を付与
・拒否割り当てにより許可されないアクションのセットをロールに定義可能
⇒リソース保護のためにAzureによって拒否割り当ては作成/管理

### Azure RBACの考慮事項
・ベストプラクティス：作業を実行するために最小限の特権をユーザに付与
⇒チーム内で職務を分離し、職務に必要なアクセス許可のみを付与

## 次の学習内容
**◆ロール定義**

https://qiita.com/fsd-jume/items/2f16ce98ad9e94c22e89

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
Railsバージョンアップにおける変更PRの特定の仕方

## 本記事について
Railsに特化して書いているが汎用的ではある。
CHANGELOG.mdなファイルに全部載ってたら楽だが、全てのライブラリがそうではない。
じゃあどうやって調べるのかという話。

## 環境
ruby 2.7.5
Rails 6.1.7.1

## 本記事の題材

```.rb
Rails 6.1の場合
[1] pry(main)> Time.current
=> Tue, 31 Jan 2023 10:12:36.749685920 JST +09:00

Rails 6.0の場合
[1] pry(main)> Time.current
=> Tue, 31 Jan 2023 10:06:14 JST +09:00
```

Time.current.class
=> ActiveSupport::TimeWithZone

なため、ここに変更があったのかなと予想できる

ナノ秒出力されるようになってる！

## 調べ方1 変更が加わったバージョンを特定し、Releasesで確認

https://github.com/rails/rails/releases?q=TimeWithZone&expanded=true

![スクリーンショット 2023-01-31 10.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/6e3229fd-7338-264a-16e8-13c233991833.png)

リリースのページで検索するとすぐ出る。Tagsからバージョン指定して探してもいいと思う

> Add subsec to ActiveSupport::TimeWithZone#inspect.

## 調べ方2 railsのコード直で見る

本件に関してはとてもわかりやすくコメントがある

https://github.com/rails/rails/blob/v6.1.0/activesupport/lib/active_support/time_with_zone.rb#L17-L22

```.rb
  #   Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  #   Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
  #   Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
  #   Time.zone.at(1171139445)                        # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
  #   Time.zone.now                                   # => Sun, 18 May 2008 13:07:55.754107581 EDT -04:00
  #   Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
```

https://github.com/rails/rails/blob/v6.0.6.1/activesupport/lib/active_support/time_with_zone.rb#L17-L22

```.rb
  #   Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  #   Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.at(1171139445)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  #   Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00
```

この行を変更したPRが探しているものでしょう！ということで vscode の GitLens で飛ぶ
![スクリーンショット_2023-01-31_11_17_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/fd8604c2-7727-9916-3632-399bfcecb836.png)

https://github.com/rails/rails/pull/38874

## この調査の仕方にたどり着くまでにためしてだめだったこと。

`Rails 6.1 ナノ秒`とかで検索する。
=> 全然出ない。何故?

Railsガイドのリリースノートを見る

https://railsguides.jp/6_1_release_notes.html

=> ない。

Rails 6.1の変更系記事をいくつか見る
=> ない

Chat GPTに聞いてみる
![スクリーンショット 2023-01-31 11.05.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/42b25ba2-7614-8607-7f7b-d4055006ca4b.png)
これで出るのが一番楽なのでぜひ成長してほしい。今後に期待。
Playground 環境を導入して機能開発を爆速にする

## はじめに

こんにちは。with で Android エンジニアをしている [石田(@maxfie1d)](https://github.com/maxfie1d) です。
本記事では 最近導入して機能開発が爆速になった Playground 環境について紹介します。

## Playground 環境とは

アプリ全体ではなく、アプリの一部の機能のみをサポートしたアプリのことを with では Playground 環境と呼んでいます。ミニアプリやデモアプリと呼ばれることもあるようです。

アプリが大規模化していくにつれ、アプリ全体をビルドしたり、実際に触って動かしてみたりといったことが徐々にツラくなってきます。

記事執筆時点で with はサービス提供開始より 7 年が経過しており、with Android 版の LOC は 20 万行を越えそこそこの規模のコードベースになりつつあります。フルビルドをしてアプリが起動した上に何回も画面をタップしてやっと動作確認をしたい画面にたどり着く...。これを 1 日に何度も繰り返すのは大変です。

この課題に対応するために 先日 with の Android 版 (以下、with-android) では Playground 環境の導入を行いました。

## Playground 環境の実現方法

ログインが必要な「ある機能 X」 の Playground 環境を作る場合を想定し、Playground 環境をどのように実現するかを説明します。

### マルチモジュール化

Playground 環境を作成するにはマルチモジュール化が必須です。[公式ガイド](https://developer.android.com/jetpack/guide?hl=ja)に沿ってマルチモジュール化していれば問題ありません。with-android は以前は図の左側で示されているようなシンプルなモジュール構成でしたが、2022年にマルチモジュール化に着手しました。

現在のモジュール構成の例を図の右側に示します。`app` モジュールが `feature-X` の他に `feature-Y` `feature-Z` 等のすべての機能のモジュールに依存している一方で、`playground-X` は `feature-X` にのみ依存している点がポイントです。

![Module dependency](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/4dd6def7-3f86-73ca-789d-dd056bd4ce98.png)

### playground-X モジュールの作成

Playground 環境で試したい機能とログイン機能への導線を含む Actiivty を作成します。

with-android の Playground 環境は以下のような画面になっています。非常にシンプルな作りとなっていて、「いいね！」や「もらったスペシャルいいね！」等のアイテムをタップすることで各機能にアクセスすることができます。右上の「歯車のボタン」をタップするとログイン画面へ遷移します。

| いいね！の Playground 環境                    | Playground 環境用のログイン画面      |
| --- | ------------------ |
![playground-like.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/f048a4d2-fbb0-0645-30ef-a10d5f54656c.png) | ![playground-login-screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/95e97dc7-dde6-b853-4a3b-60fd7eac5482.png) |

例えば以下のようにして「いいね！」のボトムシートの挙動を確認することができます。

![anim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/997f927e-6df2-d5f8-386a-75c2f034d0a8.gif)

### 依存していないモジュールの画面への遷移をどうするか

さてここで 1 つ問題です。Playground 環境において依存していないモジュールの画面への遷移はどうすればよいでしょうか。with-android では Fake の画面へ遷移するようにしています。マルチモジュール化をした際に画面遷移は `interface` を介して行うようにしており、これにより Playground 環境 でビルドした時は Fake に遷移し、`app` でビルドした時は実画面に遷移するという制御を DI で行うことが可能となっています。

![playground-navigation-resolution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/d968146f-470f-fdda-b6ed-0cd87d25c16c.png)


## Playground 環境を導入して変わったこと

Playground 環境を導入して感じたメリットを簡単にまとめると以下のようになります。

- ビルド時間が **1/3〜1/10** 程度になり、作業に集中しやすくスピーディーに開発を完了できる
- 目的の画面にすぐに辿り着けるので、動作確認を素早く行える
- アプリに入るかどうか分からない実験的な機能やプロトタイプを Playground 環境上に作って、プランナーやデザイナーと気軽に共有できる

## 直近の課題

Playground 環境を導入してみて感じた直近の課題です。

#### CI でビルドできるようにしたい

CI 上でも Playground 環境をビルドできるようにしたいと思っています。実現のアイデアとしては GitHub の Label もしくは Pull Request のコメントを使って好きな Playground 環境をビルドできるようにしたいと思っています。

#### Fake 画面の作成を効率化したい

現状 Fake 画面は手動で作っているため効率が悪いので、コード生成等を使って半自動的に作成できるようにしたいと思っています。

## まとめ

with-android ではアプリの一部の機能のみをサポートしたアプリであるPlayground 環境を導入しました。マルチモジュール化ができているプロジェクトであれば、`app` モジュールと別に `playground` モジュールを作るだけで比較的簡単に導入することができます。Playground 環境を導入することで、ビルド時間が大幅に短縮されたりプロトタイプがしやすくなったりと複数の効果を得ることができました。今後さらに Playground 環境を充実させていきたいと思っています。
Windows バージョン、ビルド番号、リビジョンの取得

これら情報がWin32APIで書かれたアプリの起動時にちょいと必要になったのですが、
API調べるのが億劫だったので＾＾；
```
cmd.exe /c ver.exe
```
の出力をもらうことにしました(手抜き)。標準入出力のパイプ関連のソース(山本ワールドさん)を探して書いてみました。

```
bool ExecCMDCommand(char *cmd, char *outtxt, int outtxtlen)
{
  bool bret=true;

  HANDLE rPipe=NULL, wPipe=NULL;
  SECURITY_ATTRIBUTES sa{ sizeof(SECURITY_ATTRIBUTES) };
  sa.bInheritHandle=TRUE;
  if(CreatePipe(&rPipe, &wPipe, &sa, 0)==FALSE) return false;

  char cmdline[MAX_PATH]{};
  sprintf(cmdline, "cmd.exe /c %s", cmd);

  STARTUPINFO si{ sizeof(STARTUPINFO) };
  si.dwFlags=STARTF_USESTDHANDLES| STARTF_USESHOWWINDOW;
  si.hStdOutput=si.hStdError=wPipe;
  si.wShowWindow=SW_HIDE;
  PROCESS_INFORMATION pi{};
  CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
  WaitForInputIdle(pi.hProcess, INFINITE);//SOFTWARETIMEOUT);
  WaitForSingleObject(pi.hProcess, INFINITE);//SOFTWARETIMEOUT);
  CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
  
  DWORD tlen, len;
  PeekNamedPipe(rPipe, NULL, 0, NULL, &tlen, NULL);
  if(tlen>0){
    ReadFile(rPipe, outtxt, outtxtlen, &len, NULL);
  }else{
    bret=false;
  }
  
  CloseHandle(rPipe); CloseHandle(wPipe);
  return bret;
}
```

こんな感じか。あとは適当に文字列切り出して終わり。説明も、ver.exeの出力と同じフォーマットだよ、で済むし。
esp-idf: mqtt の使い方

esp-idf/examples/protocols/mqtt/tcp のプログラムを改造します。
M5Stack Core2 で動作確認をしました。
次にサブスクライブするのを確認しました。
>ブローカー　mqtt.eclipseprojects.io
>トピック　/topic/qos0

## プログラム


プロジェクトのコピー

```bash
cd ~/esp
cp -r ~/esp/esp-idf/examples/protocols/mqtt/tcp .
```

tcp/sdkconfig を作成

```bash
idf.py build
```

変更する場所

```text:tcp/sdkconfig
（省略）
CONFIG_EXAMPLE_WIFI_SSID="****"
CONFIG_EXAMPLE_WIFI_PASSWORD="****"
（省略）
```

## コンパイル、実行

```bash
idf.py -p /dev/ttyUSB0 flash
```

## テスト結果

テスト用のスクリプト

```bash:go_pub_mqtt.sh
message="こんにちは Mqtt "`date`
mosquitto_pub -d -t orz -m "${message}" \
	-h  mqtt.eclipseprojects.io \
	--topic /topic/qos0
```

スクリプトを実行後のシリアルコンソールの表示

```text
$ cu -l /dev/ttyUSB0 -s 115200
Connected.
I (100839) mqtt_example: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA=こんにちは Mqtt 2024年 10月 13日 日曜日 10:12:43 JST
```
Fargateの見積もりについて

Fargateの見積もりを行う際によくわからない項目があったのでメモ。

https://calculator.aws/#/


この「タスクまたはポッド数」と「平均期間」であるが、それぞれ単位が秒〜月（日数）がありイマイチわからない、、、
![スクリーンショット 2023-01-31 11.08.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659784/d99dbc43-773c-ac2e-2209-341db6646c86.png)

考え方としてこのようになるらしい。
```
■ 例1: 1ヶ月(30日換算)の間に2個のタスクが常時起動
タスクまたはポッドの数: 2、/月
平均期間: 30、日数
```

```
■ 例2: 10時間の間に4個のタスクが常時起動
タスクまたはポッドの数: 4、/月
平均期間: 10、時間
```

```
■ 例3: 20分の間に1個のタスクが毎日起動
タスクまたはポッドの数: 1、/日
平均期間: 20、分
```