OmniAICreator/Qiita-1.07M huggingface dataset:
(ベンチマーク)STM32H743(480MHz)で素数を求める3...100まで(理系フリマ入手)


x 理系フリマ831にあるよ

目的
素数を求めて時間を測って遊ぶ
2から開始しする
割るのは、2からn-1まで割る
ちゃんと割ってあまりを求める
z = x / y
a = x - ( z * y )

いろいろ
Arduino UNOより速い
逆に速いのか遅いのかわからん
32ビット480MHz

結果

![o_coq320.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/998e4f3a-3828-8502-8afc-ee93449fd83f.jpeg)



![o_coq321.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a025b8be-9fce-e8e5-460b-e6bc5e4b70d9.jpeg)

「理系フリマ」で入手

![o_coq322.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b4777347-6a11-946e-00c1-c70480280222.jpeg)


プログラム


```c++


//souu_H743ZI2_1


void setup() {

  Serial.begin(9600);

}//setup

void loop() {

  int s[100];
  for (int ii = 0; ii < 100; ii++) {
    s[ii] = 0;
  }//for

  unsigned long time;

  int a=1;//work

  int pp = 0;
  //s[pp++] = 1;//debug
  //s[pp++] = 2;//debug
  Serial.println("START>>");
  time = millis();

  for (int ii = 2; ii < (100 + 1); ii++) {

    //Serial.print('(');  //debug
    //Serial.print(ii);   //debug
    //Serial.print(')');  //debug
    //Serial.println();   //debug

    for (int jj = 2; jj < (ii); jj++) {

      //Serial.print('['); //debug
      //Serial.print(jj);  //debug
      //Serial.print(']'); //debug

      a = ii / jj;
      a = ii - (a * jj);
      if ( a == 0) {
        //Serial.print('*');//debug
        break;
      }//if

    }//for
    if (a != 0) {
      //Serial.print('@');
      s[pp++] = ii;
    }
    //Serial.println();//debug
  }//for

  time = millis() - time;
  Serial.print("millis=");
  Serial.println((int)time);

  int yy = 0;
  while (s[yy] != 0) {
    Serial.print(s[yy]);
    Serial.print(',');
    yy++;
  }//while
  Serial.println();

  Serial.println("<<END");
  delay(3000);
  //while (1) {} //debug
}//loop


```
Microsoft Copilot(旧M365 Chat)で直近のあらゆる情報が確認できるようになってる

# Micorosoft Copilotがプチ進化してた
webからも、Edgeからも、Teamsからもアクセス可能なMicrosoft Copilot。
普段は会議、資料、人、メール等の検索ができるなんでも屋さんですが、ちょっと進化していました。7月の更新アップデート分だったみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/75e26c6e-fd54-71dd-74be-8598dc827094.png)

# 「最新の状況の確認」の追加
あれ、こんなのあったっけ。押してみると最近触ったり、かかわったことのある資料や会議がずらずらっと出てきます。
昨日と今日の様子しかみていませんが、直近でかかわった資料とこれから予定のある会議や終わったばかりの会議がレコメンドされるようです。
レコメンドは手動では更新できず…しばらくは固定で表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/51c55c68-fa86-8ad3-9464-33ea1fd3a740.png)

## 「このファイルは何ですか？」
こちらは、最近共有されたり編集されたドキュメントがレコメンドされます。
あープロンプト一個なのか～と思っていたら、いくつかデフォルトプロンプトがサジェスチョンされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/87e72488-724b-3d41-43a1-edd4dae14ee8.png)

そのまま「このファイルは何ですか？」を押してみたとことろ、「XXの要点を箇条書きしてください」のプロンプトが投稿され、いつも通りの資料要約が行われました。ワンタッチでできるのはいいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/92f951a9-568b-7092-2310-ab295497fc34.png)

## 「会議の準備を手伝う」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/ae733424-2b11-dabc-2902-2f3958339034.png)
※記事書いているうちに私のレコメンドから消えたのでイメージ図を下記MSサイトから引用

https://prod.support.services.microsoft.com/ja-jp/topic/copilot-for-microsoft-365-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%81%99%E3%81%B0%E3%82%84%E3%81%8F%E6%9C%80%E6%96%B0%E3%81%AE%E7%8A%B6%E6%B3%81%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B-cffb11c2-bb06-4d5b-bd4b-9497895daff3

これから予定している会議に関わる資料や、会議の名前やキーワード、メンバーから導き出した資料を引っ張って勝手にいろいろおせっかいしてくれます。
その会議で実際使っていない資料も勝手に引っ張ってきてくれます。取捨選択はあなた次第…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/a98f9953-4610-e25d-e49e-f605c89895bb.png)

## 「会議の要約」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/26dbacef-6258-b5af-1baf-f325999048be.png)

※こちらも私のレコメンドから消えたのでイメージ図をまたMSサイトから引用

こちらも参加できなかった会議の要約をワンタッチでできます。便利だね。
LaravelとSeleniumを使用してDocker環境を構築してみた

こんばんは。

今日は「LaravelとSeleniumを使用してDocker環境を構築する方法」について説明します。

LaravelとSeleniumを使用してDocker環境を構築するプロセスにはいくつかのステップが含まれます。このプロセスは、Dockerfileとdocker-compose.ymlファイルを作成して、SeleniumサーバーとLaravelアプリケーションをコンテナ化することを中心に進行します。

以下はその基本的な手順です：

# Dockerfileの作成
Laravelアプリケーション用のDockerイメージを作成するためのDockerfile例です：

```dockerfile
FROM php:7.4-fpm

# PHP拡張機能をインストール
RUN docker-php-ext-install pdo pdo_mysql

# Composerをインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Laravelのソースコードをコピー
COPY . /var/www/html
WORKDIR /var/www/html

# ファイルの所有権を設定
RUN chown -R www-data:www-data /var/www/html

# Composer依存関係をインストール
RUN composer install

# ポートを公開
EXPOSE 8000

# Laravelサーバーを起動
CMD php artisan serve --host=0.0.0.0 --port=8000

```

# Selenium Dockerイメージの使用

DockerでSeleniumを実行するために、公式の`selenium/standalone-chrome`イメージを使用します。このイメージにはChromeブラウザとSeleniumサーバーが含まれています。

# docker-compose.ymlファイルの作成

docker-compose.ymlファイルを作成して、LaravelアプリケーションとSeleniumサーバーを一緒に設定します：

```
version: '3'
services:
  app:
    build:
      context: .
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html

  selenium:
    image: selenium/standalone-chrome
    ports:
      - "4444:4444"
```

# 環境設定

LaravelでSeleniumを利用するために、.envファイルやテスト設定ファイルにSeleniumサーバーのホストとポートを指定します

```makefile
SELENIUM_HOST=selenium
SELENIUM_PORT=4444
```

これらの設定により、LaravelアプリケーションとSeleniumサーバーがそれぞれ独立したコンテナで実行されつつ、互いに通信が可能となります。Laravelアプリケーションからは、Seleniumサーバーを通じてブラウザテストを行うことができます。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
VR空間上にUIを設置した際、必ず手前に表示させる(OVROverlay)

# はじめに
ユニバーサルレンダーパイプライン(URP)の環境を利用している場合は、カメラスタッキングを利用してしまうのが楽ですが、ビルトインレンダーパイプラインを利用している場合の手法として、OVROverlayコンポーネントを利用する方法を試してみました。

# 環境
Unity 2022.3.40f1
Meta XR Core SDK 67.0.0
Meta Quest3

# シーン構築
:::note warn
プロジェクト作成などの環境構築は割愛します。
:::

# ベースシーンの作成
## PlaneとOVRPlayerController、Cubeを追加
1. 地面として、Planeを追加
1. Main Cameraを削除して、OVRPlayerControllerを追加
1. UIが手前に表示されていることを確認するためにCubeを追加
![スクリーンショット 2024-08-16 192807.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/c6e992f3-149c-4786-325e-09f4bd2ab053.png)

:::note info
Plane : OVRPlayerControllerを原点に配置するため、Positionを(0, -1, 0)
OVRPlayerController : Positionを(0, 0, 0)
Cube : Positionを(0, 0, 3)
:::

## UIとCameraを追加
1. UIのサンプルとして、銃の照準のImageを追加
1. UIの専用カメラとして、Cameraを追加し、UI Cameraに名前を変更
![スクリーンショット 2024-08-16 202321.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/d009023d-c30c-95a7-7fff-83452b46d589.png)

:::note info
Canvas, Image : 画像の通り
UI Camera : Positioinを(0, 0, 0)

※CanvasやUI Cameraは、UI Cameraから対象のUIが映っていれば、Positionはどこでも大丈夫です。
:::

# UIを手前に表示
## レンダーテクスチャを作成
1. Assets > Create > Render Textureから作成し、名前をUICameraRenderTextureに変更
![スクリーンショット 2024-08-16 195515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/5f2f86ca-7b54-1d9b-2e97-68b219aeacfc.png)

## UI Cameraの設定を変更
- Culling Mask : UIのみ
- 出力先をレンダーテクスチャに変更
- 背景を透明
- Audio Listenerを無効化
![スクリーンショット 2024-08-16 200101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/ff8704fa-605a-bc41-4a71-9a0f7764c3b2.png)

