OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 24.04でDockerを使用して任意のCUDAバージョンのコンテナを動作させる方法

# はじめに
機械学習の勉強をしていると、使用するAIモデルに合わせたライブラリやCUDAバージョンを用意する必要があります。このガイドでは、Ubuntu 24.04でDockerを使用し、任意のCUDAバージョンを使用したコンテナを実行する方法を説明します。

Dockerのインストールまでは前回の記事で紹介しているのでそちらを参考にしてください。

https://qiita.com/Marron-chan/items/570c7c7baaae3b4d6b11

## Dockerを使用する前に、、
まずは現在の環境でnvidiaドライバがインストールされているかを確認します。
ターミナルで以下コマンドを入力して確認をしてください。

```terminal
nvidia-msi
```

もしドライバがなければ、vidiaのGPUが取り付けられていることを確認した上で以下のコマンドでドライバのインストールを行ってください。

```terminal
sudo ubuntu-drivers autoinstall
```

# nvidia コンテナツールキットのインストール
[NVIDIA CONTAINER TOOLKIT](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installation)の公式ページを参考にインストールします。

```terminal
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list


sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
```

こちらのコマンドでツールキットがインストールされたかを確認します。

```terminal
nvidia-container-toolkit info
```

正しくインストールされていれば以下のコメントが出力されるはずです。
動かない場合は再起動してみてください。

```
Usage of nvidia-container-toolkit:

※以下割愛
```

# CUDA/cuDNNのイメージのプル
ここから、任意のCUDAバージョンのイメージをローカルにプルし、立ち上げてみます。

[nvidia/cudaのDocker hub](https://hub.docker.com/r/nvidia/cuda/tags?page=2&page_size=&ordering=&name=)から使用したいイメージを選択します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/b5fc6a79-2f18-9083-7002-d1df74964bc7.png)


使用したいTAGイメージを選択し、ターミナルにペーストして実行します。画面右にあるCopyボタンをクリックするとコマンドがコピーされて便利です。

今回、私はCUDAバージョン12.3.1のイメージを使用します。TAG名は以下のようなルールで決められていますので、自分の必要に合わせて使用してください。

:::note info
* `12.3.1-base-ubuntu22.04`
    * イメージのタグを示し、イメージのバージョンや特定の構成を識別するために使用されます。
* `12.3.1`
    * CUDAのバージョン番号を示し、この場合、CUDA 12.3.1バージョンです。
* `base`
    * ベースイメージであることを示します。追加のツールやライブラリが含まれていない最小限のセットアップです。
* `ubuntu22.04`
    * ベースとなるオペレーティングシステムのバージョンを示しています。この場合、Ubuntu 22.04です。
:::

以下のコマンドでイメージをプルします。

```terminal
docker pull nvidia/cuda:12.3.1-base-ubuntu22.04
```

# イメージの起動
ターミナルからイメージを起動します。

```
docker run --gpus all -it nvidia/cuda:12.3.1-base-ubuntu22.04
```

比較として、生Ubuntuとコンテナ内でOSバージョン及びGPUの認識を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/49b37458-099b-5adf-0a41-9dafd5010bfc.png)

OSがUbuntu 22.04となりCUDAバージョンが12.3となっていることが確認できます。

# おわりに
ここまでで任意のCUDAバージョン及びOSのイメージをインストールし起動することができました。
この中で自分の行いたいAIの実行を行うことができます。
VSCode 大量の設定・拡張機能をプロファイルで整理する

![スクリーンショット 2024-06-18 18.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596510/ea0efc38-b01b-e25b-ec6c-75243396675d.png)

## 問題点

VSCodeは様々な用途で使われるかと思います。筆者の場合、

- コーディング（HTML/CSS/JS）
- バックエンド（PHP/Laravel）
- Python
- C/C++

など。
それぞれで必要な拡張機能は異なるにも関わらず、同じ設定・拡張機能を用いると以下のような状態に陥ることがあります。

- 不必要な拡張機能が多い（動作が遅くなる原因）
- 設定ファイル（setting.json）の見通しが悪い

## 改善方法

VSCode標準機能の **「プロファイル」** を用いることで、以下の項目をプロファイル毎に分離可能です。

1. 設定
1. キーボードショートカット
1. ユーザースニペット
1. ユーザータスク
1. 拡張機能

構成内容は、プロファイルごとに選択可能です。
例えば **「5.拡張機能」のみ選択** した場合、拡張機能だけは他のプロファイルと分離され、1~4は「既定」プロファイルの設定に従います。

## 一部設定はすべてのプロファイルで同期させたい

各種設定をすべてのプロファイルに同期させることも可能です。
例えば、「空白文字の表示設定」や「ファイルアイコンの拡張機能」などは、すべてのプロファイルで同期させたい、と思うかもしれません。

以下の手順で、プロファイルごとに変更し直す必要がなくなります。

### 設定

設定項目左端に表示される歯車から、「設定をすべてのプロファイルに適用」にチェック。
※チェックされた設定項目は、どのプロファイルから変更してもすべてのプロファイルに適用されるようになります。「既存プロファイルの設定を上書き」という動作ではないことに注意してください。

![スクリーンショット 2024-06-18 18.40.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596510/356962cb-0603-8018-dbaf-d9a70e2f19e4.png)

### 拡張機能

拡張機能の右下に表示される歯車から、「すべてのプロファイルに拡張機能を適用する」にチェック。
※設定と同様に、どのプロファイルから変更してもすべてのプロファイルに適用されるようになります。削除するとすべてのプロファイルから削除されることに注意してください。

![スクリーンショット 2024-06-18 18.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596510/423b38c5-4b4f-c5b1-43ab-cc84535ca3cc.png)
PythonでGoogleスプレッドシートを操作する

この記事では、GoogleスプレッドシートをPythonで操作する方法を紹介します。

#### 必要な準備

まず、GoogleスプレッドシートAPIを使用するための設定を行います。

##### 1. Google Cloud Platformでプロジェクトを作成

