OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】意図していないアクションが実行されてしまう時に確認してほしいこと

## はじめに
Railsでアプリ開発をしていて、意図通りにアクションが実行されないことはよくあると思います。
その原因は様々あると思いますが、今回は未来の自分の為にいくつか例を投稿します。
ついでに初学者の方々の助けにもなれば幸いです。

## ルーティングの記述の順番を確認する。
Railsのルーティングは、ルートの定義順によって評価されます。
つまり、最初にマッチしたものが実行されます。
以下の場合`item_export_list_path`をリクエストすると
`item#export_list`ではなく`item#show`が実行されてしまいます。
~~~ruby:config/routes.rb
post 'items/:id', to: 'item#show', as: 'items_show'
post 'items/item_list', to: 'item#export_list', as: 'item_export_list'
~~~
なので以下のように順番を入れ替えて修正
~~~ruby:config/routes.rb
post 'items/item_list', to: 'item#export_list', as: 'item_export_list'
post 'items/:id', to: 'item#show', as: 'items_show'
~~~
これで`item_export_list_path`をリクエストすると
意図通り`item#export_list`が実行されました。

### 詳しい原因はよくわかっていないのでchatgptに聞いてみた。
:id は任意の文字列にマッチするため、post 'items/:id' の方が広範なパスにマッチすると判断されます。
/items/export_list というパスが来た場合、Railsはまず最初のルートから順にマッチするかどうかを確認します。post 'items/:id' の方は :id が任意の文字列にマッチするため、このパスにもマッチしてしまいます。そのため、最初のルートがマッチしてしまい、items#show アクションが実行されてしまいます。

つまりは、`/:id`は文字列にもマッチすることがあり、
`/items/export_list`(この場合/export_listが文字列)のリクエストがより前に定義していた`items/:id`と判断され`item#show`が実行されたということでしょうか。
基本的に、今回のようにルーティングを設定する場合は`items/:id`のようなルーティングは:id以外を渡した場合も呼ばれる可能性があるため後ろに定義しておくことが無難という考え方で問題ないのでしょうか。
なんちゃってエンジニアの私に教えていただければ幸いです。

## javascriptを設定せずに`link_to`を使用している場合
javascriptを設定しておらず、`link_to`で`method: :post`などget以外を指定している場合はデフォルトでgetリクエストが生成されるので違ったアクションが呼ばれてしまうことがあります。
javascriptを有効にした場合はjavascriptが介入して指定したHTTPメソッドでリクエストしてくれます。
javascriptを有効にしない場合は`button_to`に書きかえるか
 ~~~
<%= form_with(url: XXXXX_path) do |form| %>
    <input type="submit" value="button">
<% end %>
 ~~~
 のように実装することで対応できます。

 ## 最後に
 今後も開発していくなかで新しく陥ってしまった事例など出てきましたら記事に追記していこうと思います。
間違った内容や表現などありましたらご指摘いただけますと幸いです。
【Excel】セルが操作できない...だと...

## 何もしてないのに、矢印でセルを動かせなくなった(白目)
Excelでドキュメントを作成していた、ある日。
セルを移動しようとしたら、矢印をクリックした方向に画面がずれるではないか。  
少し困ったことになったので、調べ増した。

## 解決方法
Excelのウィンドウ下部のステータスバーに`ScrollLock`が付いていたらキーボードの`ScrollLock`なければ、`Scrlk`をクリック。ステータスバーから`ScrollLock`が消えたら事象解決です。

## 後書き
初めての経験だったので、一瞬何が起こっているのかよくわからなかったです。調べれば30秒で片付く内容ですが、せっかくなので記事にしてみました。

## 参考文献
[MSの公式記事](https://support.microsoft.com/ja-jp/office/scrolllock-%E3%82%AD%E3%83%BC%E3%82%92%E3%82%AA%E3%83%95%E3%81%AB%E3%81%99%E3%82%8B-a78492cc-c124-4782-a38b-df46669520e0)
S3 の静的ホスティングでうまくいかないときに確認するべき３つのこと

# 初めに
みなさこんにちは、AWS の S3 静的ホスティングで少しはまったので記録を残しておきます。
S3 の静的ホスティングは AWS WAF や CloudFront の検証などで意外と設定する機会が多いのではないのでしょうか？

# 発生したエラー
今回発生したのは 404 Forbidden エラーです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/c1565903-0b46-2b9f-6ed4-e06b5aa7d2cb.png)


# 確認するべき３か所
## 1. S3静的ホスティングが有効化されていか
しっかり確認しましょう、意外と忘れているかもしれません。
S3バケット画面のプロパティ下部にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/7169e9b2-750e-d3f5-6ead-be3dfd3c3dd1.png)

## 2. オブジェクトへのパブリックアクセスは許可されているか
アクセス許可タブ、上から二番目にあります。
チェックを外してパブリックからのアクセスを受け入れましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/baed4835-8a52-5f31-89f1-5526f4204971.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531208/b47f61a3-a01b-edfc-5a7b-8c47ed195213.png)


## 3. S3バケットのポリシーは適切か
今回私はこれでした、忘れないようにしましょう
パブリックアクセスの下にあります。
```JSON
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "PublicReadGetObject",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "バケットのARN/*"
		}
	]
}
```
ポリシーの編集ウィジット上からバケットのARNをコピーできます、親切。

これらがしっかり設定できていればS3静的ホスティングはできるはずです。
それではよい検証ライフを！
誤ってTerraform Stateファイルをロックしてしまったときの対処

# 初めに
チームでTerraformを使い、かつTerraform Cloudを使わない場合はStateファイルをリモートに置くことがベストプラクティスとされています。
Azureのストレージの一つであるBlob Storageには、書き込みのロック機能があり、同時に`terraform Apply`してしまってStateファイルがめちゃくちゃになるなどの事故を防ぐことができます。

https://learn.microsoft.com/ja-jp/azure/developer/terraform/store-state-in-azure-storage?tabs=azure-cli

安全にStateファイルを管理できてとても良い構成なのですが、`terraform apply`を誤ってCtrl+Cなどで中断してしまうと、ファイルがロックされた状態のままになり、Stateファイルの更新が出来なくなります。
解決方法が意外とweb上に落ちておらず、すこし時間かかったのでここに置いておきます。

# 解決方法
1. ストレージアカウントの保管先のコンテナ＞terrafrom.tfstateファイルを選択
    リースステータスが「ロック済み」になっていて、編集できない...
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523715/a4fb2e66-f770-f153-c85b-8a4cd17578eb.png)

2. 上記画面の「リースの解約」を選択すると、確認画面が出るので「はい」を押す

3. リースステータスが「ロック解除」になっていることを確認
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523715/6f137136-5343-fc30-5d37-f14659e0fa63.png)
4. Stateファイルの手動修正
    反映状況が中途半端なものは手動で編集したり、`terraform import`したりで修正
Stateファイルは「編集」タブからAzure Portal上で編集可能

# 最後に
手癖でローカルにあるときと同じようにCtrl+Cをやらかしてしまうことがあったので、他の方も参考になれば幸いです。
【備忘】（今更ですが）Web APIとWebhookの違いについて

### 結論
・**Web API**：要求してデータを取得するための手段
・**Webhook**：特定のイベントが発生したときに通知を受け取る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303394/b4acd147-311d-76c4-b388-1a5bd8775266.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303394/1657904d-608d-00e8-65dd-37182629a5c1.png)


### 詳細
広義の意味では、WebhookもWeb APIの定義である「HTTP通信を主としたアプリケーション・プログラミング・インターフェイス」である。
Web APIとWebhookの違いは「**通信の手順とデータが流れる方向**」である。

Web API の通信は、下記 2 ステップで成り立ちます。
1. クライアントがサーバにデータを要求する（リクエスト）
2. サーバがクライアントにデータを送る（レスポンス）
※原則として、リクエストが先・レスポンスが後

Webhook の通信は、下記1 ステップのみで成り立ちます。
1. 送信元サーバが送信先サーバにデータを送信する（リクエスト）

Web API の場合はサーバからクライアントへのレスポンスでデータが返信されているのに対して、Webhook の場合はリクエストでいきなりデータを送信している。


### 使用例
#### Web APIの使用例:
・Twitter API:開発者がTwitterのデータにアクセスし、操作するためのWeb APIの一例。
開発者はTwitter APIを使用して、ツイートの検索、ユーザーのタイムラインの取得、新しいツイートの投稿などを行うことが可能。
https://developer.twitter.com/ja/docs/twitter-api

・Google Maps API:地図や地理的な情報にアクセスするためのAPI。
開発者はGoogle Maps APIを使用して、カスタム地図の表示、経路の検索、場所の詳細情報の取得などを実現可能。
https://developers.google.com/maps/documentation/javascript?hl=ja