:::note info
Background : (0, 0, 0, 0)
:::

:::note warn
Canvasのレイヤーが「UI」になっているため、UI Cameraは、UIレイヤーのみを映すようにする
:::

## OVRPlayerControllerのCenterEyeAncyhorの設定を変更
- Culling Mask : UIを除外
![スクリーンショット 2024-08-16 200903.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/b8fc6faf-43b6-2285-bffe-d119612e9b13.png)

:::note warn
Canvasのレイヤーが「UI」になっているため、UIレイヤーを映さないようにする
:::

## OVROverlayコンポーネントを追加
1. CenterEyeAnchorの下に空のGameObjectを作成し、OVROverlayと名前を変更
1. OVROverlayコンポーネントを追加
1. レンダーテクスチャをLeft Eye Textureに設定
1. CenterEyeAnchorのカメラ表示と重なるため、Positionを(0, 0, 1)に設定
![スクリーンショット 2024-08-16 203237.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/75c385d5-2e76-e581-4976-732aec236c18.png)

:::note info
Left Eye Texture に設定すると、自動的にRight Eye Textureに設定されます。

Positionは、(0, 0, 1)でなくても、重ならなければ大丈夫です。
:::

## 動作確認
![OVROverlay.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/c56f55d0-acb0-74c2-f4bd-1c99da9dc7de.gif)
Vue3 computedについて

## 読んで欲しい人
- Vue.jsを使用していて`computed()`の使い方がわからない人
- 過去の自分

## computedとは

ざっくり言うと、コンポーネント内のデータが変更された時に、自動で計算をしてくれる便利なメソッドです。

## 使い方

```js
//引数の中に関数入れて使う
computed(() => {})

//関数内では計算処理を記述する
const totalAmount = computed(() => {
  return price.value * 5
})

//templateでは下記な感じで表示できちゃう
//<p>{{ totalAmount }}</p>
```

## いつ使うのか、何が嬉しいのか

例えば下記のプログラム

- scoreが75点以上であればA評価、それ以下であればB評価を出すと言うプログラム

```vue
<script>
const score = ref(0)

const results = computed(() => {
  return score.value > 75 ? 'A' : 'B'
})
</script>

<template>
 <p>{{ results }}<p>
</template>

//結果→B

```

**嬉しいこと**
- scoreの値が変わるたびに、computed()は関数を実行してくれる

  - `computed()`は常に、自分の中で使用されているリアクティブな値(今回ならscore)を監視し続けてくれる。

ので、

下記のようなボタンを押した場合、computedは再実行されて結果がAになる

```vue
<script>
const score = ref(0)

const results = computed(() => {
  return score.value > 75 ? 'A' : 'B'
})
</script>

<template>
 <p>{{ results }}<p>
 
 <button @click="score + 80"><button>
 
</template>

//ボタンを押すと結果→A
```

## 仕組み

- templateと同じ技術を利用している

vue.jsではリアクティブエフェクトという機能を利用して、リアクティブなメソッドを監視している。

- 内部のリアクティブな値が変更されると`computed()`であれば関数の中身を再度実行する
- templateであれば、表示をサイレンダリングしている

上記2つは同じ処理を用いて実装されている。

https://ja.vuejs.org/guide/extras/reactivity-in-depth

## 注意

- 監視されてない時は動かない

```vue
<script>
const score = ref(0)
const results = computed(() => {
  return score.value > 75 ? 'A' : 'B'
})
</script>

<template>
 <button @click="score + 80"><button>
</template>
```

誰も`results`を監視していない場合は、`score.value`の値が変更されても`computed()`内部の関数は実行されません

## 感想、学び

- `computed()`よくわからなくて難しかった
- `computed()`を深ぼって調べるとVue.jsがどんな技術を用いているのか？がわかるので結構良かった。
- 応用がたくさん効きそう
解いてみた。「Aランク：山折り谷折り」

# 問題
[「Aランク：山折り谷折り」](https://paiza.jp/works/mondai/real_event/origami)

# コード
Javaで解いてみました。

``` Java
import java.util.*;

public class Main {
    
    public static final boolean TANI = false;
    public static final boolean YAMA = true;
    
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int nN = sc.nextInt();

        // 初期設定
        int nSize = 0;        
        boolean[] abFolds = new boolean[(int)(Math.pow(2, nN))];

        // 谷折りをi 回開く
        for (int i = 1; i <= nN; i++) {
            if (i == 1) {
                abFolds[1] = TANI;
                nSize = 1;
            } else {
                int nOrgSize = nSize;
                nSize = nSize * 2 + 1;

                // 開いた側の折り目（元の折り目の逆の折り目になる）
                for (int j = 1; j <= nOrgSize; j++) {
                    abFolds[nSize+1 - j] = !abFolds[j];
                }
                // 中心の折り目（谷折り）
                abFolds[nOrgSize+1] = TANI;
            }
        }
        
        // 結果出力
        for (int i = 1; i <= nSize; i++) {
            if (abFolds[i]) {
                System.out.print("1");
            } else {
                System.out.print("0");
            }
        }
        System.out.println("");
    }
}
```

# 解説
## 標準入力からの数値の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値を取得しています。

## 初期設定
+ 折り目の本数を０にする
+ 折り目を格納する abFolds[] 配列を作成する。この時、サイズは $2^N-1 $であるが、0番目を使用しないため、+1 している

## i 回開く
### 1　回目
+ 中心の折り目（谷折り）をつける
+ 折り目の本数を 1 にする

### k回目（１以外）
折り目は、以下の通りになる。
+ 左から nOrgSize(本) の折り目は、そのまま維持される
+ 開いた側の 1, .., nOrgSize(番目) の折り目は、開いた折り目（谷折り）を中心として、開いた側の外側から 2nOrgSize+1, 2nOrgSize, .., nOrgSize+1 番目の折り目として、逆（山折りなら谷折り、谷折りなら山折り）にコピーされる
+ 開いた折り目 nOrgSize+1 番目の折り目は谷折りになる
+ 折り目の本数を、2nOrgSize + 1  にする

## 結果出力
abFolds[] について、以下をprint()メソッドで表示する。
+ true:山折り → 1
+ false:谷折り → 0

最後に改行（println()メソッド）を表示する。
VB.net 基本的な文法（繰り返し2）for each文

前回の記事では、繰り返しの処理としてfor文を利用しました。
https://qiita.com/HiHiroyoshi/items/24e7d0e0cfdade21c8be

今回は、for each文について取り上げます。
要素数が不明な場合、全要素に対して処理を行いたい場合に利用します。

今回は、新たにDataTableというもの（Object）を扱います。
配列(Array)は、同じ型（Integer:整数やString:文字列）でないと、使えないといった制約があります。
ですが、DataTableでは、列（Column:カラム）ごとにデータ型を宣言することができます。


DataTableのイメージ
|Integer(整数)  |String(文字列)  |String(文字列2)  |
|---|---|---|
|1  |A  |Test  |

配列のイメージ
|添え字|0  |1 |2  |
|---|---|---|---|
|値  |3  |5  |7|

といった具合です。
for each文を使うメリットの一つが読みやすさ（可読性）です。
まずは、値を格納しましょう。
下準備をします。
DataTableを生成して、カラム(列)を定義して、
4行ほどのサンプルデータを入れてみます。

```
'配列を用意
Dim array1() As String = {"Alice", "Bob", "Caroll", "Daisy"}
Dim array2() As String = {"USA", "Canada", "UK", "Japan"}

Dim dataTable1 As New DataTable
'列の追加
dataTable1.Columns.Add("No", GetType(Integer))
dataTable1.Columns.Add("Name", GetType(String))
dataTable1.Columns.Add("Address", GetType(String))

For i = 0 To 3

    Dim dr As DataRow = dataTable1.Rows.Add()
    dr("No") = i + 1
    dr("Name") = array1(i)
    dr("Address") = array2(i)

Next i
```

これを実行すると、dataTable1に下記のデータが作成されます。
手入力の場合、カラム名には気を付けましょう。
○ No
× NO
○ Address
× Adress
こういった場合、DataTable内に列NOは、テーブルに属していません。
といったメッセージが表示されます。

NoがInteger,NameがString、AddressがStringといった型の具合です。

これが下準備です。

さて、このDataTableに対して、for each文を行ってみましょう。

Datatable(dataTable1)のrow（行）をdatarowとして、dataTable2にデータを置きかえてみます。


```

        Dim array1() As String = {"Alice", "Bob", "Caroll", "Daisy"}
        Dim array2() As String = {"USA", "Canada", "UK", "Japan"}

        Dim dataTable1 As New DataTable

        dataTable1.Columns.Add("No", GetType(Integer))
        dataTable1.Columns.Add("Name", GetType(String))
        dataTable1.Columns.Add("Address", GetType(String))

        For i = 0 To 3

            Dim dr As DataRow = dataTable1.Rows.Add()
            dr("No") = i + 1
            dr("Name") = array1(i)
            dr("Address") = array2(i)

        Next i

        Dim dataTable2 As New DataTable

        dataTable2.Columns.Add("No", GetType(Integer))
        dataTable2.Columns.Add("Name", GetType(String))
        dataTable2.Columns.Add("Address", GetType(String))

        For Each dr As DataRow In dataTable1.Rows

            Dim dr2 As DataRow = dataTable2.Rows.Add()
            dr2("No") = dr("No")
            dr2("Name") = dr("Name")
            dr2("Address") = dr("Address")

        Next dr

```

dataTable1をdataTable2に置き換えただけなので、cloneメソッドを使えば一発だと思われた方もいるかと思いますが、For Each 文に関して述べさせていただくためのサンプルということで......

## まとめ
For文は、For Each文を利用することも可能です。
For Eachを利用して全要素に対して処理を行うことで比較的に読みやすいコードを書くことが可能です。
【超簡単】GASとGeminiで無料でAIのLINEbotを作成する。

geminiのAPIとGoogle Apps Scriptを使用すれば、自分なりのAIをLINEbotに組み込めるのでその方法を公開します。

とても簡単なので是非真似してみてください。

LINEBOTとGeminiのAPI Keyを発行してそれをGASに貼り付けた以下のコードのyour_～_keyに貼り付けてください。

アプリを公開して、WebhockにそのURLを設定すれば動くと思います。初めてGASを動かす方は色々トラブルと思いますが、調べれば簡単にできると思います。

ぜひやってみてください。

こちらの記事を参考にしています。詳しくはこちらを参考にしてください。

https://cros.co.jp/2024/01/12/%E6%A5%AD%E5%8B%99%E6%94%B9%E5%96%84google-apps-script%E3%81%A7gemini%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8Bgpts/#index_id8



```
const GEMINI_API_KEY = 'your_gemini_api_key'; // あなたのAPIキーを設定
const GEMINI_API_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent';
const LINE_ACCESS_TOKEN = 'your_line_api_key';
const PUSH_API_URL = 'https://api.line.me/v2/bot/message/push';


function doPost(e) {
  const json = JSON.parse(e.postData.contents);
  const event = json.events[0];
  const userId = event.source.userId;

  aiMessageGenerator(message,userId)
  
}


function aiMessageGenerator(message, userId) {

  var payload = {
    contents: [{
      parts: [{
        text: `あなたは孔子です。素晴らしい考えで人々の些細な悩みを吹き飛ばすような一言を返信します。以下のメッセージに対して適切な返信メッセージを考えてください。 ${message}`
      }]
    }],
    // パラメータの設定
    generationConfig: {
      stopSequences: ["The End"], // ストップシーケンス
      temperature: 0.9, // ランダム性の度合い（0から1）
      maxOutputTokens: 150, // 最大トークン数
      topP: 0.9, // 生成の多様性
      topK: 40 // 生成の多様性
    },
    safetySettings: {
      category: "HARM_CATEGORY_DANGEROUS_CONTENT",
      threshold: "BLOCK_ONLY_HIGH"
    }
  };

  var options = {
    'method' : 'post',
    'contentType': 'application/json',
    'payload' : JSON.stringify(payload),
    'muteHttpExceptions': true
  };

  try {
    var response = UrlFetchApp.fetch(GEMINI_API_URL + '?key=' + GEMINI_API_KEY, options);
    var content = JSON.parse(response.getContentText());
    Logger.log(content); // レスポンス内容をログに記録
    pushMessageToUser(userId, content.candidates[0].content.parts[0].text)
  } catch (error) {
    Logger.log(error.toString());
  }
}

function pushMessageToUser(userId, message) {
  Logger.log(message)
  const options = {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${LINE_ACCESS_TOKEN}`
    },
    payload: JSON.stringify({
      to: userId,
      messages: message
    })
  };

  UrlFetchApp.fetch(PUSH_API_URL, options);
}