1. [Google Cloud Platform](https://console.cloud.google.com/)にアクセスし、Googleアカウントでログインします。
2. 新しいプロジェクトを作成します。

##### 2. APIを有効化

1. プロジェクトが作成されたら、ナビゲーションメニューから「APIとサービス」→「ライブラリ」に移動します。
2. 「Google Sheets API」を検索して有効にします。
3. 同様に「Google Drive API」も有効にします。

##### 3. 認証情報の作成

1. ナビゲーションメニューから「APIとサービス」→「認証情報」に移動します。
2. 「認証情報を作成」ボタンをクリックし、「サービスアカウントキー」を選択します。
3. 新しいサービスアカウントを作成し、「役割」で「編集者」を選択します。
4. JSON形式のキーをダウンロードします。このファイルを安全な場所に保存してください。

##### 4. gspreadとoauth2clientのインストール

以下のコマンドを実行して、必要なライブラリをインストールします。

```bash
pip install gspread oauth2client
```

#### PythonでGoogleスプレッドシートを操作する

##### 1. 認証とスプレッドシートへのアクセス

まず、ダウンロードしたJSONファイルを使用して認証を行い、Googleスプレッドシートにアクセスします。

```python
import gspread
from oauth2client.service_account import ServiceAccountCredentials

# 認証情報の設定
scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
creds = ServiceAccountCredentials.from_json_keyfile_name('path/to/your/json/file.json', scope)

# クライアントの作成
client = gspread.authorize(creds)

# スプレッドシートの取得
spreadsheet = client.open('Your Spreadsheet Name')

# ワークシートの取得
worksheet = spreadsheet.sheet1
```

##### 2. データの読み込み

次に、スプレッドシートからデータを読み込んでみましょう。

```python
# 全データの取得
data = worksheet.get_all_records()
print(data)

# 特定のセルの値を取得
cell_value = worksheet.acell('A1').value
print(f"A1セルの値: {cell_value}")

# 特定の範囲の値を取得
range_values = worksheet.get('A1:B2')
print(f"A1:B2の値: {range_values}")
```

##### 3. データの書き込み

スプレッドシートにデータを書き込む方法を紹介します。

```python
# 特定のセルに値を書き込む
worksheet.update_acell('A1', 'Hello World')

# 特定の範囲に値を書き込む
worksheet.update('A2:B2', [['Foo', 'Bar']])

# 新しい行を追加
worksheet.append_row(['New', 'Row', 'Data'])
```

##### 4. 行と列の操作

行や列を挿入・削除する方法を紹介します。

```python
# 新しい行を挿入
worksheet.insert_row(['Inserted', 'Row'], 2)

# 行の削除
worksheet.delete_row(2)

# 新しい列を挿入
worksheet.insert_col(['Inserted', 'Column'], 2)

# 列の削除
worksheet.delete_col(2)
```

##### 5. データのフィルタリングとソート

データのフィルタリングやソートを行う方法を紹介します。

```python
# 条件に基づいてデータをフィルタリング（例: 1列目の値が'Foo'の行）
filtered_data = [row for row in worksheet.get_all_records() if row['Column1'] == 'Foo']
print(filtered_data)

# データのソート（例: 2列目の値でソート）
sorted_data = sorted(worksheet.get_all_records(), key=lambda x: x['Column2'])
print(sorted_data)
```

以上
Pythonでのユニットテストの基本と実践（サンプルコードあり）

# はじめに
Pythonでのユニットテストは、コードの品質を保つために非常に重要です。
この記事では、基本的なユニットテストの書き方と、具体的なサンプルコードを紹介します。

# ユニットテストとは？
ユニットテストは、プログラムの最小単位である「ユニット」（関数やメソッド）が正しく動作するかを検証するテストです。これにより、バグの早期発見やコードのリファクタリング時の安心感を得ることができます。

# やってみよう
### 1. テスト対象のコードを作成
まず、テスト対象のコードを作成します。ここでは、基本的な数学関数を実装した
math_functions.py を用意します。

##### math_functions.py
```
# math_functions.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero!")
    return a / b
```



### 2. ユニットテストの作成
次に、この関数群をテストするためのユニットテストを test_math_functions.py というファイルに作成します。

##### test_math_functions.py
```
# test_math_functions.py
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

import unittest
from math_functions import add, subtract, multiply, divide

class TestMathFunctions(unittest.TestCase):
    
    def test_add(self):
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(-1, 1), 0)
        self.assertEqual(add(-1, -1), -2)
        self.assertEqual(add(0, 0), 0)
    
    def test_subtract(self):
        self.assertEqual(subtract(2, 1), 1)
        self.assertEqual(subtract(-1, 1), -2)
        self.assertEqual(subtract(-1, -1), 0)
        self.assertEqual(subtract(0, 0), 0)
    
    def test_multiply(self):
        self.assertEqual(multiply(2, 3), 6)
        self.assertEqual(multiply(-1, 1), -1)
        self.assertEqual(multiply(-1, -1), 1)
        self.assertEqual(multiply(0, 100), 0)
    
    def test_divide(self):
        self.assertEqual(divide(6, 3), 2)
        self.assertEqual(divide(-6, -3), 2)
        self.assertEqual(divide(-6, 3), -2)
        with self.assertRaises(ValueError):
            divide(1, 0)
        with self.assertRaises(ValueError):
            divide(0, 0)

if __name__ == '__main__':
    unittest.main()

```
    
##### 3. テストの実行
次に、ターミナルで以下のコマンドを実行してテストを実行します。

```
python3 test_math_functions.py
```
これで、ユニットテストが実行され、すべてのテストが成功するかどうかが確認できます。


テストがすべて成功した場合、次のような出力が表示されます。

```
....
----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK
```


### 4. テストの拡張

* **テストケースの追加:**
    * 異常系やエッジケースのテストも追加してみましょう。
    * 例えば、divide 関数においてゼロ以外のさまざまなケースをテストするなど。
* **テストカバレッジの向上:**
    * coverage パッケージを使って、テストカバレッジを確認できます。これにより、どの部分のコードがテストされていないかを把握できます。
```
インストール: pip install coverage
実行: coverage run -m unittest test_math_functions.py
レポート生成: coverage report
```

* **自動化:**
    * テストをCI/CDパイプラインに組み込むことで、コードが変更されるたびに自動的にテストが実行されるようにします。GitHub ActionsやTravis CIなどのツールを利用できます。

* **モックとパッチ:**
    * 外部依存やI/O操作を行う部分をテストする際には、unittest.mock を利用してモックやパッチを使います。

* **ドキュメントとコメント:**
    * テストコードにも適切なコメントを付けることで、他の開発者がテストの目的や意図を理解しやすくなります。



### 5. まとめ
ユニットテストは、コードの品質を保ち、バグを早期に発見するための重要な手段です。ここでは基本的な数学関数のテストを例に取り上げましたが、他のプロジェクトでも同様の手法でテストを追加していくことができます。
実際に動かしてみると問題なくテストてできました。


また以下のポイントに注意して、効果的なユニットテストを作成していきましょう。

* テストケースの追加: 異常系やエッジケースのテストを追加する。
* テストカバレッジの向上: coverage パッケージを使ってテストカバレッジを確認する。
* 自動化: テストをCI/CDパイプラインに組み込む。
驚くべき論破術

**私は真に驚くべき論破術を編み出したが、ここにそれを書くには余白が狭過ぎる。**
などといった内容に違いない! いや冗談ではなく、本当にそういう事です。以下はこの手法の使用例です。

**私はあなたの主張が間違っている事を証明したが、ここにそれを書くには余白が狭過ぎる。**

などといった内容に違いないのです。この手法は遥か360年以上前から使い古されまくってきました。開発者はあの**超天才ド素人数学者もどき**のフェルマーである事を私は証明しましたが、余白が狭過ぎてここにそれを示すとは不可能です。
## 応用
書けない事が前提なので、口頭では役に立ちません。他の言い回しで言いくるめてやりましょう。

**私はあなたの主張が間違っている事を証明したが、ここでそれを説明するには時間が少な過ぎる。**

証明しておきながらその内容は伏せてしまう、非常に巧妙な論破術。もはや相手は手も足も出ません。あなたの勝利です。おめでとうございます。
掲示板なり投稿動画への書き込みなり、この手法が役に立ちまくる事を私は証明しましたが、それをここに書くにはやはり余白が狭過ぎます。
社内AIの活用でプログラミング開発をもっとスムーズに！～メリットと注意点～

こんにちは。最近有志により社内にAIチャットを立ち上げてくれて利用できるようになったことから、社内で活用しているAIチャットについてお話ししたいと思います。現状感じたプログラミング開発におけるAIのメリットと注意点を、ざっくりまとめました。

### 機密事項を守りながらAIを活用したいので

プログラミング開発には機密事項が多く含まれますよね。そのため、AIを使う際にはプライバシーポリシーをしっかりと守る必要があります。私たちの社内AIは、ログ情報を社内管理の仕組みでしっかり管理し、AIの思考部分だけの恩恵を受けるように学習には使われないように利用しています。これにより、機密情報が外部に漏れる心配をせずに、AIの力を最大限に活用できるのです。

### AIの誤回答に気をつけて

とはいえ、AIも完璧ではありません。技術的な質問に対して、時にはハルシネーション（誤回答）をすることがあります。例えば、弊社で利用しているWebRTCを使ったSDKに関する質問では、そもそもSDKがオープンソースではなく有料のため、情報が少なく見当違いな回答をすることがありました。また、Androidアプリ開発においては、つい最近のGoogle IO後のバージョンアップでDeprecatedされた仕組みを使ったプログラムを返すこともあります。

### シンプルなプログラムの解釈はおまかせ！

しかし、AIはシンプルなプログラムの文法解釈においては非常に優れています。Googleなどの検索エンジンで探すよりも信頼性が高い結果が得られることが多いのです。ちょっとしたプログラムの疑問には、社内AIがすぐに答えてくれるので、とても助かっています。

### AIと一緒に壁打ちセッション

プログラミングの内部設計を検討する際にも、社内AIはとても便利です。アイデアを出し合ったり、疑問点を解消したりする「壁打ちセッション」において、AIが的確なアドバイスをくれることがあります。これにより、チーム全体の生産性が向上し、より良い設計が可能になります。

### ログ解析なんか、とても助かる！

サーバーやエディタのシミュレーターが出力する膨大なログデータを解析するのは、慣れていてもなかなか大変な作業ですが、社内AIに概要を確認してもらいエラーの有無や気になる部分の抽出を行ってもらうことで、確認作業が大幅に簡単になります。

### チームでの振り返りや技術検討にも大活躍？！？！

私たちのチームでは、振り返りや技術検討を行う際にも、社内AIの力を借りることを検討しています。具体的にはまだ試したことはありませんが、アイデアの捻出や技術的な検討に役立ちそうです。AIがチームメンバーの一員として活躍することで、より創造的なアイデアが生まれることを期待しています。

### まとめ

社内AIを活用することで、私たちのプログラミング開発はよりスムーズになり、効率が向上しています。もちろん、AIの誤回答には注意が必要ですが、シンプルなプログラムの解釈や内部設計の壁打ちには大いに役立っています。これからも、AIの力を借りながら、より良い製品を開発していきたいと思います。

皆さんも、AIを活用してみてはいかがでしょうか？新しい発見と効率化の道が開けるかもしれませんよ！


> ※こちらでは具体的な構築情報などは現状機密扱いなため取り扱いません。もし居身がある方がいらっしゃたら、詳しい情報が知りたければ、社員として入ってみてください💦

 ちなみに、利用しているのは「Claude3」と「ChatGPT 4o」です。
コードブロックのインデント方法

## コードブロックと言えば、

次のように`コード`を書く場所です。

```text:コードブロック
ここにコードを書きます
```

本文をインデントしているときは、コードブロックも同じように インデントしたい場合があります。例えば、

- インデント1
  ここに、
    + インデント2
    ここに、
        * インデント3
        ここに、


（ここに、）コードブロックを付け加える場合です。


## 順序なしリスト


- インデント1

  ```
  コードブロック1
  ```

  + インデント2

    ```
    コードブロック2
    ```

    * インデント3

      ```
      コードブロック3
      ```


<br>↓次のように書きます。行頭のスペースの個数が重要です。

~~~
- インデント1

  ```
  コードブロック1
  ```

  + インデント2

    ```
    コードブロック2
    ```

    * インデント3

      ```
      コードブロック3
      ```
~~~

## 番号付きリスト

「番号付きリスト」でも試してみます。

2. インデント1

   ```
   コードブロック1
   ```

   3. インデント2

      ```
      コードブロック2
      ```

      4. インデント3

         ```
         コードブロック3
         ```


<br>↓次のように書きます。行頭のスペースの個数が重要で、先の「順序なしリスト」の場合の個数とも違います。

~~~
2. インデント1

   ```
   コードブロック1
   ```

   3. インデント2

      ```
      コードブロック2
      ```

      4. インデント3

         ```
         コードブロック3
         ```
~~~


_プレビューだとレイアウトが一部崩れるときがあるため、「下書き保存」して確認しています。_
Excel VBA チェックボックスに全選択/全解除機能を付ける

## チェックボックスに全選択/全解除機能を付けるコード

自分メモ
チェックボックスの上で右クリック → マクロの登録 で以下のプロシージャを登録
    
```vb
Sub チェック11_Click()

Dim i As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet4")

    If ws.Range("E1") = True Then

        For i = 2 To 11
            ws.Cells(i, 5) = True
        Next i

    Else

        For i = 2 To 11
            ws.Cells(i, 5) = False
        Next i

    End If

End Sub
```
実行結果
D1セルのチェックボックスをクリックすると、すべてのチェックボックスにチェックが入る

![全選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/77b5d88a-a698-2268-34ab-13d24c5606e3.png)
アプリケーション共通認証基盤をつくってみた

# はじめに
**認証認可って大切ですよね**


弊社には多数の社内システムが存在しており、その認証認可方式は様々です。
ADFSとSAML連携、独自実装、LDAP参照…等々

- 折角EntraIDに全ての社員情報が統合されているのに活用しないのは勿体ない :anguished: 
- システムが個々に認証機能を考えて実装するのは手間がかかる :confounded:
- システム毎にユーザの追加削除運用がバラバラで面倒くさい :sob:

という事で内製開発の推進や、社内システムのクラウドマイグレーションに合わせて「共通機能」の１つとして**共通認証基盤**を実装しています。

# 弊社における共通機能の位置づけ
<span style="background-color:#f0f8ff">**共通機能**</span>或いは<span style="background-color:#f0f8ff">**共通基盤**</span>というキーワードでシステムインフラや非機能部分を統合する事で無駄を省き、運用を効率化するというアプローチは多くの会社で実施されているのではないでしょうか。
しかし、実際の利用頻度は高く無く、結果として運用保守コストが増えてしまっただけ…というリスクが存在すると思います。

そこで、今回社内で作成する共通機能はCCoEが別途作成する<span style="background-color:#f0f8ff">**クラウドガイドラインへの準拠を助ける為のツール**</span>と位置づけ、<span style="background-color:#f0f8ff">**共通機能を活用する事で、結果的にガイドラインに準拠出来ている状態を目指す**</span>ものとしました。

そうする事でシステム関係者がガイドラインを守る為に何かをしなければならないという負のイメージではなく、便利な共通機能が出来た、コレを使った方が楽になるね。という正のイメージから共通機能を使って頂き、その結果としてガイドラインに準拠出来る環境を作った方がスムーズなのではないか。
という考え方（仮説）に基づいて共通機能を実装しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734719/9d44eb30-5b52-7040-9bba-05c1a584c16e.png)



