OmniAICreator/Qiita-1.07M huggingface dataset:
react

import React, { Component } from 'react';

class ArrayCounter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      array: props.initialArray,
      count: props.initialArray.length,
      currentIndex: 0,
    };
  }

  handlePrevClick = () => {
    this.setState((prevState) => ({
      currentIndex: Math.max(prevState.currentIndex - 1, 0),
    }));
  };

  handleNextClick = () => {
    this.setState((prevState) => ({
      currentIndex: Math.min(prevState.currentIndex + 1, prevState.count - 1),
    }));
  };

  render() {
    const { array, count, currentIndex } = this.state;
    const currentElement = array[currentIndex];

    return (
      <div>
        <p>要素数: {count}</p>
        <button onClick={this.handlePrevClick}>前へ</button>
        <span>{currentElement}</span>
        <button onClick={this.handleNextClick}>次へ</button>
      </div>
    );
  }
}

export default ArrayCounter;
鍵認証shhの設定

# ターミナルで.shhに移動

```
# cd ~/.ssh
```

# 鍵ペアを作成

-tで形式を指定　rsa

-bでビット長を指定 4096bit

```
ssh-keygen -t rsa -b 4096

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/アカウント名/.ssh/id_rsa):
```
ファイル名と場所を尋ねられるので指定

".ssh"ディレクトリの中に"example"という名前の鍵を作成する

```
/Users/アカウント名/.ssh/example

Enter passphrase (empty for no passphrase): 
```
パスワードを尋ねられるがパスワードなしの場合は無入力でEnter

```
Enter same passphrase again:
```
再び無入力でEnter

```
Your identification has been saved in /Users/アカウント名/.ssh/example
Your public key has been saved in /Users/アカウント名/.ssh/example.pub
The key fingerprint is:
SHA256:*****
アカウント名@端末名.local
The key's randomart image is:
+---[RSA 4096]----+
|                 |
|     --  -       |
|    ------       |
|  --------       |
| ----------      |
|  ---------      |
|---------        |
|---------        |
|  ---------      |
+----[SHA256]-----+

```
鍵作成に成功

/Users/アカウント名/.ssh 内に
example　（秘密鍵）
example.pub　（公開鍵）
の2つの鍵が作成される

# 公開鍵をサーバーにアップロード

公開鍵のファイル名を "authorized_keys" に変更

root/.shh　内にアップロード

# パーミッション設定

```
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
```

# ターミナルの接続設定

```:vim ~/.ssh/config

Host 接続名（任意）
HostName sshホスト名
User sshユーザー名
Port 22
IdentityFile /Users/アカウント名/.ssh/example
```

# 接続テスト

ターミナルで

```
ssh 接続名
```
でパスワードなしで接続できれば成功

# 参考記事
https://tech-blog.rakus.co.jp/entry/20210512/ssh
https://tech-blog.rakus.co.jp/entry/20210727/ssh
https://cafehedgehogs.com/linux/88.html#toc6
https://qiita.com/pugiemonn/items/1597939003ca83208e0d
認証プロキシがある環境でscoopをインストールして利用する方法

## このページは？
- 認証プロキシがある環境でscoopをインストールする方法と、scoopでパッケージをインストールする方法を調べたので記載しておく

## 実行環境
- OS: Windows10 22H2
- 使用ターミナル: Powershell 7.3.6

## scoopのインストール方法
- Powershell 7 で以下のコマンドを実行する

```powershell
# 最初に認証プロキシの情報を変数に格納する
> $ProxyCred = Get-Credential
Powershell credential request
Enter your credentials.
User: myProxyUserName
Password for myProxyUserName: myProxyPassword
# -> 上記入力プロンプトにプロキシのユーザー名とパスワードを入力してEnterを押下
# -> これで認証情報オブジェクトを $ProxyCred 変数に格納できた

# scoopインストールスクリプト install.ps1 を認証プロキシ経由でカレントディレクトリにダウンロードする
# 引数として以下を指定する
# -> 認証プロキシのアドレスとポート
# -> 先程作成した認証プロキシの情報を格納した変数
> irm get.scoop.sh -Proxy 'http://my.proxy.domain:8080' -ProxyCredential $ProxyCred -OutFile 'install.ps1'

# 認証プロキシ経由でインストールスクリプトを起動する
# インストール時と同じく認証プロキシに関する情報を引数で指定する
> .\install.ps1 -Proxy 'http://my.proxy.domain:8080' -ProxyCredential $ProxyCred

# インストールが完了したらダウンロードした install.ps1 は不要なので削除しておく
> rm install.ps1
```

## 認証プロキシ経由でscoopパッケージをインストールする
- インストールが完了したらscoopコマンドへのPATHが通った状態でコマンド実行するためpowershellを再起動しておく

```powershell
# scoopにプロキシ情報を設定する
# ユーザー名:パスワード@プロキシドメイン:ポート番号 の形式で指定する
# ユーザー名やパスワードに記号が含まれる場合URLエンコードした状態での入力が必要かも
> scoop config proxy myProxyUserName:myProxyPassword@my.proxy.domain:8080

# パッケージをインストールしてみる
> scoop install git
```

## 備考
- かつては環境変数 `$HTTP_PROXY`と `$HTTPS_PROXY` を設定してインストールする方法が紹介されていたが、現在は Get-Credential コマンドと scoop config proxy コマンドを使うのが推奨されている様子
- 環境変数は `$HTTP_PROXY`と `$HTTPS_PROXY` は他のアプリケーションも参照する場合があり、設定したことを忘れていると意図しない挙動を発生させることもある
- このページの方法はscoopに閉じた設定となっているため他に影響を及ぼすことがなく安心して利用可能
【高先さんの電子工作】第16回：チルトスイッチを使って振動を検知する

https://youtu.be/yEJ7V_fbgq8

チルトスイッチを使って振動を検知するプログラムです。

```python:main.py
from machine import Pin
from utime import sleep

led = Pin(14, Pin.OUT, value=1)
tilt = Pin(15, Pin.IN)

while True:
    if tilt.value() == 0:
        print('振動を検知しました。')
        led.value(0)
        sleep(1)
    else:
        led.value(1)

```
Qiita記事投稿でよく使うHTMLタグのメモ


- Qiita記事投稿の際に頻繁に使うhtmlタグについて、自分用にメモを残しておきます。
- 基本的に、htmlなどのマークアップ言語をQiita記事の投稿に用いることができます。



## 【よく使うHTMLタグのメモ】

##### ***画像サイズ変更***
`<img src="" width=50%>`

##### ***画像サイズ変更 ＋ alt属性付与***
`<img src="" alt="" width=50%>`

##### ***アンカーリンク***
`<a href="URL">テキスト</a>`

##### ***アンカーリンク（新しいタブで開く）***
`<a href="URL" target="_blank">テキスト</a>`
例： <a href="https://www.yahoo.co.jp/" target="_blank">Yahoo!</a>

##### ***打ち消し線***
`<del> </del>`

##### ***コードを表示***
`<code>コードを入力</code>` 
※これはQiitaで言うところの「``」と同じ。

##### ***文字色を指定する***
`<font color="SteelBlue">テキスト</font>`
<font color="SteelBlue">例：テキスト</font>

##### ***引用ブロック***
`<blockquote cite="引用元URL"> <p>テキスト</p>< /blockquote>`

#### ***イタリック***
`<em>おはよう</em>`

#### ***ボールド***
`<p>hey guys <strong>hello world</strong> what's up?</p>`
<p>例： hey guys <strong>hello world</strong> what's up?</p>


#### ***箇条書きリスト：マークアップ言語（html）の場合***

```html
<ul>
    <li>あああ</li>
    <li>あああ</li>
    <li>あああ</li>
</ul>
```
#### ***箇条書きリスト：マークダウン記法の場合***

```
- [ ] タスク1
- [x] タスク2
```
- [x] タスク1
- [ ] タスク2


#### ***テキストを折りたたむ***

```html
<details>
  <summary>見出し（以下のテキストが展開される）</summary>
  折りたたまれるテキストがここ
</details>
```

#### ***テーブル・表： こんな感じの表が作れる。コードは以下の通り***

<details>
  <summary>
    <strong>テーブル（表）を作成（クリックすると中身の内容が展開される）</strong>
  </summary>

```html
<table>
    <thead>
        <tr>
            <th>id</th>
            <th>商品名</th>
            <th>数量</th>
            <th>金額</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>焼肉定食</td>
            <td>1</td>
            <td>1000</td>
        </tr>
        <tr>
            <td>2</td>
            <td>生姜焼き定食</td>
            <td>1</td>
            <td>900</td>
        </tr>
        <tr>
            <td>3</td>
            <td>中華丼</td>
            <td>2</td>
            <td>1600</td>
        </tr>
    </tbody>
</table>
```
</details>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486945/318e4b18-8d8f-0c0d-1701-d8dedef49201.jpeg" width=33%>


#### ***diffと他の言語のシンタックスを同時に使う***
- ` ```diff_ruby``` `
- ` ```diff_ruby:ファイル名.rb``` `


