OmniAICreator/Qiita-1.07M huggingface dataset:
robloxでassistant その137

# 概要
robloxでassistantやってみた。
make scriptテストしてみた。

# サンプルコード

```

local KillScript = Instance.new("Script")
KillScript.Name = "MyFunctions"
KillScript.Parent = workspace
KillScript.Source = "print(a)"

```

# 実行結果


```
08:33:40.886  The current thread cannot write 'Source' (lacking capability Plugin)  -  クライアント - LocalScript:7
```


以上。
yukicoder No.4 重りと天秤　解説

[問題文](https://yukicoder.me/problems/no/4)
# 解説
いわゆる部分和問題というタイプのやつ。
まず制約が $N\leqq 100$ なのでbit全探索および再帰関数では厳しそう。
しかし、代わりに $W\leqq 100$ という制約もあるので、dp(動的計画法)で解けると考えられる。
$\text{dp}[i][j]=W_1$~$W_i$ まででjを作ることができるかどうか。
dpの横のサイズは $10001$ もあれば十分。(あり得る解は $0$ ~ $10000$ のため)
$\text{dp}[i][j]$ がtrueなら $\text{dp}[i+1][j]$ もtrue。
$\text{dp}[i][j]$ がtrueなら $\text{dp}[i+1][j+w[i]]$ もtrue。
$(\sum_{i=1}^{N}W_i)\bmod{2}=1$ ならimpossible(事故を防ぐために事前に場合分けしておく)
そうでないなら
$dp[n][\text{sum}/2]$ がtrueならpossible。
そうでないならimpossible。
計算量は $O(N\max(W)^2)$。よって、十分高速。

## C++での解答例
```C++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int n, sum=0;
  cin >> n;
  vector<int> w(n);
  for(int i = 0; i < n; i++) {
    cin >> w[i];
    sum += w[i];
  }
  if(sum % 2 == 1){
    cout << "impossible\n";
    return 0;
  }
  vector<vector<bool>> dp(n+1, vector<bool>(10099, false));
  dp[0][0] = true;
  for(int i = 0; i < n; i++) {
    for(int j = 0; j <= 10000; j++) {
      if(!dp[i][j])continue;
      dp[i + 1][j] = true;
      dp[i + 1][j + w[i]]=true;
    }
  }
  cout<<(dp[n][sum / 2] ? "possible\n": "impossible\n");
}
```
Djangoで処理を定期的に実行する


# はじめに

こんにちは、Python初心者のkeitaMaxです。

今回はDjangoで処理を定期的に実行するようにしたいと思います。

前回の記事はこちら

https://qiita.com/keitaMax/items/c898d0364cd153f90e9d

# APSchedulerのインストール

最後にバッチを作成するために、コマンドを定期的に叩けるようにしようと思います。

`APScheduler`を以下コマンドでインストールします。

```
pip install apscheduler
```

また、`docker/app/requirements.txt`に`apscheduler`を追加しておきます。

```txt:docker/app/requirements.txt
Django==5.0

mysqlclient
apscheduler

```
# 設定

インストールできたら、`app/settings.py`に以下を追加します。

```py:app/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'batch',
    'batch.apps.AppConfig', #追加
]
```

`batch/apps.py`に以下を追加します。

```py:batch/apps.py
from django.apps import AppConfig


class BatchConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'batch'

    def ready(self): #追加
        from .management.commands.example_batch import start #追加
        start() #追加
        
```

これを設定すると、runserverを実行時に読み込まれるらしいです。

`batch/management/commands/example_batch.py`を作成します。

```py:batch/management/commands/example_batch.py
from apscheduler.schedulers.background import BackgroundScheduler

def example(self, *args, **options):
    print("Hello, World!")

def start():
    scheduler = BackgroundScheduler()
    scheduler.add_job(example, 'interval', seconds=5)
    scheduler.start()
```

これで設定完了です。

# 実際に確認してみる

手動で起動させるために、
`docker-compose.yml`の`command: python3 manage.py runserver 0.0.0.0:8000`をコメントアウトします。

```yml:docker-compose.yml
services:
  app:
    build:
      context: ./docker/app
      dockerfile: Dockerfile
    # command: python3 manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - ./src/:/code
    tty: true
```

その後以下コマンドでDockerを立ち上げ直します。
```
docker compose stop 
docker compose build
docker compose up -d  
```

コンテナに入り、サーバを起動させます。
```
docker compose exec app bash
python3 manage.py runserver 0.0.0.0:8000
```

すると下の画像のように、定期的に実行されていることが確認できました。

![スクリーンショット 2024-07-18 20.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/5833cb3d-e0f0-08d9-feac-23764ace2f85.png)

最後に`docker-compose.yml`のコメントアウトは外しておきましょう。

# おわりに

途中何度かつまづきましたが、なんとか定期実行できるようになりました。

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://apscheduler.readthedocs.io/en/3.x/

https://se-memorandum.com/apsheduler/

# 次の記事

https://qiita.com/keitaMax/items/be9b639b5024c77d93f6
Proxmox VEでNICデバイス名を固定する方法

Proxmox VEを使っていると、新しいデバイスを追加した際にネットワークが接続できなくなることがあります。この問題は、DebianベースのOSがデバイスを認識する際のデバイス名の決定方法に起因します。ここでは、ProxmoxにおいてNICのデバイス名を固定する方法について説明します。

### 1. 設定方法

udevルールを使用することで、デバイス名を固定することができます。例えば、特定のMACアドレスを持つデバイスに対して`vmnic0`という名前を割り当てるudevルールを作成します。

```bash
echo 'SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="a8:a1:59:a5:06:74", NAME="vmnic0"' > /etc/udev/rules.d/10-network.rules
```

このルールにより、指定されたMACアドレスのデバイスが常に`vmnic0`という名前を持つようになりますので、ネットワーク設定ファイル（`/etc/network/interfaces`）を修正して、新しいデバイス名を反映させます。

```
root@pve:~# diff -ruN /etc/network/interfaces.20240711 /etc/network/interfaces
--- /etc/network/interfaces.20240711    2024-07-09 23:20:49.794636816 +0900
+++ /etc/network/interfaces     2024-07-11 00:24:07.190602090 +0900
@@ -12,7 +12,7 @@
 auto lo
 iface lo inet loopback

-iface enp8s0 inet manual
+iface vmnic0 inet manual

 iface enp6s0f0 inet manual

@@ -22,7 +22,7 @@
 iface vmbr0 inet static
        address 192.168.11.45/24
        gateway 192.168.11.1
-       bridge-ports enp8s0
+       bridge-ports vmnic0
        bridge-stp off
        bridge-fd 0
```

### 2. 動作確認

OSの再起動後、以下の通り確認を行います。

```bash
root@pve:~# ip link show | grep vmnic0
2: vmnic0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state UP mode DEFAULT group default qlen 1000
```

### 3. 注意点

NICを変更した際など、MACアドレスが変わった場合にNICが認識出来なくなります。
この場合は、手動で設定変更を行う必要があります。
CRA(create-react-app)とViteの違いを軽く調べてみた

# はじめに
ViteでReactの環境構築をはじめてしたのですが、なぜ最近Viteで環境構築をしてる人が多いのか気になり違いを軽く調べてみました。

# CRAとViteそれぞれの環境構築を見てみる
### CRAの場合
```
npx create-react-app プロジェクト名
```
### Viteの場合
CRAとは違い別途npmインストールする必要があるみたいです。
```
npm create vite@latest プロジェクト名 -- --template react
cd プロジェクト名
npm install
```
# なぜViteがいいのか
ネット記事で色々みてみた感じだと以下のメリットが挙げられます。
- 初期の立ち上げが早い
- ビルド時間が短い
- 生成物が非常に軽量
- カスタマイズしやすい
- react以外でも使える

最近学習しはじめた方で特にカスタマイズやパフォーマンスが必要なくコマンド1つで環境構築したい方はCRA、少し慣れてきて開発体験にこだわっていくならViteという感じでしょうか？
# おわりに
Viteいいですね。
# 参考
https://zenn.dev/pyhrinezumi/books/693ddc2f58a985/viewer/974bbd

https://buildersbox.corp-sansan.com/entry/2022/03/24/110000

https://qiita.com/yuppe-namura/items/fbe8c1af9779e7ba8f87

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
robloxでassistant その136

# 概要
robloxでassistantやってみた。
getfenvテストしてみた。

# サンプルコード

```
print("Hello world!") 
warn("Hello world!") 
local Print, Warn = print, warn
local fenv = getfenv(0)
fenv.print = Warn
fenv.warn = Print
setfenv(0, fenv)
print("Hello world!") 
warn("Hello world!") 
Print("Hello world!") 
Warn("Hello world!") 
```

# 実行結果


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8f7046ce-c18f-6286-76be-9413c939ecf6.png)