# 仕組み
## 概要図
AWS Cognito と EntraID を連携させることで実現しています。
実装においては [コチラ](https://dev.classmethod.jp/articles/using-azure-ad-as-an-external-idp-for-amazon-cognito/) のサイトなどを参考にさせて頂きました。

共通機能としては**認証**部分のみを実装し、**認可**はアプリケーション側で実装する事を想定した構成にしています。
何をもって認可するかのコントロールについてはアプリケーション側の要件に柔軟に対応できるよう、Entraprise App 側のクレーム設定で吸収する形を想定しています。

下記の図は Enterprise App 側のクレーム設定で SecurityGroup の Object ID を連携するように設定し、アプリケーション側がレスポンスで返却された Object ID を元に権限を制御する構成をイメージした図です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734719/a131e7df-f432-0096-b2ca-5429c096c1ce.png)




## 躓いた点
実装において注意すべき制約が存在します。

Enterprise App の仕様として紐づけた SecurityGroup がネストされていると、ネストした 2層目以降のSecurityGroup 直下の Object は Cognito からの認証要求に答えられません。
これは Enterprise App 側の仕様・制約である為連携先が AWS Identity and Access Management であっても変わりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734719/f4e71ef9-f614-4e1b-ef81-1f985e3ba887.png)

この制約の為、EntraID側に既存の SecurityGroup をネストする形では権限付与に利用できず、権限を付与するには対象者を簡単にリストアップ出来る仕組みに加えて、権限付与を楽に出来る手順や仕組みが求められることになります。

## 今後の改善点
EntraIDには動的グループという設定が存在する為これを Enterprise App に紐づけることが出来ないかの調査検証は引き続き実施が必要かなと感じています。
これが出来ると権限管理が楽に出来るようになるのではと考えています。

また、今後のクレーム設定として SecurityGroup の情報ではなく、ユーザのカスタム属性値を返す事で制御をさせるようにしたいと考えています。これはアプリケーション側からの要求に対する柔軟性を高めたい意図があります。



今後も弊社CCoEとしては同様の位置づけの共通機能の実装を複数計画・検討しており、システム開発担当者や運用担当者が楽を出来る、そして結果としてガイドラインにも準拠しているという仕組みの拡充を図って行きます。



# :sunflower:   弊社では一緒に働く仲間を募集中です :sunflower:
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。
https://engineer.po-holdings.co.jp/
闘魂Elixir ーー AtCoder Beginner Contest 338(A)をElixirで楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>


# はじめに

