OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】AWS Backupでk3sクラスタを復元する時の注意点

お試しk3sクラスタをAWS EC2上で運用しています。暫く使わないので、AWS Backupを使ってバックアップ・レストア(復元)を試しました。
AWS Backupは大変便利で、EC2をバックアップするとついでにアタッチされたEBSボリューム一緒にバックアップしてくれます。ですが、私が試しに使ってみると、問題になる点がいくつかありました。
* 復元したEC2インスタンスには元のプライベートIPアドレスが割り振られず、違うアドレスになってしまう。
* 復元したEC2インスタンスにSSHでログインしようとすると、「SSHのホスト鍵が変わっている」と盛大に叱られてしまう。
* k3sで使う証明書を作り直す必要がある。

# 元のプライベートアドレスを保持してEC2インスタンスを復元する

バックアップした時と同じプライベートIPアドレスにしてあげないと、k3sクラスタが復元後にまともに動作しなくなります。しかし何も考えずにAWSコンソール上で復元すると勝手に違うアドレスに割り振ってしまいます。
元のプライベートIPアドレスを保持して復元する方法は、以下に書いてあります。

https://repost.aws/ja/knowledge-center/backup-change-retain-ip-ec2-restore

ですが、以下のQiita記事の方が分かりやすいでしょう。

https://qiita.com/sakai00kou/items/77eafd4600e96ef3c828

二点だけ。
メタデータ取得する時、`--output json`を指定してあげないと、json形式でメタデータを取れなかったのですが、私だけでしょうか。
もうひとつ取得したメタデータを編集し、不要な部分を削るのですが、私の場合上記記事の内容にプラスして
`\"SecondaryPrivateIpAddressCount\":0`
も削除する必要がありました。これを残していると復元が失敗し、「`SecondaryPrivateIpAddressCount`の内容は正の数を入れる必要があります。」と叱られました（AWS Backupの復元ジョブを確認すると分かります)。

# ホスト鍵が変わってしまう場合の対策
EC2インスタンスの復元に成功したのですが、SSHで使うホスト鍵は変わってしまうようです(メカニズムは分かりませんw)そこで、以下のQiita記事に基づいて処置をしました。

https://qiita.com/hnw/items/0eeee62ce403b8d6a23c

こちらは簡単に、
```
$ ssh-keygen -R example.com
```
を行って解決しました。


# k3s証明書の作り直し
k3sの証明書の作り直しも必要でした。参考記事は手前味噌ですが、

https://qiita.com/yasuyuki_terashi/items/71d7a0bb4bbb43f582dd

これを見ながら処置しました。「キャッシュされた証明書の削除」は多分不要かな、と思ってやりませんでしたが。

# まとめ
その他、k3s自体を新しく入れなおしたら、ローカル側(Windows10)のkubectlが古いと文句を言われたり色々あったのですが、これはまた別の話だと思います。

AWS Backupは便利だな、と思う反面、ipアドレスまで簡単に元通りになる訳ではない、とか、証明書類の作り直しなどが必要だったり、面倒な点はいくつかありました。
とは言え、私の場合勉強用・実験用なので使わないがあります。その間、EBSボリュームなどをそのままにしておくのは料金がもったいない。使わない時はインスタンスごと全て削除してしまい、必要な時に復元する運用としたいです。
これで大幅に料金が節約できる、、、、、、はず！？
Databricksの新しいSQLエディター

こちらの新機能です。

https://docs.databricks.com/ja/sql/user/sql-editor/new.html

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

# 有効化

プレビューで**Allow users to enable the new SQL editor for queries**がオンになっていることを確認します。

![Screenshot 2024-10-12 at 14.34.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c8f7578f-cf3b-5f7f-d865-9940039af9bb.png)

SQLエディターで**New SQL editor**をクリックし、オンにします。

![Screenshot 2024-10-12 at 14.33.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f7e403d7-b5ea-6059-d261-6a1b9d40c27f.png)

![Screenshot 2024-10-12 at 14.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/44521b02-56db-8d39-0a1b-763a70d20222.png)

# 複数ステートメントの実行結果のブラウズ

複数のSQLを実行した際、画面下部でそれぞれの実行結果を参照することができます。

![Screenshot 2024-10-12 at 14.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/990211d8-00c1-8f40-b38e-0eec344a45bf.png)
![Screenshot 2024-10-12 at 14.40.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3a446e5d-2a9d-2181-458e-cb934c94d02f.png)

# SQLへのコメント

ノートブックではサポートされていた機能でしたが、SQLエディタでもサポートされました。

![Screenshot 2024-10-12 at 14.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fa985f0d-bbd1-9202-3733-95c691749796.png)

# バージョン管理

これもノートブックでサポートされていた機能のです。嬉しい。

![Screenshot 2024-10-12 at 14.41.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/aa4096f0-6ca8-fe05-3b01-af812a63fcb9.png)

# 同時参照、同時編集

これもノートブックからの輸入。SQLでもリモートでのペアプログラミングが可能に。

![Screenshot 2024-10-12 at 14.44.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/07c83577-db33-d1e7-368d-47ee8c2c26bb.png)

# エディタのテーマ

こちらもノートブックと同様にテーマ設定が反映されるようになりました。

![Screenshot 2024-10-12 at 14.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/06f0ded1-693b-e0b9-2581-6d4e87a762dc.png)


ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
在宅ワークで生産性は下がるのか　反事実を対象とする RCT(ランダム化比較実験)

 
　9/16、米アマゾン・ドットコムが、世界の社員に週5日の出社を義務化した。アマゾンは従業員を19年から22年のコロナ禍の間に、約80万人から160万人に増やしている。表向きでは、在宅勤務により企業文化に緩みが出ているので、その引き締めを図るためだとしている。

　ここで、在宅ワークによって生産性は下がるのかをみていきたい。もちろん、アマゾンは企業文化の緩みを理由に出社を義務化したので、生産性における検証はアマゾンとは関係がない。ただし、米国の大手が出社を義務付けたことにより、日本にもその波が来る可能性があるので、そのための判断材料として頂きたい。

　結論から言うと、週3日の出社でも生産性は維持されるという研究結果が出ている。この研究は米スタンフォード大学や香港中文大学などが実施したもので、英科学誌「ネイチャー」に掲載されている。内容は以下の通りである。

　中国の旅行予約サイト「トリップドットコム」の事務職員とIT職員の計1612人を対象に、2021年8月から22年1月までRCT（ランダム化比較試験）を実施。参加者を2グループに分け、片方のグループに平日5日間の出社を指示、もう片方のグループに週3日出社する指示を出した（水曜、金曜が在宅）。

　結果、完全出社と週3日の出社で、仕事の生産性に有意な違いはみられなかった。具体的には、各従業員におけるパフォーマンスの評価や昇進率、書いたソースコードの行数などに差異がなかった。また、パフォーマンスの評価の下位項目である「イノベーション」「リーダーシップ」「開発」「遂行力」などの全9要素でも同様の結果が出た。

 　また、勤務では離職率が低いことも分かった。期間中に週5日の出社のグループでは7.2%が離職したが、週3日のグループでは4.8%と3分の2にとどまった。

　
　このRCT（ランダム化比較試験）について少し掘り下げておきたい。RCTとは、研究の対象者をランダムに複数のグループに分け、特定の介入の効果を検証する科学的研究方法であり、臨床試験でよく使われる手法だ。この比較方法は、特定の介入の効果を調べる際に、その介入を行わなかったらどうなるかを検証できる点が優れている。この「〇〇をしなかったら、起こっていたかもしれないこと」を反事実と呼ぶ。

　RCTによって、直感的な判断を覆した例を一つ挙げる。

　アメリカはアフリカの子供達に対して、学力の向上を目標に、教科書を無料で配布していた。配布された学校では、テスト成績が向上する結果が得られた。これを聞くと、教科書の配布には効果があったと思うかもしれない。しかし、この結果には、反事実である「教科書を無料で配布しなかった場合」の結果が抜けているのだ。そこで、ある学者のグループがRCTを行ったところ、教科書を無料配布した学校の成績は、配布しなかった学校の成績と変わらないという結果が出た。原因は、教科書が英語で書かれていたため、アフリカの地方の子供達にとって第3言語である英語は理解しづらかったのである。RCTの比較によって、アフリカへの無意味とも言える開発援助のプログラムがあることが明らかになった。

　話を元に戻す。RCTによる在宅ワークでも生産性が落ちないという結果は、在宅ワークを今後も取り入れたいと考えている会社にとって、適切な判断材料となるだろう。私も普段はリモートで仕事をしており、生産性が下がっているとは感じられない。むしろ、同僚に話しかけられたり、不用な飲み会に参加させられることがないので、出社してる時より仕事に集中できている。出社義務の波は、太平洋で温帯低気圧（波なので温帯低気波）になって欲しいと願う。