以上。
知財のあれこれをPythonで何とかする

１．ファミリを何とかする(その３）

今回は外国特許のファミリの取得を容易にするための処理方法を紹介したいと思います。

２．今回やろうとしていること

今回やろうとしていることは「J-platpatで表示させたワン・ポータル・ドシエのページの、登録番号の情報だけを抜き出す」ことになります。
手作業としては「J-platpatをアクセスして出願番号、公開番号、登録番号のいずれかを入力、ワン・ポータル・ドシエのページを表示させ、登録番号を含むテキストデータをコピペする」ここまでは手作業です。
プログラムでは、コピペしたテキストデータから登録番号を抽出する処理をします。
J-platpatをアクセスして番号入力すると、ワン・ポータル・ドシエのページを表示させる以下のようなボタンが表示されるはずです。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/260f9d2b-86f4-3ff8-4f1d-d063a870d40a.jpeg)
「ＯＰＤ」ボタンをクリックすると外国特許を含んだファミリ情報が表示されますので、表示されたページのテキストデータを以下のプログラムの「ワン･ポータル･ドシエ(OPD)照会うんたら・・・」の行にペーストしてください。
前回同様ExcelのClean関数等で改行コードを除くこと、また、特殊な文字（"■"）もエラーになりますので、特殊文字を含まない範囲でコピペするもしくはSubstitute関数をかける等、無い状態にしておく必要があります。
```python:qiita1.py
import re
jplt =["ワン･ポータル･ドシエ(OPD)照会うんたらJP.7776655.B2かんたらJP.6665544.B1うんたらUS.8887766.B2"]

index =0 
for item in jplt: 
    patinf = jplt[index]
    idg1='\r\n'.join(re.findall("JP.[0-9]{7}.B[1-2]", patinf))#JP特許全件を抽出し改行コードを挟んで結合する
    idg2='\r\n'.join(re.findall("US.[0-9]{7,8}.B[1-2]", patinf))#US特許全件を抽出し改行コードを挟んで結合する
    print(idg1)
    print(idg2)
    print("+++++")
    index += 1
```
上記プログラムを実行すると変数「idg1」に日本特許、「idg2」に米国特許を抜き出すことができます。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/c087e375-3b74-2517-d8c4-5d64bd71969b.jpeg)
プログラムのポイントは正規表現(re)で指定した文字列を全件抽出(findall)する処理で、これがプログラム1行で実現できます。pythonの優れた文字列処理機能であり、種々の応用が利くと思われます。

リストjpltの行（「"・・・",」）を増やせば何件でも一度に変換できます。
```python:qiita2.py
jplt =["ワン･ポータル･ドシエ(OPD)照会うんたらJP.7776655.B2かんたらJP.6665544.B1うんたらUS.8887766.B2",
       "ワン･ポータル･ドシエ(OPD)照会かんたらUS.9998877.B1うんたらUS.10777666.B2かんたらUS.11666555.B1"]
```
(実行結果)
![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/0131009f-61ca-c4c2-a9f6-4b0da7ed4ea8.jpeg)

２－２．ほかの国の特許も抽出する
国を指定する行を追加すれば、ヨーロッパや中国の特許も抽出できます。
”JP.[0-9]{7}.B[1-2]”のうち、
”JP.[0-9]{7}”→　国記号JPと0～9までの数値7桁
”.B[1-2]”→　　　登録符号（B1またはB2）
を示していますので、国記号、桁数、登録符号を各国ごとに修正・追加してください。

例：ヨーロッパ: "EP.[0-9]{7}.B[1-2]"
例：中国: "CN.[0-9]{9}.[BC]"
例：米国再発行: "US.RE[0-9]{5}.E"

３．最後に
一般的な商用の特許データベースではファミリ情報は多くがINPADOCを転用しているものと思いますが、特に日本出願に関してはINPADOCのファミリ情報は不備が多くJ-platpatを1件ずつ見ないといけないケースが少なからず存在します。今回の記事が何らかの助けになれば幸いです。
【アイディア】ローグライトなオセロ


## 概要

* 基本的にオセロと同じルール
* マスに石を置いたときにスキルやアイテムを入手できる
* 座標B2のような置くと角を取られてしまうリスキーな箇所では強力な効果のスキル/アイテムが入手しやすい

以上
もしかしたらすでにあるかもしれないけど、とりま思いついたので書いた。
別にパクって構いません。（が、この記事を参照に付けてくれると嬉しい。）

ローグライクの「もっと不思議のダンジョン」みたいに99連戦みたいなモードがあったら面白そう。

## アイテム

* 任意の敵石を裏返す
  * 個数、範囲などで
* N回連続配置
* やっぱやめた
  * 1ターン戻る
* 復活
  * 負けたときにやり直せる
* 必勝
  * 勝ったことにする
* 固定化
  * 任意の自石を裏返さなくさせる
  * 個数、範囲などで
  * Nターン制限つけることもあり
* 置いちゃダメ
  * 特定の範囲に敵が石を置けなくさせる
  * Nターン制限つけることもあり
  * 右側からだけ、上側からだけみたいな制限も面白そう
* 全反転
  * 自石と敵石をすべて反転させる
* 負けるが勝ち
  * 自石が少ない方が勝利するルールにする
* シャッフル
  * 自石と敵石をランダムに入れ替える
* 台風
  * 石数はそのままに、配置、自石数、敵石数をすべてランダムにする
* ハンデ
  * ゲーム開始時に有利盤面にする
  * 逆に相手にハンデしてあげることも可能
    * その場合、強力なスキル/アイテムが入手しやすい
* 場外配置
  * 端の外側に配置することができる
* 早期決着
  * Nターン後に強制的に勝敗判定
* 体力回復/能力バフ

## スキル

* 体力+N
* アイテム保持数+N
* 攻撃力+N
* 防御力+N
* 回復量+N
* ピンチで○○
* たまに○○
* 敵強化
  * 代わりに強力なスキル/アイテムが入手しやすくなる

## システム

* 体力制度
  * プレイヤーに体力を設定
  * 自石をひっくり返されると10減少
  * 敵石をひっくり返すと5回復
  * 敵にも体力を持たせる
    * 敵の体力を0にできたら強制勝利
    * 低レベルの敵をサクッと倒せるためダレない
* 能力向上
  * 最大体力、アイテム保持数、防御力、回復量の向上
  * それはスキルであったり、レベルアップであったり、アイテムであったり、色々考えられる
* 報酬
  * 10人倒したら何らかの報酬など

## ゲームモード

* チャレンジモード
  * 99連戦のような長期戦のモードを導入し、途中で得たスキル/アイテムを戦略的に使用することで最後まで勝ち抜くことを目指すモード
* チャレンジモード（エンドレス）
  * チャレンジモードの終わりがないバージョン
* タイムアタックモード
  * 制限時間内にできるだけ多くの敵を倒すことを目指すモード
    * プレイヤーの思考時間のみ計測する

## ゲーム名

ダサいけど
**オセローグ**
とか？

ちなみにオセロが商標なのは知っている。
Reactで学習記録アプリを作る

# はじめに
今回はReactで簡単に学習記録アプリを作ってみました。dbやcicdはこれからですが、ざっとどんなものを作ったか紹介していきます。

# 作ったもの
TODOアプリに少し機能を加えた感じです(スタイルはほぼなし)。イベントやstate,map表示など基本的な実装の練習になるので、皆さんもぜひ実装してみてください。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/a96cf484-3751-95d3-37fe-a9ea14629ee0.gif)



# 悩んだところ ・ そしてその解決策
- 学習内容と学習時間を一緒に登録するにはどうしたら良いか
    → オブジェクトで扱う
- 学習時間の合計値表示はどう実装していくか
    → reduce()を使う(最初はstateを使ってましたがこっちの方が短い記述ですみそうです)
- 合計時間を表示させる実装をした時になぜか数値が文字列連結されてしまう
    → 時間をparseIntで扱う

# 気づき
やはり実際に手を動かすと自分がよくわかっていない部分が浮き彫りになるので、改めてアウトプットの重要性を感じました。新しい知識も増えていいですね。

# おわりに
今回は学習記録アプリを作ってみました。今後はsupabaseでのデータ保持やfirebaseへのデプロイ、github actionsを利用したci/cdにも挑戦していきます。

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
robloxでassistant その135

# 概要
robloxでassistantやってみた。
loadstringテストしてみた。