[AtCoder Beginner Contest 338](https://atcoder.jp/contests/abc338)を[Elixir](https://elixir-lang.org/)で解いてみます。

[AtCoder](https://atcoder.jp/)を解くのが趣味で、休憩時間に解いているという若い人がいて、それってすごい意識の高い休憩時間の過ごし方だと思って、私も真似してみることにしました。


# [AtCoderをElixirでやってみる](https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01)

入力の読み取り方や解答の作り方は、別の記事にまとめています。


https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01

ご参照くださいませ。

[Elixir](https://elixir-lang.org/)で[AtCoder](https://atcoder.jp/)を楽しむためには、エントリポイントを`Main.main/0`にする必要があります。つまり`Main`モジュールを作って、その中に`main/0`関数を定義するわけです。

# [A - Capitalized?](https://atcoder.jp/contests/abc338/tasks/abc338_a)

問題はリンク先をご参照くださいませ。
私の解答を貼っておきます。


<details><summary>私の解答</summary>

_問題文を読んでいることを前提にひとこと解説をしておきます。_

[String.capitalize/2](https://hexdocs.pm/elixir/String.html#capitalize/2)関数で、入力文字列をcapitalizeしてみます。そしてその変換後の文字列が元の文字列と一致していれば、capitalizeされている、反対にそうでなければcapitalizeされていないというふうに実装しました。
Charlistにして`?a`や`?z`、`?A`、`?Z`を使って判定することもできます。


```elixir
defmodule Main do
  def main do
    s = IO.read(:line) |> String.trim()
    
    solve(s)
    |> IO.puts()
  end
  
  def solve(s) do
    capitalize_s = String.capitalize(s)
    if s == capitalize_s, do: "Yes", else: "No"
  end
end
```




</details>




---

# さいごに

[AtCoder Beginner Contest 338](https://atcoder.jp/contests/abc338)を[Elixir](https://elixir-lang.org/)で解くことを楽しみました。

あなたのお好きなプログラミング言語でお楽しみください。

---


**闘魂**とは、  **「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
**アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。**

---

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>
<b><font color="red">$\huge{１、２、３ ぁっダァー！}$</font></b>
生声系の動画を自動で文字起こしして、YMM4で編集する方法(完全無料)(カット,字幕,効果音等一般的な編集は全てできます)

# はじめに
普段PremiereProで動画を作成していたのですが、学生が2,3万円のお金を払うのはきつすぎるのでどうにか完全無料で動画を作る方法はないかと模索して個人的に最も使いやすい方法を見つけたので紹介します。カット,字幕,効果音など一般的な編集は全てできます、なんならPremiereProより操作しやすい部分もたくさんあります。テレビ番組のような凝った編集はせずに、一般的な編集だけをするのであればこの方法が一番よいのではないかと思います。
ダビンチリゾルブ等だとシーンチェンジなどの装飾をかけたり、二重縁取りをするのが大変ですが、YMM4だととてつもなく簡単です。

# 動画編集でやること
①YMM4でカット編集をする(字幕等の編集は一切しない)

②カット編集したものをmp4で出力して、Vrewというソフトに投げて文字起こしをしてもらう(Vrewの無料コースのみで編集すると左上にVrewのマークが出ますが、下に書くcsv出力などをするとマークは出てきません)(使い方等はYoutubeを漁るとわかりやすいのがあると思います)
[Vrewのダウンロードリンク(有料のコースは無料コースの制限をオーバーしたら入ればいいです)](https://vrew.voyagerx.com/ja/)

③文字起こしした内容を人力で手直しする(Vrew内でのフォントの設定を一切変える必要はありません、変えても後で全て消えます。手直ししていく上で見やすくするという意味での変更はやるべきです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/4297b308-eb2c-6ca1-5424-c74cda2ecd23.png)


④手直しが終わったら、srtファイルで出力する🐇
![GQWHjYMbMAAbsxK.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/017d10c1-3679-3605-cc35-4fafab12bbbf.jpeg)

⑤そのsrtファイルをYMM4のカットしただけの編集データに投げると、Vrewで用意した字幕がテキストとして生成されている。
※YMM4内でテキストをテンプレートなどで一括変更する方法はわかっていません、変更したいものをまとめて変更して色などを変更することはできますが、たくさんの装飾を施した内容は一個ずつ手作業でやる必要があります。ただ、srtファイルをYMM4に投げる前の段階で、テキストのデフォルト設定をしておけば最初だけ一括で変更できます。

⑥ここからは一般的な編集方法と同じで、字幕の色やサイズ、改行などを個別で修正する
⑦効果音やBGMを入れて音量変更などをする
⑧最後にmp4で出力して完成

# サムネイルでやること
- YMM4で作るだけ
→ 良く使う文字の装飾や、図形などをテンプレートとして登録しておくとサムネイルが高速に作れます。
- オシャレな装飾を施す場合、作成途中のサムネイルを保存して、それをAviutlで編集することになると思います。

# ショートカットキー
YMM4はショートカットキーを自由に設定できるので、乗り換え前の編集ソフトで使用していたショートカットキーと同じような内容に設定することができます。カット編集する上で「ジェットカット」というテクニックのようなものがあるのですが、自分がPremiereProでよく使用していた「前の編集点を再生ヘッドまでリップルトリミング」というショートカットキーは、YMM4だと「削除してレイヤーを左寄せ」というやつと同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/d1eda1c3-03de-f6bc-cca7-0ae97466d6ba.png)


# PremiereProよりもYMM4の方が使いやすい点(愚痴)
- 「字幕の装飾」をテンプレート化はPremiereProでもできるが、そのために「prtextstyle」という拡張子のファイルを編集画面に登録して、なおかつそれを字幕に適応させないといけないので使いにくい。しかしYMM4だと右クリックからすぐに出せる
- 図形のテンプレート化ができる(PremiereProでもできるが、その画面を開くのがめんどくさすぎる。右クリックで出せるYMM4が神)
- 初期状態で編集画面に無駄なものがない(PremiereProだといろんなものがあってどれが必要でどれがいらないのかわかりにくくて邪魔)

# 終わりに
ゆっくり実況を作成したことのある人だと、PremiereProよりもYMM4やAviutlのような編集画面が使いやすいと思うのでそのような人にはかなりおすすめです(一切お金がかかりませんし)。
Excel VBAのスクリプトファイルをSVNで構成管理する

# はじめに
スクリプトを構成管理したいのならExcel VBAを選ぶべきではないかもしれませんが、
そんな、ちょっとお世話しづらいExcel VBAを、
バッチとSVNで履歴をみられるようにした記事です。

## この記事について

<dl>
  <dt>想定読者</dt>
    <dd>Excel VBAでどこを直してきたか忘れてしまう方</dd>
  <dt>記事のゴール</dt>
    <dd>Excel VBAのスクリプトの修正履歴がわかるようになる</dd>
</dl>

# 本文
## 全体像

作成する流れはこんな感じ

1. Excel VBAのスクリプトを出力するバッチを用意します
1. SVNのリポジトリを用意し、バッチとともに配置します
1. Excel VBAを所定のフォルダに集めます
1. バッチを実行
1. SVNで確認

## 作業環境

<dl>
  <dt>環境</dt>
    <dd>OS: Windows 10 Pro</dd>
    <dd>Office 2019</dd>
</dl>

## 実施内容

### 1. Excel VBAのスクリプトを出力するバッチを用意します

第一引数のマクロ付きExcelファイル内のスクリプトを、第二引数のフォルダに書き出すバッチ

``` VB: ExportVBA.vbs
'Excelを起動
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False

'Excelファイルを開く
Set objWorkbook = objExcel.Workbooks.Open(WScript.Arguments(0))

'VBProject内の各ファイルを取得
For Each objVBComponent in objWorkbook.VBProject.VBComponents
    'ファイル名を取得
    strFileName = objVBComponent.Name
    '拡張子決定
    strExtension = ".cls"
    If Left(objVBComponent.Name, 3) = "mod" Then
        strExtension = ".bas"
    End If
    'ファイルの内容を取得
    If objVBComponent.CodeModule.CountOfLines > 0 Then
        strFileContent = objVBComponent.CodeModule.Lines(1, objVBComponent.CodeModule.CountOfLines)
        'テキストファイルに出力
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objFile = objFSO.CreateTextFile(WScript.Arguments(1) & strFileName & strExtension, True)
        objFile.Write(strFileContent)
        objFile.Close
    End If
Next

'Excelファイルを閉じる
objWorkbook.Close False
Set objWorkbook = Nothing
'Excelを終了する
objExcel.Quit
Set objExcel = Nothing
```

`Excel`フォルダに格納したマクロ付きExcelファイルを読み取り、
`VBA`フォルダに書き出すバッチファイル

``` ExportVBA.bat
@ECHO OFF
REM バッチ実行フォルダへ移動
CD /D %~dp0
REM 文字コードをUTF-8に設定
CHCP 65001
REM Excelフォルダ内の全ファイルと同じ名前のフォルダをVBAフォルダ配下に作成
FOR %%f IN (.\Excel\*.xlsm) DO IF NOT EXIST ".\VBA\%%~nf\" MKDIR ".\VBA\%%~nf\"
REM Excelフォルダ内の全ファイルに対してVBAスクリプトをエクスポート
FOR %%f IN (.\Excel\*.xlsm) DO CScript ExportVBA.vbs %~dp0"%%f" ".\VBA\%%~nf\"
```

### 2. SVNのリポジトリを用意し、バッチとともに配置します

SVN管理フォルダを作成し、その中に以下のように資産を配置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762098/3f9ad3d9-aa10-de3b-7bcd-f4101b9238a6.png)

### 3. Excel VBAを所定のフォルダに集めます

`Excel`フォルダ内に対象となるマクロ付きExcelファイルを以下のように配置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762098/c81ff48c-52cf-b82f-897a-fe31d4e8652f.png)

### 4. バッチを実行

ExportVBA.bat をダブルクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762098/de289496-c5ca-c71b-f7d3-0eae8dcfbad2.png)

実行後の`VBA`フォルダの状態

<img width=400 alt="VBAフォルダの状態" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762098/11fd279a-ceec-a2e7-bb82-33afc497d163.png">

### 5. SVNで確認

テキストなので、コミット前にプログラムの修正状況がわかります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762098/1c6e8903-5d60-3991-07cc-1f12d16d3d58.png)

以上。
pgAdmin4でテーブル毎のディスク使用量を見る方法

pgAdmin4でテーブル毎のディスク使用量を見る方法を紹介します。

# 方法
クエリツールで以下のSQLを実行するとテーブル毎のディスク使用量を確認することができます。
```sql
SELECT
     pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
     pg_size_pretty(pg_relation_size(relid)) AS data_size,
     relname
FROM
     pg_catalog.pg_statio_user_tables
ORDER BY
     pg_total_relation_size(relid) DESC;
```
![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/7e440c68-cec1-2e6d-0a14-b2ee713d8662.png)


# 終わりに
データベースとかで無料枠を使用している時に、どのテーブルが容量圧迫してるかわかるので便利ですね。
Pinia: Vue.js アプリケーションのためのステート管理ライブラリ

### 概要
Pinia は、Vue.js アプリケーションのステート管理をしてくれるライブラリです。従来の Vuex に比べてシンプルになったみたいですので、この記事では、Pinia の導入とステート管理の基本について解説します。

### 1. Pinia のインストール

まず、Pinia をプロジェクトにインストールします。

```bash
npm install pinia
```

### 2. Pinia の初期化

次に、Pinia を Vue アプリケーションに初期化します。

```javascript
import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';

const app = createApp(App);
app.use(createPinia());
app.mount('#app');
```

このコードでは、`createPinia` 関数を使用して Pinia インスタンスを作成し、`use` メソッドを使用して Vue アプリケーションに登録しています。

### 3. ストアの作成

Pinia を使用してステートを管理するには、ストアを作成する必要があります。ストアは、アプリケーションのデータとロジックをカプセル化するオブジェクトです。

```typescript
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    }
  }
})
```

このコードでは、`defineStore` 関数を使用して `counter` という名前のストアを作成します。ストアには、`state`と`getters` と `actions` が含まれます。

* `state`: ストアに格納されるデータ
* `getters`: state のデータを基に、計算されたプロパティを作成するために使用
* `actions`: ストア内のデータを変更する関数

### 4. ストアの使用

ストアは、Vue コンポーネントからアクセスできます。

```vue
<script setup>
import { useCounterStore } from '../stores/counter'
import { computed } from 'vue'

const counterStore = useCounterStore()
const count = computed(() => counterStore.count)
const doubleCount = computed(() => counterStore.doubleCount)
const increment = () => counterStore.increment()
</script>

<template>
  <div>
    <p>カウント: {{ count }}</p>
    <p>2 倍のカウント: {{ doubleCount }}</p>
    <button @click="increment">カウント</button>
  </div>
</template>
```

このコードでは、`useCounterStore` 関数を使用してストアにアクセスし、`count` プロパティと `increment` メソッドを定義しています。`computed` は、`count` プロパティの変化に応じて自動的に更新される計算プロパティを作成します。

### まとめ

vuexはまだ使えますが今後新しい機能は提供されないみたいなので、piniaを扱い方を学習してみました。
シンプルでわかりやすい点やCompositionAPI、typeScriptなどとも互換性があるため扱いやすかったです。
【Windows Form】プログラム実行ファイルのリリース前のチェックリスト

以下はプログラムの実行ファイルを提出するときに個人的にチェックしているリストです。インストールがあったりいろいろ違う時もありますが。

Webでもスマホのアプリケーションでもなく、パソコンのソフトウェアのことが多いです。
（開発環境はC＃の.Net FlameworkのWindows Form）

# プログラムのリリース前チェックリスト
- アイコン置き換えた？
- 警告はちゃんと消し飛ばしたか？
- いったん設定ファイルを消して新規起動しても問題ないか？
- ダイアログは（必要がない場合は）Fixedになっているか？
- タブオーダーは正しいか？
- 改造の場合、バージョンtxtは更新する必要があるか？　あるなら更新したか？
- バージョン情報は書き換えたか？　番号を増やす必要はあるか？

# 項目の解説


## アイコン置き換えた？（特に初回）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/cb4d9762-b6c0-237d-c6e8-8ce5e912460a.png)

メイン画面のアイコンのところと、あと、プログラム自体のアイコンもプロパティで設定する必要があります。
どれか忘れがちです。
タスクバー常駐ならタスクバーのアイコンも設定しましょうね。

## 警告はちゃんと消し飛ばしたか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/f7f8894f-7754-b3fb-3b9c-2d9732ea77a9.png)

よく古い型を使用しているとかもうすぐ廃止するとかそういう警告がよく出ます。
警告はなるべく消し飛ばしたほうがいいです。

## いったん設定ファイルを消して新規起動しても問題ないか？（必要な場合は最低限の設定情報を同梱する）

デバッグ時は動いているので見逃しがちです。

## ダイアログアプリケーションは（必要がない場合は）Fixedになっているか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/7d8ed650-2a33-7138-2c33-a4ed2ca71894.png)

パッと作ったアプリでは忘れがちなんですがウィンドウを伸び縮みさせるのに対応する意味がない場合ぱぱっとFixにしておいたほうがいいです。

## タブオーダーは正しいか？

Tabキーを押すとコントローラー間を行き来することができます（Shift＋Tabで逆回り）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/006f1a62-9786-0f90-8516-8b377497fd36.png)