・GitHub REST API:GitHubのリポジトリやユーザーに関する情報にアクセスするためのAPI。
開発者はGitHub REST APIを使用して、リポジトリの作成、コミットの取得、プルリクエストの作成などを行える。
https://docs.github.com/ja/rest?apiVersion=2022-11-28

#### Webhookの使用例:
・GitHub Webhook:GitHubのWebhookを使用すると、特定のリポジトリに新しいコミットがプッシュされたときに通知を受け取ることが可能。
これにより、コードが変更されるたびにビルドやデプロイの自動化などが可能。
https://docs.github.com/ja/webhooks/about-webhooks

・Stripe Webhook:Stripeは、オンライン支払い処理を行うためのサービスで、Webhookを使用してイベント通知を提供。
例えば、支払いが成功したときや失敗したときにWebhookがトリガーされ、開発者はこれを利用して注文の処理やユーザーへの通知を行うことが可能。
https://stripe.com/docs/webhooks?locale=ja-JP

・Slack Incoming Webhooks:SlackのIncoming Webhooksを使用すると、外部のシステムやサービスがSlackにメッセージを投稿可能。
イベントが発生した場合に通知をSlackに送り、チーム全体で共有することができる。
https://api.slack.com/messaging/webhooks


### 参考情報
https://qiita.com/kuwazzy/items/fdf363cc1caee9a23686
https://jp.quora.com/webhook%E3%81%A8API%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B
画面に新しい機能を呼び出すボタンを追加した際の考慮点

# 経緯
１年目に担当した業務は、今あるアプリケーションに新しくボタンを追加することでした。
ここでは、その業務で学んだボタンを追加するときに考えるべきことをまとめようと思います。ちなみに開発言語はVB.netでした。

# Tabの選択順を合わせる
これは言語によって違うのかもしれませんが、すでにあるアプリケーションに新しくボタンを追加すると、当然ながらTabを押した時に選択される順番は、新しく追加したボタンが最後に選択されます。順番を自然にするため、プロパティTabIndexを設定する必要があります。当然ながら、すでにあるボタンも追加されるボタンの分、一つずつずらしていく必要があります。

# 処理中の挙動
ボタンを押し、処理を実行している間の挙動は機能によって考える必要があります。自分が担当した業務では以下のようなことを考えました。機能によってどうするかは考える必要があると思います。
- ボタンを押している途中は、カーソルを待機状態にしておく
- 処理が終わったら、カーソルをデフォルトに戻す
- 処理中はボタンが反応しないようにする（ボタンを非活性）

また、処理中にボタンを反応しないようにする場面では一つ落とし穴のようなところがありました。ボタンを非活性にしておけば、処理中にボタンをクリックしても反応しないと思いました。しかし、非活性中にボタンをクリックすると、そのクリックイベントは待機していて、ボタンが非活性から活性になると、再び送られ処理を実行してしまいました。とりあえず最後にDoEventsで待機中のイベントを全部廃棄するようにしました。

:::note warn
DoEventsは推奨されていなようです。フラグを立てたり、いろいろ別の方法はあるようで、次に同じことをやる場合は、この部分は詳しく調べる必要がありそうです。（自分が担当したところは複雑な部分でないので大丈夫...なはず。）

:::


# 処理が正常に終わらなかった場合
これも処理がどういうものかに依存すると思います。自分が担当したものは独立した機能なので、その機能が正常に動かなくても、業務自体に大きな支障はありません。そのため処理が正常に終わらなくても、画面は閉じないようにしました。

# できるだけ既存の形に合わせる
自分が追加した機能と同じような機能がありましたので、エラーメッセージの表示方法などはそちらの機能と同じようにしました。 ***ただし、これはあくまでユーザーが分かりやすいようにするということなので、中身まで無理に合わせる必要はないと思います。*** 実際、自分が担当したシステムはかなり古いもので、いわゆるレガシーコードがたくさんあります。それに無理に合わせると、どんどん分かりにくいコードが増えていくことになります（リファクタリングをするのがベストなのだろうなとは思いますが）。

# まとめ
初めての開発ということで、後から見直すとかなり拙い部分が多かったなと思います。また今までよくプログラムの知識だけではなく業務理解も必要という意味がよくわからなかったのですが、今回実際に開発してみて、その意味が理解できたと思います。
vscodeでamazon linux 2 に Remote sshできない件

# 原因

vscode 1.86 から glibc の要求バージョンが 2.28 以上になったのだが、amazon linux 2 の glibc の最新は2.26 なので、接続できなくなっている。

https://github.com/microsoft/vscode/issues/201129

https://github.com/microsoft/vscode/issues/203375

# 解決策

一応、vscode的には古いLinuxディストリビューションで利用したい場合は1.85にバージョンを落とせとのこと。

https://code.visualstudio.com/docs/remote/faq#_can-i-run-vs-code-server-on-older-linux-distributions

バージョン1.85はここからダウンロードできます。

https://code.visualstudio.com/updates/v1_85

# 続報 (2024-02-08)

`glibc >= 2.28` を満たさないLinuxディストリビューションへの接続を12ヶ月間は許可する模様。
この修正は 2024-02-08 にリリースされるとのこと。

https://github.com/microsoft/vscode/issues/203375#issuecomment-1927893504
【ST言語ことはじめ】パルス処理をPLSを使わずに実装してみた【箸休め】

## はじめに

この記事では、PLCのST言語におけるカウンタのインクリメント方法について、従来のPLS命令と新しいアプローチを比較します。具体的には、ボタンの状態に応じてカウンタをインクリメントする方法について検討します。

## 使用機材

|   |機種など   |  
|:---:|------|  
|PLC  |Q02CPU, QX41, QY41P, Q62P, Q38B    |  
|アプリ  |GX Works 2    |  

I/O割り付けは[こちら](https://qiita.com/so2/items/0f0cab2e324179718b89 "I/O割り付け表")を参照してください。

## サンプルプログラム

### 従来の方法: PLS命令の利用

```st  
PLS(X1, M0);  

IF M0 THEN  
    INC(K1, CN1);  
END_IF;  

K4Y40 := CN1;
(* カウンタをDPLに表示します *)
```

この方法では、PLS（Pulse）命令を使用して、ボタン（X1）が押されたときにカウンタを1つ増やします。M0はパルスフラグとして使用され、ボタンが押されたときに一度だけインクリメントされることを保証します。

### 新しい方法: PLS命令の代替

```st  
IF X1 AND NOT M0 THEN  
    (* ボタン１が押されて、かつパルスフラグがFALSEの時のみ *)
    M0 := TRUE; (* パルスフラグ *)  
    INC(K1, CN1);  
ELSIF NOT X1 THEN  
    (* ボタン１がOFFになった時にパルスフラグを解放します *)
    M0 := FALSE;  
END_IF;  

K4Y40 := CN1;
(* カウンタをDPLに表示します *)
```

新しい方法では、PLS命令を使用せずにボタンの状態を監視し、条件を満たした場合にのみカウンタをインクリメントします。M0はパルスフラグとして機能し、ボタンが押されたときに一度だけカウンタを増やす役割を果たします。

## まとめ

従来のPLS命令と新しい方法を比較した結果、両者は同じ目的を達成しますが、実装方法が異なります。PLS命令を使用する方法は、簡潔で直感的ですが、新しい方法はより細かな制御が可能です。どちらの方法もボタンの状態を正確に監視し、適切なタイミングでカウンタを増やすことができます。使用する状況やプロジェクトの要件に応じて、適切な方法を選択することが重要です。
<苦戦してる人必見>簡単にGithub Educationの審査に通過し、無料でGithub Copilotを使う方法


# 本記事の目的

Github Copilotを学生は無料で使えるのですが、そのためのGithub Educationの審査に苦戦したので、これからの人のために私の審査に通った方法を共有しようと思う。
今回は詳しいGithub Educationの概要は省き、登録方法のみに絞って説明する。

# 登録方法

# 学校メールアドレス追加
まず、自分の学校から支給されているであろうメールアドレスをあなたのGithubのメールアドレスとして設定する必要がある。

https://github.com/settings/emails
このリンクにアクセスすると、GithubのSettingsのAccessのEmailsに飛ぶことができる。

そこからメールアドレスを設定しよう。
ただし、別にPrimaryに設定しなくてもよい。　

# Billing informationの設定
https://github.com/settings/billing/payment_information
このリンク先にあるBilling informationというところに情報を入れる必要があるようだ。とにかく必須になっている部分を埋めればよい。

この部分の入力がされておらず、エラーになるケースも多く、私もその一人であった。

:::note info
英語で入力するのが好ましい

:::


# Github Educationにアクセス

https://education.github.com/discount_requests/application
このページのGet school benefitsをクリック。

飛んだページで先ほど設定した学校メールアドレスを使い、申請を進めていく。
What is the name of your school?は英語で学校名を入れ（おそらく自動で入力される）、
How do you plan to use Github?は適当で良い。

# 学生証の提出
順調に進むと、学生証の写真の提出が求められる。以下のようなページである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/11c4cc6c-5636-f008-dadc-036734a66e12.png)