# サンプルコード
```

local test = loadstring("print('Hello world!')")
test()

```
# 実行結果

```
6:46:12.978  loadstring() is not available  -  クライアント - LocalScript:5
```

以上。
SassのMixed Declarationsに対応する

# Mixed Declarationsって何？

DartSassをアップデートしたら下記のエラーが表示されるようになりました。

```
Deprecation Warning: Sass's behavior for declarations that appear after nested
rules will be changing to match the behavior specified by CSS in an upcoming
version. To keep the existing behavior, move the declaration above the nested
rule. To opt into the new behavior, wrap the declaration in `& {}`.

More info: https://sass-lang.com/d/mixed-decls
```


**「ネストの後に宣言するな」** というルールです。
言葉で書いても良く分からないですね。

https://sass-lang.com/documentation/breaking-changes/mixed-decls/

例えば下記のサンプルだと `font-weight: normal;` がネストの後にあるのでNGです。


```sass
.example {
  color: red;

  a {
    font-weight: bold;
  }

  font-weight: normal;
}
```

下記が修正版です。

```sass
.example {
  color: red;
  font-weight: normal;

  a {
    font-weight: bold;
  }
}
```

今まではSassが上記のように修正してくれました。

その後CSSワーキンググループの話し合いで **「書いた順番に適用するのが正しいよね」** という事になり、下記のように扱われることになりました。

```sass
.example {
  color: red;
}

.example a {
    font-weight: bold;
  }

.example {
  font-weight: normal;
}
```

**じゃあ自動でやってくれよ！！！！**
と思うのですが、そうはいかないようです。

**面倒くさい！！！！**


# 対応方法

## 対応方法①　 &{} で囲む

```sass
.example {
  color: red;

  a {
    font-weight: bold;
  }

  & {
    font-weight: normal;
  }
}
```


## 対応方法②　@include を分ける

ボタンの共通スタイルを例にします。
下記はNGの例です。

```sass
@mixin btn-common {
  display: block;
  width: fit-content;

  &[disabled='disabled']{
    cursor: not-allowed;
    pointer-events: none;    
  }
}

.btn{
  // disabled のブロックが間にあるのでNG
  @include btn-common;

  background-color: red;
  color: white;
}
```

下記が対応版です。
@mixin を分割しています。
くっそ面倒臭いですね。

```sass
@mixin btn-common {
  display: block;
  width: fit-content;
}

@mixin btn-disabled-common {
  &[disabled='disabled']{
    cursor: not-allowed;
    pointer-events: none;    
  }
}

.btn{
  @include btn-common;

  background-color: red;
  color: white;

  @include btn-disabled-common;
}
```

## 対応方法③　ブロック自体を分ける

自分はメディアクエリー毎のCSS変数を頭で定義することが多いのですが、それがNGになりました。

```sass
.btn{
  @media (PC用メディアクエリー) {
    --btn--font-size: 3rem;
  }
  @media (タブレット用メディアクエリー) {
    --btn--font-size: 2rem;
  }
  @media (スマホ用メディアクエリー) {
    --btn--font-size: 1rem;
  }

  font-size: var(--btn--font-size);
}
```

下記が対応版です。

```sass
// 変数定義用ブロック
.btn{
  @media (PC用メディアクエリー) {
    --btn--font-size: 3rem;
  }
  @media (タブレット用メディアクエリー) {
    --btn--font-size: 2rem;
  }
  @media (スマホ用メディアクエリー) {
    --btn--font-size: 1rem;
  }
}

// 実装用ブロック
.btn{
  font-size: var(--btn--font-size);
}
```

# おわり

オプションで `silenceDeprecations` を指定すれば警告を消せるらしいのですが、 **gulp-sass経由だとDartSassのオプションを指定できないらしく、警告を消せません。**

**な ん だ そ れ**

https://sass-lang.com/documentation/js-api/interfaces/options/#silenceDeprecations

対応できない場面も出てきそうで正直かなり面倒な気分です。
DartSassのバージョンを戻したいです。
Javaで「戻り値として配列を返す」の動作を確認してみた

# 概要

Javaで「戻り値として配列を返す」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/method/index6.html

# 実装

以下のファイルを作成しました。
```JSample6_1.java
class JSample6_1{
  public static void main(String args[]){
    int data[];

    data = init();
    System.out.println(data[0]);
    System.out.println(data[1]);
  }

  private static int[] init(){
    int data[] = new int[2];
    data[0] = 10;
    data[1] = 19;

    return data;
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample6_1.java 
$ java JSample6_1 
10
19
```

# まとめ

何かの役に立てばと。
【PHP】Enumでの検証を簡単にする

## PHPのEnumでの検証
以下のようなEnumがあるとしたとき
```php
enum Test: string
{
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}
```
検証の際いちいち
```php
if ($test === Test::Test1) {}
```
みたいなことを書くと可読性が悪くなる気がしたので

以下のようなトレイトを用意して
```php
trait EnumIsTrait {
    public static function tryFromName(string $name)
    {
        foreach (self::cases() as $case) {
            if ($case->name === $name) {
                return $case;
            }
        }
        return null;
    }
    

    public function is(string $name)
    {
        return $this === self::tryFromName($name);
    }
    

    public function __call($calledName, $args)
    {
        preg_match('/^is([a-zA-Z0-9]+)$/', $calledName, $matches);
        $caseName = $matches[1] ?? false;
        if ($caseName) {
            return $this->is($caseName);
        }

        throw new \Exception();
    }
}
```

先ほどのEnumに実装すると
```php
enum Test: string
{
    use EnumIsTrait;
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}
```

```php
if ($test->isTest1()) { }
```

のような形で検証ができると思います。
関数の実態はないので、`@method` などを定義しておくと良いと思います。


## 確認用コード
```php
<?php

enum Test: string
{
    use IsEnumTrait;
    
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}

trait IsEnumTrait {

    /**
     * Enumの name から Enumを取得
     */
    public static function tryFromName(string $name)
    {
        foreach (self::cases() as $case) {
            if ($case->name === $name) {
                return $case;
            }
        }
        return null;
    }
    

    /**
     * 現在のEnumが name のEnumかどうか検証
     */
    public function is(string $name)
    {
        return $this === self::tryFromName($name);
    }
    

    public function __call($calledName, $args)
    {
        preg_match('/^is([a-zA-Z0-9]+)$/', $calledName, $matches);
        $caseName = $matches[1] ?? false;
        if ($caseName) {
            return $this->is($caseName);
        }

        throw new \Exception();
    }
}

var_dump(Test::Test1->isTest1());
var_dump(Test::Test2->isTest1());

// outputs
// bool(true)
// bool(false)
```

laravelのモデルのプロパティにEnumをセットして判定する際は
`$casts = [];`
でEnumへの変換を設定していると
`$this->xxxx->is〇〇();`
で判定できるので一行あたりが短く書けるかなと思いました。
1つのブックからシートごとにブックを分割する

なにかと便利なので置いておきます

``` vba:splitSheet
Option Explicit
'''
' 1つのブックからシートごとにブックを分割する
'''
Sub copyBook()
    ' ループ対象シート
    Dim objSheet As Worksheet
    ' 出力先ブック
    Dim wb As Workbook
    ' 出力先シート
    Dim ws As Worksheet
    ' 分割対象ブック
    Dim wob As Workbook
    '分割対象ファイルパス
    Dim fname As String

    ' マクロ高速化開始
    With Application
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
    End With
    
    ' 分割対象ブックを選択
    fname = Application.GetOpenFilename(Filefilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm")
    If fname <> "False" Then
    
        ' 分割対象のブックを読み取り専用で開く
        Set wob = Workbooks.Open(fname, ReadOnly:=True)
        
        ' 貼り付け元ブックの全シートを 1 つずつループして処理する
        For Each objSheet In wob.Worksheets
    
            ' 貼り付け先ワークブックを作成
            Set wb = Workbooks.Add
            ' 貼り付け先のシートを取得
            Set ws = wb.Sheets(wb.Sheets.Count)
            '名前同じにしたいなら以下の'外す
             ws.Name = objSheet.Name
            
            ' 貼り付け元の全ての値を貼り付け先ワークシートに張り付ける(値だけ)
            ws.Range(objSheet.UsedRange.Address).Value = objSheet.UsedRange.Value
            
            ' ワークブックの保存(元ブック名 + シート名)
            wb.SaveAs wob.Path & "\" & Replace(Replace(wob.Name, ".xlsx", ""), ".xlsm", "") & "_" & ws.Name & ".xlsx"
            wb.Close
            ' ワークシートの開放
            Set ws = Nothing
            Set wb = Nothing
        Next
        
        ' 分割対象ブックを閉じる
        wob.Close False
        
        MsgBox "分割が完了しました"
    Else
        MsgBox "中止しました"
    End If
    
    ' マクロ高速化終了
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = xlCalculationAutomatic
    End With
End Sub
```
自作コマンド「note」 - 素早くメモを作成しエディターを起動するmacOS用CLIツール