キーボードだけで操作する場合大変便利ですが、タブの順番を設定する必要があります。

(VisualStudioだとAlt+D)

コントロールの追加時も注意です。

## バージョン情報は書き換えたか？　番号を増やす必要はあるか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/2ff003a4-904c-b9af-12b2-ed54bd25acbd.png)

結構忘れがちですが、バージョン情報を更新する必要があります。
プロジェクトのプロパティの、アセンブリ情報から設定します。

一つのプロジェクトに複数のソリューションが登録されている場合はバージョン情報が分かれているので、ちゃんと狙ったものバージョン情報を書き換えましょう。
indesignからYahooのAPIを叩く(win版)

## まえがき


Yahoo!デベロッパーネットワークが提供しているAPIが、indesign上でも動作するぞ！という噂を聞きました。


ですが、調べてみた限りネット上で紹介されている方法がMacのものばかりだったので、windowsで動作するよう関数を作成してみました。


Mac版のスクリプトとの違いはAppleScriptの代わりにVBSを利用するところのみなので、詳しい解説や使い方は他の方のブログや記事などを参考にしてください。


ざっくりとした処理の流れは、

1. 変数に処理を書き込む
2. doscriptメソッドでVBSを実行
3. WinHttpからYahooAPIにPOSTリクエストを送る
4. 結果を取得して返す

のような形です。

## 動作環境
・Indesign 18.064/17.064　で動作確認済み


## サンプルコード

```js:useApiTest.js
   function httpRequest(input) {
	var result = "";
	var myinput = input;
	var vbs = "";
	vbs += "Public s\r";
	vbs += 'Dim http: Set http = CreateObject("WinHttp.WinHttpRequest.5.1")\r';
	vbs += 'Dim url: url = "https://jlp.yahooapis.jp/FuriganaService/V2/furigana"\r';
	vbs +=
		'Dim data : data = "{ ""id"": ""1234-1"", ""jsonrpc"": ""2.0"", ""method"": ""jlp.furiganaservice.furigana"", ""params"": { ""q"": ""' +
		myinput +
		'"", ""grade"": ""1"" } }"\r';
	vbs += "With http\r";
	vbs += '.Open "POST", url, False\r';
	vbs += '.SetRequestHeader "Content-Type", "application/json"\r';
	vbs += '.SetRequestHeader "User-Agent" , "Yahoo AppID: あなたの取得したYahoo AppID"\r';
	vbs += ".Send data\r";
	vbs += "End With\r";
	vbs += "s = http.ResponseText\r";
	vbs += 'Set objInDesign = CreateObject("InDesign.Application")\r';
	vbs += 'objInDesign.ScriptArgs.SetValue "http_data", s\r';
	app.doScript(vbs, ScriptLanguage.VISUAL_BASIC, undefined, UndoModes.FAST_ENTIRE_SCRIPT);
	result = app.scriptArgs.getValue("http_data");
	app.scriptArgs.clear();
	return result;
}

alert(httpRequest("漢字混じりの文字列からふりがなを取得します。"));

```
Yahoo!デベロッパーネットワークでClient IDを取得してきて、上記コードの`あなたの取得したYahoo AppID`の部分を置き換えるだけで動作すると思います。

