OmniAICreator/Qiita-1.07M huggingface dataset:
GitHubの草が反映されない時の解決法：コミットユーザーの確認と修正手順

## はじめに
現在プログラミングを学習中の初学者です🔰
この記事では、GitHubの草（コミット履歴）が正しく反映されない問題の解決方法について共有します。もし間違いや改善点があれば、教えていただけると幸いです。


## 問題発生状況
GitHubにコミットをプッシュしたのに、プロフィールの草（コミット履歴）が反映されないという問題に直面していませんか？原因として、Gitのユーザー名やメールアドレスの設定が異なっている可能性があります。

以下では、コミットに紐づけられたユーザーが異なる場合の原因の特定と修正方法について説明します。

　
参考URL（Githubの草とは？）
https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile
## 原因：コミットユーザーが違った！
実際に確認してみたところ、コミット履歴に表示されているユーザー名が異なっていることが原因でした。例えば、正しいGitHubのユーザー名が gotoshota777 なのに対し、コミット履歴には shota goto と表示されている場合などです。

### 1. Gitのユーザー名とメールアドレスを確認する
まずは、現在のGitの設定を確認します。以下のコマンドを実行してください。
```
$ git config user.name
$ git config user.email
```
もし、何も値が返ってこない場合は、ユーザー名やメールアドレスが正しく設定されていないことを示しています。
　

### 2. Gitのユーザー名とメールアドレスを設定する
ユーザー名とメールアドレスが設定されていない場合、以下のコマンドを実行して正しい情報を設定します。
```
$ git config --global user.name "XXXXX"
$ git config --global user.email "YYYYY"
```
```
※XXXXXには正しいGithubのユーザー名
※YYYYYには正しいGithubのメールアドレス
```
この設定を行うことで、**今後のコミットは正しいユーザー情報で記録**されるようになり、Githubの草として反映されるようなります。

参考URL
https://docs.github.com/ja/get-started/getting-started-with-git/setting-your-username-in-git
　

ただし、上記の設定では過去のコミットは修正されません。過去のコミットを正しいユーザー情報に変更するには、次の手順を慎重に行う必要があります。
## 過去のコミットユーザー情報を修正する

:::note warn
＿過去のコミットを修正する操作はリポジトリに影響を与える可能性があるため、作業を行う前に必ずリポジトリのバックアップを取るようにしてください。また、この操作を行う際には、有識者の協力を得て行うことを強く推奨します。
:::
### 1. リポジトリのコミットユーザーを変更する
手順：
修正したいリポジトリのディレクトリに移動します。

以下のコマンドを実行して、過去のコミットユーザー情報を修正します。

```
git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='XXXXX'; \ 
GIT_AUTHOR_EMAIL='YYYYY'; \
GIT_COMMITTER_NAME='XXXXX'; \
GIT_COMMITTER_EMAIL='YYYYY';" \
HEAD
```
```
※XXXXXには正しいGithubのユーザー名
※YYYYYには正しいGithubのメールアドレス
```

ここでは、GIT_AUTHOR_NAME と GIT_COMMITTER_NAME はコードの作成者とコミット者の名前を意味し、それぞれのメールアドレスも適切に設定します。
>`git filter-branch` コマンドは、リポジトリの過去のコミットを一括で修正する際に用いられる強力なコマンドですが、誤った操作を行うとリポジトリの履歴に大きな影響を与える可能性があります。そのため、この操作は慎重に行い、できる限り他のメンバーと連携して行うことをお勧めします。

参考URl
https://git-scm.com/docs/git-filter-branch

### 2.コミット情報が正しく修正されているか確認します。

```
$ git log
```

### 3.修正した履歴をリモートリポジトリに強制プッシュします。
```
$ git push -f
```
>`git push -f`（強制プッシュ）とは、ローカルの変更内容をリモートリポジトリに強制的に上書きする操作です。通常のプッシュではリモートとローカルの履歴が異なる場合にエラーが発生しますが、`-f` オプションをつけることで、リモートの内容をローカルの履歴に置き換えることができます。この操作は慎重に行い、他のメンバーと連携を取って実行することが推奨されます。