# 概要

* メモを素早く取るということに特化したCLIツール（中身はzshスクリプト）
* メモファイルが無ければ新規作成、すでに存在している場合は既存のメモファイルを作成
    * 作成されるメモファイル形式は `.md` (Markdown)
* `$EDITOR` で指定されたエディターを起動
    * `$EDITOR` が設定されていない場合はcode(Visual Studio Code)を起動
* 基本的にはmacOS用

# 動作確認環境

* M1 Max MacBook Pro
* macOS Sonoma 14.5
* VSCode 1.91.1
* zsh 5.9 (x86_64-apple-darwin23.0)

# セットアップ

noteコマンドはzshのスクリプトとなっているので、以下の手順で作成する

```zsh:$HOME
mkdir -p $HOME/bin
touch $HOME/bin/note
chmod +x $HOME/bin/note
code $HOME/bin/note
```

```zsh:$HOME/bin/note
#!/usr/bin/env zsh

set -eo pipefail

editor=${EDITOR:-code}

# create a note dir
NOTE_ROOT="$HOME/works/note"
NOTE_DIR="$NOTE_ROOT/$(date +%Y-%m)"
if [ ! -d $NOTE_DIR ]; then
  mkdir -p $NOTE_DIR
fi

# list notes
NOTE_NAME=${1:-1}
if [ "$NOTE_NAME" = "ls" ]; then
  ls -1 "$NOTE_DIR/"*
  exit 0
fi

# create a note file
NOTE_FILE="$NOTE_DIR/note_$(date +%Y%m%d)__${NOTE_NAME}.md"
NOTE_TEMPLATE_STR="# $(LANG=C date +"%Y%m%d %a") ${NOTE_NAME}\n"
if [ ! -f $NOTE_FILE ]; then
  echo "$NOTE_TEMPLATE_STR" >> $NOTE_FILE
fi

# append text to the note file
NOTE_DESC=${${@:2}:-""}
if [ "$NOTE_DESC" != "" ]; then
  echo "$NOTE_DESC" >> $NOTE_FILE
fi

# show the note path
echo "$NOTE_NAME: $NOTE_FILE"

# edit the note file
$editor $NOTE_FILE
```

必要に応じて `$HOME/bin` にPATHを通しておく。

```zsh:~/.zshrc
export PATH="$HOME/bin:$PATH"
```

# 使い方

```sh:Usage
note [メモ番号] [...メモ追記内容]
```

## noteコマンド実行例

```zsh
# メモを作成してエディターを開く(デフォルトのメモ番号は1)
note

# メモ番号を指定してエディターを開く
note 1
note 99

# 数値以外も指定可能(メモ番号はファイル名と見出しになる)
note hello

# 第二引数以降の文字列はメモに追記される
note 1 hello
note 1 hello world
note 1 "foo bar baz"
```

```zsh
# 今日作成したメモ一覧を表示する
note ls
```

## 補足

* 必要に応じてzshスクリプトを変更してください
辞書型①のvalue値が辞書型②のkey名と一致する時に辞書型②のvalueで書き換える方法

簡単にやる方法で詰まったのでメモ

### やりたいこと
dict1の{}内の項目名とdict2のkeyが一致するときにdict2のvalueで置き換えたい

```python
dict1 = {"name": "{answer1}", "age": "{answer2}"}
dict2  = {"answer1": "tarou", "answer2": 20}
```

### 最終的な値
```python
dict3 = {'name': 'tarou', 'age': '20'}
```
### 実現ソース
```python
dict3 = {k: v.format(**dict2) for k, v in dict1.items()}
```
関数化するとこんな感じ？
```python
def format_dict_values(target_dict, format_dict):
    """
    辞書の値を別の辞書の値でフォーマットします。

    Args:
        target_dict (dict): フォーマットする対象の辞書
        format_dict (dict): フォーマットに使用する値を持つ辞書

    Returns:
        dict: フォーマットされた値を持つ新しい辞書
    """
    return {k: v.format(**format_dict) for k, v in target_dict.items()}
```
### 説明
以降はChatGPtに詳しい説明を求めました！

1. **辞書の内包表記**:
   - `dict3` は辞書の内包表記を使って作成されています。これはリスト内包表記と似ていますが、辞書を作成するためのものです。

2. **`dict1.items()`**:
   - `dict1` のキーと値のペアを取得します。`dict1` は `{"name": "{answer1}", "age": "{answer2}"}` です。

3. **`v.format(**dict2)`**:
   - `v` は `dict1` の値 (`"{answer1}"` や `"{answer2}"`) です。
   - `v.format(**dict2)` は、`v` の中のプレースホルダー (`{answer1}` や `{answer2}`) を `dict2` の対応する値で置き換えます。

4. **辞書の生成**:
   - 各キー `k` に対して、値 `v` を `dict2` の値でフォーマットした結果を新しい辞書 `dict3` に格納します。

### 具体例

- `dict1` = `{"name": "{answer1}", "age": "{answer2}"}`
- `dict2` = `{"answer1": "tarou", "answer2": 10}`

この場合、`dict3` は次のように生成されます:

- `name` の値は `"{answer1}"` で、`answer1` を `tarou` に置き換えると `"tarou"` になります。
- `age` の値は `"{answer2}"` で、`answer2` を 20 に置き換えると `20` になります。

したがって、`dict3` は `{"name": "tarou", "age": 20}` になります。

### まとめ
今回は`dict1` の各値の中のプレースホルダーを `dict2` の対応する値で置き換えた新しい辞書 `dict3` の作成方法をまとめました。
Fizz BuzzをPHP/Ruby/Java/Python/C/C#/JavaScript/C++/Kotlinでやってみた(for コードモンスター大図鑑 etc)

https://paiza.jp/works/mondai/c_rank_skillcheck_sample/fizz-buzz/

「コードガールこれくしょん」「コードクロニクル」「推しと学べるプログラミング」「コードモンスター大図鑑」のStage17での問題として選出される可能性がある、Fizz Buzzを一から書く問題。(Stage17では) **1問あたりの制限時間はならしで15秒** 。一から書く問題はご法度かと…

今回Qiitaコラボ問題でFizz Buzzが選出されたため、これを機会にテンプレートを保存しておくことにしました。

Stage 17に挑むときはこれをコピーして、Fizz Buzzを見つけ次第ペーストできるようにしておくのが吉。

## PHP

```php
#!/usr/bin/php
<?php
$n=intval(fgets(STDIN));
for($i=1;$i<=$n;$i++){
	echo ($i%15==0?"Fizz Buzz":($i%3==0?"Fizz":($i%5==0?"Buzz":$i))).PHP_EOL;
}
```

## Ruby

```rb
#!/usr/bin/ruby
puts (1..gets.to_i).map{|i|
	i%15==0 ? 'Fizz Buzz' : i%3==0 ? 'Fizz' : i%5==0 ? 'Buzz' : i
}
```

## Java

```java
import java.util.*;
class Main{
	public static void main(String[]z){
		Scanner cin=new Scanner(System.in);
		int n=cin.nextInt();
		for(int i=1;i<=n;i++){
			System.out.println(i%15==0?"Fizz Buzz":i%3==0?"Fizz":i%5==0?"Buzz":i);
		}
	}
}
```

## Python

一応Py2/Py3両対応です(ガルこれetcはPython3です、念のため)

※Py2だとinput()はeval(raw_input())の意味になりますがこの入力では問題なく使えます。

```py
#!/usr/bin/python
for i in range(1,1+int(input())):
	print('Fizz Buzz' if i%15==0 else 'Fizz' if i%3==0 else 'Buzz' if i%5==0 else i)
```

## C / C++

C++でもこちらの答案で問題ありません。

```c
#include <stdio.h>
int main(){
	int i=1,n;
	scanf("%d",&n);
	for(;i<=n;i++){
		printf(i%15==0?"Fizz Buzz\n":i%3==0?"Fizz\n":i%5==0?"Buzz\n":"%d\n",i);
	}
}
```

## C# ##

```cs
using System;
class FizzBuzz{
	static void Main(){
		int n=int.Parse(Console.ReadLine());
		for(int i=1;i<=n;i++){
			Console.WriteLine(i%15==0?"Fizz Buzz":i%3==0?"Fizz":i%5==0?"Buzz":i.ToString());
		}
	}
}
```