//temperature:

//最低値: 0
//最高値: 1
//説明: 生成されるテキストのランダム性を制御します。0は完全に決定論的な出力（非常に予測可能）、1は最大のランダム性を意味します。

//maxOutputTokens:

//最低値: 1
//最高値: Gemini APIの限界に依存（ドキュメントによれば、通常の上限は2048トークン）
//説明: 生成される出力の最大トークン数（単語数）を制限します。この値が大きいほど、より長いテキストが生成されます。

//topP (nucleus sampling):

//最低値: 0
//最高値: 1
//説明: 生成時に考慮される次の単語の確率質量の累積閾値。高い値はより多様なテキストを生成し、低い値はより予測可能なテキストを生成します。

//topK:

//最低値: 0
//最高値: 任意の正の整数
//説明: 次の単語の候補として考慮される最高の単語数。高い値は多様性を高め、低い値は一貫性を高めます。


```
Office のデータベースエンジン

# はじめに
Office 製品が採用しているデータベースエンジンは、大きく 2 つ存在します。
この 2 つの概要と、注意点を書きなぐっておきます。

![スクリーンショット 2024-08-17 091717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847080/8feaae88-22ed-923a-2359-ff59d28add16.png)

# Jet
- Joint Engine Technology (共同エンジン技術) の頭字語
- Jet のバージョンは 4.0 まで存在している
- 32 ビット版のみ存在 (このため、64 ビットのアプリケーションでは使用することができない)
- Microsoft Data Access Components (MDAC) のコンポーネントとしてダウンロードできた
- OLEDB を使用する場合は、ConnectionString プロパティの Provider 引数に `Microsoft.Jet.OLEDB.4.0` と設定する (Provider に指定する数字部分は、Jet のバージョン)
- 今は (たぶん)、単体でダウンロードするすべがない

# ACE
- 当初は Office Access Connectivity Engine (ACE) と呼ばれていた
- 現在は Access データベースエンジン
- ただなぜか、省略する場合はいまだに ACE と書かれている。(たまに ADE と書かれているので紛らわしい)
- Jet エンジンと下位互換がある
- 32 ビットと 64 ビットの両方がある
- Office 2007 から登場
- ACE のバージョンは 12.0 から始まる (Office 2007 の内部バージョンが 12.0 に起因していると思う)
- Office のバージョンとともに、ACE のバージョンも 15.0、16.0と上がっていく
- ただし接続文字列は 12.0 のまま (accdb 形式のファイルバージョンが 12.0 だから？)
- OLEDB を使用する場合は、ConnectionString プロパティの Provider 引数に `Microsoft.ACE.OLEDB.12.0` と設定する (Provider に指定する数字部分は、ACE のバージョン**ではない**ので注意)
- Access Database Engineの再頒布可能コンポーネントや、Access Runtime をインストールすることで、ACE を使用することができる

:::note warn
Office をインストールしている端末に、Access Database Engine や Access Runtime をインストールする場合は、一般的な Office 製品の共存ルールに従う必要があります。
たとえば、同じビットをインストールする必要があります。
なお、Access Database Engine 2016 は、MSI 形式でインストールします。
よって、 C2R 形式である Office 2019 以降とは共存できません。
この場合、Access Runtime をインストールする必要があります。
ただし、Office 製品をインストールすると、ACE ももれなくインストールします。
このため、Office を使用している環境では、Access Runtime を導入する必要はないと思います。
:::

# 参考資料
https://learn.microsoft.com/ja-jp/office/troubleshoot/access/jet-odbc-driver-available-32-bit-version

https://www.microsoft.com/ja-jp/download/details.aspx?id=54920

https://support.microsoft.com/ja-jp/office/microsoft-365-access-runtime-%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%A6%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B-185c5a32-8ba9-491e-ac76-91cbe3ea09c9
nRFConnectSDKを基盤としたSesameの暗号通信 #9 Kconfig

![sesame](https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/7612.pastedimage1711200987952v3.png)


# 雑談
Configは、組み込み開発の悪夢です。まるで意味不明なスイッチの集まりのようで、1つをオフにするとコンパイルが失敗し、1つをオンにするとコンパイルされたファイルが肥大化します。もう2024年ですが、依然としてこのような開発方法は、大量のコードを読んでどのコードモジュールが有効になっているかを確認するしかありません。これによってコンパイルも遅くなります。
SwiftLint：non_optional_string_data_conversion の落とし穴

APIから取得した data型を .utf8 の String に変換したい場合、SwiftLint ではタイトルの通り、`non_optional_string_data_conversion`という warning が発生します。

# 使用技術
- Swift
- Xcode
- SwiftLint

# `non_optional_string_data_conversion` とは？
さて、今回の話の中心となる `non_optional_string_data_conversion` とはなんでしょうか。
タイトルにもある通り、これは SwiftLint のルールの1つです。

https://realm.github.io/SwiftLint/non_optional_string_data_conversion.html

このルールの内容は、
> Prefer using UTF-8 encoded strings when converting between `String`and `Data`
> 訳：`String` と `Data` 間の変換時に、UTF-8エンコードされた文字列を優先的に使用する
というものです。

例えば、以下のコードはこのルールには違反しません。
```swift: Non Triggering Examples
Data("foo".utf8)
String(decoding: data, as: UTF8.self)
```

一方で、以下のコードは違反となり、トリガーされます。トリガーされたコードは、Xcode上で `warning` として表示されます。

```swift: Triggering Examples
"foo".data(using: .utf8)
String(data: data, encoding: .utf8)
```

# 注目すべきポイント
今回注目したいのは、Data 型をエンコードする際に使う、`String(decoding: data, as: UTF8.self)` についてです。
このメソッドの便利な点は、String 型を返す点です。

一方、Xcode上で warning が出る `String(data: data, encoding: .utf8)` は、`Optional<String>` を返します。

では、両者の違いはなんでしょうか。
`String(decoding: data, as: UTF8.self)` は、たとえ `data` がUTF-8として正しくエンコードできない場合でも、String 型として値を返します。
それに対して、`String(data: data, encoding: .utf8)` は、エンコードに失敗すると nil を返します。


つまり、`String(decoding: data, as: UTF8.self)` は、デコードに失敗した場合でも**文字化けした String 型**を返してしまう可能性があるということです。

したがって、このイニシャライザを使用する際は、`data` が確実に UTF-8 としてエンコード可能であることを確認した上で使用することをお勧めします。
以下は、この問題に関するサンプルコードです。

https://swiftfiddle.com/nabvhbfuibb77cwik7koyvroea

# この問題の落とし穴
上記を踏まえて、今回注意したいのは、`non_optional_string_data_conversion` がSwiftLint 上では "Enabled by default: Yes"、つまりデフォルトのルールとして設定されている点です。
そのため、`.swiftlint.yml` ファイルに、このルールを除外する必要があります。

## ルールの除外方法
このルールの除外方法は簡単です。
ファイル内で `disabled_rules` の配下に `non_optional_string_data_conversion` を追記するだけです。

```yaml: .swiftlint_yml
disabled_rules:
  - ... 除外したいその他のルール
  - non_optional_string_data_conversion
  - ...