## 参考記事
また、この記事を書く際に以下の参考記事を活用させていただきました。併せて確認していただけると理解が深まるかと思います。
・[Gitの設定をgit configで確認・変更](https://note.nkmk.me/git-config-setting/)
・[GitのCommitユーザを修正する方法](https://qiita.com/y10exxx/items/dcea0e39788d649ca8ba)

## さいごに
今回、GitHubに草が反映されない問題が発生しましたが、学習仲間の皆さんの協力のおかげで無事に解決することができました。

この記事が、同じように悩んでいる方々の助けとなり、少しでも草を生やすお手伝いができれば幸いです。最後まで読んでいただき、ありがとうございました！🌱🌱🌱
LibreChatにPerplexity APIを設定する

~~~bash
$nano librechat.yaml
~~~
librechat.yamlに追記
LibreChatのドキュメントに記載のモデルは古いようでエラーが出たので
~~~yaml
    - name: "Perplexity"
      apiKey: "${PERPLEXITY_API_KEY}"
      baseURL: "https://api.perplexity.ai/"
      models:
        default: [
          "llama-3.1-sonar-small-128k-online",
          "llama-3.1-sonar-large-128k-online",
          "llama-3.1-sonar-huge-128k-online",
          "llama-3.1-sonar-small-128k-chat",
          "llama-3.1-sonar-large-128k-chat",
          "llama-3.1-8b-instruct",
          "llama-3.1-70b-instruct"
          ]
        fetch: false # fetching list of models is not supported
      titleConvo: true
      titleModel: "llama-3.1-sonar-small-128k-chat"
      summarize: false
      summaryModel: "llama-3.1-sonar-small-128k-chat"
      forcePrompt: false
      dropParams: ["stop", "frequency_penalty"]
      modelDisplayLabel: "Perplexity"
~~~

~~~bash
$nano .env
~~~
.envに追記
~~~yaml
PERPLEXITY_API_KEY=xxxxxx
~~~
ソースとかは表示されないのでPerplexityのサイトで使う方が便利かもだけど、あとにチャットを続けられるのは良いかも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322108/f9b984d4-6949-c092-0f0e-45a18aebf0d3.png)
DatabricksからPower BIへのデータモデルの公開

正式提供されたこちらの機能を試してみます。

https://qiita.com/taka_yayoi/items/09c83723456e6ce4e6dc

マニュアルはこちら。

https://docs.gcp.databricks.com/ja/partners/bi/power-bi.html

Databricks側で以下のようなリレーションシップがあるテーブルを準備します。

![Screenshot 2024-10-29 at 17.35.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c4c4ddc9-760f-6870-1c73-d4556c904e7b.png)


リレーションシップを張るには、以下の`ALTER TABLE ADD CONSTRAINT`などを使います。

https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-ddl-alter-table-add-constraint.html

自分の場合は以下のように設定しました。

```sql
ALTER TABLE
  202411_handson_catalog.takaaki_yayoi_databricks_com.pref_area
ALTER COLUMN
  Prefecture
SET
  NOT NULL;

ALTER TABLE
  202411_handson_catalog.takaaki_yayoi_databricks_com.pref_area
ADD
  CONSTRAINT area_pk PRIMARY KEY(Prefecture);

ALTER TABLE
  202411_handson_catalog.takaaki_yayoi_databricks_com.japan_cases
ADD
  CONSTRAINT case_area_fk FOREIGN KEY(Prefecture) REFERENCES 202411_handson_catalog.takaaki_yayoi_databricks_com.pref_area;
```

カタログエクスプローラで、上記テーブルが格納されているスキーマ(データベース)にアクセスし、右上で**公開先 Power BIワークスペース**をクリックします。

![Screenshot 2024-10-29 at 17.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/90271998-610a-9aa8-4a57-a59f97ab7c0f.png)

以下のような確認画面が出てきたらAcceptします。

![Screenshot 2024-10-29 at 16.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0ed24148-b08a-bef6-2513-5fe5df472583.png)

Power BIワークスペースやデータセットモード、認証方法などを選択します。ここではPATを選択します。OAuthが推奨ですが、今回はデモなので設定がシンプルな方を選択します。公開する際にはFabricのキャパシティが稼働していることを確認してください。

![Screenshot 2024-10-29 at 17.36.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a2b61492-278e-9e63-4799-609f21a6f458.png)

正常に公開されました。

![Screenshot 2024-10-29 at 17.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/96b3c249-a797-670e-9da1-fdfaa5718b34.png)

**Power BIを開く**をクリックします。お馴染みの画面にアクセスできます。公開したデータモデルが設定されています。

![Screenshot 2024-10-29 at 17.37.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b33a321d-fbc5-a9b5-98a4-66afb7ced1aa.png)

もちろんグラフを作ることができます。

![Screenshot 2024-10-29 at 17.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6c7352ce-39a6-7dcc-09f1-e3b6e7ca33e4.png)

データモデルにアクセスすると、Databricksで定義したリレーションシップを確認することができます。

![Screenshot 2024-10-29 at 17.38.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a4aba4dc-7b4c-9ed8-55f1-e6a6998d424e.png)

レポートの自動生成機能を使ってみます。

![Screenshot 2024-10-29 at 17.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b6db543b-a363-bf42-1e4c-25c0ddffa817.png)

ちゃんとリレーションシップを考慮してダッシュボードを作ってくれました。すごい。

![Screenshot 2024-10-29 at 17.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ec8a9a0f-945d-c8a6-26b0-65567099fd3b.png)

データはコピーされるのではなく同期されるので、データバージョンの違いに起因する問題などを回避することができます。Databricksから簡単にPower BIにデータ連携できる機能、是非ご活用ください！

### はじめてのDatabricks

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

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
デザインパターンを教えるときに気を付けること　ー例えは豊富にー

最近、新人にデザインパターンを教えているため、その時に気を付けていることの一つをここに書きます。

### 例えを豊富に準備する
デザインパターンを説明する際、複数の具体例を持つようにしています。例えば、Chain of Responsibilityパターンなら、一般的な「たらい回し」の例や、複数条件を使った並べ替えの例など、状況に応じた異なる比喩を使います。

### なぜ例えを多く持つのか
学ぶ人のバックグラウンドはさまざまなので、理解しやすい例は人によって異なります。例えば、グラフ理論を知っている人にはCompositeパターンを「木構造」として説明できますが、そうでない人にはエクスプローラーのフォルダツリーの例が分かりやすいこともあります。反応を見ながら最適な例えを選ぶことで、相手の理解が深まります。
SPring-8 BL37XU の 2D_Data_Viewer 代替スクリプト

## Abstract
私が時々利用する放射光ビームラインに[SPring-8のBL37XU](https://bl37xu.spring8.or.jp/)があります。HXマイクロビームでイメージングもできて嬉しいのですが, 取得したマップのビューワーである Labviewベースのソフト 2D_Data_Viewer がどうしても私の環境で走らなかったので代替となるスクリプトを書きました。

https://bl37xu.spring8.or.jp/

スクリプトと同じディレクトリにあるマップの生データファイルを適当に読み込んでtif画像ファイルを新たに作るディレクトリ "processed" の下に出力するだけの簡単なpythonスクリプトです。吐き出されたtifファイルはImageJなんかで解析できます。高速化を特に考えてないので5重forループとかいう本職が見たらぶっ倒れるだろうことを平気で書いてます。赦してくだしあ

## Script
ファイルごと, ROIごと, スキャン高さ, スキャン幅, SDDのチャンネルごとにループをかけました。途中でスキャン方向を判別して条件分岐
~~~python:map_to_tif.py
# この .py ファイルを 生データと同じ階層 に配置
import os
import re
import gc
import pandas as pd
import numpy as np
from PIL import Image

# setting global params
files = os.listdir()
files.remove('map_to_tiff.py')

# 生データファイルがあるディレクトリに格納されるはず
for file in files:
    lines = []
    with open(file, 'r', encoding = 'UTF-8') as paramset:
        line_num = 0
        while line_num < 10:
            line_num += 1
            txt = paramset.readline()
            lines.append(txt)
# 正規表現の練習がてら
    x_start = re.findall(r'\D\d+\.\d+', lines[4])
    x_end = re.findall(r'\D\d+\.\d+', lines[5])
    x_step = re.findall(r'\D\d+\.\d+', lines[6])
    z_start = re.findall(r'\D\d+\.\d+', lines[7])
    z_end = re.findall(r'\D\d+\.\d+', lines[8])
    z_step = re.findall(r'\D\d+\.\d+', lines[9])

    scan_width = int((float(x_end[0]) - float(x_start[0]))/float(x_step[0])) # スキャンの幅
    scan_hight = int((float(z_end[0]) - float(z_start[0]))/float(z_step[0])) # スキャンの高さ
    
    del lines, line_num, txt, x_start, x_end, x_step, z_start, z_end, z_step
    gc.collect()

# スキャン方向判別
# 初動の座標値変化をみる
    df = pd.read_csv(file, header = 12, sep = '\t')
    ch_num = 7 # しばらくCh数は変わんないと思う
    roi_num = int((df.shape[1] - 4)/ch_num -1)
    if abs(df['x/um'][1]-df['x/um'][0]) > abs(df['z/um'][1]-df['z/um'][0]):
        on_the_fly = 0
    else:
        on_the_fly = 1
    for m in range(roi_num):
        os.makedirs('processed/' + file, exist_ok=True)
    
    print(file)
    for i in range(roi_num):
        im_2d = np.zeros((scan_hight, scan_width))
        if on_the_fly == 0:
            for j in range(scan_hight):
                for k in range(scan_width):
                    for l in range(ch_num):
                        im_2d[j][k] += df['ROI'+str(i + 1)+'_Ch'+ str(l + 1)][k + scan_width*j]
                    im_2d[j][k] = im_2d[j][k] / df['ch1(I0)'][k + scan_width*j]
            img = Image.fromarray(im_2d)
            img.save('processed/' + file + '/roi_' + str(i + 1)+'.tif')
        else:
            for j in range(scan_width):
                for k in range(scan_hight):
                    for l in range(ch_num):
                        im_2d[k][j] += df['ROI'+str(i + 1)+'_Ch'+ str(l + 1)][k + scan_hight*j]
                    im_2d[k][j] = im_2d[k][j] / df['ch1(I0)'][k + scan_hight*j]
            img = Image.fromarray(im_2d)
            img.save('processed/' + file + '/roi_' + str(i + 1)+'.tif')
~~~
[Github](https://github.com/KMEZ-PG/BL37XU_mapconverter)

## Notes
本スクリプトは2024年4月現在の仕様に基づいて記述しています。
標準ライブラリのほかにpandas, numpy, pillowを使用しています。
再実行する際は既に作られている "processed" ディレクトリを移動するか削除してください。
Webサービスを構築する時は、ファイアウォールの設定を忘れるな

# はじめに
GCE のVMインスタンス上に「Unleash」を構築しましたが、
ファイアウォールルールの設定をせずにUnleash のWeb サービスにアクセスしようとしたため、接続できない問題が発生しました。
本記事では、この事象と対応方法について紹介します。
なお、Unleash 以外のWeb サービス構築にも応用できる内容なので、同じ問題に直面した際の参考になれば幸いです。

# 当時の環境
GCE 上にVM インスタンスを作成しており、その上にUnleash を構築しました。
Unleashの構築手順は、https://github.com/Unleash/unleash?tab=readme-ov-file#getting-started-with-unleash に従いました。

# 発生事象
 * $ docker compose up -d でUnleash を起動
 * ブラウザからhttp://{VMインスタンスの外部IP}:4242 にアクセス（4242 はUnleash のポート番号）

しかし、期待していたUnleash のログイン画面が表示されず、接続失敗の画面が表示されました。
![接続失敗の画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877523/efcbc72c-a182-73d0-c719-ab1e74bbedbd.png)

# 原因の特定
まず、URLやポート番号が正しいか、Unleash が起動しているかを確認し、どちらにも問題がないことを確認しました。
次に、インスタンスのファイアウォール設定を確認したところ、設定が行われていないことが判明しました。
このため、インターネットからのネットワークトラフィックがすべてブロックされ、ポート4242 へのアクセスが失敗していました。


# 解決手順
以下の手順でファイアウォールルールを作成し、　アクセスを許可しました。
1. GCP コンソールで「VPCネットワーク」→「ファイアウォール」に移動
1. 「ファイアウォールルールを作成する」を選択
1. 画面遷移後、以下の内容を設定
![ファイアウォールルール作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877523/e17190b5-d4c0-4739-5b7e-b8e777e9d769.png)

    * ターゲットタグ
        * 識別しやすい名称を設定
    * 送信元IP 範囲
        * 0.0.0.0/0
        * アクセス制限が必要な場合は、特定のIPアドレス範囲を指定
    * プロトコルとポート
        * TCP を選択し、ポート番号に4242 を入力
1. VM インスタンス のネットワークタグに、作成したファイアウォールルールのネットワークタグを設定
1. Unleash を再起動
1. ブラウザからhttp://{VMインスタンスの外部IP}:4242 にアクセスし、正常にページが表示されることを確認 ![Unleashログイン画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877523/12f17184-ad47-d77d-ce73-97fd6059924f.png)


# 最後に
ファイアウォールの設定を失念していたため、原因特定に時間がかかりました。
今後同様の問題が発生した場合はまずファイアウォールの設定を確認するようにしたいと思います。
この記事が同じようなトラブル解決の参考になれば幸いです。

# 参考記事
https://cloud.google.com/firewall/docs/firewalls?hl=ja

https://cloud.google.com/vpc/docs/using-firewalls?hl=ja
Microsoft Fabricチュートリアル躓きポイント解決集：Power BI

[チュートリアル: Power BI ユーザー向け Fabric](https://learn.microsoft.com/ja-jp/power-bi/fundamentals/fabric-get-started)の手順に沿ってチュートリアルを実施していくうえで、ドキュメント通りに操作してもうまく動作しなかった点をまとめました。

:::note info
ドキュメント通りでないパターン例
+ ドキュメント通りに実行したのにエラーになる
+ ドキュメントと実際のUIが違う
:::

少しでも皆さんの参考になれば幸いです。

# 躓きポイント①：データ格納先を追加する 1.
ドキュメントの画面では「データの同期先の追加」が選択できるが、実際の画面ではグレーアウトされていて選択することができない
▽ドキュメントの画面
![ドキュメントの画面①](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/3cc2930b-194a-35d3-42ea-ba39218b1200.png)
▽実際の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/f2723db2-7d0e-b5b7-61dd-2383cdfdde40.png)

### 対策
画面右側のデータ接続先の設定アイコンを押すと、チュートリアルの2.と同じ画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/89c13ead-fa4f-15d9-f1ab-641138093f7f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/044c6076-69ad-4f97-58cd-1c332ab0bdb9.png)

# 躓きポイント②：データパイプラインを調整する 16.
RUNを押すと、エラーメッセージが出てくるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/9b273337-5d88-7a7f-51e9-9f79c2978147.png)

### 対策
Bodyに適当な文字を入力し、再度実行するとエラーメッセージは消える
今回は"a"と入力してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/f1085072-d7e5-8968-c638-2b6c80d23a9c.png)