## JavaScript

```js
#!/usr/bin/node
(function(){
	var T=[];
	var stdin = process.openStdin();
	stdin.setEncoding('utf8');

	var input_fragment="";
	stdin.on('data', function(input) {
			var ref=(input_fragment+input).split("\n");
			input_fragment=ref.pop();
			for(var i=0;i<ref.length;i++){
				if(ref[i]=='')continue;
				T.push(ref[i].split(' ').map(Number));
			}
	});

	stdin.on('end', function(z) {
		if(input_fragment){
			var ref=(input_fragment+"\n").split("\n");
			input_fragment=ref.pop();
			for(var i=0;i<ref.length;i++){
				if(ref[i]=='')continue;
				T.push(ref[i].split(' ').map(Number));
			}
		}
		n=T[0][0];
		for(i=1;i<=n;i++){
			console.log(i%15==0?"Fizz Buzz":i%3==0?"Fizz":i%5==0?"Buzz":i);
		}
	});
})();
```

## Kotlin

```kotlin
fun main(args: Array<String>) {
	val n=readLine()!!.toInt()
	for(i in 1..n){
		println(if(i%15==0)"Fizz Buzz" else if(i%3==0)"Fizz" else if(i%5==0)"Buzz" else i)
	}
}
```

[^1]:
BLE advertise と tkinter

何回か前の nt 富山で ble advertise を使った環境情報（e.g. 温度湿度照度など）観測の試作を出したんだけど当時は nRF51 に欠陥があることを知らなかったので会場では使いものにならなかった。 今回の nt 金沢では nRF52 で汚名を雪ぐ。

あと、前回は通信 soft の画面そのものを見せていたけれどもう少し実用というか体裁を整えよう、と画策した結果 tkinter に落ち着いた。 

その画面がこれ。


![DSC_0179.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/f88a54a1-17f9-d3ef-fc2c-22899c60d731.jpeg)

こんな感じで電流（など）が表示される。

通信 soft の window が 2 つ出てるのは どちらの code も別 thread を使っており これをひとつにまとめて書く術が時間内に分からなかったため。 

逃げ策として ble scan 側で udp socket に書き出し、udp 受け側で tkinter を使っている。 後者の python コードがこれ。

```py
import threading
import socket
import tkinter

root = tkinter.Tk()
root.title("BLE Advertised UDP ClampMeter")	# 適宜適合されたし
root.geometry("386x133")

root.configure(bg='#d8c8b8')
root.resizable(False, False)
root.attributes("-alpha",0.75)

host = '127.0.0.1'		# 適宜適合されたし
port = 32032

def udp_recv():		# スレッドの中身
	while True:	# 待ち - 読み の繰り返し
		try :
			print('Waiting message')
			message, cli_addr = sock.recvfrom(512)
			message = message.decode()
			print(f'Received message is [{message}]')

			target = ','
			ix = message.find(target)
			op1 = int(message[:ix])/100  	# camma より前を切り出し
			op2 = message[ix+1:]  	# camma 1 以降を切り出し

			letter = str(op1) + ' [A]'
			disp["text"] = letter

		except KeyboardInterrupt:
			sock.close()
			break
#


global udp_recv_thread 		# 受信用スレッドの handle

ip_addr = (host, port)
sock = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)	# お馴染み udp socket 生成
sock.bind(ip_addr)

print('create socket')

disp = tkinter.Label(		# label 部分の宣言というか生成
	background='#d8c8b8',	# label 部分の背景色
	foreground='#803208',	# 文字色
#	relief = tkinter.SOLID,
#	borderwidth = 1,		# label 部分を見たいときに deremark
	font = ('Times', 36) ,
	anchor = tkinter.E,		# 枠の中で右詰め
	padx = 10,
	pady = 4		)

disp.pack(anchor = tkinter.E, padx = 64, pady = 32)		# 枠そのものの右詰め

udp_recv_thread = threading.Thread(target=udp_recv, daemon=True)
udp_recv_thread.start()


root.mainloop()
sock.close()

#	eof
```

電力線の電流を読むための回路を付けて nt 金沢 @2024 に出展し、動作は問題なかったが ble scan に時間が掛かるので電流を逐次見るには間隔が開きすぎて不適切な応用、かもという印象。 まあ無線 ct は nRF52｜sam d51 ではなく nxp でやるつもりなのでこれ以上は突っ込まない。


環境情報なら分単位かそれ以上だから幕間に sleep できるので最適かと思う。
Bootstrapを使ってみた

## はじめに
簡単なアプリやHP作成はできるようになったけれど、なかなかHTMLやCSSが思ったようにいかないというのが課題でした。ChatGPTにどうしたら上手くできるか聞いたところ、CSSフレームワークとしてBootstrapというフレームワークがあると知り、学習したため記録を残します。

## Bootstrapについて
Bootstrapは、Twitter社が開発したオープンソースのフロントエンドフレームワークで、ウェブ開発者が迅速にレスポンシブでスタイリッシュなウェブサイトやウェブアプリケーションを構築するのに役立ちます。Bootstrapを使用することで、CSSとJavaScriptの基本的な部分を簡単に取り入れることができます。

https://getbootstrap.jp/

## 主な特徴
### 1. レスポンシブデザイン
Bootstrapはモバイルファーストのデザインを採用しており、デフォルトでレスポンシブレイアウトを提供します。これにより、異なるデバイスや画面サイズに応じてウェブサイトのレイアウトが自動的に調整されます。

### 2. 豊富なコンポーネント
ボタン、ナビゲーションバー、モーダル、カードなど、様々な再利用可能なコンポーネントが用意されています。これらのコンポーネントは簡単にカスタマイズでき、ウェブサイトの構築を迅速に行えます。

### 3. グリッドシステム
Bootstrapのグリッドシステムは、ページレイアウトを効率的に構築するための12カラムのレスポンシブグリッドです。グリッドシステムを使うことで、レイアウトの配置や調整が容易になります。

### 4. カスタマイズ可能
Sass（Syntactically Awesome Stylesheets）を使用して、Bootstrapのスタイルをカスタマイズすることができます。必要なコンポーネントだけをインポートすることも可能で、プロジェクトに必要な部分だけを効率的に使用できます。

### 5. プラグインと拡張
Bootstrapは多くのJavaScriptプラグインを含んでおり、モーダルウィンドウやツールチップ、ポップオーバーなどのインタラクティブな要素を簡単に追加することができます。

## 使い方
使い方としては、サイトからダウンロードする方法、CDNを使用する方法などがあります。
今回はサイトからダウンロードして使用してみました。

1.　ダウンロードページからコンパイルされたCSSとJSをダウンロードする
https://getbootstrap.jp/docs/5.3/getting-started/download/

2.　ダウンロードしたフォルダを解凍し、CSSとJSのフォルダをVScodeの適当なフォルダにコピーする。今回はVScodeにbootostrrap_practiceというフォルダを作成しその中にCSSとJSフォルダをコピーしました。

3.　２で作成したフォルダ内にHTMLファイルを作成し、以下を記述します。
``` HTML
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link rel="stylesheet" href="bootstrap-5.3.0-dist/css/bootstrap.min.css">
  </head>
  <body>
    <h1>Hello, world!</h1>
  </body>
</html>
```
あとは、classを記入しbootostrapで設定されているCSSの情報を記入すると使うことができます。

## 使ってみた感想

簡単にデザインを編集することができるのですごく便利！！
次はアプリに導入して整ったサイトを作っていきたいと思います。
[Python]if-elif-else文の判定

# 学び
共通の条件を含む条件分岐において、条件が先に満たされる場合には当たり前に初めの文でプログラムが処理される。

# コード
### 間違ったコード
```python
input = 15
if input % 3 == 0:
    print("3の倍数です")
elif input % 5 == 0:
    print("5の倍数です")
elif (input % 3 == 0) and (input % 5 == 0):
    print("15の倍数です")
else:pass
```
この場合、始めの条件が満たされるので3番目の条件であるelif文に辿り着く前にプログラムが終了します。
### 正しいコード
```python
input = 15
if (input % 3 == 0) and (input % 5 == 0):
    print("15の倍数です")
elif input % 3 == 0:
    print("3の倍数です")
elif input % 5 == 0:
    print("5の倍数です")
else:pass
```
正しくは、このように先に二つの条件を満たす出力を書いておいてその他の出力でそれぞれの条件を分けて書きます。
fletで縦横スクロール付きのDataTableを表示する