```diff_ruby:ruby
def say_hello
- puts "hello"
+ puts "bye"
end
```

参考：<a href="https://qiita.com/Qiita/items/c686397e4a0f4f11683d#diffと他の言語のシンタックスを同時に使う" target="_blank">diffと他の言語のシンタックスを同時に使う｜Markdown記法チートシート - Qiita</a>

https://qiita.com/Qiita/items/c686397e4a0f4f11683d#diffと他の言語のシンタックスを同時に使う






## さいごに｜参考サイト

- <a href="https://qiita.com/ym0628/items/c348d5620fecdaf032bd">Qiita記事投稿でよく使うHTMLタグのメモ</a>

https://qiita.com/ym0628/items/c348d5620fecdaf032bd


- <a href="https://qiita.com/Qiita/items/c686397e4a0f4f11683d">Markdown記法 チートシート</a>

https://qiita.com/Qiita/items/c686397e4a0f4f11683d


- <a href="https://qiita.com/twipg/items/d8043cd4681a2780c160">Qiitaのマークダウンで色をつける方法[140色]</a>

https://qiita.com/twipg/items/d8043cd4681a2780c160


- <a href="https://qiita.com/ym0628/private/8b249658085c5ed8b28d" target="_blank">htmlタグを使ってPCキッティングチェックリストを作る</a>

https://qiita.com/ym0628/private/8b249658085c5ed8b28d
nerfstudioでAttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS' エラーの対処法メモ

## エラー
[nerfstudio](https://github.com/nerfstudio-project/nerfstudio/tree/main)のDockerfileで環境を作ってからns-process-dataコマンドでcolmapを使おうとしたらエラーが出た

~~~
AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS
~~~

## 対処法
Pillow 10.0.0以降ではImage.ANTIALIASが削除されているため、9.5.0にダウングレードする

- Dockerfileに以下の行を追加
~~~
RUN pip install Pillow==9.5.0
~~~
または
- ターミナルで以下を実行
~~~
pip install --force-reinstall -v "Pillow==9.5.0"
~~~



---
参考記事
- https://github.com/nerfstudio-project/nerfstudio/issues/2378
- https://stackoverflow.com/questions/76616042/attributeerror-module-pil-image-has-no-attribute-antialias
iOS17 Xcode15 プライバシー マニフェストにUserDefaultsの理由を記載する（理由の宣言が求められるAPIの記載例）

## ```プライバシー マニフェスト```ファイルの作成

Xcodeナビゲーターから```App Privacy```を選択すると、直接新しい```プライバシー マニフェスト```を作成できます。
「PrivacyInfo.xcprivacy」という名前のファイルを作成します。
![AppPrivacy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/652be18e-fb53-0c60-58ce-1d4c36ea07a2.png)

:::note info
サードパーティのSDK開発者は、SDKに```プライバシー マニフェスト```を含めることができます。 
:::
:::note info
[プライバシー マニフェストとは？](https://qiita.com/4q_sano/items/768482e2522c480069c4#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%90%E3%82%B7%E3%83%BC-%E3%83%9E%E3%83%8B%E3%83%95%E3%82%A7%E3%82%B9%E3%83%88%E3%81%A8%E3%81%AF )
:::

## 「理由の宣言が求められるAPI」の記載例（UserDefaults）

##### UserDefaultsの記載例

[Appleサイトに載っているリスト](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api/#4278401)から関連する値を指定します。

>Privacy Accessed API Reasonsの配列へ指定
>
>CA92.1
UserDefaultsへのアクセスは、アプリ自身のみアクセス可能とした情報を読み書きすることを宣言
このため、他のアプリやシステムによって書き込まれた情報の読み取ったり、他のアプリからアクセスできる情報の書き込みは許可しません。

```PrivacyInfo.xcprivacy```に```Privacy Accessed API Types```を選択し、追加
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/9e69fe5e-7d28-820b-f48c-1ec85eeb2c31.png)

```Privacy Accessed API Type```に```User Defaults```を選択
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/4e646d72-3e4d-3298-5f8c-33f57fe22be8.png)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/d3e646a4-daf7-2ff6-3d8d-65299a381c83.png)

```Privacy Accessed API Reasons```に```CA92.1: Access info from same app, per documentation```を選択
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/befe7a2e-5470-ba63-0520-cb4d91196a92.png)
（[User defaults APIsの選択肢](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api/#4278401)は**CA92.1**だけなので、これを選択します）
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/5b95c3e2-7e3e-ff89-cb3d-380c0899b1ed.png)

以下の通り、```PrivacyInfo.xcprivacy```にUserDefaultsの理由を記載しました
![UserDefaults.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/52c8d08f-2b88-192e-1f1d-8e7634323367.png)
M5Stack CoreS3 の輝度変更方法

# M5StackCoreS3でM5CoreS3.hをincludeしたときにArduinoIDEから輝度変更する方法

## 最小輝度
```cpp
M5.Axp.setOutputVoltage(M5.Axp.OP_DLDO1, 500);
```

## 最大輝度
```cpp
M5.Axp.setOutputVoltage(M5.Axp.OP_DLDO1, 3300);
```

内部で500~3300に制限しているので小さすぎるor大きすぎる値を入れても範囲内
にしてはくれる。

一度設定すると再起動してもその値を使う感じが見受けられるので
真っ暗にしたまま右往左往しないように気を付ける(自分への戒め)

追記
```#include <M5CoreS3.h>```
をするのではなく
```#include <M5Unified.h>```
にすると
```
M5.Lcd.setBrightness(0)//0~255
```
等が使えるようになるので可能ならM5Unifiedを使うこと。
リバースエンジニアリング

リバースエンジニアリングを行うのは下記のような目的が考えられます。

* 類似の製品を作るために
* セキュリティのチェックのために
* 製品を別用途で使うために

一番目は違法となるケースだと思います。

二番目が結構流行ってるようです。

私は三番目です。IOのアドレスや挙動を調べたりします。

ターゲットは8bitの8051だったり32bitのMIPSだったりします。

昔の製品はROMだったりOTPが使われていて、再利用が難しかったのですが、最近の製品ではFlashが使われることが多く、何度も作り直すことが出来ます。

最近のFlashは1万回以上の書き込みが出来ます。

メーカーでのSOCの開発はFPGAでプロトタイプを作り、ASICで製品にしたりします。FPGAに入れるIOはIPとよばれて、自社開発のものもあるでしょうし、売り物の場合もあります。

GPLなコードがあればそれを見ます。

データーシートが手に入るものもあります。

これらがない場合は最終手段でバイナリを逆アセンブルしてリバースエンジニアリングします。

動かして、JTAGでレジスタを覗いたりすることもあります。

ルーターからルーターの機能をとっぱらってIOTのモジュールにしたりしています。

脆弱性が報告されたルーターでもルーターの機能を消しているので、脆弱性はありません。

ターゲットはHardOffで500円以下で購入できるようなものです。
【Flask】賞味期限管理アプリを作成したので、学習をまとめる

Flaskの学習のために、購入した食材の賞味(消費)期限を管理するアプリを作成しました。
http://43.207.31.69/

備忘録として、学習や記事をまとめます。

※コードの一部をGithubにて公開しています。

https://github.com/Koichi73/Expiration-Date-Management

## 入門
基本的な使い方は、以下などの記事を参考。

https://qiita.com/Bashi50/items/30065e8f54f7e8038323

## HTMLファイルの共通化
extendsを使う。パーツ化はinclude。

https://blog.imind.jp/entry/2020/02/01/174702

## ファイルの分割
コードの保守性を上げるために、機能ごとにファイルを分けたい。
以下に具体的なテンプレートをまとめた。

https://qiita.com/Koichi73/items/9d73f062f0ad56d6f953

#### (1)pythonファイル
Blueprintを用いて分割する。
app.pyなどに、Blueprintの設定を集約するイメージ。

#### (2)データベース
以下を参考に、DBの設定を各ファイルでimportできるように。

https://qiita.com/Bashi50/items/e3459ca2a4661ce5dac6

※`RuntimeError: Working outside of application context.`が出た場合、以下のサイトで解決。

https://qiita.com/Yu_unI1/items/00110442d66a5f11f7b1

## instanceフォルダ
機密性の高い情報を格納する。
※.gitignoreへの追加は必要。

instanceフォルダ配下のファイルは、instance_relative_config=Trueで自動で読み込める。
```
# instance/config.pyを読み込む
app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile('config.py')
```

## 環境変数
.envファイルに設定するのが簡単。
- .envファイルは、環境変数を使うファイルの親にあればOK
- python-dotenvを使って読み込む

https://zenn.dev/sivaquen/articles/4cfd2561b3e071