あとはレスポンスを加工してよしなにしてください。


## 注意点
:::note warn 
ESDebuggerでスクリプトを実行した際に「エンジンのxml が無効です」のメッセージが表示されたり、Indesign上で実行したときに何も結果が表示されないなど、うまく動作しないことがあります。
:::

その場合は、以下の手順を実行して「`Resources for Visual Basic.tlb`」を再作成することでうまく動作するようになるかもしれません。

#### 手順
1. 次のディレクトリに移動する
: C:\ProgramData\Adobe\InDesign\Version XX.X\xx_XX\Scripting Support\XX.X (または tlb ファイルが配置されている場所)
2. ファイル「Resources for Visual Basic.tlb」を削除する
3. Indesignを管理者権限で起動する

以上
    





# 参考サイト

APIドキュメント

https://developer.yahoo.co.jp/webapi/jlp/furigana/v2/furigana.html

諸々の仕様の参考にさせて頂いたサイト

https://uske-s.hatenablog.com/entry/2021/10/24/201059
XunziALLMは「不入虎穴不得虎子」の続きをどう生成するのか

『[Overview of EvaHan2024: The First International Evaluation on Ancient Chinese Sentence Segmentation and Punctuation](https://aclanthology.org/2024.lt4hala-1.27)』を横目に、[XunziALLM](https://github.com/Xunzi-LLM-of-Chinese-classics/XunziALLM)で漢文(古典中国語)の生成を試してみた。Google Colaboratory (GPU版)だと、こんな感じ。

```
!pip install transformers accelerate transformers_stream_generator einops tiktoken
from transformers import AutoTokenizer,AutoModelForCausalLM
d="ccwu0918/XunziALLM"
tkz=AutoTokenizer.from_pretrained(d,trust_remote_code=True)
mdl=AutoModelForCausalLM.from_pretrained(d,trust_remote_code=True,device_map="auto")
inp=tkz("不入虎穴不得虎子",return_tensors="pt").to(mdl.device)
doc=tkz.decode(mdl.generate(**inp)[0])
print(doc)
```

私(安岡孝一)の手元では、以下の文が生成された。

> 不入虎穴不得虎子今入闗中不拔金人不北兵行则民心危不进则敌势盛进则可与敌战不进则吾欲战不可得而金人深入吾腹心故必欲灭之使吾重得择利之所在则吾欲战之志一发而不可遏其计也况河北人心未服者犹未肯附于我盖彼见吾入敌境则必深疑且惧而叛去之必多矣且金人之欲内属者皆未去尔今敌既得利复欲内属吾又欲招之恐敌势益盛入吾境内吾复取利使彼不得复如其故是以沮之若使敌之无利吾又且欲招之使其人皆复其故则吾得师众之势众虽骄且惰尚可制也况今众皆骄惰欲使之为吾用难矣今来有建康之师既不入闗中则敌势益重吾欲收民之心安未可知今又以师南来恐民之见吾入敌境将无反吾之心故曰师不入敌境则无以收民心也况今敌已有隙将入吾境则吾欲与之战则必败而失士心若不与之战则敌势益盛乃日月不进退之无策是以战也惟上速与之战以收民心耳今敌既入吾境内是无益于吾而反有害于吾矣今又以师来南是师老而气衰无益于吾而反有害于吾也且兵有进退有险有阻吾兵既入敌境则我所恃以为险阻者皆空虚而敌可以乗虚而入矣是以师老气衰是进退无策者也故今必欲战乃无大害也今吾之众巳复淮河之险复旧有州县不为无益矣然敌复据淮西则吾气衰而无险阻吾复淮西亦无益于吾而反有害于吾也况今吾军士不精而胜败未可知彼能安肯来战哉此师之不进战无益于吾而反有害于吾也故今当战以收民心又以无损于吾而反有益于吾也故曰不战则

漢文風ではあるものの、「不入虎穴不得虎子」の続きに「当今之計独有因夜以火攻虜」が生成されたりしないようだ。しかも、簡化字の中に「闗」が紛れ込んでたりして、かなり読みにくい。というか読めない。試しに句読点を追加すると、どうなるだろう。

```
inp=tkz("不入虎穴、不得虎子。",return_tensors="pt").to(mdl.device)
doc=tkz.decode(mdl.generate(**inp)[0])
print(doc)
```

> 不入虎穴、不得虎子。昨與南嶽相公同在。丞相府。見丞相在御前。出一老僧骨塔。云：「昨夜臨安城中。有一和尚。身長丈餘。目能旋日月。手能轉乾坤。昨夜投宿山中。為鬼神所殺。遺骨塔在此。」南嶽公曰：「向者。何以處之？」丞相曰：「老僧惡知有甚鬼神。亦不見有甚和尚。」令丞相心未信。南嶽曰：「君無道事。恐是觀音大士。」丞相曰：「觀音大士。復何事。人間那得有如此和尚。」南嶽公曰：「南嶽本山。亦有如是之相。此是正教。且住一時。待觀其事。」南嶽公既還山。訪北嶽相公。具道其事。北嶽曰：「只如。丞相尚不見信。似我等小僧。何由得信。」南嶽曰：「向者丞相既不見信。如何處置。」北嶽曰：「待八月十五日中秋。只許有一輪滿月。和尚入宮。則知信否。」南嶽公即令小僧。望北祝聖曰：「和尚既是正教。何必夜入人家。特為人害。只願待月圓之夜。更增人世平安。早得一僧。與之講說。庶不寂寞。」語未畢。有一僧前問曰：「師有甚話。與小僧講說。」小僧具述南嶽之意。僧曰：「我與南嶽相公。亦有宿緣。待至中秋。吾當入山。與南岳講說。」時北嶽公問南嶽曰：「待和尚入宮。我等何時得進見。」南嶽曰：「待月圓。」南嶽既不信有和尚。待八月十五夜。往觀。果然見那大相公進宮。正得東宮夜臥。寺僧相待。在彼行道。如南嶽不應與同寺僧。

うーむ、全く別の話に変わってしまった。まあ、実行するたびに違う文が生成されるので、こういうものなのかな。
AWS EC2の削除

【備忘録】AWSでEC2を削除する方法

・AWSコンソールを開いてサービスメニューからEC2を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818601/83d6745a-9080-ac9f-60f5-c01f3644dd20.png)

・AWSコンソールの左側に表示されるメニューから「インスタンス」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818601/c738de52-9595-1bb9-12a7-df9105ab70f2.png)

・表示されたインスタンスの一覧から、削除したいEC2をチェックし、
　「インスタンスの状態」のプルダウンを展開し、「インスタンスの終了」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818601/e471c7ee-5b21-1e8c-363a-9fcfec60346f.png)


・削除処理が実行される。数分して「インスタンスの状態」列が「終了済み」になればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818601/2f89e5f8-0a21-5367-b67d-cf74fe8df06b.png)

※※　注意　※※
インスタンス一覧から削除したEC2が表示されなくなるまでは数日かかります。
ROS2のtf_transformationを使っているモジュールで、'Installing the transforms3d library by hand required. ...' と言われた時

2時間くらいハマったので備忘録を残しておきます。
同じエラーで苦しんでいる人が少しでも減りますように。

# TL; DR
transforms3dのバージョンを0.4.1以前にしてみてください。
もしくは、下記サイトの解決法を試してみてください。

https://natsutan.hatenablog.com/entry/2024/06/05/090256

# 概要
本日(2024/6/18)、ROS2のtf_tranformationsを使っているモジュールにて、突然下記エラーが出ました。
```bash
Installing the transforms3d library by hand required. Please run
	sudo pip3 install transforms3d
```

原因を色々探ってみたところ、[6/17にtransforms3dのバージョンが0.4.2に上がっていたことが判明。](https://pypi.org/project/transforms3d/#history
)


0.4.1に戻してみたところ、無事にエラーを解消できました。

```bash
pip3 install 'transforms3d==0.4.1'
```
# hoge
2年ぶりのアップデートに引っかかるとは、、、
構成管理はちゃんとしようと思いました。
DeSmuMEで組み込まれているLua用API　非公式リファレンス　～stylusライブラリ～

この記事はニンテンドーDS向けエミュレータの一つである「DeSmuME」（以降Desmume）のLua用APIの非公式日本語リファレンスです。今回はstylusライブラリについてのリファレンスです。