参考文献
日本経済新聞「週3出社でも生産性維持、離職率も3分の2に　米大研究」2024年9月23日
https://www.nikkei.com/article/DGXZQOSG084450Y4A700C2000000/

日本経済新聞「Amazon、社員に週5日出社義務付け　米巨大テックで初」　2024年9月17日
https://www.nikkei.com/article/DGXZQOGN163PR0W4A910C2000000/

Webサイト：ランダム化比較試験、無作為化（比較）試験、RCT：https://ez2understand.ifi.u-tokyo.ac.jp/terms/terms_03/#:~:text=%E3%80%8C%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E5%8C%96%E6%AF%94%E8%BC%83%E8%A9%A6%E9%A8%93%E3%80%8D%E3%81%A8,%E9%AB%98%E3%81%84%E8%A9%A6%E9%A8%93%E3%81%A8%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82

失敗の科学　マシュー・サイド
Reactで画像を挿入する際に躓いたところ

Reactでポートフォリオを作成する際に少し時間がかかってしまったので試したことを備忘録としてまとめる

<h2>どんなエラーが出るか</h2>
まず画像を使用するための設定をしないときに出たエラーは下記

![スクリーンショット 2024-10-12 14.33.16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822116/698cd759-d0ba-4dbe-6d7a-568dedeff8f0.jpeg)

<h2>試したこと</h2>
・画像のパスを確認

・画像ファイルを配置しているフォルダがsrc配下にあるか確認

・ブラウザのキャッシュをクリア

・TypeScriptに画像ファイルの型を教える

エラーの情報的には4つ目のものが原因だったようで、対応したところ画像がうまく読み込めるようになった。

1.プロジェクトのルートにsrc/custom.d.tsというファイルを作成
2.次のように記述
```
declare module '*.jpg' {
  const value: string;
  export default value;
}
declare module '*.png' {
  const value: string;
  export default value;
}
```

3.webpack.config.tsにfile-loaderの設定を追加
```
npm install file-loader --save-dev
```
4.Webpackの設定にfile-loaderを追加
```
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]', // 出力されるファイル名を指定
            },
          },
        ],
      },
    ],
  },
};
```

以上で再度ビルドしたところ、うまく読み込めるようになりました。
WSL(Ubuntu22.04)環境でDockerが動作しない問題 "Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running"


## 作業概要
WSL環境構築中にDockerが起動しない問題が発生しました。
普段はVagrantで環境構築を行っていますが、今回は学習も兼ねてWSLを使用してみました。
>エラー発生まで完了している作業
  >>WSL(Ubuntu22.04)インストール
  >>Docker、docker-composeもインストール
## エラー内容
``docker-compose build``, ``docker ps``などのDockerコマンドを実行したら以下のエラーが発生。

````bash
$ docker-compose build
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running
````
いつものようにDockerが起動していないだけだろう..と思い``sudo service docker start``コマンドを実行したものの解決せず・・・。

## 調査
色々記事を漁っていると以下の記事を発見

https://qiita.com/motoJinC25/items/c6fbb10f00230f6a5a97

どうやらネットワーク関連の問題ぽかったです。

## 原因
Ubuntu(22.04)は**iptables-nft**とかいうパケットフィルタリング？のようなものをデフォルトで使用しているみたいでこいつが悪さしていたみたいです。

## 解決策
問題の**iptables-nft**を手動で別のものに切り替えることで解決するみたいなので早速実行してみましょう。
``sudo update-alternatives --config iptables``コマンドを実行してください。
すると、表示が対話モードになります。
そこから**iptables-legacy**というものに切り替えたいので、それに該当する**1**を入力してください。
````bash
$ sudo update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

  Selection    Path                       Priority   Status
------------------------------------------------------------
* 0            /usr/sbin/iptables-nft      20        auto mode
  1            /usr/sbin/iptables-legacy   10        manual mode
  2            /usr/sbin/iptables-nft      20        manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in manual mode
````

入力したら``sudo service docker start``を実行するとうまくいくはずです。

## 参考記事
https://qiita.com/Muusann/items/6696601f03f80b2e8322

https://blog.ecbeing.tech/entry/2021/09/07/150000
FREDの経済指標をPythonの標準ライブラリで取得

FREDはセントルイス連邦準備銀行の提供する経済統計データのデータベースである。ここから経済指標（今回は米国の失業率）をPythonで取得することを試みる。「FRED python 取得」などとググってみるとpandas_datareaderやその他のライブラリを使用している例が見受けられたが、FREDのAPIのドキュメントを読んでみるとごく普通のシンプルなAPIだったので、標準ライブラリのurllibを使う無難な手法を採用した。

まずはHPにアクセスしてアカウントを作成し、API Keyを取得する。API Keyのページはアカウント作成後ページ右上の三本線 -> Myaccount -> API Keysで到達する。

https://fred.stlouisfed.org/

API Keyを取得できたら下記のコードの`API_KEY`の部分を書き換えて実行する。失業率ではなく他の指標を取得したい場合はその下の`SERIES_ID`を変える。標準ライブラリしか使わないので事前に`pip install hoge`等は不要。
```python
import urllib.request
import json

def main():
  API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  SERIES_ID = "UNRATE"
  URL = f"https://api.stlouisfed.org/fred/series/observations"
  params = {
    "api_key": API_KEY,
    "file_type": "json",
    "series_id": SERIES_ID
  }
  req = urllib.request.Request(f"{URL}?{urllib.parse.urlencode(params)}")
  with urllib.request.urlopen(req) as res:
    data = json.loads(res.read().decode("utf-8"))
  # 取得した値がデフォルトではstr型なのでfloat型float型に変換する
  for d in data["observations"]:
    d["value"] = float(d["value"])
  # 綺麗に表示
  import pprint
  pprint.pprint(data)
  
if __name__ == '__main__':
  main()
```
実行結果:
```sh
{'count': 921,
 'file_type': 'json',
 'limit': 100000,
 'observation_end': '9999-12-31',
 'observation_start': '1600-01-01',
 'observations': [{'date': '1948-01-01',
                   'realtime_end': '2024-10-04',
                   'realtime_start': '2024-10-04',
                   'value': 3.4},
                  {'date': '1948-02-01',
                   'realtime_end': '2024-10-04',
                   'realtime_start': '2024-10-04',
                   'value': 3.8},
                  {'date': '1948-03-01',
                   'realtime_end': '2024-10-04',
                   'realtime_start': '2024-10-04',
                   'value': 4.0},
（====================== 中略 ======================）
                  {'date': '2024-09-01',
                   'realtime_end': '2024-10-04',
                   'realtime_start': '2024-10-04',
                   'value': 4.1}],
 'offset': 0,
 'order_by': 'observation_date',
 'output_type': 1,
 'realtime_end': '2024-10-04',
 'realtime_start': '2024-10-04',
 'sort_order': 'asc',
 'units': 'lin'}

```
# 参考
FREDのAPIのドキュメント:

https://fred.stlouisfed.org/docs/api/fred/#
Parseの使い方（C#初心者エンジニア向け）

C#基本の文法を初学者でもわかりやすく、簡潔に解説したいと思います。

Parceは一言で言えば型変換をしてくれる呪文です。

◯.Parse(✖️✖️✖️✖️✖️✖️✖️✖️);

この場合は、✖️✖️✖️✖️✖️✖️✖️✖️を◯型に変換するという意味です。


int.Parse(Console.ReadLine());

例えば、このコードがあった場合は

Console.ReadLine(入力された文字列をそのまま出力する呪文）を

int型に変えて出力しているということになります。
blastengineのC# SDKを使って一括配信メールの送信を行う

[blastengine（ブラストエンジン）]()はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先に届けられます。

現在、C#向けに、blastengine SDKを開発しています。.NET6以上を対象としているので、macOSを含め幅広い環境で実行できるはずです。

今回は、バルクメール（一括配信メール）の作成と送信方法を解説します。

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg)

そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png)

## 必要な情報について

SDKを使う上で必要なのは、先ほどのAPIキーとユーザIDになります。

## SDKのインストール

SDKはNuGetでリリースしています。Visual StudioのNuGetパッケージの管理よりインストールしてください。