# 躓きポイント③：DAX でメジャーを作成する 1.
ドキュメントにはNew Measure ボタンがあるが、環境によってはこのボタンが表示されない
そもそもTable toolsタブが表示されていない
▽ドキュメントの画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/c6a34196-5641-cd76-537b-2b35971aa7a6.png)
▽実際の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/e82bb589-00de-c0db-7f52-1c75dfa9cd0e.png)

### 対策：セマンティックモデルを新規作成し、作成したセマンティックモデルの方でDAXメジャーを作成する
※SQL ビューを作成するまで終了してから行ってください

1. 報告タブから新しいセマンティックモデルをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/1e29100e-a953-ca15-fffe-26551e336cd6.png)

2. 各項目を入力し、すべてのテーブルとビューを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/77b94cd4-5be0-3a0d-9cc3-d80afea59131.png)

3. 作成したセマンティックモデルからデータモデルを開き、再びリレーションを引く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/c4e38c58-303f-e793-d574-13131f1879eb.png)

4.テーブルを右クリックまたは、テーブル右上の・・・から新しいメジャーをクリックし、ドキュメント通りメジャーを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/c074f688-a9e2-17bd-8f2b-e60664ac1453.png)
Goで実装したdll(so)から取得した文字列のメモリを開放する

# TL;DR
文字列をctypes.c_char_pではなく、ctypes.POINTER(ctypes.c_char)で受け取り、ctypes.string_atで文字列を取得した後メモリを適切に開放する。
```python
lib = ctypes.CDLL("./mydll.dll")
lib.GetString.restype = ctypes.POINTER(ctypes.c_char)
#コールバックの引数の場合も同様
CALLBACKFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.POINTER(ctypes.c_char))

result_pointer = lib.GetString()
result_str = ctypes.string_at(result_pointer)
print(result_str) # -> hogehoge
ctypes.cdll.msvcrt.free(result_pointer) #メモリを解放
```
# 経緯
諸事情があり、受け取ったデータを適切に処理してJSON形式で返すプログラムをGoで記述し、dll化してPythonから呼び出すような実装をした。Python側で繰り返しdllの関数を呼び出していると、Pythonプログラムのメモリ使用量が際限なく(GB単位)上昇していっていることに気づいた。メモリリークが発生しているとすればdll周りであろうと考え、対応を行うことにした。