:::note warn
このリファレンスは非公式の日本語リファレンスです。そもそも英語のリファレンスも公式のリファレンスもありません。
さらに詳細の仕様を確認したい場合はDesmumeのソースコードを参照することを推奨します。
→https://github.com/TASEmulators/desmume/blob/master/desmume/src/lua-engine.cpp
:::

---

`stylus.get()`
タッチ操作のX座標Y座標とタッチしていたかを取得する。（1F前の情報）


<details><summary>引数</summary>

無し　nil

</details>

<details><summary>戻り値</summary>

`table`型
<キー>
[x]:X座標　`int`型
[y]:Y座標　`int`型
[touch]:タッチの有無　`boolean`型

</details>

``` lua: example.lua
local function Fn()
local table = {}

table = stylus.get()

if table.touch then

gui.text(0,10,"X: "..table.x)
gui.text(0,20,"Y: "..table.y)

end

end
gui.register(Fn)
```

---

`stylus.peek()`
現在のタッチ操作のX座標Y座標とタッチしているかを取得する。

<details><summary>引数</summary>

無し　nil

</details>

<details><summary>戻り値</summary>

`table`型
<キー>
[x]:X座標　`int`型
[y]:Y座標　`int`型
[touch]:タッチの有無　`boolean`型

</details>

``` lua: example.lua
local function Fn()
local table = {}

table = stylus.peek()

if table.touch then

gui.text(0,10,"X: "..table.x)
gui.text(0,20,"Y: "..table.y)

end

end
gui.register(Fn)

```
:::note info
現在情報なので一時停止中でもとにかく取得します。
:::

---

`sylus.set()`

<details><summary>引数</summary>

第一引数　操作内容
`table`型
<キー>
[x]:X座標　`int`型
[y]:Y座標　`int`型
[touch]:タッチの有無　`boolean`型

</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
local table = {}

table.x = 100
table.y = 100
table.touch = true

stylus.set(table)
```
:::note alert
実際に使う際にはemu.registerbefore()で呼び出すかemu.registerboundary()で呼び出さないと描画が更新されずにdesyncする。
サンプルコードは一回切りのコードで、なおかつframe advance操作を行っていない。これはあくまでも動作確認用コード
:::

---

代替名一覧
以下の関数でコードを書いても右側の関数として認識されます。
`stylus.read()`→`stylus.get()`
`stylus.write()`→`stylus.set()`
Note

すぐ確認できるように、ここにまとめておきます（ほぼ自分用）。
## CPUアーキテクチャについて
```
CISC(Complex Instruction Set Computer)
   └── x86，x86-64（x64またはamd64と呼ばれることも）
        └── Intel社
              └── Xeon、Core、Pentium、Celeronなど
        └── AMD社
              └── Ryzen、Athlon、Optelonなど

RISC(Reduced Instruction Set Computer) 
   └── arm
        └── ARM社
              └── ARMv7(32bit)
              └── ARMv8
                    └── AArch32(32bit)（LinuxではAArch32をarmと表記）
                    └── AArch64(64bit)（LinuxではAArch64をarm64と表記）
   └── RISC-V
        └── カリフォルニア大学バークレー校
```
参考：https://qiita.com/rihib/items/6b70361b48c3840d09b0https://qiita.com/rihib/items/6b70361b48c3840d09b0
laravelで過去漏洩パスワードのバリデーションをかける

【前置き】
PwnedPasswordsというらしいですが、過去漏洩した記録を基に
入力した新しいパスワードを辞書索引し、
一致したらバリデーションとしてエラーを返し再入力を求めるというもの。
使っているLaravelのバージョンは6。

参考にした記事[Laravel de パスワードチェッカー](https://qiita.com/kyoya0819/items/3637cd4d0e7c5d48bb23)ではAPIで最新のデータと照合かけるみたいですが、なぜかあんまり精度が高くなく、[Pwned Passwords Validator for Laravel](https://github.com/valorin/pwned-validator)も同じく精度が低くセキュリティ的に通らなさそうなんでテストされるとわかってるjsonデータを元に対応。


#### 独自バリデーションルールをつくる

```cmd:cmd
> php artisan make:rule SafePassword
```
```php:app\Rules\SafePassword.php
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class SafePassword implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        //
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The validation error message.';
    }
}

```


#### pwnedPass json読みこんで、パスワードと一致したらfalseを返す

jsonはpublicの/json/に配置した。

```php:app\Rules\SafePassword.phpのpasses()の中
        $json_path = public_path()."/json/PwnedPasswords.json";
        $json = file_get_contents($json_path);
        $json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $json = json_decode($json, true);

        if (in_array($value, $json)) {
          return false;
        }
        return true;
```

```php:app\http\Controllers/ChangePasswordController.phpのvalidator()の中
    return Validator::make($data,[
            'new_password' => ['required', 'confirmed', 'min:8','max:72', new SafePassword]
        ]);
    }
```


```PwnedPasswords.json
    [
        "123456",
    	"123456789",
    	"qwerty",
    ]
```
jsonは多すぎるから割愛
https://www.ncsc.gov.uk/static-assets/documents/PwnedPasswordsTop100k.txt
ブラウザでChrome拡張機能のソースコードを確認する

ブラウザでChrome拡張機能のソースコードを確認する方法を紹介します。

## 手順
私が作成した、Chrome拡張機能[Google Scholar ダークモード](https://chromewebstore.google.com/detail/google-scholar-%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89/jplmbheenbhcoihdheoeipfdnamlodbm)を実験台にして説明します。

まず、Chrome拡張機能のページを開きます。拡張機能のURLを取得します。
[crxviewer](https://robwu.nl/crxviewer/)というツールを使用して、拡張機能のソースコードを確認します。

https://robwu.nl/crxviewer/

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/40506077-25ce-98db-c381-78de245fae7e.png)

先ほど取得したURLを入力し、`Open in this viewer`ボタンをクリックします。

すると解析が始まり、拡張機能のソースコードが表示されます。

![スクリーンショット2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/6a7cb464-a4b3-9ed7-d650-600f3533cf18.png)

ちなみにダウンロードも可能です。

![スクリーンショット3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/fd1fd0c3-7617-8895-ccd5-9a4a8fedc723.png)

## まとめ
WebpackやBabelなどのビルドツールを使用していない場合、Chrome拡張機能のソースコードを確認することができます。ただし、ビルドツールを使用している場合は、ソースコードが難読化されていることがあります。
cakephp環境構築

````												
1	バージョン確認						'							
	php -v													
	composer -V													
	mysql --version													
														
2	php.ini下記全てコメントアウトを外す													
	extension=curl													
	extension=php_intl.dll 													
	extension=openssl													
	extension=pdo_mysql													
	extension=pdo_odbc													
	extension=pdo_pgsql													
	extension=pdo_sqlite													
														
3	自作のパスに移動													
	cd C:\cakephp													
	cakephpのプロジェクトを作成													
	composer self-update && composer create-project --prefer-dist cakephp/app:"4.*" CakeBlog													
	Set Folder Permissions ? (Default to Y) [Y,n]? y													
														
4	開発サーバ起動													
	cd CakeBlog
 
    サーバ起動
	bin\cake server			注意　windowsの場合、/ ではない。
    サーバ停止
    cstr c
    
	http://localhost:8765/				動作確認									
														
	vscode 起動													
	code ./													
 
    db
	bin\cake migrations migrate
														
														
5	app 設定													
	config/.env.example  コピー  .env作成												
	.envは以下に設定する													
														
	export APP_NAME="CakeBlog"													
	export DEBUG="true"													
	export APP_ENCODING="UTF-8"													
	export APP_DEFAULT_LOCALE="ja_JP"													
	export APP_DEFAULT_TIMEZONE="Asia/Tokyo"													
	export SECURITY_SALT="sdfsfdewe568998"						←任意入力							
														
6	.env読み込みような設定													
	config/bootstrap.php													
	下記コメントアウト外す													
	// if (!env('APP_NAME') && file_exists(CONFIG . '.env')) {													
	//     $dotenv = new \josegonzalez\Dotenv\Loader([CONFIG . '.env']);													
	//     $dotenv->parse()													
	//         ->putenv()													
	//         ->toEnv()													
	//         ->toServer();													
	// }													
														
7	db 設定
    1⃣
    coonfig/app.php コピー  app_local.php作成
    
    2⃣
    app_local.php
	一番上に下記一行追加													
	use Cake\Database\Driver\Mysql;	

    3⃣
	Datasources'以下ように設定
 
    'driver' => Mysql::class,													
    'host' => 'localhost',													
    'username' => 'root',													
    'password' => 'test',													
    'database' => 'cakedb',
Electron プロセス間通信学習ログ

Electronにはプロセス間通信というものがあります。
そのプロセス間通信が少しややこしかったので図にして学習した記録を載せます。

- [プロセス間通信(片方向)](#プロセス間通信片方向)
- [プロセス間通信(双方向)](#プロセス間通信双方向)


# プロセス間通信(片方向)
https://www.electronjs.org/ja/docs/latest/tutorial/ipc#パターン-1-レンダラーからメインへ-片方向

IPC：あいぴーしー：interprocess communication：動作中のプログラムの間でデータの交換をすること：プロセス間通信

`ipcRenderer.send`と`ipcMain.on`を使用して実現する

```js:main.js
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
 