## 公開
~~[PythonAnywhere](https://www.pythonanywhere.com/)を用いた。
アプリ1つまでなら、条件はあるが基本無料で使える。
2つ以上は有料なので、HerokuやAWSなどを検討。~~

AWSに移管。EC2 + Apache + WSGIの構成を採用した。

## その他
デバッグモードをonにすると、pythonファイル中のprint()はターミナル上で確認できる。
WindowsでPythonを使う

## Pythonをダウンロード

`Download Python 3.11.5`を押下。
https://www.python.org/downloads/

## Pythonをインストール

### ファイル実行

`python-3.11.5-amd64.exe`を実行。

### インストール実行

`Use admin privileges when installing py.exe`にチェックあり
`Add python.exe to Path`にチェックなし
のまま`Install Now`を押下。

### デバイス変更確認

`はい`を押下。

### インストール完了

`Close`を押下。

### コマンド実行

`python`ではなく`py`を用いる。

```python
py -V
```

## venv

```zsh
python3 -m venv venv; source venv/bin/activate;
```

ではなく

```powershell
py -m venv venv; venv/Scripts/activate;
```

`deactivate`は同じ。

```powershell
deactivate
```

## アンインストール

削除したくなった場合、以下の手順で削除できる。

### アプリ検索

プログラムの追加と削除 > 検索条件にpython

削除したいものを選び、`アンインストール`を押下。

- Python 3.11.5 (64-bit)
- Python Launcher
Homerow Tips

# Homerowのキーバインド

![スクリーンショット 2023-08-06 12.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921144/a1fd9633-c4bb-0476-07cb-ec567b402c8b.png)

![スクリーンショット 2023-08-06 12.10.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921144/6a185891-9677-de7f-6131-fdec7b4bab1f.png)

![スクリーンショット 2023-08-06 12.10.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921144/e5120b8d-9baa-8afa-6f39-74a39ad21717.png)

![スクリーンショット 2023-08-06 12.10.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921144/1079b47b-a358-0537-20f0-1ebccdeccce6.png)
iOS17 Xcode15 プライバシー マニフェストにメールアドレスの用途を記載する（データ用途の記載例）

## ```プライバシー マニフェスト```ファイルの作成

Xcodeナビゲーターから```App Privacy```を選択すると、直接新しい```プライバシー マニフェスト```を作成できます。
「PrivacyInfo.xcprivacy」という名前のファイルを作成します。
![AppPrivacy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/652be18e-fb53-0c60-58ce-1d4c36ea07a2.png)

:::note info
サードパーティのSDK開発者は、SDKに```プライバシー マニフェスト```を含めることができます。 
:::

## 「データの用途」の記載例
収集する[特定カテゴリ](https://developer.apple.com/jp/app-store/app-privacy-details/#data-type)のデータ用途を説明する「```Privacy Nutrition Label Types```の辞書」をプライバシー マニフェストに記載します。

#### Email Addressの記載例

```PrivacyInfo.xcprivacy```に```Privacy Nutrition Label Types```を選択し、追加
![PrivacyNutritionLabelTypes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/43208019-16b6-c281-2119-1db90472fc5b.png)

| ```Collected Data Type``` | ```Linked to User``` | ```Used for Tracking``` | ```Collection Purposes``` |
|:-:|:-:|:-:|:-:|
| ```Email Address```を選択  |  YESを選択 | NOを選択  |  ```App Functionality```を選択 |

```Collected Data Type```に```Email Address```を選択
![EmailAddress0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/6db6f231-24cb-aedd-cbf8-d6db1f4c04ca.png)

```Collection Purposes```に```App Functionality```を選択
![EmailAddress1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/cf9f0d32-a01f-f2c0-fcac-9611a4a0d21c.png)


```PrivacyInfo.xcprivacy```は、以下のとおりです。
![PrivacyInfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/b27630d6-1bbd-97b8-bf86-ecc0e6ad2017.png)

:::note info
```Collected Data Type```：　**App Store Connect**上では、Data Typeに表示される
![DataTypes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/6134674d-a1a6-1f12-29ed-2965b0233fd2.png)
:::

:::note info
```Collection Purposes```：　**App Store Connect**上では、以下のチェック項目となります
![EmailAddress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/f10b3cf1-efbf-6931-f1f1-26b5fee1d4e2.png)
:::

## プライバシーレポート
プライバシーレポートの出力はXcode Organizerから実施します。PDFのプライバシーレポートがダウンロード出来ます。
![Generate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/3e993401-9b9c-5992-4d4a-4b5d0e434bab.png)

プライバシーレポートは、以下のとおりです。
![PrivacyReport1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/b749d547-e763-e14c-3b98-f346fd496467.png)
激安中華HMIを購入したが使~~いこなせなかった~~えるようになった話ｗ

HMI＋PLCを使いたくて、Amazonの山奥に分け入ってみるとこんなものがあった。

![スクリーンショット_2023-09-14_12-58-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/d444f63e-7732-38c6-b223-c2ef3c61edb9.png)


うむ。安い。とりあえずポチる。中国の山奥から１週間位で届いた。 中華満載ｗ

![top.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/b5dbf76c-7b6d-8ccb-e7d0-8a0100a47e25.jpeg)


AP320TというHMIらしい。開発ソフトは中国のWinsunzk社からダウンロードできるようだ。

 ~~https://www.winsunzk.cn/en/file?type=1&page=2~~ 

 ~~にある、AP320tSoft(20190710)_all が使えるらしい。~~ 



早速インストールして付属のRS-232Cケーブルでつないでみるがウントモスントモ言わないｗ

色々いじっていると、RS232Cコネクタの１ピンと２ピンをショートさせるとダウンロードモードに入れるようだ。

![Download.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/ccca49e5-c7c4-722d-7c0d-334b9827e6d1.jpeg)

これでダウンロードボタンを押せばプログラムが動く、と思ったら機種が違うとか言われて書き込めないｗ

![download2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/77f530bd-f8bd-934f-9104-18ac932675a5.jpeg)

OP320Tってなによｗ　情報読み出しではちゃんとAP320Tが出てくるのに。

![download4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/bf834288-a705-43ea-b05b-8741a531f19b.jpeg)


バイナリファイルに含まれるOP320Tの文字列をAP320Tに書き換えたりしたが、ダウンロードできず降参ｗ

~~こいつを動かせる勇者を求む！！~~
---
ダメ元でこれとおなじHMIを売っているAliexpressのセラーに連絡してみたところ、製品の製造元の直販セラーであることが判明。

色々調べてもらい、ダウンロード先の開発ソフトのバージョンが古くて書き込みができないことが判明した。
ありがとう、Owenさん！

https://www.winsunzk.cn/en/file?type=1&page=1 

開発ソフトを APSoft(20211129)_English に差し替えてもらった。これだとAP320Tにダウンロードができた。

![hmi.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/fe671501-8c62-4a4c-268a-8af944c74572.jpeg)

これで開発ができるようになったので、PLCと組み合わせてモーターでも回してみようｗ

と、やってみたがまた躓いた。HMIとPLCの通信ができないのである。

PLCは三菱の互換品（Fx2N)で、Amazonで3000円くらいで手に入る。
このPLCはPythonでも操作することができた。

https://github.com/KrystianD/fxplc

最初、HMIにRS232Cの口が出ているので、こことPLCの書き込みポートをつないだのだが、
操作ができない。またまたOWENさんに聞いてみると、RS232C-TTL変換器が必要とのことｗ

![image0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/4d7ecd15-6f4f-ef06-2b79-237871a864bf.jpeg)

幸いAmazonで500円くらいで売ってるので、これを介してつなげるとモーターが回った！

![image1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/d6f4ab6e-bf8a-2e0d-03b5-5473bf6ae643.jpeg)

総額１万円以下でPLC+HMI環境が手に入った。やれやれ。
【メモ】Material UI - Tabs APIのTabの色を個別に変更する。

## はじめに
Tabsの中の１つだけ目立たせる時に使用した。

直接styleを書き換えても良いが、そうするとずっと色がついたままになり、せっかくのTabs,Tabの機能で選択していない時に、灰色になる効果が薄れてしまうので、選択した時にだけ色が他のタブと変わるようにした。

**一応公式ドキュメント**

https://mui.com/material-ui/api/tabs/

## サンプルコード(chatGPT)

```jsx
import React from 'react';
import { Tabs, Tab, makeStyles } from '@material-ui/core';

const useStyles = makeStyles({
  hoge: {
    '&.Mui-selected': {
      color: 'red',
    },
  },
});

export default function CustomTabs() {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <Tabs value={value} onChange={handleChange}>
      <Tab label="foo" />
      <Tab label="hoge" classes={{ selected: classes.hoge }} />
      <Tab label="bar" />
    </Tabs>
  );
}
```

## 結果

このコードを参考に、Tabごとに色を変えることができた。

あまり調べても情報がなかった時に、chatGPTはとても便利だと思う。
javascriptで配列の仕分け方をChatGPTにコードレビューしてもらいました。



# やる事
numbers配列内の数値を３以下とそれ以外で分けたオブジェクトを作る

```ruby:js
const numbers = [1, 2, 3, 4, 5, 6];

{
	ika: [1,2,3],
	igai: [4,5,6]
}
```

## まずは自分で書いてみる

```ruby:mycode.js
	const numbers = [1, 2, 3, 4, 5, 6];

	let siwake = {
		ika: [],
		igai: []
	}

	numbers.forEach((number) => {
		if (number <= 3) {
			siwake.ika = [...siwake.ika, number]
		}
		else {
			siwake.igai = [...siwake.igai, number]
		}
	});

	console.log(siwake);
```

スプレット構文をループ処理内で使っているあたりを怒られそう。


# 質問してみた

Q.
    上記のようなjavascriptのコードのように3以下とそれ以外で分ける処理で、より軽量でエラーが起こりにくい書き方を教えて下さい。

A.
    上記のコードは、与えられた配列`numbers`をループして、特定の条件に基づいて2つの別々の配列 `siwake.ika`と`siwake.igai`に要素を追加しています。このコードは機能的ではありますが、より効率的な方法があります。

以下は、より効率的なアプローチです。

```ruby:ChatGPT.js

const numbers = [1, 2, 3, 4, 5, 6];

const siwake = {
  ika: [],
  igai: []
};

for (const num of numbers) {
  if (num <= 3) {
    siwake.ika.push(num);
  } else {
    siwake.igai.push(num);
  }
}

console.log(siwake);
```

このコードでは、`forEach`メソッドの代わりに`for...of`ループを使用し、配列に要素を直接`push`メソッドを使用して追加しています。これにより、スプレッド演算子や新しい配列を作成する必要がなく、メモリ使用量が削減され、パフォーマンスが向上します。

また、`const`キーワードを使用して`numbers`と`siwake`変数を宣言しました。これは、変数が再代入されないことを示すため、より安全なコードになります。

# さらに質問をする。

Q.これでも動きましたけど
```ruby:mycode.js
for (num of numbers) {
		if (num <= 3) {
			siwake.ika.push(num);
		} else {
			siwake.igai.push(num);
		}
	}
```
以下のようにconst num とした理由を教えてください。

```ruby:ChatGPT.js
for (const num of numbers) {
		if (num <= 3) {
			siwake.ika.push(num);
		} else {
			siwake.igai.push(num);
		}
	}
```


A.
`for...of`ループを使用する際に、ループ内で`num`という変数を宣言する方法についての質問ですね。

```ruby:mycode.js
for (num of numbers) { ... }
```

このコードは、`for...of`ループで`num`という変数を宣言していますが、この場合、`num`変数はループ内で再代入可能な変数として扱われます。つまり、`num`の値が再代入される可能性があるため、このコードは動作しますが、コードの可読性や保守性に欠ける可能性があります。

一方、

```ruby:ChatGPT.js
for (const num of numbers) { ... }
```
このコードでは、`const`キーワードを使用して`num`変数を宣言しています。この場合、`num`変数は再代入不可能な定数として扱われ、ループ内で`num`の値が再代入されることはありません。このようにすることで、コードの可読性が向上し、`num`の値が誤って変更されることを防ぐことができます。

したがって、`const`キーワードを使用して変数を宣言することは、コードの品質を向上させ、バグを防ぐのに役立つ良いプラクティスです。コード内で再代入が不要な変数は、できるだけ定数として宣言することが推奨されます。

# TypeScriptで書き直してもらう

もちろん、TypeScriptで同じ処理を書いてみましょう。以下がTypeScriptでのコードです。

```ruby:ChatGPT.ts
const numbers: number[] = [1, 2, 3, 4, 5, 6];

const siwake: { ika: number[]; igai: number[] } = {
  ika: [],
  igai: [],
};

for (const num of numbers) {
  if (num <= 3) {
    siwake.ika.push(num);
  } else {
    siwake.igai.push(num);
  }
}

console.log(siwake);
```

このコードでは、変数`numbers`と`siwake`の型注釈を追加して、TypeScriptの型チェックを有効にしています。また、`number[]`型の配列を使用して`numbers`と`siwake`の型を指定しました。これにより、TypeScriptは適切な型で変数を使用することを確認し、型の不一致によるエラーを防ぎます。


# まとめ

簡単な処理でChatGPTで質問を行ってから、本番のコードに生かすと、インプットとアウトプットが効率的にできますね！
まだまだ、chatGPT力を上げなければ。。。
Texで図表番号を途中から始める方法

とあるJournalのstylefileを使用して、Texを書いていた。
本文中ではFigureやTableの番号が自動的にそれぞれ順番に割り振られているが (e.g `Figure 5`)、AppendixからFigureやTableの番号が `{Section名}.{Appendix以降の番号}` (e.g. `Figure A.1`) の形式で記載されていた。
Authors Instructionで本文中の番号を引き継ぐ様に指示が出ていたので対応した↓

```
\renewcommand{\thefigure}{\arabic{figure}}
\setcounter{figure}{9}
\renewcommand{\thetable}{\arabic{table}}
\setcounter{table}{5}
```


cf) https://hibikanblog.net/blog-entry-766.html
cf) https://izumin.hateblo.jp/entry/2015/02/06/225753
Azure AppService code デプロイ + FastAPI の備忘録