ここが厄介で、英訳されている学生証が求められるのである。ここの部分でネット上では紙に書いて、学生証と共に写真に撮るだの、パワポで英訳を上に追加するだのといった様々な方法が提案されているが、今回は私が実際に使用した簡単にできる方法を提案しようと思う。

### それがGoogleレンズの翻訳機能である。

まず、学生証の写真を撮る。この時必要な情報は、名前、学校名、有効期限である。

:::note info
私の場合は有効期限だけ裏面に書かれていたので、表と裏の写真を加工アプリで一つの画像にするという手間が発生した。私のような場合に該当する人はPhotoDirectorというアプリなどで写真を合成すると良い
:::



次に、用意した画像をGoogleレンズを使い翻訳する。使い方はGoogleの検索を入力するところの右にある以下のアイコンをクリックするだけである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/f9e7d3fb-4bd8-981c-867c-f5b64a4bceea.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/faa757ec-e101-85d2-fcd4-e8ca114e13e3.png)


そこで先ほどの画像を翻訳する。そうすると、日本語の部分が英語に書き換わる。
その画面をスクショして、カッティングツールなどで日本語が画像内に存在しないようにしよう。「日本語→英語」という部分も消したほうがいい。

![IMG_CFD24B79F488-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/ee457ee1-3f22-96b8-b3ee-a73f94f2e2da.jpeg)



出来上がった画像を先ほどのページでアップロードし、提出して、以下の画面が表示されれば、成功である。

:::note warn
複数回アップロードするのはエラーとなるので、その場合は違う画像を用意する
:::

:::note warn
画像はjpgのみであるので、適宜変換しよう
:::


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/37996d20-3d3f-322d-e1ec-44e6e241b73d.png)

申請した時にメールは来ないので、成功しているか心配になるかもしれないが、審査に通った場合、学校メールアドレス宛にメールが来る。私の場合は４日ほどかかったので、それぐらいを目安に待ってみよう。

成功すれば、あなたも今日からPROだ！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513930/a48716e0-f9b7-9ca7-ec1c-cf3d09cc234b.png)


# まとめ
これで無料でGithub Copilotが使えるので、この特権を大いに使いまくろう！他にも学生ならではの特権があるので、登録必須である。

この記事で少しでも誰かの役に立っていれば幸いだ。
egrep

### egrepとgrepの違い
grepはfileで名前を指定されたファイルを検索して、与えられたパターンにマッチする部分を含む行を探します。
さらに、二つの兄弟プログラムegrepとfgrepが利用可能です。
egrepはgrep -E ,fgrepはgrep -F と同じです。
egrepやfgrepを直接その名前で呼び出すのはお勧めしません。
...
出典　man egrep (CentOS 7.0)

### egrep -E
-Eを使うと拡張正規表現として解釈されます。
### 出典
https://www.sbcr.jp/product/4797380941/

grep および sed は基本正規表現を受け入れますが、–E オプションが 使用されている場合は、拡張正規表現を受け入れます。
正規表現は、通常文字または特殊文字 (メタキャラクター とも呼ばれる) で構成されます。 基本正規表現と拡張正規表現の違いは、それぞれが含むことのできるメタキャラクターが異なるということだけです。
### 出典 
https://www.ibm.com/docs/ja/zos/2.3.0?topic=reference-regular-expressions-regexp#:~:text=grep%20%E3%81%8A%E3%82%88%E3%81%B3%20sed,%E3%81%93%E3%81%A8%E3%81%A0%E3%81%91%E3%81%A7%E3%81%99%E3%80%82

### 気づき
メタ文字の違いだけだろう。

# 感想
まだまだ勉強が必要だ。
/usr/share/locale以下のファイル、ディレクトリ

### 判別するコマンド
```
ls -1 /usr/share/locale | egrep -v "^(default|en|ja|locale)" | less
```
### 出典
https://qiita.com/bezeklik/items/a8274bb230f2efa61ffa#%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%AB%E3%82%BF%E3%83%AD%E3%82%B0%E3%81%AE%E7%A2%BA%E8%AA%8D

### 気づき
en,ja以外にも削除対象を外している。

### /usr/share/locale/locale.aliasとは？
catコマンドで中身をみた。
```
Locale name alias data base.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later vesion .

This program is distributed in the hope that it will be useful, but  WITHOUT ANY WARRANT without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for more details.

....

The format of this file is the same as for the corresponding file of the X window System, which normally can be found in /usr/
A single line contains two fields: an alias and a substitution value.
All entries are case independent.

Note: this file is obsolete and kept around for the time being for backward compatibility.
Nobody should rely on the names defined here.
Locales should always be specified by their full name.

bokmal      nb_NO.ISO-8859-1
...
```
....

ロケール名エイリアスデータベース。

このプログラムはフリーソフトウェアです。あなたは、Free Software Foundationによって発行されたGNU一般公衆利用許諾契約書(GNU General Public License)、バージョン2、または(あなたの選択により)それ以降のバージョンのいずれかに従って、再配布および/または改変することができます。

このプログラムは有用であることを願って配布されていますが、商品性や特定の目的への適合性についての暗黙の保証もなく、いかなる保証もありません。詳細はGNU一般公衆利用許諾契約書をご覧ください。

...

このファイルのフォーマットは、Xウィンドウ・システムの対応するファイルと同じで、通常は/usr/にある。
1行にはエイリアスと置換値の2つのフィールドが含まれる。
すべての項目は大文字小文字を区別しない。

注意：このファイルは時代遅れであり、後方互換性のために当分の間残しておくものである。
ここで定義された名前を鵜呑みにする人はいないはずだ。
ロケールは常にフルネームで指定すべきである。

bokmal nb_NO.ISO-8859-1
...

出典　deepL

### 気づき
bokmalがnb_NO.ISO-8859-1のエイリアスなのだろうと思う。
あまりこのファイルの存在を理解することはできなかったが、注意書きによればこのファイルは時代遅れらしいのであまり強い存在ではなさそうだ。
しかし削除を避ける理由はわからなかった。

### /usr/share/locale/default/LC_MESSAGEとは？
lsコマンドで何も表示されなかったので中身は空なのだろう。
このディレクトリに関する情報は取れなかった。
なので削除を避ける理由はわからなかった。

# 感想
英語を読めないと厳しそう。
とりえあえずこれを真似して削除してみよう。
AtCoder B,C問題をKotlinで解こう - ABC270

当記事ではAtCoder、ABCのB問題ならびにC問題（時々D問題も）のKotlinでの解法を超初心者向けに詳細に解説します。