```

# エンコードが確実ではない場合の回避方法
では、UTF-8でエンコード可能であると確実に言えない場合、どのようにしてエンコードしたら良いでしょうか。

1つの解決策として、オプショナルバインディングして、nil の場合は別の文字列を返すのが良いでしょう。
以下は、そのサンプルことです。

```swift
if let html = String(data: invalidData, encoding: .utf8) {
  print(html)
} else {
  print("エンコード失敗")
}
```
https://swiftfiddle.com/uebk6jrukzdmdjj6oepht7oeru

# 最後に
今回紹介した「落とし穴」は、`String(decoding: data, as: UTF8.self)` を推奨するルールが SwiftLint でデフォルトで有効化されている点にあります。
そのため、必要に応じて `.swiftlint.yml` に設定を追加する必要があります。
また、エンコードが確実ではない場合、オプショナルバインディングをしてあげる必要があります。

# 参考

https://github.com/realm/SwiftLint/issues/5263

https://www.hackingwithswift.com/example-code/language/how-to-convert-data-to-a-string
VsCodeからQiita投稿

# VSCodeからQiita投稿
1. Ctrl + Shift + P 
    コマンドパレットを開く

1. `qiitaに投稿する`を選択

1. `記事のタイトルを入力する`(必須)

1. `private``public`を選択

1. `タグ`を入力(必須)
AWS Certified Data Engineer - Associate(DEA-C01)を取得しました

# はじめに
AWS認定コンプリートを目指すべく、DEA-C01を取得しました。

# AWS Certified Data Engineer - Associate(DEA-C01) とは
[この辺](https://aws.amazon.com/jp/certification/certified-data-engineer-associate/)を参照ください。

# 教材
1. [Cloud License](https://cloud-license.com/exam/dea/)
    - 有償のおなじみのやつです。
    - 77問(11セクションx7問)です。
    - これだけで良いかもしれません。
1. [Exam Prep Official Practice Question Set: AWS Certified Data Engineer - Associate (DEA-C01 - Japanese)](https://explore.skillbuilder.aws/learn/course/internal/view/elearning/18145/exam-prep-official-practice-question-set-aws-certified-data-engineer-associate-dea-c01-japanese)
    - 公式の模擬試験で、20問です。無償です。
1. [Exam Prep Official Pretest: AWS Certified Data Engineer - Associate (DEA-C01 - Japanese)](https://explore.skillbuilder.aws/learn/course/internal/view/elearning/18862/exam-prep-official-pretest-aws-certified-data-engineer-associate-dea-c01-japanese)
    - 公式の模擬試験で、65問です。有償です。

# 結果&感想
1時間で終えました。[Cloud License]が参考になりました。
解いてみた。「Aランク：本の整理」

# 問題
[「Aランク：本の整理」](https://paiza.jp/works/mondai/real_event/book_sort)

# コード
Javaで解いてみました。

``` Java
import java.util.*;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int nN = sc.nextInt();
        int[] anBooks = new int[nN+1];

        // 本の並び順を格納
        for (int i = 1; i <= nN; i++) {
            anBooks[i] = sc.nextInt();
        }

        // 交換回数
        int nChange = 0;

        // 左からi冊目の本について
        for (int i = 1; i <= nN; i++) {
            // 番号がiなら、交換不要
            if (anBooks[i] == i) {
                continue;
            }

            // i+1番目以降にある、番号iの本を探し、交換する
            for (int j = i+1; j <= nN; j++) {
                if (anBooks[j] == i) {
                    int temp = anBooks[i];
                    anBooks[i] = anBooks[j];
                    anBooks[j] = temp;
                    nChange++;
                    break;
                }
            }
        }

        // 結果出力
        System.out.println(nChange);
    }
}
```

# 解説
## 標準入力からの数値の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値（本の冊数）を取得しています。

## 本の並び順を取得
標準入力から anBooks[] に本の並び順を格納しています。

## 初期設定
交換回数 nChange に0を設定します。

## 本の並び替え
左からi冊目の本について調べる。
### 本の番号がiである場合。
交換不要のため、次の本へ。
### 本の番号がi以外の場合。
i+1冊目以降の本を調べていき、番号iの本を見つけたら、その本とi冊目の本を交換し、交換回数を１増やす。
#### 補足
ここでは、i番目とj番目（番号iの本があった場所）の交換を行なっていますが、速さを少しでも追求するならば、
``` java
    int temp = anBooks[i];
    anBooks[i] = anBooks[j];
    anBooks[j] = temp;
```
を
``` java
    anBooks[j] = anBooks[i];