# 対応
まずGoogleで検索してみると、GoでC.CStringを用いて返した文字列のポインタは関数を呼び出した側で解放すべきであることが分かった([参考記事](https://zenn.dev/mattn/articles/23f4e202eb1f35#%E3%81%8A%E3%81%BE%E3%81%91))。
今回問題に遭遇したGo側のプログラムは以下のようなもの。
```go
//export GetString
func GetString(arg C.int) *C.char {
	res := someFunc(int(arg))
	bytes, err := json.Marshal(res)
	if err != nil {
		return C.CString("")
	}
	return C.CString(string(bytes))
}
```
C.CStringで文字列を返している。そして、Python側はというと
```python
lib = ctypes.CDLL("./mydll.dll")
lib.GetString.restype = ctypes.c_char_p

result_pointer = lib.GetString()
result = json.loads(result_pointer)
print(result)
```
特にメモリの開放を意識していなかったためメモリリークが発生したようだ。そこで、以下のようにコードを変更した。
```python
lib = ctypes.CDLL("./mydll.dll")
lib.GetString.restype = ctypes.c_char_p

result_pointer = lib.GetString()
result = json.loads(result_pointer)
ctypes.cdll.msvcrt.free(result_pointer) #メモリを解放
print(result)
```
この変更ですべてうまくいくはずだった。しかし実際に実行してみると、`0xC0000374`というエラーが発生する。これはメモリの開放に失敗したことを意味する。よくよく調べてみると、c_char_p型として読み込むと自動的にバイト配列へと変換されポインタとして扱えなくなってしまうらしい。どうしたものかと思っていた所たどり着いたのが[こちら](https://stackoverflow.com/questions/78859283/unreachable-python-and-go-code-after-trying-to-free-c-cstring-from-python).ちょうど必要としていたことが全部書いてあった。冒頭に示した通り、ctypes.POINTERを使う形に書き直したところ、無事にメモリ使用量が爆発することはなくなった。めでたしめでたし。
初心者プログラミングバイト生活八日目【シーン作成やっぱりイミフ】

今日は、火曜日。いつも通りに10:00からのバイトに向かい、バイトをする。

今日は前回苦戦したシーン作成のリベンジということで張り切っていたのだが、、、、、、

意味不明なバグ(シーン作成にはあまり関係のないところ)があってそれが気になりすぎてめちゃめちゃ時間を食ってしまった。。。

まあそれは置いといて、肝心のシーン作成だが、またもや苦戦して画面が映らなかった。

シーンが始まってから終わるまでの流れがなんにし難しいんですねぇ。

今わかってることを、復讐がてらに書いてみる。

AppMainNextProIDでシーンが呼び出される

→SceneのInitが呼び出される

→その中で、ChangeProcessが呼び出され、関数ポインタに最初の関数が代入される

え、こんだけかも。Sub stepとかも色々理解はしたけど、部分的に理解しただけで、全部が繋がってないんだな。

てことで明後日は、ノートを使って、関数とかの流れを書いてみよう。

そうだそれだ。それをやってみる。

ちなみに今日は社会学Ⅱが突然休講になり、バイトフルで入れるじゃん！と思ったけど、バグやら何やらでもう😕って感じやったからやめた。

雨も降ってて帰ってくるのに濡れたし、さいあくだ。

まあでも夜は食堂で美味しいご飯たべられるから幸せ😃

実務と独学ってえげつない壁あるなぁ。。。。

任天堂入るまでに経験できてまじでラッキー。

なんか京大は、成績カスやったけど高校1年の時から謎にイケる自信あったけど、

任天堂はなんか話違うわ。まあやるべきこととかが決まってないとかが大きい原因かもね。

受験なんてやるべきこと決まってる時点で実は超楽勝だったりする。これはイケシロも言ってた。

任天堂まじはいりたーーーーーーーーーい
React入門ガイド：初心者のための完全解説

## Reactとは？
Reactは、Facebookが開発・維持しているJavaScriptライブラリです。ユーザーインターフェース（UI）を構築するための、最も人気のあるフロントエンドライブラリの一つです。

### Reactの主な特徴
1. **コンポーネントベース**
   - UIを小さな独立した部品（コンポーネント）に分割して開発
   - 再利用性が高く、保守が容易
   - コードの見通しが良くなる

2. **仮想DOM（Virtual DOM）**
   - 実際のDOMの軽量なコピーを使用
   - 効率的な差分更新により高いパフォーマンスを実現
   - 開発者はDOMの直接操作を気にする必要がない

3. **単方向データフロー**
   - データは親から子へ一方向に流れる
   - 予測可能で分かりやすい状態管理
   - デバッグが容易

## 他のフレームワークとの比較

### Vue.js との比較
- **Vue.js**
  - より緩やかな学習曲線
  - テンプレート構文が直感的
  - 小〜中規模プロジェクトに最適
  
- **React**
  - より柔軟な設計が可能
  - JavaScriptの知識をより活かせる
  - 大規模プロジェクトでの実績が豊富

### Angular との比較
- **Angular**
  - フルスタックフレームワーク
  - TypeScriptが標準
  - より厳密な構造化が必要
  
- **React**
  - より軽量
  - 学習コストが比較的低い
  - 必要な機能だけを選んで使える

## Reactを選ぶべき理由
1. **大きなコミュニティ**
   - 豊富な学習リソース
   - 多くのライブラリやツール
   - 問題解決が容易

2. **高い求人需要**
   - 多くの企業が採用
   - キャリアの選択肢が広がる

3. **モバイルアプリ開発も可能**
   - React NativeでiOS/Androidアプリ開発が可能
   - Webの知識を活かせる

## 基本的な使い方の例

```jsx
// シンプルなコンポーネントの例
function Welcome(props) {
  return <h1>こんにちは、{props.name}さん</h1>;
}

// 状態を持つコンポーネントの例
function Counter() {
  const [count, setCount] = React.useState(0);
  
  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        増やす
      </button>
    </div>
  );
}
```

## 始め方
1. Node.jsをインストール
2. Create React Appで開発環境を構築:
```bash
npx create-react-app my-app
cd my-app
npm start
```

## まとめ
Reactは現代のWeb開発において最も重要なライブラリの一つです。初心者にとっては学習曲線がやや急かもしれませんが、一度基本を理解すれば、効率的で保守性の高いアプリケーションを開発できるようになります。大きなコミュニティのサポートがあり、継続的に進化を続けているため、Web開発の重要なスキルとして習得する価値が十分にあります。
# pulumi を試してみた (プロキシ環境下)

試してみたときのメモ。

IaC としては terraform をメインで使っているが、
他の選択肢を模索中。

一番気になるのは aws lambda 周りだが、とりあえず試せたところまで。

## 私的要点まとめ

- pulumi cloud にスタックを作ってそこからデプロイする
  - 有料版でのサポートとかを上手く使えれば結構なメリットが得られるかもしれない
- cdk よりはデプロイが速い
  - というか cdk が cloudformation 経由なので遅い
- メソッドは terraform と似ている感じがする
- python でオブジェクト管理と変数渡しが可能
  - 変数渡しが手っ取り早くできる (良し悪しは別として)
- IaC 以外のサービスもある
- aws 以外にも使える

## 試したこと

S3 だけ作ってみた。
チュートリアルでバケット作成、ファイルアップロード、静的ウェブサイトホスティングをやっている。

dynamodb と lambda についてはドキュメントを読んだだけ。

lambda にサードパーティライブラリを入れる時にどうするかが気になるところだが、
触れている記事があまり見つからなかったので結局頑張ることになりそう。

[これ](https://www.pulumi.com/ai/answers/iWoQW6uT1Yy7YRXyDQBvLS/deploying-aws-lambda-with-dependencies-in-python)
が近い感じだが、他に同じような記事が見当たらない。

## セットアップ

[公式サイト](https://www.pulumi.com/docs/iac/get-started/aws/)の通りにやったので、気になったところだけピックアップ。

### pulumi にログイン

サインアップして CLI からログインする。

クラウド経由で実行する形になるっぽい。

アップロードしたくない気持ちはあるが、設定ファイルをどこに置いたかわからなくなるよりはマシかという気持ちもある。

### プロジェクト作成

`pulumi new` でプロジェクトを作成する。

python の場合は venv の作成も行われた。

### プロキシ

grpc を使っている都合で、`http_proxy` と `https_proxy` があるとエラーになるらしい。

とりあえず `unset` して対応。

`HTTP_PROXY` と `HTTPS_PROXY` は残したまま、プロキシ環境下でデプロイできた。

### デプロイ

`pulumi up` で差分の確認とデプロイを実行する。

pulumi cloud にスタックを作成してそこからデプロイする形になる模様。

このスタックの数とかデプロイ回数とかで料金が発生するっぽい。

## 料金関係

### 無料版の制限

月あたりのリソース数が制限されている模様。

Team プランだと無料枠を超えた分だけ課金されるらしい。

### 有料版の機能

企業向けサポートや削除したリソースの復旧、セルフホステッド（自前のサーバに pulumi cloud を置く？）などがある。
[tips][python] numpy

# ブロードキャスト機能

## 配列

tipsです。メモなので日々追記していきます。


xには単一値でも配列でもよく、配列の場合は各要素に対して定めた演算を行い、和をとるとかしてくれるのがブロードキャスト機能。

```python
import numpy as np
def function_2(x):
	return np.sum(x**2)

a = np.array([1, 2, 3])
res = function_2(a)
print("二乗和", res)
```

```python
二乗和 14
```

- エラー

**np.array() 関数による生成**ではなく次のようにただのリストにすると、numpyがかた推論できずエラーになります。

```python
c = [1, 2, 3]
res = function_2(c)
print("二乗和", res)
```

```python
TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
```

## 参考

https://www.kamishima.net/mlmpyja/nbayes1/ndarray.html
# aws cdk を試してみた感想

python と typescript をちょっとだけ試した感想

## 背景

IaC として terraform と SAM を使っていたが、他の選択肢を模索中。
lambda がいい感じに作れるかどうかが気になっている。
特に python での外部ライブラリをサクッと入れたい。

sam の lambda デプロイだとランタイムに合わせたビルド用コンテナを使って
requirements.txt から自動でインストール・zip化までしてくれる。
これがとても便利な一方、sam だと作れるリソースに制限があるので、
今は terraform との併用で使っている。

## まとめ

- aws cdk
  - ◯
    - 慣れた言語で書ける
    - cloudformation スタック = オブジェクト になるのでわかりやすい
  - △
    - aws でしか使えない
    - ブラウザからの操作が実質できない
- sam
  - ◯
    - lambda のデプロイが簡単
  - △
    - サーバレスのリソースしか作れない
    - 記法が独特
- terraform
  - ◯
    - 一つ一つの設定内容はわかりやすい
    - aws 以外でも使える
  - △
    - 設定を探すのが難しい

## aws cdk

一般的なことは公式サイトに任せて、個人的に気になったところだけメモ。

- 内部的には cloudformation を使っている。

  - プログラム側でスタックに対応するオブジェクトを作って、それをデプロイして実際のスタックを作る。
    その後スタックから各リソースを作る、という感じ。

  - python のオブジェクト操作の感覚で操作できるところは大きなメリットかもしれない。
    terraform でもモジュール分割とかで同じようなことはできるが、モジュールでデータを受け取るのが面倒だったような。

- terraform がリソース一つずつの管理になるのに対して、aws cdk はスタック単位での管理になるのでわかりやすいかも。

  - terraform だと依存関係の順序を勝手に解釈してくれるが、一方で順序がわかりにくくなっているかもしれない。

## おわりに

当面は terraform で良さそう。

lambda に python ライブラリを入れることについては、
terraform からコンテナでビルドしたり、sam でレイヤーだけ作るとかにするのが良さそう。
パケットの経路を探索

パケットは目的地までどのように届くのだろうか？

# ルーティング＝経路の探索
>インターネット上でデータを届けるには、`ルーターがどのルーターに繋がっているかを調べ`ていき、`宛先までの経路を見つけ`なければいけません。そのための仕組みがルーティングです。なるべく`最短の経路を探し`、`経路途中で障害が発生していたら別ルートを探す`必要があります。

* `ルーターがどのルータと繋がっているか`をどうやって調べるのか？

https://qiita.com/masatom86650860/items/a50c36db0752a6ccb885
* `宛先までの経路を見つけ`るにはどうするのか？

https://qiita.com/masatom86650860/items/708af8863ec525a38d6f


* `最短の経路を探し`方は何か？

https://qiita.com/masatom86650860/items/28d15eebab762ddd902f
* `経路途中で障害が発生`はどう確かめるのか？

見つけられなかった。
* 送っている最中に障害が発生した場合はどうなるのか？

見つけられなかった。
模写コーディングに初挑戦(2) アレンジ

[模写コーディングに初挑戦（１）](https://qiita.com/zosanmama/items/708bbdd4f4653ec4d12f)の続きです。

書きかけです。

### HTMLの全体コーディング・続き

コーディングの前作業に結構いろいろと注ぎ込んだけれど、ようやくメインの作業に入る。
レイアウトやパーツ名を書いた、構成図を出してくる。
![layout_composition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683665/dbfd523e-dcea-e9d7-43ab-eb03fa5552e2.png)

それをみながら、`index.html` の`<body>` に全体の構成をいれる。図でいうと、オレンジ・緑・ピンクの部分を、サイトの骨組みとして記述するイメージ。
```
  <body>
        <header id="header"></header>
        <main>
            <div id="mainvisual"></div>
            <section id="about"></section>
            <section id="works"></section>
            <section id="news"></section>
            <section id="contact"></section>
        </main>
        <footer></footer>
    </body>
```

模写コーディングの手順を読むと、ここで、HTMLにCSSを当てていくのがよいとあるので、CSSも書き始める。 `css` フォルダーを作成し、その中に `style.css` を作成。一行目に `@charset "UTF-8";` と記述した。

HTML内の要素に、CSSを当てていこう。

現状の `index.html` にあるのは、
1. html
1. body
1. header
1. main
1. div mainvisual
1. section about
1. section works
1. section news
1. section contact
1. footer
になる。

### 1. html
まず、**html**に指定したいのは、サイト全体へのグローバルなスタイルの設定。
- 全体の高さと幅の設定
- フォント（サイズ/ファミリー）
- 色設定（テキスト色/背景色）
- ベースラインリセット
- スクロール設定

実際のサンプルサイトを見ながら、設定してみるとこんな感じに。
```
html {
  min-height: 100%;
  font-size: 62.5%; /* 基準が10pxになり、フォントサイズ計算が楽になる */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "ヒラギノ角ゴ Pro W3", "Yu Gothic", "Meiryo", sans-serif;
  color: #333; /* テキストの色 */
  background-color: #fff; /* 背景色 */
  /* ブラウザデフォルトの余白をリセット */
  margin: 0;
  padding: 0;
  scroll-behavior: smooth; /* スクロールの設定を滑らかに */
}
```

#### 2. body
次に、**body**に指定したいのは、サイト全体の見栄えを整えるために、基本的なデフォルトスタイル。

- ブラウザデフォルトの余白とパディングをリセット
- レイアウト設定
その他、　**html**で指定した項目もここで指定することもできる。
【個人メモ】Ruby on Rails チュートリアル 第4章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです
# 個人メモ
- カスタムヘルパー
自作のメソッドをカスタムヘルパーと呼ぶ
Railsでは自動的にヘルパーモジュールを読み込む
したがって自動的に全てのビューで利用できるようになっている
- コンストラクタ
クラスからインスタンスを生成する処理のこと
ex) s = String.new("a")
- リテラル
“”で囲んだものを文字列リテラル、123などを数値リテラルと呼ぶ
- ２つのメソッド
クラスが直接呼び出すメソッドをクラスメソッド、インスタンスが呼び出すメソッドをインスタンスメソッドと呼ぶ
- ユーザークラスの作成について
ユーザー名とメアドについてのアクセサー
attr_accessor :name, :email
アクセサーを作成すると、そのデータを取り出すメソッド（getter）と、データに代入するメソッド（setter）をそれぞれ定義してくれる
- シンボル
シンボルはRailsではラベルとして用いられる
追加的な構造を持たない（代入などができない）文字列みたいなもの
G-LEAPの投稿一覧

# 概要
筆者が現在所属している組織では、共通アカウントを使用してQiitaに記事を投稿しているため、本記事を作成し、筆者が組織で投稿した記事を一覧化していきます。（随時更新予定）

https://qiita.com/organizations/g-leap

# 記事一覧
## Terraform関連
- [Terraformのprovider等のバージョン制約と不整合について](https://qiita.com/GleapPost/items/50d080a81420fc81bc6e)
- [Terraform Cloud利用時のmodule参照エラーについて](https://qiita.com/GleapPost/items/1d3cf71a34aa44bda878)
- [Terraformで利用する外部モジュールの参照エラーについて](https://qiita.com/GleapPost/items/8191aed27428d0f23f4f)
- [API経由でTerraform CloudのWorkspaceの設定を変更する](https://qiita.com/GleapPost/items/92b67a0f096c2017f906)
- [Google CloudのAPI GatewayでAPI Keyを使用したAPIを作成する - Terraform編](https://qiita.com/GleapPost/items/ce9027d9191b40ee1c53)
- [Terraform Cloudでtfvarsファイルを使う方法](https://qiita.com/GleapPost/items/e6d75699957daf9832b6)
- [HCP TerraformでGoogle Cloudのクレデンシャルを設定する方法](https://qiita.com/GleapPost/items/b933b23a42eb3df40272)
- [Terraformのコメントの書き方について](https://qiita.com/GleapPost/items/e8be2706872d70d8f9ac)

## Google Cloud関連
- [GCPのAPIGWにおけるAPI更新方法について](https://qiita.com/GleapPost/items/e34b42ad6a83600cabcc)
- [GeminiのPython SDKを使ってみた](https://qiita.com/GleapPost/items/2ef2e95fb0dce765bdfe)
- [Google CloudをNew Relicにリンクする](https://qiita.com/GleapPost/items/c72563d3224c460ed8fc)
- [Google CloudのAPI GatewayでAPI Keyを使用したAPIを作成する](https://qiita.com/GleapPost/items/799c83e3b26eebb0f3d6)
- [Cloud Monitoringでログ監視をやってみた](https://qiita.com/GleapPost/items/43863d9bdc56a6c995ac)
- [BigQueryのビュー情報のバックアップについて](https://qiita.com/GleapPost/items/e965d63dd126a3a6f29b)
- [Googleで管理されているサービスアカウントについて](https://qiita.com/GleapPost/items/92e1d0350514b1bc52b4)
ルーティングプロトコル

# 距離ベクトル型
>RIPなどのプロトコルが利用する方式で、`宛先までの距離`（ホップ数＝ルーター間で転送する回数）を調べて、`距離の短い経路を選択`します。シンプルなネットワーク構成に向けており、`主にLAN内で使われ`ています。

https://www.sbcr.jp/product/4797396072/

* 宛先までの距離を調べて距離の短い経路を選択します
* LANで使われることが多い
* RIPとは？

>### 距離ベクトル・ルーティング
>...
>それぞれのルーターに宛先ごとの`最短距離`と`その経路をテーブル（ベクトル）の形`で保持する。このテーブルは`隣接ルーターと情報を交換することで更新`される。その結果、すべてのルーターが、それぞれの宛先へ最短で到達するための転送先リンクを把握できる
...
各ルーターはルーティング・テーブルを持ち、ネットワークの他の各ルーターに対して一つずつエントリを保持する。このエントリは、その`宛先に対する最適なパケット転送先リンク`と`その宛先までの推定距離`の二つの構成要素からなる。推定距離の算出には、`ホップ数`が用いられることもあれば、`最短経路を計算する際に紹介した他の尺度`が用いられている場合もある。
　ルーターは各隣接ルーターとの「距離」を知っていると仮定する。`尺度がホップ数だとすると、距離は1ホップ`である。`尺度が伝搬遅延時間だとすると、特別なECHOパケットを発行して、受信側がタイムスタンプを付けて直ちに送り返すことで直接的に時間を測る`ことができる。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
* エントリとは何か？
* パケットの宛先リンクと推定距離でエントリが構成される
* 推定距離はホップ数だけではなく他にもある。
* どうやってルーターは宛先ごとの最短距離とその経路を知ることができるのか？

# リンク状態型
>`OSPF`などのプロトコルが利用する方式で、`ネットワークの接続状態を表すマップを作成し、それから最適な経路を探し出し`ます。`複雑で変化しやすいネットワーク構成`に向かいます。

https://www.sbcr.jp/product/4797396072/

* OSPFとは？
* ネットワークの地図を作り、そこから最適な経路を探し出す

>距離ベクトル・ルーティングは1979年までARPANETで用いられ、その後はリンク状態ルーティングに置き換えられた。この変更のきっかけとなった最大の要因は、距離ベクトル・ルーティングではネットワーク・トポロジに変化が会った時、アルゴリズムの収束に非常に長い時間がかかる場合があるという点である。そのため、距離ベクトル・ルーティングはリンク状態ルーティングと呼ばれる新しいアルゴリズムに置き換えられた。現在では、`リンク状態ルーティングの一種であるIS-ISやOSPF`が、大規模ネットワークやインターネットで最も広く用いられているルーティング・アルゴリズムとなっている。
　リンク状態ルーティングの考え方は非常に単純であり、次の５つの部分に分けられる。リンク状態ルーティングが機能するためには、核ルーターは次のことを実行しなければならない.
>* `隣接ルーターを調べ、そのネットワーク・アドレスを取得`する。
>* 隣接ルーターそれぞれに対して、`距離あるいはコストを設定`する
>* `収束した情報を全て含むパケットを構成`する
>* このパケットを全ての隣接ルーターに送付し、`同様のパケットを全ての隣接ルーターから受け取る`
>* 全てのルーターに対する`最短経路を計算`する
>
>結果として、完全なネットワーク・トポロジの情報が全てのルーターに配信される。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

* 隣接する全てのルーターに対してそれらが隣接するルーターの距離を送らせ全体のネットワークの最短距離を測ることができる。
* アルゴリズムの問題でこういう感じの問題を解いた覚えがある

https://www.ap-siken.com/kakomon/06_haru/pm03.html
#### トポロジとは
https://qiita.com/masatom86650860/items/7b1d7a7ea2a99e24988f
よく見る「x86」「x64」「IA-64」とはなにか？

## 答え
CPUのbit数を表す表示
注意としてx64のほうがbit数が多い

<table>
    <tr>
        <th>表記</th><th>bit数</th>
    </tr>
    <tr>
        <td>×86</td><td>32bit</td>
    </tr>
    <tr>
        <td>×64</td><td>64bit</td>
    </tr>
    <tr>
        <td>IA-64</td><td>64bit</td>
    </tr>
</table>

## 32bit版が×86と呼ばれているのは何故？

78年に発売されたマイクロプロセッサ(MPU)の型番が『`8086`』だったので後半の桁『`86`』を使用している。
（正確には`8086`は16bitなのだが、後に32bitに拡張された`80386`が登場したため32bitとして使われている…）

![ダウンロード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796579/3187230b-5b36-0fa1-de6b-993558d8fe39.jpeg)
写真:Intel 8086

## 64bitだから×64と呼ばれているの？
ほとんど"はい"

×86(32bit)では限界が見え始めた頃に現れた64bit版の×86系、通称`×86-64`
これを省略して`×64`と呼ばれる

## IA-64とは？
正式名称「Intel Architecture 64」
文字通りIntelがヒューレット・パッカード社と協力して作ったアーキテクチャ。
×86をIA-32と位置づけ、その次世代として作られたが色々あって余り使われなかった。

そして…

https://pc.watch.impress.co.jp/docs/news/1168049.html


## 参考
https://htech.blog.fc2.com/blog-entry-699.html

https://wa3.i-3-i.info/word13410.html
ROSでimage_viewの動画が保存できないとき

# image_viewで動画が保存できない
ROSを使っていて、カメラ画像をsubして、何かをしてpubしたときに、
その画像をRvizやimage_viewで見られるのに、なぜが、image_view video_recorderで保存しようとすると、できない。aviはできてるけど、開くと見れない。ってときは、

headerを確かめてください。frame_idありますか？stampありますか？
なければ、プログラム中でtopicをpubするまえに、

```
    topic名.header.frame_id = 'なんか良い感じのID'
    topic名.header.stamp = rospy.Time.now()
```

こんな感じで、両者を追加すると解決するかも。

3時間ハマッた…。
YoomとSalesforceの連携　 INVALID_SESSION_ID



相変わらずsandboxには接続できませんね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7e036127-98b1-0b52-d462-ad08ae81a7a4.png)


以下のヘルプの設定をやってみましたが、やはり INVALID_SESSION_ID　エラーです。

https://help.salesforce.com/s/articleView?id=000387018&type=1

アカウント情報をyoomのアカウントと同じメールアドレスに変えてみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7b82e16b-3ab9-99e0-eff4-989ba1d9b6de.png)



以下のエラーに変わったということは、接続できたのかも...

```
[
  {
    "message": "「費用管理メインフロー」処理失敗により、このレコードを保存できません。Salesforce システム管理者に次の詳細を報告してください。An Apex error occurred: System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set\n エラー ID: 375153965-13468 (-920844619)on: Malformed JSON: Expected '[' at the beginning of List/Set\n エラー ID: 375153965-13468 (-920844619)",
    "errorCode": "CANNOT_EXECUTE_FLOW_TRIGGER",
    "fields": [

    ]
  }
]
```

このアカウントって何のことだろう？



# エラーの中身

以下のようなJsonを期待していますが...

```
[
[{"column_number":"0","value":"収入印紙"},{"column_number":"1","value":"600 円 × 5 枚 = 3,000"}],
[{"column_number":"0","value":"収入印紙"},{"column_number":"1","value":"1,000 円 × 3 枚 = 3,000"}],
[{"column_number":"0","value":"切手"},{"column_number":"1","value":"460 円 × 3 枚 = 1,380"}]
]
```
tableのところで＋を押して追加します。ここでは見た感じ[がある



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/23936b26-92cc-f83e-0b66-1c860ac9001f.png)


取得した値にも[[がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d54faaea-d7ff-d6be-71c0-7f8ee945315b.png)

保存前にもちゃんとある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2e907554-2082-13ef-3fa1-07d64decf64b.png)


しかし何故か、保存後には以下になりますね。バグだろう。これだからこんなツールは信用できん。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d815dab3-f758-73c3-e34b-08e3a80274fe.png)


```
{"column_number"=>"0", "value"=>"収入印紙"},{"column_number"=>"1", "value"=>"600 円 × 5 枚 = 3,000"},
{"column_number"=>"0", "value"=>"収入印紙"},{"column_number"=>"1", "value"=>"1,000 円 × 3 枚 = 3,000"},
{"column_number"=>"0", "value"=>"切手"},{"column_number"=>"1", "value"=>"460 円 × 3 枚 = 1,380"}
```
【JavaScrip】コールバック関数

JSのコールバック関数について勘違いしていたので、勉強し直したことをメモとして残します。

こんなところで引っかかってるやつもいるんだなと知ってもらえれば幸いです。
## コールバック関数とは
### 定義
>引数として他の関数に渡され、外側の関数の中で呼び出されて、何らかのルーチンやアクションを完了させる関数のこと
[Callback function (コールバック関数) | MDN Web Docs 用語集 ](https://developer.mozilla.org/ja/docs/Glossary/Callback_function)
### 簡単な例
```javascript:例1
const fn1 = a => a + 1; // コールバック関数
const fn2 = (b) => b(1) * 2;
fn2(fn1) // 4
```
例1では確かに`fn1`が外側の`fn2`内で呼び出されてから実行されているため、`fn1`はコールバック関数と言えます。（Chat GPTさんに確認したので間違いないはず！）
### 勘違い
ただ、コールバックとして使用される関数は必ずしも変数に代入（宣言）する必要はないということです。つまり、**無名関数で記述することができます**。私はずっと変数に代入して使うものだと思っていました。（そういう書き方をしている解説を多く見てきたので...）

```javascript:例2
const num = 1;
const fn = a => a() * 2;
fn(() => num * 3); // 6
```
上の例2で関数`() => num * 3`は変数に代入（宣言）せず、`fn`の引数として直接書かれていますが、これもコールバック関数となります。

アロー関数を使わずに書くと下のようになります。

```javascript:例2. アロー関数を使わない場合
const num = 1;

const fn = function(a) {
    return a() * 2; // ()は実行するの意味
}

fn(function() { // 無名関数として記述
    return num * 3;
}); // 6
```
冒頭でも書いているように、コールバック関数の定義は **『引数として他の関数に渡され、外側の関数の中で呼び出されて、何らかのルーチンやアクションを完了させる関数のこと』** です。

上の例2では関数`fn`内で渡ってきた引数`a`を**実行してアクションを完了**させるように`()`を記述しているところがポイントになります。

### 間違い例
以下のコードはどれもコールバック関数を使用できていません。
```javascript: コールバック関数ではない
// 例A
const num = 3;
const fn = a => a * 2;
fn(num + 1); // 8

// 例B
const fn1 = a => a + 1;
const fn2 = b => b * 2;
fn2(fn1(1)); // 4

// 例C
const num = 1;
const fn3 = a => a * 2;
fn3(() => num * 3); // NaN

// 例D
const num = 1;
const fn4 = a => a * 2;
fn4((() => num * 3)()); // 6
```
例Aは`num + 1`の結果をただ`fn`に渡しているだけで、これは関数ではありません。

例Bは先に実行された`fn1`の結果が`fn2`に渡っているだけです。[^1]

例Cは一見すると`() => num * 3`という関数を`fn3`に渡しているようですが、これは実行されず関数そのものをオブジェクトとして渡しているだけです。

例Dは`() => num * 3`が即時関数として実行され、その結果が数値として`fn4`に渡っているだけで、外側の関数`fn4`が呼び出している（実行している）わけではありません。

よって、どれも定義から外れています。

## 学んだこと
* コールバック関数は無名関数でもOK
* 関数の「実行される場所」を意識する


間違いやアドバイスなどあれば、コメントいただけると大変勉強になります。
[^1]:@junerさん、コメントでのご指摘ありがとうございました。
SamtoolsのFILTER EXPRESSIONについて（機械翻訳）

http://www.htslib.org/doc/samtools.html

samtools の FILTER EXPRESSION について、日本語でサクッと見返せるように、マニュアルをChatGPTに日本語に翻訳してもらいました。原文は `man samtools` もしくは、上のリンクから確認できます。

## FILTER EXPRESSIONS（フィルター式）

フィルター式は、SAM、BAM、CRAMレコードを随時チェックし、指定された条件に一致しないレコードを破棄するために使用します。

この言語は主にC言語スタイルに基づいていますが、ビット演算子の優先順位規則に若干の違いがあり、正規表現の一致もサポートしています。

### 演算子の優先順位

優先順位が高い順から低い順に並べています：

1. **グルーピング** `(`, `)`  
   例: `(1 + 2) * 3`
2. **値**: リテラル、変数  
   数値、文字列、変数
3. **単項演算子**: `+`, `-`, `!`, `~`  
   例: `-10`, `+10`, `!10`（論理否定）, `~5`（ビット否定）
4. **算術演算子**: `*`, `/`, `%`  
   乗算、除算、剰余（整数）
5. **算術演算子**: `+`, `-`  
   加算、減算
6. **ビット単位の演算**: `&`  
   ビットAND
7. **ビット単位の演算**: `^`  
   ビットXOR
8. **ビット単位の演算**: `|`  
   ビットOR
9. **条件演算子**: `>`, `>=`, `<`, `<=`
10. **等価演算子**: `==`, `!=`, `=~`, `!~`  
    `=~` と `!~` は正規表現の一致を確認します。
11. **論理演算子**: `&&`, `||`  
    論理AND、論理OR

---

### 演算の詳細

フィルター式の計算には浮動小数点演算が使用されるため、`10 / 4` は `2.5` となり、`2` ではありません。数値は10進数や16進数（`0x`を付与）で表現できます。浮動小数点も指数付きで表現可能です。  
ただし、整数を要求する演算では暗黙的に型変換が行われます。たとえば、`7.9 % 5` は `2` となり、`7.9 & 4.1` は `7 & 4` と等価で `4` になります。  
文字列は必ずダブルクォートで囲み、ダブルクォート自体を文字列内に含めるにはバックスラッシュを使用します（例：`ab\"c\\d` は `ab"c\d`）。

---

### 比較演算と未定義値の扱い

比較演算は一致した場合 `1`、不一致の場合 `0` を返します。たとえば、`(2 > 1) + (3 < 5)` は `2` になります。未定義（null）値を含むすべての比較は偽（false）と見なされます。

---

### 変数とSAMフィールド

変数はSAM形式のフィールドを表しており、これを使ってレコードをフィルタリングします。たとえば、高いマッピング品質（mapping quality）かつ非常に大きなインサートサイズを持つペアのアラインメントを探す場合、次の式を使用します：

```
mapq >= 30 && (tlen >= 100000 || tlen <= -100000)
```

使用できる変数とそのデータ型を以下に示します：

- `endpos`（int）: アラインメント終了位置（1-based）
- `flag`（int）: FLAGフィールド全体
- `flag.paired`（int）: シングルビット（0 または 1）
- `flag.proper_pair`（int）: シングルビット（0 または 2）
- `flag.unmap`（int）: シングルビット（0 または 4）
- `flag.munmap`（int）: シングルビット（0 または 8）
- `flag.reverse`（int）: シングルビット（0 または 16）
- `flag.mreverse`（int）: シングルビット（0 または 32）
- `flag.read1`（int）: シングルビット（0 または 64）
- `flag.read2`（int）: シングルビット（0 または 128）
- `flag.secondary`（int）: シングルビット（0 または 256）
- `flag.qcfail`（int）: シングルビット（0 または 512）
- `flag.dup`（int）: シングルビット（0 または 1024）
- `flag.supplementary`（int）: シングルビット（0 または 2048）
- `hclen`（int）: ハードクリップされた塩基数
- `library`（string）: ライブラリ（RGヘッダーのLBフィールド）
- `mapq`（int）: マッピング品質（mapping quality）
- `mpos`（int）: `pnext` の同義語
- `mrefid`（int）: メイトの参照番号（0-based）
- `mrname`（string）: `rnext` の同義語
- `ncigar`（int）: CIGAR操作の数
- `pnext`（int）: メイトのアラインメント位置（1-based）
- `pos`（int）: アラインメント位置（1-based）
- `qlen`（int）: クエリ塩基数
- `qname`（string）: クエリ名
- `qual`（string）: 品質値（0-based）
- `refid`（int）: 参照番号（0-based）
- `rlen`（int）: 参照塩基数
- `rname`（string）: 参照名
- `rnext`（string）: メイトの参照名
- `sclen`（int）: ソフトクリップされた塩基数
- `seq`（string）: 配列
- `tlen`（int）: テンプレート長（インサートサイズ）
- `[XX]`（int / string）: XXタグの値

---

### 補助タグの扱い

タグが存在するかの確認は単にタグ名を記述するだけで行います（例：`[NM]`）。`htslib <= 1.15` では、`![NM]` がタグが存在しない場合や値が0の場合のどちらでも真（true）でしたが、`1.16` 以降では「存在しない」場合のみ真と判断されるようになりました。

---

### 関数

文字列や数値を操作するための関数がいくつか用意されています。

- `length(x)`：文字列の長さ（null文字を除く）
- `min(x)`：文字列内の最小バイト値
- `max(x)`：文字列内の最大バイト値
- `avg(x)`：文字列内のバイト値の平均

数値専用の関数もあります：

- `sqrt(x)`：平方根
- `log(x)`：自然対数
- `pow(x, y)`：`x` の `y` 乗
- `exp(x)`：自然指数関数
windowsのSEを爆裂魔法詠唱にしたい

こんにちはwhyyouyouです
いつもXでなんのアニメを見たかつぶやいてます
-

## youtubeなどから爆裂魔法詠唱音声を切り取りましょう

使用した音声
https://youtu.be/Msk9Bf2RMyA?si=XBdrxow9fBLTgbaB
使用ソフト
https://github.com/yt-dlp/yt-dlp

今回はyt-dlpを使用して音源を取り込みfimoraで.wav形式にしました
<br>
<br>
ステップ１
![スクリーンショット 2024-10-29 153013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921561/c1e278bb-b749-a372-b2a9-60d6ae36a5f3.png)
コントロールパネル
↓
サウンド

![スクリーンショット 2024-10-29 153142.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921561/85fb944e-8650-a556-b172-30cf5401a15a.png)

サウンド
↓
サウンド

![スクリーンショット 2024-10-29 153401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921561/053a7d9a-4830-6cdc-9665-f8a7348d9c44.png)
### 今回はデバイスの接続を変えてみました

## 感想&まとめ
やる気が余ってるときに作業しました

音量調節に苦戦しましたがうまくできてよかったです
みんなもやってみよう！
Rustで自身をフィールドに持つ親の構造体を可変参照する

以下のような構造体を考えます。
```rs
#[derive(Debug)]
struct Parent {
    name: String,
    children: Vec<Child>,
}

#[derive(Debug)]
struct Child {
    name: String,
}

impl Child {
    fn update(&mut self, parent: &mut Parent) {
        self.name = parent.name.clone();// 親の構造体のフィールドを可変参照する(可変参照する必要は無いが便宜上)
    }
}
```

この構造体でupdate関連関数を呼び出すとき、自身を含むparentを引数に渡すときには注意が必要です。

まず実体にします。
```rs
let mut parent = Parent {
    name: "parent".to_string(),
    children: vec![Child {
        name: "child".to_string(),
    }],
};
```

ここで、以下のように自身を含む構造体をupdateに渡すと、可変参照が2回行われ所有権の規則に反します。

```rs
for child in &mut parent.children {
    child.update(&mut parent);// cannot borrow `parent` as mutable more than once at a time
}
```

そのため、可変参照を2つ以上取らないようにするため、**構造体から自身を退避**した後に、**戻す**必要があります。

```rs
// std::mem::takeで奪うと、自身を含まなくなるので親を可変参照できる
let mut children = std::mem::take(&mut parent.children);

for child in &mut children {
    child.update(&mut parent);
}
        
// 奪ったので戻す
parent.children = children;
```

最終的なコードは以下のようになります。

```rs
#[derive(Debug)]
struct Parent {
    name: String,
    children: Vec<Child>,
}

#[derive(Debug)]
struct Child {
    name: String,
}

impl Child {
    fn update(&mut self, parent: &mut Parent) {
        self.name = parent.name.clone();
    }
}

fn main() {
    let mut parent = Parent {
        name: "parent".to_string(),
        children: vec![Child {
            name: "child".to_string(),
        }],
    };

        
    // std::mem::takeで奪うと、自身を含まなくなるので親を可変参照できる
    let mut children = std::mem::take(&mut parent.children);
    for child in &mut children {
        child.update(&mut parent);
    }
    
    // 奪ったので戻す
    parent.children = children;

    println!("{:?}", parent);

}
```

これを実行すると`Parent { name: "parent", children: [Child { name: "parent" }] }`が結果になります。
Flutter WebでファイルをFirebase Storageにアップロードする方法のメモ

## 概要
Flutter WebでファイルをFirebase Storageにアップロードしようとした際に試したことをメモします。もっと良い方法がありましたら教えていただけると幸いです。

## 使用技術・環境
- Flutter 3.22.2
- Firebase Storage
- M1 MacBook Air Sonoma 14.6.1

## 試した方法

### putFileを使用
FirebaseStorageのputFileを使う方法です。

```dart
FirebaseStorage storage = FirebaseStorage.instance;
FirebaseFirestore firestore = FirebaseFirestore.instance;

final file = File(uploadFile.files.first.path!);
final uploadTask = await storage
    .ref('uploaded_file/${uploadFile.files[0].name}')
    .putFile(file);
```

uploadFile変数には、FilepickerのpickFilesで選択した情報が入っています。AndroidやIphoneでは動作しましたが、Flutter Webでは動作しませんでした。また、アップロードに二十秒ほどの時間がかかりました。

### putDataを使用

putFileの代わりに、putDataを使用しました。Filepickerで選択したファイルのバイトデータを取得し、これを送る方法です。

```dart
FirebaseStorage storage = FirebaseStorage.instance;
FirebaseFirestore firestore = FirebaseFirestore.instance;

final uploadedFile = uploadFile.files[0].bytes;
final uploadTask = await storage
    .ref('uploaded_file/${uploadFile.files[0].name}')
    .putData(uploadFile.files[0].bytes!);
```

FilepickerのGitHubを確認しますと、PlatFormFileというクラスが存在しました。FilePikcerのpickFileで取得したファイルは、PlatFormFileというクラスで管理されているようです。コードを読んでいきますと、Uint8List型のbytesというメンバ変数を見つけました。

```dart
...
  /// Byte data for this file. Particularly useful if you want to manipulate its data
  /// or easily upload to somewhere else.
  /// [Check here in the FAQ](https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ) an example on how to use it to upload on web.
  final Uint8List? bytes;
...
```

Firebase Storageには、Uint8List型のデータを送信できるメソッドがありますので、ファイルのバイト列を送る方法を試してみました。

## 結果
putDataを使う方法で、無事ファイルを送信することができました。また、送信にかかる時間も短縮されました。

## まとめ
Flutter WebでFirebase Storageにファイルをアップロードする際、FilePickerで選択したファイルのバイト列をputDataで送信することで、ファイルをアップロードすることができました。

## 参考
https://pub.dev/packages/file_picker

https://zenn.dev/yanasan/articles/5baa30b3c48019

https://github.com/miguelpruivo/flutter_file_picker

https://github.com/miguelpruivo/flutter_file_picker/blob/master/lib/_internal/file_picker_web.dart

https://firebase.google.com/docs/storage/flutter/upload-files

https://github.com/miguelpruivo/flutter_file_picker/blob/master/lib/src/platform_file.dart
nRFConnectSDK：I2C非同期動作

# 未だ実装されていない
1年半くらい前にDevZoneで以下のようなやりとりをしました。

https://devzone.nordicsemi.com/f/nordic-q-a/95889/twim-i2c-on-ncs-is-not-working-properly

非同期I2Cを使いたかったのですが、ソースコードを追いかけていくとどうも実装されていない(少なくともNordicのSoCは非対応)ということが判明しました。
SDKは絶賛開発中だし、まだ実装されていなくてもしょうがないか、そのうち実装されるはずだ……なんて考えてはや1年半、未だ実装されていません。厳密に言うとAPIレベルではすでに実装されていて常に非同期I2C(Callbackあり)で動いており、それをセマフォで制御することにより同期I2Cとして動いています。なので、そこからセマフォの同期制御を止めてコールバック関数の登録があれば呼び出す、みたいなのでいけそうな感じはあるのですが、何も進んでおりません。

::: note
なんで僕がソースコード解析しないといけないんだｗ
:::

## 本題に行く前に訂正
上記のスレッドでは「I2Cがまともに動いていないんだけど？200kHzってなに？」という質問を投げかけています。最近になってやっとこれの正体が分かりまして、実は内蔵プルアップを使ったI2Cだったのです。元々、内蔵プルアップというのは入力ピンのプルアップ抵抗のために存在しており、非常に弱い電流でよいので100～300kΩが一般的です。この内蔵プルアップがI2Cで使うときにも設定できてしまうため、このような問題が発生したわけです。だって普通のI2Cのプルアップに300kΩなんて絶対使わないでしょ、電流足りなくてなまりまくりますよ。
もっと言うと内蔵プルアップはGPIOを入力ピンとして設定した場合だけ使えるのが一般的で、ルネサスのマイコンはそのようになっています。それがどんな設定でも使えてしまうほうがおかしいわけですよねｗ

::: note
いいわけですｗ
:::

ということで、外付けのプルアップ抵抗は必須です。頓珍漢な質問をしてすみませんでした……。

::: note
これ以外にも頓珍漢な質問結構しておりますｗ
人はそうやって強くなっていくのさ(適当ｗ)
:::

# APIでは未来永劫対応できない(と思う)
先にも書いたように内部処理の深いところでコールバックをすでに使っているので、ユーザーレベルに引っ張り出してくるのはかなり難しいんじゃないかなと思っています。

## Nordicもそう思っているらしい(ただし未確認)
先のスレッドの最後の回答が「NRFX TWIMドライバーを直接叩け」でした(笑)。そして、それをサポートするかのように実はサンプルプロジェクトが存在していたりします。tx_rx_non_blockingというプロジェクトですが、プロジェクト名にI2CもTWI[M]も入っていないので知らないと見つけようがないですよね。

::: note
はたしていつごろからあったのか……分かりません。
:::

# nRF7002で4系統非同期動作
nRF7002(nRF5340)はI2Cを最大4系統持っています。nRF528xxと違ってUARTとペリフェラルが共通なので全部使おうと思うとコンソールのログ出力とかUSB通信とかができなくなってしまいますが、IoTデバイスを扱うには非常に魅力的なペリフェラル数です。
ただし、これを同期通信で動かしてしまうとせっかく4系統ある魅力も半減してしまいます。いくらスレッド処理ができると言っても、スレッドでI2Cをアクセスしている間は他が動けないからです。
ということで、上記のサンプルを使って4系統の非同期動作を実装してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3797041/74e58975-9af0-4325-bd6d-dabd64d9dd6a.png)
クロック出力動作が完全に終わらない段階で違う系統のクロックが動き始めているので、これはまごうことなき非同期動作ですね。

::: note warn
単に非同期で動いていることを確認するためだけのものなので、すべてのペリフェラルがNACKで終わっています
:::

## 2024/11/13 追記
ちゃんと実装してみたものです。美しい非同期処理ですね(笑)
CH1がTWIM1のSCL, CH2がTWIM1のSDA, CH3がTWIM0のSCL, CH4がTWIM0のSDAです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3797041/a162add8-b3cd-8ed2-68bb-db59c3379547.png)

# 余談：非同期SPIMは実装されている
同じ非同期動作でもSPIMはすでに実装されており、問題なく使えることが確認できています。
PyTorchのDataLoader使わないほうがいいかも

GPU使用率が上がらない。調べるとPyTorchのDataLoaderが遅い。
まさかそんな、と思うぐらい遅い。

大した仕事してないのに。
高速化オプションも調べたがあんまり効かないしコケる。

仕事にもよるけど、わざわざDataset,Dataloaderを使って書くのは時間のムダ。

直接copilotとかに書かせたほうがいいかも。
学習用データセットをGPUに送っといて、batch取り出しできるようにしとけばいいだけだしねえ。特定の仕事に使うのなら汎用性は必要ない。単純に考えてGPUが24GBならデータをストックしておくのに1,2GB使っても問題ないだろう。非同期データ転送も可能らしい。

DataLoaderはGPUでもCPU並列でも動かさなあかんし設計思想からしてしんどそう。生pythonで書かれてるのかもしれん。
2020年にhttps://qiita.com/bauer/items/98cb096e9fe585e7a926
だし、あんまりメンテされてないのかもしれないということかな。
Swift: Dictionary の要素の削除

## プログラム

```swift:text_delete.swift
// --------------------------------------------------------------------
//	  text_delete.swift
//
//						  Oct/29/2024
//
// --------------------------------------------------------------------
import Foundation

// --------------------------------------------------------------------
func textWriteProc(fileOut: String, dictAA: [String: [String: Any]]) {
	do {
		let fileURL = URL(fileURLWithPath: fileOut)
		var strOut = ""
		
		for (key, unit) in dictAA {
			if let name = unit["name"] as? String,
			   let population = unit["population"] as? Int,
			   let dateMod = unit["date_mod"] as? String {
				strOut += "\(key)\t\(name)\t\(population)\t\(dateMod)\n"
			}
		}
		
		try strOut.write(to: fileURL, atomically: true, encoding: .utf8)
	} catch {
		fputs("*** error *** in textWriteProc ***\n", stderr)
		fputs("\(error)\n", stderr)
	}
}

// --------------------------------------------------------------------
func textReadProc(fileIn: String) -> [String:[String:Any]] {
	var dict = [String: [String: Any]]()
	
	let fpIn = try! String(contentsOfFile: fileIn, encoding: .utf8)
	let lines = fpIn.components(separatedBy: .newlines)
	
	for line in lines {
		let cols = line.trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: "\t")
		if cols.count >= 4, cols[0].hasPrefix("t") {
			if let population = Int(cols[2]) {
				dict[cols[0]] = ["name": cols[1], "population": population, "date_mod": cols[3]]
			} else {
				print("*** error *** \(fileIn) ***")
				print("*** \(line) ***")
			}
		}
	}
	
	return dict
}

// --------------------------------------------------------------------
func dictDisplayProc(dict: [String:[String:Any]]) {
	for (key, value) in dict.sorted(by: { $0.key < $1.key }) {
		let name = value["name"]!
		let population = value["population"]!
		let dateMod = value["date_mod"]!
		print("\(key)\t\(name)\t\(population)\t\(dateMod)")
	}
}

// --------------------------------------------------------------------
print("*** 開始 ***")

guard CommandLine.arguments.count > 1 else {
	print("入力ファイル名を指定してください")
	exit(1)
}

let fileIn = CommandLine.arguments[1]
let keyIn = CommandLine.arguments[2]

print(fileIn) 
print(keyIn) 

var dict = textReadProc(fileIn: fileIn)

if dict.keys.contains(keyIn) {
	let value = dict[keyIn]!
	let name_target = value["name"]!
	print(name_target)

	dict.removeValue(forKey: keyIn)

	dictDisplayProc(dict: dict)
	textWriteProc(fileOut: fileIn, dictAA: dict)
	}

print("*** 終了 ***")
// --------------------------------------------------------------------
```

## 実行コマンド

```bash
swift text_delete.swift cities.txt t2387
```

## 確認したバージョン

```text
$ swift --version
Swift version 6.0.1 (swift-6.0.1-RELEASE)
Target: x86_64-unknown-linux-gnu
```