[NuGet Gallery \| Blastengine](https://www.nuget.org/packages/Blastengine/)

## 初期化

先ほどのAPIキーとユーザIDを使って初期化します。

```csharp
new Blastengine.Client("YOUR_USER_ID", "YOUR_API_KEY");
```

## バルクメールオブジェクトの作成

バルク（一括配信）メール送信用の、バルクメールオブジェクトを作成します。

```csharp
var bulk = new Blastengine.Bulk();
```

## 必要な情報をセットする

続けて、必要な情報をセットします。

```csharp
bulk.Subject = "テストメール from C#";
bulk.TextPart = "これはテストメールです to __name__";
bulk.HtmlPart = "<h1>これはテストメールです to __name__</h1>";
bulk.From = new Blastengine.From("info@example.com", "Admin");
```

## 保存する

情報をセットしたら、まず `Begin` メソッドを使って保存します。

```csharp
var bol1 = await bulk.Begin();
```

## 宛先データをセットして更新する

次に宛先の情報をセットして、更新します。

```csharp
// 置き換えコードあり
bulk.To.Add(new Blastengine.BulkTo("user1@example.jp", new List<Blastengine.InsertCode>() {
	new Blastengine.InsertCode("name", "User1")
}));
// 置き換えコードなし
bulk.To.Add(new Blastengine.BulkTo("user2@example.jp"));

// 宛先を登録
await bulk.Update();
```

## 送信する

送信は `Send` メソッドを使います。引数として、配信予定日時を指定できます。

```csharp
// 即時配信
var res = await bulk.Send();
// 予約配信（10分後）
var res = await bulk.Send(DateTime.Now.AddMinutes(10));
```

## コードについて

コードはGitHubにアップしてあります。ライセンスはMIT Licenseになります。

[blastengineMania/blastengine-csharp: blastengineのC# SDKです](https://github.com/blastengineMania/blastengine-csharp)

## まとめ

blastengineには他にも即時メール配信を行ったり、添付ファイル付きのメール配信機能などもあります。これらの機能も随時実装していきますので、ぜひ皆さんのシステム開発に役立ててください。

[エンジニア向けメール配信システム「ブラストエンジン」](https://blastengine.jp/)
【Python】クイックソート

## 概要
クイックソートは、高速かつ効率的なソートアルゴリズムの一つで、分割統治法（Divide and Conquer）に基づいています。クイックソートは、リストをピボットを基準に小さな部分に分けていき、それぞれの部分を再帰的にソートすることで、全体のリストを整列させます。
平均計算量は O(n log n)であり、大規模なデータセットにも適しています。最悪の場合は O(n^2) になりますが、通常の使用では非常に高速です。

クイックソートは、以下の手順で動作します：
1. 配列の中から基準となるピボットを選びます
2. ピボットより小さい要素と大きい要素に配列を分けます
3. 各部分配列に対して再帰的にクイックソートを適用します

この記事では、Pythonでのクイックソート実装方法について説明します。

## コード
以下がPythonでのクイックソートの実装例です。

```python
def partition(arr, low, high):
    # 小さい要素のインデックスを管理
    i = low - 1
    # ピボットを最後の要素に設定
    pivot = arr[high]
    for j in range(low, high):
        # 現在の要素がピボットより小さいか等しい場合、交換する
        if arr[j] <= pivot:
            i += 1
            # 要素をスワップ
            arr[i], arr[j] = arr[j], arr[i]
    # ピボットを正しい位置に移動
    arr[i+1], arr[high] = arr[high], arr[i+1]
    # ピボットの位置を返す
    return i + 1


def quick_sort(arr):
    def _quick_sort(arr, low, high):
        if low < high:
            # パーティション実行
            partition_index = partition(arr, low, high)
            # 左側を再帰的にソート
            _quick_sort(arr, low, partition_index - 1)
            # 右側を再帰的にソート
            _quick_sort(arr, partition_index + 1, high)

    # リスト全体に対してクイックソートを実行
    _quick_sort(arr, 0, len(arr) - 1)
    return arr


# サンプルの使用例
if __name__ == "__main__":
    sample_data = [10, 7, 8, 9, 1, 5]
    print("ソート前:", sample_data)
    sorted_data = quick_sort(sample_data)
    print("ソート後:", sorted_data)
```

### 実行結果
上記のコードを実行すると、次のような結果が得られます。

```
ソート前: [3, 6, 8, 10, 1, 2, 1]
ソート後: [1, 1, 2, 3, 6, 8, 10]
```

### 詳細
partition関数は、リストの最後の要素をピボットとして選択し、それを基準にリストを2つの部分に分割します。ピボットより小さい要素は左側、大きい要素は右側に配置されます。
_quick_sort関数は、partition関数によって分割された部分配列を再帰的にソートします。

## 参考
https://www.udemy.com/course/python-algo/?couponCode=KEEPLEARNING
[tips][vscode] cpp version setting

# Vscodeのcpp version

```cpp
std::set<char> s = {'a', 'b', 'c'};

// キー2の要素が含まれているか
if (s.contains('b')) {
  std::cout << "contain" << std::endl;
} else {
  std::cout << "doesn't contain" << std::endl;
}
```

`contains`関数はcpp+20から導入された関数です。vscodeの設定がc++20以上出ないと次のようなエラーを出力します。
![スクリーンショット 2024-10-12 14.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/0607a840-d75f-151a-5c23-2797dbdd9866.png)


同じこと言ってる人いた。
https://stackoverflow.com/questions/69456226/class-stdmap-has-no-member-contains-in-visual-studio-code

ただし、code runnnerに次のコマンドを指定してる場合は、`-std=c++20`としてコンパイラがコンパイルするので実行されます（当たり前か）
```
g++ -std=c++20 hoge.cpp -o hoge
```

```cpp
#include <iostream>

int main() {
  std::cout << __cplusplus << std::endl;
  return 0;
}
```


# Vscodeでcppのversionを設定する方法

設定もしくはSettingを開く。
![スクリーンショット 2024-10-12 14.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/c9ed7bf5-a006-a56b-e826-6103e370f332.png)

`cppStandard`を検索。

![スクリーンショット 2024-10-12 14.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/fd6fd806-f059-8453-78e6-80bc8dbc939a.png)

pulldownから、ユーザー、ワークスペース両方の設定を`c++20`に選択。


これでコンパイルエラーが綺麗に消えます。めでたし。

## intelliSenseMode

https://code.visualstudio.com/docs/cpp/configure-intellisense
OpenStudioのチュートリアルを試してみる　その17

# 1. はじめに
先日[OpenStudioのチュートリアルを試してみる　その16](https://qiita.com/bebebefu/items/33016eff3e0b13969cc6)の記事にて、以下のリンクの動画シリーズで紹介されているOpenStudioを用いたfire station（消防署）のモデル作成・シミュレーションの18番目の動画についての手順を追っていきました。今回はこの動画シリーズの19番目の動画の手順を追っていきたいと思います。

https://www.youtube.com/playlist?list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU

# 2. 実施環境
CPU: CORE i5 8th Gen
メモリ: 8GB
OS: Windows 11 22H2

# 3. 手順（HVAC Systemsの設定）
本記事で内容・手順を追った動画（上記動画シリーズの19番目の動画）

https://www.youtube.com/watch?v=NQ4FpKrpeD8&list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU&index=19

## 3.1 Thermal ZonesのBaseboard Convective Electricの設定
以下の図で赤枠で囲んだ"Thermal Zones"のタブをクリックします。
そして画面右のLibraryのタブで、以下の図で黄枠で囲んだ"Baseboard Convective Electric"の中の"EWH-01"を以下の図で青枠で囲んだName"TZ-106"の"Zone Equipment"ところにドラッグアンドドロップします。なお、動画の中では"Elec Baseboard"から設定を変更して"EWH-01"を作成していますが、私が読み込んだ環境では既に"EWH-01"がありました。

![EWH01のドラックアンドドロップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/eb0c3afc-423d-38f1-d021-d105c136611b.png)

続けてName"TZ-105"の"Zone Equipment"ところに"EWH-01"をコピーしてきます。
コピー方法としては以下の図で赤枠で囲んだところにチェックを入れて"TZ-105"のところが青帯で選択されたことが確認できたら、"EWH-01"（黄枠部分）をクリックした後に、"Apply to Selected"ボタン（緑枠部分）をクリックすることでコピーできます。なお、名前は"EWH-02"に変えます。

![オブジェクトコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/6d1cb73b-1679-c4dc-ef6c-a3c5b3003c85.png)

## 3.2 Thermal ZonesのUnit Heaterの設定
画面右のLibraryのタブで、以下の図で赤枠で囲んだ"Unit Heater"の中にあるオブジェクトを、以下のTermal Zoneの"Zone Equipment"のところにドラッグアンドドロップして設定していきます。

- TZ-102(Termal Zone): EWH-04(Unit Heater)
- TZ-103(Termal Zone): EWH-03(Unit Heater)
- TZ-105(Termal Zone): EWH-03(Unit Heater)
- TZ-108/109(Termal Zone): EWH-0506(Unit Heater)
- TZ-110(Termal Zone): EWH-07(Unit Heater)

以下の図が設定後の画面です。

![EWHの設定1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/96e592bf-3a06-9bdc-876e-22c3e86e6292.png)

![EWHの設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/0360bf6b-cdd5-fff1-9365-c078de25b6af.png)

## 3.3 Thermal ZonesのPTHPの設定
画面右のLibraryのタブで、以下の図で赤枠で囲んだ"PTHP"の中にあるオブジェクトを、それぞれ以下のTermal Zoneの"Zone Equipment"のところにドラッグアンドドロップして設定していきます。

- TZ-107(Termal Zone): FC-04(PTHP)
- TZ-110(Termal Zone): FC-01(PTHP)

以下の図が設定後の画面です。

![PTHPの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/ff17002e-fb48-4482-e3cf-5a6370abbb6d.png)

# 4. まとめ
今回はかなり短いですが、とりあえずここまでも特にエラーなく進めることができました。
次回は動画シリーズの20番目：https://www.youtube.com/watch?v=GL_fFPGSeAs&list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU&index=20 を実施していきたいと思います。
Amazon SageMaker と GitHub の連携

### 手順
1. Amazon SageMaker ドメインへの GitHub リポジトリの登録
    1. Amazon SageMaker -> ドメイン -> ドメインの詳細 -> 環境 に遷移
    2. ドメインの推奨コードリポジトリより「アタッチ」ボタンを押下
    3. JupyterServer アプリ・JupiterLab アプリそれぞれに対象の Git リポジトリの URL を登録

2. Code Editor 内でのリポジトリのコードの取り込み
    1. Amazon SageMaker CodeEditor の対象ブックを開く
    2. Explorer より「Clone Repository」を選択
    3. GitHub の認証を通し、対象のリポジトリを選択して Clone

3. git config の設定
    1. GitHub のユーザー名、メールアドレスを設定する
```$ git config --global user.name "your name"```
```$ git config --global user.email your.email@example.com```

### 参考記事・資料
- https://zenn.dev/ncdc/articles/de2364127094e2
- https://docs.aws.amazon.com/sagemaker/latest/dg/studio-git-attach-console.html
一週間の簡易ログローテーション

### サンプル

こういうのでいい。

```
0 8 * * * ruby main.rb > $(date +"\%a").log
```

これでデイリーのバッチのログファイルが曜日名で作られる。
`Sat.log`
みたいなファイル名。

### なぜ必要か

- デイリーの集計やらチェックみたいな簡易な日時バッチはある
- トラブった時だけログをみたいというようなログ
- それだけのためにログローテーションを埋め込むのは大げさ
- とはいえトラブった時用のログなのでデバッグログ的にいっぱい情報は詰め込みたい
- 単純な追記だとストレージを圧迫する
- ログサーバに飛ばすのも大げさ
- ということで曜日をファイル名すれば一週間で上書きできる
- 一週間何も気づかないなら業務として破綻しているので、これで十分

### cronで書く時の注意

cronでは%をエスケープしないといけないので、曜日を取り出す際には、

```
date +"%a"
```
ではなく
```
date +"\%a"
```
と記述する必要がある。
【VBA】システム日付を西暦日付表示に変換する

# はじめに
Excelでシステム日付を西暦日付表示に変換する必要がったので、マクロを実装しました

## マクロ実行前のデータ
マクロ実行前のデータ画像は下記の通りです

![test1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/15553843-1cc9-a55f-1be4-f7720a8aeb14.jpeg)

## 実装したマクロ
実装したマクロのソースコードです。

```VBA
Sub change_date()
    'システム日付変数の定義
    Dim date_data As Variant
    '西暦日付変数
    Dim ans_date As Date
    'ワークシートオブジェクト変数
    Dim ws As Worksheet
    'ws変数の定義セット
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    'カウント変数
    Dim i As Long
    'データの最終行を取得
    Dim end_row_num As Long
    end_row_num = ws.Cells(Rows.Count, 4).End(xlUp).Row
    'ループで回して西暦に変換する
    For i = 4 To end_row_num
        date_data = ws.Cells(i, 4)
        ans_date = DateSerial(1900, 1, 1) + date_data - 2
        ws.Cells(i, 5).Value = ans_date
    Next i
End Sub
```

## 実行結果
実行結果は下記の画像です。

![test2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/7191e2c7-4034-5013-5a66-1b3d497f3a7f.jpeg)


# 最後に
シリアル日付の変換について記事にしました。
pygameでRPGをつくってみる９


[記事全体の目次へ移動](https://qiita.com/hijpa/items/056acaa13e935590fdc2)

# ダメージアニメ

ricky-senseiの記事にあったコードを短くしてみました。
Zキーが押されたとき、数字が上昇して消えます。

<details><summary>ここをクリックしてください</summary>

```python:
import pygame
from pygame.locals import *
import sys
import time

pygame.init()  
screen = pygame.display.set_mode((160, 160))  
pygame.display.set_caption("damage_anime")  
font = pygame.font.Font(None, 50)
# 色
white = (255, 255, 255)    
damage = 0
# ダメージ量表示のY座標    
damageY = 0  
clock = pygame.time.Clock()
running = True
while running:
    clock.tick(60)
    # 画面を黒色に塗りつぶし
    screen.fill((0, 0, 0))  
    # attackのアニメーション表示
    text_damage = font.render(str(damage), True, white)
    if damageY > 50:
        screen.blit(text_damage, (55,damageY))
        damageY -= 1
        time.sleep(0.01)
    pygame.display.update()  
    # イベント処理
    for event in pygame.event.get():
        if event.type == QUIT: 
            pygame.quit()  
            sys.exit()
        elif event.type == KEYDOWN:
            # Zーキーが押されたとき
             if event.key == K_z:            
                # ダメージ
                damage = 10                     
                damageY = 120


```
</details>
 
# HPゲージ

Zキーが押された時、HPゲージが減っていきます。

<details><summary>ここをクリックしてください</summary>

```python:

import pygame
import sys
from pygame.locals import *
import time

pygame.init()
screen = pygame.display.set_mode((160, 160))
pygame.display.set_caption('HP_gauge')
player_HP = 8
deffence = 0
monster_power = 6
gauge_rectx = 80
gauge_rectx2 = 80
monster_HP =  10                            
player_damage = 0

clock = pygame.time.Clock()
running = True
while running:
    clock.tick(60)
    screen.fill((0, 0, 0))
    #HPゲージの表示    
    if gauge_rectx > gauge_rectx2:
        gauge_rectx -= 1
        time.sleep(0.005)
        
    pygame.draw.rect(screen,(255,0,0),(40,79,80,3))            
    pygame.draw.rect(screen,(0,255,0),(40,79,gauge_rectx,3))
    pygame.display.update()
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_z:
                 if monster_HP > 0:                            
                     player_damage = monster_power // 2 - deffence // 4
                     if 0 != player_HP:
                         gauge_rectx2 = int(gauge_rectx - player_damage / player_HP * gauge_rectx)
                     elif 0 >= player_HP:
                         cage_rectx2 = 0
                     if player_damage <= 0:
                         player_damage = 1
                     player_HP -= player_damage


```
</details>
 
#

<details><summary>ここをクリックしてください</summary>

```python:


```
</details>
 
#

<details><summary>ここをクリックしてください</summary>

```python:


```
</details>
 
#

<details><summary>ここをクリックしてください</summary>

```python:


```
</details>
Gitでファイル毎のコミット数をカウントする

Gitのリポジトリにて、ファイル毎の大まかなコミット数を手軽にカウントできないか試してみたところ、一応は下記コマンド（カウント数の多い順で出力する場合）で実現できました。

ただし、リネームによる変更前後のファイル名の組み合わせもカウント対象となります。

```sh:ファイル毎のコミット数カウント
git whatchanged --oneline | sed '/^[^:]/d' | cut -f 2-3 | sort | uniq -c | sort -r
```

更にコミットメッセージをカウント対象としても良いのなら、次のように簡略化できます。

```sh:ファイル毎のコミット数カウント簡易版
git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r 
```

# 処理内容

まず、```git whatchanged``` コマンドでコミットとそのコミットで変更したファイルの情報が出力され、```--oneline``` オプションを指定する事でコミットの情報部分が 1行になります。

出力内容から本件で必要な部分に着目すると、次のような特徴が見られます。

* 先頭文字が ```:``` で始まる行に変更のあったファイル名が記載される
* ファイル名はタブ（```\t```）で区切られる

例えば、実際の出力結果はこのようになります。[^1]

[^1]: ちなみに、A は追加、M は変更、D は削除、R100 はリネーム（git mv の結果）のようです

```sh:git whatchanged 出力結果例
$ git whatchanged --oneline
38aa697 (HEAD -> main) step5
:100644 100644 1483170 ed634ec M        a.txt
:000000 100644 0000000 4bcfe98 A        d.txt
157dbbc step4
:100644 100644 c1f7537 1483170 M        a.txt
:100644 000000 3410062 0000000 D        c.txt
:100644 100644 a510a94 6178079 M        sub/b1.txt
04d0c8e step3
:100644 100644 a510a94 a510a94 R100     b.txt   sub/b1.txt
6350ca5 step2
:100644 100644 7898192 c1f7537 M        a.txt
:100644 100644 6178079 a510a94 M        b.txt
:000000 100644 0000000 3410062 A        c.txt
d6c1f16 step1
:000000 100644 0000000 7898192 A        a.txt
:000000 100644 0000000 6178079 A        b.txt
```

そこで、このような出力を下記の手順で処理するのが前述のコマンドです。

1. 先頭文字が ```:``` 以外の行を削除
2. タブで区切った 2つ目と 3つ目の要素を取得[^2]
3. ソートして同一行をカウント
4. カウント数の多い順にソート

[^2]: タブが含まれていなければ、その文字列全体になります

# 出力例

実際の出力結果はこのようになります。

```sh:出力例1
$ git whatchanged --oneline | sed '/^[^:]/d' | cut -f 2-3 | sort | uniq -c | sort -r
   4 a.txt
   2 c.txt
   2 b.txt
   1 sub/b1.txt
   1 d.txt
   1 b.txt      sub/b1.txt
```

簡易版だとこうなります。

```sh:出力例2
$ git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r 
   4 a.txt
   2 c.txt
   2 b.txt
   1 sub/b1.txt
   1 d6c1f16 step1
   1 d.txt
   1 b.txt      sub/b1.txt
   1 6350ca5 step2
   1 38aa697 step5
   1 157dbbc step4
   1 04d0c8e step3
```

最後に、```https://github.com/git/git``` へ適用してみるとこのようになりました。

```sh:出力例3
$ git clone https://github.com/git/git
$ cd git
$ git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r | head
2166 Makefile
1471 cache.h
1132 diff.c
 956 refs.c
 912 Documentation/config.txt
 822 contrib/completion/git-completion.bash
 811 GIT-VERSION-GEN
 740 sha1_file.c
 714 revision.c
 705 gitweb/gitweb.perl
```
C#13の部分プロパティとMVVM Toolkit(ver9？)


## C#13の新機能：部分プロパティ

.NET9と同時にリリース予定の C# 13 では「部分プロパティ」がやっと導入される見込みです。これの何が嬉しいかというと、ソースジェネレータがプロパティにも対応できるという事です。

例えばC# 11/NET 7 で導入された`[GeneratedRegex]`(正規表現の高速化)は部分メソッドで生成されていましたが、部分プロパティでもっと自然に書けます。

```csharp:
//部分メソッド(C#11)で書いた場合
[GeneratedRegex("abc|def")]
private static partial Regex AbcOrDefMethod();

if (AbcOrDefMethod().IsMatch(text)) {  //ちょっと違和感がある書き方
}

//部分プロパティ(C#13)導入後
[GeneratedRegex("abc|def")]
private static partial Regex AbcOrDefProperty { get; }
 
if (AbcOrDefProperty.IsMatch(text)) { //自然体でかける
}
```

## MVVM ToolKitで部分プロパティ対応

となると期待されるのが、MVVM ToolKitで違和感のある書き方だった`[ObservableProperty]`の改善です。

以前の紹介記事「[.NET用 MVVM Toolkit v8でMVVMコードを短く](https://qiita.com/hqf00342/items/d12bb669d1ac6fed6ab6)」に書いたようにver8では変更通知プロパティは以下のようにバッキングフィールドを書いています。

```csharp:MVVM ToolKit ver8
[ObservableProperty]
private string name;
```

これで変更通知対応した`Name`プロパティが生成されますが、コード上に無いため間違えやすく、現在はアナライザーを使って「`name`じゃなくて `Name` を使ってね」と警告が出してしのいでます。
これは部分プロパティが導入されれば解決できるはずです。

```csharp: MVVM ToolKit ver9? なら?
[ObservableProperty]
public partial string Name { get; set; }
```


MVVM ToolKit側では [昔から要望が上がっていた](https://github.com/CommunityToolkit/dotnet/issues/555)のですが、部分プロパティのC#への導入が前回見送られたのでToolKit側も見送られました。
しかし**MVVM ToolKit ver9** ではかなり前からこの機能はバックログに積まれています。早めに実現されるとうれしいですね。

GitHub: CommunityToolkit/Projects/9.0
https://github.com/orgs/CommunityToolkit/projects/6/views/1


#### 2024年11月17日追記

C#13/.NET9もリリースされ、この[PRが無事マージ](https://github.com/CommunityToolkit/dotnet/pull/966)されたようです。
(ver8.4でリリースされました）

が、C#13にプロパティの「field」キーワードが導入されなかったことで現時点では`LangVersion=preview`(C#14相当)が必要になるようです。
[tips][cpp] 文字コード char型とint型の相互変換

# cppでint型とchar型の相互変換

相互変換のtipsです。


## 文字コードとint型の値の対応

```cpp
cout << (int)'A' << endl;
cout << (int)'B' << endl;
cout << (int)'Z' << endl;
cout << (char)65 << endl;
cout << (char)66 << endl;
cout << (char)90 << endl;

cout << endl;

cout << (int)'a' << endl;
cout << (int)'b' << endl;
cout << (int)'z' << endl;
cout << (char)97 << endl;
cout << (char)98 << endl;
cout << (char)122 << endl;
```

otput
```cpp
65
66
90
A
B
Z

97
98
122
a
b
z
(b
```

## 順序づけられた文字コードを使ってアルファベット取得

'A'の文字コードに対応するintの値の最初から初めて、
```cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  for (int i = 0; i <= ('Z' - 'A'); i++) {
    cout << (char)('A' + i);
  }
}
```

or

```cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  for (int i = (int)'A'; i <= 'Z'; i++) {
    cout << (char)i;
  }
}

```

output
```cpp
ABCDEFGHIJKLMNOPQRSTUVWXYZ
```



# 参考
https://atcoder.jp/contests/apg4b/tasks/APG4b_ad?lang=ja
PHP 条件分岐(if)

## はじめに
ifとswitchについて理解はしているのですが、書き方がごっちゃになることがあるので自分用まとめです。


## ifサンプルコード
```js
$score = 100;

if ($score === 100) {
    echo "excellent!!" . PHP_EOL;
} else if ($score >= 80) { //elseifじゃなくてelse if
    echo "Great!" . PHP_EOL;
} else {
    echo "もうすこしがんばりましょう" . PHP_EOL;
}   
```
```
excellent!!
```
## 比較演算子
```js
>=  //以上
<=  //以下
>   //超過
<   //未満
=== //等しい
!== //等しくない
```

## 複数条件
```js
&& and //なおかつ
|| or  //もしくは
!      //ではない
```

## returnで処理の中断
ifの中でreturnを使用するとifを抜けます。

## おわりに
基礎なんでちゃんと覚えたいですね。
設定 メール-to-ケース email to case について

### Email to Caseが発生した時、生成される対象オブジェクト

1. Case
1. EmailMessage
1. EmailMessageRelation

[EmailMessageRelation](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_emailmessagerelation.htm)
#### EmailMessageRelationはCaseとEmailMessageの関連を表示するオブジェクトではない、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/812bd973-54f0-b160-0641-bd2a5120e4f7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/2d8fc200-142a-0561-f291-b03cf64b983a.png)


#### EmailMessagのParentIdがCaseId
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/d43c554a-f2f3-b0a9-c47a-76118dfd3f97.png)

[EmailMessage](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_emailmessage.htm)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/9e0de2ab-df66-c8b2-c3a3-0036d4cccb51.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/16581b01-d264-69f9-c6f3-f4201fcdfcc1.png)

#### Caseについては省略

### 受信メールログ取得方法
メールの方向で「着信」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/5a70bf86-005c-9ea3-b7bc-7f52ee8fe3f6.png)
【ChatGPT Canvas】での編集を指示だけで、完成させます。


　どうも、カーブミラーです。

　今回は、Canvasでの編集を、指示だけで、完成させます。直接の手入力はしません。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::

　ニュースはありませんので、
　　さっそく本題に入ります。

　今回は、
　　記事の編集を
　　　指示だけで、完成させます。

　まず、もとにする論文は、こちら。
　　[AIDBさんポスト](https://x.com/ai_database/status/1844583408514761122?t=r7_8CJL496CMW4XDbmsbCw&s=19)

　ただし、
　　無料で読める範囲に
　　　限られます。

　この論文は、
　　Promptで
　　　ペルソナを設定しても
　　　　効果は薄く、
　　　　　逆に効果が下がる場合も
　　　　　　ある、というものです。

　まぁ、
　　それ自体は
　　　ChatGPTを
　　　　彼氏彼女にしたいとか
　　　　優しい教師にしたいとか
　　　　　の指定は否定していません。

　　プロや専門家を設定するのは
　　　無意味だと言っているようです。

　それはともかく、
　　この論文から記事を作成し、
　　　編集していこうと思います。

　その過程で、
　　記事自体に
　　　私自身は手を加えません。

　必ず、
　　ChatGPTへの指示をして
　　　編集していきます。

　では、やり取りをどうぞ。
***
***●user***
ai-data-base.com/archives/76905
論文内容の概要とあなたの見解とメリットデメリットと、最後にまとめをCanvasに書き込んでください。

***GPT-4o with canvas***
（Canvasに書き込まれた）

***●user***
目次を作成して

***GPT-4o with canvas***
（先頭に目次が書き込まれた）

***●user***
目次から記事へとハイパーリンクして

***GPT-4o with canvas***
（ハイパーリンクが設定された）

***●user***
記事から目次に戻れるようにして

***GPT-4o with canvas***
（記事の頭に“目次に戻る”が追加）

***●user***
“目次に戻る”は記事の最後に

***GPT-4o with canvas***
（記事の最後に“目次に戻る”が移動）
***

　Canvasからコピーしたのが、こちら。
　　ちなみに、ハイパーリンクですが
　　　ここでは働かないようです。
　　　　ごめんなさい。
***
**目次**

1. [概要](#概要)
2. [見解](#見解)
3. [メリット](#メリット)
4. [デメリット](#デメリット)
5. [まとめ](#まとめ)

概要

この記事では、カーネギーメロン大学やスタンフォード大学などの研究者が行った研究について紹介しています。この研究は、LLM（大規模言語モデル）に対して「あなたは○○です」といったペルソナ設定を行った場合の効果を体系的に評価しています。162種類の異なる役割設定を4種類のLLMに対して行い、2,410の事実に基づく質問を用いて検証した結果、ペルソナ設定が回答精度を向上させる効果は確認されなかったという結果が得られました。

[目次に戻る](#目次)

**見解**

この研究結果は、ペルソナ設定が必ずしも回答の質を改善しないことを示唆しており、特に事実に基づく質問に対してはその効果が限定的であると考えられます。LLMに役割を持たせることで人間のような対話を期待することが多いですが、回答精度の向上にはつながらない点は注目すべきです。

[目次に戻る](#目次)

**メリット**

メリットとして、この研究により、ペルソナ設定の効果を過度に期待せず、より本質的なモデルの改良に注力する必要性が明らかになった点が挙げられます。

[目次に戻る](#目次)

**デメリット**

一方で、デメリットとしては、ペルソナを使ったインターフェースがユーザーにとって親しみやすさを提供するものの、その効果が必ずしもパフォーマンス向上に結びつかないため、ユーザー体験の期待とのギャップを生む可能性がある点が挙げられます。

[目次に戻る](#目次)

**まとめ**

LLMにおけるペルソナ設定は、対話の自然さやユーザーの親しみやすさには寄与するものの、回答精度の向上には直接つながらないことが示されました。今後は、ペルソナ設定以外のアプローチにより、LLMの精度向上やユーザー体験の改善を目指すべきかもしれません。

[目次に戻る](#目次)
***


　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
***
2024/10/13更新
　リンク先に飛ばない方へ。

　リンク先の表記が
　　“\*\*”と“\*\*”で
　　　囲まれているのが原因です。

　その場合は
　　同じセッションで、
```Text:リンク先Markdown修正
Canvasの内容の小見出しを“**”で囲まず、頭に“##”を付けてください。
```
　　　でイケます。

　ちなみに、
　　Canvas内では、
　　　飛びませんよ😅
　　　　編集中ですから。
OpenTelemetryのCollectorをいかにデプロイするか

前回の続き
* https://qiita.com/uS_aito/items/3282c0becfffe15e1373

前回の調査で分散トレーシングのコレクタがどういうものかはわかったが、では実際にproduction-readyな形でデプロイしようとした時に、どの様な手段でデプロイできるのか、どの様な形でデプロイされるのかがわからなかったので調査した。
今回は具体的なコレクタの実装として、OpenTelemetroyのCollectorを使用する。またインストール先はkubernetesを想定する。

opentelemetry collectorのinstallページを見ると、production-readyなcollectorをインストールしたいときは、helmチャートを使うかoperatorを使えとある。
* https://opentelemetry.io/docs/collector/installation/

# helm chart
helm経由でcollectorをインストールする場合、インストール方法をdeamonset、deployment、statefulsetの中から選ぶことができる。どの方法を使うべきか、意思決定の方法はgithub側に記載がないが、opentelemetroyの[Kubernetes Getting Started](https://opentelemetry.io/docs/kubernetes/getting-started/)のページに多少の記載がある。
このページによると、collectorの最初のステップとしてはdeamonsetの利用が勧められている。各ノードにcollectorをインストールして、各ノードのメトリクスやトレースなどを収集してくれる。
getting startedのページを読んでいたらOTEL Receiverという新しい単語がまた出てきた。collectorの一要素で、実際のトレースやメトリクス、ログの受信はこのコンポーネントが行なっているらしい。[OTEL Receiverのconfig](https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver#getting-started)を見ると前回起動したcollectorの設定と一致するので、前回もこのReceiverを知らず知らず使っていたようだ。

# operator
OTELのoperatorはopentelemetry Collectorの他に、自動計装のサイドカーもインストールすることができる。このサイドカーをpodにインジェクションすると、対応している言語のアプリに限り、コードの変更を行わなくてもトレースやメトリクスを取得することができる。
参考：
* https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-auto-instrumentation-injection
* https://opentelemetry.io/docs/concepts/instrumentation/zero-code/
備忘録: UTL_FILE_DIR サブディレクトリへディレクトリパス設定

Oracle Database UTL_FILE_DIRのディレクトリ設定について、
2~3週間詰まっていたところがやっと設定できたので、
記事として残しておきたいと思います。

現在ではディレクトリオブジェクトの方が使用されていることと思うので、
そちらを利用されている方はあまり参考にならないかもしれません。

設定内容ですが、日次処理で日々動的に作成されるフォルダへUTL_FILEを使用して
ファイルを吐き出す設定を行いました。
結果的に、サブディレクトリへパスを通すというよりは、
読み書きが許可されているPC内のすべてのフォルダへパスを通す方法で実現したのですが、
その方法をまとめておこうと思います。

# 設定内容

基本的にUTL_FILE_DIRは
```　
ALTER SYSTEM SET UTL_FILE_DIR = 'C:\hoge' SCOPE = SPFILE;
```
という形でディレクトリのパスを初期化するのですが、
この方法だと、そのディレクトリにしかファイルを吐き出すことができません。
(サブディレクトリなど、その配下のディレクトリに吐き出そうとすると、エラーが出る)

そのため、2~3週間その他の方法を探していて、先日やっと13年前に作成された
公式のリファレンスにたどり着き、設定できました。

リファレンスの中で紹介されていた方法は
```
ALTER SYSTEM SET UTL_FILE_DIR = '*' SCOPE = SPFILE;
```
というものでした。

(リファレンス内でセキュリティ的には推奨されない方法であると記載)

古いシステムを触っている方々など、参考になれば幸いです。

# 参考文献
https://www.oracle.com/technetwork/jp/ondemand/db-technique/b-12-sql-1484774-ja.pdf
「BOSCAR」ってなに...?

## とある日の上司からの言葉

とある日、現場のPLと1on1をしました。その時PLに「問題解決能力があるので問題を細分化して都度報告するようにしてください」と言われました。

上記の指摘内容をまとめると「問題を細分化して報連相を徹底してくれ」ということだろう。ぼくは管理職になったことはないけれど、相手からのレスポンス待ちになる場面が多い役職は考えるだけでもやもやしてしまいます。

う「問題を細分化する方法がよくわかりません」

こんな基礎的な質問をしてしまうのは申し訳ないけれど、何とかこの現場に貢献したいと思いPLに伝えました。

P「俺は**BOSCAR**っていうフレームワーク使っているからうるし君も使ってみなよ」

## BOSCARとは

う「PLさん、BOSCARって何ですか？思考フレームワークみたいないものですか？」

P「BOSCARは思考フレームワークじゃなくてプロジェクト管理のフレームワークのことだね。内容は

* Background（背景）: プロジェクトの背景や目的を明確にする
* Objective（目的）: プロジェクトが達成しようとするゴールを定義する
* Scope（範囲）: プロジェクトの範囲を設定し、対象外となる部分も明記する
* Constraints（制約）: プロジェクトに影響を与える制約を明確にする
* Assumptions（仮定）: プロジェクト開始時に立てた仮定をリスト化し、これらが正しいかどうかを確認する
* Risks（リスク）: プロジェクトで考えられるリスクとその対策をまとめる

って感じだね」

う「へ～そうなんですね！知らなかったです！」

う「でもぼく管理職とかになるつもりないですよ？」

P「確かにBOSCARは管理をする人が使うフレームワークだけど仕事をする人全員が意識するべき内容だね。管理職はいろんな仕事のペースを管理することが大切なんだけど非管理職の人も結局自分の仕事の管理をすることになるよね？**自分の仕事の管理を全部管理職の人に任せたらパンクしちゃうよね？**」

う「確かに、小規模でも難しそうだけど中規模・大規模になったら相当難しいですね」

P「だろ？そしたら結局自分の仕事ができなくなるだろ？だから非管理職の人も自分の仕事は自分でまとめて、それを管理職の人に連絡するだけにすれば問題ないんだよ」

う「確かに大切そうです！そしたらBOSCARの具体的な使い方について教えてください！」

## BOSCARの使い方

P「そうだね。このBOSCARはプロジェクト向けになっているから非管理職向けの表現に変えてみようか」

* Background（背景）: タスクの背景を明確にする
* Objective（目的）: タスクが達成しようとするゴールを定義する
* Scope（範囲）: タスクの範囲を設定し、対象外となる部分も明記する
* Constraints（制約）: タスクに影響を与える制約を明確にする
* Assumptions（仮定）: タスク開始時に立てた仮定をリスト化し、これらが正しいかどうかを確認する
* Risks（リスク）: タスクで考えられるリスクとその対策をまとめる

P「プロジェクトの部分をタスクに変えただけだけどこれで考えやすくなったかな？」

P「もちろん上流の人たちでタスクの背景や目的の部分をまとめているからだいたいコピペで済むんだけど、自分で一度考えてみるっていうのも力になるだろうからやってみてほしいな」

う「わかりました！試してみます！」

## おわりに

これは1年以上前の話を脚色して書いています。BOSCARについて話してくれたのは本当ですかそれ以降の使い方のような部分は現場でちょくちょく相談しながら行っていました。

今は個人タスクの管理にBOSCARを使っておりません。やはりプロジェクトの規模とタスクの規模だとサイズ感が合わないと感じました。これより個人タスク管理向けのフレームワークはいくらでもありますが、プロジェクト管理も、タスク管理も本質的には同じなんだよという部分が伝われば幸いです。

## 参考文献

https://scrapbox.io/nobuoka-pub/BOSCAR_%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF

https://yoshi7.blogspot.com/2012/12/boscar.html
blastengineのC# SDKを使ってメールの取得・削除を行う

blastengine（ブラストエンジン）はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先に届けられます。

現在、C#向けに、blastengine SDKを開発しています。.NET6以上を対象としているので、macOSを含め幅広い環境で実行できるはずです。

今回は、メールデータの取得と削除方法を解説します。

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg)

そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png)

## 必要な情報について

SDKを使う上で必要なのは、先ほどのAPIキーとユーザIDになります。

## SDKのインストール

SDKはNuGetでリリースしています。Visual StudioのNuGetパッケージの管理よりインストールしてください。

[NuGet Gallery \| Blastengine 0\.1\.0](https://www.nuget.org/packages/Blastengine/)

## 初期化

先ほどのAPIキーとユーザIDを使って初期化します。

```csharp
new Blastengine.Client("YOUR_USER_ID", "YOUR_API_KEY");
```

## トランザクションオブジェクトの作成

メールデータを取得するために、トランザクションオブジェクトを作成します。

```csharp
var transaction = new Transaction();
```

## 必要な情報をセットする

続けて、トランザクションオブジェクトにデリバリーID（配信ID）をセットします。

```csharp
transaction.DeliveryId = 999; // 例
```

後は `Get` メソッドで情報を取得できます。

```csharp
await transaction.Get();
transaction.Subject; // 件名
```

### メールデータを削除する

メールデータを削除する場合は、`Delete` メソッドを使います。

```csharp
var transaction = new Transaction();
transaction.DeliveryId = 999; // 例
await transaction.Delete();
```

## コードについて

コードはGitHubにアップしてあります。ライセンスはMIT Licenseになります。

[blastengineMania/blastengine-csharp: blastengineのC# SDKです](https://github.com/blastengineMania/blastengine-csharp)

## まとめ

blastengineには他にも一括メール配信を行ったり、添付ファイル付きのメール配信機能などもあります。これらの機能も随時実装していきますので、ぜひ皆さんのシステム開発に役立ててください。

[エンジニア向けメール配信システム「ブラストエンジン」](https://blastengine.jp/)
TypeScriptでpubsubモジュールを実装する

:::note
## 概要
pubsubモジュールは、アプリケーション内の異なるモジュール同士が連携するための役割を果たします。
主に、2つのメソッドを提供しています。
`subscribeメソッド`: イベントに対して購読（登録）を行い、指定されたコールバック関数を保持します。購読されたイベントが発生した際に、このコールバックが実行されます。
`publishメソッド`: 指定されたイベントを発生させ、そのイベントに紐づいているすべての購読者（サブスクライバー）のコールバック関数を呼び出します。

これにより、各モジュールが「イベント」という共通の方法を使って通信できるようになります。イベントが発生すると、そのイベントに登録された購読者のコールバック関数が順次実行される仕組みです。
:::

# 背景
業務のコードでpubsub-jsを知ったので、PubSubパターン/モジュールを理解したいと思います

# pubsub-jsとは

https://www.npmjs.com/package/pubsub-js

JavaScriptで書かれたトピックベースのPub/Subパターンのライブラリです。

# Pub/Subパターンとは

https://medium.com/@thebabscraig/javascript-design-patterns-part-2-the-publisher-subscriber-pattern-8fe07e157213

Publisher/Subscriberパターンの略です

疎結合でデータの受け渡しができるモジュールを作成できるパターンです

# シンプルなPub/Subモジュールを実装してみる

https://github.com/yamatai12/sample-pubsub

以下を参考に実装しました

https://github.com/babzcraig/javascript-design-patterns/tree/master/pubsub

## 実装

```src/pubsub.ts
let subscribers = {} as {
  [event: string]: ((data: { msg: string }) => void)[];
};

export = {
  publish(event: string, data: { msg: string }) {
    if (!subscribers[event]) return;
    subscribers[event].forEach((subscriberCallback) =>
      subscriberCallback(data)
    );
  },
  subscribe(event: string, callback: (data: { msg: string }) => void) {
    let index: number;
    if (!subscribers[event]) {
      subscribers[event] = [];
    }
    index = subscribers[event].push(callback) - 1;
    return {
      unsubscribe() {
        subscribers[event].splice(index, 1);
      },
    };
  },
};
```

- publishメソッド
指定されたイベントを発生させ、そのイベントに紐づいているすべての購読者（サブスクライバー）のコールバック関数を呼び出します

- subscribeメソッド
 イベントに対して購読（登録）を行い、指定されたコールバック関数を保持します。購読されたイベントが発生した際に、このコールバックが実行されます。

次に二つのモジュール間でイベントを通して通信します。

```src/executePublishEvent.ts
import pubSub from "./pubsub";

export const executePublishEvent = () => {
  const data = {
    msg: "TOP SECRET DATA",
  };

  pubSub.publish("anEvent", data);
};
```

```src/executeSubScribeEvent.ts
import pubSub from "./pubsub";

export const executeSubScribeEvent = () => {
  let subscription: { unsubscribe(): void };

  subscription = pubSub.subscribe("anEvent", (data) => {
    console.log(`"anEvent", was published with this data: "${data.msg}"`);
    subscription.unsubscribe();
  });
};
```

```src/index.ts
import { executeSubScribeEvent } from "./executeSubScribeEvent";
import { executePublishEvent } from "./executePublishEvent";

executeSubScribeEvent();
executePublishEvent();
```

## 実行

以下のコマンドで実行可能です
```
npx ts-node src/index.ts
```
or
```
npm run pubsub;
```

実行結果は以下です
```terminal
"anEvent", was published with this data: "TOP SECRET DATA"
```

二つのモジュール間でイベントを通して通信できました。

# 最後に
PubSubパターン/モジュールについて理解を深めたいと思います
業務で使われている実装を見て、pubsubjsの概要を掴みたいと思います

# 参考

https://dev.to/anishkumar/design-patterns-in-javascript-publish-subscribe-or-pubsub-20gf

https://medium.com/@thebabscraig/javascript-design-patterns-part-2-the-publisher-subscriber-pattern-8fe07e157213

https://zenn.dev/shinkano/articles/84431a42c73794
[Python]雑多な備忘録

# numpyを使わずに二重リストの行列を入れ替える
numpyを使えばいいと思われるかもしれませんが、**競技プログラミングなどでは外部ライブラリを使えないことがある**ので、zipを使ってリスト内包表記で解決します。
~~~Python:irekae.py
data = [[1, 5, 3], [2, 4, 6], [8, 1, 9]]
transposed = [ x for x in zip(*data)]
print(transposed)
~~~
実行結果
~~~
[(1, 2, 8), (5, 4, 1), (3, 6, 9)]
~~~
# サイコロの偶奇判定
randint(a, b)は、a以上**b以下**ということで**bも含まれる**ことを時々忘れるので
備忘録として書いてみました。
~~~Python:even_or_odd.py
import random

dice_roll = random.randint(1, 6)

if dice_roll % 2 == 0:
    print(dice_roll, "偶数")
else:
    print(dice_roll, "奇数")
~~~
実行結果
~~~
3 奇数
~~~
# サイコロの各目が出る確率を求める
Pythonの標準ライブラリcollectionsは、リスト、タプル、辞書などの基本的なデータ構造を拡張した特殊なデータ構造を提供します。Counterクラスを使うと、出現回数が多い順に要素を取得可能です。Counterはキーに要素、値に出現回数という形のデータを持ちます。
~~~Python:dice_roll.py
import random, collections

n = 100
result = []

for _ in range(n):
    dice_roll = random.randint(1, 6)
    result.append(dice_roll)

result.sort()
for num, count in collections.Counter(result).items():
    print(num, f"{count / n:.3%}") # 小数点以下第３位までの%表記
~~~
実行結果
~~~
1 17.000%
2 21.000%
3 12.000%
4 16.000%
5 18.000%
6 16.000%
~~~
# Collentionsのdeque
collectionsのdequeは、**両端に対する要素の追加や削除が高速に行える**データ構造です。**但し中央部分の要素へのアクセスは遅い**ので、両端以外の要素へ頻繁にアクセスする場合はリストを使うほうがいいです。下のコード例の**extendleft()は、指定したイテラブルの要素の順番が逆転されて連結される**ので注意が必要です。
~~~Python:deque.py
from collections import deque

names = deque()
names = deque(["Charlie", "Ellen", "Jasmine"])
names.popleft() # 先頭の要素を削除
names.append("Michael")
names.appendleft("Bob") # 先頭に要素を追加
names.extendleft(["Abraham", "Anne", "Arthur"]) # 先頭に複数の要素を追加
print(names)
~~~
実行結果
~~~
deque(['Arthur', 'Anne', 'Abraham', 'Bob', 'Ellen', 'Jasmine', 'Michael'])
~~~
herokuのaddonsの共有と解除方法（主にPostgres）

# 概要
productionとstagingでDBを同一にしたい場合などに、productionのアドオンをstagingに共有する方法です。
めっちゃ簡単にStagingが構築できるので便利。

![スクリーンショット 2024-10-12 10.59.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253667/5e69d732-70f9-311c-19ae-2161c69a0e9e.png)




# 共有

### アドオン名を確認する

```
heroku addons -a [productionアプリ名]
```
postgresを共有したい場合、これで postgresql-flat-xxxxやらredis-contoured-xxxxのようなアドオン名が表示される。


### アタッチする
stagingにproductionのPostgresアドオンをアタッチする場合

```
heroku addons:attach [アドオン名] -a [stagingのアプリ名]
```

# 解除

### デタッチする

```
heroku addons:detach [アドオン名] -a [stagingアプリ名]
```

# 参照
https://devcenter.heroku.com/articles/add-ons#sharing-an-add-on-between-apps
[tips][cpp] 昇順・降順sort

# Sort/Reverse

これを書いておく。
```
#define all(a) a.begin(), a.end()
#define reverse_all(a) a.rbegin(), a.rend()
```

## 降順ソート

### 数値

```cpp
vector<int> a = {4, 2, 3, 1, 5};

reverse(all(a));
for (int i = 0; i < 5; i++) {
  cout << a[i] << " ";
}
```

output
```cpp
5 4 3 2 1 
```

or

```cpp
vector<int> a = {4, 2, 3, 1, 5};

sort(reverse_all(a));
for (int i = 0; i < 5; i++) {
  cout << a[i] << " ";
}
```

output
```cpp
5 4 3 2 1 
```

### 文字列

```cpp
string str = "abcdefg";
reverse(all(str));
cout << str << std::endl;
```

```cpp
gfedcba
```
### pair型

reverseはただ配列の順序を逆順にする。
```cpp
vector<pair<int, int>> a = {make_pair(3,1), make_pair(4,2), make_pair(2,3)};
reverse(all(a));
for(pair<int, int> v:a){
  cout << v.first << " " << v.second << endl;
}
```

このように、第一要素が降順にならないので。
output
```cpp
2 3
4 2
3 1
```

第一要素を降順にしたい場合は、sortしてからreverseする。

```cpp
vector<pair<int, int>> b = {make_pair(3,1), make_pair(4,2), make_pair(2,3)};

// sortして第一要素を昇順にする!!!
sort(all(b));
// 順序を逆にする
reverse(all(b));
for(pair<int, int> v:b){
  cout << v.first << " " << v.second << endl;
}
```

第一要素が降順になった。めでたし。

output
```cpp
4 2
3 1
2 3
```



## 昇順ソート

```cpp
vector<int> a = {4, 2, 3, 1, 5};

sort(all(a));
for (int i = 0; i < 5; i++) {
  cout << a[i] << " ";
}
```

output
```cpp
1 2 3 4 5
```

pair型の場合は一つ目の値を基準にsortされる。(**一つ目の値が同じであった場合は、二つ目の値を基準にsortされる。**)

```cpp
vector<int> a = {make_pair(3,7), make_pair(2,8), make_pair(1,2)};

sort(all(a));
for(pair<int, int> v:a){
  cout << v.first << " ";
}
```

output
```cpp
1 2 3
```

## 参考

https://hiroms-blog.com/entries/vetor-pair-sort-varieties

[sort - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/algorithm/sort.html)
[rbegin - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/reference/iterator/rbegin.html)

[ABC222 C - Swiss-System Tournament](https://atcoder.jp/contests/abc222/tasks/abc222_c)
[ABC219 C - Neo-lexicographic Ordering](https://atcoder.jp/contests/abc219/tasks/abc219_c)
paizaラーニング問題集「【シミュレーション 3】燃費」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__fuel_economy

▼考え方

ポイントになる考え方1.～2.を以下に示します。

1.全長L[m]を以下のように区間に分け、区間ごとに燃費を考えます。
```
0 --- s_1[m] --- s_2[m] ... --- s_N[m] --- L[m]
　↑区間　　　　↑区間　　　　↑複数の区間　　↑区間
```
以下、N=2の時を例に説明します。s_1が30[m]、s_2が60[m]のとき、リストsをs=[0,30,60,100]と定義します。

2.出発地点s[i-1]からX[m]走ったあと、まだ一時停止地点s[i]に到達しないのであれば、燃料がF_1[ml]とF_2[ml]の距離が存在します。到達しているのであれば、F_1[ml]の距離のみ存在します。両者を場合分けして区間ごとの燃費の和を計算します。

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

X = int(input())

f_1,f_2 = map(int,input().split())

L,N = map(int,input().split())

# 考え方1.
s = [int(x) for x in input().split()]
s.insert(0,0)
s.append(L)

total = 0
for i in range(1,len(s)):
    # 考え方2.
    if s[i-1] + X <= s[i]:
        total += X*f_1+(s[i]-(s[i-1]+X))*f_2
    else:
        total += (s[i]-s[i-1])*f_1

print(total)
```