```py:main.py
import flet as ft

def main(page: ft.Page):
    """縦横スクロール付きDataTable
    縦スクロール(コンテナのheight必須):
        ft.Container(
            content=ft.ListView(
                ft.DataTable()
            )
            height=CONTAINER_HEIGHT
            width=CONTAINER_WIDTH 
        )
    横スクロール(scroll="auto" or "always"必須):
      ft.Row(scroll="auto")
      ウィンドウ幅 < コンテンツ幅
    """
    CONTAINER_HEIGHT = 500
    CONTAINER_WIDTH = 450
    page.window_width = 400

    dt_cols = []
    for col in ["ID", "Name", "Age"]:
        dt_cols.append(ft.DataColumn(ft.Text(col))) 

    dt_rows = []
    for row in [(x, f"Test{x}", x) for x in range(1, 101)]:
        cells = []
        for cell in row:
            cells.append(ft.DataCell(ft.Text(cell)))
        dt_rows.append(ft.DataRow(cells))

    dt = ft.DataTable(
        columns=dt_cols,
        rows=dt_rows
    )

    lv = ft.ListView([dt], expand=1, spacing=10, padding=20)

    page.add(
        ft.Row(
            [
                ft.Container(
                    content=lv,
                    border=ft.border.all(1),
                    height=CONTAINER_HEIGHT,
                    width=CONTAINER_WIDTH,
                ),
            ],
            scroll="auto",
        )
    )

ft.app(target=main)
```
バカラを遊ぶプログラム（Python）

# 1. 動機

クラスについて学びたいと思い，トランプカードを用いるゲームならばよい練習になるのではないかと考えたこと．

# 2. バカラのルール

プレイヤーとバンカーが2枚ずつカードを引き，数の和下一桁を得点とする．ただし，Aは1，絵札は0として扱う．以下のルールによりお互い3枚目のカードを引くか決定し，最終的な点数が大きい方の勝利とする．

（ルール）
2枚ずつカードを引いた時点におけるプレイヤーとバンカーの得点を，それぞれ $ S_p, \ S_b $ とする．

1. $ \min (S_p, \ S_b) \leq 5 $ かつ $ \max (S_p, \ S_b) \leq 7 $ のとき，前者の式を満たす方一人（プレイヤー優先）が引く

2. 1. でプレイヤーの引いたカード $ X $ が $ \left \lfloor \dfrac {X - 9 \cdot \left \lfloor \dfrac {X}{8} \right \rfloor}{2} \right \rfloor + 3 \geq S_b $ を満たすとき，バンカーも引く

# 3. 実装

トランプカードはスートとランクという2つの属性をもつので， ``` suit ``` および ``` rank ``` というインスタンス変数を設定したクラスを ``` for ``` 文で呼び出すと山を生成できます．

```Python
class Card:
    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank

deck = [Card(i, j) for i in ['Clb', 'Dmd', 'Hrt', 'Spd'] for j in range(1, 14)]
```

``` deck.pop(0) ``` で引いたカードはオブジェクトなので， ``` .suit ``` でスートに， ``` .rank ``` でランクにアクセスできます．

<br>

カードの得点を求める式は，素直に書くと

```Python
self.score = self.rank if self.rank < 10 else 0
```

ですが，せっかくよい方法を思いついたので

```Python
self.score = min(self.rank, 10) % 10
```

としました．

# 4. コード

```Python
from math import floor
from random import shuffle

class Card:
    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank
        self.score = min(self.rank, 10) % 10

deck = [Card(i, j) for i in ['Clb', 'Dmd', 'Hrt', 'Spd'] for j in range(1, 14)]
shuffle(deck)

p1, p2 = deck.pop(0), deck.pop(0);    p_score = (p1.score + p2.score) % 10
b1, b2 = deck.pop(0), deck.pop(0);    b_score = (b1.score + b2.score) % 10

print(f'\nPlayer\'s hand: {p1.suit} {p1.rank: >2}, {p2.suit} {p2.rank: >2}')
print(f'Banker\'s hand: {b1.suit} {b1.rank: >2}, {b2.suit} {b2.rank: >2}')

if p_score <= 5 and b_score <= 7:
    p3 = deck.pop(0);    p_score = (p_score + p3.score) % 10
    print(f'\nPlayer hit another card: {p3.suit} {p3.rank: >2}')
    if floor((p3.score - 9 * floor(p3.score / 8)) / 2) + 3 >= b_score:
        b3 = deck.pop(0);    b_score = (b_score + b3.score) % 10
        print(f'Banker hit another card: {b3.suit} {b3.rank: >2}')
elif 7 >= p_score > 5 >= b_score:
    b3 = deck.pop(0);    b_score = (b_score + b3.score) % 10
    print(f'\nBanker hit another card: {b3.suit} {b3.rank: >2}')

print(f'\nPlayer\'s score: {p_score}\nBanker\'s score: {b_score}')

if p_score > b_score:
    print('\nPlayer Wins!')
elif b_score > p_score:
    print('\nBanker Wins!')
else:
    print('\nTie!')
```

# 5. 実行結果

```
Player's hand: Clb 11, Hrt  3
Banker's hand: Spd  6, Dmd 11

Player hit another card: Dmd  8

Player's score: 1
Banker's score: 6

Banker Wins!
```

# 6. 終わりに

今回プログラムを書くにあたり最も苦労したのは，プレイヤーとバンカーが3枚目のカードを引く条件を式で表すことです．これの説明にはほとんどの場合表が用られるのですが， ``` if ``` 文を多用するのは避けたかったので，頑張って式に落とし込みました．
【Python3】【殿堂入りキャンペーン】名刺バインダー管理 (paizaランク B 相当)をやってみた

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/name_card

**問題**:
あなたはこれまでに出会った人たちの名刺を集めています。名刺はバインダーに保存されており、1枚のファイルにはn個のポケットが横に並んでいます。表と裏の両面から名刺を眺めることができ、1つのポケットには2枚の名刺が背中合わせに入っています。

名刺の番号mが与えられるので、その名刺の裏側の名刺の番号を表示するプログラムを作成してください。番号mの名刺の裏面には必ず名刺が存在するものとします。

**入力値**:
```
n m
```

**期待される出力値**:
```
m番の名刺の裏側の番号
```

**条件**:
1 ≦ n ≦ 100,000
1 ≦ m ≦ 100,000

**Pythonプログラム**:
```python
# 入力値を読み込み、nとmに分割
n, m = list(map(int, input().split()))

# 名刺のページ番号を計算
# (m-1) // (n * 2) は0始まりのページ番号、+1で1始まりのページ番号に変換
page = (m-1) // (n * 2) + 1

# ページの最後の名刺番号を計算
pmax = page * n * 2

# ページの最初の名刺番号を計算
pmin = pmax - (n * 2 - 1)

# 名刺の裏側の番号を計算
# pmax + pmin - m でm番の名刺の裏側の番号を求める
print(pmax + pmin - m)
```

**コードの説明**:
1. **入力値の読み込み**:
    ```python
    n, m = list(map(int, input().split()))
    ```
    - 入力を読み込み、`n` と `m` に分割して格納します。

2. **ページ番号の計算**:
    ```python
    page = (m-1) // (n * 2) + 1
    ```
    - `(m-1) // (n * 2)` は0始まりのページ番号を計算します。`+1` することで1始まりのページ番号に変換します。

3. **ページの最初と最後の名刺番号の計算**:
    ```python
    pmax = page * n * 2
    pmin = pmax - (n * 2 - 1)
    ```
    - `pmax` はページの最後の名刺番号を計算します。
    - `pmin` はページの最初の名刺番号を計算します。

4. **名刺の裏側の番号の計算**:
    ```python
    print(pmax + pmin - m)
    ```
    - `pmax + pmin - m` で `m` 番の名刺の裏側の番号を計算します。
AtCoder 勉強記録[C++] その25

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - (K+1)-th Largest Number
[C - (K+1)-th Largest Number](https://atcoder.jp/contests/abc273/tasks/abc273_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll a, n;
  cin >> n;
  map<ll, ll> res;
  rep(i, n) {
    cin >> a;
    res[a]++;
  }
  for(auto i = res.rbegin(); i != res.rend(); i++){
    cout << i->second << endl;
  }
  for(ll i = 0; i < n - res.size(); i++) cout << 0 << endl;
}
```
### 解法
[ABC273 C問題（(K+1)-th Largest Number）を解く](https://programming-hiroba.com/abc273-c/)こちらの記事を参考にして解いた。
## C - Ameba
[C - Ameba](https://atcoder.jp/contests/abc274/tasks/abc274_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  vec a(n+1);
  vec res(2*n+2);
  res[1] = 0;
  for(int i = 1; i <= n; i++) {
    cin >> a[i];
    res[2*i] = res[a[i]] + 1;
    res[2*i+1] = res[a[i]] + 1;
  }
  for(int i = 1; i < 2*n+2; i++) cout << res[i] << endl;
}
```
### 解法
親の世代に+1世代するとこの世代が求まるため、すべてのアメーバの世代を入れておく配列を用意しておくことで結果が求まる。
【GitHub】プルリクエストのタイトルがConventional Commitsに則っているか検証する方法

