OmniAICreator/Qiita-1.07M huggingface dataset:
python3のroundは銀行丸め（にハマったのでメモ）

pythonのroundは銀行丸めpythonのroundは銀行丸め
pythonのroundは銀行丸めpythonのroundは銀行丸め
pythonのroundは銀行丸めpythonのroundは銀行丸め

pythonのroundは銀行丸めなんだったら！！
ヨシッ覚えた（たぶん半年後ぐらいにまたハマる）
半日無駄にしたからな、次から同じミスはしない。

pythonとrubyで同じコード書いたはずなに何故か同じ結果にならず調べたら四捨五入するroundの挙動が違っていました。
分かりやすくするために小規模テスト。
```python3:test.py
test = 0.5000000
for ii in range(10) :
        temp = test + ii
        print(round(temp),"{:.30f}".format(temp) )
```
この実行結果は下記のようにX.5の時に偶数側に丸められます
銀行丸めとかなんか金額の平均計算したり合計したりするときに誤差が少なくなる丸めかたたらしいです
```実行結果
0 0.500000000000000000000000000000
2 1.500000000000000000000000000000
2 2.500000000000000000000000000000
4 3.500000000000000000000000000000
4 4.500000000000000000000000000000
6 5.500000000000000000000000000000
6 6.500000000000000000000000000000
8 7.500000000000000000000000000000
8 8.500000000000000000000000000000
10 9.500000000000000000000000000000
```

対策は色々ありますが今回は簡単な関数を自力で作ってみました。
通常の四捨五入の実装（なんていうの?）
```python3 mround.py
def mround(num) :
        shou = int(num // 1 )
        amari = num % 1
        if amari >= 0.5 :
                return shou + 1
        else :
                return shou
#enddef mround
test = 0.25000000

for ii in range(15) :
        temp = test + ( ii * 0.25 )
        print(mround(temp),round(temp),"{:.30f}".format(temp) )
```
大きいほうに切り上げられること確認！
0.5だけだとテストケース少なくね？
ということで0.25刻みでチェック
ヨシッ
```実行結果
0 0 0.250000000000000000000000000000
1 0 0.500000000000000000000000000000
1 1 0.750000000000000000000000000000
1 1 1.000000000000000000000000000000
1 1 1.250000000000000000000000000000
2 2 1.500000000000000000000000000000
2 2 1.750000000000000000000000000000
2 2 2.000000000000000000000000000000
2 2 2.250000000000000000000000000000
3 2 2.500000000000000000000000000000
3 3 2.750000000000000000000000000000
3 3 3.000000000000000000000000000000
3 3 3.250000000000000000000000000000
4 4 3.500000000000000000000000000000
4 4 3.750000000000000000000000000000
```
外部サービスからのイベントを受け取るよ（前編）、"Webhook"