function createWindow () {
   const mainWindow = new BrowserWindow({
     webPreferences: {
       preload: path.join(__dirname, 'preload.js');
     }
   })
   mainWindow.loadFile('index.html');
}
 
app.whenReady().then(() => {
   ipcMain.on('say-hello', (event, hello) => console.log(hello));
   createWindow();
});
```

```js:preload.js
const { contextBridge, ipcRenderer } = require('electron')
 
contextBridge.exposeInMainWorld('electronAPI', {
    seyHello: (hello) => ipcRenderer.send('say-hello', hello);
});
```

```html:index.html
<html>
 	<script>
 		window.electronAPI.sayHello("hello");
 	</script>
</html> 
```

![e82c527c1f10f9de06472bfe02ec7263.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/28cb4f5b-1583-7cf2-6de6-19ba045bde6c.png)

# プロセス間通信(双方向)

https://www.electronjs.org/ja/docs/latest/tutorial/ipc#パターン-2-レンダラーからメインへ-双方向

`ipcRenderer.invoke`と`ipcMain.handle`を対にして使うことで実現

```js:main.js
const {app, BrowserWindow, ipcMain, dialog} = require('electron')
const path = require('path')
 
async function handleYourName() {
   return "Taki Tachibana"
}
 
function createWindow () {
   const mainWindow = new BrowserWindow({
     webPreferences: {
       preload: path.join(__dirname, 'preload.js')
     }
   })
   mainWindow.loadFile('index.html')
}
 
app.whenReady().then(() => {
   ipcMain.handle('whats:yourname', handleYourName)
   createWindow()
})
```

```js:preload.js
const { contextBridge, ipcRenderer } = require('electron')
 
contextBridge.exposeInMainWorld('electronAPI',{
   yourName: () => ipcRenderer.invoke('whats:yourName')
})
```

```html:index.html
<html>
 	<script>
 		const yourName = await window.electronAPI.yourName()
      	console.log("I'm Mitsuha Miyamizu your name:" + yourName);
 	</script>
</html>
```

![055949ec096e7b46dbbf8ca25adcf1ad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/4204945c-f81f-5ec4-0af0-6f42edf27822.png)
【TypeScript】実はクロージャ外で型ガードしてもクロージャ内部では型判定の結果が無効化されていた

# 問題！！

以下コードを実行すると何が出るでしょうか！？

```tsx
function getUrls(url: string | URL, names: string[]) {
    if (typeof url === "string") {
        url = new URL(url);
    }

    return names.map(name => {
        url.searchParams.set("name", name)
        return url.toString();
    });
}

console.log(getUrls("http://localhost:8080", ["test"]))
```

## 答え！！

クロージャ内で引数urlの型が分からないのにURL型のメソッドを使おうとしてエラーになります。

つまり型判定の結果が無効化されちゃっています…..

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500157/47e12df7-8ad0-0df0-1628-ae2b251ea769.png)


# でもバージョン5.4から！！！

バージョン5.4からクロージャ内部に対して型判定の結果が有効化されるようになりました。

ちゃんと正常に表示されます！！

```tsx
["http://localhost:8080/?name=test"]
```

TypeScript Playgroundからもエラーが表示されていません！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500157/e119a775-d9ca-16f7-277b-0a8eb4cc5401.png)


# 参考文献

https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/
古いAPIバージョンの廃止の驚くべき事実。


少々騙されてきた感じですね。

Salesforce Agile AcceleratorのApexが古いので大丈夫かと言う質問

+ [Salesforce Platform API バージョン 21.0 ～ 30.0 の廃止](https://help.salesforce.com/s/articleView?id=000389618&type=1)

+ [Upgrade plans for package with salesforce legacy API versions being retired?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cm9ScSAI)


調べてみると...

+ [Agile Accelarator has some very old API versions (eg many are API v 11)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000C5NVJSA3)

>Short answer: not possible 
There's also probably no merit in updating those classes.  Apex Classes are not affected by Salesforce's recent announcement to deprecate older API Version - should this be your moviation

短い答え: 不可能です
また、これらのクラスを更新するメリットもおそらくありません。 **Apex クラスは、古い API バージョンを廃止するという Salesforce の最近の発表の影響を受けません** - これがあなたの希望であれば

**ええ、APIのバージョンってApexクラスには関係ないの？**


>Agile Accelerator is not officially supported and is not updated very often.   When my team does update it we do update the API versions of the meta data that is modified.  However the good news is the API version deprecation only applies to API connections you make between your Salesforce Org and other systems. It does not apply to meta-data inside the org. I can see how it it is confusing for customers but if you take a closer look at this link: https://help.salesforce.com/articleView?id=000351312&type=1&mode=1 you will see this line: **"This retirement does not include Custom Apex REST & SOAP Web Services, Apex Classes, Apex Triggers, or Visualforce Pages."**


Agile Accelerator は正式にはサポートされておらず、あまり頻繁には更新されません。   

私のチームが更新する場合は、変更されたメタデータの API バージョンも更新します。  ただし、幸いなことに、API バージョンの非推奨は、**Salesforce 組織と他のシステム間で作成する API 接続にのみ適用されるということです。** 組織内のメタデータには適用されません。顧客にとって混乱を招くのはわかりますが、このリンク https://help.salesforce.com/articleView?id=000351312&type=1&mode=1 をよく見てみると、


**次の行が表示されます。カスタム Apex REST および SOAP Web サービス、Apex クラス、Apex トリガー、または Visualforce ページは含まれません。**


カスタム Apex REST および SOAP Web サービスも関係ないの？
Auraコンポーネントはどうなんだろうね。

# 質問 & 回答例

+ [We have a couple of Visualforce pages that are in the API set that Salesforce is retiring.  RelationshipsSettings and RelationshipsViewer are at version 23.0.  They are in the npe4 namespace.  Is this something we need to be concerned about?](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Ke4qQ0AR)
モチベーション

前回の問題解決しました。
[前回の記事](https://qiita.com/suzukidog/items/c4bd6b785b09a18fef1b)

---
webエンジニアになると決めた時より最近はモチベーションが落ちています…。
これが季節の変わり目による時期的なものであればよいのですが、そうでなくこのまま落ちていくようでは困ります。
それと同時に「本当に俺がwebエンジニアになってやっていけるのか？」という不安も出てきています。

プログラミングが好きで好きでたまらない人間になりてーーーーーーーーーーーーー！！
時間のなやみ

## 時間が足りない
日々時間に追われている方々は多くいると思います。かくいう私も、なかなか時間がとれず、読みたい本も積んどく状態。このままでよいのか、と思い悩むときがよくあります。

## 何に時間が奪われているのか
多くは「仕事」。兼務、タスクの嵐。
嵐が終われば、お家で家事育児。気づくと24時。
睡眠時間は最低6時間、できれば7時間確保したい。
どれも時間も効率化・時間を削るは一朝一夕じゃできそうにありません。

## どう時間を捻出するか
こんな状況が何年か続き、ふと思いました。仕事がお勉強にできればよいのでは。
幸い我が社（我が部）では、業務の支障のない範囲で業務中に勉強も認められています。これを活用すべきかと思い、チーム4人で週次の勉強会を始めました。
この時間に勉強の成果をシェアできると理想ですが、現実は甘くありません。
アウトプットがないときは、この時間を「もくもく会」にして、勉強の時間にあててもよいかと思います。

もくもく会のやりかたも勉強せねば。。。日々勉強です。

## まとめ
- 日々忙しいですが、自分の人生に自分の成長はとっても大事。
- 日々のタスクが削れないなら、腐らずタスクを成長につなげる努力をする。
- こういうチャンスがあることに感謝。