## 概要

Azure AppService code デプロイで
FastAPI をVSCodeからデプロイする時の備忘録です。


## 備忘録

AppService --> Configuration --> General Settings
から、

![Screenshot 2023-09-14 at 12.30.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1840635/1912c315-e7dd-33ef-eb55-8d340dd0523d.png)

以上のように設定し、

FastAPIレポジトリには

```startup.sh
python -m uvicorn app.main:app --host 0.0.0.0
```

という様にstartup.sh を用意します。

以上。
Javascriptでasync使うと、promiseが返ってきた...

# 背景
JavaScriptで関数の戻り値が、普通の（？）戻り値ではなく、promiseが返ってきました。。
promiseとかきちんと理解しないまま使ってて、とりあえず同期とるならasync/await使えばいいや、くらいのノリで使っていたのが原因ですね。。。

・・・というわけで、初心者向けのメモ。。

# 環境
* Windows 10 64bit
* Node.js（v18.0.0）

# Node.js のパッケージ
* cmd > npm install express（今回express使わないですが。。）

# sample1
~~~javascript：sample1.js
const temp = test();
console.log(temp);

function test(){
    const a = "aaa"
    return a;
}
~~~

~~~:コマンドプロンプト
> aaa
~~~
aaaが出力されます。
まぁ、想定通りですよね。

# sample2
~~~javascript：sample2.js
const temp = test();
console.log(temp);

async function test(){
    const a = "aaa"
    return a;
}
~~~

~~~:コマンドプロンプト
> promise { 'aaa' }
~~~
！！！
なんと、promiseが返ってきました！
sample1とsample2の違いは、functionの前に、asyncを付けただけ。

async関数に対する戻り値は、promiseで返ってくるのですね。。（知らなかった。。。）


# sample3
~~~javascript：sample3.js
test2();

async function test2(){
    const ret = await test();
    console.log(ret)
}

async function test(){{
    const a = "aaa"
    return a;
}}
~~~

~~~:コマンドプロンプト
> aaa
~~~
test()は、前と同じですが、test()を呼ぶtest2()を作ってみました。
その関数の中で、awaitを使って、戻り値を取り出してみると・・・・

（promiseではない）欲しかった値が取得できた！！！


ちなみに、
# sample4
~~~javascript：sample3.js
test2();

async function test2(){
    const ret = test();
    console.log(ret)
}

async function test(){{
    const a = "aaa"
    return a;
}}
~~~

~~~:コマンドプロンプト
> promise { 'aaa' }
~~~
と、sample3のtest2()からawaitをとってしまうと、またpromiseが戻ってきました。。

awaitは、promiseの中身を取り出してくれるのですね。。
ありがたや、ありがたや、、（いまさら！？）
パブリッククラウドのセキュリティを改めて考えてみた