同記事を[Zenn](https://zenn.dev/paragraph14/articles/100c074442a172)にも投稿しています。

https://atcoder.jp/contests/abc270/tasks

## [B - Hammer](https://atcoder.jp/contests/abc270/tasks/abc270_b)
#### やりたいこと
スタート、ゴール、壁、ハンマーの位置関係で場合分けを行い、スタートからゴールまでの最短移動距離を求めよう。ゴールに到達できない場合は-1を出力しよう。

位置関係の場合わけは以下の3パターンとなる。
1. **スタートとゴールの間に壁がある場合**
    1. **スタートとハンマーの間に壁がある場合**
ゴールに到達できない
    2. **スタートとハンマーの間に壁がない場合**
スタートからハンマーまで移動し、ハンマーからゴールに移動する
2. **スタートとゴールの間に壁がない場合**
スタートからゴールに移動する。

#### 入力値の取得
```kotlin
    // 入力値の取得
    val (x, y, z) = readln().split(" ").map { it.toInt() }
```
#### サンプルコード
```kotlin:main.kt
fun main(args: Array<String>) {
    println(getAns())
}

fun getAns(): Int {
    // 入力値の取得
    val (x, y, z) = readln().split(" ").map { it.toInt() }

    // スタート、ゴール、壁、ハンマーの位置関係で場合分けをする
    return if (y in 0..x || y in x..0) {
        // スタートからゴールまでの間に壁がある
        if (y in 0..z || y in z..0) {
            // スタートからハンマーまでの間に壁がある
            // この場合ゴール不可能
            -1
        } else {
            // スタートからハンマーまでの間に壁はない
            // ハンマーを拾ってからゴールを目指す
            Math.abs(z) + Math.abs(x - z)
        }
    } else {
        // スタートからゴールまでの間に壁はないのでそのままゴールできる
        Math.abs(x)
    }
}
```

## [C - Simple path](https://atcoder.jp/contests/abc270/tasks/abc270_c)
#### やりたいこと
- x から y への最短経路を求める。
    - 最短距離を求め、経路の復元を行う。

**幅優先探索** を行い、x から 各頂点への最短距離を求める。各頂点への最短距離を求める際に、**どこの頂点から来たのか** を保持して、経路の復元を行えるようにする。

#### 入力値の取得
```kotlin
    // 入力値の取得
    val (n,x,y) = readln().split(" ").map { it.toInt() }
    // 頂点同士の繋がりを取得
    val connect = Array(n+1) { mutableSetOf<Int>() }
    repeat(n-1) {
        val (a,b) = readln().split(" ").map { it.toInt() }
        connect[a].add(b)
        connect[b].add(a)
    }
```
#### サンプルコード
```kotlin:main.kt
import java.util.LinkedList

fun main(args: Array<String>) {
    // 入力値の取得
    val (n, x, y) = readln().split(" ").map { it.toInt() }
    // 頂点同士の繋がりを取得
    val connect = Array(n + 1) { mutableSetOf<Int>() }
    repeat(n - 1) {
        val (a, b) = readln().split(" ").map { it.toInt() }
        connect[a].add(b)
        connect[b].add(a)
    }

    // x からの距離を保持
    val step = IntArray(n + 1) { Int.MAX_VALUE }
    // どこの頂点から移動してきたのかを保持
    val from = IntArray(n + 1)

    // x -> y へ移動する場合の最短距離とその経路を求める
    val queue = LinkedList<Int>()
    queue.add(x)
    step[x] = 0
    
    // 幅優先探索を行う
    while (queue.isNotEmpty()) {
        val cur = queue.pop()
        if (cur == y) {
            // y はゴールなので、それ以上は処理しなくていい
            break
        }
        for (i in connect[cur]) {
            if (step[i] <= step[cur] + 1) {
                continue
            }
            step[i] = step[cur] + 1
            from[i] = cur
            queue.add(i)
        }
    }

    // y から移動元を辿って経路を復元
    val route = mutableListOf(y)
    while (route.last() != x) {
        route.add(from[route.last()])
    }
    println(route.reversed().joinToString(" "))
}
```
java でローカル変数に値を代入しているのに、使用されていないと怒られる

# 現象
こんな感じ（testに値を入れているし、使用してるやん…）
※ワーニングは出るけど、代入された値そのものは認識する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658170/4392d8b1-c3f2-f4a8-91ab-600c8f6543b0.png)

# 原因（解決）
代入だけだと使ったうちに入らないらしい
変数を何かしら使うことで、エラーは消える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658170/d8e26409-77ef-2053-22f8-48dc91e80882.png)
[GitHub] work flow images

![git_workflow_0clone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/147316a1-304e-2ec6-85d3-a8bee02e8ff4.png)
![git_workflow_1checkout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/b86700b5-482d-74bd-6512-5f4eb071dd46.png)
![git_workflow_2edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/108ac02f-e10e-abcd-9bbf-b12b87409694.png)
![git_workflow_3add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/261907a6-04e5-fdda-79e9-cb65316b5a81.png)
![git_workflow_4commit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/3673106e-8f90-96c7-086a-7ccea133f161.png)
![git_workflow_5push.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/b14dddce-24cd-02f8-7783-974a0564d83a.png)
![git_workflow_6pullrequest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/7434f262-601f-9946-11fa-5f683f4d2f19.png)
Flutterでadmobをandroidに追加するための備忘録

# google_mobile_adsのインストール
pubspec.yamlに以下の行を追加する
```
dependencies:
    google_mobile_ads: ^4.0.0
```

# google_mobile_adsの初期化
```dart:main.dart
import 'dart:async';
import 'package:google_mobile_ads/google_mobile_ads.dart';
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  unawaited(MobileAds.instance.initialize());//これを追加
  runApp(const MyApp());
}
```

# 広告の読み込み等
下のサイトのexampleを参考にすれば、すぐに実装できる。
https://pub.dev/packages/google_mobile_ads/example

# なんかビルドで失敗する
多分、google_mobile_adsを加えると, androidの64k問題に到達する。
下のサイトに従って、```flutter run --debug```を行えば、簡単にmultidexに対応できるので、変にbuild.gradleとかいじらないこと。
https://docs.flutter.dev/deployment/android#enabling-multidex-support
Windows11でJavaのバージョンを確認するには

# 始めに
Javaのダウンロードが出来るサイトでの説明によると...

https://www.java.com/ja/download/help/version_manual.html

こちらのサイトでは、Windows10までの確認方法しか無く、Windows11でのJavaバージョンの確認方法は発見できませんでした。


# そもそもコントロールパネル...どこ？
上記のサイトではコントロールパネルからの確認が可能であると記述されていますが、Windows11ではコントロールパネルが探しにくくなっています。

アプリ検索を行うとコントロールパネルを発見する事が出来ます。
しかし、Windowsのスタートメニューからすべてのアプリを調べてもコントロールパネルを発見する事が出来ませんでした。

また、コントロールパネルからJavaのバージョンを確認する事はできませんでした。
（コントロールパネルでの検索でJavaのファイルを確認できませんでした。）
※私の実行環境の問題もあるかもしれません。

# 結論

コマンドプロンプトやターミナルにて”java -version”と入力する事で確認が出来ます。
※user名が出る行に関しては削除している為、実際の出力結果とは異なります

~~~ :出力結果
java version "21.0.1" 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 21.0.1+12-LTS-29)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.1+12-LTS-29, mixed mode, sharing)
~~~

私が今使っているJavaのバージョンは"21.0.1"だそうです。
Prometheus アーキテクチャ と Time series Database

# Prometheusのアーキテクチャ

Prometheusはクラウドネイティブな監視システムであり、多くのオープンソースプロジェクトで利用されています。以下では、Prometheusのアーキテクチャについて説明します。

## 概要

Prometheusは時系列データを収集し、処理、可視化、アラートのために使用されます。主な特徴は以下の通りです。

- マルチディメンショナルなデータモデルを使用し、柔軟なクエリ言語（PromQL）を提供します。
- Pull型のアプローチで動作し、サーバー間でメトリクスを取得します。
- データの抽出、変換、ロギング、メトリクスエクスポートに利用できる豊富なエコシステムを提供します。

## Prometheusの機能

Prometheusは以下の主な機能を提供します。

1. メトリクス収集: Prometheusはエージェントレスの形式でアプリケーションやサービスからメトリクスを収集します。HTTPや特定のエクスポーターを介して、メトリクスをエクスポートできるようにします。

2. データモデル: Prometheusはユーザーが作成したメトリクスデータを、キー/バリューの形式で格納します。このデータモデルは柔軟であり、タグ付けやレーベル付けなどを含めることができます。

3. データ保存: Prometheusは収集したメトリクスデータを時間の経過とともに永続的に保存します。デフォルトでは、ローカルのディスク上に保存されます。

4. クエリ言語: Prometheusは独自のクエリ言語（PromQL）を提供し、収集したメトリクスデータに対して強力なクエリと集計操作を実行できます。これにより、データの可視化やトレンドの分析が容易になります。

5. アラート: Prometheusはメトリクスデータに基づいてアラートを生成し、ユーザーへ通知する機能を提供します。この機能により、システムの異常や問題を早期に検知することができます。

## コンポーネント

Prometheusは以下の主要なコンポーネントで構成されます。

1. Prometheus Server: メトリクスの収集、保存、クエリ処理を行う中央のコンポーネントです。PromQL言語を使用してメトリクスデータに対するクエリを実行します。

2. Exporters: Prometheusにメトリクスをエクスポートするためのエージェントです。アプリケーションやサービスに組み込んで使用され、メトリクスデータを収集してPrometheus Serverに送信します。

3. Push Gateway: Push型のジョブのメトリクスを受け取り、クライアントアプリケーションからの全メトリクスデータを一時的に格納しておくことができます。これにより、非常に短い期間で別のプロセスからのメトリクスデータを受け付けることができます。

4. Alertmanager: Prometheusから受け取ったアラートを管理し、通知を制御するコンポーネントです。アラートのルーティング、サイレンシング、通知のグルーピングなどを行います。

5. Grafana: データの可視化とダッシュボードの作成に利用されます。Prometheusから取得したメトリクスデータをグラフやチャートで表示することができます。

以上がPrometheusのアーキテクチャの概要と、その機能およびコンポーネントについての詳細な説明です。
### Prometheusを利用したユースケース

Prometheusは、大規模なシステムやクラウドインフラストラクチャの監視に広く利用されています。以下にいくつかの具体的なユースケースを挙げます。

