OmniAICreator/Qiita-1.07M huggingface dataset:
Proxmox VEログイン時のEnterprise Subscription通知の無効化方法

# 概要
Proxmox VEをサブスクリプション無しで利用すると、ログイン時に毎回「有効なサブスクリプションがありません」とポップアップが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/f43fb2c6-280e-df5f-c302-169690312a7e.png)

このメッセージを無効化する手順は以下の通りです。注意点として、この操作はProxmoxの公式サポートポリシーに反する場合があるため、使用する際は自己責任で行ってください。

### 手順
1. **SSHでProxmoxサーバーにログインする**
   - SSHクライアント（例：PuTTY）を使用してProxmoxサーバーにログインします。
   - サーバーのIPアドレスと管理者の認証情報を使用します。

2. **通知を無効化するスクリプトファイルを編集する**
   - SSHでログイン後、次のコマンドを実行してエディタ（例：nano）を開きます。
     ```sh
     nano /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
     ```

3. **該当する行をコメントアウトまたは変更する**
   - ファイルを開いたら、次の行を探します。
     ```javascript
                success: function(response, opts) {
                    let res = response.result;
                    if (res === null || res === undefined || !res || res
                        .data.status.toLowerCase() !== 'active') {
                        Ext.Msg.show({
                            title: gettext('No valid subscription'),
                            icon: Ext.Msg.WARNING,
                            message: Proxmox.Utils.getNoSubKeyHtml(res.data.url),
                            buttons: Ext.Msg.OK,
                            callback: function(btn) {
                                if (btn !== 'ok') {
                                    return;
                                }
                                orig_cmd();
                            },
                        });
                    } else {
                        orig_cmd();
                    }
                },
     ```
   - この部分をコメントアウトするか、次のように変更して通知を無効化します。
     ```javascript
                success: function(response, opts) {
                    let res = response.result;
                    if (false) {
                        Ext.Msg.show({
                            title: gettext('No valid subscription'),
                            icon: Ext.Msg.WARNING,
                            message: Proxmox.Utils.getNoSubKeyHtml(res.data.url),
                            buttons: Ext.Msg.OK,
                            callback: function(btn) {
                                if (btn !== 'ok') {
                                    return;
                                }
                                orig_cmd();
                            },
                        });
                    } else {
                        orig_cmd();
                    }
                },
            },
     ```

4. **ファイルを保存して終了する**
   - ファイルを編集したら、変更を保存してエディタを終了します。nanoの場合は以下の手順で行います：
     - `Ctrl + O` を押して保存
     - `Enter` を押して確定
     - `Ctrl + X` を押して終了

5. **Proxmoxサービスを再起動する**
   - 変更を反映させるために、Proxmoxサービスを再起動します。
     ```sh
     systemctl restart pveproxy
     ```

これで、Proxmox VEの管理画面にログインした際にEnterprise Subscriptionの通知が表示されなくなります。
ミドルウェアの存在する理由