`action-semantic-pull-request`を使用してプルリクエストのタイトルが[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)に則っているのか検証できます。

https://github.com/amannn/action-semantic-pull-request

## 導入方法

`.github/workflows/semantic-pull-request.yml`を以下の内容で作成します。

```yaml:.github/workflows/semantic-pull-request.yml
name: "Lint PR"

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize

permissions:
  pull-requests: read

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

```

プルリクエストのタイトルをコミットメッセージのタイトルにするため、リポジトリのSettings > General >  Pull RequestsでAllow squash mergingにチェックを入れ、Default commit messageをPull request titleに変更します。

![スクリーンショット 2024-07-19 23.52.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5ee67f81-5560-c36d-20e6-75535d0d52f8.png)
Raspberry PiでMinecraft 1.21のサーバーを建てる

# 環境
- Raspberry Pi 4 8GB
- Raspberry Pi OS 64bit
- ストレージ：SSD（USB3.0接続） 128GB
# サーバーが起動できない
Minecraftの新バージョン（1.21）が出たので、Raspberry Piで起動しようとした。
しかし、エラーが発生し起動できない。
```bash
$ java -Xmx4G -Xms4G -jar server.jar nogui
Error: LinkageError occurred while loading main class net.minecraft.bundler.Main
        java.lang.UnsupportedClassVersionError: net/minecraft/bundler/Main has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 61.0
```
具体的には、MinecraftサーバーがJavaの新しいバージョンでコンパイルされており、クラスファイルバージョン65.0を要求しているようだ。
# Javaを更新する
当方が最後に起動したMinecraftサーバーは1.20.1である。

Javaのバージョンを確認すると17.0.11だった。これを更新する必要がある。
```bash
$ java -version
openjdk version "17.0.11" 2024-04-16
OpenJDK Runtime Environment (build 17.0.11+9-Debian-1deb11u1)
OpenJDK 64-Bit Server VM (build 17.0.11+9-Debian-1deb11u1, mixed mode, sharing)
```
どうせこのバージョンはもう使わないので削除する。
```bash
$ sudo apt remove openjdk-*
```
クラスファイルバージョン65.0以上を要求しているため、Java21以上が必要なようだ。
https://javaalmanac.io/bytecode/versions/

## aptでインストール
aptを用いて対応しているopenjdkのインストールを試みる。
```bash
$ sudo apt install openjdk-21-jdk
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package openjdk-21-jdk

$ sudo apt install openjdk-22-jdk
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package openjdk-22-jdk
```
openjdkの21以降が必要だが、21も22（GA最新版）もaptではインストールできない。

Ubuntuではインストールできている記事を散見するので、armなのが問題なのだろうか。有識者求ム。
## 手動でインストール
aptが使えないので、[こちら](https://jdk.java.net/22/)から自分でarmのバイナリを落としてインストールする。

2024/07/19現在、最新のGAは22.0.2とのことなので、それをインストールする。
### openjdkをダウンロードする
wgetでダウンロード
```bash
$ wget https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_linux-aarch64_bin.tar.gz
```
落としたtar.gzを解凍する
```bash
$ tar -xvf openjdk-22.0.2_linux-aarch64_bin.tar.gz
```
適切なディレクトリに保存
```bash
$ sudo cp -r jdk-22.0.2 /opt/
```
### 環境変数の設定
```bash
$ vi ~/.bashrc
```
ファイルの最後に、次の2行を追記する。
```text
export JAVA_HOME=/opt/jdk-22.0.2
export PATH=$PATH:$JAVA_HOME/bin
```
設定を反映させるため、一度ターミナルを切ってから再度開く。

そしてバージョンを確認。
```
$ java -version
openjdk version "22.0.2" 2024-07-16
OpenJDK Runtime Environment (build 22.0.2+9-70)
OpenJDK 64-Bit Server VM (build 22.0.2+9-70, mixed mode, sharing)
```
これで1.21のMinecraftサーバーをRaspberry Piで起動できるようになった。
# まとめ
Javaランタイムのバージョンが古く、Minecraftサーバーを起動できなかった。

aptで適切なパッケージが見つからなかったため、手動でGA最新版のarm用ランタイムをインストールして解決した。
【Python3】3Dプリンタ (paizaランク B 相当)をやってみた

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/3d_printer

**問題: 3Dプリンタの立体データを正面から見たときの図を生成**

**入力**:
1. 奥行きを表す整数 `X`
2. 横幅を表す整数 `Y`
3. 高さを表す整数 `Z`
4. 各セルが `#` または `.` で表される立体データ

**出力**:
- 正面（x軸の正の方向）から見たときの図を Z 行 Y 列で出力

**アプローチ**:
1. 標準入力から `X`, `Y`, `Z` と立体データを読み込む
2. 各層ごとにデータを処理し、3次元リストに格納
3. 正面図を生成し、結果を出力

**コード**:
```python
# X, Y, Zのサイズを読み込む
X, Y, Z = list(map(int, input().split()))

# Z行Y列の出力用の2次元リストを初期化
m = [['.' for j in range(Y)] for i in range(Z)]

# 各層（Z軸方向の各平面）ごとにデータを読み込む
for k in range(Z):
    for i in range(X):
        # 一行分のデータを読み込む
        n = input().strip()
        # Y軸方向に沿ってデータを処理
        for j in range(Y):
            # '#'があればその位置を出力用のリストに設定
            if n[j] == '#':
                m[k][j] = '#'
    # 区切り文字を読み込む
    l = input().strip()

# 出力用のリストを逆順に処理して出力
for i in reversed(range(Z)):
    # 各行を文字列に変換
    l = ''.join(m[i])
    # 各行を出力
    print(l)
```

**コードの説明**:
1. **入力の読み込み**:
    - `X`, `Y`, `Z` を標準入力から読み込み、整数に変換。
    - 正面図を格納するための2次元リスト `m` を初期化。各要素は `'.'` で初期化。

2. **データの処理**:
    - 各層（Z軸方向の各平面）ごとにデータを読み込みます。
    - `n` に一行分のデータを読み込み、Y軸方向に沿ってデータを処理。
    - `'#'` があれば、その位置を正面図リスト `m` に設定。
    - 区切り文字 `--` を読み込む。

3. **正面図の生成と出力**:
    - 正面図リスト `m` を逆順に処理して出力。
    - 各行を文字列に変換して出力。

このプログラムは、与えられた立体データを読み込み、正面から見たときの図を生成して正確に出力します。
【React学習】ランダム画像表示画面を作成

こちらの記事を参考に、ランダム画像表示画面をつくりました。

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

### 作ったもの
画像取得ボタンを押すと、ランダムで画像が表示されます。サイズは800pxで固定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842044/7e25cc3a-55a8-3885-9571-f6b176b287d5.png)

ソースコードは以下です。ほかのサイトから参考にした点も多いです。
```
        function ImageButton() {

            const [image, setImage] = React.useState(null);

            const onClick = checked => {
                fetch('https://picsum.photos/800', {
                    method: 'GET',
                    mode: "cors"
                })
                    .then(res => res.blob())
                    .then(blob => {
                        setImage([URL.createObjectURL(blob)]);
                        console.log(URL.createObjectURL(blob));
                    })
                    .then(data => {
                        // .thenは成功した時の処理を示す場合に使う。
                        console.log('Success');
                    })
                    .catch((error) => {
                        // .catchは失敗の時の処理を示す場合に使う。
                        console.error('Error:', error);
                    });


            };

            return (
                <div className="panel">
                    <button onClick={onClick}>
                        画像取得
                    </button>
                    <img src={image} width="800px" />
                </div>
            );
        }

        function App() {
            return (
                <div className="container is-fluid">
                    <ImageButton />
                </div>
            );
        }

        const root = document.getElementById('root');
        ReactDOM.render(<App />, root);
```

### 詰まった点
- 元にしたページで紹介されていたhttps://source.unsplash.com/random が使用できなくなっていたので、代わりに https://picsum.photos を使用しました。
- ランダムに表示させようと https://picsum.photos/800?random でリクエストしていたのですが、なぜか画像が表示されませんでした。
　30分ぐらい悩んでようやく解決しました。
YoloXモデルのCoreML変換