1. サービスの可用性とパフォーマンスの監視：Prometheusは一般的に、システムのリソース使用状況、レイテンシ、エラーレートなどのメトリクスを収集し、リアルタイムで可視化するために使用されます。これにより、問題の早期発見やトラブルシューティングが可能となります。

2. インフラストラクチャの監視：Prometheusは、クラウドインフラストラクチャのコンポーネント（サーバ、ネットワーク、ロードバランサ、ストレージなど）のメトリクスを収集し、インフラストラクチャの状態を監視するために使用されます。これにより、リソースの使用状況や障害の早期検出が可能となります。

3. アラートとトリガーの作成：Prometheusは、設定した条件に基づいてアラートを生成し、外部ツール（例：Slack、PagerDuty）への通知や自動的なアクションのトリガーを行うことができます。これにより、異常な状態やパフォーマンスの低下などの問題に対して即座に対処することができます。

### タイムシリーズデータベースの特徴

タイムシリーズデータベース（TSDB）は、時系列データ（タイムスタンプと値のペア）を効率的に格納し、クエリや分析を行うための特化したデータベースです。以下に、TSDBの特徴をいくつか挙げます。

1. 高速で効率的なデータ書き込みと読み取り：TSDBは、時系列データの高速な書き込みと読み取りに特化しています。大量のデータを効率的に処理することができます。

2. データ圧縮と保持期間：TSDBは、データの圧縮と効率的なディスク使用により、大量の時系列データを格納することができます。また、データの保持期間を柔軟に設定することも可能です。

3. クエリと集計のサポート：TSDBは、時系列データによく使用される特定のクエリパターンと集計操作をサポートしています。時間範囲に基づく集計やスライド窓関数などの機能を提供します。

### Prometheusとタイムシリーズデータベースの関係

Prometheusは、内部的に自身のタイムシリーズデータベース（Prometheus TSDB）を使用しています。Prometheus TSDBは、Prometheusが収集したすべてのメトリクスを格納するために使用されます。

Prometheus TSDBは、高いスケーラビリティと効率性を備えており、Prometheusの柔軟な監視システムを支えています。Prometheusは、メトリクスデータを収集し、Prometheusクエリ言語（PromQL）を使用してデータを抽出、処理、視覚化することができます。

ただし、Prometheusはタイムシリーズデータベースとしての機能が限定されており、特に大規模なデータセットや長期間のデータ保持には制限があります。そのため、Prometheusを拡張し、長期間データの保持や高度なクエリ・分析機能を備えた専用のTSDBとの組み合わせが一般的です。さまざまなタイムシリーズデータベース（例：InfluxDB、OpenTSDB）がPrometheusと統合され、将来的なデータの需要に応えるためのソリューションとなっています。
Jenkinsコンテナでアクセスログを有効化する

## はじめに
Jenkinsをコンテナで構築していると、アクセスログを有効化したい...等カスタムしたくなるかと思います。
私自身dockerでの変更の仕方に若干手間取ったので、忘れない様、備忘録として投稿します。