```
にするとStep数を減らすことができます。（左からi冊目については、この問題では、もう使用しないので、anBooks[i]を更新する必要はない。）

### 結果出力
交換回数 nChange を表示します。
[Windows Server GPO] 管理用テンプレートについて

# 「管理用テンプレート」 とは
「管理用テンプレート」とは、<mark>GPOの設定項目/設定値を、管理者が見たときに理解がしやすいように定義したテンプレートファイル</mark>のこと。

<span style="font-size: 80%; ">↓GPO管理コンソールにおける管理用テンプレートの該当箇所</span>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550683/19ed92aa-de54-6d6c-2ace-a88c53337411.png)

:::note info
管理用テンプレートファイルは、admxという拡張子でローカルディレクトリに格納されている
C:\Windows\PolicyDefinitions
:::

# 設定項目の拡張
特定のアプリケーションをGPOで管理する際、<mark>対応するadmxファイルを管理用テンプレート追加する必要がある。</mark>

### 設定手順
例えば、**Microsoft Edge** の管理用テンプレートファイルを追加し、設定項目を拡張する手順としては、以下のブログが参考になる。

> 参考URL：[[Microsoft Edge] 管理用テンプレート追加手順](https://pcnote.me/post/system-recipe-200815-1/)

### その他対象サービス
Microsoft Edge だけではなく、以下のようなサービスについても管理用テンプレートを追加のうえ、GPOでの管理が可能なようだ。

* WindowsOS の各バージョン
* Office製品
* Edgeをはじめとしたブラウザ類
* Webexなどのチャットツール
  
> 参考URL：[対象サービス一覧](https://ittrip.xyz/soft/windows/admx-ichiran)

# 以上を踏まえて

### 課題
ドメコンが複数存在する環境下で管理用テンプレートを追加する場合、以下の課題が生じる。
* 全てのドメコンに手動で管理用テンプレート追加処理を行う必要がある。
   ⇒ 管理用テンプレートファイルは、ローカルのディレクトリに存在する
  
*   1台のドメコンに管理用テンプレート追加処理を行った場合、他ドメコンが存在する場合には同様の処理を繰り返し行う必要がある。

### 対策
以上の課題を解決するために、「**セントラルストア**」という仕組みが存在している。
次の記事でセントラルストアについてまとめる。
[DB設計]インデックス設計の基本と注意点

## はじめに
初期開発プロジェクトでDB設計を担当することになった際、今まで深く考えず使っていたインデックスの設計で思考の沼にハマりました。
ではどのような基準でインデックス設計を行うべきなのか？
基本的な考え方と、設計初心者が迷ってしまいがちなポイントについてまとめてみました。

**本記事の対象者**
・今までなんとなくDB操作を行なっていたがあらためてインデックスについて知りたい人
・初めてデータベース設計に挑戦する人

## １．そもそもインデックスって？
データベース内のデータを高速に検索するための仕組みです。データベースに大量のデータが格納されている場合、特定のデータを見つけるためには全体を順番に探索するのではなく、効率的な方法で目的のデータを見つける必要があります。そのために、インデックスが利用されます。
インデックスは、特定のカラム（列）やフィールドに対して作成されます。インデックスは、そのカラムの値と、それが存在するデータの位置情報（物理的なディスク上の場所など）を関連付けるデータ構造です。
インデックスが作成されると、データベースはそのインデックスを使用してデータを効率的に検索します。インデックスは通常、二分木やBツリーなどのデータ構造を使用して実装されます。これにより、データベースは迅速かつ効率的に目的のデータを見つけることができます。

・・・と長々と書きましたが、よく例えられるのは本の末尾にある索引です。
単語があいうえお順、アルファベット順など特定のルールに従って並べられているので目的の単語を探しやすいですよね。
初めのページから地道に探していくと途方もない時間がかかるので、できることなら索引を用意しておきたいわけです。

## ２．インデックスのメリットとデメリット
インデックスは検索処理の高速化ができるためとても便利なように思えますが、以下のようなデメリットも存在します。

・インデックスのためのディスク領域が必要になる
・テーブルに変更（追加・更新・削除）を行う際の処理速度が遅くなる
・運用に伴いメンテナンスが必要となる

上記のように、闇雲に作成すると容量が増えるだけではなくかえってパフォーマンスが下がる場合があります。
よく検索される項目だからと安易に判断せず、メリット・デメリットを比較した上でインデックスを作成すべきか検討が必要です。

## ３．インデックスを作成すべきパターン

#### その１：レコード数の多いテーブル
レコード数の少ないテーブルではそもそもフルスキャンした方が高速な場合があります。
ひとつの目安として1万レコード以下であればまずインデックスの効果は発揮できないでしょう。
この閾値について明確な基準はなく、サーバーのスペックなどにもよるため理想としては実測しながら決定することが望ましいです。

#### その２：カーディナリティの高いカラム
カーディナリティとは「値の分散度」を示す言葉であり、これがインデックスを作る際に最も重要な指針となります。
特定の列について多くの種類の値を持っていればカーディナリティが高く、少なければカーディナリティが低いということを指します。
例えば、フラグやステータスのようにパターン数が決まっている項目はインデックスの効果が望みにくいですが、何百、何千パターンも入るような項目はインデックスの効果が高くなります。

#### その３：SQLの抽出条件や結合条件に使用されるカラム
SQLを発行する際、以下のように使われるカラムにインデックスを作成することで効果を発揮します。
・WHERE句に使用されるカラム
・テーブル結合でON句に使用されるカラム
・ORDER BY句に使用されるカラム
逆に言えば検索条件や結合条件に利用されないカラムにインデックスを張るのは無意味なので気をつけましょう。

## ４．インデックス作成で注意したいこと
#### その１：主キー制約や一意制約が付与されているカラム
制約としてプライマリキー、ユニークキーを付けている場合、そのカラムには自動的にインデックスが付与されています。そのため明示的にインデックスを作成する必要はありません。
※一部DBでは対象外の場合もあるため、使用するDBの仕様を確認してください。

#### その２：データに極端な偏りがある
カラムに入ることが想定されるデータに偏りが多いとインデックスの効果が薄くなります。
例えば100パターンのデータが入りうるが、ほとんどはデータAが入っているというようにデータに偏りのある場合、結局はフルスキャンしているのと同じ状態となってしまうためです。
実際にバラバラのデータが入ることが予想されるカラムにインデックスを作成しましょう。

#### その３：テーブルのデータ量に対して抽出対象のデータが少ない
抽出対象となるデータが全データに対して多い場合も同様に、インデックスの効果を生かしきれません。

#### その４：データ更新の処理速度を遅くする
インデックスを貼っているテーブルのデータの変更が行われる際、INSERT、UPDATE、DELETEいずれにおいてもインデックスの変更も必要になるため、インデックスを作成していないテーブルよりも処理速度が遅くなります。
テーブルの使用目的を十分に理解して、インデックスを作成するメリットが上回るのか検討が必要です。

## ５．インデックスを活用できないSQL
#### その１：NULL検索
```SQL
SELECT * FROM users WHERE age IS NULL;
```
#### その２：OR検索
```SQL
SELECT * FROM users WHERE age = 20 OR age = 30;
```
#### その３：否定系
```SQL
SELECT * FROM users WHERE age <> 20;
```
#### その４：演算の使用
```SQL
/* NG */
SELECT * FROM users WHERE age + 1 = 20;

/* OK */
SELECT * FROM users WHERE age = 20 - 1;
```

#### その５：中間一致、後方一致
```SQL
/* NG */ 
SELECT * FROM users WHERE name LIKE '%田中%';
SELECT * FROM users WHERE name LIKE '%田中';

/* OK */
SELECT * FROM users WHERE name LIKE '田中%';
```
#### その６：暗黙の型変換
```SQL
/* NG */ 
SELECT * FROM users WHERE age = '20'; -- NUMBER型に文字列を指定

/* OK */
SELECT * FROM users WHERE age = 20;
```

## おわりに
インフラ担当や初期開発プロジェクトでない限り、DB設計について深く考える機会ってありませんよね。
エンジニア歴の長い方でも意外とインデックスについての知識が曖昧なままの方も少なくないと思います。
これからDB設計に挑戦したいと考えている方や初学者の最初の取っ掛かりとして、参考にしてもらえると幸いです。

#### 参考文献
・ミック、木村明治.「おうちで学べるデータベースのきほん」.翔泳社
・ミック.「達人に学ぶDB設計徹底指南書: 初級者で終わりたくないあなたへ」 .翔泳社
P-1-1：freecodecampを始めてみた

# ■前提
- 大学時代に、Html CSS Javascriptなどをかじった程度
- 社会人になってからは、主にIT営業
- 最近、事業会社の情報システム部門に転職
- エンジニアとしての実務経験はゼロ
:::note info
※独り言
Qiitaで初めて投稿作成しているが、Notionのように書けて少し感動している
:::

# ■なぜ勉強するか？？
- 仕事でアプリ開発を行う機会が結構ありそう
- 社内環境だと制約が多く、練習しづらい
- エンジニアとしても働ける力をつけたい

# ■何となくのゴール
- ビジネスサイドもわかる
- 開発もわかる
- インフラもわかる
人になれたら嬉しい

# ■やったこと
- 参考記事の確認
    - https://qiita.com/chi1180/items/d945f5507f546bffa610
    - これはめっちゃ助かりました。。🙇‍♂️
- 様々なサイトがあり情報量多すぎて少し萎える( ﾉД`)ｼｸｼｸ…
- とりあえずfreecodecamp.orgだけやることを決断
- freecodecamp.orgに登録
- 最初のカリキュラム消化

# ■カリキュラム一覧
- <strong>レスポンシブウェブデザイン 認定講座　　　　　　　　　　　　　　←　今ココ
- JavaScript アルゴリズムとデータ構造 (ベータ版) 認定講座
- フロントエンド開発ライブラリ 認定講座
- データ可視化 認定講座
- リレーショナルデータベース 認定講座
- バックエンド開発と API 認定講座
- 品質保証 認定講座
- Python を用いた科学計算 (ベータ版) 認定講座
- Python を用いたデータ分析 認定講座
- 情報セキュリティ 認定講座
- Python を用いた機械学習 認定講座
- Python を用いた代数学 認定講座

# ■レスポンシブウェブデザイン 認定講座
- 講座の中でも、更に複数コースに細分化されている
- 今日完了したのは、何個もあるうちの一つ
![a-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862700/54897392-5835-5b47-187e-c6ed33a3f2a9.png)
:::note info
赤枠が終了した所
:::


# ■所感
- 1個1個段階的に進められるので、初心者にも比較的わかりやすいのかな
- 実際の開発現場で戦える「力」がつくのかは、講座を全部完了するまでは判断つかない
- まずは、毎日1コースだけ完了を目標に進めてみる

# ■メモ
- Markdownで書くのも最初は違和感ありあり
【Android】Retrofit2 で Kotlin Serialization を用いて変換を行う

Retrofit2 で Kotlin Serialization を用いて変換を行う方法として、
Codelab では retrofit2-kotlinx-serialization-converter を使う方法が紹介されている。

https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter

https://developer.android.com/codelabs/basic-android-kotlin-compose-getting-data-internet#7

## 手順

### Kotlin Serialization をモジュールに導入する。

モジュールの build.gradle.kts の `plugins` ブロックに次を追加する。

```build.gradle.kts
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.10"
```

モジュールの build.gradle.kts の `dependencies` ブロックに次を追加する。

```build.gradle.kts
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
```

### JSON に対応するクラスを実装する

```Kotlin
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class MarsPhoto(
    val id: String,
    @SerialName(value = "img_src")
    val imgSrc: String
)
```

### Retrofit2 をモジュールに導入する

モジュールの build.gradle.kts の `dependencies` ブロックに次を追加する。

```build.gradle.kts
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
```

### `Retrofit` オブジェクトをビルドする

`Json.asConverterFactory("application/json".toMediaType())` でコンバーターファクトリーを生成し、
`Retrofit.Builder` に追加してから
ビルドする。

```Kotlin
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit

private val retrofit = Retrofit.Builder()
    .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
    .baseUrl(BASE_URL)
    .build()

private const val BASE_URL =
    "https://android-kotlin-fun-mars-server.appspot.com"
```

### 使う

```Kotlin
import retrofit2.http.GET

interface MarsApiService {
    @GET("photos")
    suspend fun getPhotos(): List<MarsPhoto>
}

val retrofitService: MarsApiService by lazy {
    retrofit.create(MarsApiService::class.java)
}

suspend fun getPhotos(): List<MarsPhoto> {
    return retrofitService.getPhotos()
}
```