[Symfony Component Advent Calendar 2023](https://qiita.com/advent-calendar/2023/symfony-component)の15日目の記事です。

## 外部サービスからのイベントを受け取るよ、"Webhook"

[Webhook](https://github.com/symfony/webhook)は、外部サービスからのイベントをWebhookで受け取るコンポーネントです。

### インストール

```shell
composer require symfony/webhook
```

### 使い方

メールサービスなどのSaaSなサービスは、サービス内で起こったイベントをきっかけに設定したWebhookを呼び出す機能があったりします。通常であれば、その受け取るWebhookを実装していくのですが、Webhookコンポーネントを使えば簡単に実装できます。

まず、Webhookを受け取った際の処理を行うConsumerを作っていきます。`ConsumerInterface`を実装します。

```php:SampleEventConsumer.php

#[AsRemoteEventConsumer(name: 'sample')]
class SampleEventConsumer implements ConsumerInterface
{
    public function consume(RemoteEvent $event): void
    {
        // サービスから送られてきて解析されたリクエスト
        $payload = $event->getPayload();

        // 何かしらイベントを受け取ってやる処理
    }
}
```

引き続き、`#[AsRemoteEventConsumer()]`に指定した名前をつかって、webhookのルーティングを行います。
ここでは、SendGridのwebhookとして登録してみます。

```yaml:services/packages/webhook.yaml
framework:
    webhook:
        routing:
            sample:
                service: 'mailer.webhook.request_parser.sendgrid'
```

この設定を行うと、`{ドメイン}/webhook/sample` というWebhookが作成されます。ここで作ったWebhookは`202`ステータスを返して、何も出力されずに完了します。

## まとめ

今回は`Webhook`を紹介しました。他にもMailgunやtwilioなどのサービスのWebhookも設定されているので、簡単にWebhookが作れます。では、他のサービスや独自で作ったものに対してはどうすれば良いのでしょうか？
続きは後半、`RemoteEvent`で。
SBOM管理に取り組んでみた

## はじめに

[SRA Advent Calendar 2023](https://qiita.com/advent-calendar/2023/sra)の19日目です。  
関西事業部の南部です。

可能な限り誕生日の本日(12/19)に記事を書くようにして7年。47歳になりました。もう紛れもないアラフィフです。

今回は、2020年6月に以前一緒に仕事をしていた人にSBOM管理環境を構築しましょうとお声掛けをいただき早3年。  
ようやく形になり運用も始まり一段落したので、SBOMについて少し書いておこうと思いました。

## SBOMとは

Software Bill of Materialsの頭文字をとったもので、「エスボム」と読みます。   
詳しくは[OpenChain Japan](https://qiita.com/organizations/openchainproject)や、[日立ソリューションズ社のHP](https://www.hitachi-solutions.co.jp/sbom/sp/solution/sbom/)と、たくさんあるので見てみてください。  
それらの情報をまとめると、SBOMとは、該当のソフトウェアが「どのような要素から構成されているのか？」をリストにしたもので、特定の製品に含まれるすべて（オープンソースなど）のソフトウェアコンポーネント、ライセンス、依存関係を一覧化したものになります。  
例えるなら、食料品におけるどんな原材料で構成されているか表した食品表示のようなものかと思います。  

2021年5月に署名されたアメリカの大統領令でSBOMの提出が必要になったり、経済産業省 商務情報政策局 サイバーセキュリティ課で検討タスクフォースが出来たり、経済産業省にて手引書が公表されたりと近年どんどん注目度が高まっています。

## こんな時にSBOMがあると便利

弊社内ではOSSのXXXに脆弱性が見つかった！これまで製造したソフトウェアでそれを使用していないか確認して！  
とちょいちょい連絡があり、各マネージャーが調査結果を報告していますが、SBOMを作成し、常に最新化しておけば、担当者がSBOMを検索すれば済むようになり、脆弱性対応がスムーズにいくようになります。  
そういう意味では、脆弱性対応の第一歩ではないかと思っています。

## おわりに

先にも書きましたが、SBOM作成は脆弱性対応の第一歩、入口だと思っています。  
SBOM作成や、管理の仕組みが簡単に出来ればなと思ったので、そのあたりをサービス化出来ればビジネスになるかもとちょっと活動を開始しました。  
競合サービスがたくさんあり差別化が大変ですが、頑張ってみたいと思います。

## 参考URL

- [OpenChain Japan](https://qiita.com/organizations/openchainproject)
- [日立ソリューションズ](https://www.hitachi-solutions.co.jp/sbom/sp/solution/sbom/)
- [ソフトウェア管理に向けたSBOM（Software Bill of Materials）の導入に関する手引](https://www.meti.go.jp/press/2023/07/20230728004/20230728004.html)
OSS-DB Silver に合格するためにやったこと

この記事は、デフエンジニアの会 Advent Calendar 2023 19日目の記事です。

https://qiita.com/advent-calendar/2023/deafengineers

:::note
「いいね」をお願いします！
:::

# はじめに
こんにちは、[@rito_e](https://qiita.com/rito_e) です。現職ではインフラ構築に従事しているデフエンジニアです。

2023年2月に、PostgreSQL関連のオープンソースデータベース技術者認定資格「[OSS-DB Silver （Ver.2.0）](https://oss-db.jp/outline/silver)」を取得しました。その学習方法や期間についての備忘録を残します。

# 資格について
オープンソースデータベース(PostgreSQL)に関する技術力と知識を問う試験です。
-  受験費用：16,500円（税込）
-  試験実施方式：CBT方式（マウスによる選択方式）

出題範囲は以下の通りです。

| 項目                  | 説明                                 |
|-----------------------|--------------------------------------|
| **S1 一般知識**        |                                      |
| 　S1.1 OSS-DBの特徴     | PostgreSQLの機能やOSSの役割について理解 |
| 　S1.2 RDBの一般知識    | リレーショナルデータモデルやSQLの基本概念 |
| **S2 運用管理**        |                                      |
| 　S2.1 インストール方法  | PostgreSQLのインストールとクラスタ作成   |
| 　S2.2 付属ツールの使い方 | OSコマンドでの管理ツールの利用           |
| 　S2.3 設定ファイル       | 設定ファイル利用と基本パラメータの知識   |
| 　S2.4 バックアップ方法   | バックアップ手法やWALアーカイブの理解     |
| 　S2.5 運用管理作業       | PostgreSQL起動停止や基本運用コマンド     |
| **S3 開発/SQL**        |                                      |
| 　S3.1 SQL コマンド      | 基本的なSQL文やデータベース要素の知識      |
| 　S3.2 組み込み関数       | データベースの標準関数や演算子の理解     |
| 　S3.3 トランザクション   | トランザクションの概念と分離レベル       |

データベースの基本的な知識と操作を問う問題が中心で、データベースの運用管理、性能監視、パフォーマンスチューニング、障害対応などの実務的な問題は出題されません。

https://oss-db.jp/outline/silver

# 受験目的
この資格を受験するに至った目的は以下の通りです。
- 運用保守に関する業務に従事しており、現在のスキルセットを客観的に把握したい
- キャリアアップの一環として、専門的な技術力を向上させたい
- DB初心者なので、基礎知識を固めておきたい

# 学習に使用した教材
受験勉強に使用した主な教材は以下です。
- OSS教科書 OSS-DB Silver Ver2.0対応（緑本）

https://www.shoeisha.co.jp/book/detail/9784798162553

- Ping-t（3カ月プラン）

https://ping-t.com/

# 学習方法
学習期間は約2カ月（2023年1月〜2月）で、学習時間は約45時間でした。
具体的な学習手順は以下の通りです。

## 1. 受験の申し込み
本試験は、
- 自宅で受験（OnVUE）
- テストセンターで受験

の2通りがあります。私は、準備の手間やネットワークトラブルのリスクを避けるために、「テストセンターで受験」することにしました。会場の空きがあれば24時間前までに申し込めば、いつでも受けられるのですが、デッドラインを意識するために早めに申し込みました。**試験勉強は、申し込みから始まると言っても過言ではありません。**

また、耳が聞こえないため、テストセンターに事前にメールで連絡し、筆談での対応をお願いしました。

## 2. 緑本で全体像を把握（10時間）
試験の雰囲気や全体像を把握するために、緑本をざっくりと10時間かけて1周しました。細部まで把握しきれなかったものの、インプットよりもこの後のアウトプットに時間を割くことが効率的だと考え、そのようにしていました。

## 3. Ping-tで問題演習（30時間）
Ping-tでは約500問の問題が用意されており、これらをひたすら解きまくって、わからないところは解説を読んでいって分からないところをつぶして理解を深めていく方法でやっていました。Ping-tの解説が非常にわかりやすいため、緑本がなくても合格できそうな感じがしました。

## 4. 模擬試験で実力をチェック（5時間）
Ping-tの模擬試験で、今までの勉強の成果を確認しました。模擬試験で合格点に達していれば、本試験でも合格できると思っていましたが、念のため、1〜2回ほど追加で模擬試験を受けました。

# 受験結果
結果は64/100点以上に対して、78点で合格しました。
パソコンで試験終了を押すと、即座に結果が出てきて驚きました（笑）

# 学習方法の改善点
予想してたより点数が低かったので、学習方法の改善点を考えてみました。
- 緑本をもう少し丁寧に読み、理解を深める
- 問題演習の量を増やす
- 実務で役立つ知識を意識して学習する

これらの点に留意して、さらにスキルアップを目指したいと思います。

# 終わりに
約2カ月の学習期間で合格できましたが、まだまだ実務経験が浅いため、取得した知識を実務にどれだけ生かせるかは別の課題ですが、ひととおり体系的な知識を得ることができたので良い経験となりました。今後も実務での経験を積みつつ、学んだ知識を生かしていきたいと思います。皆さんの参考になれば幸いです。
検証工数激減の立役者：ノーコードE2Eテストを導入してみた

[人数半減の中で総開発量UPを実現させた秘訣 by エイチームコマーステック Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ateam-commerce-tech)

6記事目は、エイチームコマーステック フロントエンドエンジニアの 大沢（@kazzzzzz） が担当します！

今回は、ノーコードのE2Eテストを社内で導入してみたので、その経緯と所感をお伝えしたいと思います！

E2Eテストを導入したきっかけは、組織体制の見直しでエンジニアチームの人数が半減したことでした。限られたエンジニアリソースで開発を回していくために必要だと考え、本導入に向けて動き出しました。

使っているテストツールはMagicPodですが、ツール問わずに得られた知見をお伝えしたいと思っておりますので、MagicPod固有の話はあまり触れませんがご了承ください。

## これまでの検証の課題

これまではスプレッドシートで検証リストをあらかじめ作成し、リリース前にエンジニアが手動で検証していました。役割的には、リグレッションテストに近い形で運用しておりました。

![lZp6qXNRFbP1Kma1701905309_1701905435.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305522/1231135a-86be-48de-a4be-be842bc25ab2.png)

リリース頻度は大小合わせると 40~50回/月 ほどあり、影響範囲が狭めだと考えられるリリースに関しては部分的に検証を行い、影響範囲が読めない or 広いリリースはすべての検証を行なっておりました。

これまでで説明した手動検証の課題は以下二点だと考えました

- 検証作業によりエンジニア工数が圧迫される
- 検証漏れが発生しやすい

### 検証作業によりエンジニア工数が圧迫される

こちらは当然の話ではあるのですが、私たちのチームではdevelopなどの開発ブランチは設けておらず修正ごとにリリースを行う運用をしておりますので、より負担が大きい状態でした。

小さめの改修は数分で検証できますが、大きい改修はサイト全体の検証になるとエンドエンジニア二人がかりで半日かかるみたいなこともザラにありました。

大体、月40時間ほどは検証作業に工数を割いていたかなと思います。

### 検証漏れが発生しやすい

冒頭でリグレッションテストに近い形で運用していると記載しましたが、この「近い」というのは、リグレッションテストとして不十分でした。理由は、実装したエンジニア自身が検証範囲を決めていたためです。

リリース回数が月40~50回と多いため、全部のリリースに対してサイト全体の検証を行なっていたら検証だけで人生が終わってしまいます。

なので開発者から見て、他のページや処理への影響値が読めない場合、もしくは全体に影響がある場合にのみ全体検証を行い、そうで無い場合は開発者の判断で検証範囲を決めていました。

この検証範囲を決める判断が、検証漏れにつながることが多かったように考えます。

その他の要因として、当然人間なので見落としやサボりが発生しますので、そういった機械ではないからこそのエラーも存在していました。

## ノーコードテストを選んだ理由

前提として、当時サービスはローンチから1年ちょっとしか経っておらず、ビジネス的にも作っては壊しがよく発生するフェーズでした。

そんな中でせっかく時間かけて質の高いテストコードを作成したところで、ページや機能自体がごっそりなくなったりすることもよくあります。そのため、いかにツール導入・テスト作成コストを下げるかがE2Eテストを効果的に運用するために重要だと考えました。

そのニーズが満たせるのが、ノーコードE2Eテストでした。

GUI上でポチポチとテストが作成できるようになりますし、コードベースのテストだと意識しなければならない部分もツールがいい感じにしてくれます。

例えば、

- 状態ごとのUIキャプチャを見ながらテストが作れるので、1画面で完結するので楽
- 基本的にxpathなどのロケータ情報をツールが自動検出してくれるため、ソースコードと行ったり来たりせずにサクサクと作れる
- 待機処理やドラッグ＆ドロップなどの処理を自分で書かなくても良い

みたいな感じです。

## 運用を続けられている理由

テストってどうしても運用が続かない、いい加減になってしまう、みたいなことが起こりがちですが、導入して1年弱経ちますがそうはならずに運用を続けられています。

テストが通過しないとリリースできない運用にしているのも大きいですが、

その他にも、

- リリース計画にテスト作成の時間を含める
- 運用が曖昧になりそうになった時に、エンジニア同士声掛けする（朝会のタスク確認時など）
- ビジネス側の理解を得た（テストが通らない時のリリース延期などがしやすい）

などの理由があると考えています。

## 結果

E2Eテストのメンテナンス工数を加味した上で、エンジニア全体の検証工数を 24時間/月 削減することができました。元々が 40時間/月 なので、検証工数6割減です。

また、リリース前の不具合も月に2~3回ほど検出できています。特に、副業のエンジニアの方に一任している実装タスクのテストに効果的に働いています。

次回カレンダーは、

エラー監視でシステムを安定化！緊急対応が減ってチームも安定化！

です！

もしご興味がありましたら次回記事もご購読いただければと思います！

よろしくお願い致します！
S3からS3 Glacierへデータ移行する際の移行費用を抑える方法

# はじめに
本記事は、S3のデータをS3 Glacier(以下Glacier)へ移行する際のポイントについて、料金面からまとめたものになります。

# リクエスト料金
S3 Glacier(以下Glacier)のストレージ料金は全クラスで一番安いですが、一方でCRUDなどのリクエスト料金は一番高いです。何も考えずに全てのS3データをGlacierに移行すると、移行料金だけで数百万かかる可能性もあります。

執筆時点でのGlacierアップロード料金は、`0.065USD/1000回`ですので、例えば100万件のオブジェクトを移行する場合、ちょうど100万円ほどの費用となる見込みです。

これほどの移行費用となると、オブジェクトサイズにもよりますが、ストレージ料金による費用削減が移行費用を上回るまでに数年かかる可能性もあり、慎重にならざるを得なくなります。(オブジェクトの取り出しにも料金がかかるので尚更)

そこで、AWS公式ではGlaicerへの移行の際には、複数データをZIPなどにまとめてからアップロードすることを推奨しています。今回、私がアーカイブに取り組むにあたっても、ZIP圧縮専用のLambda関数を用意して、1000件ごとにまとめてGlacierにアップロードするという戦略を採用しました。

# ネットワーク料金
S3とデータをやり取りする際に、データ量に応じて料金がかかりますが、これはルートによって異なります。ちなみに単にストレージクラスを変更するだけであれば、この料金は発生しません。今回のようにオブジェクトを圧縮するため、一度S3からデータを取り出さなければならない場合などに、考慮する必要があります。

方法の一つは、パブリックサブネット内に設置したEC2やLambdaなどのインスタンスから、インターネットゲートウェイを通じてS3にアクセスする方法です。この方法では、同一リージョンの場合に限り無料となります。

ですが、要件によってはインスタンスをプライベートサブネットに設置したいかもしれません。その場合、インターネット接続のためにはNAT Gatewayを使用する必要があります。執筆現在、NAT Gatewayの料金は`0.062USD / 1GB`なので、1TBあたり1万円ほどかかる見込みとなります。データ量によってはかなりの料金となるかもしれません。

NAT Gatewayの代わりとして、Gateway Endpointというオプションもあります。これはS3とDynamoDB限定ですが、利用料が無料ですので、理由がない限りはこれを設置するのが一番良いと思います。

# 参考
https://aws.amazon.com/jp/s3/pricing/

https://aws.amazon.com/jp/vpc/pricing/
build.gradleの依存に立ち向かう

# はじめに
この記事は [Globee Advent Calendar](https://qiita.com/advent-calendar/2023/globee) の13日目の記事です。
こんにちはGlobeeでAndroidエンジニアをしています屋代です。
皆さんは、ライブラリを有効活用して開発していますでしょうか？

運用期間が長くなっていくと、使用していたライブラリのバージョンアップを行うことがあるかと思います。
何事もなくすっとアップデートが完了すれば良いのですが、ライブラリ内で依存しているライブラリと、別ライブラリ内で依存しているライブラリが競合してしまう場合があります。
そうなると依存の解決地獄、場合によってはアップデートを断念するなんてことも。

今回は、そんな状況に陥っていたAndroid版abceedが健全性を取り戻せた方法をご紹介します。

# 最初に結論
- 大きいライブラリを使う場合は、依存を閉じ込めよう
    - 場合によっては、そのライブラリをラップするandroidライブラリを作るのも手
- テストを書いてロジックの恒常性を担保しよう

# Android版abceedで何が起きていたか
弊社ではabceedという英語教育アプリを開発していますが、その機能の一つに、英語の発音の正確性をチェックする機能があります。
通常、Androidで音声認識を使うのであれば `SpeechRecognizer` を使用しますが、abceedでは機能要件からSpeechRecognizerではなく、 Google Cloudの `speech-to-text` で実装されています。

Android標準で使用しているライブラリと同じライブラリが、speech-to-text内では別リポジトリで提供されていたため、名前空間の競合が発生していました。

# 名前空間の競合をどう解決したか
結論にある通り、speech-to-textを分離して、別Androidライブラリに閉じ込めました。

## 大変だったこと
abceedアプリ内でspeech-to-textが提供する型を引き回しており、ライブラリとアプリが密接に結合していました。
そのため、
- ライブラリの設計
- アプリ内で引き回す用の型の再定義
- それらを使用するように該当機能を再設計

という手順を踏む必要がありました。結果として、アップデートができる状況にするために、既存のリファクタリング+新規開発以上のコストを必要としました。

# 今後発生しうる同様事象にむけて
アプリケーションが存続する限り、事業が軌道に乗れば乗るほどに依存問題はつきまといます。
事業の継続的インテグレーションを達成するためには、ドメインのバウンダリを見極めて、適切にモジュール化していくことが重要だと、思いを新たにした次第です。
[Unity]Newtonsoft.Jsonの基本的な使い方

# 概要
UnityでJSONを扱いたい時の選択肢にはJsonUtilityやUtf8Jsonなどがあります。今回はそれらではなくNewtonsoft.Jsonについての記事です。
# 本文
## 導入
Unityのバージョンによっては標準でNewtonsoft.Jsonが入っています。もし入ってなかった場合は
①メニューからWindows > PackageManager
②左上の＋ボタン > Add Package from git URL
③URL欄に「com.unity.nuget.newtonsoft-json」と入力して「Add」を押す
この手順でNewtonsoft.Jsonが使えるようになります。

## コード
以下にシリアライズ＆デシリアライズのサンプルコードを載せます。
Playerクラス型の実体を一度Json型に変換してすぐPlayerクラス型に戻しています。
最後にこの変換を経た内容をログに表示するサンプルコードです。

```cs
public class Player
{
    public string Name;
    public int Level;
    public int Health;
}
```

```cs
using Newtonsoft.Json;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    void Start()
    {
        var player = new Player();
        player.Name = "Player 1";
        player.Level = 1;
        player.Health = 100;

        // PlayerクラスからJSONを生成
        var json = JsonConvert.SerializeObject(player);
        // JSONからPlayerクラスを生成
        var model = JsonConvert.DeserializeObject<Player>(json);

        Debug.Log("Name: " + model.Name);
        Debug.Log("Level: " + model.Level);
        Debug.Log("Health: " + model.Health);
    }
}
```




# 補足
APIでプロパティ名と違うキーを扱いたい時は以下のように記述します。
```cs
public class Player
{
    [JsonProperty("player_name")]
    public string Name;
    [JsonProperty("player_level")]
    public int Level;
    [JsonProperty("player_health")]
    public int Health;
}
```
雰囲気で使うから抜け出すためにやっていること

:::note info
「この記事は、この記事は [Microsoft Power BI Advent Calendar 2023](https://qiita.com/advent-calendar/2023/powerbi) の 12 月 13 日担当分の記事です。」
:::

## 概要

突然ですが、Power Query のデータ型における固定小数点について説明できますか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/fdffff59-281d-fb1c-82e1-96b4ede24fe7.png)
そんなとき、調べものが少し楽になるかもしれない方法について書きます。

## 注意事項

- Power BI に関することだけでなく調べものをするときに使っている方法紹介です。
- 個人的な見解が多分に含まれます。
- 2023 年 12 月時点での情報です。
- Copilot まわりは進化が激しすぎて 1 年後全く違う方法をとっているかもしれません。

## Copilot を試す

ざっくりイメージをつかむのであれば Windows の Copilot もよいかもしれません。しかし油断は禁物です。質問で手を抜くとブレが大きいです。

「固定小数点について」会話のスタイルを「より厳密に」を選択して聞いてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/56517857-7a57-c8e9-4675-39e44c397183.png)
なんか違います。
質問に「データ型」という言葉を追加して聞いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/91a212a9-c437-570e-04a1-9fa7034bd75a.png)
良い感じで答えてくれました。
聞き方しだいというのは現実もいっしょですね。

## 検索する

- 調べながら学ぶのであれば私はいまのところ検索が多いです。
- その際さんざん言われてきたように一次情報を参照するようにしています。
- なるべく雑多なノイズを少なく検索しています。

### 1. Learn でキーワード検索してみる

https://learn.microsoft.com/ja-jp/microsoftsearch/

ここで検索窓からキーワード検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/8adc4827-ce42-7602-99d0-ec81db25524a.png)

### 2. ググる

一番使う方法です。Bing は使っていません。すいません！
今回の例でいえば Learn をサイト指定して検索ワードを使うようにしています。

`site:https://learn.microsoft.com/ja-jp Power Query 固定小数点`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/d1282df7-7a5a-f4b0-da36-5ac3bfdc6242.png)

サイト指定する方法は汎用性が高い検索方法です。Learn だけでなくさまざまな技術の公式ドキュメントや Wikipedia 、 GitHub やユーザーコミュニティ、ドメイン指定もできます。例えば go.jp や ac.jp など・・わからない単語を調べるときも、この方法を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/b6c0b2e7-30e7-7ca1-74c5-5889d13a728c.png)

## 手を動かす

あとは実際に手を動かしてどんなコマンドで型が制御されているのか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/57feb516-003a-999e-5875-e83f37509d2d.png)

ポチポチだけではずっと雰囲気になってしまうので、使われているコマンドを同じようにサイト指定して調べていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/0b22faa2-b60e-875b-21c1-1abc27c61ac1.png)

固定小数点について調べていると 10 進数（浮動小数点）や整数型の種類と使い分け、そして丸めについて気になるはずです。一次情報かそれに近しい情報を調べ、手を動かすを繰り返すように心がけています。それらの使い分けができるようになったころ、センパイたちの書いてくれたブログなどの凄さがわかるようになってきました。

## まとめ

- さんざん言われていることですが 1 次情報を検索するように心がけています。
- わからない言葉はそのままにしないように、なるべく調べています。
- Copilot 利用時、油断は禁物。（聞き方が結構難しい）
- 「手を動かすこと」 と、`site:`検索の往復することが私にはあっているようです。

Learn については URL の ja-jp を en-us に変更したほうが良い場合があります。また個人的には書籍から知見を得ていることも多いです。以上、雰囲気で使うから抜け出すために個人的にやっていることでした。

おしまい
AtCoder Beginner Contest 332 振り返り

# ABC332
## 概要
実力的には二年前に茶色になって放置して暫くぶりの参加なので詳しい解説などは期待しないでもらえると。
同じぐらいの初心者さんがこんな感じで解いたのかぁ的な見方か、上級者の方が愉悦として見ていただけると幸いです。

https://atcoder.jp/contests/abc332

コンテスト中に触ることができたのはA,B,C,D問題。ACできたのはC問題までです。
触れた問題で解説を見て理解できたものについては振り返っていきたいと考えています。

## A - Online Shopping
__考えてたこと__
P*Qをn回してそれらを合算、その値がSを超えていたらそのまま、超えていなかったらKを足す。

__提出したもの__
```c++:a.cpp
int main() {
    ll n,s,k;
    cin >> n >> s >> k;

    ll ans = 0;

    rep(i,0,n){
        ll p,q;
        cin >> p >> q;
        ans += p*q;
    }

    if(!(ans >= s)){
        ans += k;
    }

    cout << ans << endl;
    return 0;
}
```

__振り返り__
A問題にしては結構やること多くて難しい...?と思いました。あまり複雑に考えず見たものを見た通り処理しました。

## B - Glass and Mug
__考えてたこと__
問題文が長くて理解が大変...と思ったので問題文を読みながら書いていることをそのままif文で実装しました。

__提出したもの__
```c++:b.cpp
int main() {
    int k, g, m;
    cin >> k >> g >> m;

    int g_now = 0;
    int m_now = 0;

    rep(i, 0, k) {
        if (g_now == g) {
            g_now = 0;
        } else if (m_now == 0) {
            m_now = m;
        } else {
            if (g_now + m_now > g) {
                m_now = g_now + m_now - g;
                g_now = g;
            } else {
                g_now = g_now + m_now;
                m_now = 0;
            }
        }
    }

    cout << g_now << ' ' << m_now << endl;
    return 0;
}
```
__振り返り__
マグカップが空になるか、グラスが水で満たされるまでマグカップからグラスに水を移す、の部分の処理を書く部分で少し時間がかかってしまいました。解説のマグカップに入っている水の量と、グラスを水で満たすために必要な水の量のminを先に取っておいて使う解き方が一番綺麗だと感じました。

## C - T-shirts
__考えてたこと__
0のタイミングで区切ること、無地のTシャツはロゴ入りのTシャツでも代用できることさえ上手く実装できれば多分解けるかな、と考えていました。

__提出したもの__
```c++:c.cpp
int main() {
    int n, m;
    cin >> n >> m;
    string s;
    cin >> s;

    int shirts = 0;
    int shirts_logo = 0;

    int ans = 0;

    rep(i, 0, n) {
        if (s[i] == '0') {
            shirts = 0;
            shirts_logo = 0;
        } else if (s[i] == '1') {
            shirts++;
            ans = max(ans, shirts_logo + max(0, shirts - m));
        } else {
            shirts_logo++;
            ans = max(ans, shirts_logo + max(0, shirts - m));
        }
    }

    cout << ans << endl;
    return 0;
}
```

__振り返り__
最初はansの計算する位置を0のタイミングにしていたので最後に0が来ない場合計算されなくなってしまったので逆に1,2の時に計算してi日目までの必要な枚数を求め続けその最大値を保持し続けるという実装になりました。
解答であった配列の最後に0を足すことで一番最後にもう一度ansを計算するという処理が綺麗でした。

## D - Swapping Puzzle
__考えてたこと__
見てすぐ解けないだろうなぁと感じてしまいました、グリッド系の問題全然解けません...。
最小回数を求める問題なので最近勉強していた幅優先探索を使うのかな...?ぐらいに思いましたが、付け焼き刃では何もできませんでした。

__振り返り__
コードは公式の回答を見てください。
解答を見てみましたが、そもそもグリッドのパターンが全探索が可能な範囲だということに気づいていませんでした。ただ気づいていたとしても、全パターン探索して転倒数を求めるという解は出せたとは思いません、そもそも転倒数自体初めて知りました。

## 感想
結果はこんな感じでした。C問題まで30分ぐらいで解ければ意外と高めになるんだなぁという前回同様の感想です。
C問題までは安定して解けているので、当面の目標はD問題のAC, 解説を読んだ上でE問題まで理解することです。過去問やdaily trainingで訓練頑張ります。
![Screenshot 2023-12-12 at 20.56.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396642/78e73828-e0bf-1dbd-48e8-6449fdfee11a.png)

## 終わり
ABC331はその日、本業が忙しく参戦できなかったのでお正月休みに解いて振り返りしたいなぁ、と考えています。
【SwiftUI】ウィジェットのアニメーションを無効にしたい

# はじめに
iOS16から自動でウィジェットにアニメーションが付与されるようになりました。

![画面収録-2023-12-12-20.45.39.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/55cbe5a1-6f6c-43d4-748b-7e62baa43c71.gif)

これは便利なこともありますが、用途によってはアニメーションを無くしたい時もあります。
ちょうど無くしたい場面に遭遇したので、やり方を記事にしておきます。

# サンプルの実装
```swift
struct DemoWidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.date.formatted(.dateTime.hour(.twoDigits(amPM: .omitted)).minute().second()))
    }
}
```

# 実装
```swift
extension View {
    @ViewBuilder
    func contentTransitionIfNeeded() -> some View {
        if #available(iOSApplicationExtension 16.0, *) {
            self.contentTransition(.identity)
        } else {
            self
        }
    }
}
```

# 使い方
```swift
struct demoWidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.date.formatted(.dateTime.hour(.twoDigits(amPM: .omitted)).minute().second()))
            .contentTransitionIfNeeded()
    }
}
```

# こんな感じでアニメーションが消える
![画面収録-2023-12-12-20.55.41.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d7019271-16bb-8996-23d2-a86796e0cb5e.gif)

# 公式ドキュメント
https://developer.apple.com/documentation/widgetkit/animating-data-updates-in-widgets-and-live-activities#Disable-animations

# 参考記事
https://developer.apple.com/forums/thread/731237
スキルアップあれこれ

こんにちは！

最近、国内のITスキルレベルが上がってきてますね！
小学校からプログラミング教育が始まり、オンラインの発達によってリモート参加の機会も増えました。

AIの発達によって新しい知識も得やすくなり、以前より格段にチャレンジしやすい環境になったと言えます。

チャレンジしないと、もったいないです！

みなさん様々な方法でスキルアップをしていると思いますが、今回は私が経験したスキルアップの方法をまとめたいと思います:slight_smile:

# なんのためにスキルアップをするのか
これ一番大事ですね。
おそらく全く同じことをやっても、やる理由が違うと成果が異なります。
最初にこれを決めてから取り組んだ方がいいです。
例えば、私の周りだと以下のような感じです。

- 仕事に必要だから
- 将来的な目標のため
- 自分が活躍できるフィールドを増やすため
- 追求して知識を深めるのが好きだから
- 新しい技術に興味があるから
- この業界で生き残るため
- なんとなく、やった方がよさそうだから

このように、人によってやる理由は様々です。
どれもいい理由ですが、どこまで踏み込んで学習するかは違ってきそうですね。

ちなみに私は、将来的な目標のため、という理由が一番大きいです。

# スキルアップの方法
それでは、私が今まで経験したスキルアップの方法をご紹介します。

### 仕事で技術を深掘りする
仕事をしているのであれば、これをやるのが一番早いです。
単に設計やコーディング、テストを行うのではなく、その設計やロジック、テスト項目の根拠を考えたり、もっといい方法はないか、ユーザーにとっていいシステムになっているか、など、様々な視点から考えると、技術に深みが増します。
どちらかと言うと、職人を目指す方にぴったりですね。

### 資格を取得する
経歴としては実績が優先されますが、やはり知識も大事。
きちんとした知識があって初めてクリアできる問題などもあるので、資格の取得はおすすめです。
知識の証明になるし、知識があった方が自信がつきますね。
きちんと学習する人、という証明にもなります。

### 個人開発をする
色々と新しい技術に興味がある方には、個人開発がおすすめです。
やはり業務とは違いますが、制約が無いので、自分が使いたい技術で自由に作れます。
最近はAIの発達が目覚ましいので、新しいことにもチャレンジしやすいですね。

何かサービスを作ったとしたら、GitのREADMEを、できるだけ詳しく、見やすく、分かりやすく書くのがおすすめです。

やったときが一番覚えている、というのもありますが、きちんとしたアウトプットを残すことで、将来的に自分のためにもなります。

### 勉強会に参加する
自分より詳しい方の知識は、とても貴重です。
すでに実績がある方が主催することが多いので、できるだけ参加したいですね。
勉強会後の交流も楽しいです。

### セミナーに参加する
生の最新情報を得やすいのはセミナーです。
相手も仕事としてやっているので、クオリティーは高め。
無料セミナー、有料セミナーとありますが、目的と予算に応じて参加してみるといいと思います。

### 読書する
技術に限らず、伝え方などのビジネススキルも大事ですね。
じっくりと集中してインプットできるので、私も定期的に読書をするようにしてます。
良さそうな本があれば、技術とビジネススキルと半々くらいの割合で購入してます。

### Udemyなどのコンテンツを購入する
Youtubeなどでも視聴可能なものもありますが、コンテンツの購入もおすすめです。
体系的に基礎を固められる有料コンテンツが多い印象です。
高品質なコンテンツが多いと思います。

### 情報収集する
検索やIT系情報サイト、Facebook、Xなど、スマホで閲覧できるので、ちょっとした時間での情報収集に最適です。
私はXとGoogle Discoverがメインです。
特にXはアクティブな方が多く、情報が早いですね。

### もくもく会に参加する
基本的には自習形式ですが、情報交換も活発です。
まさに今取り組んでいる方からの情報を得られるので、とてもいい情報を得ることができます。

弊社でも、約5年ぶりにもくもく会を再開しました！
「[MOKU-MOKU WORKSHOP](https://diamond-f.connpass.com/)」という名称で開催しているので、ご都合のよろしい方は、ぜひ参加してください！
入退場自由で、軽食もあります！:bread::coffee:

# まとめ
今回は、スキルアップの方法についてまとめました。
どの手段もそれぞれの良さがあり、どれが一番、というのは無いです。

目的によってどれを選ぶかが大事なので、実際に経験してみてはどうでしょうか:slight_smile:

みなさんも一緒に、楽しくスキルアップしましょう:smiley::dizzy:
最新の JavaScript で Image を読み込む方法

JavaScript の `HTMLImageElement` オブジェクトは多くの場合、非同期で画像を読み込みます。

(`decoding` プロパティの値によって同期して読み込むことも可能ですが、非同期の方が効率よく画像を扱えるため、本記事では説明しません。)

JavaScript では元々非同期の処理はコールバック関数を用いる必要がありました。

```js
const image = new Image();
image.onload = () => {
    // ... image ...
};
image.onerror = event => {
    // ... event ...
};
image.src = 'image.png';
```

`Promise`, `async`, `await` の追加によって、コールバック関数をラップして分かりやすく書くことができるようになりました。

```js
const loadImage = src => new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = event => reject(event);
    image.src = src;
});

const image = await loadImage('image.png');
// ... image ...
```

`decode()` メソッドの追加によって、`new Promise()` を書かずに `Promise` で扱えるようになりました。

```js
const loadImage = async src => {
    const image = new Image();
    image.src = src;
    await image.decode();
    return image;
};

const image = await loadImage('image.png');
// ... image ...
```

参考「[HTMLImageElement: decode() メソッド - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/HTMLImageElement/decode)」
FreeBSDの使えるIaaS(VPS/クラウド）

FreeBSDの使えるIaaS(VPS/クラウド）を一覧

----- 非正規 -------

1: AWS
https://aws.amazon.com/
  なにもいうことはありません、オフィシャルなイメージがあります。

2:さくらのクラウド
https://cloud.sakura.ad.jp/
　コスパは VPSの方に軍配が上がります。

3:さくらのVPS
https://vps.sakura.ad.jp/
  正規なんだが、とりあえずLinuxで購入後FreeBSDで上書きという謎仕様
  さくらのレンタルサーバはFreeBSDなのに、なぜこの様な差別を。。。
　また、RBLに登録されてるIPアドレスが当たってしまうと悲惨なので
 まずは、お試しとして登録して割り当てられたアドレスをRBLで検索してフリーなら本契約にするのが 吉

4:Conoha VPS
https://www.conoha.jp/vps
ZFSのテンプレートがあるので一番おすすめ。

5:カゴヤ VPS
https://www.kagoya.jp/vps/
　　容量的なコスパはいいのだが、絶対にバックアップ機能つかっちゃだめ。
　　死ぬほど高いです。単純に容量x世代数になります。気づいて死んだ。

----- 非正規 -------
6:Oracle Cloud
https://www.oracle.com/jp/cloud/
頑張ればインストールできるらしい。しかも2個まで無料で使えるという神

https://qiita.com/nanorkyo/items/5cc02f717ab3c77f53ba?fbclid=IwAR3VpDuSgBP7y-NRf-qpbJyoJfFCABTeM7pOIYwttBtgptwAPE-vVgH6zJE
スクラムチームの管理ツールにNotionを使い始めたのでメリット・デメリットをまとめる

[ディップ株式会社 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/dip-dev)の記事です。


# はじめに

数ヶ月前からスクラムマスターをやっており、スクラムの原則をチームに浸透させるため奮闘しています。

さて、最近弊社ではドキュメントリポジトリとしてNotionの全社的な活用が求められています。
Notionはドキュメント管理ツールですが、プロジェクト管理としても使用でき、[スクラム向けの機能](https://www.notion.so/ja-jp/help/guides/product-engineering-notion-sprint-planning)も公開されています（2023/12/12時点ではβ版）。

自分の所属チームでは、元々プロジェクト管理にAsanaを使用していました。
Asanaの使用感に強く不満があったわけではないのですが、組織的な背景からプロジェクト管理もNotionで行うことができれば何かと都合がよいと思い、Notionへの切り替えに至りました。

この記事では、実際に使い始めて感じたメリットとデメリットをまとめてみます。

管理ツールの選定や移行の判断材料になれば幸いです。


# この記事で触れないこと

- スクラム自体の話
- Notionの使い方
- AsanaからNotionへの移行に関する内容


# ざっくりとNotionで出来ること

- プロジェクト管理
    - AsanaやJiraと同じようなことができます
- タスク管理
    - AsanaやJiraと同じようなことができます
- スプリント管理
    - Jiraと同じようなことができます
- 上記管理周りの設定
    - 特にレイアウトに関してはかなりの自由度でカスタマイズできます
- 外部連携
    - AsanaやJiraと同様に、タスクのステータス変更をフックにSlack通知ができます


# メリット


### レトロスペクティブも管理できる

スクラムの管理をする上で、個人的にこれが一番嬉しかったです。

自分が経験したスクラムチームでは、いずれもプロジェクト管理ツールとレトロスペクティブに使用するツールは分かれていました。
スプリントごとの振り返りなので、スプリント管理ツールと統一しておきたくないですか？

自分は統一したい派なのでハッピーになりました。


### 情報の検索性が高い

これはドキュメント管理とプロジェクト管理をまとめてNotionで行う場合のメリットだと思いますが、経緯や状況、ナレッジの検索を全てNotionで行える点はすごく良いと思います。

また、最近だと[Notion Q&A](https://www.notion.so/ja-jp/product/ai)という機能が公開されおり（2023/12/12時点ではβ版）、対話式に検索を行うこともできます。


### レイアウトの自由度が高い

とにかく見た目に関しては他のプロジェクト管理ツールと比べてはるかに自由度が高いです。

ユースケース（開発者以外の人に見やすくしたり、デイリースクラムで使うことに特化させたり）に合わせて使い心地をカスタマイズできるのは利点の一つだと思います。

# デメリット


### 導入コストが他のプロジェクト管理ツールよりもかかる


個人的にはこれに尽きると言っても過言ではないです。

[スクラムのプロジェクト管理向けテンプレート](https://www.notion.so/?tg=agile)が公式で用意されていますが、実務で使用する場合はこれに多少のアレンジを加えると思います。
その際にNotionの細かい仕様や、レイアウト構成に悩むことがありました。

他のプロジェクト管理ツールでは初めから決まっているものが、Notionでは使用者が自ら考える必要があります。自由度が高いが故に...。

この辺りの凝り具合は、自身の業務の本質から逸れない程度に留めておきたいですね！


### 一部機能は2023/12/12時点でβ版

Notionに切り替える前から承知の上でしたが、[スプリント管理機能](https://www.notion.so/ja-jp/help/sprints)はβ版です。
正式版のリリースで使用感が変わる可能性があります。


# まとめ

いざNotionに切り替えてみると、メリットが大きく感じており満足しています。

挙げたメリットを振り返ると、プロジェクト管理以外の用途でもNotionを利用している（利用する予定がある）であれば、プロジェクト管理もNotionで行ってみても良いかもしれませんね。
プロジェクト管理のみの用途ではメリットが少し弱いと感じました。
PagerDutyのiOSアプリをインストールすると電話通知が来なくなった話

## PagerDutyの活用
弊社ではシステムを監視しているツールをPagerDutyと連携させ、緊急度の高いアラート発生時のオンコールを実現しています（全てがそうなっているわけではありません）。

## 突然、電話通知が来なくなった
PagerDutyにはiOS/Androidアプリがあります。
このiOSアプリ(v7.48.1)を携帯端末iPhoneにインストールし、アカウント連携を行なったところ電話通知が来ないという事象が起きました。

https://support.pagerduty.com/lang-ja/docs/mobile-app

SlackにもPagerDutyからの通知が来るようにしているので、Slackを開いていたおかげですぐにアラートの発生に気づくことができました。ちなみにアプリからの通知は来ていました。

## なぜ？
PagerDutyからMy Profile > Notification Rulesを開き「When a high-urgency incident is assigned to me...」を見ます。

以下のキャプチャではすべての通知手段が`Immediately`となっていて即時通知です。これが元々の設定です。

![B0F919F2-1291-4D7D-9545-50773405514D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222808/8ff2ea60-c885-e6bc-5247-9e902bf0e3de.png)

しかしアプリをインストールすると以下のキャプチャのようにアプリ通知以外`Immediately`ではなくなってしまっていました。

![E13BE031-023D-4B3D-8011-8A49128673C7_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222808/9f38743c-f208-9b4c-e6a7-4d20d9c991ea.jpeg)

## 設定変更
以下のようにすることで`Immediately`に変更できます。

1. 右側の編集ボタンを選択
1. `0` minutesに変更
1. Saveを選択

![7CC7CB9C-D6F9-4429-98EA-6E906ACE60DB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222808/96f35a41-13ab-883c-a800-983745abc80f.png)


![0DE9DFA3-33B2-45FD-A1F9-BCD6E91D2CD5_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222808/6a56d24b-9798-f25a-faf3-4f7409e15854.jpeg)

## おわり
PagerDutyのiOSアプリをインストールした際の困った出来事でした。自分はSlackで気づくことができましたが、もしアラートの発生が就寝時だったとしたら気づくのに数分遅れてしまい、サービス影響が大きくなっていたかもしれません。

念の為言っておくと、インストールしてからアカウント連携するまでに**必要な設定をスキップしていた可能性は否めません**。さくっとセットアップできるわかり易い導線でしたのでドキュメントは読んでおりません。またAndroidアプリは試していません。

これからiOSアプリを入れようとしている、もしくは同じ事象にあっている方に本記事が参考になれば幸いです。
Reactの基礎

React学習まとめ。


- Reactはコンポーネント思考。
→データを細分化していき、部品のような形で組み立てていく。
一つのJavaScriptファイルに記述していくと行数が長くなる。
ファイルを分けてコンポーネント（部品）として管理していく。


```
import React from 'react';
```

・HTMLにコンポーネントを反映していくために必要なReactDomをインポート。
```
import ReactDom from 'react-dom';
```



- JSX記法：JavaScirptの中で、HTMLを記述して値を返す事。

記述のルール。
returnするHTMLの内容は一つのタグで囲う必要あり。
※エラーを回避するためだけに囲うなら、React.Flagmentを使用すれば画面には何もレンダリングされない。

```
return(
　<React.Flagment>
   <h1>こんにちは！</h1>
   <p>お元気ですか？</p>
  </React.Flagment>
);

※React.Flagmentの箇所は<></>と記述する事も可能。
```

- 他のファイルでも使うために、文末にexportを記述する。
```
export default App;
```

- Appを引用して使用するJavaScriptファイルにもimportを記述する。

```
import App from "パス"
```

- コンポーネント名の命名規則について。
・必ず戦闘を大文字から始める事。
・単語を区切って使用する場合は、パスカルケースを使用する事→先頭が大文字で始まり、単語の区切りを大文字とする変数名の付け方。
例)
Some_Component
MacのExcellでwebから表データの取り出しをする方法

# webから表データを取り出せなかった
URLからデータを取り出す方法として、データタブより「webから」を選択してデータを取り出すように記述されているサイトをみますが、これはMac版のエクセルでは使えません。基本的にwebクエリを通しての方法になります。
ここではwebクエリの使用の前にまずクエリを作成します。その後クエリを読み込み表を貼ります。

環境
os: macOs Catalina(10.15.7)
エクセルバージョン: Excel for Mac (16.66.1)

## webクエリの作成
今回卒論を作成する上でjetson nanoの性能表が必要になったため、その[サイト](https://www.switch-science.com/products/6239)の表を取り出そうと思います。
![Screen Shot 2023-12-12 at 19.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/004195bf-c262-9093-c8f7-015d046a262b.png)
この表を取り出したいです。
テキストエディットやWordを開いてください。GUIが嫌いな人はViでもNanoでもなんでもいいです。とりあえずtxtファイルを作成します。
![Screen Shot 2023-12-12 at 19.37.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/eea907e5-4083-4bee-2bc5-d9b97f5058d4.png)
自分はテキストエディットで新規にプレーンテキスト(.txt)ファイルを作成します。
https://www.switch-science.com/products/6239
自分は上のサイトを貼り付けていますが、個々人で好きなサイトを貼ってください。
貼り付けたらテキストファイルのまま保存します。
![Screen Shot 2023-12-12 at 19.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/48e11275-773e-6957-b095-89711b5cb200.png)
![Screen Shot 2023-12-12 at 19.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/008ed4bc-080b-1840-769b-153e5e858611.png)
拡張子を.iqy変えてください。拡張子は変わりますが実態はただのテキストファイルなので、今後も開くアプリをテキストエディタなどに既定すればurlは編集できます。
![Screen Shot 2023-12-12 at 19.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/065fcd96-4ecd-b772-cf73-01997b5653c4.png)
警告が出ますが.iqyを使用してください。

これでクエリの作成は完了です。

## クエリを読み込む
ここでは実際に作成したクエリファイルを読み込みます。
上のバーのデータタブを選択し、webクエリの実行を選択してください。
![Screen Shot 2023-12-12 at 19.41.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/b56dda99-d68c-8ff0-dc9b-a2d08ae44649.png)
先ほど作成したファイルを選択します。
![Screen Shot 2023-12-12 at 19.41.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/af27a236-5f60-8a6b-63cb-1ced629fcdaa.png)
データを貼り付ける場所はお好みでいいです。
![Screen Shot 2023-12-12 at 19.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/330278ee-de8f-ecb2-11f4-f711e36349e0.png)
これで貼り付けができます。
![Screen Shot 2023-12-12 at 19.42.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473997/bd7c44fa-5f7a-e1a6-80fb-6f5530f01e03.png)
どこもwindowsでの作成方法だったり肝心のクエリの作成方法までを一貫して書いてないのでメモを残しておきます。
ローカルで使えるアプリケーションという都合上多少の操作感が違うのはosの関係上仕方ないですが、変な差はなくしてほしいです、mirosoftさんや...
CLI でなくコード上の webpack で React の開発環境を作る

## この記事は何か？

[JavaScript Advent Calendar 2023](https://qiita.com/advent-calendar/2023/javascript) 12日目です。 

通常、Recat の環境を構築するには、create-react-app か create-react-app なしで CLIでコマンドを打って環境構築をすると思います。
ここでは、そうではなくて、コード上で webpack を呼び出して、React の環境構築をする方法を説明します。

create-react-app なしでも、CLI ばっかりで中身がどうなっているか気になる方向けの記事になります。
また、この記事では nextjs には触れません、、、が、nextjs や remix のような React フレームワークを作るためには役にたつと思います。

## まとめると
1. webpack を コード上で import し、それを使ってコードをまとめるコードを書く（はまりどころ多数）
2. jsx がついた react のコード全てに、`/* @jsx React.createElement */`をつける
3. webpack をかいたコードを動かす
4. bundleされたファイルが出力されるので、index.html のスクリプト部分に bundle されたファイルを加える。
5. 内容を確認する

## 成果物
https://github.com/coffeecupjapan/WebpackReact/tree/main

## 説明
上のまとめを１つずつ説明していきます。
まず 前提として、npm なりで プロジェクトを作って、React のソースコードを `src` 配下に書きます。

#### webpack を import したコードを書く

その後で、この `src` 配下の React を webpack で１つのファイルにまとめます。このソースコードを作るのが厄介で、ネットを普通に検索しても CLI を使った webpack の使い方しか出てきません。
自分の場合は、以下のようなコードを書いて、webpack をコード上から呼び出しました。

```diff_javascript: index.js (webpackをコード上から呼び出すコード)
import webpack from "webpack";
import { fileURLToPath } from 'url';
import path from "path";
import fs from "fs";
import HtmlWebpackPlugin from "html-webpack-plugin";
import {glob} from "glob";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

(async() => {

const files = (await glob("src/**/*")).map((file) => "./" + file);

const config = {
    context: __dirname,
    mode: "development",
    entry: files,
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.jsx|js$/,
++              include: [/node_modules/, path.resolve(__dirname, 'src')],
                use: {
                    loader: 'babel-loader',
                    options: {
++                     presets: ["@babel/preset-react", "@babel/preset-env"],
                    }
                },
            }
        ]
    },
    plugins: [
++      new HtmlWebpackPlugin({
++          template: './public/index.html',
        })
    ]
}

++ const compiler = webpack(config);
++ compiler.inputFileSystem = fs;
++ compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
    if (err) console.log(err);
    // console.log(stats);
});

})()
```

重要箇所は、ハイライトさせました。
特に、`module.rules[0].include` の行はないとエラーが出てきてしまうので注意です。

#### React のプロジェクトの先頭にjsxのコメント行を加える

この後で、React のプロジェクトに戻り、その先頭に 

```jsx: index.jsx
/** @jsx React.createElement */
```

のようなコメント行を追加します
[didact](https://qiita.com/Asaminnn/items/68b5b614ba44e70c3d74) を作ったことがある方なら見たことがあるかもしれませんが、こちらを加えることで jsx をどう仮想DOMのh関数でjsx記法をjsオブジェクトに変えるかを決めることができます。今回は React の組み込みの関数 React.createElement を使っていきます。

#### webpack を書いたコードを動かす

ここまで書いて、ようやく webpack のコードでコードを bundle させることができます。
通常通り

```zsh:
node index.js
```

で webpack のコードを動かします。

#### bundle されたファイルを確認

こうすると、bundle されたファイルが、dist 配下に現れるので、これと index.html を [http-server](https://zenn.dev/rabee/articles/node-npx-http-server) などを使って、アクセスすると、React が動くことが確認できると思います。

---

以上でした。
では、皆様もいいコーディングライフを！
Pytorch dataloader で陥ったこと

# 状況
・３回目のkaggle挑戦で画像分類に初挑戦
・学習は完了したが、テストデータのevalでエラー発生
・備忘として記録

現在、Editではうまくsubmission.csvまで出力できるのに、submitするとエラーが出て採点してもらえない状況。。。なぜ？（原因わかって解決できれば投稿したいと思います）



# 陥ったこと
kaggleのコンペ「[UBC Ovarian Cancer Subtype Classification and Outlier Detection (UBC-OCEAN)](https://www.kaggle.com/competitions/UBC-OCEAN/overview)」に挑戦している時、テスト画像の予測中に下記エラーが発生した。
```python
RuntimeError: Given groups=1, weight of size [3, 6, 1, 1], expected input[1, 3, 1024, 512] to have 6 channels, but got 3 channels instead
```

# エラー内容と原因
エラーの内容はtorchの形状の不一致のようだった。学習ではバッチサイズ５で実施していたが、
テストの時に画像読み込みが１枚しかなく、形状が異なっていることが原因のようだ。

### モデルのコード
```python
class Model_CNN(nn.Module):
    def __init__(self, filters) -> None:
        super(Model_CNN, self).__init__()
        
        self.main = nn.Sequential(
            nn.Conv2d(3, 512, kernel_size=19, stride=11, padding=1, bias=False),
            nn.BatchNorm2d(512),
            nn.LeakyReLU(0.2),

            nn.Conv2d(512, 256, kernel_size=13, stride=11, padding=1, bias=False),
            nn.BatchNorm2d(256),
            nn.LeakyReLU(0.2),

            nn.Conv2d(256, 128, kernel_size=4, stride=1, bias=False),
            nn.BatchNorm2d(128),
            nn.LeakyReLU(0.2),
        )
        self.classifier = nn.Sequential(nn.Linear(128, num_class))
                                
        
    def forward(self, x):
        out = self.main(x)
        out = out.view(out.size(0), -1)
        out = self.classifier(out)
        return out
```
モデルでエラー発生箇所は下記の予測のところで発生。

### モデルを使った予測
```python
pred_list = []

model.load_state_dict(torch.load(w_save_path))
model.eval()
with torch.no_grad():
    for imgs in testdataloader:　　# 予測
        imgs = Variable(imgs.to(device))
        pred = model(imgs)
        pred_list.append(int(pred.max(1)[1]))
```



# 回避策
いい方法がわからなかったので、画像１枚の時に形状を変更することにした
```python
pred_list = []

model.load_state_dict(torch.load(w_save_path))
model.eval()
with torch.no_grad():
    for imgs in testdataloader.dataset:
        if len(imgs) == 3:　# ファイルが１つしかない場合
            imgs = imgs[np.newaxis, :, :, :]　# 形状を一致させる
        imgs = Variable(imgs.to(device))
        pred = model(imgs)
        pred_list.append(int(pred.max(1)[1]))
```

# その他
  ・他にいい方法があれば教えていただけると、助かります。
Unityで音声対話ボットを簡単に作る方法（APIの使用料金有り）

## はじめに

Unityを使って音声対話ができるAIチャットボットが短時間でできる方法と初心者でもできるようにつまずきそうな点を解説しながら紹介します。

主にこちらのサイトを参考にし説明不足や私が実際にやってみて詰まった部分を少し補足する形になります。下記の内容とこれから説明する内容を見ていただければ簡単に実装ができると思います。
・[ChatGPT＋3Dモデルの音声対話エージェントを15分で開発する方法](https://qiita.com/uezo/items/7ff1566f05c0a1c74a46#%E3%81%8B%E3%82%8F%E3%81%84%E3%81%84%E3%81%8B%E3%81%A3%E3%81%93%E3%81%84%E3%81%84%E5%A3%B0%E3%81%AB%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)



## APIの取得
実装のためには二つのAPIキーが必要です。
私は「Speech-to-Text APIキー」というGoogleが公開しているものと「OpenAIのAPIキー」（GPT-3.5）を使いました。
簡単に言えば、一つ目のキーであなたの声をテキストに変換する部分を用意し、二つ目のキーでAIが返答する部分を取得します。

#### 注意すべきこと
上記二つについては利用料金が発生します！
・Speech-to-Text の料金は、月ごとに請求されます。（月60分以内の使用であれば無料です）[Speech-to-Textの料金の詳細はこちら](https://cloud.google.com/speech-to-text/pricing?hl=ja)
・OpenAIのAPIキーの料金は、使用した分だけ料金が発生します。（最初の３ヶ月は５ドル無料）[OpenAIのAPIキーの料金の詳細はこちら](https://book.st-hakky.com/data-science/open-ai-api-pricing/)

どちらも上限金額を設定できるので、ご自分の財布と相談して使用してください。

## ライブラリのインポート方法
ここではインポートするライブラリについて少しややこしいもの（５つあるうちの下二つ）について説明します。

・[OVRLipSync v29](https://developer.oculus.com/downloads/package/oculus-lipsync-unity/)（キャラクターの口を動かす）
ダウンロードした後、ファイルの中にある「15Puzzle.unitypackage」をつかいます。
Macとは相性が悪いかも...

・[Anime Girl Idle Animations Free](https://assetstore.unity.com/packages/3d/animations/anime-girl-idle-animations-free-150406)（動きを指定する）
UnityStoreから指定のものを購入します。（料金は発生しません）

・ファイルをダウンロードし直接UnityでAssetsに入れる。（こっちの方が簡単）
・Unityで開くを選んで、パッケージをインポートする。

## 完了
ここまでのことを行えば動くはずです。
まずは、「こんにちは」と話しかければ返答をしてくれます。

![スクリーンショット 2023-12-12 20.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631202/9e86ed4f-5fcb-b9a9-ff8a-fa8759376dcf.png)
【10分でできる】Githubのプロフィールにオリジナル画像を設定する方法

# はじめに
休憩がてらQiitaで面白そうな記事を探していたところ、このような記事を見つけました。

https://qiita.com/iijima-naoya-45b/items/ff65dae6b7f37e6a532f

どうやらGithubのトップページはある程度自分仕様にカスタマイズできるとのこと。

たしかに初期状態では少し物寂しい気もしたので、早速実践してみました！

# Before-After
* **ほぼ初期状態（Before）**

![f4392796f1731451a79ebb37acd5f1b9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/c0b39a6e-c16f-4d2a-4ef9-d1aa7903645b.png)

* **少し手を加えてみると（After）**
![01a5a2d1b11f30c140c2a64674040e19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/424e8ecb-494e-4d1f-43fb-39ecf55466d0.png)


# 実装方法
上に示したAfterバージョンの「Stats」部分の実装方法に関しては、

先にご紹介した@iijima-naoya-45bさんの記事をご覧ください！

https://qiita.com/iijima-naoya-45b/items/ff65dae6b7f37e6a532f

今回は「TECH OTAKUS SAVE THE WORLD」と書かれた部分の、カバー画像の作り方と実装方法を簡単に説明します。

# カバー画像の作り方
まずは[Canva](https://www.canva.com/)にログインします（無料版で大丈夫です）。

そして左のメニューバーから「テンプレート」をクリックします。

![9a790963198d929ee39fc1efe8cab97c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/32582848-a4ad-04cd-66e1-670be35c2e1d.png)

次に表示される「おすすめ」の中から、「LinkedIn背景写真」を選びます。

横長のフォルムなので、Githubのカバー画像には使いやすいかと思います。

![ed453444fac41fb98ce19ad0bf0f5890.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/62ea7eb0-2715-79e3-a484-73f952ceed36.png)

すると以下のようにテンプレートがたくさん表示されるので、好きなものを選んで編集し、PNG形式で保存します。

![5fd61519b2caf814f9f4597435a343af.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/c00f30c9-2e66-bdd4-6c2b-bd4cc442dd2b.png)

編集画面右上の「共有」から編集した画像を保存できます。


### Githubで反映させる方法

画像の保存が終わったら、自分のGithubのアカウント名と同じ名前のパブリックリポジトリを作成します。

そして、そのリポジトリ内で「issues」をクリック。

![dc077c41134e56574fd05d78bbf91b4f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/623e15c8-f49c-4b9c-d390-ea08da95fef2.png)

次に「New Issue」をクリックし、「Add a discription」内に先ほどの画像をドラッグ＆ドロップします。

赤丸で囲っている「Paste, drop, or click to add files」から可能です。

![9396080da47be94ae795d9713c28c9ae.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/f129c5f6-c78f-b108-f1f5-dd21d6e4bda1.png)

そして、上画像のように表示されたコードをリポジトリ内に作成した「README」内に書き込み、

「Commit changes」で保存すれば、プロフィールの部分に作成した画像が反映されます。

![6c00131b64c2acd1253016611e13fc54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/dfd1173c-3dc4-e099-e6ac-8633581f8b74.png)



# まとめ
結構簡単にイジれちゃうので、空き時間とかにサクッと試してみるのがおススメです！

他にもいろいろな方法があると思うので、ぜひ自分に合ったプロフィールを作成してみて下さい！


# 参考
偉大なる先人達に心からの感謝を。

https://qiita.com/iijima-naoya-45b/items/ff65dae6b7f37e6a532f

https://medium.com/nerd-for-tech/stand-out-by-personalizing-your-github-profile-f0a5d73f2b4d
はじめて読む486　第13章 486応用プログラミング

## 13.1 メモリマップトファイル

- ページング機能によって物理アドレスを論理アドレスに対応づけることを、物理アドレスを論理アドレスに「マップする」という
    - EMS機能は、プロテクトモードメモリをEMSページのメモリにマップする機能
- メモリマップトファイルをサポートしたオペレーティングシステムでは、アプリケーションソフトウェアがマップさせたメモリに書き込みを行うと、オペレーティングシステムが書いた内容をファイルに反映する
- 本来は、メモリ上でデータを操作するためには、すべてのデータを一旦メモリ上に読み込まなければならないが、無駄な処理も多く非効率
- ファイルサイズが非常に大きい場合も仮に仮想記憶を利用できたとしても物理アドレスに対応づけていない論理アドレスにあるデータは、スワップ用のファイルに保存することとなり、二重にディスク上に記憶させる必要があり非効率
- メモリマップトファイルではこれらの問題を解消し効率の良い、わかりやすいプログラムが作成できるメリットがある
- メモリマップトファイルの仕組み
    - 指定した領域を指定したファイルに対応させる
        - 仮想記憶ではメモリ空間全体をディスク上のスワップファイルに対応させる
    - ファイルをマップした領域のページをすべて物理メモリに対応づけられていない状態にする
    - アプリケーションソフトウェアがこの領域にアクセスすると486がページフォルトを発生させ、オペレーティングシステムに制御が移る
    - オペレーティングシステムはページフォルトへの対応処理として、アドレスに対応する位置のデータをファイルから物理メモリに読み込み、論理ページとの対応づけを行う
    - 物理メモリが不足してくると、使用頻度の低いページに対応づけられた物理メモリの内容を対応するファイルの位置に書き込み、そのページを解放する
    - アプリケーションソフトウェアがマップの解除を要求すると、オペレーティングシステムは書き込みの行われたページに対応づけられた物理メモリの内容をすべてファイルに書き込む

## 13.2 I/Oモニター

- I/Oアクセスの管理
    - I/Oアクセスの管理は486のタスクの保護機能を応用して実現する
    - オペレーティングシステムは、仮想8086モード用のタスクのTSS内にあるI/O許可マップに、個々のI/Oポートへのアクセスの設定を行う
    - アプリケーションソフトウェアは、許可されたI/Oポートには直接アクセスできるが、禁止されたI/Oポートにアクセスすると、486が一般保護例外を発生させてプロテクトモードに移行し、IDTに登録した割り込み処理ルーチンを呼び出す
    - オペレーティングシステムに制御が移るので、I/Oポートに相当する周辺機器の操作をエミュレートしたり、排他制御を行ったりする
- I/Oアクセス管理プログラムの代わりにI/Oモニタープログラムを使ってI/Oポートのアクセス状況を記録する仕組みを考える
    - 以下I/Oモニターの実装についてなので省略

## 13.3 486とオペレーティングシステムの将来

- オペレーティングシステムの内部のしくみを理解することは、アプリケーションソフトウェアを設計したり開発したりする際に大きな助けになる
    - オペレーティングシステムが提供する多くの機能の中から、目的とする処理内容や規模に適したものを選択し、効率がよく柔軟なプログラムを作成できる
- 今後のCPUは高速化を追求していくと思われるが、本書で扱ったメモリ管理、プロセス管理の機能をベースに発展していくものと考えられる（ので内容が陳腐化することもないと思われる）
M1/M2 macのarm64シェルでPython−MIPを動かすには？

## 概要

この記事は、下記の続編です。「arm64のシェルでx86_64のPythonを動かす方法」を説明します。

https://qiita.com/SaitoTsutomu/items/fbc33299e1906a238f53

上記の記事では、**x86_64のzsh**上で、x86_64でしか動かないPython−MIPを稼働させました。
しかし、ときには**arm64のzsh**上で、x86_64のPythonを動かしたい場合もあるでしょう。たとえば、PoetryでPython−MIPを動かしたい場合があたります。

## 前提条件

Rosetteを有効化してください。

Python 3.11を使います。
Python 3.11は、[公式サイト](https://www.python.org/downloads/macos/)の`macOS 64-bit universal2 installer`版をインストールされている必要があります。

また、下記のようにPoetryをインストールしているとします（`%`はシェルのプロンプトです）。
```zsh:zsh
% curl -sSL https://install.python-poetry.org | python3 -
```

さらに、プロジェクト内に仮想環境を作成するように設定します。

```zsh:zsh
% poetry config --local virtualenvs.in-project true
```

## PoetryでPython−MIPを動かすには

ここからは、実際に実行しながら説明します。前提のようにPoetryをインストールすると、下記のようにx86_64上ではPoetryが動きません。

```zsh:zsh
% arch --x86_64 poetry
Traceback (most recent call last):
（中略）
(mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))
```

本記事では、arm64上のシェルで、Poetryを使ってPython−MIPを動かすことがゴールになります。まずは、Poetryの新規プロジェクトを作成します。

```zsh:zsh
# arm64の確認
% uname -m
arm64
# Poetryの新規プロジェクト作成
% poetry new sample
Created package sample in sample
% cd sample
```

Poetryで仮想環境を作成するには`poetry install`としますが、この方法ではうまくいきません。次のように、仮想環境を作成する必要があります。

```zsh:zsh
% python3.11-intel64 -m venv venv .venv
```

`python3.11-intel64`は、x86_64版のPythonです。これで、x86_64版のPythonの仮想環境が作成されればいいのですが、作成されません。そこで、次のように自前で修正します。

```zsh:zsh
% cd .venv/bin
% rm python*
% ln -s python3.11-intel64 python
% ln -s python3.11-intel64 python3
% ln -s python3.11-intel64 python3.11
% ln -s /Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11-intel64
% cd ../..
```

これで、Poetryの仮想環境がx86_64になります。

続いて、pyproject.tomlを次のように修正してください。

```toml:pyproject.toml
[tool.poetry.dependencies]
python = "^3.11"

↓

[tool.poetry.dependencies]
python = "~3.11"
```

`^3.11`は、`>=3.11.0 <4.0.0`を意味してますが、この範囲に対応するPython−MIPのバージョンは存在しません。
`~3.11`とするとことで、`>=3.11.0 <3.12.0`の範囲になり、Python−MIPの`1.15.0`が対応します。

下記のようにPython−MIPをインストールしましょう。

```zsh:zsh
% poetry add mip
```

ここまでくると、PoetryでPython−MIPを実行できます。

```zsh:zsh
% poetry run python -c 'import mip; m = mip.Model()'
```

## x86_64の仮想環境を作成するには（まとめに変えて）

arm64シェルでx86_64のPythonを動かす仮想環境（`.venv`）を作成するには、次のようにします。

```zsh:zsh
% python3.11-intel64 -m venv venv .venv
% cd .venv/bin
% rm python*
% ln -s python3.11-intel64 python
% ln -s python3.11-intel64 python3
% ln -s python3.11-intel64 python3.11
% ln -s /Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11-intel64
% cd ../..
```

アクティベートは、通常通りにできます。

```zsh:zsh
% source .venv/bin/activate
```

なお、`.venv`は、`venv`などの他の名前に変更できます。

以上
Mayaでログインしているアカウントのユーザー名を取得する

## はじめに

メリークリスマス

この記事は[Maya Advent Calender 2023](https://qiita.com/advent-calendar/2023/maya)の25日目の記事になります。

今年も@9boz さんが大量の記事をアップしていて凄いなと感じる年でしたね！

それに比べて僕はトリにも拘らず大した情報しか持ってきてませんがご容赦下さい。


## Mayaでログインしているアカウントのユーザー名を取得する

厳密にはここに表示されている文字列を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/5a8c2a76-4fe7-68be-1ccb-d9b03cdcbc27.png)

もしかしたら既にこういうことをやってる人は多いかもしれませんが、
私が`Maya get login name [検索]`した限りではこちらの記事のしか見つけられませんでした。
https://forums.autodesk.com/t5/maya-programming/get-autodesk-account-username-via-mel-python/td-p/10568045

この記事の中で紹介されている[cmds.license](https://help.autodesk.com/cloudhelp/2022/JPN/Maya-Tech-Docs/CommandsPython/license.html)と[cmds.about](http://me.autodesk.jp/wam/maya/docs/Maya2010/CommandsPython/about.html)も調べてみましたが、licenseのほうはどうやらもう使われていなさそうな雰囲気を醸し出していて、aboutのほうは使われてはいそうですが目的としているユーザー名を取得する方法はありませんでした。

なので、何とか取得できないか試してみました。


## 環境
Maya2023.3

## 結論(コード)

```python
import maya.OpenMayaUI as omui

import shiboken2
from PySide2 import QtWidgets


def getLoginUserName():
    ptr = omui.MQtUtil_findControl('AdlSdkFixedCtrl')
    accountCtrl = shiboken2.wrapInstance(int(ptr), QtWidgets.QPushButton)
    return accountCtrl.text()
    
if __name__ == '__main__':
    print(f'僕の名前は{getLoginUserName()}だよ')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/91ce28d6-14a5-98f4-3fac-f3ae3e919f79.png)



## 解説
MayaのUI要素の殆どはPySideで構成されています。
そのため、ユーザー名が表示されている箇所のWidgetのobjectNameさえ特定できればそこからtextを取得することが出来そうだと考えました。

そこで、@UnitBus さんが公開されている[PySideのWidget一覧を取得できるツール](https://unitbus.github.io/pages/notes/python/pyside#widget%E4%B8%80%E8%A6%A7)を使用させていただき[^1]、根気強く探しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/c67698d1-42ec-2eeb-53fc-04d7a2a70cef.png)

恐らくこれっぽい？というものを見つけ、後はその周辺の要素のtypeやtextの内容を調べて`AdlSdkFixedCtrl`がユーザー名の文字列情報を持ったWidgetだということが特定できました。

そして、結論のコードに至るわけです。

めでたしめでたし！

## おわりに
ユーザー名に限らずMayaのUI要素として表示されている情報の殆どは同様の手順で取得できそうです。
そして、WidgetのobjectNameを調べるための手段として@UnitBus さんのツールは非常に便利で助かりました。この場を借りて感謝いたします。

最後に、Maya Adovent Calendar2023、完走お疲れ様でした！
参加された皆さんの1年に幸多からんことをお祈り申し上げます。


[^1]: ツールのサポートバージョンがMaya2016~2019までのPython2環境のため、当たり前ですが私の動作環境ではエラーが出て動作しませんでした。そのため、簡単な手直しをして最低限の動作をするところまで修正する必要がありました。本来はtextやtypeもUI上に表示されるようなので本文中のように泥臭く要素を調べる必要はなさそうです。便利！