dockerを使ったJenkinsの構築方法は以下。  
[DockerコンテナでJenkinsを構築](https://qiita.com/xiaochun0001/items/c78d01cdb864aef39284)

**-eオプション**で環境変数を設定してあげることで大体は設定できるっぽいです。

## プレフィックスをつける
mysite.com/jenkins などのプレフィックスが付いたリバース プロキシの背後に Jenkins をインストールする場合は、環境変数を追加します。
`JENKINS_OPTS="--prefix=/jenkins"`
```
docker run -d --name jenkins -e JENKINS_OPTS="prefix=/jenkins" -p 8080:8080 --restart=on-failure -v jenkins:/var/jenkins_home jenkins/jenkins:lts-jdk17
```


## アクセスログを有効化する 
アクセスログを有効にするには、JENKINS_OPTS環境変数の値を以下のように設定します。
`--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/var/jenkins_home/logs/access_log`
```
docker run -d --name jenkins -e JENKINS_OPTS="--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/var/jenkins_home/logs/access_log" -p 8080:8080 --restart=on-failure -v jenkins:/var/jenkins_home jenkins/jenkins:lts-jdk17
```

アクセスログが有効化できました。
ログの出力先を買えたい場合は「--simpleAccessLogger.file=」の値を変更すれば、任意のパスに出力できます。
```
root@77f1bb9ad9a5:# ls -l /var/jenkins_home/logs/
total 4
-rw-r--r--. 1 jenkins jenkins 3063 Feb  1 12:00 access_log
drwxr-xr-x. 2 jenkins jenkins   35 Feb  1 08:02 tasks
root@77f1bb9ad9a5:#
root@77f1bb9ad9a5:#
root@77f1bb9ad9a5:# cat /var/jenkins_home/logs/access_log
192.168.75.1 - - [01/Feb/2024:12:00:15 +0000] "POST /widget/ExecutorsWidget/ajax HTTP/1.1" 500 4833 "http://192.168.75.129:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
~
192.168.75.1 - - [01/Feb/2024:12:00:47 +0000] "GET /login HTTP/1.1" 200 787 "http://192.168.75.129:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
192.168.75.1 - - [01/Feb/2024:12:00:47 +0000] "GET /static/6fbb23e3/favicon.ico HTTP/1.1" 200 17542 "http://192.168.75.129:8080/login?from=%2F" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
root@77f1bb9ad9a5:#
```

## JENKINS_HOMEの値を変更する
JENKINS_HOMEを変更する場合は変数に以下を設定します。  
`JENKINS_HOME="<任意のパス>"`
**-vオプション**を使用している場合は、コンテナ側のパスも併せて変更してください。

※変数を指定しなかった場合のデフォルトJENKINS_HOMEは<code>/var/jenkins_home</code>です。

```
docker run -d --name jenkins -e JENKINS_HOME="/var/lib/jenkins_home" -p 8080:8080 --restart=on-failure -v jenkins:/var/lib/jenkins_home jenkins/jenkins:lts-jdk17
```

JENKINS_HOMEの値が変わりました。
```
root@b6c711d4d324:/# printenv | grep JENKINS_HOME
JENKINS_HOME=/var/lib/jenkins_home
```
![スクリーンショット 2024-02-01 213220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844260/b7b688a3-adc1-fbd1-dd77-61e02ce1312c.png)


* 参考サイト
https://github.com/jenkinsci/docker/blob/master/README.md
JavaSilver勉強法「実務未経験」

Java Silver SE11に合格したので、勉強法の忘備録

# 勉強期間と勉強時間
２か月
100時間くらい（土日はやってない）

# プログラミング歴　
java 半年

# 勉強法

黒本をひたすら解き続ける（**特に12章、13章**）

わからない問題はすぐ答えをみる

多次元配列の問題はコードを書いてデバックする

コンパイルエラー、例外発生の問題は自分でコードを書いて
直してみる

例外の種類を全部覚える（検査例外と非検査例外)

 interface,継承,ポリモフィズム,static修飾へのアクセスは
 コードを書いて理解する（**超超超頻出問題**）

 # 使った参考書等

 黒本

 すっきりわかるJava(文法の確認くらいでしか使っていない）

 Udemiy 【Java-基礎】完全未経験からの基礎入門講座（丁寧解説/豊富な図解/ハンズオン/Java Silver試験対応）
 
 https://www.udemy.com/course/uz-java-kiso/


黒本で弱点の部分をすっきりわかるJavaやUdemyの動画教材で勉強した

# まとめ

黒本の12章、13章をどれだけやりこめるかが鍵

ほとんどの問題がこの2章から出題されるので
1週目から答えをみながらでいいからさっさと解き始めた方がいい

ちなみに私は1週目答え見ないで解いたら正答率30％だったけど
本番は80％で合格しました
Bazel https://bazel.build/

Bazel を使ったプロジェクトに出るくわした時のためのメモ。Bazel というのは Make のようなビルド用のツールらしい。

## インストール

お薦めにしたがって [Bazelisk](https://github.com/bazelbuild/bazelisk/blob/master/README.md) を使った。Mac OS の場合

```
brew install bazelisk
```

で bazelisk と bazel コマンドの両方がインストールされる。(bazel 直接のインストールとの違いは謎)

## Bazel の基本

[Bazel Tutorial: Build a C++ Project](https://bazel.build/start/cpp) を読みながら基本的な使い方をメモする。

Bazel を使ったプロジェクトには WORKSPACE と BUILD の二つのファイルがある。

* WORKSPACE:
    * プロジェクトのルートに置く。
    * `//` はこのディレクトリを指す。
* BUILD:
    * BUILD.bazel と書いても良い
    * bazel コマンドへの指示を書く。
    * WORKSPACE や BUILD など、Bazelisk のファイルは [Starlark Language](https://bazel.build/rules/language) で書かれている。

その他の基本は [Getting Started](https://bazel.build/start) の Build concepts 以下に書かれてある。

## bazel コマンドと BUILD ファイルの使い方

bazel コマンドの書式

    bazel コマンド (target)

例えば以下のようなファイルが `main/BUILD` にあるとする。

```
load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)
```

これは、`hello-world.cc` から `hello-world` コマンドを生成するという意味。以下のコマンドでビルドと実行ができる。

    bazel run //main:hello-world

* コマンドには build, run, test, clean などがある。
    * [Build programs with Bazel](https://bazel.build/run/build) に詳しく書いてある。
* target `//main:hello-world` の意味。
    * `//` は WORKSPACE のあるパス。
    * `:` の前の `main` は package (ディレクトリ) の名前。
    * `:` の後ろの `hello-world` は target の名前。この場合は `cc_binary` の name= で指定された名前。
    * 相対パス指定もできる。
        * `bazel run main:hello-world`
        * `cd main && bazel run :hello-world`
    * その他の書式は [Labels](https://bazel.build/concepts/labels) 参照。
* `cc_binary` は rule と呼ばれる。コマンドを作成する `cc_binary` のほか `cc_library` など色々ある。
    * [Build Encyclopedia](https://bazel.build/reference/be/overview) に様々な Rule の紹介がある。
    * 色々な言語の Rule はこのページの右のメニューから辿れる。
        * 

## BUILD ファイルの書き方

* [BUILD Style Guide](https://bazel.build/build/style-guide) に詳しく書いてある。
* [Buildifier](https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md) というのを使うと整形してくれる。
    * インストール方法: `go install github.com/bazelbuild/buildtools/buildifier@latest`

## 疑問

* 例えば bazel build を実行した時に何が行われるのかよく分からない。
* 同じ label に対して bazel build した時と bazel run した時の違いはどう定義されているか?
【UiPath】Communications Miningの学習済みモデルをRobotから呼び出す

# はじめに
UiPath Communications Miningについて書きます。
以前、Communications Miningにおけるモデルトレーニングの方法を記事にしました。

https://qiita.com/shuy/items/521b9f7f17798792fef8

今回は学習済みのモデルをUiPath Robotから呼び出して、予測結果を得るまでの方法を解説します。


# つかうもの
※クラウド環境は2024年1月時点のもの
Automation Cloud(Communications Mining) Enterprise版
Studio v2023.10 Enterprise版


# アクティビティパックをインストールする
Studio/RobotからCommunications Miningを呼び出すにはUiPath.CommunicationsMining.Activitiesをインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/7c0c58d9-8ba0-9234-36f7-75393bf3105f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/f5fa6915-c19d-cf48-381e-5e642350a015.png)


# ワークフローを作成する
Communications Miningへメールデータを投入し、予測結果を得るには、以下の2つアクティビティを使います。

* レコードを作成（Records.CreateRecord）
* レコードを予測（Predictions.PredictRecords）


## レコードを作成
Communications Miningへインプットする用のフォーマットデータを作成します。
この前にメール取得系アクティビティ（GetOutlookMailMessagesなど）でメールメッセージを取得しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/0bcf67d1-ca7b-cb9d-914d-ec6fdaffac8e.png)

今回は必要最低限のプロパティのみ設定します。
* **コミュニケーションデータの種類**： 今回は「電子メール」
* **レコードID**： 今回は適当でよい（固定値にしておく）
* **メッセージのタイムスタンプ**： 今回は適当でよい（今の時刻にしておく）
* **メッセージ本文**： 取得したメールメッセージの本文
* **件名**： 取得したメールメッセージの件名
* **出力**： 次のアクティビティへ渡すための変数（UiPath.CommunicationsMining.Activities.Records.Models.Record型）


## レコードを予測
上記で作成したレコードをインプットとして、Communications Miningへデータを投入し予測結果を得ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/976fdda5-8232-187e-ba37-6c16e77e34bf.png)

以下のプロパティを設定します。モデルを事前にトレーニングしておき、さらにStudioがAutomation Cloudへ接続している必要があります。

* **プロジェクト名**： 選択肢から選ぶ（接続先のCommunications Miningに依存）
* **データセット名**： 選択肢から選ぶ（接続先のCommunications Miningに依存）
* **AIモデルのバージョン**： 選択肢から選ぶ（接続先のCommunications Miningに依存）
* **レコード**： 上記で作成したレコード
* **出力**： 予測結果（UiPath.CommunicationsMining.Activities.Predictions.Models.PredictResponse型）


## 予測結果を取り出す
「レコードを予測」アクティビティの出力から、予測されたラベルとエンティティ、さらには各予測に対する信頼度を抽出します。
正直使いづらい型だなあと・・・JSONで扱えないのですか？？

例えば、ラベルの信頼度を取り出すには以下のコードを呼びます（％表記、小数第1位で四捨五入する場合）。
```
Math.Round(cmResult.GetLabel(ラベル名).Probability * 100, 1, MidpointRounding.AwayFromZero)
```

こちらはエンティティを取り出す例です。
```
cmResult.GetEntity(エンティティ名).FormattedValue
```


# おわりに
アクティビティの使い方は以上です。そんなに難しくなかったと思います。
ちなみにアプリで作ってみるとこんな感じとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/74dc0c9b-d47b-23e0-5dce-d0cc4afa9d35.png)
Dockerの　no space left on device　エラーの対処法

# 背景
DockerFileからdocker buildを行いイメージ作成をする際に、容量不足で最後まで実行できないことが発生したため。

エラー時は下記メッセージが出る。
```
no space left on device
```

下記サイトを参考にさせていただきました。
https://rurukblog.com/post/Linux-disk-research/

# 確認方法

### 1.PCの容量を確認する。

設定からストレージを確認し容量が足りているか確認。ローカル環境でdockerを使用している場合はこれが原因の場合がある。



### 2.docker上の容量を確認

下記コマンドを実行。docker内のイメージ、コンテナ、ボリューム、ビルドキャッシュが表示される。
```
docker system df
```

実行すると下記のような表示になる。RECLAIMABLEは「使用されていない」イメージによって消費されるスペース。

```
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          1         0         5.068GB   5.068GB (100%)
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B
```


下記コマンドでイメージ、コンテナの詳細が確認できる。
```
#イメージの詳細を確認できる。
docker images
 
#コンテナの詳細を確認できる。
docker ps -a
```


### 3.ディスク使用量を確認

下記コマンドを入力するとディスク容量が確認できる。
```
df -h
```

実行結果は下記。
これを見ると/dev/xvda1　が使用領域が多いことがわかる。
```
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1        20G   13G  7.7G   62% /
```

### 4.容量が多いフォルダの特定

マウント位置が　”/”　なのでそこの容量一覧を取得するために下記コマンドを使用。
```
du -sh /*
```

Permission deniedが表示される場合は下記コマンドを使用。

```
sudo du -sh /*
```


```
6.6G	/var
```


同様の作業を繰り返す。
```
du -sh /var/*

#コマンド結果
4.9G	/var/lib
```
```
du -sh /var/lib/*

#コマンド結果
4.9G	/var/lib/docker
```

```
du -sh /var/lib/docker/*

#コマンド結果
4.9G	/var/lib/docker/overlay2
```

上記作業により、”/var/lib/docker/overlay2”の容量が大きいことが確認できる。

***overlay2フォルダはDockerコンテナのファイルシステムを管理するためのストレージドライバーの一つのようだ。***

dockerビルドが失敗した時も、ここに途中までダウンロードしたファイルなどの不要ファイルが溜まっていくことが起きていた。それにより容量不足になりエラーメッセージが表示されていた。



### 5.容量の削除

overlay2　配下の不要なファイルを削除するには下記コマンドを使用。

先ほどのRECLAIMABLEも削除対象である。

確認画面が出るがyesで実行。

```
docker system prune -a
```


実行すると、使用されていない容量が解放されてエラーが解消される。

再度、手順2を確認するとわかりやすい。

# まとめ
Dockerの容量不足の原因を調査した。結果的にエラーの際の不要ファイルがたまっていることが原因だった。
ARC171回答メモ

# 0.はじめに
　ABCに引き続き開催のARC。せめて1問回答をノルマに挑戦し
　なんとか1問AC頂けました。
　B以降は、異次元の難しさだったので、すっぱりあきらめがつきました。

　そんな感じでもレートは上がり、963という過去最高位となりました。
　このまま900台キープを当面の目標としたいと思います。
 

# 1.A - No Attacking
　チェスのこま置き問題。
　まぁ実際におくのではなく、理論上置ける値を算出するタイプです。

　段階的に考えていき最終的にACに至りました。
　【考え方基本】
 　　N<Aの時はどう考えても置けないから"No"
　【考え方１】
 　　・右上隅からルークを置いていき余った正方形に
   　　置けるだけポーンを置く
     　→これだと、N=5、A=2の時、B=6が最高
      　Ａ＋－－－
      　＋Ａ－－－
      　｜｜ＢＢＢ
      　｜｜＿＿＿
      　｜｜ＢＢＢ
       →例題すらうまくいかない。
　【考え方２】
    　・ルークを2列目から2行毎に置けば縦はうまるが
     　 横は、ポーンの移動スペースになるので結構置ける
     　→これだと、N=5、A=2の時、B=9置ける
      　｜｜ＢＢＢ
      　Ａ＋－－－
      　｜｜ＢＢＢ
      　＋Ａ－－－
      　｜｜ＢＢＢ
       →例題はすべてAC！
       　Aが置けるのは、（N-A）の2乗まで
        　上の例だと、9個！
    　・・・
     　結果は、ACWA7つでした。
      　まぁ、例えばAが１の場合とか全然当てはまりませんね。
　【考え方３】
　　・N-AがA以下の場合
   　　考え方２の例のように、Aを置いた行すべてを
     　ポーンの移動先にできるため、BはN-Aの2乗置ける
　　・N-AがAより大きい場合
     　まず、Bは横にN-A列並べられる。
       縦は、(N+1)//2行分並べられる。
     　ゆえに(N-A)*((N+1)//2)まで置ける。
　　・Bの値が上で求めた置ける数以下ならYes、でなければNo
  　として、ACとなりました。
  　　
　https://atcoder.jp/contests/arc171/submissions/50006398

以上
JavaScriptのイベント駆動について復習

# はじめに
自分は現在、大学3年生でフロントエンジニアとして、インターンをしている。
普段はTypeScript,Reactを使って開発を行っているので、今一度JavaScriptのイベントについて復習をしたい。（メモ用に書き残した）


# イベント駆動について

JavaScriptでイベントを設定する方法は2種類ある

- on~
- addEventListiner

### on〜を使うパターンについて

このパターンでは2つのイベントを同時につけることができない。
なぜなら、もし２つつけたとしても、１つ目のイベントは２つ目の方のイベントに更新されてしまうからである。

```jsx
style {
const button = querySelector.("button")
button.onclick　= () =>{ alert("clicked")}
}

<button onclick="alert("clicked")">click me</button>
```

### addEventListener

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener




```jsx
button.addEventListener("イベント名"、"実効する関数",{オブジェクト})

const event = button.addEventListener("click",
()=> {console.log("クリックされたお"),
{
//一度発火されたら、削除される。
once : true,
}})

このwindowは表示表域を指している
window.addEventListener
```

イベントの種類
https://developer.mozilla.org/ja/docs/Web/Events
```jsx
ユーザーインタラクションイベント
click: ユーザーが要素をクリックしたとき。
dblclick: ユーザーが要素をダブルクリックしたとき。
mousedown, mouseup: マウスボタンが押されたり離されたりしたとき。
mousemove: マウスが要素上を移動したとき。
mouseover, mouseout: マウスが要素に入ったり出たりしたとき。
keydown, keyup, keypress: キーボードのキーが押されたり離されたりしたとき。

UIイベント
load: ページや画像が完全にロードされたとき。
unload: ページがアンロードされるとき（例えば、別のページに移動するとき）。
resize: ブラウザウィンドウのサイズが変更されたとき。
scroll: スクロールが発生したとき。

フォームイベント
submit: フォームが送信されたとき。
change: フォーム要素の値が変更されたとき。
focus, blur: 要素がフォーカスを得たり失ったりしたとき。
タッチイベント
touchstart, touchmove, touchend, touchcancel: タッチスクリーンデバイスにおけるタッチ操作に関連するイベント。

```

### addEventListenerの３つ目の引数

```tsx
{
//一度発火されたら、削除される。
once : true,
//キャプチャリング
capture:true
//重たい処理でも、画面がカクつかないように
passive
}

```



 ### removeEventListener(”イベント”,関数を入れた定数)
 https://developer.mozilla.org/ja/docs/Web/API/EventTarget/removeEventListener

イベントを削除する

```jsx
button.removeEventListener("click",event)
```

**eventオブジェクト**

イベントはブラウザによって発火する。そして、そのイベントの情報を第二引数の関数で受け取ることができる。

```jsx
button.addEventListener("click",(event) => {
console.log(event)
})
```

### イベントの伝播するフェーズ

①キャプチャリングフェーズ：Windowオブジェクトから子の要素に下りていくフェーズ

②ターゲットフェーズ：イベントが発生した要素に到達するフェーズ

③バブリングフェーズ：イベントが発生した要素から親要素に上っていくフェーズ

#### バブリング

子要素で起こったイベントが親要素まで起きる

keydownなどのイベントによって、どの要素からバブリングが始まるかは異なる




https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Events

#### キャプチャリング

https://tcd-theme.com/2022/09/javascript-bubbling-capturing.html

windowオブジェクトから小要素の順番でイベントを実行していくこと。

第三引数で{capture : true}と設定することにより、キャプチャリングフェーズの時に発生する

```jsx
button.addEventListener("click",() => {
console.log("event")
},
{capture : true; }
)
```


### stopPropagation

キャプチャリング、バブリングをスキップする。

現段階のフェーズでストップする。例ターゲットフェーズでstopPropagationを使用すれば、キャプチャリングとターゲットだけ起きる。

### stopImmediatePropagation()

同じ要素にイベントをつけていたとしても、これを実行したイベントリスナで止まる。

### preventDefault()

ブラウザのデフォルトの挙動が起きるのを防ぐことができる。

```tsx
formElement.addEventListener("submit", (event) => {
    // submitイベントの本来の動作を止める
    event.preventDefault();
    console.log(`入力欄の値: ${inputElement.value}`);
});

formは、送信後リロードされてしまうが、
preventDefault()をつけることによって防ぐことができる。
```



### dispatchEvent()

JavaScript で DOMの要素に対してイベントをプログラム的に発火させるためのメソッド。このメソッドを使用することで、ユーザーのアクション（クリックやキーボード入力など）によって通常発生するイベントを、コード上から直接トリガーすることができます。
OutputDebugString 可変数で出力 メモ

`OutputDebugString関数`の使い方と、`printf`の様な可変数での`OutputDebugString`使い方については、以下にて紹介されている
link:[その３ デバッグウィンドウを知らないと大変です](http://marupeke296.com/DBG_No3_OutputDebugWindow.html)

しかし、今どき`printf系`は使用したくなかったので、`C++17`までは、可変引数をBoost Formatで無理矢理実現してきた

ただ、いつの間にかに`C++20`になっていて、`std::format`が導入されたので、`std::format`対応版の`OutputDebugString 可変数化`に修正したので、それのメモです
link:[C++20の文字列フォーマットライブラリ std::format](https://qiita.com/tetsurom/items/e660c7aaf008d8a1e904)

# 実行イメージと結果
任意の場所で、`自作関数MyOutputDbgStr(std::format記述)`を呼び出す
```C++:C++
    MyOutputDbgStr(TEXT("テストコード \n"));
    MyOutputDbgStr(TEXT("テストコード i= {} \n"), 1);
    MyOutputDbgStr(TEXT("テストコード i= {},{} \n"), 2, TEXT("msg"));
    //  MyOutputDbgStr(TEXT("テストコード i= {},{} \n"), 3 );     //{}が多いと、コンパイルは通るが、実行時例外エラー発生する。なお呼出し履歴を辿れば呼び出し元が分かる               
    MyOutputDbgStr(TEXT("テストコード i= \n"), 4 );           //{}がないときは、文字列のまま出力（引数無視）
    MyOutputDbgStr(TEXT("テストコード i={} \n"), 5, 100);     //{}が少ないときも、余剰引数無視
    //  MyOutputDbgStr(TEXT("テストコード i={},{} \n"), 6, "100");//引数の文字列がUNICODEでないので、コンパイルエラー
    //  MyOutputDbgStr("テストコード i={} \n", 7);             　 //UNICODEでないので、コンパイルエラー
```
VisualStudioでのデバッグ出力
![2024-02-05_115906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612873/bcd9b3a2-8c5e-31ee-72fc-cffccf4378ea.png)
※接頭部に呼び出し元ファイル、行数、関数名も自動追記しているので、Visual Studioデバッガならダブルクリックのジャンプ対応
# 環境
- Windows 10
- Visual Studio 2022 C++
- (デバッグ構成プロパティ－全般で、ISO C++ 20 標準 (/std:c++20)　)
- (デバッグ構成プロパティ－詳細で、Unicode 文字セットを使用する)

# 作成
1. デバッグ関数呼び出し元の情報を、接頭に`#define`追記する
※なお、従来、`__FILE__`、`__LINE__`、`__FUNC__`を使用していたが、最近のコンパイル？でうまく展開できなかったので？、`std::source_location`を使用した
（`L__FUNC__：定義されていない識別子です。`となる。define分けても駄目だった）
    ```C++:C++
    #define MyOutputDbgStr( ... ) MyOutputDbgStr_( std::source_location::current() , __VA_ARGS__ )
    ```
    <br>
    
1. 文字列を整形して`OutputDebugString`に投げる
    1. `std::format`を使って、接頭に`__FILE__(__LINE__):__FUNC__:`の文字列を作成する
    (この文字列の存在により、Visual Studioデバッガのダブルクリックジャンプに対応する、気がする)
    1. `std::string`を`std::wstring`に変換する
        UNICODE環境の為、`OutputDebugString`は`OutputDebugStringW`を呼び出すため。
        `ansi_to_wide`は、`std::string`を`std::wstring`に変換する自作関数(適宜実装、`static inline宣言必須？`)
    1. 残りの文字列(`Args`)の処理は、`std::format`に任せる
    1. `OutputDebugString`出力時は、厳密には、`mutex`した方がいいらしい？別途検討
    1. `OutputDebugString`出力する
    ```C++:C++
    template<typename... Args>
    void MyOutputDbgStr_(const std::source_location location,
    	std::wformat_string<Args...> s, Args&&... args)
    {
    	std::string fmt = std::format("{}({}):{}:", location.file_name(), location.line() , location.function_name() );
    	std::wstring wfmt = ansi_to_wide(fmt);
    
    	wfmt += std::format(s, std::forward<Args>(args)...);
    
    //	std::lock_guard<std::mutex> lock(mtx_OutputDebugStr); // mtxを使ってロックする
    	::OutputDebugString(wfmt.c_str());
    }
    ```
japanize_matplotlibがPython 3.12以降`ModuleNotFoundError`で動かない時の対処法

## 問題点と原因

```
ModuleNotFoundError: No module named 'distutils'
```

原因: `distutils`モジュールがPython 3.12では削除されたから。

## 解決法の提案

`distutils`の代わりに`packaging`モジュールを使うようにjapanize_matplotlib本体のソースをいじります。

```diff:japanize_matplotlib/japanize_matplotlib.py
import matplotlib
from matplotlib import font_manager
- from distutils.version import LooseVersion
+ from packaging.version import parse as parse_version

FONTS_DIR = 'fonts'
FONT_NAME = "IPAexGothic"
FONT_TTF = 'ipaexg.ttf'


def japanize():
    font_dir_path = get_font_path()
    font_dirs = [font_dir_path]
    font_files = font_manager.findSystemFonts(fontpaths=font_dirs)
-   is_support_createFontList = LooseVersion(matplotlib.__version__) < '3.2'
+   is_support_createFontList = parse_version(matplotlib.__version__) < parse_version('3.2')
    if is_support_createFontList:
        font_list = font_manager.createFontList(font_files)
        font_manager.fontManager.ttflist.extend(font_list)
```

この件について、issueを立ててPRを送っていますが、作者様からの今のところ返答はありません。

https://github.com/uehara1414/japanize-matplotlib/issues/26

https://github.com/uehara1414/japanize-matplotlib/pull/27

有志が対応した版リリースしているので、こちらを使っても良いかもしれません。

https://github.com/ciffelia/matplotlib-fontja
gitブランチが壊れた時の対処法

# ブランチが壊れてしまった

masterブランチに移ろうとしたら、以下のエラーが出てしまい、移動することができなくなってしまった。

`git switch master
fatal: bad object refs/heads/mobileToPC 2`

これは、`mobileToPC 2`の名前が問題で、スペースが含まれていることが問題であった。
Gitではブランチにスペースを含めることができない。</span>そのため、このブランチを削除する必要がある。

以下のコマンドをうち、ブランチを削除する。
`git update-ref -d "refs/heads/mobileToPC 2"
`

*このコマンドを実行する時は、削除するブランチではないブランチで行うことがマスト！




#### gitブランチが壊れた時、参考になる記事

https://stackoverflow.com/questions/33012869/broken-branch-in-git-fatal-your-current-branch-appears-to-be-broken/48716529#48716529


https://copyprogramming.com/howto/broken-branch-in-git-fatal-your-current-branch-appears-to-be-broken#broken-branch-in-git-fatal-your-current-branch-appears-to-be-broken
CFIも直した

CFIの書き込みもうまくいってないので調べてみました。

確認方法はmx25lの時と一緒です。

やはり書き込んでもハッシュが一致しません。

何度書くと、そのたびハッシュ値が違うので、タイミング問題のようなきがします。

おそらく昔は動いていたのが、なんらかの理由で動かなくなったものと思われます。

FreeBSDのcfiのコードはsys/dev/cfiにありJuniperから提供されたものでコピーライトが2007で入っています。

NetBSDのcfiのコードはsys/dev/norにあり、独自に実装したもので、コピーライトが2011とちょっと新しいです。

cfiのコードはIntel方式とAMD方式で処理が実装されていて、FreeBSDは同じソース内にswitch()などで処理を変えています。NetBSDはAMD方式を別ソースファイルとしているようです。

NetBSDの人がちょっといけてないのはAMD方式のソースファイルがcfi_0002.cとかになっていて、0002はAMDのメーカー番号なので、分かる人にはわかりますがcfi_amd.cとか明示的なファイル名にしたほうが良いです。

以前FreeBSDのコードでresetがコマンド一つの実行だったのですが、上手く動かないデバイスがあり、NetBSDなどを見るとコマンド二つ実行していたので、同じようにしました。

NetBSDのコードには書き込みの処理が未実装のように見えます。

FreeBSDのコードはイレースして書き込む時と、イレースはせずに書き込む時があるようです。ロジックはなんだかよく分かりません。

とりあえず動くようにしてみました。

https://github.com/ZRouter/freebsd-src/commit/477cb1845916d336b61620afd5064abd226f0be1

u-bootをオペレーションして書き換えるのは面倒なので、FreeBSDから書き換えのため、必要でした。

以前はできていたのが、突然出来なくなったようなきがするので、このパッチも突然動かなくなる可能性があります。またこのパッチは4M Flashでうごいていますが、8Mとか32Mではダメでした。

SILICON IDをブーとログに出すようにしてみました。
【06】Next.js app routerのチュートリアルやってみる(DBのセットアップ)

# はじめに

Next.js app routerのチュートリアルの第６章のアウトプットします。

https://nextjs.org/learn/dashboard-app/setting-up-your-database

<details><summary>前の記事</summary>

【01】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/af58da3d20cbc790e767

【02】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/edf450b3ee135e83d1e8

【03】Next.js app routerのチュートリアルやってみる
https://qiita.com/naoyuki2/items/612221eac233aa9cbb74

【04】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/62f9beccbfe36eaf7f90

【05】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/8b71b1d1df7c9435a9c9

</details>

# 第６章 データベースのセットアップ

この章では下記を学習しました。

- プロジェクトを`GitHub`にプッシュする
- `vercel`にプロジェクトをデプロイする
- `Postgresデータベース`をセットアップする
- データベースに初期データを入れる

今回やったことは私が前に記事を書いたことがあったので、この記事には書きません。

見たい方は下記のリンクからお願いします。

https://qiita.com/naoyuki2/items/e974c630c6cbd3c55254

# 知らなかったこと

上の記事では触れていないことがいくつかあったので書きます。

### Vercel Postgres SDK

```
npm i @vercel/postgres
```

このコマンドで、`Vercel Postgres SDK`というものをインストールできるそうです。

具体的な使い方は次回以降出てくると思います。

### データベースをシードする

データベースにおける初期データのことをシード(種)というらしいです。

長いので割愛していますが、下記のように`JavaScript`ファイルに`SQL`を記述することでシードデータを作ります。

```js:seed.js
const { db } = require('@vercel/postgres');
const {
  invoices,
  customers,
  revenue,
  users,
} = require('../app/lib/placeholder-data.js');
const bcrypt = require('bcrypt');

async function seedUsers(client) {
  try {
    await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`;
    // Create the "users" table if it doesn't exist
    const createTable = await client.sql`
      CREATE TABLE IF NOT EXISTS users (
        id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        email TEXT NOT NULL UNIQUE,
        password TEXT NOT NULL
      );
    `;

    // ...
    
```

そして、作成したシードデータを挿入するために、下記のように`package.json`を書き換えて、

`npm run seed`でシードデータの挿入が完了です。

```diff_json:package.json
"scripts": {
  "build": "next build",
  "dev": "next dev",
  "start": "next start",
+ "seed": "node -r dotenv/config ./scripts/seed.js"
},
```

# おわりに

次はデータフェッチです。

# 次の記事

https://qiita.com/naoyuki2/items/2c2da0f8071e60454679