／以上
Alibaba Cloud OSSの代わりにローカルでMinIOを使いたかった（失敗）

## 環境

- .NET 6.0
- [Aliyun.OSS.SDK.NetCore v2.13.0](https://www.nuget.org/packages/Aliyun.OSS.SDK.NetCore/2.13.0)

## やりたかったこと

docker-composeでMinIOを立てて、OSSのSDKを使ってアクセスしたかった

## やったこと

1. docker-compose.yamlでMinIOを起動できるようにする
    minioを起動し、init-minioでbucketを作成しています
    virtual-hosted styleを有効にするためにMINIO_DOMAINを指定しています
    ```yaml:docker-compose.yml
    services:
    minio:
        image: minio/minio:latest
        environment:
        MINIO_DOMAIN: localhost
        ports:
        - "9000:9000"
        - "9001:9001"
        volumes:
        - minio-data:/data
        command: server /export --console-address ":9001"
    init-minio:
        image: minio/mc:latest
        depends_on:
        - minio
        entrypoint: >
        /bin/sh -c "
        mc alias set minio http://minio:9000 minioadmin minioadmin;
        mc mb --ignore-existing minio/test;
        mc anonymous set public minio/test;
        "

    volumes:
    minio-data:
    ```

2. /etc/hostsを設定する
    virtual-hosted styleでtest.localhost:9000などとアクセスされるので設定
    ```shell:/etc/hosts
    127.0.0.1 *.localhost
    ```

3. C#から実行してみる
    SDKのサンプルを元にバケット一覧を取得
    ```csharp
    OssClient client = new OssClient("http://localhost:9000", "minioadmin", "minioadmin", conf);
    var buckets = client.ListBuckets();
    
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name + ", " + bucket.Location + ", " + bucket.Owner);
    }
    ```

## 起きたこと

下記エラーが発生した。使っているSDKのバージョンでは署名バージョンV4をサポートしていなかったため、認証に失敗してしまった。

```
The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.
```

V4に対応したバージョンに更新したが改善されなかった

```shell
dotnet add package Aliyun.OSS.SDK.NetCore --version 2.14.1
```

ソースを見たところ、`AWS4-HMAC-SHA256`ではなく`OSS4-HMAC-SHA256`という文字列が使われていた。おそらく基本的な仕組みは同じだが、ヘッダー情報にもOSS4の方で設定されるので、MinIO側でもAWS4として処理できないのだと思われる。

## 余談

AWSのSDKを使ってAlibabaのOSSにアクセスするサポートはされているみたいだった。MinIOはS3互換だけど、OSS互換ではなかったということか。
AlibabのOSSを使う時もAWSのSDKを使った方がいいかも。
AWS Summit Japanへ行ってきました

## はじめに
おはこんばんにちは。キティちゃんです。台風がいきなり来て片頭痛に悩まされています。今回は今更ながらですが、AWS Summit Japanへ行ってきたことについて書こうと思います。長時間滞在していたわけではないため、簡単な内容になってしまうのは許してください。

## AWS Summit Japanとは
日本最大のAWSのイベントで、AWS初心者の方はもちろん、経験豊富な方も参加し、様々な情報交換が行われたりする場となります。

## AWS AppFabric
これは最近リリースされたサービスのようですが、SaaSからの情報漏洩が起きないかを監視するサービスだと伺いました。Slackやmiroといったサービスの監視もできるらしいです。

## Amazon GuardDuty
GuardDutyはかなり有名なサービスですよね。このサービスについては偶然にもAWSの日本法人の社員の方とお話しできるチャンスがあったので色々お聞きました。凄い失礼ながら「どれくらい誤検知とかあったりします？」と聞いてみると「ログを見てアラートを飛ばしているのでほぼ誤検知はないです。あるとすれば、誰かが意図して実行したかどうかの判断は必要になります。」と。それはそう。ですが、こう実際に法人の方から言われると凄い信頼できますよね。相も変わらず便利なサービスです。

## まとめ
今回は本当にざっくりな内容なのですが、短い時間で得られた収穫として忘れないように残しておきます。時間のある方、クラウドに興味のある方、これからクラウドに携わる方は是非来年こそAWS Summit Japanへ参加してみてください。
【python】単語のカウント問題を解きました

# はじめに
paiza様のpython問題集から、単語のカウント問題を解きました

## 問題
>スペースで区切られた英単語列が与えられます。
>英単語列に含まれる英単語の出現回数を出現した順番に出力してください。

## 実装したソースコード
```python
array1 = input().split(' ')
array2 = []
for x in array1:
    if x not in array2:
        array2.append(x)

for y in array2:
    count = 0
    for z in array1:
        if z == y:
            count += 1 
    print(y + " " + str(count))
```

## 実行した結果
![test1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/50a9fe59-5c4c-ed95-ce1a-fcc591340e4b.jpeg)

# 最後に
この問題は実は段階別にヒント問題を解いて最終的にこの問題を解く流れです。
時間は存在しない

## 時間があっという間に過ぎていく理由

こんにちは。私はとある会社で社内教育の研修講師をしています。

今回は今日10記事めということで普段はAIに書いてもらっている記事を自分で書いてみようと思いました。

## エンジニアとしての時間とは

私は日々お陰様で忙しく仕事をしています。

もう8月も中盤に来て、先月からそうですが、1ヶ月に1回は祝日がある年の後半にさしかかり、あと1ヶ月もすれば年末まで100日を切ります。

今日はそんな時間というテーマを扱っていきたいと思います。

## 時間は存在しない説

うろ覚えですが、時間は存在しないというカルロ・ロヴェッリさんという著者の方が書いた本を以前読みました。

でも事実、時間が存在しているから私は今日も仕事してると思っていたんです。

ですから、私にとってこの本はとんでも本という類でした。

つまり言っていることが荒唐無稽でタイトルは釣りだと思っていたんです。

## 1時間は長いけれど1日は早い。10年と20年が同じ感覚

時間というものは不思議だなと最近私は改めて感じるようになりました。

そして私は最初の結論に辿り着きました。1日は14400秒という途方もない時間が過ぎているにも関わらず全く自覚がない、つまり時間は正確に測ることができるが、私たち人間は時間の感覚を司る器官が不足している。

もしくは欠けているから時間の感覚を感じることが乏しいか苦手であるという自分の中の仮説が出ました。

## 次の仮説:時間はただの原因発生装置説

私はこれをスマホで書いてます。このスマホが発明された2008年までスマホはなかったわけです。

ということはスマホが発明されるまで2008年間、紀元前を入れると数万年かかっているわけです。

それは時間ではなく原因の塊だと私は考えました。

今のタッチパネル式のスマホができた理由は当時他の会社が出してたスマホが使いにくかったことが原因です。

なぜそういった使いづらいスマホがあったかというと当時のガラケーは日本以外インターネット機能がついていなかったからです。

そのように何かが発明される裏には発明される原因があると考えました。

世の中の一切は原因でできてるのではないかと考えるようになりました。

そしてその世の中の便利なものを生んだ最大の要因は便利なものが生まれるための原因であると思うようになりました。

私たちが生まれたのも原因があるし両親が出会ったのも原因がある。原因というものがまるで空気のように私たちの1分1秒の中に存在しているんです

## 時間とは原因の発生装置

時間とは原因を発生させる巨大装置だと私は思いました。これが現在の私にとっての考え方です。

つまり、駅前にコンビニがあるのは何らかの原因がありその結果駅前にコンビニができたんです。原因を細分化しまくるとひとつの原因に辿り着き、それが宇宙の誕生みたいなところだと思います。

## つまり、生きてる限り深く考えずに行動しまくる

確かに、時間は測れますがそれはただ時間を数えているに過ぎず、私たちが感じている時間とは違うのではないかと思ってます。


初めから答えなんてないんだから、時間が存在する理由にもあるように我々はよい結果をのぞみたいのなら、その分良い結果が発生する原因に辿り着くまで行動しまくらないといけないと感じました。

私はソシャゲをやったことないですが、原因というガチャを回し続けることが現時点における最良の判断、私にとっての答えなんです。

なぜならそれが人生の構成要素だからです。時間だからです
【初心者OK！WEBライター募集中】自宅で仕事してみませんか？

![企业微信截图_17237979757626.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857348/ca0de625-6bff-3a0d-6804-f2242b21a9df.png)
こんにちは、皆さん！
自宅で自由な時間に働き、しっかりとした報酬を得たいと思いませんか？現在、私たちはWEBライターを募集しています。
# こんな方をお待ちしています！
1.AIや最新のIT技術に興味がある方
2.オンラインホワイトボードに興味がある方
3.自分の知識や経験を生かして、他の人に情報を届けたいと思っている方

# 仕事内容
主にAI技術やITツールに関する記事を執筆していただきます。専門知識を活かし、読者にわかりやすく伝えることが求められます。もちろん、執筆の内容に応じて報酬もご用意しておりますので、ご安心ください。
＊経験がある方、未経験の方、問わずお気軽にお問合せ下さい。
# 募集要項
l  勤務地：完全リモート（自宅）
l  報酬：経験・能力に応じて決定
l  募集人数：若干名
l  募集期間：本募集は長期的に行っておりますので、いつでもお気軽にご連絡ください。長期的に協力していただける方を優先いたします。
l 応募方法：ご興味のある方は、下記のメールアドレスまでお気軽にお問い合わせください。
📧sasa.hui@pixso.net
Pythonで最適化問題を解く場合のライブラリとソルバー

# 概要
最適化問題を解くことが多くなってきていたが、どのライブラリを使ったらいいか迷うことが多かったため簡単にまとめる。

# Pythonの最適化ライブラリ

| ライブラリ名 | 公式サイト | 特徴 | 使用できるソルバー | 商用利用 | ライセンス |
|--------------|-----------|------|-------------------|----------|------------|
| SciPy | [scipy.org](https://www.scipy.org/) | 科学技術計算のための包括的なライブラリ。最適化モジュールを含む。 | BFGS、L-BFGS-B、SLSQP、Nelder-Mead、Powell、CG、Newton-CG、TNC、COBYLA、信頼領域法など | 可 | BSD |
| PuLP | [coin-or.github.io/pulp](https://coin-or.github.io/pulp/) | 線形計画問題に特化したライブラリ。モデリングが直感的。 | CBC、GLPK、CPLEX、Gurobi、XPRESS | 可 | BSD |
| Pyomo | [pyomo.org](http://www.pyomo.org/) | 数理最適化モデリング言語。複雑な最適化問題にも対応。 | GLPK、CBC、CPLEX、Gurobi、BARON、IPOPT など多数 | 可 | BSD |
| CVXPY | [cvxpy.org](https://www.cvxpy.org/) | 凸最適化問題のモデリングと解法に特化。 | ECOS、SCS、OSQP、GLPK、CPLEX、Gurobi、MOSEK など多数 | 可 | Apache 2.0 |
| Gurobi | [gurobi.com](https://www.gurobi.com/) | 商用の高性能ソルバー。Pythonインターフェースあり。 | Gurobi | 要ライセンス | 商用 |
| CPLEX | [ibm.com/analytics/cplex-optimizer](https://www.ibm.com/analytics/cplex-optimizer) | IBMの商用ソルバー。大規模問題に強い。 | CPLEX | 要ライセンス | 商用 |
| OR-Tools | [developers.google.com/optimization](https://developers.google.com/optimization?hl=ja) | Googleが開発した最適化ツールキット。 | GLOP、CBC、SCIP、CP-SAT | 可 | Apache 2.0 |
| Gekko | [gekko.readthedocs.io](https://gekko.readthedocs.io/) | 動的最適化問題に特化。制御系の最適化に強い。 | APOPT、BPOPT、IPOPT、SPOPT | 可 | MIT |
| PyOpt | [pyopt.org](http://www.pyopt.org/) | 多様な最適化アルゴリズムを提供。 | SNOPT、NLPQL、CONMIN、COBYLA、SOLVOPT、PSQP、NLPQL、NSGA-II など | 可（一部制限あり） | LGPL |

# Pythonから利用できる最適化ソルバー

| ソルバー名 | 公式サイト | 特徴 | 商用利用 | ライセンス |
|------------|-----------|------|----------|------------|
| CPLEX | [ibm.com/analytics/cplex-optimizer](https://www.ibm.com/analytics/cplex-optimizer) | 高性能な商用ソルバー。線形計画法、混合整数計画法、二次計画法に強い。 | 要ライセンス | 商用 |
| Gurobi | [gurobi.com](https://www.gurobi.com/) | 高速で信頼性の高い商用ソルバー。大規模最適化問題に適している。 | 要ライセンス | 商用 |
| MOSEK | [mosek.com](https://www.mosek.com/) | 線形、二次、円錐最適化問題に特化した商用ソルバー。 | 要ライセンス | 商用 |
| GLPK | [gnu.org/software/glpk](https://www.gnu.org/software/glpk/) | オープンソースの線形計画法ソルバー。中小規模の問題に適している。 | 可 | GNU GPL |
| CBC | [github.com/coin-or/Cbc](https://github.com/coin-or/Cbc) | オープンソースの混合整数線形計画法ソルバー。 | 可 | Eclipse Public License 2.0 |
| IPOPT | [github.com/coin-or/Ipopt](https://github.com/coin-or/Ipopt) | 大規模な非線形最適化問題向けのオープンソースソルバー。 | 可 | Eclipse Public License 2.0 |
| SCIP | [scipopt.org](https://scipopt.org/) | 混合整数計画法と制約整数計画法のためのフレームワーク。 | (8.0.2まで)要ライセンス,(8.0.3以降)可 | (8.0.2まで)ZIB Academic License, (8.0.3以降) Apache 2.0|
| XPRESS | [fico.com/en/products/fico-xpress-optimization](https://www.fico.com/en/products/fico-xpress-optimization) | 高性能な商用ソルバー。線形計画法、混合整数計画法、非線形最適化に対応。 | 要ライセンス | 商用 |
| BARON | [minlp.com/baron](https://minlp.com/baron) | 全域的最適化のための商用ソルバー。非凸最適化問題に強い。 | 要ライセンス | 商用 |
| ECOS | [github.com/embotech/ecos](https://github.com/embotech/ecos) | 組込みシステム向けの軽量な凸最適化ソルバー。 | 可 | GNU GPL v3 |
| SCS | [github.com/cvxgrp/scs](https://github.com/cvxgrp/scs) | 大規模な凸錐計画問題向けのソルバー。 | 可 | MIT |
| OSQP | [osqp.org](https://osqp.org/) | 高速な二次計画法ソルバー。組込みシステムにも適している。 | 可 | Apache 2.0 |
質問力こそエンジニアの最強スキル！効果的な質問の仕方を例を交えて解説

エンジニアとして成長したいのに、質問の仕方がわからず悩んでいませんか？「質問すること＝無能」と思い込み、必要な情報を得られずに苦戦している方も多いはず。実は質問力は、エンジニアの重要なスキルの一つなのです。

私も新人時代、質問の仕方に悩み、チームの生産性を下げてしまった経験があります。でも適切な質問の仕方を学ぶことで、問題解決力が飛躍的に向上し、キャリアアップにもつながりました。

本記事ではエンジニアに求められる質問力と、効果的な質問の仕方について詳しく解説します。具体的な質問例や先輩エンジニアからの回答を引き出すコツなど、すぐに実践できるテクニックをお伝えします。


<iframe width="560" height="315" src="https://www.youtube.com/embed/jQNWfMqbOvU?si=UsWceSoW7icpDect" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## エンジニアにとって質問が重要な3つの理由

エンジニアにとって質問することの重要性は、しばしば見過ごされがちですが、その価値は計り知れません。なぜエンジニアは積極的に質問すべきなのか、3つの重要な理由があります。それは、以下の3つです。

- 知識の吸収を加速させる
- 問題解決能力の向上
- チームワークの強化

[>> 重要な理由の詳細はコチラ！](https://taishi-official.com/2024/08/16/2791/#toc1)

## エンジニアの質問力不足でどんな問題が発生するのか？

質問力不足は多くの問題を引き起こし、エンジニアの成長を阻む可能性があります。質問力不足が引き起こす問題として、以下のようなものがあります。

- 生産性の低下
- バグの増加
- チーム内の摩擦

[>> 質問力不足で起こる問題の詳細解説はココから！](https://taishi-official.com/2024/08/16/2791/#toc5)

## エンジニア流質問の仕方を解説

エンジニアリングの世界では、問題解決能力が成功の鍵を握ります。その中で、適切な質問をする能力は極めて重要です。本記事では、エンジニアが直面する典型的な場面での効果的な質問方法について、4つの重要なポイントを解説します。

### 1. どんなエラーなのか

エラーに遭遇したとき、まず明確にすべきは「どんなエラーなのか」です。エラーの性質を正確に把握することで、問題の原因特定と解決への道筋が見えてきます。

**【ポイント】**

- エラーメッセージを正確に記録する
- エラーコードがある場合は必ず記載する
- エラーが発生した状況（タイミング、頻度など）を説明する

[>> 質問例はコチラで確認！](https://taishi-official.com/2024/08/16/2791/#toc10)

### 2. 何がわからないのか

問題に直面したとき、自分が何を理解していて何がわからないのかを明確にすることが重要です。これにより、回答者は適切なレベルで説明を提供できます。

【ポイント】

- 自分が理解している部分を簡潔に説明する
- 具体的にわからない点や疑問を挙げる
- 可能であれば、なぜそれがわからないのかも説明する

[>> 質問例はコチラで確認！](https://taishi-official.com/2024/08/16/2791/#toc11)

### 3. どのように試したのか

問題解決を試みた過程を説明することで、無駄な提案を避け、より効果的なアドバイスを得られる可能性が高まります。

**【ポイント】**

- 試したアプローチや方法を具体的に説明する
- それぞれの試行の結果（成功/失敗、エラーメッセージなど）を記述する
- 可能であれば、なぜそのアプローチを選んだかの理由も述べる

[>> 質問例はコチラで確認！](https://taishi-official.com/2024/08/16/2791/#toc12)

### 4. 何か参照にしたものがあるのか

問題解決のプロセスで参照した情報源を共有することで、議論の出発点を提供し、より深い理解につながります。

**【ポイント】**

- 参照したドキュメント、記事、フォーラムの投稿などを具体的に挙げる
- それらの情報源から得た洞察や、試してみたことを説明する
- 情報源の解釈で不明確な点があれば、それも質問に含める

[>> 質問例はコチラで確認！](https://taishi-official.com/2024/08/16/2791/#toc13)

## まとめ

今回はエンジニアと質問について、なぜエンジニアにとって質問力が大事なのかや、エンジニアの質問方法についてご紹介しました。質問力を伸ばすことはプログラミング言語に関する知識を伸ばすよりも、よっぽど大事で**汎用性が高いスキル**です。

質問力は重要なスキルですが、**一見無関係で意外と見落とされやすいスキル**です。ただこのスキルを伸ばすと、プログラミングのスキルも飛躍的に向上します。本記事を参考にして、ぜひ質問力向上にも力を入れてみてください。

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
Selenium VBAでWebページをPDFで保存（印刷）する

# 目的、背景など
業務自動化の一環としてWebスクレイピングを独自に学習しています。
SeleniumにてWebページをPDF保存するために色んな記事を見て回ったんですが、
どれもPythonの記事ばかりでVBAの記事がありませんでした。
どうしても一部のソースコードの書き方がわからず、試行錯誤していたんですが、
英語の記事を見て解決に至りました。
めっちゃ探し回ったので私のほかにもVBAでスクレイピングしている方も苦戦したんじゃないかと思います。
なのでその記事の転載しようと思います。

# 作業環境
* Selenium Basic 2.0.9.0
* Microsoft Visual Basic for Applications 7.1
* Google Chrome バージョン:126.0.6478.182（Official Build）（64 ビット）


# 参考記事
https://github.com/florentbr/SeleniumBasic/issues/214
https://qiita.com/NauSakaguchi/items/76d66683f3c54e9d2a34

# PythonでWebページをPDFで保存（サンプルとして参考記事から転載）
Pythonで行う場合、以下のappStateという文言をJson形式で記述し、所定の変数に格納します。
この文言の記述をVBAに書き直すのが詰まったポイントです。
```python:sample.py
import json
from selenium import webdriver

# 印刷用の設定
appState = {
    "recentDestinations": [
        {
            "id": "Save as PDF",
            "origin": "local",
            "account": ""
        }
    ],
    "selectedDestinationId": "Save as PDF",
    "version": 2
}

profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState),
           'savefile.default_directory': 'path/to/dir/'} # ここでデフォルトの保存先を設定

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('prefs', profile)
chrome_options.add_argument('--kiosk-printing')  #　印刷用のプロンプトが表示された時、自動的に印刷ボタンが押される

driver = webdriver.Chrome(options=chrome_options)  # webdriverを設定
driver.get(url) # urlへアクセス
driver.execute_script('window.print();')  # javascriptを実行して印刷用のプロンプトを表示
```

# VBAでWebページをPDFで保存（本題）
[参考記事](https://github.com/florentbr/SeleniumBasic/issues/214)をもとに書けたものが以下です。
単にJson構文をワンライナーに記述するところまでは想像できたんですが、それだけだと不十分でした。
このワンライナーをDictionaryとして、要はKey・Value型として格納する必要があったようです。
（というかDictってVBAでも使えたんですね。すんなりコンパイルできたんですが、もしかしたら追加したライブラリの一部かもしれません。調べるのめんどい）
```vb
Dim driver As New ChromeDriver

'PDF印刷用　パラメータ
Dim appState As String
Dim d As New Dictionary
driver.AddArgument "--kiosk-printing" '印刷ダイアログが開くと即時保存するオプション
appState = "{""recentDestinations"": [{""id"": ""Save as PDF"", ""origin"": ""local"", ""account"": """"}], ""selectedDestination"": ""Save as PDF"", ""version"": 2}"
d.Add "appState", appState
driver.SetPreference "printing.print_preview_sticky_settings", d
driver.SetPreference "savefile.default_directory", "c:\hoge" 'ここにPDFが保存される

driver.Start "chrome"
driver.Get "https://www.yahoo.co.jp/"
driver.Wait 3000
driver.ExecuteScript "window.print();" '印刷ダイアログを開き、PDFとして保存
driver.Wait 3000
driver.Close
driver.Quit
```

それともう一点詰まった箇所があります。
PythonにしろVBAにしろ保存先の指定は``driver.SetPreference "download.default_directory", filePath``で記述されている記事がほとんどです。
ですがこのやり方でのPDFの保存先は`` driver.SetPreference "savefile.default_directory", filePath``であるようです。
これは当記事でも[参考記事](https://qiita.com/NauSakaguchi/items/76d66683f3c54e9d2a34)として紹介している記事でも言及されています。


# 末筆
以上です。
結構詰まったんですが、いかがだったでしょうか。
もし以下のことで試行錯誤されている方がいたら、何かの助けになればと思います。

* Selenium VBA Webページ PDF保存
* VBAでJson構文関連の処理をしたい
* download.default_directoryで指定した保存先に保存されない
* ~~Pythonなんか無くてもこれくらいVBAでもできんだよ！！~~
男のリハビリ 〜再びAIグラビア写真集を作ってみた。〜

## はじめに
　久々に投稿させていただきます。某法人でCEO兼CHief IMPact Officer、通称CHIMPOを務めている者です。
　ちなみに、ペンネーム「股ノ毛　茂」として、このような[グラビア写真集](https://www.amazon.co.jp/AI%E3%82%AB%E3%83%8E%E3%82%B8%E3%83%A7-%E7%BE%8E%E5%A5%B3%E3%81%AE%E3%81%BB%E3%81%BB%E3%81%88%E3%81%BF-%E5%A4%8F-1-%E5%85%A882%E6%9E%9A-ebook/dp/B0CLL21KPX)を作成しておりました。今回、リハビリも兼ねて久しぶりにAIグラビア写真集を出したので、その作成方法を備忘録として残しておきたいを思います。

ちなみに、今回作った作品はコレ。
https://www.amazon.co.jp/dp/B0DCG8P9J4
`あざとい彼女とデート ～思春期リターンズ～ 140枚以上`
`著者: 股ノ毛　茂`
 ![00016-142539582.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1689863/bde6a9a4-a74c-fddd-69b9-0bedcfcc0689.jpeg)
 ![00091-1250196745.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1689863/9b0296bf-da1b-f8b1-4dfb-dc5c9c792d38.jpeg)
![00129-2711721429.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1689863/03e3c5e1-be29-7dfb-1dae-29d759294a6f.jpeg)



## 売上に追われる中、忘れていたリビドー
　働くとは辛いものです。目の前の売上を追いかけるあまり、気がついたら本来やりたかったことを忘れておりました。そして、そうこうしているうちに身体が悲鳴をあげて強制停止。2週間は死んでおりました(PCに触るのも嫌でした)。
　しかし、それでも何かが湧き出てくるのがエンジニアリングに関わるものの悲しい習性。久しぶりにPCを立ち上げて、キーボードを打ち始めました。そう、失われたと思っていたリビドー、性欲のままに。
 「立てなくても、勃たせよう」
僕は、昔好きだったショートカット女子の面影を頼りに、Stable Diffusionを立ち上げました。

## 作業量を減らすために
 　リハビリを開始したのはいいですが、できるだけ無理はしたくない。それでいて、入力と出力にランダムな要素がある生成AI。前回プロンプトで作成した時に、
 「もっと楽にできると思っていたのに…。」
 と何度も呟いてました。端的に言ってガチャです。アプローチは生成精度を上げるか、効率的に画像を多く作って実用に耐えうるものを人力で選別するか。今回は、後者を選択しました。

 　そこで今回採用したのは、`Prompt Matrix`。今更な感はありますが、だいぶ資料が出揃ったようなので今回採用しました。参考にしたのは[こちらのサイト](https://romptn.com/article/20655)。こちらの方法を使用することで、一回のGenerateボタン操作で
  `1girl, masterpiece, best quality,`
  `1girl, masterpiece, best quality, blonde hair`
  `1girl, masterpiece, best quality, long hair`
  `1girl, masterpiece, best quality, blonde hair, long hair`
のように、`1girl, masterpiece, best quality,`という人物の中心的な特徴を使いまわした上で、別の特徴を自動的に変更させて一気に多くの枚数の画像を作成することが可能です。今回は初めてということで、32枚ずつ作成しました。それでも、一枚ずつ作成していた前回よりはるかに早かったです。途中、なぜか全裸で脚を広げた画像が唐突に出てきて、僕の股間がチンピクしてガマン汁で濡れたのは内緒です。

## 終わりに
　男とは情けないものです。いつまで経っても股間を刺激するものに心が揺れるものです。多くの男性が「男として終わった」かどうかの判断基準を「勃った」「勃たない」にしているのですから、「あの若さをもう一度」と言ったキャッチコピーの精力剤が広告市場から消えないのも納得がいきます。これからも、体調管理しつつマカを飲んで中折れしない状態を維持しつつ、新たなAI女優を作成していきたいと思います。

 それではまた。


https://www.amazon.co.jp/dp/B0DCG8P9J4
`あざとい彼女とデート ～思春期リターンズ～ 140枚以上`
`著者: 股ノ毛　茂`