# はじめに
<!-- 発端や概要を記載 -->
Laravelを学んで行く中で
初学者なりに疑問に思った事を記述しております


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [疑問点](#疑問点)
1. [結論](#結論)
1. [対比](#対比)
1. [まとめ](#まとめ)

## 疑問点

例えば、loginしているユーザーであるか否かを含め、
コントローラー（MVCの「C」）で実装できるので
ミドルウェアの存在する理由とは

## 結論
時と場合により、必要な機能でした。但し、絶対に必要なわけではなく、
例えば、session情報を他ページに跨ぎ。複数ページにわたり、
同じ内容の処理を施さないとならない場合などに使用する事が多い

ミドルウェアとコントローラーの主な違いを対比した形で理解したら、
納得できたため、下記に記述

## 対比
### ミドルウェア

[実行タイミング]
　HTTPリクエストがアプリケーションに到達する前または後に実行
 
 [適用範囲]
　アプリケーション全体、または特定のルートに対して適用
 
[利点]
- 共通のロジック（認証、キャッシュ、エラーハンドリングなど）を実装するのに適している
- チェーンとして連結することができ、リクエストとレスポンスの両方に対して処理を行うことができる

### コントローラ
[実行タイミング]
特定のルート（URL）に対するリクエストが来たときのみ実行

 [適用される範囲]
一つのルート、または一つのアクションに対し適用

[利点]
- ルートに対する具体的なロジック（データの取得、ビューの表示など）を実装するのに適している
- リクエストの処理結果をレスポンスとして返す
## まとめ

webアプリの全体に対する共通処理（認証機能、エラー表示等）内容は、
ミドルウェアを記述し、複数ページに渡って管理を行う。<br>
一方、コントローラーは、あるルートに紐づく単一的な処理内容を記述する形が適している。例えば、getでページを遷移することもそうだし、ブログ記事の一覧表示や個別記事の実装等がそれにあたる。
DockerのMySQL8が起動出来ないエラーが発生した

私の所属する部署では、LAMP環境をDockerで構築して開発をしています。
先日、メンバーから「MySQLが起動しない」との報告を受けました。

![20240526-210410.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569001/39590465-5829-62da-0e31-9e49c6fac58b.jpeg)

ERRORを見てみると、以下のエラーが発生していました。

```
[MY-013129][Server]A message intended for a client cannot be sent there as no client-session is attached. Therefore, we're sending th information to the error-log instead: MY-001146 - Table 'mysql.component' doesn't exist
```
```
[MY-000067][Server]unknown variable 'default-authentication-plugin=mysql_native_password'.
```

ここで怪しいのが2つ目、[MY-000067]です。
「'default-authentication-plugin=mysql_native_password'って値がないよ」と言われていますね。

みんな大好き、StackOverflowを検索してみると、以下の投稿が行われていました。
[unknown variable 'default-authentication-plugin=mysql_native_password' [closed]](https://stackoverflow.com/questions/78445419/unknown-variable-default-authentication-plugin-mysql-native-password)

どうやら、MySQL8のVer.8.4がリリースされており、'default-authentication-plugin=mysql_native_password'が非推奨になっているようです。

MySQLを構築しているDockerfileを以下のように変更しました。

```Dockerfile
FROM mysql:8
RUN echo "[mysqld]" >> /etc/mysql/my.cnf
# RUN echo "default-authentication-plugin=mysql_native_password" >> /etc/mysql/my.cnf
RUN echo "mysql-native-password=ON" >> /etc/mysql/my.cnf
RUN echo "authentication_policy=mysql_native_password,," >> /etc/mysql/my.cnf
```
このように変更し、buildされたmysqlを削除したうえで実行してみたところ、問題なく動作可能でした。
FRCで機体の設計をした話-SAZANKA Robotics

# はじめに
こんにちは、しがない高校生をしているBasalte(ばさると)と申します。
今回はSAZANKA RoboticsというFRCチームに参加した記録、経験などを残しておきたいと思います。
### 宣伝
自分は普段PyLoT Roboticsというチームを立ち上げ、RoboCup@Home Eucationという大会に挑戦しています！
もしよければこちらのリンクも合わせてご覧ください！！

https://t.co/QZzCm7T8UX

# 加入
SAZANKA Roboticsから学校にお誘いの電話が来たので、さらっと返信してみたところ、リーダーが文化祭に来てくれました。
そこでお話しした結果、すぐに加入することが決まってしまいました。
SAZANKAは毎年企業からお金を集めて活動をしていて、アメリカの大きな大会に参加している珍しいチームだったということで、自分の経験にプラスになりそうだなと思い加入を決めました。

# 9月～12月
この期間はひたすら資金集めと過去の他チームのロボットのCAD漁りをやっていました。
資金集めに関して、たくさんの企業の方をお話をすることができ、資金面の交渉以前にとてもいい経験になりました。

CAD漁りは、過去のFRCチームが公開しているビルドスレッドとCADデータを見て、ロボットの機構やなぜそのような機構になったのかの過程などを調べました。
設計の雰囲気をつかみ、どういう過程を踏んでロボットを作っているかを学びました。


# 1月～2月上旬
1/7にこの年のルールが発表され、シーズンが始まります。
最初はとにかくルールを読み、どういう機構を作ったら点を取れるかを考えます。
自分たちはRI3Dという社会人(?)がやっているルールが出てから3日でFRCロボットを作り上げるというYoutubeをよく見ていました。
1月中旬には自分も担当を持ち、過去のロボットを参考に設計に入りました。
海外の部品やCADは全部インチで作られているので、寸法を合わせる際にはヤードポンド法を割と恨みました。~~ヤーポンは滅べ~~

設計が終わると金属加工、組み立てです。これはMISUMI、Andymarkから部品が届くのを待っていたので少し遅れました。

<img width=25%><img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1895796/cb4c1970-9086-0c82-7ae6-a0fc99c596c7.png width=50%>

<img width=25%><img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1895796/b6adaada-0e56-4b30-29d9-b4807ad74d54.png width=50%>

# 2月下旬～4月
ちまちまと自分の担当の修正を加えてはいましたが、基本的に自分はあまり活動には参加しませんでした。
これはシーズンが始まる前から伝えてはあったのですが、普段は別のロボコンチームのリーダーをやっているため、自分の担当の設計が終わったらコミットを下げる予定でした。ハワイに行かないことも決まっていたため、本当に数日しか活動場所に行かず、部品の加工などを少し手伝ってメンバーを送り出しました。

大会期間中は作業の傍ら大会結果や公式配信をたまに見ていました。
大会期間中は私が設計した部分を中学生がメンテナンスしていて本当に頭が上がりませんでした。
公式配信で私が担当した部分で点数を取っていた時は何とも言えない嬉しい思いに駆られました。

<img width=25%><img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1895796/cefb0c07-3a6d-f44c-0a18-545e4466c758.jpeg width=50%>


<img width=25%><img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1895796/1765a34d-fc57-7c28-6e16-ed73f13e7fde.png width=50%>




# 最後に
自分がコミットできたことは少ないですが、初めてこんなに幅広い学年の人たちと共同作業をやったなという新鮮な体験でした。
また、普段は制御しかしない人なので、設計を少し触ることができたことも大きい経験だったと思います。

改めて一緒に戦ってくれたチームリーダー、メンバー、メンターの皆さんに感謝を伝えたいと思います。
ありがとうございました。
857. Minimum Cost to Hire K Workers の解き方メモ

https://leetcode.com/problems/minimum-cost-to-hire-k-workers/description

品質あたりに払う給料をコスパ係数と定義します。たとえば、品質20、給料50の労働者のコスパ係数は2.5です。そして、コスパ係数が高いことを「コスパが良い」、その逆を「コスパが悪い」と呼ぶことにします。

Aさんを基準にグループを構成することを考えると、まずはAさんよりコスパの悪いK-1人を選ぶ必要があります。たとえば、Aさん=品質20、給与50、コスパ係数2.5だとします。このとき、Aさんよりコスパの良いXさん=品質5、給与25、コスパ係数5を選ぶと、Xさんに払う給与は20となり、最低給与25を下回ってしまいます。

ここで、Aさんよりコスパの悪いBさんとCさんを選んだとすると、このグループに払う給与は

```
  Aさんのコスパ係数 * Aさんの品質
+ Aさんのコスパ係数 * Bさんの品質
+ Aさんのコスパ係数 * Cさんの品質
```

これを整理すると

```
Aさんのコスパ係数 * (Aさんの品質 + Bさんの品質 + Cさんの品質)
```

グループに払う給料が最小になる可能性があるのは、`Aさんの品質 + Bさんの品質 + Cさんの品質` が最小になるケースです。つまり、Aさんを基準にしたとき、Aさんよりコスパが悪い労働者のうち、品質が低いK-1人を選択すればよいとわかります。

あとはこれを実装します。「Aさんよりコスパが悪い労働者のうち、品質が低いK-1人」については優先度付きキューなどで管理すればよいです。

```rust
use std::collections::BinaryHeap;

impl Solution {
    pub fn mincost_to_hire_workers(quality: Vec<i32>, wage: Vec<i32>, k: i32) -> f64 {
        let mut cost_perfomaces = (0..quality.len())
            .map(|i| (wage[i] as f64 / quality[i] as f64, i))
            .collect::<Vec<_>>();
        cost_perfomaces.sort_by(|(cost_pefomance1, i1), (cost_pefomance2, i2)| {
            cost_pefomance1.partial_cmp(cost_pefomance2).unwrap()
        });

        let mut heap = BinaryHeap::new();
        let mut quality_sum = 0;
        let mut best = f64::MAX;
        for (cost_perfomance, i) in cost_perfomaces {
            if heap.len() == k as usize - 1 {
                best = best.min(cost_perfomance * (quality[i] as f64 + quality_sum as f64));
                heap.push(quality[i]);
                quality_sum += quality[i];
                quality_sum -= heap.pop().unwrap();
            } else {
                heap.push(quality[i]);
                quality_sum += quality[i];
            }
        }

        best
    }
}
```
Visualforceページで意味不明のエラー発生時の対処

あるExperienceCloudサイトのVisualforceページ改修で意味不明のエラーを遭遇、
その時に対応内容をメモっておきます。

#### 要約
Experience Cloud上で、Visualforceページを利用して、データ登録プログラムを実装。
登録処理で入力チェックを行い、入力エラーがある場合は、

```C#
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, 'エラーメッセージ'));
return null;
```
で元の画面に戻るようしていますが、
実際には下記のエラー画面が表示されてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159211/9864d8d9-b3e3-c2ad-3f5e-eb0b7cc97b71.png)

System.debugを「return null;」前に入れてみましたが、ちゃんと出力されているので
return null;は確実に実行されている。

デバッグログでの出力を時間順で見ると
操作の列は
/apex/xxxScreenName　の次に
/apex/Exception　 がありその後に何らかのエラーが発生したよう見える、

中身を見てもエラーのようなものは見つかりませんでした。

Chromeの開発ツールから見ると戻り値のHttpコードは500：Internal Server Errorとなっています。
おそらくページの処理は終わり、その後ブラウザー側に戻す前になにかが発生したはず・・・

#### 疑問
上記のVisualforceページで発生したエラーはどこかで見れるようにできますか？

#### いろいろググって
ExperienceCloudのサイトの指定で標準のエラーページの指定があり、
その指定したページを編集して、エラーの説明を出力できることが分かった。

#### 手順
１．設定　⇒　ユーザーインターフェース　⇒　サイトおよびドメイン　⇒　サイト
２．サイトの表示ラベル列で、対象のサイト名をクリック
３．エラーページセクションで、汎用エラーページの「サイトページ名」をクリック

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159211/e952d0c4-96b2-fbd6-7c9f-22c2435d1ac1.png)

４．表示されるVisualforceページで「編集」ボタンをクリックし下記のように修正

```HTML
<apex:param value="{!$Site.ErrorMessage}"/>
```
を
```HTML
<apex:param value="{!$Site.ErrorDescription}"/>
```
に変更する。

```HTML
<apex:page showHeader="false" title="{!$Label.site.error2}" cache="false">
  <apex:composition template="{!$Site.Template}">
    <apex:define name="body">
      <center>
        <apex:panelGrid bgcolor="white" columns="1" style="align: center;">
          <br/>
          <br/>
          <apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="1" styleClass="topPanelContainer">
            <br/>
            <apex:outputPanel layout="block" styleClass="topPanel">
              <apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="3">
                <apex:image url="{!URLFOR($Resource.SiteSamples, 'img/clock.png')}"/>
                <apex:image url="{!URLFOR($Resource.SiteSamples, 'img/warning.png')}"/>
                <apex:panelGroup >
                  <apex:outputText styleClass="title" value="{!$Label.site.error}">
                   
                   <!-- this parameter needs to be italic in the site.error label 
                   <apex:param value="{!$Site.ErrorMessage}"/>
                   -->
                   <apex:param value="{!$Site.ErrorDescription}"/>
                  </apex:outputText>
                  <br/>
                  <br/>
                </apex:panelGroup>
              </apex:panelGrid>
             </apex:outputPanel>
            <c:SitePoweredBy />
          </apex:panelGrid>
          <br/>
          <apex:messages />
          <br/>
        </apex:panelGrid>
      </center>
    </apex:define>
  </apex:composition>
</apex:page>
```

５．保存して閉じる、
６．テスト画面に戻って再度実行してみると、エラーの内容が表示されるようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159211/64da88a7-6c2a-35ff-5f4c-171985ea06f5.png)

エラーの内容は分かったので、次は何とかできるでしょう。
エラーが解決できたらまた内容を追記しておきます。
!empty()と??(Null合体演算子)とisEmpty()

# empty()
変数が存在し、かつ「空」でないことを確認する場合に使用

# ?? (Null合体演算子)
変数がnullでない場合のデフォルト値を設定する場合に使用

## 使い方
```php
$foo = null;
$bar = $foo ?? 'default';
// $bar は 'default' になる

$foo = 'value';
$bar = $foo ?? 'default';
// $bar は 'value' になる
```

# isEmpty()
コレクションが空であるかどうかを確認する

# 自分のしたミス1

`$var`が存在すればそのまま`$var`を表示
空であればdefaultを表示したいといったような場面があったのですが、
空文字列の時Null合体演算子は`$var`が存在するという判定になるらしくそのまま空文字列を表示してしまうというミスをしてしまいました。

```php
$var = '';
$result = $var ?? 'default';
// $result は '' (空文字列) になる
```

## 解決策
Null合体演算子で省略せずに`!empty()`を使う

# 自分のしたミス2

```php
$collection = collect([])
```
上記のような空のコレクションの際
コレクションオブジェクト自体は存在するため、empty()はfalseを返し、!empty()はtrueを返します。
よって自分の思い描いた実装ではなくなってしまいました。

## 解決策
isEmpty()やisNotEmpty()を使う。
コレクション自体が空であるか判定するものを最初から使うことを学びました。
【技術書典】Streamlitの入門書で初出展してみて

# 前置き
こんにちは。データエンジニアの山口歩夢です！

5/26の技術書典のオフラインイベントにて、Streamlitの入門書を執筆して初出展してきました。

「Streamlitデータ可視化入門」を購入してくださった皆様、手に取ってくださった皆様、興味を持ってくださった皆様、誠にありがとうございます。
そして、レビューやブースでの販売、告知などお力を貸してくださった皆様、本当にありがとうございました。

# 頒布した同人誌
今回の頒布物はこちらです。

https://techbookfest.org/product/t5GBwbFm4kUhXrTPkGpAnY?utm_source=twitter&utm_medium=social&utm_campaign=share

Streamlitの公式ドキュメントを基礎的なところからしっかり読み、2ヶ月くらいかけてコツコツ書き進めました。
Streamlitの本当に基礎的なところから、自分が業務でStreamlitを使っていて便利だなと思った機能など幅広く書かせていただきました。
公式ドキュメントを入念にチェックすることでしか気付けなかった機能なども書けて良かったなと感じています！

# 当日の話
ここからは当日のお話になります。

物理本はこういったものが届いていました。
しろくまが可愛く写っていてテンションが上がりました。

![IMG_2562 (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/ea6ec51a-696c-cd70-ecad-0204ee339064.jpeg)

そして、ブースをこのように設営致しました。
物理本は50冊ご用意させていただきましたが、**2時間30分**ほどで売り切れとなりました！誠にありがとうございます:bow:

そして、物理本をお渡しできなかった皆様、大変申し訳ございません:bow: 
電子版はまだ購入可能なため、もし宜しければチェックいただけると幸いです...

![IMG_2560.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/15380586-aed0-c25a-f862-96658b615051.jpeg)

ブースにはSnowflakeの本橋さんや、Streamlit勉強会の檜山さんがデモアプリを作成して応援に来てくださいました。
檜山さんのデモアプリはこういったすごいもので、Streamlitでリアルタイムのデータ可視化を行なっています！

https://x.com/toru_data/status/1766822727317635116

# 購入したもの
Snowflakeの勉強のために、自分はこちらの同人誌を購入しました。
読むのが楽しみです！

![IMG_2568.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/2e978e8a-bb83-5371-0168-1d003b35c379.jpeg)


# まとめ
初めて書いた技術書が多くの人に興味を持っていただけて、お役に立てたようで本当に嬉しかったです。
Streamlitの日本語の情報が少なめで、書籍なども無いため、自分が書いてみようという思いで書いてみましたが、やってみて良かったなぁと思います。

そして、Streamlitのスキルアップはもちろん、英語の勉強もしっかりやって、海外の記事などからもStreamlitの有用な情報を集められるようになって、もっと良いStreamlitの技術書をまた書きたいなと思いました💪
Copilot Plus PC　～Digest～

5月下旬にMicrosoftのAIに関する最新の発表がありましたので、簡単に紹介させていただきます。

# Copilot Plus PC

**Copilot Plus PC**は、AIを搭載したPCです。高性能なCopilot機能を搭載しています。(AI PC自体は約2年前くらいから話題にはされていましたが、今年の4月に入ってからHPがAI PCを出したと[News Picks](https://www.youtube.com/watch?v=Dww4z_wWrP8)で話題にされてからAI PCの話題は加速化しました。)  

### できること

・Copilotはホーム画面にボタンとして表示され、簡単に呼び出すことができます。  
・ウィンドウのサイズ変更やスナップなど、ユーザーのニーズに合わせてカスタマイズできます。  
・Copilotは、質問に答えたり、ウェブ検索や文書の要約など、タスクを完了することができます。  
・PCの操作にもAIを使用することができます。

## 新しいリコール機能

・タブやアプリを検索することで、PCから必要な情報を見つけやすくしてくれます。  
・キーワードやフレーズを使って検索することができます。

## マイクロソフトのLLM（大規模言語モデル）ラインナップ

・オープンソースとクローズドソース、大規模と小規模のモデルを含む、幅広いLLMを提供。  
・Mistral AI、OpenAIのGPT-4 Omni、Command R Plus、MetaのLaMDA 3など、他社のAIモデルも多数提供しています。
文化祭で来場者数を調べたかった

# はじめに

こんにちは、しがない高校生をしているBasalteと申します。

今回は、クラッシュしたプロジェクトの供養をする記事です。

大まかにいうと、校門にカメラを置いてあるラインを超えた人数を計測する装置です。
最近Twitterなどで話題になっていますが、DeepSortという技術を使って人間の個体識別をするだけです。


# 目的
2023年の文化祭はコロナなどない久しぶりの通常開催で、何人外部から人が来るか本当にわからない状態で、パンフレットや食品などを不透明な状態で数を用意することになりました。

ですが、リアルタイムで来場者数が分かれば、1日目、2日目でパンフレットを配るペース配分などを計算できるのではないかということや、来年度以降の準備の参考になるという目的で始まりました。
~~ただ単に自分が調べたかったのもある~~

# 技術スタック
・Python3
・Anaconda
・Yolov8
・DeepSORT
・OPenCV
Yolov8はともかく、DeepSortは触ったことがなかったので勉強しながらという感じでした。

# 実装
やってることはObject RecogitionとTrakingと位置判定です。
車の台数を数えるサンプルなどもあり、意外とサクッと実装出来ました。リアルタイムでやってるものは少なかったです。
動作映像はファイルの奥深くに消えてしまいました。すいません。


## エラー
わざわざDeepSortを使ったのはYolov8のtrackが使えなかったからなのですが、これは単純にultralyticsのバージョンが古かったらしく、先日updateしたら普通に使えました。泣きたいです。

# 設置までの課題
実際に当日設置するにはいくつかの課題を乗り越えなければなりませんでした。

### 当日動作するPCがない
私は計算資源が貧弱なMac Bookかデスクトップしか持っていなかったので、ある程度計算能力のあるノートPCが必要でしたが、当日確保できる見通しが立ちませんでした。
### 設置場所がない
当日、校門前はもちろん、校舎内、中庭も人でごった返し、三脚を立てる場所もテントを立てる場所もないです。また、私の学校は謎に校門が広く、入場門と退場門が分かれており、どちらも視認できる画角がほぼ存在しなかったため入退場を管理できないという結論になりました。
### 外に置くと高温でPC、カメラ共に逝く
これはさらに前年度の文化祭で知ったのですが、屋外で30分ほど撮影をしていると日射で熱が溜まって撮影できなくなってしまいます。PCも同じで、少しの間外で日光を浴びていただけで動作不能になってしまうことが容易に想像できます。
### 精度が出ない
たくさんの人が来るので、ピークの時は(カメラから見て)たくさんの人が重なり合ってしまうので、天下のYolov8様でも人を全て認識するのはほぼ不可能です。また、日光の加減でもパラメーターの閾値が変わってしまうため、一日を通して一定して精度を出すのは難しいです。
### 活用できる場面がない
この装置のいいところはリアルタイムで校内にいる人数と全入場者数を調べられることですが、それを活用する場所があまりありませんでした。
モニターや放送で使うにも他の文化祭実行委員との連携が必要で、きちんと運用できるかも不透明だったため、準備をするのが難しかったです。
また、来年度の準備に使用できるということも、パンフの消費枚数や食品の消費のデータをそのまま使用できるため、あまり効果がないということに気づきました。

# 結果
上のような課題が山積してしまい、特にやる意味も感じれなくなってしまったため、モチベとともにプロジェクトが終了を迎えました。~~(自分1人でやってたので一瞬で終了させました)~~

今後復活させる予定はないですが、他の小さめのイベントなどでやってみるのもいいかもしれませんね。
[Windows] マウスの60fpsスムース感がたまに無くなる現象の時に試すこと

# 現象
PCが少し古い場合や、ノートPCで控えめなグラフィックボード搭載の場合、HDMIでWQXGAや4Kモニタに接続すると、たまに30fpsになってしまうことがあります。
ランダムで発生して、直ったりするタイミングも読めません。
GPU性能の限界として諦めるところでしたが、念のため理由を調べてみました。
# 結論
「ホバーしたときに非アクティブウインドウをスクロールする」
ここをオフにして下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/2b407eba-9a41-7a32-e669-a088e72ec5e6.png)
これで30fps化されてカクつくことが無くなります。お試し下さい。
# 補足
なぜかUSB-C PD Alternate接続だと発生しないんですよね。
モニタとPCがPD Alternate対応の場合は、なるべくHDMIではなくUSB-Cで接続するのがオススメです。
SwiftライブラリLightWeightDIを使ったDIの実現

### SwiftによるDIの実現
- 依存性の解決の方法はコンストラクタインジェクション、フィールドインジェクションなどがあります。ここではDIコンテナとSwiftの`@PropertyWrapper`を使ったライブラリ`LightWeightDI`により依存性を解決する方法を紹介します。

## DIの必要性
サンプルはkotlinですが、言語仕様的に似てるので参考になります。
[依存性注入について](https://zenn.dev/atsu77/articles/230612_dependency_injection)


## LightWeightDIについて
[LightWeightDIについて](https://github.com/daanibe12/LightWeightDI)
- 投稿者（`anibe`）が開発したお手軽にDIを実現するライブラリです。
- `Swift Package Manager` `Cocoapods`に対応してます。
- 以下のようにあらかじめコンテナに登録してから使う。内部的に使ってる`Swinject`と使い方は同じ
- スコープを指定して登録します。

```
//プロトコルの型とimplのインスタンスの紐付け
        DependencyResolver.shared.regist(AppScopeProtocol.self, scope: .container) { r in
            return AppScopeProtocolImpl()
        }

        //injected AppScopeProtocol implementation object
        @Autowired var appObj: AppScopeProtocol

//プロトコルの型とimplのインスタンスの紐付け(default 弱参照)
        DependencyResolver.shared.regist(ARepository.self) { r in
            return ARepositoryImpl()
        }


```
- DIして使う場合の記述方法、プロトコルやクラスを指定
- `@Autowired` を使って指定の型をDIして使用する
```
@Autowired var repository: ARepository
@Autowired var appObj: AppScopeProtocol

```

## 細かい使用方法について
- サンプルがあるのでそれを参考にしてください。
- [SwiftUIのプロジェクトでLightWeightDIを使ったサンプル](https://github.com/daanibe12/LightWeightDI/files/15502655/SampleLightWeightDI5.zip)


### LightWeightDIを公開してみて、今後
- SwiftでDIのライブラリ以外に少なくて、メジャーじゃないので、使いやすいように自分でこういうのあったらなあというのを作れた。
- 仕事で`Cocoapods` `Swift package manager`を使ったライブラリを作ったことがあったがその時の知見を整理できてよかった。
- コンテナ部分を`Swinject`を間借りしてるのでコンテナを時間ある時実装したい。それ終わったら`1.0.0`で公開する予定。
PwnagotchiのDIY、やってみた。

# 趣旨
自宅環境が外部のクラッカーからの攻撃に対してどれだけ脆弱なのかを楽しみながら計測してみようと思い、ポーナゴッチちゃんとDIYすることにしました。

以下のURLが公式サイトになります。パーツが揃っていればここを見るだけで全て事足ります。英語が読めれば僕の解説は必要ありません。

https://pwnagotchi.ai/installation/

# PwnagotchiのDIY手順
必要なハードウェア部品リスト
![Screenshot 2024-05-26 at 13.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/9538ba51-61f2-bf06-4a93-150f68b0df44.png)

対応しているスクリーン
![Screenshot 2024-05-26 at 13.01.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/8d7d443a-f1bd-92f0-417b-115400f20110.png)

僕の場合は公式推奨のデバイスではなく以下のデバイスを購入していたため、別途実装方法を探さないと動きませんでした。

- Waveshare v4 E-Ink Display 
- Raspberry Pi Zero 2

ポーナゴッチの設定に使用したコンピュータはMacです。

Zero 2 と v4 E-Ink に対応しているバージョンは有志の方が公開してくれています。

https://github.com/jayofelony/pwnagotchi/releases/tag/v2.6.7

pwnagotchi-rpi-bookworm-2.6.7-arm64.img.xzをダウンロードして解凍してイメージファイルを用意します。

![Screenshot 2024-05-26 at 13.04.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/b3d9adc6-193c-99a6-0bef-af4013778f11.png)

準備したイメージをBalenaEtcherでフラッシュします。MacにSDカードを直接差し込んでフラッシュします。

https://etcher.balena.io/

フラッシュ後にもう一度SDカードを接続してSDのルートディレクトリに相当する場所でConfigファイルを作成します。

```
cd /Volumes/sdcardname/
sudo nano config.toml
```
以下の内容を編集後にconfig.tomlにコピペします。
```
main.name = "changemetothenameyouwantyourpwnagotchi"
main.lang = "en"
main.whitelist = [
  "changetoyourwifiname"
]
 
main.plugins.grid.enabled = true
main.plugins.grid.report = true
main.plugins.grid.exclude = [
   "changetoyourwifiname"
]
 
ui.display.enabled = true
ui.display.type = "waveshare_3"
ui.display.color = "black"
 
bettercap.handshakes = "/home/pi/handshakes/"
```

保存した後はMacからSDカードを抜いてラズパイにさして電源ではない方（データ通信の方）とMacをUSB接続します。5分から10分ほど放置します。コード抜いたりしたら初めからやりなおしです。

しばらく放置してスクリーンにポーナゴッチちゃんの顔が映れば成功です。

Mac側でRNDIS/Ethernet Gadgetの設定をします。

System Setting > Networkから Detailsを選びTCP/IPのConfigure IPv4をマニュアルにし、IP addressを10.0.0.1、Subnet maskを255.255.255.0にします。

![Screenshot 2024-05-26 at 13.16.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/0637db47-4733-3fc7-bee8-85a5a911c7f6.png)

次はDNSを選択し、8.8.8.8と1.1.1.1を追加します。
![Screenshot 2024-05-26 at 13.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/8207ae9f-8d5f-9853-6afd-00d8d49ac08c.png)

これでMacからポーナゴッチちゃんにUSBケーブルを通してSSH接続できるようになります。

ケーブルを抜かないまま、Mac上でブラウザを開いて10.0.0.1:8080にアクセスします。ユーザー名とパスワードの入力を求められるますが、多分どちらもchangemeでログインできます。

変更したい場合は先ほどのConfigファイルの一番したに以下の2行を追加すれば変更できます。
```
ui.web.username = "my_new_username"
ui.web.password = "my_new_password"
```

あとは外出先でポーナゴッチちゃんの電源を入れてハンドシェイクをさせて集めてきたPCAPファイルをクラックするようのPCに移動させます。

```
scp -r 'pi@10.0.0.2:/home/pi/handshakes/*' /path/to/directory
```

クラックに使えるソフトはPwnagotchiの公式サイトに載っていました。

自分の環境がルーター次第で用意に侵入できてしまうと気づきますし、そもそもDIYは楽しく学べる最高の学習機会なのでお時間のあるセキュリティ意識高めの人はぜひやってみてください。
Unityのシーン遷移を作る

# やりたいこと
* ボタンを押したらシーン遷移する
* Invokeを使って、数秒経ってからシーン遷移する


## 前提準備
Build Settingsの編集を行います。これが行われていないとシーン遷移できません。

※やり方
1. メニューバーからFile>Build Settingsを開く

![スクリーンショット 2024-05-26 19.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771111/6bc063af-79ae-b905-edef-4e058d0023ea.png)

2. 上部の「Scenes In Build」にシーンをドラックアンドドロップする

![スクリーンショット 2024-05-26 19.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771111/bb5db3e0-4246-2ad6-40f7-203090f08611.png)

※特にこの後保存作業などはありません。追加できたらタブを閉じてしまってOKです。

## ボタンを押したらシーン遷移する

### スクリプト

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //これ必須です

public class Scene: MonoBehaviour {
    
    [SerializeField] private string _loadScene; //シーン名を記述

    public void SceneChange()
    {
        SceneManager.LoadScene(_loadScene);
    }

}
```

ボタンの方は、押された時に「Scene」が呼び出されるように設定します。
読み込みたいシーンはInspectorから編集可能です。使い回しをしたいときに便利そう。

もし使い回しする必要がない！という場合は、

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Scene: MonoBehaviour {

    public void SceneChange()
    {
        SceneManager.LoadScene("読み込みたいシーン名");
    }
```

と、シーン名をダブルクォーテーションで囲って直接書けばOKです。

## Invokeを使って、数秒経ってからシーン遷移する
フェードアウトやSEを聞かせるなど、何か演出をかける際に使えるといいと思います。

### スクリプト

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Scene: MonoBehaviour {

    [SerializeField] private string _loadScene;
    public int _delay; //遅延させたい秒数

    public void TimeLag()
    {
        Invoke("SceneChange", _delay);
    }

    public void SceneChange()
    {
        SceneManager.LoadScene(_loadScene);
    }
```

ボタンを押したときに呼び出す関数は「TimeLag」にしてください。
Inspectorに、読み込みたいシーン名と遅延させたい秒数を設定しておくのをお忘れなく。

![スクリーンショット 2024-05-26 20.09.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771111/8b1944a3-0617-c8bc-3299-d2e0a341fb17.png)

# 最後に
シーン遷移はほとんどのゲームで使うことになると思うので、すぐ書ける・わかりやすいように自分の型を作っておいて損はないなと感じています。
めざせ、使いやすいスクリプト！
Rust 用の Vim 環境を整える

# はじめに

自分用のメモ。

# dotfiles

https://github.com/takavfx/dotfiles/tree/main

# 環境設定

## rust.vim の導入

Rust の公式プラグイン。

dein.vim をプラグインマネージャーに使用しているので、TOML に設定してインストール。

```toml:.dein.toml
[[plugins]]
repo = "rust-lang/rust.vim"
```

## 保存時の rustfmt の適用

保存時に rustfmt フォーマッタを適用したい。
コンフィグに追加する。

```toml:~/.vim/.dein.toml
[[plugins]]
repo = "rust-lang/rust.vim"
hook_add = '''
let g:rustfmt_autosave = 1
'''
```

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/8917e546-5959-b96a-3d94-2605ff501c22.gif)

## rust-analyzer を適用する

もともと [`vim-lsp`](https://github.com/prabirshrestha/vim-lsp) を使用していたけど、[rust-analyzer のドキュメント](https://rust-analyzer.github.io/manual.html#vimneovim)には [`coc.nvim`](https://github.com/neoclide/coc.nvim) が例に書かれてたので、この際に Coc を入れて試してみることにする。
（てか coc が Vim で使えたの知らなかった。勝手に Neovim 専用だと勘違いしてた…

https://rust-analyzer.github.io/manual.html#vimneovim

### coc 自体のインストール

```toml:~/.vim/.dein.toml
[[plugins]]
repo = 'neoclide/coc.nvim'
branch = 'release'
```

### rust-analyzer の coc セットアップ

`:CocConfig` コマンドで `coc-settings.json` ファイルを開いて編集
（[dotfiles で管理することにした](https://github.com/takavfx/dotfiles/blob/main/vimfiles/coc-settings.json)


```json:~/vimfiles/coc-settings.json
{
  "launguageserver": {
    "rust": {
      "command": "rust-analyzer",
      "filetypes": ["rust"],
      "rootPatterns": ["Cargo.toml"]
    }
  }
}
```

ここまで設定するだけで、もう「コード書けるぜ」までは行ける。
**rust-analyzer 様様**。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/8ca6266e-a7b7-20fc-53fa-5b3a02fc32b8.png)


:::note info
**トラブルシュート**
```
build/index.js not found, please install dependencies and compile coc.nvim by: npm ci
```

coc.nvim を最初にインストールするとこの問題にぶつかった。

こちらのトラブルシュートで対応。
https://qiita.com/Taichi-yzrh/items/5868e618c82e328c89f6

```powershell
:call coc#util#install()
```
:::

# Rust 操作メモ

## rustfmt を任意で起動する

```
:RustFmt
```
インサートSQL生成用エクセルマクロ

# はじめに
インサートSQL生成用エクセルマクロを作成しました。自分用ですが、皆さんにも使ってもらえたらうれしいです。
出力されたSQLがOracle database環境で動くことは確認しています。



# ソース
```SqlInsertMacro.txt
Sub SqlInsertMacro()

    Dim insert As String: insert = "INSERT INTO "  '出力SQLフォーマット
    Dim sql As String: sql = "" '出力SQL本体
    Dim sqlcount As Long: sqlcount = 0  'SQL数
    Dim Column As Long: Column = 0  '列数
    
    
    'SQL数カウント
    Do
        '// セル値が未設定の場合
        If Cells(sqlcount + 4, 3).Value = "" Then
            '// ループを抜ける
            Exit Do
        End If
        
        '// ループカウンタを加算
        sqlcount = sqlcount + 1
    Loop
    
    
    
    
    '列数カウント
    Do
        '// セル値が未設定の場合
        If Cells(3, Column + 1).Value = "" Then
            '// ループを抜ける
            Exit Do
        End If
        
        '// ループカウンタを加算
        Column = Column + 1
    Loop
    
    
    
    
    'VALUESまでのフォーマット作成
    insert = insert & Range("A1").Value & " ("
    
    For i = 1 To Column
        '最初のカラム以外は前にカンマを付ける
        If i <> 1 Then
            insert = insert & ","
        End If
            
        insert = insert & Cells(2, i).Value
    Next i
         
    insert = insert & ") VALUES ("
    
    
    
    
    
    '最後まで作成し、出力する
    For j = 1 To sqlcount
    
        sql = insert
        
        For k = 1 To Column
        
            '最初のカラム以外は前にカンマを付ける
            If k <> 1 Then
                sql = sql & ","
            End If
            
            
            '型が数字の場合
            If Cells(3, k).Value = "NUMBER" Then
                 sql = sql & Cells(j + 3, k).Value
            '型がDATEの場合
            ElseIf Cells(3, k).Value = "DATE" Then
                sql = sql & "TO_DATE('" & Cells(j + 3, k).Value & "')"
            '型がTIMESTAMPの場合
            ElseIf Cells(3, k).Value = "TIMESTAMP" Then
                sql = sql & "TO_DATE('" & Cells(j + 3, k).Value & "')"
            'シングルクォーテーションをつけたい型の場合
            Else
               sql = sql & "'" & Cells(j + 3, k).Value & "'"
            End If
            
        Next k
        
    
        'SQL作成終了
        sql = sql & ");"
    
        '作成されたSQL文を出力
        Cells(j + 3, k).Value = sql

    Next j
    

End Sub


```

# 使い方
1行目…テーブル名を入力
2行目…項目名を入力
3行目…項目の型を入力
4行目以降…データを入力


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/ef38e29e-647a-ebbe-3a1f-d3ad82c629da.png)


マクロを実行すると、最後の列の次の列（この例だとF列）にインサートSQLが生成されます。




# おまけ
今回のマクロを作成する際に、テスト用に使用したSQLです。

```SQL.txt
DROP TABLE HOGE;

CREATE TABLE HOGE
(
  CHA CHAR(10),	-- 固定長文字列
	VARC VARCHAR(100),	-- 文字列
	NUM NUMBER,	-- 数値
	DA DATE,	-- 日付
	TIST TIMESTAMP	-- タイムスタンプ
);



INSERT INTO HOGE (
CHA
,VARC
,NUM
,DA
,TIST
) VALUES (
  '0001'
 ,'田中太郎'
 ,32
 ,TO_DATE('2024-03-20', 'YYYY-MM-DD')
 ,TO_DATE('2024-03-20', 'YYYY-MM-DD')
);

select * from hoge;

```
EC2とインターネット

## パブリックサブネットのEC2インスタンスがインターネットにアクセスできるようにするために、ネットワークとEC2インスタンスで利用される機能

- パブリックIPアドレス

- [Elastic IP アドレス](https://qiita.com/naoya_ok/items/022f4f5d734b2ffabc40)

- インターネットゲートウェイ



![新規 テキスト ドキュメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359600/d072ca0e-d562-7d3f-3790-d144b8d58054.png)

:::note info
デフォルトでは、EC2インスタンスのパブリックIPアドレスはインスタンスの停止後に解放されます。これによって、ドメイン名にマッピングされていた以前のIPアドレスが無効になりアクセスができなくなります。こうしたケースを避けるためには、EC2インスタンスにElastic IPを設定することが必要です。
:::
## 実際の利用シナリオ
例えば、企業が自社の社員がインターネットにアクセスする際に、一度プロキシサーバーを経由させることで、セキュリティを高めたり、アクセスログを取ったりする場合などに、この設定が役立ちます。Elastic IPを使うことで、プロキシサーバーのIPアドレスが固定されるため、設定や管理が簡単になります。
plunk()とarray_column()

# plunk()
コレクションから特定のキーの値を抽出する

```php
$users = collect([
    ['id' => 1, 'name' => 'John'],
    ['id' => 2, 'name' => 'Jane'],
    ['id' => 3, 'name' => 'Doe'],
]);

$names = $users->pluck('name');
// $namesは ['John', 'Jane', 'Doe'] となる
```

# array_column()
多次元配列から特定のカラムを抽出する

```php
$users = [
    ['id' => 1, 'name' => 'John'],
    ['id' => 2, 'name' => 'Jane'],
    ['id' => 3, 'name' => 'Doe'],
];

$names = array_column($users, 'name');
// $namesは ['John', 'Jane', 'Doe'] となる
```

## まとめ

どちらも特定のカラムを抽出するために便利
`pluck()`はLaravelコレクションに対して使われ、
`array_column()`はPHPの配列に対して使われる

個人的に使っていて感じたのは深い階層でも使える分`plunk()`は優秀だなと感じた。
PHPの連想配列では`array_column()`は使えなかった。
別の関数を使って実装する必要がある。

```php
$users = collect([
    ['id' => 1, 'profile' => ['name' => 'John']],
    ['id' => 2, 'profile' => ['name' => 'Jane']],
    ['id' => 3, 'profile' => ['name' => 'Doe']],
]);

$names = $users->pluck('profile.name');
// $names は ['John', 'Jane', 'Doe'] となる
```
execute_script()でエラーが解決した

## エラー内容
Pythonのseleniumにてwebスクレイピングをしている時にページは開くことができているのになぜかCSS Selectorが見つからずにエラーが出る

# 解決方法

```python
driver.find_element_by_id('IdName').click()
```
↓

```python
driver.execute_script('arguments[0].click();', driver.find_element_by_id('IdName'))
```
上記のように変更した。
調べたところ、画面外の要素をクリックをする際にエラーを起こすことがあるらしく、実際に画面内に収まっているように見えてもスマホサイズ？になっていたりするので注意が必要とのこと。

## execute_script()
JavaScriptを使用してクリック操作をする.
そのため要素の状態やブラウザの互換性に影響されにくい。

クリックする以外にも画面をスクロールするなど様々なことが実装可能
【Android】キーボード入力時の予測変換の学習機能をOFFにする【Kotlin】

# はじめに

今回記事にするのは、EditTextの機能内についた **IME**というものの学習機能をオフにするやり方です。
IMEについてはGoogleで調べた内容を引用しておきます。
>「IME（アイ・エム・イー）」は“Input Method Editor”の略で、直訳すると“入力方法編集プログラム”です。 パソコンに日本語を入力するときは、キーボードから「かな入力」か「ローマ字入力」でひらがなを入力し、それを漢字やカタカナなどを含む文章に変換します。

# 実践
```
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edit_text_disable_leaning"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:imeOptions="flagNoPersonalizedLearning"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

xmlのEditText内で
```
        android:imeOptions=""
```
というキーボードのEnterキーを矢印やチェックマークに変更したりするときに用いるものを利用し、**flagNoPersonalizedLearning**を指定するだけです。
これで、キーボードに一度入力された内容が予測変換に出てこなくなります。
また、このEditText内で使用した単語も、通常のキーボードで使用する際の予測変換へは影響が出ないものになっています。

# 参考

https://android.suzu-sd.com/2020/07/edittext_action_button_de_tsuuchi/

https://developer.android.com/reference/android/widget/TextView
Dart3.0 switch case pattern matching

## switch case
switch文でビジネスロジックを解く問題をやっていたときに、ふと気づいたことがありました。昔からあるcase文で書くとコードの記述量が長かったことに！

### 問題はこれ！
ある一つの引数をつる関数を作る。条件によって値を出力する。季節の値を返してもらう。

[Dart3.0以前の書き方]
case文を複数書く。なんだ冗長ですね。いや普通なのか？

```dart
String showSeason(int month) {
  switch(month) {
    case 3:
    case 4:
    case 5:
      return '春';
    case 6:
    case 7:
    case 8:
      return '夏';
    case 9:
    case 10:
    case 11:
      return '秋';
    case 12:
    case 1:
    case 2:
      return '冬';
    default:
      return '季節不明';
  }
}

void main() {
  print(showSeason(3));  // 春
  print(showSeason(6));  // 夏
  print(showSeason(9));  // 秋
  print(showSeason(12)); // 冬
  print(showSeason(13)); // 季節不明
}
```

Dart3.0 からはパターンマッチング使用できる。
https://dart.dev/language/patterns

[使用例]
```dart
switch (obj) {
  // Matches if 1 == obj.
  case 1:
    print('one');

  // Matches if the value of obj is between the
  // constant values of 'first' and 'last'.
  case >= first && <= last:
    print('in range');

  // Matches if obj is a record with two fields,
  // then assigns the fields to 'a' and 'b'.
  case (var a, var b):
    print('a = $a, b = $b');

  default:
}
```

[pattern matching]
論理演算を使うことでコードの量を２２行から１４行に削減できた!

```dart
String showSeason(int month) {
  switch(month) {
    case 3 || 4 || 5:
      return '春';
    case 6 || 7 || 8:
      return '夏';
    case 9 || 10 || 11:
      return '秋';
    case 12 || 1 || 2:
      return '冬';
    default:
      return '季節不明';
  }
}

void main() {
  print(showSeason(3));
  print(showSeason(6));
  print(showSeason(9));
  print(showSeason(12));
  print(showSeason(13));
}
```

コードの記述量の削減をDart3.0から追加されたパターンマッチングで削減してみました。
【Proxmox 7.x】ハードウェアパススルー設定しようとしたら 'No IOMMU detected' と言われた件

# エラーがでた
Proxmox web GUI 上で VM を作成して、ハードウェアタブから PCI Device を追加しようとしたら、`No IOMMU detected, please activate it.See Documentation for further information.` と言われてしまった。

# 直す
## BIOS 設定
VT-d を有効にする。
ROG STRIX Z390 の例 (使用しているハードによって違う可能性あり)
> Intel VT-x : Advanced tab > CPU Configuration > Intel Virtualization Technology : Enabled
> Intel VT-d : Advanced tab > System Agent (SA) Configuration > VT-d : Enabled

## proxmox 設定
`intel_iommu=on` を `GRUB_CMDLINE_LINUX_DEFAULT` 変数内に追加する


```bash
root@server:~# cat /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

# 省略

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"

# 省略
```

追記したら `update-grub` でシステムに適用？更新？する

```bash
root@server:~# update-grub
```

# おわり
これでエラーも出ずにハードウェアパススルーできた！


# 参考文献

https://forum.proxmox.com/threads/no-iommu-detected-please-activate-it.121788/

https://rog-forum.asus.com/t5/intel-500-400-series/rog-strix-z490-i-gaming-iommu-vt-d-support/td-p/914081

https://pve.proxmox.com/pve-docs/pve-admin-guide.html#sysboot_edit_kernel_cmdline
SeaORMで同一テーブルへの複数参照を一度に取得する

# 前提のテーブル定義説明
同一テーブルへ複数参照を持つテーブルを扱う場合にleft joinで複数の参照を一度に取得する際にどうすればいいのか詰まってしまったので備忘も兼ねて記録、、
以下はアイテムテーブルと、その構成要素テーブルの関係です
```
item_bom - item(CraftedItem)
         - item(MaterialItem)
```

エンティティの定義は以下のような感じでした
```rust
// アイテム
mod item {
    pub struct Entity {
        pub id: i32
    }
}
```

```rust
// アイテム構成要素
mod item_bom {
    pub struct Entity {
        // 作成されるアイテムのID
        pub crafted_item_id: i32,
        // 素材アイテムのID
        pub material_item_id: i32,
        // 素材の必要数
        pub amount: i32
    }
}
```
# 取得コード
```rust
    // クエリの組み立て
    let query = item_bom::find()
        .join(
            JoinType::LeftJoin,
            item_bom::Relation::Item1
                .def()
                // on_conditionはデフォルトはAND条件になるが、ConditionType::Anyを指定すればOrになる
                .condition_type(sea_orm::sea_query::ConditionType::Any)
                .on_condition(|left, right| {
                    Expr::col((left, item_bom::Column::CraftedItemId))
                        .eq(Expr::col((right, item::Column::Id)))
                        .into_condition()
                }),
        )
        .select_also(item::Entity);
    
    // 生成するSQLのチェック
    println!("{:#?}", query.build(DbBackend::Postgres).to_string());
    
    // 結果取得
    let models = query.all(tx).await?;
```

ポイントとしては**joinするときのcondition_typeをAnyにしてcraftedとmaterialのidを同時に指定**することでした

改めて見返すとただのleftjoinにただ一文追加するだけか、、という気持ちですが、気づかずに数時間Relationこねくり回したりなんなりしてしまった、、
普段はC#を使っているのでこういうときにEFの偉大さを感じます😭
TypeScript勉強してみた⑤

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

**「いいね」か「ブックマーク」**
を頂けると僕のモチベーションアップになります！:thumbsup:
少しでも気に入っていただけたらよろしくお願いいたします！:thumbsup:


# 今回の目的
TypeScriptがわからなくてやばたにえんなので、ハンドブックで学んでみました。
（前回）

https://qiita.com/mr_noppo/items/e9fc08ab64717310f5f5

# 主に参考にさせていただいた記事

https://www.typescriptlang.org/docs/handbook/intro.html


### Non-null Assertion Operator (Postfix !)
nullまたはundefinedである可能性を無視します。
明らかにnullまたはundefinedが来ないことを前提に対応します。
```ts
function liveDangerously(x?: number | null) {
  // 実行してnullがくるとエラー
  console.log(x!.toFixed());
}
```

# Narrowing

### typeof type guards
unionTypeなどで複数の型が想定される場合、呼び出せるメソッドに影響します。
その時にtypeofで型を狭める方法をtypeod type guards(型ガード）と言います。
また宣言された型を具体的な型に狭めていくプロセスをNarrowingと言います
```ts
typeof padding === "number"
```

### objectのtypeof
objectのtypeofはnullも含みます。注意しましょう。
下記の場合、typeofでobjectに狭めても、「strs」のtypeは「string[] | null」で、nullが残ります。
```ts
function printAll(strs: string | string[] | null) {
  if (typeof strs === "object") {
    for (const s of strs) {
      console.log(s);
    }
  }...
}
```
対応策としては、「truthy」であることを判定してから狭める方法です。
下記の場合、「strs」が「truthy」であることを条件にしたため、「null」は無くなります。
```ts
function printAll(strs: string | string[] | null) {
  if (strs && typeof strs === "object") {
    for (const s of strs) {
      console.log(s);
    }
  }
}
```
#### truthyとfalthy
値をtrueまたはfalseと同等に扱うことです。
下記の場合、falthy扱いになります。
```
0
NaN
""(空の文字列)
0n（bigintゼロバージョン）
null
undefined
```
if文で判定することが可能です。空の文字列を扱いたい場合も同様にfalthyです。そこは留意しましょう。
```ts
// strsがfalthyのいずれかならif文内には入らない
if (strs && typeof strs === "object") {
  ...
}
```

### 平等による推測
下記のif文の場合、xとyが同等となる型はstringのみなのでTypeScriptが推測してstringにします。
```ts
function example(x: string | number, y: string | boolean) {
  if (x === y) {
    // We can now call any 'string' method on 'x' or 'y'.
    x.toUpperCase();
    y.toLowerCase();         
  }
}
```


# 次回の予定
https://qiita.com/mr_noppo/items/71f18d8c73ecff7e4c47
React Native で React Compiler を有効にする

先日、React Conf で React Compiler のオープンソース化が発表されました。

React Compiler について、詳しくは[公式ドキュメント](https://react.dev/learn/react-compiler)を参照してください。

簡単に言えば、今まで `useMemo` や `useCallback` を書いてメモ化していたものが react-compiler を用いて自動で行われるようになります。

react compiler を使うには基本的には現状 RC である React v19 が必要になります。ただ、ワークアラウンドを使うことで React v18 でも部分的に使えるようにできます。
React Native で react-compiler を使うには react 18 のまま使う必要があるので今回はその方法を紹介します。

## Babel プラグインのインストール

react-compiler を適用させる為の babel プラグインをインストールします。

```sh
pnpm install babel-plugin-react-compiler
```

`babel.config.js` に以下のように babel プラグインを追加します。

```js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
+    [
+      'babel-plugin-react-compiler',
+      {
+        runtimeModule: 'react-compiler-runtime',
+      },
+    ],
    'react-native-reanimated/plugin',
  ],
}
```

`runtimeModule` のオプションは react-compiler がメモ化を行う為に使う関数の場所を指定します。
何も指定されていない場合は `react/compiler-runtime` を使用しますが、この関数は react v19 から実装されるものなので react 18 では使えません。
`runtimeModule` が指定されている場合は、該当モジュールから `c` 関数をインポートして使用します。

以下、[babel plugin のコード](https://github.com/facebook/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts)から引用。

````js
/*
  * If enabled, Forget will import `useMemoCache` from the given module
  * instead of `react/compiler-runtime`.
  *
  * ```
  * // If set to "react-compiler-runtime"
  * import {c as useMemoCache} from 'react-compiler-runtime';
  * ```
  */
  runtimeModule?: string | null | undefined;
````

指定されたモジュールを使えるようにするために、`package.json` に以下のようにモジュールを追加します。

```json
{
  ...
  "devDependencies": {
    ...
+   "react-compiler-runtime": "file:./lib/react-compiler-runtime"
  }"
}
```

そして、リポジトリのルートに `lib/react-compiler-runtime` ディレクトリを作成して以下のファイルを作成します。

- `package.json`

```json
{
  "name": "react-compiler-runtime",
  "version": "0.0.1",
  "license": "MIT",
  "main": "index.js",
  "dependencies": {
    "react": "^18.2.0"
  }
}
```

- `index.js`

```js
const React = require('react');
const $empty = Symbol.for("react.memo_cache_sentinel");
/**
 * DANGER: this hook is NEVER meant to be called directly!
 *
 * Note that this is a temporary userspace implementation of this function
 * from React 19. It is not as efficient and may invalidate more frequently
 * than the official API. Please upgrade to React 19 as soon as you can.
 **/
export function c(size: number) {
  return React.useState(() => {
    const $ = new Array(size);
    for (let ii = 0; ii < size; ii++) {
      $[ii] = $empty;
    }
    // @ts-ignore
    $[$empty] = true;
    return $;
  })[0];
}
```

これで react-native や react v18 を使っているプロジェクトで react-compiler を試す事ができます。

## 参考

React 18 で react-compiler を使うためのワークアラウンドのgist - https://gist.github.com/poteto/37c076bf112a07ba39d0e5f0645fec43
React Compiler のソースコード - https://github.com/facebook/react/tree/main/compiler
新卒エンジニアがGitで必要になったコマンド

## リモートリポジトリで自分が作業したブランチをマージした後に、マージを取り消したい時
1. ローカルリポジトリのDevelopブランチにて

```
git reset --hard HEAD^
```

2. developブランチのマージしたコミットの一つ前にコミットに戻っていることを確認する

```
git log
```

3.  ローカルからリモートに反映

```
git push -f origin develop
```

これでdevelopブランチがマージする前に戻る


## プルリクしてるものがコンフリクトした時
ローカルでコンフリクトを解消したいので、
1. リモートのdevelopブランチの内容をローカルに一時反映

```
git fetch origin develop
```

2. 作業ブランチにcheckoutして、developブランチの内容を作業ブランチに反映

```
git merge origin/develop
```

3. コンフリクトを起こしているファイルを修正して、コミット&プッシュで完了

## コードレビューを頼まれて、ローカルでそのコードをみたい時

1. コードレビューしたいリモートリポジトリの最新コミットを取得

```
git fetch origin [ブランチ名]
```

2. 取得したブランチにチェックアウトする。または、リモートと同じブランチをローカルに作成する

```
git checkout origin/[ブランチ名]
```

```
git checkout -b [新規ブランチ名] origin/[元にするブランチ名]

```

## 編集内容を取り消したい時
### 編集内容を取り消したい(addする前)

```
git checkout [ファイル名]
```

[ファイル名]のところを.にすると、ステージング前の全ての変更内容がなくなる。

### ステージングを取り消したい

```
git checkout HEAD -- [ファイル名]
```

ステージしたファイルを最後にコミットした状態に戻す
つまり編集内容は残らない。

## コミットせずに変更を保存し他（のブランチ）で作業をしたいとき

1. まず変更を退避する

```
git stash -u
```

-u オプションは新規作成ファイル(gitが反応してくれないファイル)も退避することができる

2. 退避した変更の一覧を見る

```
git stash list
```

退避した作業の一覧を見ることができる

3. 退避していた変更を戻す

```
git stash apply [stash名]
```

例）　`git stash apply stash@{0}`

現在いるブランチに変更が反映される

4. 退避した作業を消す

```
git stash drop [stash名]
```

例）`git stash drop stash@{0}`

stash名がstashのリストから削除される

5. 3と4を一気に片付けるコマンド

```
git stash pop [stash名]
```

例）　`git stash pop stash@{0}`

変更を現在いるブランチに反映すると同時に、退避した変更の一覧の中から削除する
sortBy()とorderBy()

# sortBy()
指定したキーでコレクションを並べ替える

```php
// モデルからデータを取得
$users = User::all();

// コレクションを並べ替える
$sortedUsers = $users->sortBy('age');
```

# orderBy()
データベースからデータを取得する際に指定したカラムで並べ替える

```php
// クエリビルダーでデータを並べ替えながら取得
$users = User::orderBy('age', 'asc')->get();
```

違いとしては対象が
`sortBy()`はLaravelのコレクション
`orderBy()`はLaravelのクエリビルダ
である点

orderBy()はよく使っていたが、今回データを取得した後に並び替える必要があったのでsortBy()を使用したのでメモ
打撃指標 wOBAを理解する

## wOBA (Weighted On-Base Average)

### 背景

- 打率や出塁率はヒットや出塁を同列に扱う。
- 長打率は長打を高く評価できるが、重みに納得感がない。

### 長打率 (SLG)
長打率は、以下の式で計算されます。

$$
SLG = \frac{塁打数}{打数}
$$

塁打数は次のように計算します。

$$
塁打数 = 単打 + (2 \times 二塁打) + (3 \times 三塁打) + (4 \times 本塁打)
$$

打者がどれだけ多くのベースを走ったか（単打は1、二塁打は2、三塁打は3、本塁打は4のベースを稼いだと数える）を総打数で割ることで、打者のパワーや長打力を評価します。

### wOBAの提案
wOBAは、四球、安打、死球などに得点に寄与する係数を割り振り、打席数で割ったものです。リーグ平均が.320になるように調整されており、高ければ高いほど優秀な打者だと言えます。

日本版の計算式は以下の通りです。

$$
\text{wOBA} = \frac{
0.692 \times (\text{四球} - \text{故意四球}) + 
0.73 \times \text{死球} + 
0.966 \times \text{失策出塁} + 
0.865 \times \text{単打} + 
1.334 \times \text{二塁打} + 
1.725 \times \text{三塁打} + 
2.065 \times \text{本塁打}
}{
打数 + 四球 - 故意四球 + 死球 + 犠飛
}
$$

## 詳細な計算方法

1. **Run Expectancy Matrixを作成する**
    - 過去のデータをもとに、アウト数、出塁パターンごとに得点期待値を求めます。
    - 例：2アウト2塁の得点期待値は0.319点

    ![run_expectancy_matrix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448913/9bbb0100-bfdf-98ee-22c3-9296a16d7be6.png)
    （https://library.fangraphs.com/the-beginners-guide-to-deriving-woba/ より）

2. **各イベントの得点変化を見る**
    - 単打、二塁打、三塁打などのイベントごとに得点の変化を計算します。
    - 例：単打の影響を計算する場合
        - 2アウト2塁から単打でランナーが帰り、ツーアウト1塁になった場合: 1 + (0.319 - 0.224) = 1.095
        - 2アウトランナーなしから単打を打った場合: 0.224 - 0.098 = 0.126

3. **アウトが0になるように引き算する**
    - アウトの影響を見積もり、他のイベントの影響から引き算します。

4. **リーグ平均wOBAを調整する**
    - リーグ平均wOBAが出塁率（敬遠を除く）と同等の.330くらいになるようにスケールを調整します。

### 参考文献

- [The Beginner's Guide to Deriving wOBA - FanGraphs](https://library.fangraphs.com/the-beginners-guide-to-deriving-woba/)
- [1.02 - Glossary - wOBA](https://1point02.jp/op/gnav/glossary/gls_index_detail.aspx?gid=10035)
- [FanGraphs - wOBA](https://library.fangraphs.com/offense/woba/)
FlutterFlow (FlutterWeb)でAPI Callが動かない時の対処法

## FlutterFlowでAPIコールが動作しない問題への対処法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778942/9c926c6c-f0b8-df6d-46e9-5abeca14c507.png)

まず、この不具合はFlutterFlowに依存する問題ではないことあらかじめをお伝えしておきます。

### 問題

以下のような現象が出ている方に有効かもしれません。

・Runモードやモバイルアプリでビルドしたものでは動いているのに、ローカルでビルドした後に、FirebaseでHostingしたら動かなくなってしまった。

・FlutterFlowでWeb Publishをした後に動かなくなった。

・ビルドしたアプリの内容をWebで公開したらバグや挙動が違うといったことが起きた。


### 原因
ブラウザ検証モードを使ってログを確認したところ、CORS ERRORというのが確認されました。

以下のような感じでログが出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778942/35a17180-a6d2-d407-9968-2a0a6cec085f.png)
CORSについてはこちらを参照: https://qiita.com/koji4104/items/65bba670f0519a23b9f6

簡単に説明すると、今開いているサイトから別のIPアドレス上に存在するAPIをコールするときに、ブラウザ側で自動的にセキュリティのブロックがかかってしまい、そのあとの処理が止まってしまうといったイメージです。

### 解消手順
#### 1.APIコールのAdvanced Settingsを開き、Make PrivateをONにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778942/1469f55e-83c7-ce9e-d485-b5b64759dd3e.png)

#### 2.Deploy Private APIsをONにして、Cloud Function上にAPIコールの関数をデプロイする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778942/aac6bf96-bd19-9506-8639-84f3b1ce99ac.png)

#### 3.FlutterFlow経由でWebにPublishする
![スクリーンショット 2024-05-26 180956.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778942/c600637c-5e0b-fcfb-df96-6ff9d2770c66.png)

上記の手順で解消されました。

※FirebaseHostingを使って、手動でホスティングを行うパターンも試しましたが、こちらでは問題が解消されなかったため、急ぎであればFlutterFlow経由の公開をお勧めします。
dwgファイルを別ファイルに変換してみた

# 概要
DWGのCADデータを使い画像処理で物体検出を行うため，CADデータを画像として保存しました．変換するとなんとDXFは約100倍，PDFだと約9倍の容量になりました．
# dwgファイルとdxfファイルについて
DWGファイルはAutoCAD標準のファイルで図面ファイルの拡張子です．
# 動作環境
google colaboratoryで実行しました．
python 3.10.12
以下のライブラリをインストールしました．
```
!pip install aspose-cad
```
# 変換するコード
もし「セッションがクラッシュしました．」と出たら容量が大きいことが原因だと思います．私の場合は2,3回連続でコードを実行すると出てきました．
## DXFに変換
7,653 KB から 715,561 KB　になりました．
```
import aspose.cad as cad

inputDWG = "drive/MyDrive/input.dwg";
outputDXF = "drive/MyDrive/out.dxf";

image = cad.Image.load(inputDWG)

options = cad.imageoptions.DxfOptions()

image.save(outputDXF, options);
```
## PDFに変換
7,653 KB から 58,099 KB になりました．
```
import aspose.cad as cad

image = cad.Image.load("drive/MyDrive/input.dwg")

pdfOptions = cad.imageoptions.PdfOptions()

image.save("drive/MyDrive/out.pdf", pdfOptions)
```
# おわりに
今回始めてqiitaで記事を書いたため，至らない点も多々あると思いますが，今後も更新していく予定なのでよろしくお願いします．
# 参考
この記事は以下のサンプルコードを参考に作成しました．
[ASPOSE](https://blog.aspose.com/ja/cad/)