ObjectDetectionをアプリに実装するときに大体のYOLOモデルはGPLv3ライセンスで配布しており、アプリは配布したいけどコードの公開はしたくないケースが業務ではままあります。

そろそろ業務アプリで使う必要がありそうなので、さてどうしようかと思っていたところタイムリーにApache2ライセンスのYoloXにCoreML変換のPRが寄稿されました。

https://github.com/Megvii-BaseDetection/YOLOX/pull/1782

試しに動かしてみたところ、エラーになります🤔
PRにコメントを投稿してみましたが修正いただけないこともあり、気になる点が多々ありましたので必要な部分以外は書き直してみました。

最終的に下記のコード以外は大体書き直しました。

```python
class YOLOXDetectModel(nn.Module):
    """Wrap an Ultralytics YOLO model for Apple iOS CoreML export."""

    def __init__(self, model, im, num_of_class):
        """Initialize the YOLOXDetectModel class with a YOLO model and example image."""
        super().__init__()
        _, _, h, w = im.shape
        self.model = model
        self.nc = num_of_class  # number of classes
        self.normalize = torch.tensor([1.0 / w, 1.0 / h, 1.0 / w, 1.0 / h])

    def forward(self, x):
        """Normalize predictions of object detection model with input size-dependent factors."""
        out_pred = self.model(x)
        xywh = out_pred[:, :, :4][0]
        objectness = out_pred[0][:, 4:5]
        class_conf = out_pred[0][:, 5:5 + self.nc]
        class_scores = objectness * class_conf
        return class_scores, xywh * self.normalize
```

その他の、YoloXを扱う上での注意点としてはモデルの入力に正規化が必要ない点です。
ですので、CoreMLに変換する際、scaleを設定するとドハマリするのでお気をつけてください。

## 出力したモデル

![スクリーンショット 2024-07-19 23.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/41f1c3e8-d05d-892b-633c-1a7a27d74d03.png)


## コード

https://gist.github.com/32aff3cfc67a118de8304de2a250234a.git

## 追記 2024/11/27

最近iOS18にアップグレードしたら[以前作成したViTPoseのモデル](https://qiita.com/mbotsu/items/f1eb6dcd2b7da6489e35)が動かなくなりました。
結果的にconvert部分をmlprogramに変更したら動きました。
サイレントアップデートで動かなくするAppleさん恐ろしや。

本題ですが、mlprogramでnms適用したライセンスの緩いコードをサクッと検索したら見つからないので試しに書いたら動いたのでメモを残しておきます。

https://gist.github.com/72cac326837bff4b4ad1dda508a91428.git
投稿 19 IPアドレスとMACアドレスの違い、ARP 2024/07/19

本日の勉強時間　6H

IPアドレスはインターネットで使われる住所のようなもの。
一方
MACアドレスは隣接する機器の通信を実現するためのアドレス。

ARP・・・アドレス解決プロトコルのこと。インターネット、社内LANなどに利用されているTCP/IPネットワークでパケット送信する際、宛先となるIPアドレスから宛先デバイスのMACアドレスを割り出せるプロトコル。
デバイス間の通信を円滑化させる。IPアドレスをMACアドレスの間の関連づけを行う役割。
NEXTJS ④Next.jsで画面遷移時プログレスバー(NProgressの紹介) 

NProgressは、Webアプリケーションにプログレスバーを簡単に追加できる軽量のJavaScriptライブラリです。Zennなどのサイトでよく使われています。NProgressを使用するための基本的な手順は以下の通りです。

#### 1. NProgressのインストール
まず、NProgressをプロジェクトにインストールします。npmを使用してインストールする場合は以下のコマンドを使用します。
```
npm install nprogress
```
#### 2. CSSのインポート
NProgressにはプログレスバーのスタイルを定義するCSSファイルがあります。これをインポートする必要があります。
```
import 'nprogress/nprogress.css';

```
#### 3. JavaScriptのインポートと設定
NProgressを使用するJavaScriptファイルに以下のコードを追加します。
```
import NProgress from 'nprogress';

// プログレスバーの開始
NProgress.start();

// プログレスバーの終了
NProgress.done();

```
#### 4. プログレスバーのカスタマイズ (オプション)
NProgressはカスタマイズ可能です。例えば、プログレスバーの速度やカラーを変更することができます。
```
NProgress.configure({ showSpinner: false }); // スピナーを非表示にする
NProgress.configure({ speed: 500 }); // プログレスバーの速度を変更する

```
これで、基本的な設定は完了です。特定のイベントやHTTPリクエストの際にプログレスバーを表示させたい場合は、そのイベントの開始時にNProgress.start()を呼び出し、終了時にNProgress.done()を呼び出すことで実現できます。

#### 例: Axiosとの連携
例えば、HTTPリクエストライブラリのAxiosと組み合わせる場合は以下のようにします。
```import axios from 'axios';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

axios.interceptors.request.use(config => {
  NProgress.start();
  return config;
});

axios.interceptors.response.use(response => {
  NProgress.done();
  return response;
}, error => {
  NProgress.done();
  return Promise.reject(error);
});

```
####  NEXTJS  hooks の作成 プログレスバーを表示させる
ページ遷移時にプログレスバーを表示させる hooks を作成します。

Next.js の useRouter でページ遷移時のイベントを取得できるので、イベントごとにプログレスバーの表示/非表示を切り替えます。

プログレスバーの制御は NProgress.start() と NProgress.done() を実行するだけです。
```
import 'nprogress/nprogress.css'

import { useRouter } from 'next/router'
import NProgress from 'nprogress'
import { useEffect } from 'react'

export const useProgressBarAtTransition = (): void => {
  const router = useRouter()

  useEffect(() => {
    const handleStart = () => {
      NProgress.start()
    }

    const handleStop = () => {
      NProgress.done()
    }

    router.events.on('routeChangeStart', handleStart)
    router.events.on('routeChangeComplete', handleStop)
    router.events.on('routeChangeError', handleStop)

    return () => {
      router.events.off('routeChangeStart', handleStart)
      router.events.off('routeChangeComplete', handleStop)
      router.events.off('routeChangeError', handleStop)
    }
  }, [router])
}
```
#### スタイルを修正する　自分のcustomer styleを作成
スタイルはライブラリデフォルトのものを指定していましたが、プログレスバーの色などを変更したい場合は css を修正します。

まずは、公式の css をプロジェクトに作成するので、 Github からコピーしてきます。
https://github.com/rstacruz/nprogress/blob/master/nprogress.css
変更したら _app.tsx でcssをインポートします。
```
import '../../styles/nprogress.css'

// ..省略..
```
WARN[0000] /Users/user/app/docker-compose.yml: `version` is obsolete

# 本日のお悩み
### Dockerを使用してDjangoを動かそうとしている時に下記コマンドを入力するとエラーが出た
下記コマンドの意味: docker-compose.yml に定義されたすべてのサービスのイメージをビルド
```zsh
docker compose build
```
エラー内容
```zsh
WARN[0000] /Users/user/app/docker-compose.yml: `version` is obsolete
```
docker-compose.ymlのバージョンが廃止されたとのこと。

### docker-compose.ymlの詳細
```docker-compose.yaml

version: '3.3'
services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=tutorial
      - POSTGRES_PASSWORD=tutorial
      - POSTGRES_DB=tutorial
    ports:
      - "127.0.0.1:5432:5432"
  web:
    build: .
    restart: always
    command: python manage.py runserver 0.0.0.0:8000
    env_file:
      - .env
    ports:
      - "127.0.0.1:8000:8000"
    volumes:
      - .:/code
    links:
      - db
    depends_on:
      - db

```

# 本日の処方箋

```docker-compose.yaml
# この行を丸ごと削除
version: '3.3'
```

### Composeのバージョンが最新になったことにより、versionプロパティが廃止されたためエラーが出力
### docker-compose.yml内のversion: '3.3'の記述を削除しました。

```zsh
docker compose build
[+] Building 2.5s (11/11) FINISHED                   docker:desktop-linux
=> [app internal] load build definition from Dockerfile.dev          0.0s
```
### このような記載が表示されればOK！！

### ちなみにこちらのドキュメントによると、色々と変更があったみたいです。

https://docs.docker.jp/compose/compose-file/index.html#compose-specification


<INS>作業ディレクトリ内での、Compose ファイルのデフォルトのパスは compose.yaml （推奨）か compose.yml です。
Compose 実装は、下位互換性のために docker-compose.yaml と docker-compose.yml もサポート すべきです。
両方のファイルが存在する場合、 Compose 実装は標準である compose.yaml を優先 しなければいけません。<INS>