"クラウドってセキュリティ大丈夫なんですか?" - クラウドコンピューティングが台頭し始めた2010年前後頃に、多くの方がこの質問をお客様から受けたのではないでしょうか? この記事は[Cloud Security Foundations, Frameworks, and Beyond](https://www.sans.org/white-papers/cloud-security-foundations-frameworks-beyond/)のChapter4 / Security Myths and Missteps in Cloud Migration: Misconceptions About Public Cloudにインスパイアされた個人の感想です。さすがSANS。当たり前のことを淀みなく完結に解説していますね。

# オンプレミスもインターネット接続がある
至極当たり前のことですが、パブリッククラウドもプライベートクラウドもオンプレミスも、全て物理的なデータセンター上で稼働していますね。物理的なデータセンターには必ずネットワークの回線が引いてあって、インターネット接続が出来る状態になっています。インターネット接続があれば、外部の攻撃者から攻撃を受ける危険性が多かれ少なかれ有ります。これはクラウドだけでなくオンプレミスにも共通しています。仮に今私がお客様から"クラウドってセキュリティ大丈夫なんですか?"と聞かれたら、"答えを持っていません"と返すと思います。理由は、大丈夫か否かの基準はお客様によりまちまちだからです。同時に、"オンプレミスであればセキュリティは万全なのですか?"と聞きたくなるかもしれません。

# クラウドの利点を再度整理
これも当たり前のことですが、オンプレミスには無いクラウドの利点を再度整理したいと思います。先ずは**柔軟性**です。クラウドはAPIやGUIを介して必要な時に必要なリソースを必要なだけ配備して、不要になったら配備したリソースを消すことができます。これはオンプレミスには無い大きな利点の1つかと思います。**生産性**も大きな利点です。オンプレミスでは、専任のITチームがサーバやストレージやネットワークのような物理リソースを調達・設置して、OSやランタイムのようなプライベートを構築、その上にアプリケーションを配備して、ようやくITサービスとして利用者にサービス提供できるようになります。クラウドは、サービスモデル(SaaS/PaaS/IaaS)によりばらつきはあるものの、基本的にはサーバやストレージやネットワーク、OSやランタイムのような基盤は出来上がっているため、すぐにアプリケーションを配備してサービス提供できるようになるため、利用者にとっての生産性が格段に上がりますね。更に**セキュリティの向上**も見逃せません。

# パブリッククラウドは何故セキュリティに利点があるのか?
くどいようで恐縮ですが、クラウドのセキュリティ対策はお客様と、クラウドサービスプロバイダやクラウドサービスブローカーのような外部事業者との分業で成り立っています。下記のダイアグラムはマイクロソフト社のサイトからピックアップしたものです。
<img src="https://i.imgur.com/mDuhBYs.png" width=70%>

サービスプロバイダの責任範囲が最も小さいIaaSであっても、物理的なデータセンターやサーバ等の物理リソースに対するセキュリティの責任はマイクロソフト社(=クラウドサービスプロバイダ)にあります。SaaSになるとマイクロソフト社の責任範囲は広がって、Applicationまでマイクロソフト社がセキュリティの責任を担うことになります。クラウドサービスプロバイダには、ある一定の実務経験やセキュリティ関連のスキルを有したセキュリティエンジニアやセキュリティアーキテクト、セキュリティコンサルタントがいて、日々定常的に最新のセキュリティスキル習得に勤しんでいます。セキュリティ関連の専門スキルを有した複数の人がセキュリティに対する責任を担うクラウドは、お客様だけがセキュリティの責任を担うオンプレミスより遥かに安全と言えます。

# パブリッククラウドは絶対に安全と言えるのか?
物事に絶対は有りえませんね。パブリッククラウドのセキュリティもしかりです。パブリッククラウドのセキュリティで、唯一の欠点はデータガバナンスかもしれません。パブリッククラウドは、複数のデータセンターで稼働していてデータセンターが設置されている国や地域の詳細はお客様には開示されません。かつ、データガバナンスに関する規制は国や地域により異なります。欧州であればGDPR、北米であればCCPAやPIPEDAのような規制があります。お客様がこれらの規制を見落としていて、自社の業界に求められるガバナンスに違反していると良からぬことになるかもしれません。
<br>

お客様から"クラウドってセキュリティ大丈夫なんですか?"と聞かれたら、どう答えるべきでしょうか? 改めて考えると難しいですね。"オンプレミスより、セキュリティに関わる人の専門性と数が異なるのでクラウドには利点もあります。"と答えるのが無難かもしれません。
Visual Studio Code のAzureアカウントからログアウトする方法

## 概要

VSCode の拡張機能でAzureと接続しているとします。
App Service のデプロイなど楽に行えていいですよね。

この時に、他のアカウントにログインしたいために、
現在接続しているアカウントからログアウトしたい時のショートカットコマンドです。


## 方法

**CTRL + Shift + P**

もしくは

**Comamnd + Shift + P**


で`Azure Logout` を実行してください。

また、ログインには同じコマンドから、

`Azure Login`を選択してください。


以上。
デコード

もちろん、APIからデータを取得し、JSON Decoderを使用してデータモデルに変換するコードを示します。以下はAPIリクエストとJSONデータのデコードのコードサンプルです。

```swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func sendRequest(_ sender: UIButton) {
        // 1. APIリクエストを送信
        if let url = URL(string: "ここにAPIのURLを入力") {
            let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
                if let error = error {
                    print("エラー：\(error)")
                    return
                }
                
                if let data = data {
                    do {
                        // 2. JSONデータをデコードしてデータモデルに変換
                        let decoder = JSONDecoder()
                        let items = try decoder.decode([Item].self, from: data)
                        
                        // 3. データモデルを使用
                        DispatchQueue.main.async {
                            // データモデルを利用してUIを更新
                            self.updateUI(with: items)
                        }
                    } catch {
                        print("JSONデータのデコードエラー：\(error)")
                    }
                }
            }
            task.resume()
        }
    }
    
    func updateUI(with items: [Item]) {
        // データモデルを使用してUIを更新する処理を行う
        print("データモデルの内容：\(items)")
    }
}

// 4. データモデルを作成
struct Item: Codable {
    let id: Int
    let name: String
    // 他のプロパティもここに追加
}
```

このコードのポイントは次の通りです：

1. `sendRequest` メソッド内でAPIリクエストを送信します。APIのURLは適切に設定してください。

2. APIから取得したデータをJSON Decoderを使用してデコードし、`Item` データモデルの配列に変換します。

3. データモデルを使用してUIを更新するために、`updateUI` メソッドを非同期で呼び出します。ここで、`items` データモデルを利用してUIを更新できます。

4. `Item` データモデルは、APIからのJSONデータの構造に対応するデータモデルです。JSON Decoderはこのデータモデルを使用してデータの変換を行います。
【ChatGPT】のWeb版とアプリ版の使い分け。Promptなし。


　どうも、カーブミラーです。

　今回は、ChatGPTのWeb版とアプリ版の使い分けの紹介です。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　昨日は、
　　[【ChatGPT（Web版）】が日本語化します。](https://qiita.com/kabumira/items/506ea403887158422c14)
　　　というニュースを
　　　　お伝えしましたね。

　日本語になって、
　　どうでしょうか？
***
　今朝も、
　　ログイン画面が……

　シンプルすぎて、
　　一瞬、固まってしまいましたw　　　
***
　さて、
　　ChatGPTには、
　　　ふたつのアクセス方法が
　　　　あるのは、ご存知でしょう。

　Web版とアプリ版ですね。

　それぞれに
　　メリットデメリットがあり、
　　　おのれのアクセス環境により
　　　　好みは変わるかと思います。
***
　アプリ版については、
　　こちらをどうぞ。

[【ChatGPT】Androidアプリ、到着。報告です。](https://qiita.com/kabumira/items/75b5ffac050478bf3313)

[【ChatGPT】Androidアプリの報告（その２）](https://qiita.com/kabumira/items/11389c1a363e227298f6)
***
　好み、という点では、
　　私はWeb版をメインに
　　　使用しています。

　理由は、
　　入力したプロンプトの
　　　編集ができるから。
***
　でも、アプリ版を使うことも
　　それなりに、あります。

　音声認識は、
　　有用です。
　　　長文の入力を
　　　　する必要があれば、
　　　　　使います。

　しかも、
　　プロンプトにせずに、
　　　コピーして、別アプリに
　　　　ペーストするなんてことも
　　　　　できちゃうわけです。
***
　ChatGPT（アプリ版）を
　　使用するもうひとつの理由。

　それが
　　今回、紹介したい事柄です。

　PC画面上では、
　　あまり感じないかも
　　　しれませんが、
　　　　私はスマホなので、
　　　　　あることに
　　　　　　煩わされる場面が
　　　　　　　多いです。

　あること、
　　それはプロンプトが
　　　完成した際の
　　　　後始末です。

　プロンプトを完成させるまで
　　何度もNewChatして、
　　　プロンプトの検証と修正を
　　　　行ないます。

　多いときは、
　　十個近くになります。

　プロンプトが
　　完成したのはいいけれど、
　　　それまでにNewChatしてきた
　　　　セッションは、
　　　　　もう必要ありません。

　これを削除していくのですが、
　　スマホでは、画面が小さいため
　　　メニューは、必要なときまで
　　　　隠れています。

　削除のたびに、
　　メニューを開き、
　　　セッションを選び、
　　　　セッションが表示されて
　　　　　メニューを開いて、
　　　　　　削除の操作を行なう、
　　　　　　　結構、大変です。

　削除だけでなく、
　　リネームも同じです。
***
　ここで、
　　アプリ版に移ります。

　アプリ版で
　　Historyを開き、
　　　そこで
　　　　削除・リネームしていく。

　メニューを開くのは、
　　最初だけです。

　これで、次から次に、
　　削除・リネームができるのです。

　おそらく、時間短縮には
　　それほど貢献しないでしょう。

　ログインして、
　　作業して、
　　　ログアウトするのですから。

　しかし、精神衛生的に
　　こちらの方が、いいのは、
　　　間違いありません。
***
　スマホでChatGPTしている人は、
　　必要になったら
　　　試してみてくださいね。

　以上。
Node.jsのchild_process実行時の出力結果で日本語を表示させたい

# 背景
Node.jsから、コマンドライン実行をためそうと思いましたが、標準出力やエラー内容に日本語が含まれていると、文字化けする。。。
いろんなサイトをみてても、なんだかうまくいかなかったので、解決法をめも。

# 環境
* Windows 10 64bit
* Node.js（v18.0.0）

# Node.jsのパッケージ
* cmd > npm install express
* cmd > npm install iconv-lite

# test_exec.js
~~~javascript:test_exec.js
const proc = require("child_process");
const iconv = require("iconv-lite");

proc.exec("dir", {encoding:"Shift_JIS"}, (error, stdout, stderr)=>{
    console.log(`stdout:${iconv.decode(stdout,"Shift_JIS")}`)
    console.log(`stderr:${iconv.decode(stderr,"Shift_JIS")}`)
})
~~~
⇒これで、日本語でも大丈夫になった！！

# メモ
* exec実行時に文字コードをShift_JISにエンコードして、文字を出力するときにShift_JISでデコードすればよいだけだった。
わかれば一瞬だけど、結構時間かかった。。
[Local Port Forwarding]ローカルで動かしてるサービスを他の人にもみてほしい[VSCode]


# はじめに
VSCodeの1.82が出たので[リリースノート](https://code.visualstudio.com/updates/v1_82#_workbench)見てみた。
すると以下の１文を見つけた。

- Built-in port forwarding - Forward local server ports from within VS Code.

ローカルで実行しているサーバーのポートを転送しまっせ

ナニコレベンリソウ

# 詳しくみてみた

Local Port Forwardingの詳しいことは[ここ](https://code.visualstudio.com/docs/editor/port-forwarding)に詳しく書いていた

ざっくりまとめると

- 拡張機能不要でローカルで実行中のサービスへの転送アドレス作ってくれる
- アクセスするにはアドレス作成者と一緒のGitHubアカウントにサインインする必要がある
- ただ設定をパブリックにすればアドレス知ってる人なら誰でもアクセスできる
- 現状リモートマシンには対応してないけど対応する予定だよ待っててね

# いつ使う？
どういう場面で使えそうかいくつか考えてみた

- デモの提供:

開発中のWebアプリケーションやサービスを、クライアントやチームメンバーにリアルタイムでデモする際。ローカル環境での動作をそのまま外部に公開できるため、特定の環境での動作確認やフィードバックを迅速に受け取れる。

- バグの再現:

チームメンバーやQAチームが特定のバグを再現できない場合、実際に問題が発生しているローカル環境を直接アクセス可能にして、バグの原因を特定しやすくする。

- 外部のAPIやサービスとの連携テスト:

外部のAPIやサービスとの連携をテストする際に、ローカル環境での動作を外部からアクセス可能にして、実際の連携の動作を確認する。

- 教育・トレーニング:

教育セッションやワークショップで、参加者にリアルタイムでローカル環境の動作を見せる際に使用。

- 一時的な公開:

すぐに外部からアクセス可能な環境が必要な場合、一時的にローカル環境を公開して対応します。例えば、ハッカソンやイベントでのプレゼンテーションなど。

# 終わり

ペアプログラミングやりやすそうだなと思ったし。
プログラミングスクール通いたてのエラーの説明もままならない人に教えるときに使えそう。
ただ、セキュリティ面のリスクはあるのでどこの利を取るかは考える必要。
医療画像のセグメンテーション×秘密計算の事例

## 概要

**医療画像のセグメンテーションを行う機械学習タスク**において、

**秘密計算**を用いてユーザの画像の秘匿性を担保しながら実行する
アプリケーションには
どの様なものがあるのか少し気になり、調べてみました。


## 今回の先行研究論文

こちらになります。2021年に公開された論文です。

![Screenshot 2023-09-14 at 11.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/43c6ad4f-a0fb-5cf3-da6f-a4c25ed13830.png)

## 使用しているデータセット

http://segchd.csail.mit.edu/

の画像を使用したセグメンテーションです。

## 使用しているモデル

１９層の畳み込み層を使用したUNetのセグメンテーションタスク

## 推論にかかる速度

約3000秒で一枚推論できる。

## 使用する秘密計算システム

レベル型準同型暗号で構成したMPC（マルチパーティコンピュテーション）
のハイブリッド構成に、
さらにTEE（秘匿演算環境）を使用しています。

## この論文を読むための前提知識

- 準同型暗号
- 秘密分散
- TEE

という秘密計算のコアエンティティと、

- DELPHI（https://www.usenix.org/conference/usenixsecurity20/presentation/mishra）2020
- GAZELLE(https://www.usenix.org/conference/usenixsecurity18/presentation/juvekar)

このあたりの秘密計算のAIへの有名な応用論文

について理解している必要があります。

## 使用しているプロトコルの詳細

使用したプロトコルは
DELPHI などで利用されている２パーティ型の加法シークレットシェアを使用したMPCで、
MPCを構成する際にはMicrosoft SEALなどの準同型暗号ライブラリを用いている。
これにより、ユーザがデータを入力する前に乱数を共有しておく（この乱数は平文で良い）ことができ、
ユーザがデータを入力した後は、行列演算に対して、MPC由来の重い通信をする必要もないし、
LHE由来の重い乗算も行う必要がないため、いいとこ取りの手法になっている。

DELPHIでは、基本方針としてReLU関数（非線形関数）の近似を二次関数で行っていたため、
その非線形演算をTEEに移したのが今回のこの論文の手法である。



## まとめ

今回は
`医療画像のセグメンテーションを行う機械学習タスク`
についておそらく一番実用性があり進んでいると考えられる応用論文について紹介しました。

みなさんもぜひキャッチアップしてみてください。

今回はこの辺で。


@kenmaro
Databricksの列マスクを試してみる

こちらの続きで今度は列マスク(column mask)を試します。

https://qiita.com/taka_yayoi/items/8ec6ec967d6d9fdae0e6

https://qiita.com/taka_yayoi/items/9fed2a76501e3db4880a

# 準備

事前に`DS`というグループを作成しておき、ユーザーAのみを追加しておきます。

対象のテーブルは`target`とします。以下のように`pickup_zip`などの郵便番号が含まれているテーブルです。ちなみにこちらはNYのタクシーの乗降記録です。
![Screenshot 2023-09-13 at 10.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d36e13bc-a4e5-3ee4-ce0e-7d73e97960a1.png)

Sharedクラスターを作成して起動します。シングルユーザークラスターでは本機能は動作しません。

# ユーザーAの作業

```sql
USE main.default;
```

列マスクの関数を定義します。このフィルターは、テーブルにアクセスするユーザーがグループ`DS`に所属している場合には全レコードをそのまま返却しますが、そうではない場合にはzipコードを`****`にマスキングします。

```sql
CREATE FUNCTION zip_mask(zip STRING)
  RETURN IF(IS_ACCOUNT_GROUP_MEMBER('DS'), zip, '****');
```
![Screenshot 2023-09-14 at 11.12.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/19e8d2be-bdeb-0607-6d8b-0c5ae1a2cdfc.png)

テーブルに列マスクを設定します。

```sql
ALTER TABLE target ALTER COLUMN dropoff_zip SET MASK zip_mask;
```

`DESCRIBE EXTENDED`で列マスクが設定されていることを確認できます。

```sql
DESCRIBE EXTENDED target;
```
![Screenshot 2023-09-14 at 11.15.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ea53f71b-8142-b99f-4d39-f8bde96938b2.png)

ユーザーAはグループ`DS`に所属しているので、列マスクは適用されません。

```sql
SELECT * FROM target;
```
![Screenshot 2023-09-14 at 11.21.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/135b8027-6219-cced-28c7-e3cf262afe4d.png)

# ユーザーBの作業

ユーザーBはグループ`DS`には属していません。

```sql
SELECT * FROM target;
```

列マスクが動作して、`dropoff_zip`が`****`にマスキングされます。
![Screenshot 2023-09-14 at 11.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/23afbce5-df9c-4fd8-7e8d-6cc52a1730aa.png)

より複雑なマスキングのロジックも実装できますので、例えば、メールアドレスの前半のみをマスキングすることも可能です。ぜひご活用ください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【Rspec】SystemSpecにてwithin〜do~end テスト対象の範囲を絞る

## 目的

システムスペックテストコードで 
it ~ do ~以降のテストコード内にある「within ~ do ~ end」 の部分について入口だけでも理解したい。

## テストコード確認

以下のシステムスペックのテストコードについて調べる。
これはタグのページでパンくず🍞を設定したので、それに関するテストの一部。

```spec/system/tags_spec.rb
require 'rails_helper'

RSpec.describe 'Tags', type: :system do
  let(:user) { create :user }
  before do
    login(user)
  end
  describe '記事に紐付くタグの一覧画面' do
    it 'Home > 「記事」というパンくずが表示されていること' do
      visit tags_path
      within('.breadcrumb') do
        expect(page).to have_content('Home'), '「Home」というパンくずが表示されていません'
        expect(page).to have_content('記事'), '「記事」というパンくずが表示されていません'
      end
    end

 # -- 以下省略 --

```

## within ~ do ~ end  とは？？

witin ⇒ 直訳すると「〜内」「以内」という意味。
つまり、テスト対象の範囲を指定するために使う！

改めてコードを見てみる。

```ruby
describe '記事に紐付くタグの一覧画面' do
    it 'Home > 「記事」というパンくずが表示されていること' do
      visit tags_path
      within('.breadcrumb') do
        expect(page).to have_content('Home'), '「Home」というパンくずが表示されていません'
        expect(page).to have_content('記事'), '「記事」というパンくずが表示されていません'
      end
    end
```

**「within('.breadcrumb') do」** となっている。
これは
**「CSSクラス名が'breadcrumb'の要素内でのみ検索・操作を行う」** ということ。
つまり
**「パンくずリスト🍞（'.breadcrumb'クラス要素）の部分だけをテスト対象の範囲にしている」** ということ！！

## なぜ範囲指定したのか？
今回のテストは画面上にパンくずを実装できたかを確認するためのもの。
そのため、単にexpect(page).to hame_content('タグ名')としてしまうと、Rspec上ではページ全部から「タグ名」を探してしまい正確性に欠けてしまう。
そのため、タグの部分だけにテスト範囲を絞る必要があった。

## 最後に
Rspecについてはまだまだ勉強中なので、手を動かしながら少しずつ覚えていきたいです。

以上！
【Xcode／Swift】Thread 1: “Could not load NIB in bundle: ‘NSBundle with name ‘fileName'”

## エラー内容
:::note alert
Thread 1: “Could not load NIB in bundle: ‘NSBundle <Path> with name ‘fileName'”
:::

## 原因
nibファイルを呼び出す際に、ファイル名が一致していないため。

## 解決方法
ファイル名かファイル名を呼んでいる箇所でスペルミスがないかチェックをする。

私の場合は、ファイル名の変更を忘れていたためにエラーが発生しました。
React Flowを触ってみよう！①

# React Flowについて
![reactflowsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1210256/474fdc21-2fce-e62d-c013-54122644f5fa.png)

### React Flowとは
React FlowはReactをベースとしたライブラリで、主にフローチャートを描画したり、ウェブアプリケーション内でユーザーがノードとエッジ（ノード間の接続）を操作できるビジュアルエディタを作成できます。

https://reactflow.dev/

### React Flowで作られているサービス
React Flowは様々なアプリで利用されています。主にオンラインホワイトボードツールなどで使用されることが多く、下のリンクのサービスは全てReact Flowを利用して開発されています。

https://miro.com/ja/

https://whimsical.com/

https://product.strap.app/

### この記事でやること
React Flowチュートリアルのcode sandboxを利用して、実際にReact Flowを表示するところと、ノードとエッジについての基本的な情報を解説します。

# 環境

https://codesandbox.io/s/react-flow-starter-typescript-j8lkh?file=/src/App.tsx

React Flowチュートリアルのcode sandbox上でテストします

# ファイル構成
基本的にはsrc配下のファイルのみ記述します

App.tsx
React Flowファイルの読み込みしているファイル。**基本触らないので無視。**

**CustomNode.tsx**
オリジナルのノード作成をするためのファイル。

**Flow.tsx**
ここで主にReact Flowの記述を行う。

index.tsx
Reactのアプリケーションをレンダリングしているファイル。**基本触らないので無視。**

**style.css**
ノードやエッジなどにスタイルをつけるためのファイル。

# 始める前に気をつけること

:::note warn
version11からパッケージ名がreactflowになりました。
react-flow-rendererと書かれている情報は基本的に古くなっています。
:::


```typescript:古いimport文
import ReactFlow from 'react-flow-renderer'; 
```

```typescript:新しいimport文
import ReactFlow from 'reactflow'; 
```

:::note warn
React Flowを機能させるには必須のcssインポートがあります。誤って消さないように気をつけましょう。
:::
```typescript:必須のcss
import 'reactflow/dist/style.css';
```

これらの詳細は下のリンクから見れます。

https://reactflow.dev/docs/guides/migrate-to-v11/

# ノード

```typescript:ノード
const initialNodes: Node[] = [
  {
    id: "1",
    type: "input",
    data: { label: "Node 1" },
    position: { x: 250, y: 5 }
  },
  { id: "2", data: { label: "Node 2" }, position: { x: 100, y: 100 } },
  { id: "3", data: { label: "Node 3" }, position: { x: 400, y: 100 } },
  {
    id: "4",
    type: "custom",
    data: { label: "Custom Node" },
    position: { x: 400, y: 200 }
  }
];
```
ここで画面に表示するノードを定義しています。

id：各ノードのid
type：typeでノードの種類を選択できます
```:ノードのタイプ 
  input: InputNode
  default: DefaultNode
  output: OutputNode
  group: GroupNode
  custom: Custom　← 自分で定義したノードタイプを使うことができます。
```
data：ここには自由にデータを入れることができます。サンプルコードではlabelを用意して、ノードに表示する文字列を持たせています。
position：ノードを配置する場所を定義しています。

そのほかにも操作可不可や削除可不可を決められるパラメータもあります。

https://reactflow.dev/docs/api/nodes/node-options/

# エッジ

```typescript:エッジ
const initialEdges: Edge[] = [
  { id: "e1-2", source: "1", target: "2", animated: true },
  { id: "e1-3", source: "1", target: "3" }
];
```
ここでは画面に表示するエッジを定義しています。
id：エッジのidです。
souce：エッジの接続元のノードidが入ります。
target：エッジの接続先のノードidが入ります。
animated：エッジのアニメーションの有無を選択できます。


# React Flowの描画
これらのデータを参照してReact Flowは描画を行います。
Custom Nodeについてはほかの記事で細かく書いていこうと思います。
![reactflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1210256/0cfda4cc-c77d-c793-553a-9ba0b9d4f0ee.png)
Apacheでユーザーごとにディレクトリを公開するには

## 環境
Ubuntu20.4 + vagrant
Apache2.4.41

## はじめに
ApacheでWebサイトを公開するとき、基本的なやり方をすれば、Apacheのルートである、**/var/www** 配下にindex.htmlを配置することになります。しかし、公開の仕方はそれだけではありません。各ユーザーごとに、ホームディレクトリ配下にindex.htmlを配置して、複数のユーザーで公開するといったやり方もできます。

つまり、Apacheのルートで、/var/www/hoge/index.htmlを公開しながら、ユーザーAさんが~user_a/index.htmlを公開したり、ユーザーBさんが~user_b/index.htmlを公開したりするといったことができるようになります。その場合の設定方法について書いてみました。

## userdir.confのデフォルト

ユーザーディレクトリを公開するときに設定するコンフィグファイルは、**/etc/apahce2/mods-available/userdir.conf**です。
デフォルトでは次の設定になっています。

```/etc/apahce2/mods-available/userdir.conf
<IfModule mod_userdir.c>
       UserDir public_html
       UserDir disabled root

       <Directory /home/*/public_html>
               AllowOverride FileInfo AuthConfig Limit Indexes
               Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
               Require method GET POST OPTIONS
       </Directory>
</IfModule>
```

## userdir.confの設定 

ホームディレクトリのユーザーディレクトリ配下に、公開するディレクトリを新規で作成します。次の例では、vagrantユーザーの配下にpublic_htmlディレクトリを作成しています。

```
#cd ~
#cd vagrant
#mkdir public_html
```

**userdir.conf**のサンプルをみると、**public_html**になっていますが、ディレクトリの名前は、public_htmlである必要はありません。自分で好きな名前を指定することができます。例えば、hoge_htmlにしたい場合は、コンフィグファイルも次のようにします。

- **UserDir hoge_html**　　： 公開するフォルダを指定します。
- **UserDir disabled root**　： ホーム配下を非公開にする設定？。（未確認）

```/etc/apahce2/mods-available/userdir.conf
<IfModule mod_userdir.c>
       UserDir hoge_html
       UserDir disabled root

       <Directory /home/*/hoge_html>
               AllowOverride FileInfo AuthConfig Limit Indexes
               Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
               Require method GET POST OPTIONS
       </Directory>
</IfModule>
```

公開するユーザーをvagrantとtanに限定する場合は、ワイルドカードを指定するのではなく、次のように各ユーザーごとに分けて設定することもできます。セキュリティ的にはこちらの設定の方が強固になりますが、公開するユーザーが増えるたびに、メンテナンスをしなくてはいけないことにはなります。

```/etc/apahce2/mods-available/userdir.conf
       <Directory /home/vagrant/hoge_html>
          # 省略
       </Directory>
       <Directory /home/tan/hoge_html>
          # 省略
       </Directory>
</IfModule>
```

/var/wwwを公開するときは、apache2.confのDirectoryディテクティブで、公開するパスを有効化する設定をしましたが、ユーザーディレクトリを公開するときは、**userdir.conf**で設定します。**apache2.conf**でも同じように設定をしなくてはいけないのかいえば、そのようなことはありません。つまり、userdir.confで設定をすれば、下記の設定を行う必要はありません。

```/etc/apache2.conf
<Directory /home/*/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>
```

## userdir.confを有効化する

userdir.confは、デフォルトで **/etc/apahce2/mods-enabled**にシンボリックリンクを作成していません。よって、次のコマンドで設定した内容を有効化する必要があります。
```
#a2enmod userdir
```

## Apacheの再起動

コンフィグファイルを触ったら、Apacheを再起動して反映させます。
```
#systemctl restart apache2
```

## 動作確認

ブラウザを起動して、URLに次のアドレスを指定すれば、画面が表示されます。このとき設定するパスは、~vagrant/public_html/index.htmlのように、**public_html**を加える必要はありません。

```URL
http://192.168.33.1/~vagrant/index.html
```

tanユーザーのディレクトリにアクセスしたい場合は、URLで次のようにします。

```URL
http://192.168.33.1/~tan/index.html
```
Hugo server で failed to extract shortcode: template for shortcode "xxxx" not found になるときの解決

ローカルでＨugoサーバーを起動できなくなったときの原因と解決方法です。

# Hugo server 起動に失敗する
Hugo と Github Pages でブログを作っていて、

ローカルでHugoを起動するコマンド

```terminal
$ hugo server
```

を実行して起動しようとすると、
以下のようなエラーが突然出るようになりました。

```terminal
$ hugo server
Start building sites …
hugo v0.110.0-e32a493b7826d02763c3b79623952e625402b168+extended windows/amd64 BuildDate=2023-01-17T12:16:09Z VendorInfo=gohugoio   
Error: Error building site: "C:\Users\hugo\aiko-han.github.io\content\post\rich-content\index.md:38:1": failed to extract shortcode: template for shortcode "bilibili" not found
Built in 36 ms
```

エラー文で怒られている index.md ファイルを確認してみます。

```markdown
## bilibili Shortcode

{{< bilibili av498363026 >}}
```

「bilibili と index.md ファイルに書いてるけど、そんな shortcode は無いよ！」と言われているようです。

上記のエラーは、"bilibili" ですが、"Gist" であったり、他の shortcode の指摘
で同じエラーが発生することもあります。

何で急に not found・・・:disappointed_relieved: となりますが
原因は単純でした。

# 原因
原因は、「`git clone`する際に Hugo のテーマを管理している Git のサブモジュールの取得が出来ていなかったこと」が原因でした。

つまり、hugo のディレクトリ構成は下記のようになっていても、themes ディレクトリ内のサブモジュールテーマが空になってしまっていたのです。

```
├── archetypes
├── content
├── layouts
├── resources
├── static
└── themes
```

# 解決方法

以下のコマンドで、取得しそびれてしまった submoduleで管理しているリポジトリを取得してあげれば解決です👍

```terminal
$ git submodule update --init --recursive
```

実行すると以下のようにサブモジュールを clone できます。
```terminal
$ git submodule update --init --recursive
Submodule 'themes/hugo-theme-stack' (https://github.com/CaiJimmy/hugo-theme-stack.git) registered for path 'themes/hugo-theme-stack'
Cloning into 'C:/Users/a0i2k/hugo/chacha8.github.io/themes/hugo-theme-stack'...
Submodule path 'themes/hugo-theme-stack': checked out 'aae9cf67db8661e86996f8808baf4f71c472d911'
```

この後、もう一度 `$ hugo server`を実行すると、無事に起動できました！

# おわりに
Hugo の中のテーマを Git のサブモジュールを使って構成していると、また遭遇しやすそうなエラーだったので自分の備忘録として残しておきました。
参考になれば嬉しいです。
QNAP QDA-A2AR(RAID1対応内蔵ドライブベイ) の使いどころ

# QNAP QDA-A2ARについて

2台の2.5インチSATAドライブを、1つの3.5インチSATAドライブベイの中で使用するためのオプション製品。SATAのポートマルチプライヤーの機能を利用して実現する。したがって、一般のPC等で利用するには、接続先のSATAコントローラがポートマルチプライヤー対応であることが必要とされている。

本稿では、QNAPのNASの空き3.5インチドライブベイに取り付けて、どのように使用できるかを見る。筆者の意図としては、3ドライブベイのNASでミラーを組んでいて、余りの1ベイを有効に活用したい、というところ。

# ハードウェア

2.5インチのハードディスクを取り付けてみたところ。

![QDA-A2AR.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/f809d4fb-a113-4c63-1b1f-faa14f020bc1.jpeg "外観")

2つのSATAコネクタのそばにディップスイッチがあり、RAID設定を行う。工場出荷時は、RAID1の設定。

![RAID設定スイッチ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/e09d0774-a351-eee2-70d7-dd5f7682f295.jpeg "RAID設定のディップスイッチ")


# NASでの制限

貼付の説明書によると、QNAPのNASで利用する場合、**'Individual(個々のドライブを別々に扱う)'** の設定は利用できない。データの安全を求める用途では、RAID1の設定を利用することになる。

![対応するRAIDモード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/afdaa062-47a0-6462-afb1-4aa50a987770.jpeg "製品貼付の説明書から")


# ディスクの見え方

QTSに接続し、'ストレージ＆スナップショット'を起動して、ディスクの状況をみる。

![ディスクの見え方.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/d7cc8546-0399-9ebc-bc31-3323140197ca.jpeg "ストレージ＆スナップショット")

デバイスとして、QDAが1つ、HDDが2つ、として認識されている。

ページ右上の'外部ストレージデバイス'を確認する。

![外部ストレージデバイス管理.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/64a6da13-2b9b-b72b-74db-cfb7f2048429.jpeg "外部ストレージデバイス管理")

QDA-A2ARと、搭載されている2つのディスクの状況を確認できる。ディップスイッチの設定の通り、RAID1と認識されている。

# ストレージプールでの利用

## 既存のストレージプールの拡張

既存のストレージプールに追加できるか確認する。既存のストレージプールの拡張のためのウィザードを起動する。

![ストレージプールへの追加.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/f6ae95a0-97c9-bdc5-55bf-dc89726604ea.jpeg "既存の外レージプールの拡張")

追加するディスクの候補としてQDAが表示されるが、容量とRAIDタイプが赤色の警告表示になっている。RAIDタイプは、RAID1のみが選択可能になっている。

![警告.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/1bb873cf-f50f-a9e7-2088-fa41d0604bdc.jpeg "警告")

'次へ'を選択すると、2台のディスクが必要とのダイアログが表示され、先に進めない。

Webの商品説明のページには、QDAを2つ、ないし、QDAと同容量のディスクがもう1つ、必要と記載されており、このダイアログ表示を裏付ける。ただし、余りの1ドライブベイを活用する、という点では、意味がない。

## 新規ストレージプールの作成

したがって、新規にストレージプールを作成して利用することになる。RAIDタイプは、単独ドライブとの表記になる。

![新規ストレージプール.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/9d92c5a2-13bd-662f-eacd-a7b8b25457a3.jpeg "ストレージプールの作成ウィザード")


# 使いどころ

ストレージプールではRAIDタイプは単独ドライブとなっているが、外部ストレージデバイス管理ではRAIDタイプはRAID1となっており、データの安全が確保された領域として、RAID1のストレージプールと同様に扱える。

例えば、AppCenterでアプリのインストール先として、選択が可能である。

![アプリの移行先.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/06ce8b22-b8bb-6c2f-01a1-5b27a94163bd.jpeg "一番下のSystemVolがQDA上に設けたボリューム")

余りの1ドライブベイの有効活用という点では、拡張できる容量に1ドライブ分の制約があるので、安価になった2.5インチSSDを搭載して、高速なiSCSIのターゲットドライブや比較的小容量の共有ドライブなどに活用するのが良さそうである。

既存のストレージプールの容量拡張には向かないのは少々残念ではある。
パワーシェル、管理者権限昇格コマンド参考URL

パワーシェルの管理者権限昇格のコマンドは以下に書かれてありました
https://qiita.com/sakekasunuts/items/63a4023887348722b416

●パワーシェル起動後下記実行
Start-Process powershell -verb runas

Start-Process powershell	PowerShellを新しく始めます
-Verb RunAs	管理者権限で

●ps1実行時に自動的に昇格させたい↑
スクリプトの頭にこれを挿入する

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) { Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs; exit }


if ( ! ( ～～～ ) )	もし（～～～）でなければ
[Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]
::GetCurrent()	現在の実行権限を確認
.IsInRole("Administrators")	管理者権限
Start-Process powershell.exe	PowerShellを新しく始めます
"-File `"$PSCommandPath`"	私自身のフルパスを指定します
-Verb RunAs	管理者権限で
; exit	現在のスクリプトを終了します。
直訳すると
現在の実行権限を確認します。もし管理者権限でなければ、 同じスクリプトを新たな管理者権限のPowerShellで起動します。 ついでに現在のスクリプトは終了します